cat-documents-ng 0.2.57 → 0.2.60
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.
- package/Shared/constant/SHARED.d.ts +21 -0
- package/fesm2022/cat-documents-ng.mjs +711 -369
- package/fesm2022/cat-documents-ng.mjs.map +1 -1
- package/lib/document/components/document-search/document-search.component.d.ts +1 -1
- package/lib/document/components/document-upload/document-upload.component.d.ts +206 -6
- package/lib/document/components/documents-menu/documents-menu.component.d.ts +26 -0
- package/lib/document/components/folder-container/folder-container.component.d.ts +25 -2
- package/lib/document/components/sidebar/sidebar.component.d.ts +63 -0
- package/lib/document/document.module.d.ts +2 -2
- package/lib/document/services/document-history.service.d.ts +1 -17
- package/lib/document/services/document-upload-business.service.d.ts +19 -6
- package/lib/document/services/document-upload-form.service.d.ts +8 -0
- package/package.json +1 -1
- package/public-api.d.ts +1 -1
- package/lib/document/components/common-sidebar/common-sidebar.component.d.ts +0 -47
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable, EventEmitter, ViewChild, Input, ViewEncapsulation, Component,
|
|
2
|
+
import { Injectable, EventEmitter, Output, ViewChild, Input, ViewEncapsulation, Component, Directive, NgModule, APP_INITIALIZER } from '@angular/core';
|
|
3
3
|
import * as i2$1 from '@angular/common';
|
|
4
4
|
import { CommonModule } from '@angular/common';
|
|
5
5
|
import { firstValueFrom, tap, EMPTY, catchError, throwError, of, combineLatest, Subject, Observable, takeUntil, Subscription, debounceTime as debounceTime$1, distinctUntilChanged as distinctUntilChanged$1 } from 'rxjs';
|
|
@@ -25,6 +25,7 @@ import * as i14 from 'primeng/dropdown';
|
|
|
25
25
|
import { DropdownModule } from 'primeng/dropdown';
|
|
26
26
|
import * as i4$1 from 'primeng/sidebar';
|
|
27
27
|
import { SidebarModule } from 'primeng/sidebar';
|
|
28
|
+
import * as i5 from 'primeng/messages';
|
|
28
29
|
import * as i1 from '@angular/router';
|
|
29
30
|
import * as i7 from 'primeng/dialog';
|
|
30
31
|
import { DialogModule } from 'primeng/dialog';
|
|
@@ -32,14 +33,13 @@ import * as i7$1 from 'primeng/inputtext';
|
|
|
32
33
|
import { InputTextModule } from 'primeng/inputtext';
|
|
33
34
|
import * as i2$2 from 'primeng/table';
|
|
34
35
|
import { TableModule } from 'primeng/table';
|
|
35
|
-
import * as i5 from 'primeng/ripple';
|
|
36
|
+
import * as i5$1 from 'primeng/ripple';
|
|
36
37
|
import { RippleModule } from 'primeng/ripple';
|
|
37
|
-
import * as i5$2 from 'primeng/messages';
|
|
38
38
|
import * as i6 from 'ng2-pdf-viewer';
|
|
39
39
|
import { PdfViewerModule } from 'ng2-pdf-viewer';
|
|
40
40
|
import * as i3$2 from 'primeng/accordion';
|
|
41
41
|
import { AccordionModule } from 'primeng/accordion';
|
|
42
|
-
import * as i5$
|
|
42
|
+
import * as i5$2 from 'primeng/inputtextarea';
|
|
43
43
|
import { InputTextareaModule } from 'primeng/inputtextarea';
|
|
44
44
|
import * as i8 from 'primeng/tooltip';
|
|
45
45
|
import * as i7$2 from 'primeng/badge';
|
|
@@ -76,6 +76,7 @@ class SHARED {
|
|
|
76
76
|
static HIDDEN = 'hidden';
|
|
77
77
|
static NO_DOCUMENTS_FOUND = 'No documents found';
|
|
78
78
|
static DOCUMENT_TYPES_DELETE = 'DocumentTypes-DELETE';
|
|
79
|
+
static SUCCESS_MESSAGE = 'Document Saved Successfully';
|
|
79
80
|
/**
|
|
80
81
|
* Represents the info.
|
|
81
82
|
*/
|
|
@@ -279,6 +280,7 @@ class SHARED {
|
|
|
279
280
|
static APPLICANT = 'Applicant';
|
|
280
281
|
static CATAGORIES = 'catagories';
|
|
281
282
|
static DOCUMENTS = 'Documents';
|
|
283
|
+
static UPLOAD_FAILED = 'Upload failed';
|
|
282
284
|
static Menu = [
|
|
283
285
|
{
|
|
284
286
|
label: 'Applicant',
|
|
@@ -508,6 +510,27 @@ class SHARED {
|
|
|
508
510
|
static BUTTON_LABEL_REJECTED = 'Rejected';
|
|
509
511
|
static BUTTON_LABEL_ACCEPT = 'Accept';
|
|
510
512
|
static BUTTON_LABEL_ACCEPTED = 'Accepted';
|
|
513
|
+
// Document Upload Validation Messages
|
|
514
|
+
static VALIDATION_NO_APPLICANT_SELECTED = 'No Applicant Selected';
|
|
515
|
+
static VALIDATION_NO_APPLICANT_DETAIL = 'Please select an applicant.';
|
|
516
|
+
static VALIDATION_NO_CATEGORY_SELECTED = 'No Category Selected';
|
|
517
|
+
static VALIDATION_NO_CATEGORY_DETAIL = 'Please select a category.';
|
|
518
|
+
static VALIDATION_NO_DOCUMENT_TYPE_SELECTED = 'No Document Type Selected';
|
|
519
|
+
static VALIDATION_NO_DOCUMENT_TYPE_DETAIL = 'Please select a document type.';
|
|
520
|
+
static VALIDATION_NO_DOCUMENTS_UPLOADED = 'No Documents Uploaded';
|
|
521
|
+
static VALIDATION_NO_DOCUMENTS_DETAIL = 'Please upload at least one document.';
|
|
522
|
+
static VALIDATION_FORM_INCOMPLETE = 'Form Incomplete';
|
|
523
|
+
static VALIDATION_FORM_INCOMPLETE_DETAIL = 'Please complete all required fields and upload at least one document.';
|
|
524
|
+
static VALIDATION_MISSING_REQUIRED_DATA = 'Missing Required Data';
|
|
525
|
+
// Document Upload Assignment Type Messages
|
|
526
|
+
static VALIDATION_SELECT_ASSIGNMENT_TYPE = 'Please select an assignment type (Applicant or Application)';
|
|
527
|
+
static VALIDATION_SELECT_CATEGORY = 'Please select a document category';
|
|
528
|
+
static VALIDATION_SELECT_DOCUMENT_TYPE = 'Please select a document type';
|
|
529
|
+
static VALIDATION_UPLOAD_AT_LEAST_ONE = 'Please upload at least one document';
|
|
530
|
+
static VALIDATION_WAIT_FOR_UPLOAD = 'Please wait for all files to finish uploading';
|
|
531
|
+
static VALIDATION_SELECT_APPLICANT = 'Please select an applicant';
|
|
532
|
+
static VALIDATION_ALL_FIELDS_COMPLETED = 'All required fields are completed';
|
|
533
|
+
static VALIDATION_OPTIONS_NOT_LOADED = 'Document options are not loaded yet';
|
|
511
534
|
}
|
|
512
535
|
/**
|
|
513
536
|
* `DUMMYDOCUMENTLIST` is a mock list of document objects used for testing and development purposes.
|
|
@@ -1116,7 +1139,7 @@ class URLS {
|
|
|
1116
1139
|
* @static
|
|
1117
1140
|
* @type {string}
|
|
1118
1141
|
*/
|
|
1119
|
-
static SAVE_DOCUMENT_UPLOAD = "documents/
|
|
1142
|
+
static SAVE_DOCUMENT_UPLOAD = "documents/create";
|
|
1120
1143
|
/**
|
|
1121
1144
|
* The query parameter to pass a context ID in API requests.
|
|
1122
1145
|
* @static
|
|
@@ -1270,7 +1293,7 @@ class DocumentService {
|
|
|
1270
1293
|
* @returns {Observable<any>} Observable that emits the newly created document.
|
|
1271
1294
|
*/
|
|
1272
1295
|
create(entity) {
|
|
1273
|
-
const headers = { 'Authorization': 'Bearer
|
|
1296
|
+
const headers = { 'Authorization': 'Bearer 514330f0-41d4-4c03-8d2e-f248a1340e8d' };
|
|
1274
1297
|
return this.http.post(`${this.apiUrl}${URLS.DOCUMENT_UPLOAD_FILE}`, entity, { headers }).pipe(tap((newEntity) => this.documentStore.add(newEntity)));
|
|
1275
1298
|
}
|
|
1276
1299
|
/**
|
|
@@ -1675,7 +1698,7 @@ class DocumentHttpService {
|
|
|
1675
1698
|
* @returns {Observable<any>} Observable that emits the transformed data for dropdown options.
|
|
1676
1699
|
*/
|
|
1677
1700
|
getDocumentCatagories(contextId) {
|
|
1678
|
-
let headers = new HttpHeaders({ Authorization: `Bearer
|
|
1701
|
+
let headers = new HttpHeaders({ Authorization: `Bearer 514330f0-41d4-4c03-8d2e-f248a1340e8d` });
|
|
1679
1702
|
return this.http.get(`${this.apiUrl}${URLS.DOCUMENTS_CATAGORIES}/${contextId}`, { headers }).pipe(tap((response) => {
|
|
1680
1703
|
// Store only the categories array, not the entire response
|
|
1681
1704
|
if (response && response.categories) {
|
|
@@ -1734,7 +1757,7 @@ class DocumentHttpService {
|
|
|
1734
1757
|
* @returns {Observable<DocumentModel>} An observable that emits the updated DocumentModel.
|
|
1735
1758
|
*/
|
|
1736
1759
|
updateDocumentName(documentId, payload) {
|
|
1737
|
-
let headers = new HttpHeaders({ Authorization: `Bearer
|
|
1760
|
+
let headers = new HttpHeaders({ Authorization: `Bearer 514330f0-41d4-4c03-8d2e-f248a1340e8d` });
|
|
1738
1761
|
return this.http.put(`${this.apiUrl}${URLS.DOCUMENT_UPLOAD}/${documentId}`, payload, { headers }).pipe(catchError((error) => {
|
|
1739
1762
|
return throwError(() => new Error(error));
|
|
1740
1763
|
}));
|
|
@@ -1747,7 +1770,7 @@ class DocumentHttpService {
|
|
|
1747
1770
|
getUserListByContextId(contextId) {
|
|
1748
1771
|
if (!contextId)
|
|
1749
1772
|
return EMPTY;
|
|
1750
|
-
let headers = new HttpHeaders({ Authorization: `Bearer
|
|
1773
|
+
let headers = new HttpHeaders({ Authorization: `Bearer 514330f0-41d4-4c03-8d2e-f248a1340e8d` });
|
|
1751
1774
|
return this.http.get(`${this.apiUrl}${URLS.USERLIST}${contextId}`, { headers }).pipe(tap((userList) => {
|
|
1752
1775
|
this.documentStore.setUserList(userList);
|
|
1753
1776
|
}), catchError((error) => {
|
|
@@ -1773,7 +1796,7 @@ class DocumentHttpService {
|
|
|
1773
1796
|
if (categoryId) {
|
|
1774
1797
|
params = params.set(SHARED.CATEGORY, categoryId);
|
|
1775
1798
|
}
|
|
1776
|
-
let headers = new HttpHeaders({ Authorization: `Bearer
|
|
1799
|
+
let headers = new HttpHeaders({ Authorization: `Bearer 514330f0-41d4-4c03-8d2e-f248a1340e8d` });
|
|
1777
1800
|
return this.http.get(url, { params, headers }).pipe(tap((statusData) => {
|
|
1778
1801
|
this.documentStore.setStatusData(statusData);
|
|
1779
1802
|
}), catchError((error) => {
|
|
@@ -1804,7 +1827,7 @@ class DocumentHttpService {
|
|
|
1804
1827
|
if (searchKey) {
|
|
1805
1828
|
params = params.set(SHARED.SEARCH_KEY, searchKey);
|
|
1806
1829
|
}
|
|
1807
|
-
let headers = new HttpHeaders({ Authorization: `Bearer
|
|
1830
|
+
let headers = new HttpHeaders({ Authorization: `Bearer 514330f0-41d4-4c03-8d2e-f248a1340e8d` });
|
|
1808
1831
|
return this.http.get(`${this.apiUrl}${URLS.GETALL}/${contextId}`, { params, headers }).pipe(tap((response) => {
|
|
1809
1832
|
if (response.documents) {
|
|
1810
1833
|
this.documentStore.setDocumentList(response.documents);
|
|
@@ -1817,7 +1840,7 @@ class DocumentHttpService {
|
|
|
1817
1840
|
if (!documentId) {
|
|
1818
1841
|
return of([]);
|
|
1819
1842
|
}
|
|
1820
|
-
let headers = new HttpHeaders({ Authorization: `Bearer
|
|
1843
|
+
let headers = new HttpHeaders({ Authorization: `Bearer 514330f0-41d4-4c03-8d2e-f248a1340e8d` });
|
|
1821
1844
|
return this.http.get(`${this.apiUrl}${URLS.DOCUMENT_HISTORY}${documentId}`, { headers });
|
|
1822
1845
|
}
|
|
1823
1846
|
/**
|
|
@@ -1828,7 +1851,7 @@ class DocumentHttpService {
|
|
|
1828
1851
|
getCategoriesBySource(source) {
|
|
1829
1852
|
if (!source)
|
|
1830
1853
|
return EMPTY;
|
|
1831
|
-
let headers = new HttpHeaders({ Authorization: `Bearer
|
|
1854
|
+
let headers = new HttpHeaders({ Authorization: `Bearer 514330f0-41d4-4c03-8d2e-f248a1340e8d` });
|
|
1832
1855
|
return this.http.get(`${this.apiUrl}${URLS.GET_CATEGORIES_BY_SOURCE}${source}`, { headers }).pipe(catchError((error) => {
|
|
1833
1856
|
return throwError(() => new Error(error));
|
|
1834
1857
|
}));
|
|
@@ -1841,7 +1864,7 @@ class DocumentHttpService {
|
|
|
1841
1864
|
getDocumentTypesByCategory(categoryId) {
|
|
1842
1865
|
if (!categoryId)
|
|
1843
1866
|
return EMPTY;
|
|
1844
|
-
let headers = new HttpHeaders({ Authorization: `Bearer
|
|
1867
|
+
let headers = new HttpHeaders({ Authorization: `Bearer 514330f0-41d4-4c03-8d2e-f248a1340e8d` });
|
|
1845
1868
|
return this.http.get(`${this.apiUrl}${URLS.GET_DOCUMENT_TYPES_BY_CATEGORY}${categoryId}`, { headers }).pipe(catchError((error) => {
|
|
1846
1869
|
return throwError(() => new Error(error));
|
|
1847
1870
|
}));
|
|
@@ -1852,7 +1875,7 @@ class DocumentHttpService {
|
|
|
1852
1875
|
* @returns {Observable<any>} Observable that emits the upload response.
|
|
1853
1876
|
*/
|
|
1854
1877
|
uploadFile(formData) {
|
|
1855
|
-
let headers = new HttpHeaders({ Authorization: `Bearer
|
|
1878
|
+
let headers = new HttpHeaders({ Authorization: `Bearer 514330f0-41d4-4c03-8d2e-f248a1340e8d` });
|
|
1856
1879
|
return this.http.post(`${this.apiUrl}${URLS.DOCUMENT_UPLOAD_FILE}`, formData, { headers }).pipe(catchError((error) => {
|
|
1857
1880
|
return throwError(() => new Error(error));
|
|
1858
1881
|
}));
|
|
@@ -1863,7 +1886,7 @@ class DocumentHttpService {
|
|
|
1863
1886
|
* @returns {Observable<any>} Observable that emits the save response.
|
|
1864
1887
|
*/
|
|
1865
1888
|
saveDocumentUpload(payload) {
|
|
1866
|
-
let headers = new HttpHeaders({ Authorization: `Bearer
|
|
1889
|
+
let headers = new HttpHeaders({ Authorization: `Bearer 514330f0-41d4-4c03-8d2e-f248a1340e8d` });
|
|
1867
1890
|
return this.http.post(`${this.apiUrl}${URLS.SAVE_DOCUMENT_UPLOAD}`, payload, { headers }).pipe(catchError((error) => {
|
|
1868
1891
|
return throwError(() => new Error(error));
|
|
1869
1892
|
}));
|
|
@@ -1879,7 +1902,7 @@ class DocumentHttpService {
|
|
|
1879
1902
|
const payload = {
|
|
1880
1903
|
statusUpdateDescription: statusUpdateDescription
|
|
1881
1904
|
};
|
|
1882
|
-
let headers = new HttpHeaders({ Authorization: `Bearer
|
|
1905
|
+
let headers = new HttpHeaders({ Authorization: `Bearer 514330f0-41d4-4c03-8d2e-f248a1340e8d` });
|
|
1883
1906
|
return this.http.put(`${this.apiUrl}${URLS.UPDATE_DOCUMENT_STATUS}${documentId}/${status}`, payload, { headers }).pipe(tap((response) => {
|
|
1884
1907
|
if (response && response.status) {
|
|
1885
1908
|
const normalizedStatus = this.normalizeStatus(response.status);
|
|
@@ -1913,7 +1936,7 @@ class DocumentHttpService {
|
|
|
1913
1936
|
* @returns {Observable<any>} Observable that emits the delete response
|
|
1914
1937
|
*/
|
|
1915
1938
|
deleteDocument(documentId, contextId) {
|
|
1916
|
-
let headers = new HttpHeaders({ Authorization: `Bearer
|
|
1939
|
+
let headers = new HttpHeaders({ Authorization: `Bearer 514330f0-41d4-4c03-8d2e-f248a1340e8d` });
|
|
1917
1940
|
return this.http.delete(`${this.apiUrl}${URLS.DELETE_DOCUMENT}${documentId}`, { headers }).pipe(tap(() => {
|
|
1918
1941
|
this.getDocumentCatagories(contextId).subscribe();
|
|
1919
1942
|
this.getUserListByContextId(contextId).subscribe();
|
|
@@ -2434,32 +2457,108 @@ class DocumentUploadBusinessService {
|
|
|
2434
2457
|
}
|
|
2435
2458
|
}
|
|
2436
2459
|
/**
|
|
2437
|
-
*
|
|
2460
|
+
* Helper method to validate form data and return validation result
|
|
2438
2461
|
*/
|
|
2439
|
-
|
|
2462
|
+
validateFormData(assignmentType, selectedCategory, selectedDocumentType, selectedApplicant, uploadedFiles, categoryOptions, documentTypeOptions) {
|
|
2463
|
+
// Check assignment type
|
|
2464
|
+
if (!assignmentType) {
|
|
2465
|
+
return { isValid: false, message: SHARED.VALIDATION_SELECT_ASSIGNMENT_TYPE };
|
|
2466
|
+
}
|
|
2467
|
+
// Check if options are loaded
|
|
2440
2468
|
if (!categoryOptions.length || !documentTypeOptions.length) {
|
|
2441
|
-
return false;
|
|
2469
|
+
return { isValid: false, message: SHARED.VALIDATION_OPTIONS_NOT_LOADED };
|
|
2442
2470
|
}
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
return hasRequiredSelections && hasFiles && Boolean(selectedApplicant);
|
|
2471
|
+
// Check category
|
|
2472
|
+
if (!selectedCategory) {
|
|
2473
|
+
return { isValid: false, message: SHARED.VALIDATION_SELECT_CATEGORY };
|
|
2447
2474
|
}
|
|
2448
|
-
|
|
2449
|
-
|
|
2475
|
+
// Check document type
|
|
2476
|
+
if (!selectedDocumentType) {
|
|
2477
|
+
return { isValid: false, message: SHARED.VALIDATION_SELECT_DOCUMENT_TYPE };
|
|
2478
|
+
}
|
|
2479
|
+
// Check files
|
|
2480
|
+
if (uploadedFiles.length === 0) {
|
|
2481
|
+
return { isValid: false, message: SHARED.VALIDATION_UPLOAD_AT_LEAST_ONE };
|
|
2482
|
+
}
|
|
2483
|
+
// Check if all files are uploaded
|
|
2484
|
+
const incompleteFiles = uploadedFiles.filter(file => file.progress !== 100);
|
|
2485
|
+
if (incompleteFiles.length > 0) {
|
|
2486
|
+
return { isValid: false, message: SHARED.VALIDATION_WAIT_FOR_UPLOAD };
|
|
2450
2487
|
}
|
|
2488
|
+
// For Applicant type, check applicant selection
|
|
2489
|
+
if (assignmentType === SHARED.APPLICANT && !selectedApplicant) {
|
|
2490
|
+
return { isValid: false, message: SHARED.VALIDATION_SELECT_APPLICANT };
|
|
2491
|
+
}
|
|
2492
|
+
return { isValid: true, message: SHARED.VALIDATION_ALL_FIELDS_COMPLETED };
|
|
2493
|
+
}
|
|
2494
|
+
/**
|
|
2495
|
+
* Validates form data
|
|
2496
|
+
*/
|
|
2497
|
+
validateForm(assignmentType, selectedCategory, selectedDocumentType, selectedApplicant, uploadedFiles, categoryOptions, documentTypeOptions) {
|
|
2498
|
+
return this.validateFormData(assignmentType, selectedCategory, selectedDocumentType, selectedApplicant, uploadedFiles, categoryOptions, documentTypeOptions).isValid;
|
|
2451
2499
|
}
|
|
2452
2500
|
/**
|
|
2453
2501
|
* Checks if save button should be disabled
|
|
2454
2502
|
*/
|
|
2455
2503
|
isSaveButtonDisabled(assignmentType, selectedCategory, selectedDocumentType, selectedApplicant, uploadedFiles, isSaving) {
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
return !hasBasicData || !selectedApplicant || isSaving;
|
|
2504
|
+
if (isSaving) {
|
|
2505
|
+
return true;
|
|
2459
2506
|
}
|
|
2460
|
-
|
|
2461
|
-
|
|
2507
|
+
// For button state, we only need to check if required fields are filled
|
|
2508
|
+
// We don't need to validate if options are loaded
|
|
2509
|
+
if (!assignmentType) {
|
|
2510
|
+
return true;
|
|
2511
|
+
}
|
|
2512
|
+
if (!selectedCategory) {
|
|
2513
|
+
return true;
|
|
2514
|
+
}
|
|
2515
|
+
if (!selectedDocumentType) {
|
|
2516
|
+
return true;
|
|
2517
|
+
}
|
|
2518
|
+
if (uploadedFiles.length === 0) {
|
|
2519
|
+
return true;
|
|
2520
|
+
}
|
|
2521
|
+
// Check if all files are uploaded
|
|
2522
|
+
const incompleteFiles = uploadedFiles.filter(file => file.progress !== 100);
|
|
2523
|
+
if (incompleteFiles.length > 0) {
|
|
2524
|
+
return true;
|
|
2525
|
+
}
|
|
2526
|
+
// For Applicant type, check applicant selection
|
|
2527
|
+
if (assignmentType === SHARED.APPLICANT && !selectedApplicant) {
|
|
2528
|
+
return true;
|
|
2529
|
+
}
|
|
2530
|
+
return false; // Button should be enabled
|
|
2531
|
+
}
|
|
2532
|
+
/**
|
|
2533
|
+
* Validates the complete payload before save
|
|
2534
|
+
*/
|
|
2535
|
+
validatePayload(assignmentType, selectedCategory, selectedDocumentType, selectedApplicant, uploadedFiles) {
|
|
2536
|
+
// Check assignment type
|
|
2537
|
+
if (!assignmentType) {
|
|
2538
|
+
return { isValid: false, message: SHARED.VALIDATION_SELECT_ASSIGNMENT_TYPE };
|
|
2539
|
+
}
|
|
2540
|
+
// Check category
|
|
2541
|
+
if (!selectedCategory) {
|
|
2542
|
+
return { isValid: false, message: SHARED.VALIDATION_SELECT_CATEGORY };
|
|
2543
|
+
}
|
|
2544
|
+
// Check document type
|
|
2545
|
+
if (!selectedDocumentType) {
|
|
2546
|
+
return { isValid: false, message: SHARED.VALIDATION_SELECT_DOCUMENT_TYPE };
|
|
2547
|
+
}
|
|
2548
|
+
// Check files
|
|
2549
|
+
if (uploadedFiles.length === 0) {
|
|
2550
|
+
return { isValid: false, message: SHARED.VALIDATION_UPLOAD_AT_LEAST_ONE };
|
|
2551
|
+
}
|
|
2552
|
+
// Check if all files are uploaded
|
|
2553
|
+
const incompleteFiles = uploadedFiles.filter(file => file.progress !== 100);
|
|
2554
|
+
if (incompleteFiles.length > 0) {
|
|
2555
|
+
return { isValid: false, message: SHARED.VALIDATION_WAIT_FOR_UPLOAD };
|
|
2462
2556
|
}
|
|
2557
|
+
// For Applicant type, check applicant selection
|
|
2558
|
+
if (assignmentType === SHARED.APPLICANT && !selectedApplicant) {
|
|
2559
|
+
return { isValid: false, message: SHARED.VALIDATION_SELECT_APPLICANT };
|
|
2560
|
+
}
|
|
2561
|
+
return { isValid: true, message: SHARED.VALIDATION_ALL_FIELDS_COMPLETED };
|
|
2463
2562
|
}
|
|
2464
2563
|
/**
|
|
2465
2564
|
* Prepares upload payload
|
|
@@ -2473,11 +2572,15 @@ class DocumentUploadBusinessService {
|
|
|
2473
2572
|
documents: uploadedFiles.map(file => ({
|
|
2474
2573
|
fileName: file.file.name,
|
|
2475
2574
|
fileSize: file.file.size,
|
|
2476
|
-
|
|
2477
|
-
|
|
2575
|
+
url: file.url,
|
|
2576
|
+
contentType: file.contentType,
|
|
2478
2577
|
uploadedFileId: file.uploadResponse?.fileId || file.uploadResponse?.id || file.uploadResponse?.fileName
|
|
2479
2578
|
}))
|
|
2480
2579
|
};
|
|
2580
|
+
// For Applicant type, include the applicant ID
|
|
2581
|
+
if (assignmentType === SHARED.APPLICANT && selectedApplicant) {
|
|
2582
|
+
payload.applicantId = selectedApplicant;
|
|
2583
|
+
}
|
|
2481
2584
|
return payload;
|
|
2482
2585
|
}
|
|
2483
2586
|
/**
|
|
@@ -2507,10 +2610,10 @@ class DocumentUploadBusinessService {
|
|
|
2507
2610
|
*/
|
|
2508
2611
|
getInitialFormState() {
|
|
2509
2612
|
return {
|
|
2510
|
-
selectedAssignmentType:
|
|
2511
|
-
selectedApplicant:
|
|
2512
|
-
selectedCategory:
|
|
2513
|
-
selectedDocumentType:
|
|
2613
|
+
selectedAssignmentType: null,
|
|
2614
|
+
selectedApplicant: null,
|
|
2615
|
+
selectedCategory: null,
|
|
2616
|
+
selectedDocumentType: null,
|
|
2514
2617
|
uploadedFiles: [],
|
|
2515
2618
|
isFormValid: false
|
|
2516
2619
|
};
|
|
@@ -2568,32 +2671,65 @@ class DocumentUploadFormService {
|
|
|
2568
2671
|
});
|
|
2569
2672
|
}
|
|
2570
2673
|
/**
|
|
2571
|
-
*
|
|
2674
|
+
* Helper method to validate required fields and show appropriate messages
|
|
2572
2675
|
*/
|
|
2573
|
-
|
|
2676
|
+
validateRequiredFieldsWithMessages(assignmentType, selectedApplicant, selectedCategory, selectedDocumentType, uploadedFiles) {
|
|
2574
2677
|
if (assignmentType === 'Applicant' && !selectedApplicant) {
|
|
2575
|
-
|
|
2576
|
-
return false;
|
|
2678
|
+
return { isValid: false, field: 'applicant' };
|
|
2577
2679
|
}
|
|
2578
2680
|
if (!selectedCategory) {
|
|
2579
|
-
|
|
2580
|
-
return false;
|
|
2681
|
+
return { isValid: false, field: 'category' };
|
|
2581
2682
|
}
|
|
2582
2683
|
if (!selectedDocumentType) {
|
|
2583
|
-
|
|
2584
|
-
return false;
|
|
2684
|
+
return { isValid: false, field: 'documentType' };
|
|
2585
2685
|
}
|
|
2586
2686
|
if (uploadedFiles.length === 0) {
|
|
2587
|
-
|
|
2588
|
-
|
|
2687
|
+
return { isValid: false, field: 'documents' };
|
|
2688
|
+
}
|
|
2689
|
+
return { isValid: true, field: null };
|
|
2690
|
+
}
|
|
2691
|
+
/**
|
|
2692
|
+
* Validates required fields for upload
|
|
2693
|
+
*/
|
|
2694
|
+
validateRequiredFields(assignmentType, selectedApplicant, selectedCategory, selectedDocumentType, uploadedFiles) {
|
|
2695
|
+
const validation = this.validateRequiredFieldsWithMessages(assignmentType, selectedApplicant, selectedCategory, selectedDocumentType, uploadedFiles);
|
|
2696
|
+
if (!validation.isValid) {
|
|
2697
|
+
this.showValidationMessage(validation.field);
|
|
2698
|
+
}
|
|
2699
|
+
return validation.isValid;
|
|
2700
|
+
}
|
|
2701
|
+
/**
|
|
2702
|
+
* Shows appropriate validation message based on the field that failed
|
|
2703
|
+
*/
|
|
2704
|
+
showValidationMessage(field) {
|
|
2705
|
+
const messages = {
|
|
2706
|
+
applicant: {
|
|
2707
|
+
summary: SHARED.VALIDATION_NO_APPLICANT_SELECTED,
|
|
2708
|
+
detail: SHARED.VALIDATION_NO_APPLICANT_DETAIL
|
|
2709
|
+
},
|
|
2710
|
+
category: {
|
|
2711
|
+
summary: SHARED.VALIDATION_NO_CATEGORY_SELECTED,
|
|
2712
|
+
detail: SHARED.VALIDATION_NO_CATEGORY_DETAIL
|
|
2713
|
+
},
|
|
2714
|
+
documentType: {
|
|
2715
|
+
summary: SHARED.VALIDATION_NO_DOCUMENT_TYPE_SELECTED,
|
|
2716
|
+
detail: SHARED.VALIDATION_NO_DOCUMENT_TYPE_DETAIL
|
|
2717
|
+
},
|
|
2718
|
+
documents: {
|
|
2719
|
+
summary: SHARED.VALIDATION_NO_DOCUMENTS_UPLOADED,
|
|
2720
|
+
detail: SHARED.VALIDATION_NO_DOCUMENTS_DETAIL
|
|
2721
|
+
}
|
|
2722
|
+
};
|
|
2723
|
+
const message = messages[field];
|
|
2724
|
+
if (message) {
|
|
2725
|
+
this.showWarningMessage(message.summary, message.detail);
|
|
2589
2726
|
}
|
|
2590
|
-
return true;
|
|
2591
2727
|
}
|
|
2592
2728
|
/**
|
|
2593
2729
|
* Validates form completeness
|
|
2594
2730
|
*/
|
|
2595
2731
|
validateFormCompleteness() {
|
|
2596
|
-
this.showWarningMessage(
|
|
2732
|
+
this.showWarningMessage(SHARED.VALIDATION_FORM_INCOMPLETE, SHARED.VALIDATION_FORM_INCOMPLETE_DETAIL);
|
|
2597
2733
|
return false;
|
|
2598
2734
|
}
|
|
2599
2735
|
/**
|
|
@@ -2601,7 +2737,7 @@ class DocumentUploadFormService {
|
|
|
2601
2737
|
*/
|
|
2602
2738
|
validateContextId(contextId, message) {
|
|
2603
2739
|
if (!contextId) {
|
|
2604
|
-
this.showErrorMessage(
|
|
2740
|
+
this.showErrorMessage(SHARED.VALIDATION_MISSING_REQUIRED_DATA, message);
|
|
2605
2741
|
return false;
|
|
2606
2742
|
}
|
|
2607
2743
|
return true;
|
|
@@ -2671,6 +2807,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
2671
2807
|
}]
|
|
2672
2808
|
}], ctorParameters: () => [{ type: DocumentUploadBusinessService }, { type: DocumentUploadFormService }] });
|
|
2673
2809
|
|
|
2810
|
+
/**
|
|
2811
|
+
* Component responsible for handling document uploads with templated metadata.
|
|
2812
|
+
* Provides a comprehensive interface for uploading documents with assignment types,
|
|
2813
|
+
* categories, document types, and applicant selection.
|
|
2814
|
+
*/
|
|
2674
2815
|
class DocumentUploadComponent {
|
|
2675
2816
|
documentUpload;
|
|
2676
2817
|
uploadService;
|
|
@@ -2681,29 +2822,60 @@ class DocumentUploadComponent {
|
|
|
2681
2822
|
businessService;
|
|
2682
2823
|
formService;
|
|
2683
2824
|
dataService;
|
|
2825
|
+
/** The context ID for the document upload operation */
|
|
2684
2826
|
contextId = SHARED.EMPTY;
|
|
2827
|
+
/** Reference to the file upload component */
|
|
2685
2828
|
fileUploader;
|
|
2686
|
-
|
|
2829
|
+
/** Event emitted when form validation state changes */
|
|
2830
|
+
onFormValidationChange = new EventEmitter();
|
|
2831
|
+
/** Event emitted when upload is successful */
|
|
2832
|
+
onUploadSuccess = new EventEmitter();
|
|
2833
|
+
/** Currently selected assignment type (Applicant or Application) */
|
|
2687
2834
|
selectedAssignmentType = null;
|
|
2835
|
+
/** Currently selected applicant ID */
|
|
2688
2836
|
selectedApplicant = SHARED.EMPTY;
|
|
2837
|
+
/** Currently selected document category */
|
|
2689
2838
|
selectedCategory = SHARED.EMPTY;
|
|
2839
|
+
/** Currently selected document type */
|
|
2690
2840
|
selectedDocumentType = SHARED.EMPTY;
|
|
2691
|
-
|
|
2841
|
+
/** List of available applicants */
|
|
2692
2842
|
applicantList = SHARED.EMPTY_ARRAY;
|
|
2843
|
+
/** Filtered list of applicants based on current selection */
|
|
2693
2844
|
filteredApplicantList = SHARED.EMPTY_ARRAY;
|
|
2845
|
+
/** Available document categories for the selected assignment type */
|
|
2694
2846
|
categoryOptions = SHARED.EMPTY_ARRAY;
|
|
2847
|
+
/** Available document types for the selected category */
|
|
2695
2848
|
documentTypeOptions = SHARED.EMPTY_ARRAY;
|
|
2696
|
-
|
|
2849
|
+
/** Array of files that have been uploaded */
|
|
2697
2850
|
uploadedFiles = SHARED.EMPTY_ARRAY;
|
|
2851
|
+
/** Map tracking upload progress for each file */
|
|
2698
2852
|
fileProgress = new Map();
|
|
2699
|
-
|
|
2853
|
+
/** Loading state for applicants data */
|
|
2700
2854
|
isLoadingApplicants = false;
|
|
2855
|
+
/** Loading state for categories data */
|
|
2701
2856
|
isLoadingCategories = false;
|
|
2857
|
+
/** Loading state for document types data */
|
|
2702
2858
|
isLoadingDocumentTypes = false;
|
|
2859
|
+
/** Loading state for save operation */
|
|
2703
2860
|
isSaving = false;
|
|
2704
|
-
|
|
2861
|
+
/** Current form validation state */
|
|
2705
2862
|
isFormValid = false;
|
|
2863
|
+
/** File size property for testing */
|
|
2864
|
+
fileSize = '';
|
|
2865
|
+
/** Subject for managing component lifecycle and unsubscribing from observables */
|
|
2706
2866
|
destroy$ = new Subject();
|
|
2867
|
+
/**
|
|
2868
|
+
* Creates an instance of DocumentUploadComponent.
|
|
2869
|
+
* @param documentUpload - Service for handling document upload operations
|
|
2870
|
+
* @param uploadService - Service for document-related operations
|
|
2871
|
+
* @param config - PrimeNG configuration service
|
|
2872
|
+
* @param fileFormatService - Service for file format validation
|
|
2873
|
+
* @param messageService - Service for displaying messages
|
|
2874
|
+
* @param cdr - Change detector reference for manual change detection
|
|
2875
|
+
* @param businessService - Service for business logic operations
|
|
2876
|
+
* @param formService - Service for form validation and handling
|
|
2877
|
+
* @param dataService - Service for data loading operations
|
|
2878
|
+
*/
|
|
2707
2879
|
constructor(documentUpload, uploadService, config, fileFormatService, messageService, cdr, businessService, formService, dataService) {
|
|
2708
2880
|
this.documentUpload = documentUpload;
|
|
2709
2881
|
this.uploadService = uploadService;
|
|
@@ -2715,55 +2887,88 @@ class DocumentUploadComponent {
|
|
|
2715
2887
|
this.formService = formService;
|
|
2716
2888
|
this.dataService = dataService;
|
|
2717
2889
|
}
|
|
2718
|
-
|
|
2890
|
+
/**
|
|
2891
|
+
* Handles changes in assignment type selection.
|
|
2892
|
+
* Resets form selections, loads categories, and handles applicant loading.
|
|
2893
|
+
*/
|
|
2719
2894
|
onAssignmentTypeChange() {
|
|
2720
2895
|
this.resetSelections();
|
|
2721
2896
|
this.loadCategories();
|
|
2722
2897
|
this.handleApplicantLoading();
|
|
2898
|
+
this.validateForm(); // Validate form after assignment type change
|
|
2899
|
+
this.emitFormValidationChange();
|
|
2723
2900
|
}
|
|
2901
|
+
/**
|
|
2902
|
+
* Handles changes in category selection.
|
|
2903
|
+
* Resets document type and loads available document types if category is selected.
|
|
2904
|
+
*/
|
|
2724
2905
|
onCategoryChange() {
|
|
2725
2906
|
this.resetDocumentType();
|
|
2726
|
-
this.
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
this.validateForm();
|
|
2731
|
-
}
|
|
2732
|
-
onApplicantSelectionChange() {
|
|
2733
|
-
this.validateForm();
|
|
2907
|
+
if (this.selectedCategory)
|
|
2908
|
+
this.loadDocumentTypes();
|
|
2909
|
+
this.validateForm(); // Validate form after category change
|
|
2910
|
+
this.validateAndEmit();
|
|
2734
2911
|
}
|
|
2912
|
+
/**
|
|
2913
|
+
* Handles changes in document type selection.
|
|
2914
|
+
* Validates form and emits validation change event.
|
|
2915
|
+
*/
|
|
2916
|
+
onDocumentTypeChange() { this.validateAndEmit(); }
|
|
2917
|
+
/**
|
|
2918
|
+
* Handles changes in applicant selection.
|
|
2919
|
+
* Validates form and emits validation change event.
|
|
2920
|
+
*/
|
|
2921
|
+
onApplicantSelectionChange() { this.validateAndEmit(); }
|
|
2922
|
+
/**
|
|
2923
|
+
* Handles file selection from the file upload component.
|
|
2924
|
+
* Processes each selected file for templated upload.
|
|
2925
|
+
* @param event - Event containing the selected files
|
|
2926
|
+
*/
|
|
2735
2927
|
onSelectedFiles(event) {
|
|
2736
|
-
event.currentFiles.forEach(
|
|
2737
|
-
this.handleTemplatedUpload(file);
|
|
2738
|
-
});
|
|
2928
|
+
event.currentFiles.forEach(file => this.handleTemplatedUpload(file));
|
|
2739
2929
|
this.fileUploader.clear();
|
|
2740
2930
|
}
|
|
2741
|
-
|
|
2931
|
+
/**
|
|
2932
|
+
* Loads the list of applicants for the current context.
|
|
2933
|
+
* Sets loading state and handles success/error responses.
|
|
2934
|
+
*/
|
|
2742
2935
|
loadApplicants() {
|
|
2743
2936
|
this.isLoadingApplicants = true;
|
|
2744
|
-
this.dataService.loadApplicants(this.contextId, (applicants) => this.handleApplicantsLoaded(applicants), (error) => this.
|
|
2937
|
+
this.dataService.loadApplicants(this.contextId, (applicants) => this.handleApplicantsLoaded(applicants), (error) => this.handleError('Failed to Load Applicants', error, () => this.isLoadingApplicants = false)).pipe(takeUntil(this.destroy$)).subscribe({
|
|
2745
2938
|
next: (applicants) => this.handleApplicantsLoaded(applicants),
|
|
2746
|
-
error: (error) => this.
|
|
2939
|
+
error: (error) => this.handleError('Failed to Load Applicants', error, () => this.isLoadingApplicants = false)
|
|
2747
2940
|
});
|
|
2748
2941
|
}
|
|
2942
|
+
/**
|
|
2943
|
+
* Loads document categories based on the selected assignment type.
|
|
2944
|
+
* Sets loading state and handles success/error responses.
|
|
2945
|
+
*/
|
|
2749
2946
|
loadCategories() {
|
|
2750
2947
|
this.isLoadingCategories = true;
|
|
2751
|
-
this.dataService.loadCategories(this.selectedAssignmentType, (categories) => this.handleCategoriesLoaded(categories), (error) => this.
|
|
2948
|
+
this.dataService.loadCategories(this.selectedAssignmentType, (categories) => this.handleCategoriesLoaded(categories), (error) => this.handleError('Failed to Load Categories', error, () => this.isLoadingCategories = false)).pipe(takeUntil(this.destroy$)).subscribe({
|
|
2752
2949
|
next: (categories) => this.handleCategoriesLoaded(categories),
|
|
2753
|
-
error: (error) => this.
|
|
2950
|
+
error: (error) => this.handleError('Failed to Load Categories', error, () => this.isLoadingCategories = false)
|
|
2754
2951
|
});
|
|
2755
2952
|
}
|
|
2953
|
+
/**
|
|
2954
|
+
* Loads document types based on the selected category.
|
|
2955
|
+
* Sets loading state and handles success/error responses.
|
|
2956
|
+
*/
|
|
2756
2957
|
loadDocumentTypes() {
|
|
2757
2958
|
this.isLoadingDocumentTypes = true;
|
|
2758
|
-
this.dataService.loadDocumentTypes(this.selectedCategory, (documentTypes) => this.handleDocumentTypesLoaded(documentTypes), (error) => this.
|
|
2959
|
+
this.dataService.loadDocumentTypes(this.selectedCategory, (documentTypes) => this.handleDocumentTypesLoaded(documentTypes), (error) => this.handleError('Failed to Load Document Types', error, () => this.isLoadingDocumentTypes = false)).pipe(takeUntil(this.destroy$)).subscribe({
|
|
2759
2960
|
next: (documentTypes) => this.handleDocumentTypesLoaded(documentTypes),
|
|
2760
|
-
error: (error) => this.
|
|
2961
|
+
error: (error) => this.handleError('Failed to Load Document Types', error, () => this.isLoadingDocumentTypes = false)
|
|
2761
2962
|
});
|
|
2762
2963
|
}
|
|
2763
|
-
|
|
2964
|
+
/**
|
|
2965
|
+
* Saves the document upload with all metadata.
|
|
2966
|
+
* Validates payload and required fields before proceeding with upload.
|
|
2967
|
+
*/
|
|
2764
2968
|
saveDocumentUpload() {
|
|
2765
|
-
|
|
2766
|
-
|
|
2969
|
+
const payloadValidation = this.businessService.validatePayload(this.selectedAssignmentType, this.selectedCategory, this.selectedDocumentType, this.selectedApplicant, this.uploadedFiles);
|
|
2970
|
+
if (!payloadValidation.isValid) {
|
|
2971
|
+
this.formService.showWarningMessage('Incomplete Form', payloadValidation.message);
|
|
2767
2972
|
return;
|
|
2768
2973
|
}
|
|
2769
2974
|
if (!this.formService.validateRequiredFields(this.selectedAssignmentType, this.selectedApplicant, this.selectedCategory, this.selectedDocumentType, this.uploadedFiles))
|
|
@@ -2771,22 +2976,16 @@ class DocumentUploadComponent {
|
|
|
2771
2976
|
this.isSaving = true;
|
|
2772
2977
|
this.saveDocumentMetadata();
|
|
2773
2978
|
}
|
|
2979
|
+
/**
|
|
2980
|
+
* Handles templated upload for a single file.
|
|
2981
|
+
* Sets up progress tracking and upload listener for the file.
|
|
2982
|
+
* @param file - The file to be uploaded
|
|
2983
|
+
*/
|
|
2774
2984
|
handleTemplatedUpload(file) {
|
|
2775
|
-
if (!this.formService.validateContextId(this.contextId, 'Context ID is required for upload.'))
|
|
2985
|
+
if (!this.formService.validateContextId(this.contextId, 'Context ID is required for upload.'))
|
|
2776
2986
|
return;
|
|
2777
|
-
}
|
|
2778
2987
|
this.fileProgress.set(file, SHARED.UPLOAD_PROGRESS_10);
|
|
2779
|
-
this.
|
|
2780
|
-
if (uploadedFile === file) {
|
|
2781
|
-
this.fileProgress.set(file, SHARED.UPLOAD_PROGRESS_100);
|
|
2782
|
-
const uploadedFileObj = this.uploadedFiles.find(uf => uf.file === file);
|
|
2783
|
-
if (uploadedFileObj) {
|
|
2784
|
-
uploadedFileObj.uploadResponse = response;
|
|
2785
|
-
uploadedFileObj.progress = SHARED.UPLOAD_PROGRESS_100;
|
|
2786
|
-
}
|
|
2787
|
-
this.cdr.detectChanges();
|
|
2788
|
-
}
|
|
2789
|
-
});
|
|
2988
|
+
this.setupFileUploadListener(file);
|
|
2790
2989
|
this.documentUpload.handleTemplatedUpload(file, this.contextId);
|
|
2791
2990
|
const formattedSize = this.businessService.formatFileSize(file.size, this.config);
|
|
2792
2991
|
const uploadedFile = this.businessService.createUploadedFile(file, formattedSize);
|
|
@@ -2794,55 +2993,95 @@ class DocumentUploadComponent {
|
|
|
2794
2993
|
this.uploadedFiles.push(uploadedFile);
|
|
2795
2994
|
this.validateForm();
|
|
2796
2995
|
}
|
|
2996
|
+
/**
|
|
2997
|
+
* Removes a document from the uploaded files list.
|
|
2998
|
+
* Updates progress tracking and validates form.
|
|
2999
|
+
* @param file - The file to be removed
|
|
3000
|
+
* @param index - The index of the file in the uploaded files array
|
|
3001
|
+
*/
|
|
2797
3002
|
handleDocumentRemove(file, index) {
|
|
2798
3003
|
this.uploadedFiles.splice(index, 1);
|
|
2799
3004
|
this.fileProgress.delete(file);
|
|
2800
|
-
this.
|
|
3005
|
+
this.validateAndEmit();
|
|
2801
3006
|
this.cdr.detectChanges();
|
|
2802
3007
|
}
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
3008
|
+
/**
|
|
3009
|
+
* Utility method for file upload component integration.
|
|
3010
|
+
* @param event - The file upload event
|
|
3011
|
+
* @param callback - Callback function to execute
|
|
3012
|
+
*/
|
|
3013
|
+
choose(event, callback) { callback(); }
|
|
3014
|
+
/**
|
|
3015
|
+
* Triggers the file upload dialog.
|
|
3016
|
+
*/
|
|
3017
|
+
triggerFileUpload() { this.fileUploader.choose(); }
|
|
3018
|
+
/**
|
|
3019
|
+
* Determines if the save button should be disabled.
|
|
3020
|
+
* @returns True if the save button should be disabled, false otherwise
|
|
3021
|
+
*/
|
|
2810
3022
|
getSaveButtonDisabled() {
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
getProgress(file) {
|
|
2814
|
-
return this.fileProgress.get(file) || 0;
|
|
3023
|
+
const isDisabled = this.businessService.isSaveButtonDisabled(this.selectedAssignmentType, this.selectedCategory, this.selectedDocumentType, this.selectedApplicant, this.uploadedFiles, this.isSaving);
|
|
3024
|
+
return isDisabled;
|
|
2815
3025
|
}
|
|
3026
|
+
/**
|
|
3027
|
+
* Gets the upload progress for a specific file.
|
|
3028
|
+
* @param file - The file to get progress for
|
|
3029
|
+
* @returns The upload progress percentage (0-100)
|
|
3030
|
+
*/
|
|
3031
|
+
getProgress(file) { return this.fileProgress.get(file) || 0; }
|
|
3032
|
+
/**
|
|
3033
|
+
* Checks if a file is currently uploading.
|
|
3034
|
+
* @param file - The file to check
|
|
3035
|
+
* @returns True if the file is uploading, false otherwise
|
|
3036
|
+
*/
|
|
2816
3037
|
isFileUploading(file) {
|
|
2817
3038
|
const progress = this.fileProgress.get(file);
|
|
2818
3039
|
return progress !== undefined && progress > 0 && progress < SHARED.UPLOAD_PROGRESS_100;
|
|
2819
3040
|
}
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
3041
|
+
/**
|
|
3042
|
+
* Checks if a file has been successfully uploaded.
|
|
3043
|
+
* @param file - The file to check
|
|
3044
|
+
* @returns True if the file is uploaded, false otherwise
|
|
3045
|
+
*/
|
|
3046
|
+
isFileUploaded(file) { return this.fileProgress.get(file) === SHARED.UPLOAD_PROGRESS_100; }
|
|
3047
|
+
/**
|
|
3048
|
+
* Checks if a file upload encountered an error.
|
|
3049
|
+
* @param file - The file to check
|
|
3050
|
+
* @returns True if the file has an error, false otherwise
|
|
3051
|
+
*/
|
|
3052
|
+
isFileError(file) { return this.fileProgress.get(file) === -1; }
|
|
3053
|
+
/**
|
|
3054
|
+
* Resets the form to its initial state.
|
|
3055
|
+
* Clears all selections, uploaded files, and progress tracking.
|
|
3056
|
+
*/
|
|
2828
3057
|
resetForm() {
|
|
2829
3058
|
const initialState = this.businessService.getInitialFormState();
|
|
2830
3059
|
Object.assign(this, initialState);
|
|
2831
3060
|
this.fileProgress.clear();
|
|
2832
|
-
this.filteredApplicantList =
|
|
3061
|
+
this.filteredApplicantList = [];
|
|
3062
|
+
this.categoryOptions = [];
|
|
3063
|
+
this.documentTypeOptions = [];
|
|
2833
3064
|
this.cdr.detectChanges();
|
|
2834
3065
|
}
|
|
2835
|
-
|
|
3066
|
+
/**
|
|
3067
|
+
* Resets form selections (applicant, category, document type).
|
|
3068
|
+
* Clears document type options.
|
|
3069
|
+
*/
|
|
2836
3070
|
resetSelections() {
|
|
2837
|
-
this.selectedApplicant = SHARED.EMPTY;
|
|
2838
|
-
this.selectedCategory = SHARED.EMPTY;
|
|
2839
|
-
this.selectedDocumentType = SHARED.EMPTY;
|
|
3071
|
+
this.selectedApplicant = this.selectedCategory = this.selectedDocumentType = SHARED.EMPTY;
|
|
2840
3072
|
this.documentTypeOptions = SHARED.EMPTY_ARRAY;
|
|
2841
3073
|
}
|
|
3074
|
+
/**
|
|
3075
|
+
* Resets document type selection and clears document type options.
|
|
3076
|
+
*/
|
|
2842
3077
|
resetDocumentType() {
|
|
2843
3078
|
this.selectedDocumentType = SHARED.EMPTY;
|
|
2844
3079
|
this.documentTypeOptions = SHARED.EMPTY_ARRAY;
|
|
2845
3080
|
}
|
|
3081
|
+
/**
|
|
3082
|
+
* Handles applicant loading based on assignment type.
|
|
3083
|
+
* Loads applicants if type is 'Applicant', otherwise filters existing list.
|
|
3084
|
+
*/
|
|
2846
3085
|
handleApplicantLoading() {
|
|
2847
3086
|
if (this.selectedAssignmentType === SHARED.APPLICANT) {
|
|
2848
3087
|
this.loadApplicants();
|
|
@@ -2851,54 +3090,78 @@ class DocumentUploadComponent {
|
|
|
2851
3090
|
this.filterApplicants();
|
|
2852
3091
|
}
|
|
2853
3092
|
}
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
3093
|
+
/**
|
|
3094
|
+
* Handles successful loading of applicants data.
|
|
3095
|
+
* Updates applicant list, filters applicants, and validates form.
|
|
3096
|
+
* @param applicants - Array of loaded applicants
|
|
3097
|
+
*/
|
|
2859
3098
|
handleApplicantsLoaded(applicants) {
|
|
2860
3099
|
this.applicantList = applicants;
|
|
2861
3100
|
this.filterApplicants();
|
|
2862
3101
|
this.isLoadingApplicants = false;
|
|
2863
3102
|
this.validateForm();
|
|
2864
3103
|
}
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
3104
|
+
/**
|
|
3105
|
+
* Handles successful loading of categories data.
|
|
3106
|
+
* Updates category options and validates form.
|
|
3107
|
+
* @param categories - Array of loaded categories
|
|
3108
|
+
*/
|
|
2869
3109
|
handleCategoriesLoaded(categories) {
|
|
2870
3110
|
this.categoryOptions = categories;
|
|
2871
3111
|
this.isLoadingCategories = false;
|
|
2872
3112
|
this.validateForm();
|
|
2873
3113
|
}
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
3114
|
+
/**
|
|
3115
|
+
* Handles successful loading of document types data.
|
|
3116
|
+
* Updates document type options and validates form.
|
|
3117
|
+
* @param documentTypes - Array of loaded document types
|
|
3118
|
+
*/
|
|
2878
3119
|
handleDocumentTypesLoaded(documentTypes) {
|
|
2879
3120
|
this.documentTypeOptions = documentTypes;
|
|
2880
3121
|
this.isLoadingDocumentTypes = false;
|
|
2881
3122
|
this.validateForm();
|
|
2882
3123
|
}
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
3124
|
+
/**
|
|
3125
|
+
* Handles successful upload completion.
|
|
3126
|
+
* Resets form and emits upload success event.
|
|
3127
|
+
* @param response - The upload response from the server
|
|
3128
|
+
*/
|
|
2887
3129
|
handleUploadSuccess(response) {
|
|
2888
3130
|
this.isSaving = false;
|
|
2889
|
-
this.formService.showSuccessMessage('Upload Successful', 'Documents uploaded and saved successfully!');
|
|
2890
3131
|
this.resetForm();
|
|
3132
|
+
this.onUploadSuccess.emit();
|
|
2891
3133
|
}
|
|
3134
|
+
/**
|
|
3135
|
+
* Handles upload error.
|
|
3136
|
+
* Resets saving state.
|
|
3137
|
+
* @param error - The error that occurred during upload
|
|
3138
|
+
*/
|
|
2892
3139
|
handleUploadError(error) {
|
|
2893
3140
|
this.isSaving = false;
|
|
2894
|
-
this.formService.showErrorMessage('Upload Failed', error?.message || 'Failed to save document upload');
|
|
2895
3141
|
}
|
|
3142
|
+
/**
|
|
3143
|
+
* Filters applicants based on the selected assignment type.
|
|
3144
|
+
* Updates the filtered applicant list.
|
|
3145
|
+
*/
|
|
2896
3146
|
filterApplicants() {
|
|
2897
3147
|
this.filteredApplicantList = this.dataService.handleApplicantsLoaded(this.applicantList, this.selectedAssignmentType);
|
|
2898
3148
|
}
|
|
3149
|
+
/**
|
|
3150
|
+
* Validates the current form state.
|
|
3151
|
+
* Checks payload validation and emits form validation change if state changed.
|
|
3152
|
+
*/
|
|
2899
3153
|
validateForm() {
|
|
2900
|
-
|
|
3154
|
+
const payloadValidation = this.businessService.validatePayload(this.selectedAssignmentType, this.selectedCategory, this.selectedDocumentType, this.selectedApplicant, this.uploadedFiles);
|
|
3155
|
+
const previousValidationState = this.isFormValid;
|
|
3156
|
+
this.isFormValid = payloadValidation.isValid;
|
|
3157
|
+
if (previousValidationState !== this.isFormValid) {
|
|
3158
|
+
this.onFormValidationChange.emit();
|
|
3159
|
+
}
|
|
2901
3160
|
}
|
|
3161
|
+
/**
|
|
3162
|
+
* Saves document metadata to the server.
|
|
3163
|
+
* Prepares upload payload and calls business service to save.
|
|
3164
|
+
*/
|
|
2902
3165
|
saveDocumentMetadata() {
|
|
2903
3166
|
const contextId = this.selectedApplicant || this.contextId;
|
|
2904
3167
|
const payload = this.businessService.prepareUploadPayload(this.selectedAssignmentType, this.selectedCategory, this.selectedDocumentType, this.selectedApplicant, this.uploadedFiles, contextId);
|
|
@@ -2909,6 +3172,61 @@ class DocumentUploadComponent {
|
|
|
2909
3172
|
error: (error) => this.handleUploadError(error)
|
|
2910
3173
|
});
|
|
2911
3174
|
}
|
|
3175
|
+
/**
|
|
3176
|
+
* Sets up a listener for file upload completion.
|
|
3177
|
+
* Updates progress tracking and emits validation change when upload completes.
|
|
3178
|
+
* @param file - The file to monitor for upload completion
|
|
3179
|
+
*/
|
|
3180
|
+
setupFileUploadListener(file) {
|
|
3181
|
+
this.documentUpload.uploadCompleted.pipe(takeUntil(this.destroy$)).subscribe(({ file: uploadedFile, response }) => {
|
|
3182
|
+
if (uploadedFile === file) {
|
|
3183
|
+
this.fileProgress.set(file, SHARED.UPLOAD_PROGRESS_100);
|
|
3184
|
+
const uploadedFileObj = this.uploadedFiles.find(uf => uf.file === file);
|
|
3185
|
+
if (uploadedFileObj) {
|
|
3186
|
+
uploadedFileObj.uploadResponse = response;
|
|
3187
|
+
uploadedFileObj.progress = SHARED.UPLOAD_PROGRESS_100;
|
|
3188
|
+
uploadedFileObj.url = response?.url;
|
|
3189
|
+
uploadedFileObj.contentType = response?.contentType;
|
|
3190
|
+
}
|
|
3191
|
+
this.cdr.detectChanges();
|
|
3192
|
+
this.onFormValidationChange.emit();
|
|
3193
|
+
}
|
|
3194
|
+
});
|
|
3195
|
+
}
|
|
3196
|
+
/**
|
|
3197
|
+
* Handles errors during data loading operations.
|
|
3198
|
+
* Resets loading state and can be extended for error logging.
|
|
3199
|
+
* @param title - Error title for display
|
|
3200
|
+
* @param error - The error object
|
|
3201
|
+
* @param resetLoading - Callback to reset loading state
|
|
3202
|
+
*/
|
|
3203
|
+
handleError(title, error, resetLoading) {
|
|
3204
|
+
resetLoading();
|
|
3205
|
+
}
|
|
3206
|
+
/**
|
|
3207
|
+
* Validates form and emits validation change event.
|
|
3208
|
+
*/
|
|
3209
|
+
validateAndEmit() {
|
|
3210
|
+
this.validateForm();
|
|
3211
|
+
this.onFormValidationChange.emit();
|
|
3212
|
+
}
|
|
3213
|
+
/**
|
|
3214
|
+
* Emits form validation change event.
|
|
3215
|
+
*/
|
|
3216
|
+
emitFormValidationChange() {
|
|
3217
|
+
this.onFormValidationChange.emit();
|
|
3218
|
+
}
|
|
3219
|
+
/**
|
|
3220
|
+
* Formats file size for testing purposes.
|
|
3221
|
+
* @param size - The file size in bytes
|
|
3222
|
+
*/
|
|
3223
|
+
formatSize(size) {
|
|
3224
|
+
this.fileSize = this.businessService.formatFileSize(size, this.config);
|
|
3225
|
+
}
|
|
3226
|
+
/**
|
|
3227
|
+
* Lifecycle hook that is called when component is destroyed.
|
|
3228
|
+
* Cleans up subscriptions and destroys services.
|
|
3229
|
+
*/
|
|
2912
3230
|
ngOnDestroy() {
|
|
2913
3231
|
this.destroy$.next();
|
|
2914
3232
|
this.destroy$.complete();
|
|
@@ -2916,16 +3234,172 @@ class DocumentUploadComponent {
|
|
|
2916
3234
|
this.dataService.destroy();
|
|
2917
3235
|
}
|
|
2918
3236
|
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 });
|
|
2919
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DocumentUploadComponent, isStandalone: false, selector: "lib-document-upload", inputs: { contextId: "contextId" }, 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=\"true\" \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:70vh;overflow-y:auto}.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}}.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 });
|
|
3237
|
+
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=\"true\" \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}.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 });
|
|
2920
3238
|
}
|
|
2921
3239
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentUploadComponent, decorators: [{
|
|
2922
3240
|
type: Component,
|
|
2923
|
-
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=\"true\" \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:70vh;overflow-y:auto}.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}}.applicant-list{display:none}\n"] }]
|
|
3241
|
+
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=\"true\" \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}.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"] }]
|
|
2924
3242
|
}], ctorParameters: () => [{ type: DocumentUploadService }, { type: DocumentService }, { type: i3.PrimeNGConfig }, { type: FileFormatService }, { type: i3.MessageService }, { type: i0.ChangeDetectorRef }, { type: DocumentUploadBusinessService }, { type: DocumentUploadFormService }, { type: DocumentUploadDataService }], propDecorators: { contextId: [{
|
|
2925
3243
|
type: Input
|
|
2926
3244
|
}], fileUploader: [{
|
|
2927
3245
|
type: ViewChild,
|
|
2928
3246
|
args: ['fileUploader']
|
|
3247
|
+
}], onFormValidationChange: [{
|
|
3248
|
+
type: Output
|
|
3249
|
+
}], onUploadSuccess: [{
|
|
3250
|
+
type: Output
|
|
3251
|
+
}] } });
|
|
3252
|
+
|
|
3253
|
+
class SidebarComponent {
|
|
3254
|
+
visible = false;
|
|
3255
|
+
position = 'right';
|
|
3256
|
+
width = SHARED.WIDTH;
|
|
3257
|
+
title = SHARED.EMPTY;
|
|
3258
|
+
showCloseButton = true;
|
|
3259
|
+
modal = true;
|
|
3260
|
+
dismissible = true;
|
|
3261
|
+
closeOnEscape = true;
|
|
3262
|
+
baseZIndex = SHARED.BASEZINDEX;
|
|
3263
|
+
autoZIndex = true;
|
|
3264
|
+
styleClass = SHARED.EMPTY;
|
|
3265
|
+
appendTo = 'body';
|
|
3266
|
+
blockScroll = true;
|
|
3267
|
+
closeIcon = SHARED.CLOSE_ICON;
|
|
3268
|
+
showSaveButton = false;
|
|
3269
|
+
saveButtonText = SHARED.SAVE;
|
|
3270
|
+
saveButtonDisabled = false;
|
|
3271
|
+
successMessage = SHARED.SUCCESS_MESSAGE;
|
|
3272
|
+
errorMessage = SHARED.EMPTY;
|
|
3273
|
+
visibleChange = new EventEmitter();
|
|
3274
|
+
onShow = new EventEmitter();
|
|
3275
|
+
onHide = new EventEmitter();
|
|
3276
|
+
onSave = new EventEmitter();
|
|
3277
|
+
showSuccessMessage = false;
|
|
3278
|
+
showErrorMessage = false;
|
|
3279
|
+
/**
|
|
3280
|
+
* Opens the sidebar
|
|
3281
|
+
*/
|
|
3282
|
+
open() {
|
|
3283
|
+
this.visible = true;
|
|
3284
|
+
this.clearMessages();
|
|
3285
|
+
this.visibleChange.emit(this.visible);
|
|
3286
|
+
this.onShow.emit();
|
|
3287
|
+
}
|
|
3288
|
+
/**
|
|
3289
|
+
* Closes the sidebar
|
|
3290
|
+
*/
|
|
3291
|
+
close() {
|
|
3292
|
+
this.visible = false;
|
|
3293
|
+
this.clearMessages();
|
|
3294
|
+
this.visibleChange.emit(this.visible);
|
|
3295
|
+
this.onHide.emit();
|
|
3296
|
+
}
|
|
3297
|
+
/**
|
|
3298
|
+
* Toggles the sidebar visibility
|
|
3299
|
+
*/
|
|
3300
|
+
toggle() {
|
|
3301
|
+
this.visible = !this.visible;
|
|
3302
|
+
if (this.visible) {
|
|
3303
|
+
this.clearMessages();
|
|
3304
|
+
this.onShow.emit();
|
|
3305
|
+
}
|
|
3306
|
+
else {
|
|
3307
|
+
this.clearMessages();
|
|
3308
|
+
this.onHide.emit();
|
|
3309
|
+
}
|
|
3310
|
+
this.visibleChange.emit(this.visible);
|
|
3311
|
+
}
|
|
3312
|
+
/**
|
|
3313
|
+
* Handles the close button click
|
|
3314
|
+
*/
|
|
3315
|
+
onCloseClick() {
|
|
3316
|
+
this.close();
|
|
3317
|
+
}
|
|
3318
|
+
/**
|
|
3319
|
+
* Handles the mask click (when dismissible is true)
|
|
3320
|
+
*/
|
|
3321
|
+
onMaskClick() {
|
|
3322
|
+
if (this.dismissible) {
|
|
3323
|
+
this.close();
|
|
3324
|
+
}
|
|
3325
|
+
}
|
|
3326
|
+
/**
|
|
3327
|
+
* Shows success message and closes sidebar after delay
|
|
3328
|
+
*/
|
|
3329
|
+
showSuccess() {
|
|
3330
|
+
this.showSuccessMessage = true;
|
|
3331
|
+
this.showErrorMessage = false;
|
|
3332
|
+
setTimeout(() => {
|
|
3333
|
+
this.close();
|
|
3334
|
+
}, 2000);
|
|
3335
|
+
}
|
|
3336
|
+
/**
|
|
3337
|
+
* Shows error message
|
|
3338
|
+
*/
|
|
3339
|
+
showError(message) {
|
|
3340
|
+
this.showErrorMessage = true;
|
|
3341
|
+
this.showSuccessMessage = false;
|
|
3342
|
+
this.errorMessage = message || SHARED.EMPTY;
|
|
3343
|
+
}
|
|
3344
|
+
/**
|
|
3345
|
+
* Clears all messages
|
|
3346
|
+
*/
|
|
3347
|
+
clearMessages() {
|
|
3348
|
+
this.showSuccessMessage = false;
|
|
3349
|
+
this.showErrorMessage = false;
|
|
3350
|
+
}
|
|
3351
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3352
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: SidebarComponent, isStandalone: false, selector: "lib-sidebar", inputs: { visible: "visible", position: "position", width: "width", title: "title", showCloseButton: "showCloseButton", modal: "modal", dismissible: "dismissible", closeOnEscape: "closeOnEscape", baseZIndex: "baseZIndex", autoZIndex: "autoZIndex", styleClass: "styleClass", appendTo: "appendTo", blockScroll: "blockScroll", closeIcon: "closeIcon", showSaveButton: "showSaveButton", saveButtonText: "saveButtonText", saveButtonDisabled: "saveButtonDisabled", successMessage: "successMessage", errorMessage: "errorMessage" }, outputs: { visibleChange: "visibleChange", onShow: "onShow", onHide: "onHide", onSave: "onSave" }, ngImport: i0, template: "<p-sidebar \r\n [(visible)]=\"visible\"\r\n [position]=\"position\"\r\n [style]=\"{width: width}\"\r\n [modal]=\"modal\"\r\n [dismissible]=\"dismissible\"\r\n [closeOnEscape]=\"closeOnEscape\"\r\n [baseZIndex]=\"baseZIndex\"\r\n [autoZIndex]=\"autoZIndex\"\r\n [styleClass]=\"styleClass\"\r\n [appendTo]=\"appendTo\"\r\n [blockScroll]=\"blockScroll\"\r\n (visibleChange)=\"visibleChange.emit($event)\"\r\n (onShow)=\"onShow.emit()\"\r\n (onHide)=\"onHide.emit()\"\r\n \r\n>\r\n <ng-template pTemplate=\"header\" *ngIf=\"title || showCloseButton || showSaveButton\">\r\n <div class=\"sidebar-header\">\r\n <h3 *ngIf=\"title\" class=\"sidebar-title\">{{ title }}</h3>\r\n <div class=\"header-content\">\r\n <ng-content select=\"[header]\"></ng-content>\r\n \r\n <p-messages \r\n *ngIf=\"showSuccessMessage\"\r\n severity=\"success\"\r\n [closable]=\"false\"\r\n [style]=\"{'margin-bottom': '0.5rem'}\"\r\n class=\"ml-3\"\r\n >\r\n <ng-template pTemplate=\"message\">\r\n <span>{{ successMessage }}</span>\r\n </ng-template>\r\n </p-messages>\r\n <p-messages \r\n *ngIf=\"showErrorMessage\"\r\n severity=\"error\"\r\n [closable]=\"false\"\r\n [style]=\"{'margin-bottom': '0.5rem'}\"\r\n class=\"ml-3\"\r\n >\r\n <ng-template pTemplate=\"message\">\r\n <span>{{ errorMessage }}</span>\r\n </ng-template>\r\n </p-messages>\r\n\r\n <div class=\"header-actions mr-3\">\r\n \r\n <button \r\n *ngIf=\"showSaveButton\"\r\n pButton \r\n type=\"button\" \r\n [label]=\"saveButtonText\"\r\n [disabled]=\"saveButtonDisabled\"\r\n class=\"p-button-primary\"\r\n (click)=\"onSave.emit()\"\r\n ></button>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template pTemplate=\"content\">\r\n <div class=\"sidebar-content\">\r\n <ng-content></ng-content>\r\n </div>\r\n </ng-template>\r\n</p-sidebar>\r\n", styles: [":host{display:block}.sidebar-header{display:flex;justify-content:space-between;align-items:center;padding:0;width:100%}.sidebar-title{margin:0;font-size:1.25rem;font-weight:600;color:#212529;flex:1}.header-content{display:flex;align-items:center;gap:.5rem;justify-content:space-between;width:100%}.header-actions{display:flex;align-items:center;gap:.5rem;margin-left:auto;margin-right:0}.close-button{background:none;border:none;color:#6c757d;cursor:pointer;padding:.5rem;border-radius:.375rem;transition:all .2s ease;display:flex;align-items:center;justify-content:center;min-width:2rem;min-height:2rem;margin-right:.5rem}.close-button:hover{background-color:#e9ecef;color:#495057}.close-button:focus{outline:none;box-shadow:0 0 0 3px #0f8bfd4d}.close-button i{font-size:1rem}.sidebar-content{height:100%;overflow-y:auto;padding:0}::ng-deep .p-sidebar .p-sidebar-header{border-bottom:1px solid #e9ecef;margin-bottom:1rem;background-color:#f8f9fa}::ng-deep .p-sidebar .p-sidebar-content{padding:0 1.5rem 1.5rem;height:calc(100% - 80px);overflow-y:auto}::ng-deep .p-sidebar.p-sidebar-right .p-sidebar-content{padding-left:1.5rem;padding-right:1.5rem}::ng-deep .p-sidebar.p-sidebar-left .p-sidebar-content{padding-left:1.5rem;padding-right:1.5rem}@media (max-width: 768px){::ng-deep .p-sidebar{width:100%!important;max-width:100%!important}::ng-deep .p-sidebar .p-sidebar-header{padding:1rem 1rem 0}::ng-deep .p-sidebar .p-sidebar-content{padding:0 1rem 1rem}}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i4.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "component", type: i4$1.Sidebar, selector: "p-sidebar", inputs: ["appendTo", "blockScroll", "style", "styleClass", "ariaCloseLabel", "autoZIndex", "baseZIndex", "modal", "dismissible", "showCloseIcon", "closeOnEscape", "transitionOptions", "visible", "position", "fullScreen"], outputs: ["onShow", "onHide", "visibleChange"] }, { kind: "component", type: i5.Messages, selector: "p-messages", inputs: ["value", "closable", "style", "styleClass", "enableService", "key", "escape", "severity", "showTransitionOptions", "hideTransitionOptions"], outputs: ["valueChange", "onClose"] }] });
|
|
3353
|
+
}
|
|
3354
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SidebarComponent, decorators: [{
|
|
3355
|
+
type: Component,
|
|
3356
|
+
args: [{ selector: 'lib-sidebar', standalone: false, template: "<p-sidebar \r\n [(visible)]=\"visible\"\r\n [position]=\"position\"\r\n [style]=\"{width: width}\"\r\n [modal]=\"modal\"\r\n [dismissible]=\"dismissible\"\r\n [closeOnEscape]=\"closeOnEscape\"\r\n [baseZIndex]=\"baseZIndex\"\r\n [autoZIndex]=\"autoZIndex\"\r\n [styleClass]=\"styleClass\"\r\n [appendTo]=\"appendTo\"\r\n [blockScroll]=\"blockScroll\"\r\n (visibleChange)=\"visibleChange.emit($event)\"\r\n (onShow)=\"onShow.emit()\"\r\n (onHide)=\"onHide.emit()\"\r\n \r\n>\r\n <ng-template pTemplate=\"header\" *ngIf=\"title || showCloseButton || showSaveButton\">\r\n <div class=\"sidebar-header\">\r\n <h3 *ngIf=\"title\" class=\"sidebar-title\">{{ title }}</h3>\r\n <div class=\"header-content\">\r\n <ng-content select=\"[header]\"></ng-content>\r\n \r\n <p-messages \r\n *ngIf=\"showSuccessMessage\"\r\n severity=\"success\"\r\n [closable]=\"false\"\r\n [style]=\"{'margin-bottom': '0.5rem'}\"\r\n class=\"ml-3\"\r\n >\r\n <ng-template pTemplate=\"message\">\r\n <span>{{ successMessage }}</span>\r\n </ng-template>\r\n </p-messages>\r\n <p-messages \r\n *ngIf=\"showErrorMessage\"\r\n severity=\"error\"\r\n [closable]=\"false\"\r\n [style]=\"{'margin-bottom': '0.5rem'}\"\r\n class=\"ml-3\"\r\n >\r\n <ng-template pTemplate=\"message\">\r\n <span>{{ errorMessage }}</span>\r\n </ng-template>\r\n </p-messages>\r\n\r\n <div class=\"header-actions mr-3\">\r\n \r\n <button \r\n *ngIf=\"showSaveButton\"\r\n pButton \r\n type=\"button\" \r\n [label]=\"saveButtonText\"\r\n [disabled]=\"saveButtonDisabled\"\r\n class=\"p-button-primary\"\r\n (click)=\"onSave.emit()\"\r\n ></button>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template pTemplate=\"content\">\r\n <div class=\"sidebar-content\">\r\n <ng-content></ng-content>\r\n </div>\r\n </ng-template>\r\n</p-sidebar>\r\n", styles: [":host{display:block}.sidebar-header{display:flex;justify-content:space-between;align-items:center;padding:0;width:100%}.sidebar-title{margin:0;font-size:1.25rem;font-weight:600;color:#212529;flex:1}.header-content{display:flex;align-items:center;gap:.5rem;justify-content:space-between;width:100%}.header-actions{display:flex;align-items:center;gap:.5rem;margin-left:auto;margin-right:0}.close-button{background:none;border:none;color:#6c757d;cursor:pointer;padding:.5rem;border-radius:.375rem;transition:all .2s ease;display:flex;align-items:center;justify-content:center;min-width:2rem;min-height:2rem;margin-right:.5rem}.close-button:hover{background-color:#e9ecef;color:#495057}.close-button:focus{outline:none;box-shadow:0 0 0 3px #0f8bfd4d}.close-button i{font-size:1rem}.sidebar-content{height:100%;overflow-y:auto;padding:0}::ng-deep .p-sidebar .p-sidebar-header{border-bottom:1px solid #e9ecef;margin-bottom:1rem;background-color:#f8f9fa}::ng-deep .p-sidebar .p-sidebar-content{padding:0 1.5rem 1.5rem;height:calc(100% - 80px);overflow-y:auto}::ng-deep .p-sidebar.p-sidebar-right .p-sidebar-content{padding-left:1.5rem;padding-right:1.5rem}::ng-deep .p-sidebar.p-sidebar-left .p-sidebar-content{padding-left:1.5rem;padding-right:1.5rem}@media (max-width: 768px){::ng-deep .p-sidebar{width:100%!important;max-width:100%!important}::ng-deep .p-sidebar .p-sidebar-header{padding:1rem 1rem 0}::ng-deep .p-sidebar .p-sidebar-content{padding:0 1rem 1rem}}\n"] }]
|
|
3357
|
+
}], propDecorators: { visible: [{
|
|
3358
|
+
type: Input
|
|
3359
|
+
}], position: [{
|
|
3360
|
+
type: Input
|
|
3361
|
+
}], width: [{
|
|
3362
|
+
type: Input
|
|
3363
|
+
}], title: [{
|
|
3364
|
+
type: Input
|
|
3365
|
+
}], showCloseButton: [{
|
|
3366
|
+
type: Input
|
|
3367
|
+
}], modal: [{
|
|
3368
|
+
type: Input
|
|
3369
|
+
}], dismissible: [{
|
|
3370
|
+
type: Input
|
|
3371
|
+
}], closeOnEscape: [{
|
|
3372
|
+
type: Input
|
|
3373
|
+
}], baseZIndex: [{
|
|
3374
|
+
type: Input
|
|
3375
|
+
}], autoZIndex: [{
|
|
3376
|
+
type: Input
|
|
3377
|
+
}], styleClass: [{
|
|
3378
|
+
type: Input
|
|
3379
|
+
}], appendTo: [{
|
|
3380
|
+
type: Input
|
|
3381
|
+
}], blockScroll: [{
|
|
3382
|
+
type: Input
|
|
3383
|
+
}], closeIcon: [{
|
|
3384
|
+
type: Input
|
|
3385
|
+
}], showSaveButton: [{
|
|
3386
|
+
type: Input
|
|
3387
|
+
}], saveButtonText: [{
|
|
3388
|
+
type: Input
|
|
3389
|
+
}], saveButtonDisabled: [{
|
|
3390
|
+
type: Input
|
|
3391
|
+
}], successMessage: [{
|
|
3392
|
+
type: Input
|
|
3393
|
+
}], errorMessage: [{
|
|
3394
|
+
type: Input
|
|
3395
|
+
}], visibleChange: [{
|
|
3396
|
+
type: Output
|
|
3397
|
+
}], onShow: [{
|
|
3398
|
+
type: Output
|
|
3399
|
+
}], onHide: [{
|
|
3400
|
+
type: Output
|
|
3401
|
+
}], onSave: [{
|
|
3402
|
+
type: Output
|
|
2929
3403
|
}] } });
|
|
2930
3404
|
|
|
2931
3405
|
class UserListService {
|
|
@@ -3273,6 +3747,7 @@ class DocumentSearchComponent {
|
|
|
3273
3747
|
onActionClick = new EventEmitter();
|
|
3274
3748
|
searchTerm = SHARED.EMPTY;
|
|
3275
3749
|
destroy$ = new Subject();
|
|
3750
|
+
searchSubject = new Subject();
|
|
3276
3751
|
constructor(documentHelperService) {
|
|
3277
3752
|
this.documentHelperService = documentHelperService;
|
|
3278
3753
|
}
|
|
@@ -3315,134 +3790,18 @@ class DocumentSearchComponent {
|
|
|
3315
3790
|
this.searchTerm = SHARED.EMPTY;
|
|
3316
3791
|
this.documentHelperService.setSearchKey(null);
|
|
3317
3792
|
}
|
|
3318
|
-
searchSubject = new Subject();
|
|
3319
3793
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentSearchComponent, deps: [{ token: DocumentHelperService }], target: i0.ɵɵFactoryTarget.Component });
|
|
3320
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DocumentSearchComponent, isStandalone: false, selector: "document-search", inputs: { contextId: "contextId" }, outputs: { onActionClick: "onActionClick" }, ngImport: i0, template: "<div class=\"search-container\">\r\n <div class=\"search-input-wrapper\">\r\n <i class=\"pi pi-search search-icon\"></i>\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"searchTerm\"\r\n (ngModelChange)=\"onSearchInputChange($event)\"\r\n class=\"search-input\"\r\n placeholder=\"Search by document name, category, type, status or applicant name...\"\r\n [attr.aria-label]=\"'Search documents'\"\r\n />\r\n <button \r\n *ngIf=\"searchTerm\"\r\n type=\"button\"\r\n class=\"clear-button\"\r\n (click)=\"onClearSearch()\"\r\n [attr.aria-label]=\"'Clear search'\"\r\n >\r\n <i class=\"pi pi-times\"></i>\r\n </button>\r\n </div>\r\n \r\n <button \r\n type=\"button\"\r\n class=\"action-button\"\r\n (click)=\"onActionClick.emit()\"\r\n [attr.aria-label]=\"'Open actions menu'\"\r\n >\r\n Actions\r\n </button>\r\n</div> ", styles: [".search-container{display:flex;align-items:center;gap:1rem;width:100%;justify-content:space-between}.search-input-wrapper{position:relative;flex:1;display:flex;align-items:center;max-width:40%}.search-icon{position:absolute;left:12px;color:#6c757d;z-index:1}.search-input{width:100%;padding:12px 40px;border:1px solid #dee2e6;border-radius:8px;font-size:14px;outline:none;transition:border-color .2s ease,box-shadow .2s ease}.search-input:focus{border-color:#0f8bfd;box-shadow:0 0 0 3px #0f8bfd1a}.search-input::placeholder{color:#6c757d}.clear-button{position:absolute;right:12px;background:none;border:none;color:#6c757d;cursor:pointer;padding:4px;border-radius:4px;transition:background-color .2s ease,color .2s ease}.clear-button:hover{background-color:#f8f9fa;color:#495057}.action-button{background-color:#0f8bfd;color:#fff;border:none;padding:12px 24px;border-radius:8px;font-size:14px;font-weight:500;cursor:pointer;transition:background-color .2s ease,transform .1s ease;white-space:nowrap}.action-button:hover{background-color:#0d7ae6;transform:translateY(-1px)}.action-button:active{transform:translateY(0)}.action-button:focus{outline:none;box-shadow:0 0 0 3px #0f8bfd4d}@media (max-width: 768px){.search-container{flex-direction:column;gap:.75rem}.search-input-wrapper{max-width:100%}.action-button{width:100%;justify-content:center}}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { 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"] }] });
|
|
3794
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DocumentSearchComponent, isStandalone: false, selector: "document-search", inputs: { contextId: "contextId" }, outputs: { onActionClick: "onActionClick" }, ngImport: i0, template: "<div class=\"search-container\">\r\n <div class=\"search-input-wrapper\">\r\n <i class=\"pi pi-search search-icon\"></i>\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"searchTerm\"\r\n (ngModelChange)=\"onSearchInputChange($event)\"\r\n class=\"search-input\"\r\n placeholder=\"Search by document name, category, type, status or applicant name...\"\r\n [attr.aria-label]=\"'Search documents'\"\r\n />\r\n <button \r\n *ngIf=\"searchTerm\"\r\n type=\"button\"\r\n class=\"clear-button\"\r\n (click)=\"onClearSearch()\"\r\n [attr.aria-label]=\"'Clear search'\"\r\n >\r\n <i class=\"pi pi-times\"></i>\r\n </button>\r\n </div>\r\n \r\n <button \r\n type=\"button\"\r\n class=\"action-button\"\r\n (click)=\"onActionClick.emit()\"\r\n [attr.aria-label]=\"'Open actions menu'\"\r\n >\r\n Actions\r\n </button>\r\n</div> ", styles: [".search-container{display:flex;align-items:center;gap:1rem;width:100%;justify-content:space-between;padding:10px}.search-input-wrapper{position:relative;flex:1;display:flex;align-items:center;max-width:40%}.search-icon{position:absolute;left:12px;color:#6c757d;z-index:1}.search-input{width:100%;padding:12px 40px;border:1px solid #dee2e6;border-radius:8px;font-size:14px;outline:none;transition:border-color .2s ease,box-shadow .2s ease}.search-input:focus{border-color:#0f8bfd;box-shadow:0 0 0 3px #0f8bfd1a}.search-input::placeholder{color:#6c757d}.clear-button{position:absolute;right:12px;background:none;border:none;color:#6c757d;cursor:pointer;padding:4px;border-radius:4px;transition:background-color .2s ease,color .2s ease}.clear-button:hover{background-color:#f8f9fa;color:#495057}.action-button{background-color:#0f8bfd;color:#fff;border:none;padding:12px 24px;border-radius:8px;font-size:14px;font-weight:500;cursor:pointer;transition:background-color .2s ease,transform .1s ease;white-space:nowrap}.action-button:hover{background-color:#0d7ae6;transform:translateY(-1px)}.action-button:active{transform:translateY(0)}.action-button:focus{outline:none;box-shadow:0 0 0 3px #0f8bfd4d}@media (max-width: 768px){.search-container{flex-direction:column;gap:.75rem}.search-input-wrapper{max-width:100%}.action-button{width:100%;justify-content:center}}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { 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"] }] });
|
|
3321
3795
|
}
|
|
3322
3796
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentSearchComponent, decorators: [{
|
|
3323
3797
|
type: Component,
|
|
3324
|
-
args: [{ selector: 'document-search', standalone: false, template: "<div class=\"search-container\">\r\n <div class=\"search-input-wrapper\">\r\n <i class=\"pi pi-search search-icon\"></i>\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"searchTerm\"\r\n (ngModelChange)=\"onSearchInputChange($event)\"\r\n class=\"search-input\"\r\n placeholder=\"Search by document name, category, type, status or applicant name...\"\r\n [attr.aria-label]=\"'Search documents'\"\r\n />\r\n <button \r\n *ngIf=\"searchTerm\"\r\n type=\"button\"\r\n class=\"clear-button\"\r\n (click)=\"onClearSearch()\"\r\n [attr.aria-label]=\"'Clear search'\"\r\n >\r\n <i class=\"pi pi-times\"></i>\r\n </button>\r\n </div>\r\n \r\n <button \r\n type=\"button\"\r\n class=\"action-button\"\r\n (click)=\"onActionClick.emit()\"\r\n [attr.aria-label]=\"'Open actions menu'\"\r\n >\r\n Actions\r\n </button>\r\n</div> ", styles: [".search-container{display:flex;align-items:center;gap:1rem;width:100%;justify-content:space-between}.search-input-wrapper{position:relative;flex:1;display:flex;align-items:center;max-width:40%}.search-icon{position:absolute;left:12px;color:#6c757d;z-index:1}.search-input{width:100%;padding:12px 40px;border:1px solid #dee2e6;border-radius:8px;font-size:14px;outline:none;transition:border-color .2s ease,box-shadow .2s ease}.search-input:focus{border-color:#0f8bfd;box-shadow:0 0 0 3px #0f8bfd1a}.search-input::placeholder{color:#6c757d}.clear-button{position:absolute;right:12px;background:none;border:none;color:#6c757d;cursor:pointer;padding:4px;border-radius:4px;transition:background-color .2s ease,color .2s ease}.clear-button:hover{background-color:#f8f9fa;color:#495057}.action-button{background-color:#0f8bfd;color:#fff;border:none;padding:12px 24px;border-radius:8px;font-size:14px;font-weight:500;cursor:pointer;transition:background-color .2s ease,transform .1s ease;white-space:nowrap}.action-button:hover{background-color:#0d7ae6;transform:translateY(-1px)}.action-button:active{transform:translateY(0)}.action-button:focus{outline:none;box-shadow:0 0 0 3px #0f8bfd4d}@media (max-width: 768px){.search-container{flex-direction:column;gap:.75rem}.search-input-wrapper{max-width:100%}.action-button{width:100%;justify-content:center}}\n"] }]
|
|
3798
|
+
args: [{ selector: 'document-search', standalone: false, template: "<div class=\"search-container\">\r\n <div class=\"search-input-wrapper\">\r\n <i class=\"pi pi-search search-icon\"></i>\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"searchTerm\"\r\n (ngModelChange)=\"onSearchInputChange($event)\"\r\n class=\"search-input\"\r\n placeholder=\"Search by document name, category, type, status or applicant name...\"\r\n [attr.aria-label]=\"'Search documents'\"\r\n />\r\n <button \r\n *ngIf=\"searchTerm\"\r\n type=\"button\"\r\n class=\"clear-button\"\r\n (click)=\"onClearSearch()\"\r\n [attr.aria-label]=\"'Clear search'\"\r\n >\r\n <i class=\"pi pi-times\"></i>\r\n </button>\r\n </div>\r\n \r\n <button \r\n type=\"button\"\r\n class=\"action-button\"\r\n (click)=\"onActionClick.emit()\"\r\n [attr.aria-label]=\"'Open actions menu'\"\r\n >\r\n Actions\r\n </button>\r\n</div> ", styles: [".search-container{display:flex;align-items:center;gap:1rem;width:100%;justify-content:space-between;padding:10px}.search-input-wrapper{position:relative;flex:1;display:flex;align-items:center;max-width:40%}.search-icon{position:absolute;left:12px;color:#6c757d;z-index:1}.search-input{width:100%;padding:12px 40px;border:1px solid #dee2e6;border-radius:8px;font-size:14px;outline:none;transition:border-color .2s ease,box-shadow .2s ease}.search-input:focus{border-color:#0f8bfd;box-shadow:0 0 0 3px #0f8bfd1a}.search-input::placeholder{color:#6c757d}.clear-button{position:absolute;right:12px;background:none;border:none;color:#6c757d;cursor:pointer;padding:4px;border-radius:4px;transition:background-color .2s ease,color .2s ease}.clear-button:hover{background-color:#f8f9fa;color:#495057}.action-button{background-color:#0f8bfd;color:#fff;border:none;padding:12px 24px;border-radius:8px;font-size:14px;font-weight:500;cursor:pointer;transition:background-color .2s ease,transform .1s ease;white-space:nowrap}.action-button:hover{background-color:#0d7ae6;transform:translateY(-1px)}.action-button:active{transform:translateY(0)}.action-button:focus{outline:none;box-shadow:0 0 0 3px #0f8bfd4d}@media (max-width: 768px){.search-container{flex-direction:column;gap:.75rem}.search-input-wrapper{max-width:100%}.action-button{width:100%;justify-content:center}}\n"] }]
|
|
3325
3799
|
}], ctorParameters: () => [{ type: DocumentHelperService }], propDecorators: { contextId: [{
|
|
3326
3800
|
type: Input
|
|
3327
3801
|
}], onActionClick: [{
|
|
3328
3802
|
type: Output
|
|
3329
3803
|
}] } });
|
|
3330
3804
|
|
|
3331
|
-
class CommonSidebarComponent {
|
|
3332
|
-
visible = false;
|
|
3333
|
-
position = 'right';
|
|
3334
|
-
width = SHARED.WIDTH;
|
|
3335
|
-
title = SHARED.EMPTY;
|
|
3336
|
-
showCloseButton = true;
|
|
3337
|
-
modal = true;
|
|
3338
|
-
dismissible = true;
|
|
3339
|
-
closeOnEscape = true;
|
|
3340
|
-
baseZIndex = SHARED.BASEZINDEX;
|
|
3341
|
-
autoZIndex = true;
|
|
3342
|
-
styleClass = SHARED.EMPTY;
|
|
3343
|
-
appendTo = 'body';
|
|
3344
|
-
blockScroll = true;
|
|
3345
|
-
closeIcon = SHARED.CLOSE_ICON;
|
|
3346
|
-
showSaveButton = false;
|
|
3347
|
-
saveButtonText = SHARED.SAVE;
|
|
3348
|
-
saveButtonDisabled = false;
|
|
3349
|
-
visibleChange = new EventEmitter();
|
|
3350
|
-
onShow = new EventEmitter();
|
|
3351
|
-
onHide = new EventEmitter();
|
|
3352
|
-
onSave = new EventEmitter();
|
|
3353
|
-
/**
|
|
3354
|
-
* Opens the sidebar
|
|
3355
|
-
*/
|
|
3356
|
-
open() {
|
|
3357
|
-
this.visible = true;
|
|
3358
|
-
this.visibleChange.emit(this.visible);
|
|
3359
|
-
this.onShow.emit();
|
|
3360
|
-
}
|
|
3361
|
-
/**
|
|
3362
|
-
* Closes the sidebar
|
|
3363
|
-
*/
|
|
3364
|
-
close() {
|
|
3365
|
-
this.visible = false;
|
|
3366
|
-
this.visibleChange.emit(this.visible);
|
|
3367
|
-
this.onHide.emit();
|
|
3368
|
-
}
|
|
3369
|
-
/**
|
|
3370
|
-
* Toggles the sidebar visibility
|
|
3371
|
-
*/
|
|
3372
|
-
toggle() {
|
|
3373
|
-
this.visible = !this.visible;
|
|
3374
|
-
this.visibleChange.emit(this.visible);
|
|
3375
|
-
if (this.visible) {
|
|
3376
|
-
this.onShow.emit();
|
|
3377
|
-
}
|
|
3378
|
-
else {
|
|
3379
|
-
this.onHide.emit();
|
|
3380
|
-
}
|
|
3381
|
-
}
|
|
3382
|
-
/**
|
|
3383
|
-
* Handles the close button click
|
|
3384
|
-
*/
|
|
3385
|
-
onCloseClick() {
|
|
3386
|
-
this.close();
|
|
3387
|
-
}
|
|
3388
|
-
/**
|
|
3389
|
-
* Handles the mask click (when dismissible is true)
|
|
3390
|
-
*/
|
|
3391
|
-
onMaskClick() {
|
|
3392
|
-
if (this.dismissible) {
|
|
3393
|
-
this.close();
|
|
3394
|
-
}
|
|
3395
|
-
}
|
|
3396
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: CommonSidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3397
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: CommonSidebarComponent, isStandalone: false, selector: "lib-common-sidebar", inputs: { visible: "visible", position: "position", width: "width", title: "title", showCloseButton: "showCloseButton", modal: "modal", dismissible: "dismissible", closeOnEscape: "closeOnEscape", baseZIndex: "baseZIndex", autoZIndex: "autoZIndex", styleClass: "styleClass", appendTo: "appendTo", blockScroll: "blockScroll", closeIcon: "closeIcon", showSaveButton: "showSaveButton", saveButtonText: "saveButtonText", saveButtonDisabled: "saveButtonDisabled" }, outputs: { visibleChange: "visibleChange", onShow: "onShow", onHide: "onHide", onSave: "onSave" }, ngImport: i0, template: "<p-sidebar \r\n [(visible)]=\"visible\"\r\n [position]=\"position\"\r\n [style]=\"{width: width}\"\r\n [modal]=\"modal\"\r\n [dismissible]=\"dismissible\"\r\n [closeOnEscape]=\"closeOnEscape\"\r\n [baseZIndex]=\"baseZIndex\"\r\n [autoZIndex]=\"autoZIndex\"\r\n [styleClass]=\"styleClass\"\r\n [appendTo]=\"appendTo\"\r\n [blockScroll]=\"blockScroll\"\r\n (visibleChange)=\"visibleChange.emit($event)\"\r\n (onShow)=\"onShow.emit()\"\r\n (onHide)=\"onHide.emit()\"\r\n \r\n>\r\n <ng-template pTemplate=\"header\" *ngIf=\"title || showCloseButton || showSaveButton\">\r\n <div class=\"sidebar-header\">\r\n <h3 *ngIf=\"title\" class=\"sidebar-title\">{{ title }}</h3>\r\n <div class=\"header-content\">\r\n <ng-content select=\"[header]\"></ng-content>\r\n <div class=\"header-actions\">\r\n <button \r\n *ngIf=\"showSaveButton\"\r\n pButton \r\n type=\"button\" \r\n [label]=\"saveButtonText\"\r\n [disabled]=\"saveButtonDisabled\"\r\n class=\"p-button-primary\"\r\n (click)=\"onSave.emit()\"\r\n ></button>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template pTemplate=\"content\">\r\n <div class=\"sidebar-content\">\r\n <!-- Content projection slot -->\r\n <ng-content></ng-content>\r\n </div>\r\n </ng-template>\r\n</p-sidebar>\r\n", styles: [":host{display:block}.sidebar-header{display:flex;justify-content:space-between;align-items:center;padding:0;width:100%}.sidebar-title{margin:0;font-size:1.25rem;font-weight:600;color:#212529;flex:1}.header-content{display:flex;align-items:center;gap:.5rem;justify-content:space-between;width:100%}.header-actions{display:flex;align-items:center;gap:.5rem;margin-left:auto;margin-right:1rem}.close-button{background:none;border:none;color:#6c757d;cursor:pointer;padding:.5rem;border-radius:.375rem;transition:all .2s ease;display:flex;align-items:center;justify-content:center;min-width:2rem;min-height:2rem}.close-button:hover{background-color:#e9ecef;color:#495057}.close-button:focus{outline:none;box-shadow:0 0 0 3px #0f8bfd4d}.close-button i{font-size:1rem}.sidebar-content{height:100%;overflow-y:auto;padding:0}::ng-deep .p-sidebar .p-sidebar-header{border-bottom:1px solid #e9ecef;margin-bottom:1rem;background-color:#f8f9fa}::ng-deep .p-sidebar .p-sidebar-content{padding:0 1.5rem 1.5rem;height:calc(100% - 80px);overflow-y:auto}::ng-deep .p-sidebar.p-sidebar-right .p-sidebar-content{padding-left:1.5rem;padding-right:1.5rem}::ng-deep .p-sidebar.p-sidebar-left .p-sidebar-content{padding-left:1.5rem;padding-right:1.5rem}@media (max-width: 768px){::ng-deep .p-sidebar{width:100%!important;max-width:100%!important}::ng-deep .p-sidebar .p-sidebar-header{padding:1rem 1rem 0}::ng-deep .p-sidebar .p-sidebar-content{padding:0 1rem 1rem}}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i4.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "component", type: i4$1.Sidebar, selector: "p-sidebar", inputs: ["appendTo", "blockScroll", "style", "styleClass", "ariaCloseLabel", "autoZIndex", "baseZIndex", "modal", "dismissible", "showCloseIcon", "closeOnEscape", "transitionOptions", "visible", "position", "fullScreen"], outputs: ["onShow", "onHide", "visibleChange"] }] });
|
|
3398
|
-
}
|
|
3399
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: CommonSidebarComponent, decorators: [{
|
|
3400
|
-
type: Component,
|
|
3401
|
-
args: [{ selector: 'lib-common-sidebar', standalone: false, template: "<p-sidebar \r\n [(visible)]=\"visible\"\r\n [position]=\"position\"\r\n [style]=\"{width: width}\"\r\n [modal]=\"modal\"\r\n [dismissible]=\"dismissible\"\r\n [closeOnEscape]=\"closeOnEscape\"\r\n [baseZIndex]=\"baseZIndex\"\r\n [autoZIndex]=\"autoZIndex\"\r\n [styleClass]=\"styleClass\"\r\n [appendTo]=\"appendTo\"\r\n [blockScroll]=\"blockScroll\"\r\n (visibleChange)=\"visibleChange.emit($event)\"\r\n (onShow)=\"onShow.emit()\"\r\n (onHide)=\"onHide.emit()\"\r\n \r\n>\r\n <ng-template pTemplate=\"header\" *ngIf=\"title || showCloseButton || showSaveButton\">\r\n <div class=\"sidebar-header\">\r\n <h3 *ngIf=\"title\" class=\"sidebar-title\">{{ title }}</h3>\r\n <div class=\"header-content\">\r\n <ng-content select=\"[header]\"></ng-content>\r\n <div class=\"header-actions\">\r\n <button \r\n *ngIf=\"showSaveButton\"\r\n pButton \r\n type=\"button\" \r\n [label]=\"saveButtonText\"\r\n [disabled]=\"saveButtonDisabled\"\r\n class=\"p-button-primary\"\r\n (click)=\"onSave.emit()\"\r\n ></button>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template pTemplate=\"content\">\r\n <div class=\"sidebar-content\">\r\n <!-- Content projection slot -->\r\n <ng-content></ng-content>\r\n </div>\r\n </ng-template>\r\n</p-sidebar>\r\n", styles: [":host{display:block}.sidebar-header{display:flex;justify-content:space-between;align-items:center;padding:0;width:100%}.sidebar-title{margin:0;font-size:1.25rem;font-weight:600;color:#212529;flex:1}.header-content{display:flex;align-items:center;gap:.5rem;justify-content:space-between;width:100%}.header-actions{display:flex;align-items:center;gap:.5rem;margin-left:auto;margin-right:1rem}.close-button{background:none;border:none;color:#6c757d;cursor:pointer;padding:.5rem;border-radius:.375rem;transition:all .2s ease;display:flex;align-items:center;justify-content:center;min-width:2rem;min-height:2rem}.close-button:hover{background-color:#e9ecef;color:#495057}.close-button:focus{outline:none;box-shadow:0 0 0 3px #0f8bfd4d}.close-button i{font-size:1rem}.sidebar-content{height:100%;overflow-y:auto;padding:0}::ng-deep .p-sidebar .p-sidebar-header{border-bottom:1px solid #e9ecef;margin-bottom:1rem;background-color:#f8f9fa}::ng-deep .p-sidebar .p-sidebar-content{padding:0 1.5rem 1.5rem;height:calc(100% - 80px);overflow-y:auto}::ng-deep .p-sidebar.p-sidebar-right .p-sidebar-content{padding-left:1.5rem;padding-right:1.5rem}::ng-deep .p-sidebar.p-sidebar-left .p-sidebar-content{padding-left:1.5rem;padding-right:1.5rem}@media (max-width: 768px){::ng-deep .p-sidebar{width:100%!important;max-width:100%!important}::ng-deep .p-sidebar .p-sidebar-header{padding:1rem 1rem 0}::ng-deep .p-sidebar .p-sidebar-content{padding:0 1rem 1rem}}\n"] }]
|
|
3402
|
-
}], propDecorators: { visible: [{
|
|
3403
|
-
type: Input
|
|
3404
|
-
}], position: [{
|
|
3405
|
-
type: Input
|
|
3406
|
-
}], width: [{
|
|
3407
|
-
type: Input
|
|
3408
|
-
}], title: [{
|
|
3409
|
-
type: Input
|
|
3410
|
-
}], showCloseButton: [{
|
|
3411
|
-
type: Input
|
|
3412
|
-
}], modal: [{
|
|
3413
|
-
type: Input
|
|
3414
|
-
}], dismissible: [{
|
|
3415
|
-
type: Input
|
|
3416
|
-
}], closeOnEscape: [{
|
|
3417
|
-
type: Input
|
|
3418
|
-
}], baseZIndex: [{
|
|
3419
|
-
type: Input
|
|
3420
|
-
}], autoZIndex: [{
|
|
3421
|
-
type: Input
|
|
3422
|
-
}], styleClass: [{
|
|
3423
|
-
type: Input
|
|
3424
|
-
}], appendTo: [{
|
|
3425
|
-
type: Input
|
|
3426
|
-
}], blockScroll: [{
|
|
3427
|
-
type: Input
|
|
3428
|
-
}], closeIcon: [{
|
|
3429
|
-
type: Input
|
|
3430
|
-
}], showSaveButton: [{
|
|
3431
|
-
type: Input
|
|
3432
|
-
}], saveButtonText: [{
|
|
3433
|
-
type: Input
|
|
3434
|
-
}], saveButtonDisabled: [{
|
|
3435
|
-
type: Input
|
|
3436
|
-
}], visibleChange: [{
|
|
3437
|
-
type: Output
|
|
3438
|
-
}], onShow: [{
|
|
3439
|
-
type: Output
|
|
3440
|
-
}], onHide: [{
|
|
3441
|
-
type: Output
|
|
3442
|
-
}], onSave: [{
|
|
3443
|
-
type: Output
|
|
3444
|
-
}] } });
|
|
3445
|
-
|
|
3446
3805
|
/**
|
|
3447
3806
|
* The `FolderContainerComponent` is responsible for rendering a container
|
|
3448
3807
|
* that displays a list of documents and associated folder panel data.
|
|
@@ -3451,6 +3810,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
3451
3810
|
*/
|
|
3452
3811
|
class FolderContainerComponent {
|
|
3453
3812
|
documentQuery;
|
|
3813
|
+
documentHelperService;
|
|
3454
3814
|
/**
|
|
3455
3815
|
* A list of documents passed as input to the component.
|
|
3456
3816
|
* Represents the document data to be displayed in the folder container.
|
|
@@ -3497,12 +3857,17 @@ class FolderContainerComponent {
|
|
|
3497
3857
|
* Reference to the document upload component
|
|
3498
3858
|
*/
|
|
3499
3859
|
documentUploadComponent;
|
|
3860
|
+
/**
|
|
3861
|
+
* Reference to the sidebar component
|
|
3862
|
+
*/
|
|
3863
|
+
sidebarComponent;
|
|
3500
3864
|
/**
|
|
3501
3865
|
* Tracks whether the save button should be disabled
|
|
3502
3866
|
*/
|
|
3503
3867
|
isSaveButtonDisabled = false;
|
|
3504
|
-
constructor(documentQuery) {
|
|
3868
|
+
constructor(documentQuery, documentHelperService) {
|
|
3505
3869
|
this.documentQuery = documentQuery;
|
|
3870
|
+
this.documentHelperService = documentHelperService;
|
|
3506
3871
|
}
|
|
3507
3872
|
ngOnInit() {
|
|
3508
3873
|
this.documentQuery.selectShowUserList().subscribe(show => {
|
|
@@ -3524,6 +3889,12 @@ class FolderContainerComponent {
|
|
|
3524
3889
|
this.isSaveButtonDisabled = this.documentUploadComponent.getSaveButtonDisabled();
|
|
3525
3890
|
}
|
|
3526
3891
|
}
|
|
3892
|
+
/**
|
|
3893
|
+
* Handles form validation changes from the document upload component
|
|
3894
|
+
*/
|
|
3895
|
+
onFormValidationChange() {
|
|
3896
|
+
this.updateSaveButtonState();
|
|
3897
|
+
}
|
|
3527
3898
|
/**
|
|
3528
3899
|
* Opens the document upload sidebar
|
|
3529
3900
|
*/
|
|
@@ -3535,6 +3906,18 @@ class FolderContainerComponent {
|
|
|
3535
3906
|
*/
|
|
3536
3907
|
onDocumentUploadSidebarHide() {
|
|
3537
3908
|
this.isDocumentUploadSidebarOpen = false;
|
|
3909
|
+
if (this.documentUploadComponent) {
|
|
3910
|
+
this.documentUploadComponent.resetForm();
|
|
3911
|
+
}
|
|
3912
|
+
}
|
|
3913
|
+
/**
|
|
3914
|
+
* Handles the document upload sidebar close event (when close button is clicked or sidebar is dismissed)
|
|
3915
|
+
*/
|
|
3916
|
+
onDocumentUploadSidebarClose() {
|
|
3917
|
+
this.isDocumentUploadSidebarOpen = false;
|
|
3918
|
+
if (this.documentUploadComponent) {
|
|
3919
|
+
this.documentUploadComponent.resetForm();
|
|
3920
|
+
}
|
|
3538
3921
|
}
|
|
3539
3922
|
/**
|
|
3540
3923
|
* Handles the document upload save event
|
|
@@ -3545,8 +3928,26 @@ class FolderContainerComponent {
|
|
|
3545
3928
|
this.updateSaveButtonState();
|
|
3546
3929
|
}
|
|
3547
3930
|
}
|
|
3548
|
-
|
|
3549
|
-
|
|
3931
|
+
/**
|
|
3932
|
+
* Handles successful document upload and refreshes data
|
|
3933
|
+
*/
|
|
3934
|
+
onDocumentUploadSuccess() {
|
|
3935
|
+
this.documentHelperService.refreshAllDataWithCurrentFilters(this.contextId);
|
|
3936
|
+
if (this.sidebarComponent) {
|
|
3937
|
+
this.sidebarComponent.showSuccess();
|
|
3938
|
+
}
|
|
3939
|
+
}
|
|
3940
|
+
/**
|
|
3941
|
+
* Handles document upload error
|
|
3942
|
+
*/
|
|
3943
|
+
onDocumentUploadError(error) {
|
|
3944
|
+
if (this.sidebarComponent) {
|
|
3945
|
+
const errorMessage = error?.message || SHARED.UPLOAD_FAILED;
|
|
3946
|
+
this.sidebarComponent.showError(errorMessage);
|
|
3947
|
+
}
|
|
3948
|
+
}
|
|
3949
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FolderContainerComponent, deps: [{ token: DocumentQuery }, { token: DocumentHelperService }], target: i0.ɵɵFactoryTarget.Component });
|
|
3950
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: FolderContainerComponent, isStandalone: false, selector: "lib-folder-container", inputs: { documentList: "documentList", folderList: "folderList", contextId: "contextId", userList: "userList", statusData: "statusData", categories: "categories" }, viewQueries: [{ propertyName: "documentUploadComponent", first: true, predicate: DocumentUploadComponent, descendants: true }, { propertyName: "sidebarComponent", first: true, predicate: SidebarComponent, descendants: true }], ngImport: i0, template: "\r\n<document-search [contextId]=\"contextId\" (onActionClick)=\"openDocumentUploadSidebar()\"></document-search>\r\n<div class=\"user-list-wrapper\" [@slideInOut]=\"userListAnimationState\">\r\n <lib-user-list [userList]=\"userList\" [categories]=\"categories\"></lib-user-list>\r\n</div>\r\n<lib-document-status [contextId]=\"contextId\" [statusData]=\"statusData\"></lib-document-status>\r\n\r\n<!-- Document Upload Sidebar -->\r\n<lib-sidebar\r\n [(visible)]=\"isDocumentUploadSidebarOpen\"\r\n position=\"right\"\r\n width=\"600px\"\r\n title=\"Upload Documents\"\r\n [showCloseButton]=\"true\"\r\n [showSaveButton]=\"true\"\r\n [saveButtonText]=\"'Save'\"\r\n [saveButtonDisabled]=\"isSaveButtonDisabled\"\r\n [successMessage]=\"'Document Saved Successfully'\"\r\n [modal]=\"true\"\r\n [dismissible]=\"true\"\r\n [closeOnEscape]=\"true\"\r\n [blockScroll]=\"true\"\r\n (onHide)=\"onDocumentUploadSidebarHide()\"\r\n (onSave)=\"onDocumentUploadSave()\"\r\n (onClose)=\"onDocumentUploadSidebarClose()\"\r\n>\r\n <lib-document-upload \r\n [contextId]=\"contextId\" \r\n (onFormValidationChange)=\"onFormValidationChange()\" \r\n (onUploadSuccess)=\"onDocumentUploadSuccess()\"\r\n (onUploadError)=\"onDocumentUploadError($event)\"\r\n ></lib-document-upload>\r\n</lib-sidebar>", styles: [".user-list-wrapper{overflow:hidden;margin-bottom:1rem}.user-list-wrapper ::ng-deep *{transition:opacity .2s ease-in-out}.user-list-wrapper.ng-animating{pointer-events:none}::ng-deep lib-user-list{display:block;width:100%}\n"], dependencies: [{ kind: "component", type: DocumentUploadComponent, selector: "lib-document-upload", inputs: ["contextId"], outputs: ["onFormValidationChange", "onUploadSuccess"] }, { kind: "component", type: UserListComponent, selector: "lib-user-list", inputs: ["userList", "categories"], outputs: ["userSelected"] }, { kind: "component", type: DocumentStatusComponent, selector: "lib-document-status", inputs: ["contextId", "statusData"] }, { kind: "component", type: DocumentSearchComponent, selector: "document-search", inputs: ["contextId"], outputs: ["onActionClick"] }, { kind: "component", type: SidebarComponent, selector: "lib-sidebar", inputs: ["visible", "position", "width", "title", "showCloseButton", "modal", "dismissible", "closeOnEscape", "baseZIndex", "autoZIndex", "styleClass", "appendTo", "blockScroll", "closeIcon", "showSaveButton", "saveButtonText", "saveButtonDisabled", "successMessage", "errorMessage"], outputs: ["visibleChange", "onShow", "onHide", "onSave"] }], animations: [
|
|
3550
3951
|
trigger('slideInOut', [
|
|
3551
3952
|
state('visible', style({
|
|
3552
3953
|
height: '*',
|
|
@@ -3600,8 +4001,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
3600
4001
|
animate('300ms cubic-bezier(0.0, 0.0, 0.2, 1)')
|
|
3601
4002
|
])
|
|
3602
4003
|
])
|
|
3603
|
-
], template: "\r\n<document-search [contextId]=\"contextId\" (onActionClick)=\"openDocumentUploadSidebar()\"></document-search>\r\n<div class=\"user-list-wrapper\" [@slideInOut]=\"userListAnimationState\">\r\n <lib-user-list [userList]=\"userList\" [categories]=\"categories\"></lib-user-list>\r\n</div>\r\n<lib-document-status [contextId]=\"contextId\" [statusData]=\"statusData\"></lib-document-status>\r\n\r\n<!-- Document Upload Sidebar -->\r\n<lib-
|
|
3604
|
-
}], ctorParameters: () => [{ type: DocumentQuery }], propDecorators: { documentList: [{
|
|
4004
|
+
], template: "\r\n<document-search [contextId]=\"contextId\" (onActionClick)=\"openDocumentUploadSidebar()\"></document-search>\r\n<div class=\"user-list-wrapper\" [@slideInOut]=\"userListAnimationState\">\r\n <lib-user-list [userList]=\"userList\" [categories]=\"categories\"></lib-user-list>\r\n</div>\r\n<lib-document-status [contextId]=\"contextId\" [statusData]=\"statusData\"></lib-document-status>\r\n\r\n<!-- Document Upload Sidebar -->\r\n<lib-sidebar\r\n [(visible)]=\"isDocumentUploadSidebarOpen\"\r\n position=\"right\"\r\n width=\"600px\"\r\n title=\"Upload Documents\"\r\n [showCloseButton]=\"true\"\r\n [showSaveButton]=\"true\"\r\n [saveButtonText]=\"'Save'\"\r\n [saveButtonDisabled]=\"isSaveButtonDisabled\"\r\n [successMessage]=\"'Document Saved Successfully'\"\r\n [modal]=\"true\"\r\n [dismissible]=\"true\"\r\n [closeOnEscape]=\"true\"\r\n [blockScroll]=\"true\"\r\n (onHide)=\"onDocumentUploadSidebarHide()\"\r\n (onSave)=\"onDocumentUploadSave()\"\r\n (onClose)=\"onDocumentUploadSidebarClose()\"\r\n>\r\n <lib-document-upload \r\n [contextId]=\"contextId\" \r\n (onFormValidationChange)=\"onFormValidationChange()\" \r\n (onUploadSuccess)=\"onDocumentUploadSuccess()\"\r\n (onUploadError)=\"onDocumentUploadError($event)\"\r\n ></lib-document-upload>\r\n</lib-sidebar>", styles: [".user-list-wrapper{overflow:hidden;margin-bottom:1rem}.user-list-wrapper ::ng-deep *{transition:opacity .2s ease-in-out}.user-list-wrapper.ng-animating{pointer-events:none}::ng-deep lib-user-list{display:block;width:100%}\n"] }]
|
|
4005
|
+
}], ctorParameters: () => [{ type: DocumentQuery }, { type: DocumentHelperService }], propDecorators: { documentList: [{
|
|
3605
4006
|
type: Input
|
|
3606
4007
|
}], folderList: [{
|
|
3607
4008
|
type: Input
|
|
@@ -3616,6 +4017,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
3616
4017
|
}], documentUploadComponent: [{
|
|
3617
4018
|
type: ViewChild,
|
|
3618
4019
|
args: [DocumentUploadComponent]
|
|
4020
|
+
}], sidebarComponent: [{
|
|
4021
|
+
type: ViewChild,
|
|
4022
|
+
args: [SidebarComponent]
|
|
3619
4023
|
}] } });
|
|
3620
4024
|
|
|
3621
4025
|
/**
|
|
@@ -4081,7 +4485,7 @@ class TablePrimaryComponent {
|
|
|
4081
4485
|
this.rowClick.emit(rowData);
|
|
4082
4486
|
}
|
|
4083
4487
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: TablePrimaryComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4084
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: TablePrimaryComponent, isStandalone: false, selector: "lib-table-primary", inputs: { tableData: "tableData", showHeader: "showHeader", tableStyle: "tableStyle" }, outputs: { rowClick: "rowClick", deleteAction: "deleteAction" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"card\">\r\n <p-table [value]=\"processedData\" [tableStyle]=\"tableStyle\">\r\n <ng-template pTemplate=\"header\" *ngIf=\"showHeader\">\r\n <tr>\r\n <th *ngFor=\"let col of tableData.columns\" [style.width]=\"col.width\">\r\n {{ col.header }}\r\n </th>\r\n </tr>\r\n </ng-template>\r\n <ng-template pTemplate=\"body\" let-rowData>\r\n <tr (click)=\"onRowClick(rowData)\" class=\"clickable-row\">\r\n <td *ngFor=\"let col of tableData.columns\" [style.width]=\"col.width\">\r\n <!-- Document Cell -->\r\n <div *ngIf=\"col.type === SHARED.CELL_TYPE_DOCUMENT\" class=\"document-cell\">\r\n <div class=\"document-info\">\r\n <div class=\"document-icon\">\r\n <i [class]=\"SHARED.ICON_FILE_PDF\" *ngIf=\"rowData._isPdfFile\"></i>\r\n <i [class]=\"SHARED.ICON_IMAGE\" *ngIf=\"rowData._isImageFile\"></i>\r\n <i [class]=\"SHARED.ICON_FILE_EXCEL\" *ngIf=\"rowData._isExcelFile\"></i>\r\n <i [class]=\"SHARED.ICON_FILE\" *ngIf=\"rowData._isOtherFile\"></i>\r\n </div>\r\n <div class=\"document-details\">\r\n <div class=\"document-name\">{{ rowData.docName }}</div>\r\n <div class=\"file-info\">{{ rowData.fileName }} - {{ rowData.fileSize }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Status Cell -->\r\n \r\n <div *ngIf=\"col.type === SHARED.CELL_TYPE_STATUS\" class=\"status-cell\">\r\n <span class=\"status-pill\" [ngClass]=\"rowData._statusClass\">\r\n <i [class]=\"rowData._statusIcon\"></i>\r\n {{ rowData[col.field] }}\r\n </span>\r\n </div>\r\n\r\n <!-- Actions Cell -->\r\n <div *ngIf=\"col.type === SHARED.CELL_TYPE_ACTIONS\" class=\"actions-cell\">\r\n @if(rowData.isUploaded){\r\n <button pButton pRipple type=\"button\" [icon]=\"SHARED.ICON_DELETE\" \r\n class=\"p-button-text p-button-rounded\" \r\n [permission]=\"'documents-deleteDocumentByDocumentId'\"\r\n (click)=\"onActionClick($event, rowData)\">\r\n </button>\r\n } \r\n </div>\r\n\r\n <!-- Default Text Cell -->\r\n <div *ngIf=\"!col.type || col.type === SHARED.CELL_TYPE_TEXT\" class=\"text-cell\">\r\n {{ rowData[col.field] }}\r\n </div>\r\n </td>\r\n </tr>\r\n </ng-template>\r\n \r\n <!-- No Records Template -->\r\n <ng-template pTemplate=\"emptymessage\">\r\n <tr>\r\n <td [attr.colspan]=\"tableData.columns.length\" class=\"no-records-cell\">\r\n <div class=\"no-records-content\">\r\n <i class=\"pi pi-inbox\" style=\"font-size: 2rem; color: #6c757d;\"></i>\r\n <p class=\"no-records-text\">No records found</p>\r\n </div>\r\n </td>\r\n </tr>\r\n </ng-template>\r\n </p-table>\r\n</div>", styles: [".document-cell .document-info{display:flex;align-items:center;gap:.75rem;text-align:left}.document-cell .document-info .document-icon{width:40px;height:40px;background-color:#e3f2fd;border-radius:6px;display:flex;align-items:center;justify-content:center;color:#1976d2;font-size:1.25rem;flex-shrink:0}.document-cell .document-info .document-details{flex:1;min-width:0}.document-cell .document-info .document-details .document-name{font-weight:400;color:#334155;line-height:20px;font-size:14px;margin-bottom:.25rem;text-align:left;word-break:break-word}.document-cell .document-info .document-details .file-info{font-size:.75rem;color:#6c757d;text-align:left}.status-cell .status-pill{display:inline-flex;align-items:center;justify-content:center;gap:.375rem;padding:.375rem .75rem;border-radius:20px;font-size:.75rem;font-weight:500;white-space:nowrap;min-width:80px}.status-cell .status-pill i{font-size:.875rem}.status-cell .status-pill.status-pending{background-color:#f3f4f6;color:#6b7280}.status-cell .status-pill.status-approved{background-color:#d1fae5;color:#065f46}.status-cell .status-pill.status-alert{background-color:#fee2e2;color:#dc2626}.status-cell .status-pill.status-uploaded{background-color:#dbeafe;color:#1d4ed8}.status-cell .status-pill.status-reviewing{background-color:#fef3c7;color:#d97706}.status-cell .status-pill.status-rejected{background-color:#fee2e2;color:#dc2626}.actions-cell{text-align:left}.actions-cell .p-button{width:2rem;height:2rem;border-radius:50%;background-color:transparent;border:none;color:#6c757d}.actions-cell .p-button:hover{background-color:#f8f9fa;color:#495057}.text-cell{font-weight:500;color:#475569;font-size:14px;line-height:20px;text-align:left}.clickable-row{cursor:pointer;transition:background-color .2s ease}.clickable-row:hover{background-color:#f8f9fa!important}.clickable-row:active{background-color:#e9ecef!important}::ng-deep .p-datatable .p-datatable-wrapper{border:1px solid #E2E8F0;border-radius:10px}::ng-deep .p-datatable .p-datatable-thead>tr>th{background-color:#f8f9fa;border:none;border-bottom:1px solid #dee2e6;padding:1rem 1.5rem;font-weight:600;color:#64748b;font-size:.875rem;text-transform:capitalize;letter-spacing:.5px;text-align:left;border-radius:8px 8px 0 0}::ng-deep .p-datatable .p-datatable-thead>tr>th:first-child{border-top-left-radius:8px}::ng-deep .p-datatable .p-datatable-thead>tr>th:last-child{border-top-right-radius:8px}::ng-deep .p-datatable .p-datatable-tbody>tr{border-bottom:1px solid #f1f3f4}::ng-deep .p-datatable .p-datatable-tbody>tr:hover{background-color:#f8f9fa}::ng-deep .p-datatable .p-datatable-tbody>tr:last-child>td:first-child{border-bottom-left-radius:8px}::ng-deep .p-datatable .p-datatable-tbody>tr:last-child>td:last-child{border-bottom-right-radius:8px}::ng-deep .p-datatable .p-datatable-tbody>tr>td{border:none;padding:1rem 1.5rem;vertical-align:middle;text-align:left}.no-records-cell{text-align:center;padding:3rem 1.5rem!important;border:none}.no-records-cell .no-records-content{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1rem}.no-records-cell .no-records-content .no-records-text{margin:0;color:#6c757d;font-size:1rem;font-weight:500}\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: "component", type: i2$2.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "style", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "scrollDirection", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "responsive", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "autoLayout", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll", "virtualRowHeight"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i4.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "directive", type: i5.Ripple, selector: "[pRipple]" }, { kind: "directive", type: HasPermissionDirective, selector: "[permission]", inputs: ["permission"] }] });
|
|
4488
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: TablePrimaryComponent, isStandalone: false, selector: "lib-table-primary", inputs: { tableData: "tableData", showHeader: "showHeader", tableStyle: "tableStyle" }, outputs: { rowClick: "rowClick", deleteAction: "deleteAction" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"card\">\r\n <p-table [value]=\"processedData\" [tableStyle]=\"tableStyle\">\r\n <ng-template pTemplate=\"header\" *ngIf=\"showHeader\">\r\n <tr>\r\n <th *ngFor=\"let col of tableData.columns\" [style.width]=\"col.width\">\r\n {{ col.header }}\r\n </th>\r\n </tr>\r\n </ng-template>\r\n <ng-template pTemplate=\"body\" let-rowData>\r\n <tr (click)=\"onRowClick(rowData)\" class=\"clickable-row\">\r\n <td *ngFor=\"let col of tableData.columns\" [style.width]=\"col.width\">\r\n <!-- Document Cell -->\r\n <div *ngIf=\"col.type === SHARED.CELL_TYPE_DOCUMENT\" class=\"document-cell\">\r\n <div class=\"document-info\">\r\n <div class=\"document-icon\">\r\n <i [class]=\"SHARED.ICON_FILE_PDF\" *ngIf=\"rowData._isPdfFile\"></i>\r\n <i [class]=\"SHARED.ICON_IMAGE\" *ngIf=\"rowData._isImageFile\"></i>\r\n <i [class]=\"SHARED.ICON_FILE_EXCEL\" *ngIf=\"rowData._isExcelFile\"></i>\r\n <i [class]=\"SHARED.ICON_FILE\" *ngIf=\"rowData._isOtherFile\"></i>\r\n </div>\r\n <div class=\"document-details\">\r\n <div class=\"document-name\">{{ rowData.docName }}</div>\r\n <div class=\"file-info\">{{ rowData.fileName }} - {{ rowData.fileSize }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Status Cell -->\r\n \r\n <div *ngIf=\"col.type === SHARED.CELL_TYPE_STATUS\" class=\"status-cell\">\r\n <span class=\"status-pill\" [ngClass]=\"rowData._statusClass\">\r\n <i [class]=\"rowData._statusIcon\"></i>\r\n {{ rowData[col.field] }}\r\n </span>\r\n </div>\r\n\r\n <!-- Actions Cell -->\r\n <div *ngIf=\"col.type === SHARED.CELL_TYPE_ACTIONS\" class=\"actions-cell\">\r\n @if(rowData.isUploaded){\r\n <button pButton pRipple type=\"button\" [icon]=\"SHARED.ICON_DELETE\" \r\n class=\"p-button-text p-button-rounded\" \r\n [permission]=\"'documents-deleteDocumentByDocumentId'\"\r\n (click)=\"onActionClick($event, rowData)\">\r\n </button>\r\n } \r\n </div>\r\n\r\n <!-- Default Text Cell -->\r\n <div *ngIf=\"!col.type || col.type === SHARED.CELL_TYPE_TEXT\" class=\"text-cell\">\r\n {{ rowData[col.field] }}\r\n </div>\r\n </td>\r\n </tr>\r\n </ng-template>\r\n \r\n <!-- No Records Template -->\r\n <ng-template pTemplate=\"emptymessage\">\r\n <tr>\r\n <td [attr.colspan]=\"tableData.columns.length\" class=\"no-records-cell\">\r\n <div class=\"no-records-content\">\r\n <i class=\"pi pi-inbox\" style=\"font-size: 2rem; color: #6c757d;\"></i>\r\n <p class=\"no-records-text\">No records found</p>\r\n </div>\r\n </td>\r\n </tr>\r\n </ng-template>\r\n </p-table>\r\n</div>", styles: [".document-cell .document-info{display:flex;align-items:center;gap:.75rem;text-align:left}.document-cell .document-info .document-icon{width:40px;height:40px;background-color:#e3f2fd;border-radius:6px;display:flex;align-items:center;justify-content:center;color:#1976d2;font-size:1.25rem;flex-shrink:0}.document-cell .document-info .document-details{flex:1;min-width:0}.document-cell .document-info .document-details .document-name{font-weight:400;color:#334155;line-height:20px;font-size:14px;margin-bottom:.25rem;text-align:left;word-break:break-word}.document-cell .document-info .document-details .file-info{font-size:.75rem;color:#6c757d;text-align:left}.status-cell .status-pill{display:inline-flex;align-items:center;justify-content:center;gap:.375rem;padding:.375rem .75rem;border-radius:20px;font-size:.75rem;font-weight:500;white-space:nowrap;min-width:80px}.status-cell .status-pill i{font-size:.875rem}.status-cell .status-pill.status-pending{background-color:#f3f4f6;color:#6b7280}.status-cell .status-pill.status-approved{background-color:#d1fae5;color:#065f46}.status-cell .status-pill.status-alert{background-color:#fee2e2;color:#dc2626}.status-cell .status-pill.status-uploaded{background-color:#dbeafe;color:#1d4ed8}.status-cell .status-pill.status-reviewing{background-color:#fef3c7;color:#d97706}.status-cell .status-pill.status-rejected{background-color:#fee2e2;color:#dc2626}.actions-cell{text-align:left}.actions-cell .p-button{width:2rem;height:2rem;border-radius:50%;background-color:transparent;border:none;color:#6c757d}.actions-cell .p-button:hover{background-color:#f8f9fa;color:#495057}.text-cell{font-weight:500;color:#475569;font-size:14px;line-height:20px;text-align:left}.clickable-row{cursor:pointer;transition:background-color .2s ease}.clickable-row:hover{background-color:#f8f9fa!important}.clickable-row:active{background-color:#e9ecef!important}::ng-deep .p-datatable .p-datatable-wrapper{border:1px solid #E2E8F0;border-radius:10px}::ng-deep .p-datatable .p-datatable-thead>tr>th{background-color:#f8f9fa;border:none;border-bottom:1px solid #dee2e6;padding:1rem 1.5rem;font-weight:600;color:#64748b;font-size:.875rem;text-transform:capitalize;letter-spacing:.5px;text-align:left;border-radius:8px 8px 0 0}::ng-deep .p-datatable .p-datatable-thead>tr>th:first-child{border-top-left-radius:8px}::ng-deep .p-datatable .p-datatable-thead>tr>th:last-child{border-top-right-radius:8px}::ng-deep .p-datatable .p-datatable-tbody>tr{border-bottom:1px solid #f1f3f4}::ng-deep .p-datatable .p-datatable-tbody>tr:hover{background-color:#f8f9fa}::ng-deep .p-datatable .p-datatable-tbody>tr:last-child>td:first-child{border-bottom-left-radius:8px}::ng-deep .p-datatable .p-datatable-tbody>tr:last-child>td:last-child{border-bottom-right-radius:8px}::ng-deep .p-datatable .p-datatable-tbody>tr>td{border:none;padding:1rem 1.5rem;vertical-align:middle;text-align:left}.no-records-cell{text-align:center;padding:3rem 1.5rem!important;border:none}.no-records-cell .no-records-content{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1rem}.no-records-cell .no-records-content .no-records-text{margin:0;color:#6c757d;font-size:1rem;font-weight:500}\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: "component", type: i2$2.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "style", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "scrollDirection", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "responsive", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "autoLayout", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll", "virtualRowHeight"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i4.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "directive", type: i5$1.Ripple, selector: "[pRipple]" }, { kind: "directive", type: HasPermissionDirective, selector: "[permission]", inputs: ["permission"] }] });
|
|
4085
4489
|
}
|
|
4086
4490
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: TablePrimaryComponent, decorators: [{
|
|
4087
4491
|
type: Component,
|
|
@@ -4132,10 +4536,7 @@ class DocumentViewerService {
|
|
|
4132
4536
|
const alertData = this.getAlertData(document);
|
|
4133
4537
|
const documentStatus = this.calculateDocumentStatus(document);
|
|
4134
4538
|
const documentIsUploaded = this.calculateIsDocumentUploaded(document);
|
|
4135
|
-
this.documentStore.updateDocumentViewerState(document, undefined,
|
|
4136
|
-
undefined, // Keep existing showHistory
|
|
4137
|
-
undefined, // Keep existing loading
|
|
4138
|
-
documentStatus, documentIsUploaded, alertData);
|
|
4539
|
+
this.documentStore.updateDocumentViewerState(document, undefined, undefined, undefined, documentStatus, documentIsUploaded, alertData);
|
|
4139
4540
|
this.loadDocumentHistory(document._id);
|
|
4140
4541
|
}
|
|
4141
4542
|
/**
|
|
@@ -4147,15 +4548,10 @@ class DocumentViewerService {
|
|
|
4147
4548
|
this.documentHttpService.getDocumentHistory(documentId)
|
|
4148
4549
|
.subscribe({
|
|
4149
4550
|
next: (history) => {
|
|
4150
|
-
this.documentStore.updateDocumentViewerState(undefined,
|
|
4151
|
-
history, true // Show history
|
|
4152
|
-
);
|
|
4551
|
+
this.documentStore.updateDocumentViewerState(undefined, history, true);
|
|
4153
4552
|
},
|
|
4154
4553
|
error: (error) => {
|
|
4155
|
-
this.documentStore.updateDocumentViewerState(undefined,
|
|
4156
|
-
undefined, // Keep existing history
|
|
4157
|
-
false // Hide history
|
|
4158
|
-
);
|
|
4554
|
+
this.documentStore.updateDocumentViewerState(undefined, undefined, false);
|
|
4159
4555
|
}
|
|
4160
4556
|
});
|
|
4161
4557
|
}
|
|
@@ -4505,13 +4901,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
4505
4901
|
class DocumentHistoryService {
|
|
4506
4902
|
documentHistoryStyleService;
|
|
4507
4903
|
http;
|
|
4508
|
-
|
|
4509
|
-
appConfigService;
|
|
4510
|
-
constructor(documentHistoryStyleService, http, sessionService, appConfigService) {
|
|
4904
|
+
constructor(documentHistoryStyleService, http) {
|
|
4511
4905
|
this.documentHistoryStyleService = documentHistoryStyleService;
|
|
4512
4906
|
this.http = http;
|
|
4513
|
-
this.sessionService = sessionService;
|
|
4514
|
-
this.appConfigService = appConfigService;
|
|
4515
4907
|
}
|
|
4516
4908
|
/**
|
|
4517
4909
|
* Get the CSS class for accordion styling based on the section's label
|
|
@@ -4580,17 +4972,8 @@ class DocumentHistoryService {
|
|
|
4580
4972
|
console.warn(ERRORS.NO_DOCUMENT_URL);
|
|
4581
4973
|
return;
|
|
4582
4974
|
}
|
|
4583
|
-
|
|
4584
|
-
const fullUrl = this.getFullUrl(documentUrl);
|
|
4585
|
-
console.log('Downloading document:', { originalUrl: documentUrl, fullUrl, docName });
|
|
4586
|
-
// Let the HTTP interceptor handle authentication - no need to add headers manually
|
|
4587
|
-
const httpOptions = {
|
|
4588
|
-
responseType: 'blob'
|
|
4589
|
-
};
|
|
4590
|
-
console.log('HTTP options being sent (interceptor will add auth):', httpOptions);
|
|
4591
|
-
this.http.get(fullUrl, httpOptions).subscribe({
|
|
4975
|
+
this.http.get(documentUrl, { responseType: 'blob' }).subscribe({
|
|
4592
4976
|
next: (blob) => {
|
|
4593
|
-
console.log('Download successful, blob size:', blob.size);
|
|
4594
4977
|
const blobUrl = window.URL.createObjectURL(blob);
|
|
4595
4978
|
const a = document.createElement('a');
|
|
4596
4979
|
a.href = blobUrl;
|
|
@@ -4602,75 +4985,11 @@ class DocumentHistoryService {
|
|
|
4602
4985
|
window.URL.revokeObjectURL(blobUrl);
|
|
4603
4986
|
},
|
|
4604
4987
|
error: (err) => {
|
|
4605
|
-
console.error('Download failed:', err);
|
|
4606
4988
|
console.error(ERRORS.DOWNLOAD_FAIL, err);
|
|
4607
4989
|
}
|
|
4608
4990
|
});
|
|
4609
4991
|
}
|
|
4610
|
-
|
|
4611
|
-
* Get the full URL for the document, handling relative URLs
|
|
4612
|
-
* @private
|
|
4613
|
-
* @param documentUrl - The document URL (can be relative or absolute)
|
|
4614
|
-
* @returns {string} The full URL
|
|
4615
|
-
*/
|
|
4616
|
-
getFullUrl(documentUrl) {
|
|
4617
|
-
// If it's already an absolute URL, return as is
|
|
4618
|
-
if (documentUrl.startsWith('http://') || documentUrl.startsWith('https://')) {
|
|
4619
|
-
return documentUrl;
|
|
4620
|
-
}
|
|
4621
|
-
// If it's a relative URL, try to get the API base URL
|
|
4622
|
-
try {
|
|
4623
|
-
const apiBaseUrl = this.appConfigService.apiBaseUrl;
|
|
4624
|
-
if (apiBaseUrl) {
|
|
4625
|
-
// Remove leading slash from documentUrl if present
|
|
4626
|
-
const cleanUrl = documentUrl.startsWith('/') ? documentUrl.substring(1) : documentUrl;
|
|
4627
|
-
return `${apiBaseUrl}/${cleanUrl}`;
|
|
4628
|
-
}
|
|
4629
|
-
}
|
|
4630
|
-
catch (error) {
|
|
4631
|
-
console.warn('Could not get API base URL, using original URL:', error);
|
|
4632
|
-
}
|
|
4633
|
-
// Fallback to original URL
|
|
4634
|
-
return documentUrl;
|
|
4635
|
-
}
|
|
4636
|
-
/**
|
|
4637
|
-
* Debug method to help identify issues when the library is used in the main project
|
|
4638
|
-
* @public
|
|
4639
|
-
*/
|
|
4640
|
-
debugEnvironment() {
|
|
4641
|
-
console.log('=== Document History Service Environment Debug ===');
|
|
4642
|
-
// Check session data
|
|
4643
|
-
const sessionData = this.sessionService.getUserSession();
|
|
4644
|
-
console.log('Session data:', sessionData);
|
|
4645
|
-
// Check localStorage for common token patterns
|
|
4646
|
-
const localStorageKeys = ['token', 'accessToken', 'authToken', 'jwt', 'userData'];
|
|
4647
|
-
const localStorageData = {};
|
|
4648
|
-
localStorageKeys.forEach(key => {
|
|
4649
|
-
const value = localStorage.getItem(key);
|
|
4650
|
-
if (value) {
|
|
4651
|
-
try {
|
|
4652
|
-
localStorageData[key] = JSON.parse(value);
|
|
4653
|
-
}
|
|
4654
|
-
catch {
|
|
4655
|
-
localStorageData[key] = value;
|
|
4656
|
-
}
|
|
4657
|
-
}
|
|
4658
|
-
});
|
|
4659
|
-
console.log('LocalStorage data:', localStorageData);
|
|
4660
|
-
// Check API configuration
|
|
4661
|
-
try {
|
|
4662
|
-
const apiBaseUrl = this.appConfigService.apiBaseUrl;
|
|
4663
|
-
console.log('API Base URL:', apiBaseUrl);
|
|
4664
|
-
}
|
|
4665
|
-
catch (error) {
|
|
4666
|
-
console.log('API Base URL error:', error);
|
|
4667
|
-
}
|
|
4668
|
-
// Check if we're in a browser environment
|
|
4669
|
-
console.log('User Agent:', navigator.userAgent);
|
|
4670
|
-
console.log('Window location:', window.location.href);
|
|
4671
|
-
console.log('=== End Debug ===');
|
|
4672
|
-
}
|
|
4673
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentHistoryService, deps: [{ token: DocumentHistoryStyleService }, { token: i2.HttpClient }, { token: SessionService }, { token: AppConfigService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
4992
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentHistoryService, deps: [{ token: DocumentHistoryStyleService }, { token: i2.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
4674
4993
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentHistoryService, providedIn: 'root' });
|
|
4675
4994
|
}
|
|
4676
4995
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentHistoryService, decorators: [{
|
|
@@ -4678,7 +4997,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
4678
4997
|
args: [{
|
|
4679
4998
|
providedIn: 'root'
|
|
4680
4999
|
}]
|
|
4681
|
-
}], ctorParameters: () => [{ type: DocumentHistoryStyleService }, { type: i2.HttpClient }
|
|
5000
|
+
}], ctorParameters: () => [{ type: DocumentHistoryStyleService }, { type: i2.HttpClient }] });
|
|
4682
5001
|
|
|
4683
5002
|
/**
|
|
4684
5003
|
* Component for displaying document history in a timeline format.
|
|
@@ -4946,7 +5265,7 @@ class DocumentActionsComponent {
|
|
|
4946
5265
|
this.rejectNote = SHARED.EMPTY;
|
|
4947
5266
|
}
|
|
4948
5267
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentActionsComponent, deps: [{ token: DocumentActionsService }], target: i0.ɵɵFactoryTarget.Component });
|
|
4949
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: DocumentActionsComponent, isStandalone: false, selector: "document-actions", inputs: { document: "document", documentId: "documentId", currentStatus: "currentStatus", isLoading: "isLoading", isUploaded: "isUploaded", statusId: "statusId" }, outputs: { actionPerformed: "actionPerformed" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"document-actions-container\" >\r\n <div class=\"actions-card\" [ngClass]=\"cardClass\">\r\n <div class=\"actions-buttons\">\r\n <!-- Reject Button -->\r\n <button *ngIf=\"!document?.isUploaded\" class=\"action-btn reject-btn\" [ngClass]=\"rejectButtonClass\" (click)=\"onRejectClick()\"\r\n [disabled]=\"currentStatus === SHARED.STATUS_REJECTED_LOWERCASE || isRejecting\">\r\n <i class=\"pi pi-times\" *ngIf=\"currentStatus === SHARED.STATUS_REJECTED_LOWERCASE\"></i>\r\n <i class=\"pi pi-spin pi-spinner\" *ngIf=\"isRejecting\"></i>\r\n <span>{{ currentStatus === SHARED.STATUS_REJECTED_LOWERCASE ? SHARED.BUTTON_LABEL_REJECTED :\r\n SHARED.BUTTON_LABEL_REJECT }}</span>\r\n </button>\r\n\r\n <!-- Accept Button -->\r\n <button *ngIf=\"!document?.isUploaded\" class=\"action-btn accept-btn\" [ngClass]=\"acceptButtonClass\" (click)=\"onAcceptClick()\"\r\n [disabled]=\"currentStatus === SHARED.STATUS_ACCEPTED || isAccepting\">\r\n <i class=\"pi pi-check\" *ngIf=\"currentStatus === SHARED.STATUS_ACCEPTED\"></i>\r\n <i class=\"pi pi-spin pi-spinner\" *ngIf=\"isAccepting\"></i>\r\n <span>{{ currentStatus === SHARED.STATUS_ACCEPTED ? SHARED.BUTTON_LABEL_ACCEPTED : SHARED.BUTTON_LABEL_ACCEPT\r\n }}</span>\r\n </button>\r\n\r\n <!-- Delete Button -->\r\n @if(document?.isUploaded){\r\n <button class=\"action-btn delete-btn\" (click)=\"onDeleteClick()\" [disabled]=\"isLoading\"\r\n [permission]=\"'documents-deleteDocumentByDocumentId'\" pTooltip=\"Delete Document\" tooltipPosition=\"top\">\r\n <i class=\"pi pi-trash\"></i>\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Accept Confirmation Dialog -->\r\n<p-dialog [(visible)]=\"showAcceptDialog\" [header]=\"SHARED.ACCEPT_CONFIRM_HEADER\" [modal]=\"true\" [draggable]=\"false\"\r\n [closable]=\"true\" [style]=\"{ width: '25rem', height: '25rem' }\" styleClass=\"confirmation-dialog\">\r\n <div class=\"dialog-content\">\r\n <label for=\"acceptNote\" class=\"note-label\">{{ SHARED.ACCEPT_NOTE_LABEL }}</label>\r\n <textarea id=\"acceptNote\" pInputTextarea [(ngModel)]=\"acceptNote\" [placeholder]=\"SHARED.ACCEPT_NOTE_PLACEHOLDER\"\r\n rows=\"6\" class=\"note-textarea\">\r\n </textarea>\r\n </div>\r\n <ng-template pTemplate=\"footer\">\r\n <div class=\"dialog-footer\">\r\n <button pButton [label]=\"SHARED.CANCEL_BUTTON_LABEL\" class=\"p-button-secondary\" (click)=\"onCancel()\">\r\n </button>\r\n <button pButton [label]=\"SHARED.ACCEPT_BUTTON_LABEL\" class=\"p-button-success\" (click)=\"onAcceptConfirm()\">\r\n </button>\r\n </div>\r\n </ng-template>\r\n</p-dialog>\r\n\r\n<!-- Reject Confirmation Dialog -->\r\n<p-dialog [(visible)]=\"showRejectDialog\" [header]=\"SHARED.REJECT_CONFIRM_HEADER\" [modal]=\"true\" [draggable]=\"false\"\r\n [closable]=\"true\" [style]=\"{ width: '25rem', height: '25rem' }\" styleClass=\"confirmation-dialog\">\r\n <div class=\"dialog-content\">\r\n <label for=\"rejectNote\" class=\"note-label\">{{ SHARED.REJECT_NOTE_LABEL }}</label>\r\n <textarea id=\"rejectNote\" pInputTextarea [(ngModel)]=\"rejectNote\" [placeholder]=\"SHARED.REJECT_NOTE_PLACEHOLDER\"\r\n rows=\"6\" class=\"note-textarea\">\r\n </textarea>\r\n </div>\r\n <ng-template pTemplate=\"footer\">\r\n <div class=\"dialog-footer\">\r\n <button pButton [label]=\"SHARED.CANCEL_BUTTON_LABEL\" class=\"p-button-secondary\" (click)=\"onCancel()\">\r\n </button>\r\n <button pButton [label]=\"SHARED.REJECT_BUTTON_LABEL\" class=\"p-button-danger\" [disabled]=\"isRejectNoteEmpty\"\r\n (click)=\"onRejectConfirm()\">\r\n </button>\r\n </div>\r\n </ng-template>\r\n</p-dialog>", styles: [".document-actions-container{margin:0}.actions-card{border-radius:8px;padding:.75rem;box-shadow:0 2px 4px #0000001a;transition:all .3s ease}.actions-card.pending-card{background-color:#f8f9fa;border:1px solid #e9ecef}.actions-card.accepted-card{background-color:#d4edda;border:1px solid #28a745}.actions-card.rejected-card{background-color:#f8d7da;border:1px solid #dc3545}.actions-card[class*=status-].status-approved-card{background-color:#d4edda;border:1px solid #28a745}.actions-card[class*=status-].status-rejected-card{background-color:#f8d7da;border:1px solid #dc3545}.actions-card[class*=status-].status-pending-card{background-color:#f8f9fa;border:1px solid #e9ecef}.actions-buttons{display:flex;gap:.5rem;align-items:center}.action-btn{padding:.5rem 1rem;border-radius:6px;border:1px solid;font-weight:500;cursor:pointer;transition:all .2s ease;display:flex;align-items:center;gap:.5rem;min-width:80px;justify-content:center}.action-btn:disabled{opacity:.6;cursor:not-allowed}.action-btn i{font-size:.875rem}.reject-btn.default-reject{background-color:#fff5f5;border-color:#feb2b2;color:#4a5568}.reject-btn.default-reject:hover:not(:disabled){background-color:#fed7d7;border-color:#fc8181}.reject-btn.secondary-reject{background-color:#f7fafc;border-color:#e2e8f0;color:#4a5568}.reject-btn.secondary-reject:hover:not(:disabled){background-color:#edf2f7;border-color:#cbd5e0}.reject-btn.primary-reject{background-color:#dc3545;border-color:#dc3545;color:#fff}.reject-btn.primary-reject:hover:not(:disabled){background-color:#c82333;border-color:#bd2130}.reject-btn[class*=status-].status-approved-reject{background-color:#f7fafc;border-color:#e2e8f0;color:#4a5568}.reject-btn[class*=status-].status-approved-reject:hover:not(:disabled){background-color:#edf2f7;border-color:#cbd5e0}.reject-btn[class*=status-].status-rejected-reject{background-color:#dc3545;border-color:#dc3545;color:#fff}.reject-btn[class*=status-].status-rejected-reject:hover:not(:disabled){background-color:#c82333;border-color:#bd2130}.reject-btn[class*=status-].status-pending-reject{background-color:#fff5f5;border-color:#feb2b2;color:#4a5568}.reject-btn[class*=status-].status-pending-reject:hover:not(:disabled){background-color:#fed7d7;border-color:#fc8181}.accept-btn.default-accept{background-color:#f0fff4;border-color:#9ae6b4;color:#4a5568}.accept-btn.default-accept:hover:not(:disabled){background-color:#c6f6d5;border-color:#68d391}.accept-btn.secondary-accept{background-color:#f7fafc;border-color:#e2e8f0;color:#4a5568}.accept-btn.secondary-accept:hover:not(:disabled){background-color:#edf2f7;border-color:#cbd5e0}.accept-btn.primary-accept{background-color:#28a745;border-color:#28a745;color:#fff}.accept-btn.primary-accept:hover:not(:disabled){background-color:#218838;border-color:#1e7e34}.accept-btn[class*=status-].status-approved-accept{background-color:#28a745;border-color:#28a745;color:#fff}.accept-btn[class*=status-].status-approved-accept:hover:not(:disabled){background-color:#218838;border-color:#1e7e34}.accept-btn[class*=status-].status-rejected-accept{background-color:#f7fafc;border-color:#e2e8f0;color:#4a5568}.accept-btn[class*=status-].status-rejected-accept:hover:not(:disabled){background-color:#edf2f7;border-color:#cbd5e0}.accept-btn[class*=status-].status-pending-accept{background-color:#f0fff4;border-color:#9ae6b4;color:#4a5568}.accept-btn[class*=status-].status-pending-accept:hover:not(:disabled){background-color:#c6f6d5;border-color:#68d391}.delete-btn{background-color:#fff;border-color:#e2e8f0;color:#e53e3e;padding:.5rem;min-width:auto;width:40px;height:40px}.delete-btn:hover:not(:disabled){background-color:#fed7d7;border-color:#fc8181;color:#c53030}.delete-btn i{font-size:1rem}:host ::ng-deep .confirmation-dialog .p-dialog{border-radius:8px;box-shadow:0 4px 12px #00000026;border:none;overflow:hidden}:host ::ng-deep .confirmation-dialog .p-dialog-header{padding:1.25rem 1.5rem;background-color:#fff;border-bottom:none;border-top-right-radius:10px;border-top-left-radius:10px}:host ::ng-deep .confirmation-dialog .p-dialog-header .p-dialog-header-icon{display:none}:host ::ng-deep .confirmation-dialog .p-dialog-header .p-dialog-title{font-size:1.125rem;font-weight:600;color:#2d3748;margin:0}:host ::ng-deep .confirmation-dialog .p-dialog-content{padding:1.5rem;background-color:#fff}:host ::ng-deep .confirmation-dialog .p-dialog-footer{padding:1rem 1.5rem;background-color:#f7fafc;border-top:1px solid #e2e8f0;display:flex;gap:.75rem;justify-content:flex-end;border-bottom-right-radius:10px;border-bottom-left-radius:10px}.dialog-content .note-label{display:block;margin-bottom:.75rem;font-weight:500;font-size:.875rem;color:#2d3748}.dialog-content .note-textarea{width:100%;min-height:100px;padding:.75rem;border:1px solid #e2e8f0;border-radius:6px;font-family:inherit;font-size:.875rem;line-height:1.5;resize:vertical;background-color:#fff;color:#2d3748}.dialog-content .note-textarea::placeholder{color:#a0aec0}.dialog-content .note-textarea:focus{outline:none;border-color:#3182ce;box-shadow:0 0 0 3px #3182ce1a}.dialog-footer{display:flex;gap:.75rem;justify-content:flex-end}.dialog-footer button{min-width:80px;padding:.5rem 1rem;border-radius:6px;font-weight:500;font-size:.875rem;border:1px solid;cursor:pointer;transition:all .2s ease}.dialog-footer button.p-button-secondary{background-color:#f7fafc;border-color:#e2e8f0;color:#4a5568}.dialog-footer button.p-button-secondary:hover{background-color:#edf2f7;border-color:#cbd5e0}.dialog-footer button.p-button-success{background-color:#38a169;border-color:#38a169;color:#fff}.dialog-footer button.p-button-success:hover{background-color:#2f855a;border-color:#2f855a}.dialog-footer button.p-button-danger{background-color:#e53e3e;border-color:#e53e3e;color:#fff}.dialog-footer button.p-button-danger:hover{background-color:#c53030;border-color:#c53030}\n"], dependencies: [{ kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i4.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "directive", type: i5$1.InputTextarea, selector: "[pInputTextarea]", inputs: ["autoResize", "variant"], outputs: ["onResize"] }, { kind: "directive", type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { 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: i7.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "visible", "style", "position"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "directive", type: i8.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "directive", type: HasPermissionDirective, selector: "[permission]", inputs: ["permission"] }] });
|
|
5268
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: DocumentActionsComponent, isStandalone: false, selector: "document-actions", inputs: { document: "document", documentId: "documentId", currentStatus: "currentStatus", isLoading: "isLoading", isUploaded: "isUploaded", statusId: "statusId" }, outputs: { actionPerformed: "actionPerformed" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"document-actions-container\" >\r\n <div class=\"actions-card\" [ngClass]=\"cardClass\">\r\n <div class=\"actions-buttons\">\r\n <!-- Reject Button -->\r\n <button *ngIf=\"!document?.isUploaded\" class=\"action-btn reject-btn\" [ngClass]=\"rejectButtonClass\" (click)=\"onRejectClick()\"\r\n [disabled]=\"currentStatus === SHARED.STATUS_REJECTED_LOWERCASE || isRejecting\">\r\n <i class=\"pi pi-times\" *ngIf=\"currentStatus === SHARED.STATUS_REJECTED_LOWERCASE\"></i>\r\n <i class=\"pi pi-spin pi-spinner\" *ngIf=\"isRejecting\"></i>\r\n <span>{{ currentStatus === SHARED.STATUS_REJECTED_LOWERCASE ? SHARED.BUTTON_LABEL_REJECTED :\r\n SHARED.BUTTON_LABEL_REJECT }}</span>\r\n </button>\r\n\r\n <!-- Accept Button -->\r\n <button *ngIf=\"!document?.isUploaded\" class=\"action-btn accept-btn\" [ngClass]=\"acceptButtonClass\" (click)=\"onAcceptClick()\"\r\n [disabled]=\"currentStatus === SHARED.STATUS_ACCEPTED || isAccepting\">\r\n <i class=\"pi pi-check\" *ngIf=\"currentStatus === SHARED.STATUS_ACCEPTED\"></i>\r\n <i class=\"pi pi-spin pi-spinner\" *ngIf=\"isAccepting\"></i>\r\n <span>{{ currentStatus === SHARED.STATUS_ACCEPTED ? SHARED.BUTTON_LABEL_ACCEPTED : SHARED.BUTTON_LABEL_ACCEPT\r\n }}</span>\r\n </button>\r\n\r\n <!-- Delete Button -->\r\n @if(document?.isUploaded){\r\n <button class=\"action-btn delete-btn\" (click)=\"onDeleteClick()\" [disabled]=\"isLoading\"\r\n [permission]=\"'documents-deleteDocumentByDocumentId'\" pTooltip=\"Delete Document\" tooltipPosition=\"top\">\r\n <i class=\"pi pi-trash\"></i>\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Accept Confirmation Dialog -->\r\n<p-dialog [(visible)]=\"showAcceptDialog\" [header]=\"SHARED.ACCEPT_CONFIRM_HEADER\" [modal]=\"true\" [draggable]=\"false\"\r\n [closable]=\"true\" [style]=\"{ width: '25rem', height: '25rem' }\" styleClass=\"confirmation-dialog\">\r\n <div class=\"dialog-content\">\r\n <label for=\"acceptNote\" class=\"note-label\">{{ SHARED.ACCEPT_NOTE_LABEL }}</label>\r\n <textarea id=\"acceptNote\" pInputTextarea [(ngModel)]=\"acceptNote\" [placeholder]=\"SHARED.ACCEPT_NOTE_PLACEHOLDER\"\r\n rows=\"6\" class=\"note-textarea\">\r\n </textarea>\r\n </div>\r\n <ng-template pTemplate=\"footer\">\r\n <div class=\"dialog-footer\">\r\n <button pButton [label]=\"SHARED.CANCEL_BUTTON_LABEL\" class=\"p-button-secondary\" (click)=\"onCancel()\">\r\n </button>\r\n <button pButton [label]=\"SHARED.ACCEPT_BUTTON_LABEL\" class=\"p-button-success\" (click)=\"onAcceptConfirm()\">\r\n </button>\r\n </div>\r\n </ng-template>\r\n</p-dialog>\r\n\r\n<!-- Reject Confirmation Dialog -->\r\n<p-dialog [(visible)]=\"showRejectDialog\" [header]=\"SHARED.REJECT_CONFIRM_HEADER\" [modal]=\"true\" [draggable]=\"false\"\r\n [closable]=\"true\" [style]=\"{ width: '25rem', height: '25rem' }\" styleClass=\"confirmation-dialog\">\r\n <div class=\"dialog-content\">\r\n <label for=\"rejectNote\" class=\"note-label\">{{ SHARED.REJECT_NOTE_LABEL }}</label>\r\n <textarea id=\"rejectNote\" pInputTextarea [(ngModel)]=\"rejectNote\" [placeholder]=\"SHARED.REJECT_NOTE_PLACEHOLDER\"\r\n rows=\"6\" class=\"note-textarea\">\r\n </textarea>\r\n </div>\r\n <ng-template pTemplate=\"footer\">\r\n <div class=\"dialog-footer\">\r\n <button pButton [label]=\"SHARED.CANCEL_BUTTON_LABEL\" class=\"p-button-secondary\" (click)=\"onCancel()\">\r\n </button>\r\n <button pButton [label]=\"SHARED.REJECT_BUTTON_LABEL\" class=\"p-button-danger\" [disabled]=\"isRejectNoteEmpty\"\r\n (click)=\"onRejectConfirm()\">\r\n </button>\r\n </div>\r\n </ng-template>\r\n</p-dialog>", styles: [".document-actions-container{margin:0}.actions-card{border-radius:8px;padding:.75rem;box-shadow:0 2px 4px #0000001a;transition:all .3s ease}.actions-card.pending-card{background-color:#f8f9fa;border:1px solid #e9ecef}.actions-card.accepted-card{background-color:#d4edda;border:1px solid #28a745}.actions-card.rejected-card{background-color:#f8d7da;border:1px solid #dc3545}.actions-card[class*=status-].status-approved-card{background-color:#d4edda;border:1px solid #28a745}.actions-card[class*=status-].status-rejected-card{background-color:#f8d7da;border:1px solid #dc3545}.actions-card[class*=status-].status-pending-card{background-color:#f8f9fa;border:1px solid #e9ecef}.actions-buttons{display:flex;gap:.5rem;align-items:center}.action-btn{padding:.5rem 1rem;border-radius:6px;border:1px solid;font-weight:500;cursor:pointer;transition:all .2s ease;display:flex;align-items:center;gap:.5rem;min-width:80px;justify-content:center}.action-btn:disabled{opacity:.6;cursor:not-allowed}.action-btn i{font-size:.875rem}.reject-btn.default-reject{background-color:#fff5f5;border-color:#feb2b2;color:#4a5568}.reject-btn.default-reject:hover:not(:disabled){background-color:#fed7d7;border-color:#fc8181}.reject-btn.secondary-reject{background-color:#f7fafc;border-color:#e2e8f0;color:#4a5568}.reject-btn.secondary-reject:hover:not(:disabled){background-color:#edf2f7;border-color:#cbd5e0}.reject-btn.primary-reject{background-color:#dc3545;border-color:#dc3545;color:#fff}.reject-btn.primary-reject:hover:not(:disabled){background-color:#c82333;border-color:#bd2130}.reject-btn[class*=status-].status-approved-reject{background-color:#f7fafc;border-color:#e2e8f0;color:#4a5568}.reject-btn[class*=status-].status-approved-reject:hover:not(:disabled){background-color:#edf2f7;border-color:#cbd5e0}.reject-btn[class*=status-].status-rejected-reject{background-color:#dc3545;border-color:#dc3545;color:#fff}.reject-btn[class*=status-].status-rejected-reject:hover:not(:disabled){background-color:#c82333;border-color:#bd2130}.reject-btn[class*=status-].status-pending-reject{background-color:#fff5f5;border-color:#feb2b2;color:#4a5568}.reject-btn[class*=status-].status-pending-reject:hover:not(:disabled){background-color:#fed7d7;border-color:#fc8181}.accept-btn.default-accept{background-color:#f0fff4;border-color:#9ae6b4;color:#4a5568}.accept-btn.default-accept:hover:not(:disabled){background-color:#c6f6d5;border-color:#68d391}.accept-btn.secondary-accept{background-color:#f7fafc;border-color:#e2e8f0;color:#4a5568}.accept-btn.secondary-accept:hover:not(:disabled){background-color:#edf2f7;border-color:#cbd5e0}.accept-btn.primary-accept{background-color:#28a745;border-color:#28a745;color:#fff}.accept-btn.primary-accept:hover:not(:disabled){background-color:#218838;border-color:#1e7e34}.accept-btn[class*=status-].status-approved-accept{background-color:#28a745;border-color:#28a745;color:#fff}.accept-btn[class*=status-].status-approved-accept:hover:not(:disabled){background-color:#218838;border-color:#1e7e34}.accept-btn[class*=status-].status-rejected-accept{background-color:#f7fafc;border-color:#e2e8f0;color:#4a5568}.accept-btn[class*=status-].status-rejected-accept:hover:not(:disabled){background-color:#edf2f7;border-color:#cbd5e0}.accept-btn[class*=status-].status-pending-accept{background-color:#f0fff4;border-color:#9ae6b4;color:#4a5568}.accept-btn[class*=status-].status-pending-accept:hover:not(:disabled){background-color:#c6f6d5;border-color:#68d391}.delete-btn{background-color:#fff;border-color:#e2e8f0;color:#e53e3e;padding:.5rem;min-width:auto;width:40px;height:40px}.delete-btn:hover:not(:disabled){background-color:#fed7d7;border-color:#fc8181;color:#c53030}.delete-btn i{font-size:1rem}:host ::ng-deep .confirmation-dialog .p-dialog{border-radius:8px;box-shadow:0 4px 12px #00000026;border:none;overflow:hidden}:host ::ng-deep .confirmation-dialog .p-dialog-header{padding:1.25rem 1.5rem;background-color:#fff;border-bottom:none;border-top-right-radius:10px;border-top-left-radius:10px}:host ::ng-deep .confirmation-dialog .p-dialog-header .p-dialog-header-icon{display:none}:host ::ng-deep .confirmation-dialog .p-dialog-header .p-dialog-title{font-size:1.125rem;font-weight:600;color:#2d3748;margin:0}:host ::ng-deep .confirmation-dialog .p-dialog-content{padding:1.5rem;background-color:#fff}:host ::ng-deep .confirmation-dialog .p-dialog-footer{padding:1rem 1.5rem;background-color:#f7fafc;border-top:1px solid #e2e8f0;display:flex;gap:.75rem;justify-content:flex-end;border-bottom-right-radius:10px;border-bottom-left-radius:10px}.dialog-content .note-label{display:block;margin-bottom:.75rem;font-weight:500;font-size:.875rem;color:#2d3748}.dialog-content .note-textarea{width:100%;min-height:100px;padding:.75rem;border:1px solid #e2e8f0;border-radius:6px;font-family:inherit;font-size:.875rem;line-height:1.5;resize:vertical;background-color:#fff;color:#2d3748}.dialog-content .note-textarea::placeholder{color:#a0aec0}.dialog-content .note-textarea:focus{outline:none;border-color:#3182ce;box-shadow:0 0 0 3px #3182ce1a}.dialog-footer{display:flex;gap:.75rem;justify-content:flex-end}.dialog-footer button{min-width:80px;padding:.5rem 1rem;border-radius:6px;font-weight:500;font-size:.875rem;border:1px solid;cursor:pointer;transition:all .2s ease}.dialog-footer button.p-button-secondary{background-color:#f7fafc;border-color:#e2e8f0;color:#4a5568}.dialog-footer button.p-button-secondary:hover{background-color:#edf2f7;border-color:#cbd5e0}.dialog-footer button.p-button-success{background-color:#38a169;border-color:#38a169;color:#fff}.dialog-footer button.p-button-success:hover{background-color:#2f855a;border-color:#2f855a}.dialog-footer button.p-button-danger{background-color:#e53e3e;border-color:#e53e3e;color:#fff}.dialog-footer button.p-button-danger:hover{background-color:#c53030;border-color:#c53030}\n"], dependencies: [{ kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i4.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "directive", type: i5$2.InputTextarea, selector: "[pInputTextarea]", inputs: ["autoResize", "variant"], outputs: ["onResize"] }, { kind: "directive", type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { 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: i7.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "visible", "style", "position"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "directive", type: i8.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "directive", type: HasPermissionDirective, selector: "[permission]", inputs: ["permission"] }] });
|
|
4950
5269
|
}
|
|
4951
5270
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentActionsComponent, decorators: [{
|
|
4952
5271
|
type: Component,
|
|
@@ -5109,11 +5428,11 @@ class DocumentViewerComponent {
|
|
|
5109
5428
|
this.subscription.unsubscribe();
|
|
5110
5429
|
}
|
|
5111
5430
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentViewerComponent, deps: [{ token: DocumentHttpService }, { token: DocumentHelperService }, { token: i3.MessageService }, { token: DocumentViewerService }], target: i0.ɵɵFactoryTarget.Component });
|
|
5112
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: DocumentViewerComponent, isStandalone: false, selector: "document-viewer", inputs: { selectedDocument: "selectedDocument", documentList: "documentList", contextId: "contextId" }, outputs: { documentStatusUpdated: "documentStatusUpdated" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"document-viewer-container\">\r\n <div class=\"main-content\">\r\n <p-messages [(value)]=\"messages\" [enableService]=\"false\"></p-messages>\r\n \r\n <div class=\"content-grid\">\r\n @if(selectedDocument){\r\n <div class=\"document-preview\">\r\n @if(isSelectedDocumentImage){\r\n <div class=\"img-container\">\r\n <img\r\n [src]=\"selectedDocument?.documentUrl || ''\"\r\n class=\"uploadedImages\"\r\n alt=\"Document Image\"\r\n />\r\n </div>\r\n }@else if(isSelectedDocumentPdf){\r\n <div class=\"pdf-container\">\r\n <pdf-viewer\r\n [src]=\"selectedDocument?.documentUrl || ''\"\r\n [rotation]=\"0\"\r\n [original-size]=\"false\"\r\n [show-all]=\"true\"\r\n [fit-to-page]=\"false\"\r\n [zoom]=\"
|
|
5431
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: DocumentViewerComponent, isStandalone: false, selector: "document-viewer", inputs: { selectedDocument: "selectedDocument", documentList: "documentList", contextId: "contextId" }, outputs: { documentStatusUpdated: "documentStatusUpdated" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"document-viewer-container\">\r\n <div class=\"main-content\">\r\n <p-messages [(value)]=\"messages\" [enableService]=\"false\"></p-messages>\r\n \r\n <div class=\"content-grid\">\r\n @if(selectedDocument){\r\n <div class=\"document-preview\">\r\n @if(isSelectedDocumentImage){\r\n <div class=\"img-container\">\r\n <img\r\n [src]=\"selectedDocument?.documentUrl || ''\"\r\n class=\"uploadedImages\"\r\n alt=\"Document Image\"\r\n />\r\n </div>\r\n }@else if(isSelectedDocumentPdf){\r\n <div class=\"pdf-container\">\r\n <pdf-viewer\r\n [src]=\"selectedDocument?.documentUrl || ''\"\r\n [rotation]=\"0\"\r\n [original-size]=\"false\"\r\n [show-all]=\"true\"\r\n [fit-to-page]=\"false\"\r\n [zoom]=\"0.7\"\r\n [zoom-scale]=\"'page-width'\"\r\n [stick-to-page]=\"false\"\r\n [render-text]=\"true\"\r\n [external-link-target]=\"'blank'\"\r\n [autoresize]=\"true\"\r\n [show-borders]=\"false\"\r\n style=\"width: 100%; height: 100%\"\r\n ></pdf-viewer>\r\n </div>\r\n }@else if(isSelectedDocumentUnsupported){\r\n <div class=\"incorrect-docType\">\r\n ContentType is incorrect.\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"left-part col-12 md:col-12 pt-0\">\r\n \r\n <!-- <div class=\"alerts mb-4 pb-1\">\r\n <button\r\n type=\"button\"\r\n *ngIf=\"\r\n (alertData?.status !== 'Pending' && !!alertData?.status) ||\r\n alertData?.isAlert === false\r\n \"\r\n class=\"bg-green-500 border-none border-round-md flex align-items-center mb-3 p-2 px-3\"\r\n >\r\n <i\r\n class=\"pi pi-verified mr-2 cursor-pointer\"\r\n [ngStyle]=\"{\r\n color:\r\n alertData?.status === 'Pending' &&\r\n alertData?.isAlert !== false\r\n ? '#FFFFFF'\r\n : '#8A8EA6'\r\n }\"\r\n style=\"font-size: 20px\"\r\n ></i>\r\n <span class=\"font-semibold text-white\">Verified</span>\r\n </button>\r\n <div\r\n class=\"card mb-0\"\r\n [ngClass]=\"\r\n (alertData?.status === 'Pending' || !alertData?.status) &&\r\n alertData?.isAlert !== false\r\n ? 'alert-card'\r\n : 'success-alert'\r\n \"\r\n >\r\n <div class=\"flex align-items-center mb-2 pb-1\" *ngIf=\"alertData?.status !== 'Verified'\">\r\n <h4 class=\"mr-3 mt-0 mb-0 text-color font-bold\" style=\"font-size: 21px; font-weight: bold; border-color: rgba(68, 72, 109, 0.2) ;\" >Alerts</h4>\r\n <i\r\n class=\"pi pi-exclamation-triangle\"\r\n style=\"font-size: 20px\"\r\n [ngStyle]=\"{\r\n color:\r\n (alertData?.status === 'Pending' || !alertData?.status) &&\r\n alertData?.isAlert !== false\r\n ? '#FB392D'\r\n : '#8A8EA6'\r\n }\"\r\n ></i>\r\n </div>\r\n <p class=\"text-color mb-0\">{{ alertData?.alertMessage }}</p>\r\n </div>\r\n </div>\r\n -->\r\n \r\n <div class=\"sidebar\">\r\n <document-actions\r\n [document]=\"selectedDocument\"\r\n [documentId]=\"selectedDocument?._id\"\r\n [currentStatus]=\"currentState.documentStatus\"\r\n [isLoading]=\"currentState.isActionLoading\"\r\n [isUploaded]=\"currentState.documentIsUploaded\"\r\n [statusId]=\"selectedDocument?.statusId\"\r\n (actionPerformed)=\"handleDocumentAction($event)\">\r\n </document-actions>\r\n \r\n <document-history \r\n [historyData]=\"currentState.documentHistory\" \r\n [showHistory]=\"currentState.showDocumentHistory\">\r\n </document-history>\r\n \r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".document-viewer-container{height:100%;width:100%}.document-viewer-container .main-content{height:100%;display:flex;flex-direction:column}.document-viewer-container .main-content .p-messages{margin-bottom:.5rem}.document-viewer-container .main-content .content-grid{display:grid;grid-template-columns:1fr 350px;gap:1rem;height:calc(100% - 60px);min-height:0}.document-viewer-container .main-content .content-grid .document-preview{background:#f8f9fa;border-radius:8px;padding:.5rem;display:flex;align-items:center;justify-content:center;overflow:hidden}.document-viewer-container .main-content .content-grid .document-preview .img-container{width:100%;height:100%;display:flex;align-items:center;justify-content:center}.document-viewer-container .main-content .content-grid .document-preview .img-container .uploadedImages{max-width:100%;max-height:100%;object-fit:contain;border-radius:4px}.document-viewer-container .main-content .content-grid .document-preview .pdf-container{width:100%;height:100%;border-radius:4px;overflow:hidden}.document-viewer-container .main-content .content-grid .document-preview .incorrect-docType{color:#dc3545;font-weight:500;text-align:center;padding:2rem}.document-viewer-container .main-content .content-grid .sidebar{display:flex;flex-direction:column;gap:.75rem;max-height:100%;overflow-y:auto}.document-viewer-container .main-content .content-grid .sidebar ::ng-deep .document-actions-container{margin:0}.document-viewer-container .main-content .content-grid .sidebar ::ng-deep .document-history-container{padding:.75rem;max-height:none}@media (max-width: 1200px){.document-viewer-container .main-content .content-grid{grid-template-columns:1fr 300px;gap:.75rem}}@media (max-width: 768px){.document-viewer-container .main-content .content-grid{grid-template-columns:1fr;gap:.5rem}.document-viewer-container .main-content .content-grid .sidebar{order:-1}}.alert-card{background-color:#fb392d1a}.success-alert{border-radius:10px;border:1px solid rgba(251,57,45,.1);background:linear-gradient(0deg,#dedede 0% 100%),#fff}.p-timeline-event-opposite{display:none}.decription{color:#676b89}.textAreaControl textarea{width:100%;resize:vertical;max-width:100%}.document-btn-wrapper .p-button-outlined{color:#f57c00}.document-viewer .p-dialog{width:100%;height:100%;max-height:100%!important;box-shadow:none!important}.document-viewer .p-dialog-header-close-icon{height:20px;width:20px}.document-viewer .p-dialog-header,.document-viewer .p-dialog-content{background-color:#fff;border-radius:0}\n"], dependencies: [{ kind: "component", type: i5.Messages, selector: "p-messages", inputs: ["value", "closable", "style", "styleClass", "enableService", "key", "escape", "severity", "showTransitionOptions", "hideTransitionOptions"], outputs: ["valueChange", "onClose"] }, { kind: "component", type: i6.PdfViewerComponent, selector: "pdf-viewer", inputs: ["src", "c-maps-url", "page", "render-text", "render-text-mode", "original-size", "show-all", "stick-to-page", "zoom", "zoom-scale", "rotation", "external-link-target", "autoresize", "fit-to-page", "show-borders"], outputs: ["after-load-complete", "page-rendered", "pages-initialized", "text-layer-rendered", "error", "on-progress", "pageChange"] }, { kind: "component", type: DocumentHistoryComponent, selector: "document-history", inputs: ["historyData", "showHistory"] }, { kind: "component", type: DocumentActionsComponent, selector: "document-actions", inputs: ["document", "documentId", "currentStatus", "isLoading", "isUploaded", "statusId"], outputs: ["actionPerformed"] }], encapsulation: i0.ViewEncapsulation.None });
|
|
5113
5432
|
}
|
|
5114
5433
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentViewerComponent, decorators: [{
|
|
5115
5434
|
type: Component,
|
|
5116
|
-
args: [{ selector: 'document-viewer', standalone: false, encapsulation: ViewEncapsulation.None, template: "<div class=\"document-viewer-container\">\r\n <div class=\"main-content\">\r\n <p-messages [(value)]=\"messages\" [enableService]=\"false\"></p-messages>\r\n \r\n <div class=\"content-grid\">\r\n @if(selectedDocument){\r\n <div class=\"document-preview\">\r\n @if(isSelectedDocumentImage){\r\n <div class=\"img-container\">\r\n <img\r\n [src]=\"selectedDocument?.documentUrl || ''\"\r\n class=\"uploadedImages\"\r\n alt=\"Document Image\"\r\n />\r\n </div>\r\n }@else if(isSelectedDocumentPdf){\r\n <div class=\"pdf-container\">\r\n <pdf-viewer\r\n [src]=\"selectedDocument?.documentUrl || ''\"\r\n [rotation]=\"0\"\r\n [original-size]=\"false\"\r\n [show-all]=\"true\"\r\n [fit-to-page]=\"false\"\r\n [zoom]=\"
|
|
5435
|
+
args: [{ selector: 'document-viewer', standalone: false, encapsulation: ViewEncapsulation.None, template: "<div class=\"document-viewer-container\">\r\n <div class=\"main-content\">\r\n <p-messages [(value)]=\"messages\" [enableService]=\"false\"></p-messages>\r\n \r\n <div class=\"content-grid\">\r\n @if(selectedDocument){\r\n <div class=\"document-preview\">\r\n @if(isSelectedDocumentImage){\r\n <div class=\"img-container\">\r\n <img\r\n [src]=\"selectedDocument?.documentUrl || ''\"\r\n class=\"uploadedImages\"\r\n alt=\"Document Image\"\r\n />\r\n </div>\r\n }@else if(isSelectedDocumentPdf){\r\n <div class=\"pdf-container\">\r\n <pdf-viewer\r\n [src]=\"selectedDocument?.documentUrl || ''\"\r\n [rotation]=\"0\"\r\n [original-size]=\"false\"\r\n [show-all]=\"true\"\r\n [fit-to-page]=\"false\"\r\n [zoom]=\"0.7\"\r\n [zoom-scale]=\"'page-width'\"\r\n [stick-to-page]=\"false\"\r\n [render-text]=\"true\"\r\n [external-link-target]=\"'blank'\"\r\n [autoresize]=\"true\"\r\n [show-borders]=\"false\"\r\n style=\"width: 100%; height: 100%\"\r\n ></pdf-viewer>\r\n </div>\r\n }@else if(isSelectedDocumentUnsupported){\r\n <div class=\"incorrect-docType\">\r\n ContentType is incorrect.\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"left-part col-12 md:col-12 pt-0\">\r\n \r\n <!-- <div class=\"alerts mb-4 pb-1\">\r\n <button\r\n type=\"button\"\r\n *ngIf=\"\r\n (alertData?.status !== 'Pending' && !!alertData?.status) ||\r\n alertData?.isAlert === false\r\n \"\r\n class=\"bg-green-500 border-none border-round-md flex align-items-center mb-3 p-2 px-3\"\r\n >\r\n <i\r\n class=\"pi pi-verified mr-2 cursor-pointer\"\r\n [ngStyle]=\"{\r\n color:\r\n alertData?.status === 'Pending' &&\r\n alertData?.isAlert !== false\r\n ? '#FFFFFF'\r\n : '#8A8EA6'\r\n }\"\r\n style=\"font-size: 20px\"\r\n ></i>\r\n <span class=\"font-semibold text-white\">Verified</span>\r\n </button>\r\n <div\r\n class=\"card mb-0\"\r\n [ngClass]=\"\r\n (alertData?.status === 'Pending' || !alertData?.status) &&\r\n alertData?.isAlert !== false\r\n ? 'alert-card'\r\n : 'success-alert'\r\n \"\r\n >\r\n <div class=\"flex align-items-center mb-2 pb-1\" *ngIf=\"alertData?.status !== 'Verified'\">\r\n <h4 class=\"mr-3 mt-0 mb-0 text-color font-bold\" style=\"font-size: 21px; font-weight: bold; border-color: rgba(68, 72, 109, 0.2) ;\" >Alerts</h4>\r\n <i\r\n class=\"pi pi-exclamation-triangle\"\r\n style=\"font-size: 20px\"\r\n [ngStyle]=\"{\r\n color:\r\n (alertData?.status === 'Pending' || !alertData?.status) &&\r\n alertData?.isAlert !== false\r\n ? '#FB392D'\r\n : '#8A8EA6'\r\n }\"\r\n ></i>\r\n </div>\r\n <p class=\"text-color mb-0\">{{ alertData?.alertMessage }}</p>\r\n </div>\r\n </div>\r\n -->\r\n \r\n <div class=\"sidebar\">\r\n <document-actions\r\n [document]=\"selectedDocument\"\r\n [documentId]=\"selectedDocument?._id\"\r\n [currentStatus]=\"currentState.documentStatus\"\r\n [isLoading]=\"currentState.isActionLoading\"\r\n [isUploaded]=\"currentState.documentIsUploaded\"\r\n [statusId]=\"selectedDocument?.statusId\"\r\n (actionPerformed)=\"handleDocumentAction($event)\">\r\n </document-actions>\r\n \r\n <document-history \r\n [historyData]=\"currentState.documentHistory\" \r\n [showHistory]=\"currentState.showDocumentHistory\">\r\n </document-history>\r\n \r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".document-viewer-container{height:100%;width:100%}.document-viewer-container .main-content{height:100%;display:flex;flex-direction:column}.document-viewer-container .main-content .p-messages{margin-bottom:.5rem}.document-viewer-container .main-content .content-grid{display:grid;grid-template-columns:1fr 350px;gap:1rem;height:calc(100% - 60px);min-height:0}.document-viewer-container .main-content .content-grid .document-preview{background:#f8f9fa;border-radius:8px;padding:.5rem;display:flex;align-items:center;justify-content:center;overflow:hidden}.document-viewer-container .main-content .content-grid .document-preview .img-container{width:100%;height:100%;display:flex;align-items:center;justify-content:center}.document-viewer-container .main-content .content-grid .document-preview .img-container .uploadedImages{max-width:100%;max-height:100%;object-fit:contain;border-radius:4px}.document-viewer-container .main-content .content-grid .document-preview .pdf-container{width:100%;height:100%;border-radius:4px;overflow:hidden}.document-viewer-container .main-content .content-grid .document-preview .incorrect-docType{color:#dc3545;font-weight:500;text-align:center;padding:2rem}.document-viewer-container .main-content .content-grid .sidebar{display:flex;flex-direction:column;gap:.75rem;max-height:100%;overflow-y:auto}.document-viewer-container .main-content .content-grid .sidebar ::ng-deep .document-actions-container{margin:0}.document-viewer-container .main-content .content-grid .sidebar ::ng-deep .document-history-container{padding:.75rem;max-height:none}@media (max-width: 1200px){.document-viewer-container .main-content .content-grid{grid-template-columns:1fr 300px;gap:.75rem}}@media (max-width: 768px){.document-viewer-container .main-content .content-grid{grid-template-columns:1fr;gap:.5rem}.document-viewer-container .main-content .content-grid .sidebar{order:-1}}.alert-card{background-color:#fb392d1a}.success-alert{border-radius:10px;border:1px solid rgba(251,57,45,.1);background:linear-gradient(0deg,#dedede 0% 100%),#fff}.p-timeline-event-opposite{display:none}.decription{color:#676b89}.textAreaControl textarea{width:100%;resize:vertical;max-width:100%}.document-btn-wrapper .p-button-outlined{color:#f57c00}.document-viewer .p-dialog{width:100%;height:100%;max-height:100%!important;box-shadow:none!important}.document-viewer .p-dialog-header-close-icon{height:20px;width:20px}.document-viewer .p-dialog-header,.document-viewer .p-dialog-content{background-color:#fff;border-radius:0}\n"] }]
|
|
5117
5436
|
}], ctorParameters: () => [{ type: DocumentHttpService }, { type: DocumentHelperService }, { type: i3.MessageService }, { type: DocumentViewerService }], propDecorators: { selectedDocument: [{
|
|
5118
5437
|
type: Input
|
|
5119
5438
|
}], documentList: [{
|
|
@@ -5493,6 +5812,11 @@ class DocumentsMenuComponent {
|
|
|
5493
5812
|
this.documentMenuService = documentMenuService;
|
|
5494
5813
|
this.documentHelperService = documentHelperService;
|
|
5495
5814
|
}
|
|
5815
|
+
/**
|
|
5816
|
+
* Initialize the component
|
|
5817
|
+
* @returns {void}
|
|
5818
|
+
* @memberof DocumentsMenuComponent
|
|
5819
|
+
*/
|
|
5496
5820
|
ngOnInit() {
|
|
5497
5821
|
this.documentQuery.selectSelectedMenuItem().subscribe(menuItemId => {
|
|
5498
5822
|
this.selectedMenuItemId = menuItemId;
|
|
@@ -5506,6 +5830,12 @@ class DocumentsMenuComponent {
|
|
|
5506
5830
|
}
|
|
5507
5831
|
});
|
|
5508
5832
|
}
|
|
5833
|
+
/**
|
|
5834
|
+
* Handle changes to input properties
|
|
5835
|
+
* @param {SimpleChanges} changes - The changes to the input properties
|
|
5836
|
+
* @returns {void}
|
|
5837
|
+
* @memberof DocumentsMenuComponent
|
|
5838
|
+
*/
|
|
5509
5839
|
ngOnChanges(changes) {
|
|
5510
5840
|
if (changes[SHARED.CATAGORIES] && this.catagories) {
|
|
5511
5841
|
this.updateMenuItemsData();
|
|
@@ -5587,14 +5917,15 @@ class DocumentsMenuComponent {
|
|
|
5587
5917
|
* Handle deselection to ensure immediate visual feedback
|
|
5588
5918
|
*/
|
|
5589
5919
|
handleDeselection() {
|
|
5590
|
-
// Force immediate update of the component state
|
|
5591
5920
|
this.selectedMenuItemId = null;
|
|
5592
5921
|
this.selectedMenuItem = null;
|
|
5593
|
-
// Trigger change detection
|
|
5594
5922
|
setTimeout(() => {
|
|
5595
|
-
// This ensures the UI updates immediately
|
|
5596
5923
|
}, 0);
|
|
5597
5924
|
}
|
|
5925
|
+
/**
|
|
5926
|
+
* Handle the menu item selection
|
|
5927
|
+
* @param {string} menuItemId - The ID of the menu item to select
|
|
5928
|
+
*/
|
|
5598
5929
|
onSelectMenuItem(menuItemId) {
|
|
5599
5930
|
const label = this.findMenuItemLabelById(menuItemId);
|
|
5600
5931
|
if (label) {
|
|
@@ -5604,12 +5935,19 @@ class DocumentsMenuComponent {
|
|
|
5604
5935
|
this.documentMenuService.handleUserListVisibility(menuItemId, this.categories);
|
|
5605
5936
|
}
|
|
5606
5937
|
}
|
|
5938
|
+
/**
|
|
5939
|
+
* Handle the menu item unselection
|
|
5940
|
+
*/
|
|
5607
5941
|
onUnselectMenuItem() {
|
|
5608
5942
|
this.selectedMenuItem = null;
|
|
5609
5943
|
this.selectedMenuItemId = null;
|
|
5610
5944
|
this.documentStore.setSelectedMenuItem(null);
|
|
5611
5945
|
this.documentHelperService.refreshDocumentsWithoutFilters(this.contextId);
|
|
5612
5946
|
}
|
|
5947
|
+
/**
|
|
5948
|
+
* Get the selected menu item
|
|
5949
|
+
* @returns {string | null} - The selected menu item
|
|
5950
|
+
*/
|
|
5613
5951
|
getSelectedMenuItem() {
|
|
5614
5952
|
return this.selectedMenuItem;
|
|
5615
5953
|
}
|
|
@@ -5624,6 +5962,10 @@ class DocumentsMenuComponent {
|
|
|
5624
5962
|
this.documentHelperService.refreshDocumentsWithoutFilters(this.contextId);
|
|
5625
5963
|
}
|
|
5626
5964
|
}
|
|
5965
|
+
/**
|
|
5966
|
+
* Get the selected menu item id
|
|
5967
|
+
* @returns {string | null} - The selected menu item id
|
|
5968
|
+
*/
|
|
5627
5969
|
getSelectedMenuItemId() {
|
|
5628
5970
|
return this.selectedMenuItemId;
|
|
5629
5971
|
}
|
|
@@ -6181,9 +6523,9 @@ class DocumentModule {
|
|
|
6181
6523
|
DocumentActionsComponent,
|
|
6182
6524
|
DocumentSearchComponent,
|
|
6183
6525
|
/**
|
|
6184
|
-
* A
|
|
6526
|
+
* A sidebar component for content projection.
|
|
6185
6527
|
*/
|
|
6186
|
-
|
|
6528
|
+
SidebarComponent], imports: [
|
|
6187
6529
|
/**
|
|
6188
6530
|
* Angular's CommonModule is imported to access common directives like `ngIf` and `ngFor`.
|
|
6189
6531
|
*/
|
|
@@ -6288,9 +6630,9 @@ class DocumentModule {
|
|
|
6288
6630
|
*/
|
|
6289
6631
|
DocumentSearchComponent,
|
|
6290
6632
|
/**
|
|
6291
|
-
* A
|
|
6633
|
+
* A sidebar component for content projection.
|
|
6292
6634
|
*/
|
|
6293
|
-
|
|
6635
|
+
SidebarComponent] });
|
|
6294
6636
|
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentModule, providers: [
|
|
6295
6637
|
/**
|
|
6296
6638
|
* Provide the messageservice to be used in other components.
|
|
@@ -6461,9 +6803,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
6461
6803
|
DocumentActionsComponent,
|
|
6462
6804
|
DocumentSearchComponent,
|
|
6463
6805
|
/**
|
|
6464
|
-
* A
|
|
6806
|
+
* A sidebar component for content projection.
|
|
6465
6807
|
*/
|
|
6466
|
-
|
|
6808
|
+
SidebarComponent,
|
|
6467
6809
|
],
|
|
6468
6810
|
imports: [
|
|
6469
6811
|
/**
|
|
@@ -6572,9 +6914,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
6572
6914
|
*/
|
|
6573
6915
|
DocumentSearchComponent,
|
|
6574
6916
|
/**
|
|
6575
|
-
* A
|
|
6917
|
+
* A sidebar component for content projection.
|
|
6576
6918
|
*/
|
|
6577
|
-
|
|
6919
|
+
SidebarComponent,
|
|
6578
6920
|
],
|
|
6579
6921
|
providers: [
|
|
6580
6922
|
/**
|
|
@@ -6623,5 +6965,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
|
|
|
6623
6965
|
* Generated bundle index. Do not edit.
|
|
6624
6966
|
*/
|
|
6625
6967
|
|
|
6626
|
-
export {
|
|
6968
|
+
export { DocumentActionsComponent, DocumentContainerComponent, DocumentDirective, DocumentHistoryComponent, DocumentListComponent, DocumentModule, DocumentSearchComponent, DocumentTableBuilderService, DocumentViewerComponent, HasPermissionDirective, SidebarComponent };
|
|
6627
6969
|
//# sourceMappingURL=cat-documents-ng.mjs.map
|