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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, EventEmitter, ViewChild, Input, ViewEncapsulation, Component, Output, Directive, NgModule, APP_INITIALIZER } from '@angular/core';
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$1 from 'primeng/inputtextarea';
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/saveDocumentUpload";
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 863660c6-dc2a-4ca5-bae1-0dd177d5c9a9' };
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 863660c6-dc2a-4ca5-bae1-0dd177d5c9a9` });
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 863660c6-dc2a-4ca5-bae1-0dd177d5c9a9` });
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 863660c6-dc2a-4ca5-bae1-0dd177d5c9a9` });
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 863660c6-dc2a-4ca5-bae1-0dd177d5c9a9` });
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 863660c6-dc2a-4ca5-bae1-0dd177d5c9a9` });
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 863660c6-dc2a-4ca5-bae1-0dd177d5c9a9` });
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 863660c6-dc2a-4ca5-bae1-0dd177d5c9a9` });
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 863660c6-dc2a-4ca5-bae1-0dd177d5c9a9` });
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 863660c6-dc2a-4ca5-bae1-0dd177d5c9a9` });
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 863660c6-dc2a-4ca5-bae1-0dd177d5c9a9` });
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 863660c6-dc2a-4ca5-bae1-0dd177d5c9a9` });
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 863660c6-dc2a-4ca5-bae1-0dd177d5c9a9` });
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
- * Validates form data
2460
+ * Helper method to validate form data and return validation result
2438
2461
  */
2439
- validateForm(assignmentType, selectedCategory, selectedDocumentType, selectedApplicant, uploadedFiles, categoryOptions, documentTypeOptions) {
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
- const hasRequiredSelections = Boolean(selectedCategory) && Boolean(selectedDocumentType);
2444
- const hasFiles = uploadedFiles.length > 0;
2445
- if (assignmentType === SHARED.APPLICANT) {
2446
- return hasRequiredSelections && hasFiles && Boolean(selectedApplicant);
2471
+ // Check category
2472
+ if (!selectedCategory) {
2473
+ return { isValid: false, message: SHARED.VALIDATION_SELECT_CATEGORY };
2447
2474
  }
2448
- else {
2449
- return hasRequiredSelections && hasFiles;
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
- const hasBasicData = selectedCategory && selectedDocumentType && uploadedFiles.length > 0;
2457
- if (assignmentType === SHARED.APPLICANT) {
2458
- return !hasBasicData || !selectedApplicant || isSaving;
2504
+ if (isSaving) {
2505
+ return true;
2459
2506
  }
2460
- else {
2461
- return !hasBasicData || isSaving;
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
- fileType: file.file.type,
2477
- file: file.file,
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: 'Applicant',
2511
- selectedApplicant: SHARED.EMPTY,
2512
- selectedCategory: SHARED.EMPTY,
2513
- selectedDocumentType: SHARED.EMPTY,
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
- * Validates required fields for upload
2674
+ * Helper method to validate required fields and show appropriate messages
2572
2675
  */
2573
- validateRequiredFields(assignmentType, selectedApplicant, selectedCategory, selectedDocumentType, uploadedFiles) {
2676
+ validateRequiredFieldsWithMessages(assignmentType, selectedApplicant, selectedCategory, selectedDocumentType, uploadedFiles) {
2574
2677
  if (assignmentType === 'Applicant' && !selectedApplicant) {
2575
- this.showWarningMessage('No Applicant Selected', 'Please select an applicant.');
2576
- return false;
2678
+ return { isValid: false, field: 'applicant' };
2577
2679
  }
2578
2680
  if (!selectedCategory) {
2579
- this.showWarningMessage('No Category Selected', 'Please select a category.');
2580
- return false;
2681
+ return { isValid: false, field: 'category' };
2581
2682
  }
2582
2683
  if (!selectedDocumentType) {
2583
- this.showWarningMessage('No Document Type Selected', 'Please select a document type.');
2584
- return false;
2684
+ return { isValid: false, field: 'documentType' };
2585
2685
  }
2586
2686
  if (uploadedFiles.length === 0) {
2587
- this.showWarningMessage('No Documents Uploaded', 'Please upload at least one document.');
2588
- return false;
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('Form Incomplete', 'Please complete all required fields and upload at least one document.');
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('Missing Required Data', message);
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
- // Form data
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
- // Data lists
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
- // File upload
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
- // Loading states
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
- // Validation
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
- // Event handlers
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.loadDocumentTypesIfCategorySelected();
2727
- this.validateForm();
2728
- }
2729
- onDocumentTypeChange() {
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((file) => {
2737
- this.handleTemplatedUpload(file);
2738
- });
2928
+ event.currentFiles.forEach(file => this.handleTemplatedUpload(file));
2739
2929
  this.fileUploader.clear();
2740
2930
  }
2741
- // Data loading methods
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.handleApplicantsError(error)).pipe(takeUntil(this.destroy$)).subscribe({
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.handleApplicantsError(error)
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.handleCategoriesError(error)).pipe(takeUntil(this.destroy$)).subscribe({
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.handleCategoriesError(error)
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.handleDocumentTypesError(error)).pipe(takeUntil(this.destroy$)).subscribe({
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.handleDocumentTypesError(error)
2961
+ error: (error) => this.handleError('Failed to Load Document Types', error, () => this.isLoadingDocumentTypes = false)
2761
2962
  });
2762
2963
  }
2763
- // Business logic methods
2964
+ /**
2965
+ * Saves the document upload with all metadata.
2966
+ * Validates payload and required fields before proceeding with upload.
2967
+ */
2764
2968
  saveDocumentUpload() {
2765
- if (!this.isFormValid) {
2766
- this.formService.validateFormCompleteness();
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.documentUpload.uploadCompleted.pipe(takeUntil(this.destroy$)).subscribe(({ file: uploadedFile, response }) => {
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.validateForm();
3005
+ this.validateAndEmit();
2801
3006
  this.cdr.detectChanges();
2802
3007
  }
2803
- // Utility methods
2804
- choose(event, callback) {
2805
- callback();
2806
- }
2807
- triggerFileUpload() {
2808
- this.fileUploader.choose();
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
- return this.businessService.isSaveButtonDisabled(this.selectedAssignmentType, this.selectedCategory, this.selectedDocumentType, this.selectedApplicant, this.uploadedFiles, this.isSaving);
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
- isFileUploaded(file) {
2821
- const progress = this.fileProgress.get(file);
2822
- return progress === SHARED.UPLOAD_PROGRESS_100;
2823
- }
2824
- isFileError(file) {
2825
- const progress = this.fileProgress.get(file);
2826
- return progress === -1;
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 = SHARED.EMPTY_ARRAY;
3061
+ this.filteredApplicantList = [];
3062
+ this.categoryOptions = [];
3063
+ this.documentTypeOptions = [];
2833
3064
  this.cdr.detectChanges();
2834
3065
  }
2835
- // Private helper methods
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
- loadDocumentTypesIfCategorySelected() {
2855
- if (this.selectedCategory) {
2856
- this.loadDocumentTypes();
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
- handleApplicantsError(error) {
2866
- this.isLoadingApplicants = false;
2867
- this.formService.showErrorMessage('Failed to Load Applicants', error?.message || 'Failed to load applicants');
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
- handleCategoriesError(error) {
2875
- this.isLoadingCategories = false;
2876
- this.formService.showErrorMessage('Failed to Load Categories', error?.message || 'Failed to load categories');
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
- handleDocumentTypesError(error) {
2884
- this.isLoadingDocumentTypes = false;
2885
- this.formService.showErrorMessage('Failed to Load Document Types', error?.message || 'Failed to load document types');
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
- this.isFormValid = this.businessService.validateForm(this.selectedAssignmentType, this.selectedCategory, this.selectedDocumentType, this.selectedApplicant, this.uploadedFiles, this.categoryOptions, this.documentTypeOptions);
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
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FolderContainerComponent, deps: [{ token: DocumentQuery }], target: i0.ɵɵFactoryTarget.Component });
3549
- 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 }], 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-common-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 [modal]=\"true\"\r\n [dismissible]=\"true\"\r\n [closeOnEscape]=\"true\"\r\n [blockScroll]=\"true\"\r\n (onHide)=\"onDocumentUploadSidebarHide()\"\r\n (onSave)=\"onDocumentUploadSave()\"\r\n>\r\n <lib-document-upload [contextId]=\"contextId\"></lib-document-upload>\r\n</lib-common-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"] }, { 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: CommonSidebarComponent, selector: "lib-common-sidebar", inputs: ["visible", "position", "width", "title", "showCloseButton", "modal", "dismissible", "closeOnEscape", "baseZIndex", "autoZIndex", "styleClass", "appendTo", "blockScroll", "closeIcon", "showSaveButton", "saveButtonText", "saveButtonDisabled"], outputs: ["visibleChange", "onShow", "onHide", "onSave"] }], animations: [
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-common-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 [modal]=\"true\"\r\n [dismissible]=\"true\"\r\n [closeOnEscape]=\"true\"\r\n [blockScroll]=\"true\"\r\n (onHide)=\"onDocumentUploadSidebarHide()\"\r\n (onSave)=\"onDocumentUploadSave()\"\r\n>\r\n <lib-document-upload [contextId]=\"contextId\"></lib-document-upload>\r\n</lib-common-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"] }]
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, // Keep existing history
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, // Keep existing document
4151
- history, true // Show history
4152
- );
4551
+ this.documentStore.updateDocumentViewerState(undefined, history, true);
4153
4552
  },
4154
4553
  error: (error) => {
4155
- this.documentStore.updateDocumentViewerState(undefined, // Keep existing document
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
- sessionService;
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
- // Ensure the URL is properly formatted
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 }, { type: SessionService }, { type: AppConfigService }] });
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]=\"1\"\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=\"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$2.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 });
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]=\"1\"\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=\"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"] }]
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 common sidebar component for content projection.
6526
+ * A sidebar component for content projection.
6185
6527
  */
6186
- CommonSidebarComponent], imports: [
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 common sidebar component for content projection.
6633
+ * A sidebar component for content projection.
6292
6634
  */
6293
- CommonSidebarComponent] });
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 common sidebar component for content projection.
6806
+ * A sidebar component for content projection.
6465
6807
  */
6466
- CommonSidebarComponent,
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 common sidebar component for content projection.
6917
+ * A sidebar component for content projection.
6576
6918
  */
6577
- CommonSidebarComponent,
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 { CommonSidebarComponent, DocumentActionsComponent, DocumentContainerComponent, DocumentDirective, DocumentHistoryComponent, DocumentListComponent, DocumentModule, DocumentSearchComponent, DocumentTableBuilderService, DocumentViewerComponent, HasPermissionDirective };
6968
+ export { DocumentActionsComponent, DocumentContainerComponent, DocumentDirective, DocumentHistoryComponent, DocumentListComponent, DocumentModule, DocumentSearchComponent, DocumentTableBuilderService, DocumentViewerComponent, HasPermissionDirective, SidebarComponent };
6627
6969
  //# sourceMappingURL=cat-documents-ng.mjs.map