cat-documents-ng 0.2.43 → 0.2.44

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,8 +1,8 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, EventEmitter, Output, Input, Component, Directive, ViewChild, ViewEncapsulation, NgModule, APP_INITIALIZER } from '@angular/core';
2
+ import { Injectable, EventEmitter, Output, Input, Component, ViewChild, ViewEncapsulation, Directive, NgModule, APP_INITIALIZER } from '@angular/core';
3
3
  import * as i5 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
- import { firstValueFrom, tap, EMPTY, catchError, throwError, of, combineLatest, Subscription, Subject, takeUntil, debounceTime as debounceTime$1, distinctUntilChanged as distinctUntilChanged$1, BehaviorSubject } from 'rxjs';
5
+ import { firstValueFrom, tap, EMPTY, catchError, throwError, of, combineLatest, Subscription, Subject, takeUntil, debounceTime as debounceTime$1, distinctUntilChanged as distinctUntilChanged$1 } from 'rxjs';
6
6
  import { __decorate } from 'tslib';
7
7
  import { EntityStore, StoreConfig, QueryEntity } from '@datorama/akita';
8
8
  import * as i2 from '@angular/common/http';
@@ -13,6 +13,7 @@ import * as i3 from '@angular/forms';
13
13
  import { FormsModule } from '@angular/forms';
14
14
  import * as i3$1 from 'primeng/api';
15
15
  import { MessageService } from 'primeng/api';
16
+ import * as i1 from '@angular/router';
16
17
  import * as i4 from 'primeng/button';
17
18
  import { ButtonModule } from 'primeng/button';
18
19
  import * as i10 from 'primeng/sidebar';
@@ -28,7 +29,6 @@ import * as i2$1 from 'primeng/table';
28
29
  import { TableModule } from 'primeng/table';
29
30
  import * as i5$1 from 'primeng/ripple';
30
31
  import { RippleModule } from 'primeng/ripple';
31
- import * as i1 from '@angular/router';
32
32
  import * as i7 from 'primeng/fileupload';
33
33
  import { FileUploadModule } from 'primeng/fileupload';
34
34
  import * as i8 from 'primeng/progressbar';
@@ -55,6 +55,14 @@ import { PanelMenuModule } from 'primeng/panelmenu';
55
55
  * These constants are related to document statuses and other shared data.
56
56
  */
57
57
  class SHARED {
58
+ /**
59
+ * Represents the info.
60
+ */
61
+ static UNKNOWN_USER = 'Unknown User';
62
+ /**
63
+ * Represents the info.
64
+ */
65
+ static ACTIONS = 'actions';
58
66
  /**
59
67
  * Represents the info.
60
68
  */
@@ -63,6 +71,7 @@ class SHARED {
63
71
  * Represents the info.
64
72
  */
65
73
  static HIDDEN = 'hidden';
74
+ static NO_DOCUMENTS_FOUND = 'No documents found';
66
75
  static DOCUMENT_TYPES_DELETE = 'DocumentTypes-DELETE';
67
76
  /**
68
77
  * Represents the info.
@@ -791,7 +800,15 @@ function createInitialState() {
791
800
  currentDocument: null,
792
801
  userList: [],
793
802
  statusData: [],
794
- documentListResponse: null
803
+ documentListResponse: null,
804
+ // Document Viewer State
805
+ selectedDocument: undefined,
806
+ documentHistory: [],
807
+ showDocumentHistory: false,
808
+ isActionLoading: false,
809
+ documentStatus: 'pending',
810
+ documentIsUploaded: false,
811
+ alertData: null
795
812
  };
796
813
  }
797
814
 
@@ -885,6 +902,59 @@ let DocumentStore = class DocumentStore extends EntityStore {
885
902
  setDocumentListResponse(response) {
886
903
  this.update({ documentListResponse: response });
887
904
  }
905
+ // Document Viewer State Management Methods
906
+ setSelectedDocument(document) {
907
+ this.update({ selectedDocument: document });
908
+ }
909
+ setDocumentHistory(history) {
910
+ this.update({ documentHistory: history });
911
+ }
912
+ setShowDocumentHistory(show) {
913
+ this.update({ showDocumentHistory: show });
914
+ }
915
+ setIsActionLoading(loading) {
916
+ this.update({ isActionLoading: loading });
917
+ }
918
+ setDocumentStatus(status) {
919
+ this.update({ documentStatus: status });
920
+ }
921
+ setDocumentIsUploaded(uploaded) {
922
+ this.update({ documentIsUploaded: uploaded });
923
+ }
924
+ setAlertData(alertData) {
925
+ this.update({ alertData: alertData });
926
+ }
927
+ // Method to update all document viewer state at once
928
+ updateDocumentViewerState(document, history, showHistory, loading, status, uploaded, alertData) {
929
+ const updates = {};
930
+ if (document !== undefined)
931
+ updates.selectedDocument = document;
932
+ if (history !== undefined)
933
+ updates.documentHistory = history;
934
+ if (showHistory !== undefined)
935
+ updates.showDocumentHistory = showHistory;
936
+ if (loading !== undefined)
937
+ updates.isActionLoading = loading;
938
+ if (status !== undefined)
939
+ updates.documentStatus = status;
940
+ if (uploaded !== undefined)
941
+ updates.documentIsUploaded = uploaded;
942
+ if (alertData !== undefined)
943
+ updates.alertData = alertData;
944
+ this.update(updates);
945
+ }
946
+ // Method to clear document viewer state
947
+ clearDocumentViewerState() {
948
+ this.update({
949
+ selectedDocument: undefined,
950
+ documentHistory: [],
951
+ showDocumentHistory: false,
952
+ isActionLoading: false,
953
+ documentStatus: 'pending',
954
+ documentIsUploaded: false,
955
+ alertData: null
956
+ });
957
+ }
888
958
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
889
959
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentStore, providedIn: 'root' });
890
960
  };
@@ -1313,6 +1383,136 @@ class DocumentQuery extends QueryEntity {
1313
1383
  getDocumentListResponse() {
1314
1384
  return this.getValue().documentListResponse;
1315
1385
  }
1386
+ // Document Viewer State Query Methods
1387
+ /**
1388
+ * Selects the selected document for viewing.
1389
+ * @returns {Observable<DocumentListItem | undefined>} Observable that emits the selected document.
1390
+ */
1391
+ selectSelectedDocument() {
1392
+ return this.select((state) => state.selectedDocument);
1393
+ }
1394
+ /**
1395
+ * Gets the current selected document value (synchronous).
1396
+ * @returns {DocumentListItem | undefined} The current selected document.
1397
+ */
1398
+ getSelectedDocument() {
1399
+ return this.getValue().selectedDocument;
1400
+ }
1401
+ /**
1402
+ * Selects the document history.
1403
+ * @returns {Observable<DocumentHistorySection[]>} Observable that emits the document history.
1404
+ */
1405
+ selectDocumentHistory() {
1406
+ return this.select((state) => state.documentHistory);
1407
+ }
1408
+ /**
1409
+ * Gets the current document history value (synchronous).
1410
+ * @returns {DocumentHistorySection[]} The current document history.
1411
+ */
1412
+ getDocumentHistory() {
1413
+ return this.getValue().documentHistory;
1414
+ }
1415
+ /**
1416
+ * Selects the document history visibility state.
1417
+ * @returns {Observable<boolean>} Observable that emits the current document history visibility.
1418
+ */
1419
+ selectShowDocumentHistory() {
1420
+ return this.select((state) => state.showDocumentHistory);
1421
+ }
1422
+ /**
1423
+ * Gets the current document history visibility value (synchronous).
1424
+ * @returns {boolean} The current document history visibility.
1425
+ */
1426
+ getShowDocumentHistory() {
1427
+ return this.getValue().showDocumentHistory;
1428
+ }
1429
+ /**
1430
+ * Selects the action loading state.
1431
+ * @returns {Observable<boolean>} Observable that emits the current action loading state.
1432
+ */
1433
+ selectIsActionLoading() {
1434
+ return this.select((state) => state.isActionLoading);
1435
+ }
1436
+ /**
1437
+ * Gets the current action loading value (synchronous).
1438
+ * @returns {boolean} The current action loading state.
1439
+ */
1440
+ getIsActionLoading() {
1441
+ return this.getValue().isActionLoading;
1442
+ }
1443
+ /**
1444
+ * Selects the document status.
1445
+ * @returns {Observable<'pending' | 'accepted' | 'rejected'>} Observable that emits the current document status.
1446
+ */
1447
+ selectDocumentStatus() {
1448
+ return this.select((state) => state.documentStatus);
1449
+ }
1450
+ /**
1451
+ * Gets the current document status value (synchronous).
1452
+ * @returns {'pending' | 'accepted' | 'rejected'} The current document status.
1453
+ */
1454
+ getDocumentStatus() {
1455
+ return this.getValue().documentStatus;
1456
+ }
1457
+ /**
1458
+ * Selects the document uploaded state.
1459
+ * @returns {Observable<boolean>} Observable that emits the current document uploaded state.
1460
+ */
1461
+ selectDocumentIsUploaded() {
1462
+ return this.select((state) => state.documentIsUploaded);
1463
+ }
1464
+ /**
1465
+ * Gets the current document uploaded value (synchronous).
1466
+ * @returns {boolean} The current document uploaded state.
1467
+ */
1468
+ getDocumentIsUploaded() {
1469
+ return this.getValue().documentIsUploaded;
1470
+ }
1471
+ /**
1472
+ * Selects the alert data.
1473
+ * @returns {Observable<any>} Observable that emits the current alert data.
1474
+ */
1475
+ selectAlertData() {
1476
+ return this.select((state) => state.alertData);
1477
+ }
1478
+ /**
1479
+ * Gets the current alert data value (synchronous).
1480
+ * @returns {any} The current alert data.
1481
+ */
1482
+ getAlertData() {
1483
+ return this.getValue().alertData;
1484
+ }
1485
+ /**
1486
+ * Selects all document viewer state properties.
1487
+ * @returns {Observable<{selectedDocument?: DocumentListItem, documentHistory: DocumentHistorySection[], showDocumentHistory: boolean, isActionLoading: boolean, documentStatus: 'pending' | 'accepted' | 'rejected', documentIsUploaded: boolean, alertData: any}>} Observable that emits the current document viewer state.
1488
+ */
1489
+ selectDocumentViewerState() {
1490
+ return this.select((state) => ({
1491
+ selectedDocument: state.selectedDocument,
1492
+ documentHistory: state.documentHistory,
1493
+ showDocumentHistory: state.showDocumentHistory,
1494
+ isActionLoading: state.isActionLoading,
1495
+ documentStatus: state.documentStatus,
1496
+ documentIsUploaded: state.documentIsUploaded,
1497
+ alertData: state.alertData
1498
+ }));
1499
+ }
1500
+ /**
1501
+ * Gets the current document viewer state values (synchronous).
1502
+ * @returns {Object} The current document viewer state values.
1503
+ */
1504
+ getDocumentViewerState() {
1505
+ const state = this.getValue();
1506
+ return {
1507
+ selectedDocument: state.selectedDocument,
1508
+ documentHistory: state.documentHistory,
1509
+ showDocumentHistory: state.showDocumentHistory,
1510
+ isActionLoading: state.isActionLoading,
1511
+ documentStatus: state.documentStatus,
1512
+ documentIsUploaded: state.documentIsUploaded,
1513
+ alertData: state.alertData
1514
+ };
1515
+ }
1316
1516
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentQuery, deps: [{ token: DocumentStore }], target: i0.ɵɵFactoryTarget.Injectable });
1317
1517
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentQuery, providedIn: 'root' });
1318
1518
  }
@@ -1542,13 +1742,16 @@ class DocumentHttpService {
1542
1742
  }
1543
1743
  }
1544
1744
  /**
1545
- * Deletes a document by its ID and refreshes the document list
1745
+ * Deletes a document by its ID and refreshes all data (categories, userlist, status, and document list)
1546
1746
  * @param {string} documentId - The ID of the document to delete
1547
- * @param {string} contextId - The context ID to refresh the document list
1747
+ * @param {string} contextId - The context ID to refresh all data
1548
1748
  * @returns {Observable<any>} Observable that emits the delete response
1549
1749
  */
1550
1750
  deleteDocument(documentId, contextId) {
1551
1751
  return this.http.delete(`${this.apiUrl}${URLS.DELETE_DOCUMENT}${documentId}`).pipe(tap(() => {
1752
+ this.getDocumentCatagories(contextId).subscribe();
1753
+ this.getUserListByContextId(contextId).subscribe();
1754
+ this.getStatusDocumentCount(contextId).subscribe();
1552
1755
  this.getDocumentsBySelection(contextId, null, null, null, null).subscribe();
1553
1756
  }), catchError((error) => {
1554
1757
  return throwError(() => new Error(error));
@@ -1755,15 +1958,17 @@ class DocumentHelperService {
1755
1958
  });
1756
1959
  }
1757
1960
  /**
1758
- * Refresh all data with current filters after accept/reject operations
1759
- * This includes status data, user list, and document list
1961
+ * Refresh all data with current filters after accept/reject/delete operations
1962
+ * This includes document categories, status data, user list, and document list
1760
1963
  *
1761
- * This method ensures that after a document status change (accept/reject):
1762
- * 1. Status counts are refreshed with current menu item and user filters
1763
- * 2. User list is refreshed with current filters (if applicable)
1764
- * 3. Document list is refreshed with all current filters (menu item, user, status, search)
1964
+ * This method ensures that after a document action (accept/reject/delete):
1965
+ * 1. Document categories are refreshed
1966
+ * 2. Status counts are refreshed with current menu item and user filters
1967
+ * 3. User list is refreshed with current filters (if applicable)
1968
+ * 4. Document list is refreshed with all current filters (menu item, user, status, search)
1765
1969
  *
1766
1970
  * Filter application:
1971
+ * - Document categories: Uses base contextId
1767
1972
  * - Status data: Uses userId as contextId and menuItem as categoryId
1768
1973
  * - User list: Uses base contextId (can be enhanced with additional filters if API supports)
1769
1974
  * - Document list: Uses all current filters (menuItem, userId, status, searchKey)
@@ -1774,6 +1979,16 @@ class DocumentHelperService {
1774
1979
  const currentState = this.documentQuery.getSelectionState();
1775
1980
  const statusContextId = currentState.userId || null;
1776
1981
  const categoryId = currentState.menuItem || null;
1982
+ // Refresh document categories
1983
+ this.documentHttpService.getDocumentCatagories(contextId).subscribe({
1984
+ next: (categories) => {
1985
+ this.documentStore.setDocumentCategories(categories);
1986
+ },
1987
+ error: (error) => {
1988
+ console.error('Error refreshing document categories after action:', error);
1989
+ }
1990
+ });
1991
+ // Refresh status data
1777
1992
  this.documentHttpService.getStatusDocumentCount(contextId, statusContextId, categoryId).subscribe({
1778
1993
  next: (statusData) => {
1779
1994
  this.documentStore.setStatusData(statusData);
@@ -1782,6 +1997,7 @@ class DocumentHelperService {
1782
1997
  console.error('Error refreshing status data after action:', error);
1783
1998
  }
1784
1999
  });
2000
+ // Refresh user list
1785
2001
  this.documentHttpService.getUserListByContextId(contextId).subscribe({
1786
2002
  next: (userList) => {
1787
2003
  this.documentStore.setUserList(userList);
@@ -1790,6 +2006,7 @@ class DocumentHelperService {
1790
2006
  console.error('Error refreshing user list after action:', error);
1791
2007
  }
1792
2008
  });
2009
+ // Refresh document list
1793
2010
  this.refreshDocumentsWithCurrentSelection(contextId);
1794
2011
  }
1795
2012
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentHelperService, deps: [{ token: DocumentStore }, { token: DocumentQuery }, { token: DocumentHttpService }], target: i0.ɵɵFactoryTarget.Injectable });
@@ -2179,11 +2396,11 @@ class DocumentSearchComponent {
2179
2396
  // Subject for handling search input changes
2180
2397
  searchSubject = new Subject();
2181
2398
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentSearchComponent, deps: [{ token: DocumentHelperService }], target: i0.ɵɵFactoryTarget.Component });
2182
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DocumentSearchComponent, isStandalone: false, selector: "document-search", inputs: { contextId: "contextId" }, 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</div> ", styles: [".search-container{padding:1rem;background:#f8fafc;border-bottom:1px solid #e2e8f0}.search-input-wrapper{position:relative;width:40%;display:flex;align-items:center;background:#fff;border:1px solid #d1d5db;border-radius:8px;padding:.75rem 1rem;transition:all .2s ease;box-shadow:0 1px 3px #0000001a}.search-input-wrapper:focus-within{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61a}.search-icon{color:#6b7280;margin-right:.75rem;font-size:1rem}.search-input{flex:1;border:none;outline:none;background:transparent;color:#374151}.search-input::placeholder{color:#9ca3af}.search-input:focus{outline:none}.clear-button{background:none;border:none;color:#6b7280;cursor:pointer;padding:.25rem;border-radius:4px;transition:all .2s ease;display:flex;align-items:center;justify-content:center}.clear-button:hover{background-color:#f3f4f6;color:#374151}.clear-button:focus{outline:none;box-shadow:0 0 0 2px #3b82f633}.clear-button i{font-size:.875rem}@media (max-width: 768px){.search-container{padding:.75rem}.search-input-wrapper{padding:.5rem .75rem}.search-input{font-size:.8rem}}\n"], dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
2399
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DocumentSearchComponent, isStandalone: false, selector: "document-search", inputs: { contextId: "contextId" }, 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</div> ", styles: [".search-container{padding:1rem}.search-input-wrapper{position:relative;width:40%;display:flex;align-items:center;background:#fff;border:1px solid #d1d5db;border-radius:8px;padding:.75rem 1rem;transition:all .2s ease;box-shadow:0 1px 3px #0000001a}.search-input-wrapper:focus-within{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61a}.search-icon{color:#6b7280;margin-right:.75rem;font-size:1rem}.search-input{flex:1;border:none;outline:none;background:transparent;color:#374151}.search-input::placeholder{color:#9ca3af}.search-input:focus{outline:none}.clear-button{background:none;border:none;color:#6b7280;cursor:pointer;padding:.25rem;border-radius:4px;transition:all .2s ease;display:flex;align-items:center;justify-content:center}.clear-button:hover{background-color:#f3f4f6;color:#374151}.clear-button:focus{outline:none;box-shadow:0 0 0 2px #3b82f633}.clear-button i{font-size:.875rem}@media (max-width: 768px){.search-container{padding:.75rem}.search-input-wrapper{padding:.5rem .75rem}.search-input{font-size:.8rem}}\n"], dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
2183
2400
  }
2184
2401
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentSearchComponent, decorators: [{
2185
2402
  type: Component,
2186
- 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</div> ", styles: [".search-container{padding:1rem;background:#f8fafc;border-bottom:1px solid #e2e8f0}.search-input-wrapper{position:relative;width:40%;display:flex;align-items:center;background:#fff;border:1px solid #d1d5db;border-radius:8px;padding:.75rem 1rem;transition:all .2s ease;box-shadow:0 1px 3px #0000001a}.search-input-wrapper:focus-within{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61a}.search-icon{color:#6b7280;margin-right:.75rem;font-size:1rem}.search-input{flex:1;border:none;outline:none;background:transparent;color:#374151}.search-input::placeholder{color:#9ca3af}.search-input:focus{outline:none}.clear-button{background:none;border:none;color:#6b7280;cursor:pointer;padding:.25rem;border-radius:4px;transition:all .2s ease;display:flex;align-items:center;justify-content:center}.clear-button:hover{background-color:#f3f4f6;color:#374151}.clear-button:focus{outline:none;box-shadow:0 0 0 2px #3b82f633}.clear-button i{font-size:.875rem}@media (max-width: 768px){.search-container{padding:.75rem}.search-input-wrapper{padding:.5rem .75rem}.search-input{font-size:.8rem}}\n"] }]
2403
+ 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</div> ", styles: [".search-container{padding:1rem}.search-input-wrapper{position:relative;width:40%;display:flex;align-items:center;background:#fff;border:1px solid #d1d5db;border-radius:8px;padding:.75rem 1rem;transition:all .2s ease;box-shadow:0 1px 3px #0000001a}.search-input-wrapper:focus-within{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61a}.search-icon{color:#6b7280;margin-right:.75rem;font-size:1rem}.search-input{flex:1;border:none;outline:none;background:transparent;color:#374151}.search-input::placeholder{color:#9ca3af}.search-input:focus{outline:none}.clear-button{background:none;border:none;color:#6b7280;cursor:pointer;padding:.25rem;border-radius:4px;transition:all .2s ease;display:flex;align-items:center;justify-content:center}.clear-button:hover{background-color:#f3f4f6;color:#374151}.clear-button:focus{outline:none;box-shadow:0 0 0 2px #3b82f633}.clear-button i{font-size:.875rem}@media (max-width: 768px){.search-container{padding:.75rem}.search-input-wrapper{padding:.5rem .75rem}.search-input{font-size:.8rem}}\n"] }]
2187
2404
  }], ctorParameters: () => [{ type: DocumentHelperService }], propDecorators: { contextId: [{
2188
2405
  type: Input
2189
2406
  }] } });
@@ -2489,75 +2706,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
2489
2706
  }]
2490
2707
  }], ctorParameters: () => [{ type: DocumentService }, { type: DocumentStore }, { type: i3$1.MessageService }] });
2491
2708
 
2492
- class DocumentTableBuilderService {
2493
- constructor() { }
2494
- /**
2495
- * Builds a single table from document list items
2496
- * @param documents Array of document list items
2497
- * @returns TableData object
2498
- */
2499
- buildDocumentTable(documents) {
2500
- return {
2501
- columns: SHARED.DOCUMENT_TABLE_COLUMNS,
2502
- data: documents
2503
- };
2504
- }
2505
- /**
2506
- * Gets completion count for a category
2507
- * @param category Document category
2508
- * @returns Completion string (e.g., "2/4")
2509
- */
2510
- getCompletionCount(category) {
2511
- const total = category.list.length;
2512
- const completed = category.list.filter(doc => doc.status.toLowerCase() === SHARED.APPROVED ||
2513
- doc.status.toLowerCase() === SHARED.UPLOADED).length;
2514
- return `${completed}/${total}`;
2515
- }
2516
- /**
2517
- * Gets pending document count for a category
2518
- * @param category Document category
2519
- * @returns Number of pending documents
2520
- */
2521
- getPendingDocumentCount(category) {
2522
- return category.totalDocs - category.acceptedDocs;
2523
- }
2524
- /**
2525
- * Gets approved document count for a category
2526
- * @param category Document category
2527
- * @returns Number of approved documents
2528
- */
2529
- getApprovedDocumentCount(category) {
2530
- return category.acceptedDocs;
2531
- }
2532
- /**
2533
- * Transforms document model to document list item
2534
- * @param documents Array of DocumentModel
2535
- * @returns Array of DocumentListItem
2536
- */
2537
- transformDocumentModelToListItem(documents) {
2538
- return documents.map(doc => ({
2539
- _id: doc._id || SHARED.EMPTY,
2540
- fileName: doc.fileName || SHARED.EMPTY,
2541
- docName: doc.docName || doc.documentName || SHARED.EMPTY,
2542
- fileSize: doc.fileSize || SHARED.EMPTY,
2543
- documentUrl: doc.documentUrl || doc.url || SHARED.EMPTY,
2544
- status: doc.status || SHARED.PENDING,
2545
- uploadedOn: doc.uploadedOn || doc.uploadDate || SHARED.EMPTY,
2546
- ownerName: doc.ownerName || doc.applicantName || SHARED.EMPTY,
2547
- contentType: doc.contentType || SHARED.EMPTY,
2548
- isUploaded: doc.isUploaded || false
2549
- }));
2550
- }
2551
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentTableBuilderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2552
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentTableBuilderService, providedIn: 'root' });
2553
- }
2554
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentTableBuilderService, decorators: [{
2555
- type: Injectable,
2556
- args: [{
2557
- providedIn: 'root'
2558
- }]
2559
- }], ctorParameters: () => [] });
2560
-
2561
2709
  /**
2562
2710
  * Service for managing user session details.
2563
2711
  * @class SessionService
@@ -2632,76 +2780,88 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
2632
2780
  }]
2633
2781
  }], ctorParameters: () => [{ type: i1.Router }] });
2634
2782
 
2635
- /**
2636
- * Directive to conditionally show or hide elements based on user permissions.
2637
- * @class HasPermissionDirective
2638
- * @typedef {HasPermissionDirective}
2639
- */
2640
- class HasPermissionDirective {
2641
- el;
2642
- renderer;
2783
+ class DocumentTableBuilderService {
2643
2784
  sessionService;
2785
+ constructor(sessionService) {
2786
+ this.sessionService = sessionService;
2787
+ }
2644
2788
  /**
2645
- * The required permission(s) to display the element.
2646
- * Accepts a single string or an array of strings.
2647
- * @type {string | string[]}
2789
+ * Builds a single table from document list items
2790
+ * @param documents Array of document list items
2791
+ * @returns TableData object
2648
2792
  */
2649
- permission;
2793
+ buildDocumentTable(documents) {
2794
+ const userPermissionsObjects = this.sessionService.getUserPermissions();
2795
+ const userPermissionNames = userPermissionsObjects?.map((perm) => perm.name) || [];
2796
+ const hasDeletePermission = userPermissionNames.includes(SHARED.DOCUMENT_TYPES_DELETE);
2797
+ const columns = SHARED.DOCUMENT_TABLE_COLUMNS.filter(col => {
2798
+ // Always include non-action columns
2799
+ if (col.type !== SHARED.ACTIONS) {
2800
+ return true;
2801
+ }
2802
+ // Only include action column if user has delete permission
2803
+ return hasDeletePermission;
2804
+ });
2805
+ return {
2806
+ columns: columns,
2807
+ data: documents
2808
+ };
2809
+ }
2650
2810
  /**
2651
- * Creates an instance of HasPermissionDirective.
2652
- * @param {ElementRef} el - Reference to the host element.
2653
- * @param {Renderer2} renderer - Angular Renderer for DOM manipulation.
2654
- * @param {SessionService} sessionService - Service to retrieve user permissions.
2811
+ * Gets completion count for a category
2812
+ * @param category Document category
2813
+ * @returns Completion string (e.g., "2/4")
2655
2814
  */
2656
- constructor(el, renderer, sessionService) {
2657
- this.el = el;
2658
- this.renderer = renderer;
2659
- this.sessionService = sessionService;
2815
+ getCompletionCount(category) {
2816
+ const total = category.list.length;
2817
+ const completed = category.list.filter(doc => doc.status.toLowerCase() === SHARED.APPROVED ||
2818
+ doc.status.toLowerCase() === SHARED.UPLOADED).length;
2819
+ return `${completed}/${total}`;
2660
2820
  }
2661
2821
  /**
2662
- * Lifecycle hook that is called when input properties change.
2663
- * @param {SimpleChanges} changes - The changes in input properties.
2822
+ * Gets pending document count for a category
2823
+ * @param category Document category
2824
+ * @returns Number of pending documents
2664
2825
  */
2665
- ngOnChanges(changes) {
2666
- if (changes['permission']) {
2667
- this.checkPermission();
2668
- }
2826
+ getPendingDocumentCount(category) {
2827
+ return category.totalDocs - category.acceptedDocs;
2669
2828
  }
2670
2829
  /**
2671
- * Checks if the user has the required permission(s).
2672
- * Hides the element if the permission is not found.
2830
+ * Gets approved document count for a category
2831
+ * @param category Document category
2832
+ * @returns Number of approved documents
2673
2833
  */
2674
- checkPermission() {
2675
- // If no permission is required (empty string, null, or undefined), show the element
2676
- if (!this.permission || this.permission === '' || (Array.isArray(this.permission) && this.permission.length === 0)) {
2677
- this.renderer.removeStyle(this.el.nativeElement, 'display');
2678
- return;
2679
- }
2680
- const userPermissionsObjects = this.sessionService.getUserPermissions();
2681
- const userPermissionNames = userPermissionsObjects?.map((perm) => perm.name) || [];
2682
- const requiredPermissions = Array.isArray(this.permission)
2683
- ? this.permission
2684
- : [this.permission];
2685
- const hasPermission = requiredPermissions.some(permission => userPermissionNames.includes(permission));
2686
- if (!hasPermission) {
2687
- this.renderer.setStyle(this.el.nativeElement, 'display', 'none');
2688
- }
2689
- else {
2690
- this.renderer.removeStyle(this.el.nativeElement, 'display');
2691
- }
2834
+ getApprovedDocumentCount(category) {
2835
+ return category.acceptedDocs;
2692
2836
  }
2693
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: HasPermissionDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: SessionService }], target: i0.ɵɵFactoryTarget.Directive });
2694
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.14", type: HasPermissionDirective, isStandalone: false, selector: "[permission]", inputs: { permission: "permission" }, usesOnChanges: true, ngImport: i0 });
2837
+ /**
2838
+ * Transforms document model to document list item
2839
+ * @param documents Array of DocumentModel
2840
+ * @returns Array of DocumentListItem
2841
+ */
2842
+ transformDocumentModelToListItem(documents) {
2843
+ return documents.map(doc => ({
2844
+ _id: doc._id || SHARED.EMPTY,
2845
+ fileName: doc.fileName || SHARED.EMPTY,
2846
+ docName: doc.docName || doc.documentName || SHARED.EMPTY,
2847
+ fileSize: doc.fileSize || SHARED.EMPTY,
2848
+ documentUrl: doc.documentUrl || doc.url || SHARED.EMPTY,
2849
+ status: doc.status || SHARED.PENDING,
2850
+ uploadedOn: doc.uploadedOn || doc.uploadDate || SHARED.EMPTY,
2851
+ ownerName: doc.ownerName || doc.applicantName || SHARED.EMPTY,
2852
+ contentType: doc.contentType || SHARED.EMPTY,
2853
+ isUploaded: doc.isUploaded || false
2854
+ }));
2855
+ }
2856
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentTableBuilderService, deps: [{ token: SessionService }], target: i0.ɵɵFactoryTarget.Injectable });
2857
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentTableBuilderService, providedIn: 'root' });
2695
2858
  }
2696
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: HasPermissionDirective, decorators: [{
2697
- type: Directive,
2859
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentTableBuilderService, decorators: [{
2860
+ type: Injectable,
2698
2861
  args: [{
2699
- selector: '[permission]',
2700
- standalone: false
2862
+ providedIn: 'root'
2701
2863
  }]
2702
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: SessionService }], propDecorators: { permission: [{
2703
- type: Input
2704
- }] } });
2864
+ }], ctorParameters: () => [{ type: SessionService }] });
2705
2865
 
2706
2866
  class TablePrimaryComponent {
2707
2867
  tableData = { columns: [], data: [] };
@@ -2784,11 +2944,11 @@ class TablePrimaryComponent {
2784
2944
  this.rowClick.emit(rowData);
2785
2945
  }
2786
2946
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: TablePrimaryComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2787
- 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\" [permission]=\"col.header === 'Actions' ? 'Documents-DELETE' : ''\">\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\r\n <button [permission]=\"'Documents-DELETE'\" pButton pRipple type=\"button\" [icon]=\"SHARED.ICON_DELETE\" \r\n class=\"p-button-text p-button-rounded\" \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 </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}.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}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$1.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$1.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"] }] });
2947
+ 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 (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: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$1.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$1.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]" }] });
2788
2948
  }
2789
2949
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: TablePrimaryComponent, decorators: [{
2790
2950
  type: Component,
2791
- args: [{ selector: 'lib-table-primary', standalone: false, 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\" [permission]=\"col.header === 'Actions' ? 'Documents-DELETE' : ''\">\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\r\n <button [permission]=\"'Documents-DELETE'\" pButton pRipple type=\"button\" [icon]=\"SHARED.ICON_DELETE\" \r\n class=\"p-button-text p-button-rounded\" \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 </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}.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}\n"] }]
2951
+ args: [{ selector: 'lib-table-primary', standalone: false, 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 (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"] }]
2792
2952
  }], propDecorators: { tableData: [{
2793
2953
  type: Input
2794
2954
  }], showHeader: [{
@@ -3000,19 +3160,26 @@ class DocumentViewerService {
3000
3160
  documentHttpService;
3001
3161
  documentService;
3002
3162
  messageService;
3003
- stateSubject = new BehaviorSubject({
3004
- documentHistory: [],
3005
- showDocumentHistory: false,
3006
- isActionLoading: false,
3007
- documentStatus: SHARED.STATUS_PENDING,
3008
- documentIsUploaded: false,
3009
- alertData: null
3010
- });
3011
- state$ = this.stateSubject.asObservable();
3012
- constructor(documentHttpService, documentService, messageService) {
3163
+ documentStore;
3164
+ documentQuery;
3165
+ constructor(documentHttpService, documentService, messageService, documentStore, documentQuery) {
3013
3166
  this.documentHttpService = documentHttpService;
3014
3167
  this.documentService = documentService;
3015
3168
  this.messageService = messageService;
3169
+ this.documentStore = documentStore;
3170
+ this.documentQuery = documentQuery;
3171
+ }
3172
+ /**
3173
+ * Gets the current document viewer state as an observable
3174
+ */
3175
+ get state$() {
3176
+ return this.documentQuery.selectDocumentViewerState();
3177
+ }
3178
+ /**
3179
+ * Gets the current document viewer state synchronously
3180
+ */
3181
+ getCurrentState() {
3182
+ return this.documentQuery.getDocumentViewerState();
3016
3183
  }
3017
3184
  /**
3018
3185
  * Updates the selected document and recalculates all computed properties
@@ -3023,13 +3190,10 @@ class DocumentViewerService {
3023
3190
  const alertData = this.getAlertData(document);
3024
3191
  const documentStatus = this.calculateDocumentStatus(document);
3025
3192
  const documentIsUploaded = this.calculateIsDocumentUploaded(document);
3026
- this.stateSubject.next({
3027
- ...this.stateSubject.value,
3028
- selectedDocument: document,
3029
- alertData,
3030
- documentStatus,
3031
- documentIsUploaded
3032
- });
3193
+ this.documentStore.updateDocumentViewerState(document, undefined, // Keep existing history
3194
+ undefined, // Keep existing showHistory
3195
+ undefined, // Keep existing loading
3196
+ documentStatus, documentIsUploaded, alertData);
3033
3197
  this.loadDocumentHistory(document._id);
3034
3198
  }
3035
3199
  /**
@@ -3041,17 +3205,15 @@ class DocumentViewerService {
3041
3205
  this.documentHttpService.getDocumentHistory(documentId)
3042
3206
  .subscribe({
3043
3207
  next: (history) => {
3044
- this.stateSubject.next({
3045
- ...this.stateSubject.value,
3046
- documentHistory: history,
3047
- showDocumentHistory: true
3048
- });
3208
+ this.documentStore.updateDocumentViewerState(undefined, // Keep existing document
3209
+ history, true // Show history
3210
+ );
3049
3211
  },
3050
3212
  error: (error) => {
3051
- this.stateSubject.next({
3052
- ...this.stateSubject.value,
3053
- showDocumentHistory: false
3054
- });
3213
+ this.documentStore.updateDocumentViewerState(undefined, // Keep existing document
3214
+ undefined, // Keep existing history
3215
+ false // Hide history
3216
+ );
3055
3217
  }
3056
3218
  });
3057
3219
  }
@@ -3070,7 +3232,7 @@ class DocumentViewerService {
3070
3232
  * @param contextId The context ID for API calls
3071
3233
  */
3072
3234
  handleDocumentAction(action, contextId) {
3073
- const currentState = this.stateSubject.value;
3235
+ const currentState = this.documentQuery.getDocumentViewerState();
3074
3236
  if (!currentState.selectedDocument?._id) {
3075
3237
  console.error('No document ID available');
3076
3238
  return;
@@ -3083,6 +3245,7 @@ class DocumentViewerService {
3083
3245
  this.updateDocumentStatus(SHARED.STATUS_REJECTED, action.note || SHARED.DOCUMENT_REJECTED_MESSAGE, contextId);
3084
3246
  break;
3085
3247
  case SHARED.DELETE_ACTION:
3248
+ this.deleteDocument(currentState.selectedDocument._id, contextId);
3086
3249
  break;
3087
3250
  }
3088
3251
  }
@@ -3093,15 +3256,12 @@ class DocumentViewerService {
3093
3256
  * @param contextId The context ID for API calls
3094
3257
  */
3095
3258
  updateDocumentStatus(status, description, contextId) {
3096
- const currentState = this.stateSubject.value;
3259
+ const currentState = this.documentQuery.getDocumentViewerState();
3097
3260
  if (!currentState.selectedDocument?._id) {
3098
3261
  console.error('No document ID available');
3099
3262
  return;
3100
3263
  }
3101
- this.stateSubject.next({
3102
- ...currentState,
3103
- isActionLoading: true
3104
- });
3264
+ this.documentStore.setIsActionLoading(true);
3105
3265
  this.documentHttpService.updateDocumentStatus(currentState.selectedDocument._id, status, description).subscribe({
3106
3266
  next: (response) => {
3107
3267
  if (currentState.selectedDocument && response.status) {
@@ -3118,10 +3278,29 @@ class DocumentViewerService {
3118
3278
  console.error('Error updating document status:', error);
3119
3279
  },
3120
3280
  complete: () => {
3121
- this.stateSubject.next({
3122
- ...this.stateSubject.value,
3123
- isActionLoading: false
3124
- });
3281
+ this.documentStore.setIsActionLoading(false);
3282
+ }
3283
+ });
3284
+ }
3285
+ /**
3286
+ * Deletes a document and refreshes all data while preserving current filters
3287
+ * @param documentId The ID of the document to delete
3288
+ * @param contextId The context ID for API calls
3289
+ */
3290
+ deleteDocument(documentId, contextId) {
3291
+ if (!contextId) {
3292
+ console.error('No context ID available for delete operation');
3293
+ return;
3294
+ }
3295
+ this.documentStore.setIsActionLoading(true);
3296
+ this.documentHttpService.deleteDocument(documentId, contextId).subscribe({
3297
+ next: () => {
3298
+ this.documentService.refreshAllDataWithCurrentFilters(contextId);
3299
+ this.documentStore.clearDocumentViewerState();
3300
+ },
3301
+ error: (error) => {
3302
+ console.error('Error deleting document:', error);
3303
+ this.documentStore.setIsActionLoading(false);
3125
3304
  }
3126
3305
  });
3127
3306
  }
@@ -3134,18 +3313,11 @@ class DocumentViewerService {
3134
3313
  console.error('No context ID available for data refresh');
3135
3314
  return;
3136
3315
  }
3137
- const currentState = this.stateSubject.value;
3316
+ const currentState = this.documentQuery.getDocumentViewerState();
3138
3317
  if (currentState.selectedDocument?._id) {
3139
3318
  this.loadDocumentHistory(currentState.selectedDocument._id);
3140
3319
  }
3141
- this.documentHttpService.getDocumentCatagories(contextId).subscribe({
3142
- next: (categories) => {
3143
- console.log('Document categories refreshed:', categories);
3144
- },
3145
- error: (error) => {
3146
- console.error('Error refreshing document categories:', error);
3147
- }
3148
- });
3320
+ // Use the same refresh method as other components for consistency
3149
3321
  this.documentService.refreshAllDataWithCurrentFilters(contextId);
3150
3322
  }
3151
3323
  /**
@@ -3200,14 +3372,7 @@ class DocumentViewerService {
3200
3372
  document.status?.toLowerCase() === SHARED.STATUS_PENDING;
3201
3373
  return !!(document.documentUrl && !isPending);
3202
3374
  }
3203
- /**
3204
- * Gets the current state
3205
- * @returns The current state
3206
- */
3207
- getCurrentState() {
3208
- return this.stateSubject.value;
3209
- }
3210
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentViewerService, deps: [{ token: DocumentHttpService }, { token: DocumentHelperService }, { token: i3$1.MessageService }], target: i0.ɵɵFactoryTarget.Injectable });
3375
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentViewerService, deps: [{ token: DocumentHttpService }, { token: DocumentHelperService }, { token: i3$1.MessageService }, { token: DocumentStore }, { token: DocumentQuery }], target: i0.ɵɵFactoryTarget.Injectable });
3211
3376
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentViewerService, providedIn: 'root' });
3212
3377
  }
3213
3378
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentViewerService, decorators: [{
@@ -3215,7 +3380,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
3215
3380
  args: [{
3216
3381
  providedIn: 'root'
3217
3382
  }]
3218
- }], ctorParameters: () => [{ type: DocumentHttpService }, { type: DocumentHelperService }, { type: i3$1.MessageService }] });
3383
+ }], ctorParameters: () => [{ type: DocumentHttpService }, { type: DocumentHelperService }, { type: i3$1.MessageService }, { type: DocumentStore }, { type: DocumentQuery }] });
3219
3384
 
3220
3385
  /**
3221
3386
  * Constants for Document History labels and styling
@@ -3468,10 +3633,9 @@ class DocumentHistoryComponent {
3468
3633
  */
3469
3634
  checkValidContent(section) {
3470
3635
  return section.list && section.list.length > 0 &&
3471
- section.list.some(item => item.label ||
3472
- item.requestDescription ||
3473
- item.documentUrl ||
3474
- item.userName);
3636
+ section.list.some(item => item.requestDescription !== SHARED.EMPTY &&
3637
+ item.documentUrl !== SHARED.EMPTY &&
3638
+ (item.userName !== SHARED.EMPTY && item.userName !== SHARED.UNKNOWN_USER));
3475
3639
  }
3476
3640
  /**
3477
3641
  * Process history data to add computed properties
@@ -3519,11 +3683,11 @@ class DocumentHistoryComponent {
3519
3683
  document.body.removeChild(link);
3520
3684
  }
3521
3685
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentHistoryComponent, deps: [{ token: DocumentHistoryStyleService }], target: i0.ɵɵFactoryTarget.Component });
3522
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DocumentHistoryComponent, isStandalone: false, selector: "document-history", inputs: { historyData: "historyData", showHistory: "showHistory" }, ngImport: i0, template: "<div class=\"document-history-container\" *ngIf=\"showHistory && historyData.length > 0\">\r\n <div class=\"history-sections\">\r\n <div class=\"history-section\" *ngFor=\"let section of processedHistoryData\">\r\n <div *ngIf=\"section.header === 'Initial Request'\" \r\n class=\"initial-request-section\"\r\n [ngClass]=\"section.accordionClass\">\r\n <p-accordion [activeIndex]=\"activeAccordionIndex\" \r\n (onOpen)=\"onAccordionOpen()\" \r\n (onClose)=\"onAccordionClose()\">\r\n <p-accordionTab [header]=\"section.header\">\r\n <div class=\"history-timeline\" *ngIf=\"section.hasValidContent\">\r\n <div class=\"timeline-item\" *ngFor=\"let item of section.list; let i = index\">\r\n <div class=\"timeline-card\" [ngClass]=\"item.actionBgColor\">\r\n <div class=\"card-header\">\r\n <div class=\"action-info\">\r\n <div class=\"action-icon\" [ngClass]=\"item.actionIconBgColor\">\r\n <i [class]=\"item.actionIcon\"></i>\r\n </div>\r\n <span class=\"action-label\" [ngClass]=\"item.actionColor\">\r\n {{ item.label }}\r\n </span>\r\n </div>\r\n <div class=\"timestamp\">\r\n {{ item.dateTime }}\r\n </div>\r\n </div>\r\n \r\n <!-- Description -->\r\n <div class=\"card-description\" *ngIf=\"item.requestDescription\">\r\n <p class=\"description-text\">{{ item.requestDescription ?? 'No Request' }}</p>\r\n </div>\r\n \r\n <!-- Document details if URL exists -->\r\n <div class=\"document-details\" *ngIf=\"item.documentUrl\">\r\n <div class=\"document-card\">\r\n <div class=\"document-info\">\r\n <div class=\"document-icon\">\r\n <i class=\"pi pi-file\"></i>\r\n </div>\r\n <div class=\"document-text\">\r\n <div class=\"document-title\">Document</div>\r\n <div class=\"document-filename clickable\" \r\n (click)=\"downloadDocument(item.documentUrl!, item.docName)\"\r\n title=\"Click to download\">\r\n {{ item.docName || 'Document' }}\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"document-actions\">\r\n <button class=\"action-btn download-btn\" \r\n title=\"Download\"\r\n (click)=\"downloadDocument(item.documentUrl!, item.docName)\">\r\n <i class=\"pi pi-download\"></i>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- User information -->\r\n <div class=\"user-info\">\r\n <span class=\"user-name\">{{ item.userName }}</span>\r\n <span class=\"user-role\">({{ item.userRole }})</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Show message if no valid content -->\r\n <div class=\"no-content-message\" *ngIf=\"!section.hasValidContent\">\r\n <p>No initial request details available.</p>\r\n </div>\r\n </p-accordionTab>\r\n </p-accordion>\r\n </div>\r\n \r\n <!-- Document History as regular timeline -->\r\n <div *ngIf=\"section.header !== 'Initial Request'\" class=\"document-history-section\">\r\n <div class=\"section-header\" *ngIf=\"section.header\">\r\n <h4 class=\"section-title\">{{ section.header }}</h4>\r\n </div>\r\n \r\n <div class=\"history-timeline\">\r\n <div class=\"timeline-item\" *ngFor=\"let item of section.list; let i = index\">\r\n <div class=\"timeline-card\" [ngClass]=\"item.actionBgColor\">\r\n <!-- Header with icon and timestamp -->\r\n <div class=\"card-header\">\r\n <div class=\"action-info\">\r\n <div class=\"action-icon\" [ngClass]=\"item.actionIconBgColor\">\r\n <i [class]=\"item.actionIcon\"></i>\r\n </div>\r\n <span class=\"action-label\" [ngClass]=\"item.actionColor\">\r\n {{ item.label }}\r\n </span>\r\n </div>\r\n <div class=\"timestamp\">\r\n {{ item.dateTime }}\r\n </div>\r\n </div>\r\n \r\n <!-- Description -->\r\n <div class=\"card-description\" *ngIf=\"item.requestDescription\">\r\n <p class=\"description-text\">{{ item.requestDescription }}</p>\r\n </div>\r\n \r\n <!-- Document details if URL exists -->\r\n <div class=\"document-details\" *ngIf=\"item.documentUrl\">\r\n <div class=\"document-card\">\r\n <div class=\"document-info\">\r\n <div class=\"document-icon\">\r\n <i class=\"pi pi-file\"></i>\r\n </div>\r\n <div class=\"document-text\">\r\n <div class=\"document-title\">Document</div>\r\n <div class=\"document-filename clickable\" \r\n (click)=\"downloadDocument(item.documentUrl!, item.docName)\"\r\n title=\"Click to download\">\r\n {{ item.docName || 'Document' }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- User information -->\r\n <div class=\"user-info\">\r\n <span class=\"user-name\">{{ item.userName }}</span>\r\n <span class=\"user-role\">({{ item.userRole }})</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>", styles: [".document-history-container{padding:1rem;background:#fff;border-radius:8px;box-shadow:0 2px 4px #0000001a;max-height:70vh;overflow-y:auto}.document-history-container .history-header{margin-bottom:1.5rem}.document-history-container .history-header .history-title{font-size:1.5rem;font-weight:600;color:#374151;margin:0}.document-history-container .history-sections .history-section{margin-bottom:2rem}.document-history-container .history-sections .history-section .initial-request-section{margin-bottom:1.5rem}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link{background:#fff;border:1px solid;border-radius:8px;padding:1rem 1.5rem;font-weight:600;color:#1f2937;font-size:1rem}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link:focus{box-shadow:none}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link .p-accordion-header-icon{color:#6b7280;font-size:.875rem}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-header.p-highlight .p-accordion-header-link{background:#fff}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content{background:#fff;border:1px solid;border-top:none;border-radius:0 0 8px 8px;padding:1.5rem}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item{margin-bottom:0}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card{background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;padding:1rem;border-right:3px solid}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .card-header .action-info .action-icon{background:#7d879b;color:#fff;width:32px;height:32px;border-radius:50%;display:flex;align-items:center;justify-content:center}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .card-header .action-info .action-icon i{font-size:14px}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .card-header .action-info .action-label{color:#1f2937;font-weight:600}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .card-header .timestamp{color:#6b7280;font-size:.75rem}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .card-description .description-text{color:#374151;line-height:1.5}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .user-info .user-name{color:#1f2937;font-weight:500}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .user-info .user-role{color:#6b7280}.document-history-container .history-sections .history-section .initial-request-section.document-requested ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link{border-color:#d1d5db}.document-history-container .history-sections .history-section .initial-request-section.document-requested ::ng-deep .p-accordion .p-accordion-content{border-color:#d1d5db}.document-history-container .history-sections .history-section .initial-request-section.document-uploaded ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link{border-color:#86efac}.document-history-container .history-sections .history-section .initial-request-section.document-uploaded ::ng-deep .p-accordion .p-accordion-content{border-color:#86efac}.document-history-container .history-sections .history-section .initial-request-section.document-rejected ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link{border-color:#fca5a5}.document-history-container .history-sections .history-section .initial-request-section.document-rejected ::ng-deep .p-accordion .p-accordion-content{border-color:#fca5a5}.document-history-container .history-sections .history-section .initial-request-section.document-accepted ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link{border-color:#86efac}.document-history-container .history-sections .history-section .initial-request-section.document-accepted ::ng-deep .p-accordion .p-accordion-content{border-color:#86efac}.document-history-container .history-sections .history-section .document-history-section .section-header{margin-bottom:1rem}.document-history-container .history-sections .history-section .document-history-section .section-header .section-title{font-size:1.25rem;font-weight:500;color:#374151;margin:0}.document-history-container .history-sections .history-section .history-timeline .timeline-item{margin-bottom:1rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card{border-radius:8px;border:1px solid;padding:1rem;position:relative;border-right:3px solid}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card.bg-green-50{background-color:#f0fdf4;border-color:#bbf7d0;border-right-color:#10b981}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card.bg-red-50{background-color:#fef2f2;border-color:#fecaca;border-right-color:#ef4444}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card.bg-blue-50{background-color:#eff6ff;border-color:#bfdbfe;border-right-color:#3b82f6}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card.bg-gray-50{background-color:#f8fafc;border-color:#e2e8f0;border-right-color:#6b7280}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:.75rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-header .action-info{display:flex;align-items:center;gap:.5rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-header .action-info .action-icon{width:32px;height:32px;border-radius:50%;display:flex;align-items:center;justify-content:center;color:#fff}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-header .action-info .action-icon i{font-size:14px}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-header .action-info .action-label{font-weight:600;font-size:.875rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-header .timestamp{font-size:.75rem;color:#6b7280}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-description{margin-bottom:.75rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-description .description-text{margin:0;color:#374151;font-size:.875rem;line-height:1.4}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details{margin-bottom:.75rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card{background:#fff;border-radius:6px;padding:.75rem;display:flex;justify-content:space-between;align-items:center;border:1px solid #e5e7eb}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-info{display:flex;align-items:center;gap:.5rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-info .document-icon{color:#3b82f6;font-size:1.25rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-info .document-text .document-title{font-weight:500;color:#374151;font-size:.875rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-info .document-text .document-filename{color:#3b82f6;font-size:.75rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-info .document-text .document-filename.clickable{cursor:pointer;text-decoration:underline}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-info .document-text .document-filename.clickable:hover{color:#2563eb;text-decoration:none}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions{display:flex;gap:.25rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn{width:24px;height:24px;border:none;border-radius:4px;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:.75rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn.edit-btn{background:#3b82f6;color:#fff}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn.edit-btn:hover{background:#2563eb}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn.delete-btn{background:#ef4444;color:#fff}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn.delete-btn:hover{background:#dc2626}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn.download-btn{background:#10b981;color:#fff}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn.download-btn:hover{background:#059669}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .user-info{text-align:right;font-size:.75rem;color:#374151}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .user-info .user-name{font-weight:500}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .user-info .user-role{color:#6b7280}.text-green-600{color:#059669}.text-red-600{color:#dc2626}.text-blue-600{color:#2563eb}.text-gray-600{color:#4b5563}.bg-green-50{background-color:#f0fdf4}.bg-red-50{background-color:#fef2f2}.bg-blue-50{background-color:#eff6ff}.bg-gray-50{background-color:#f8fafc}.border-green-200{border-color:#bbf7d0}.border-red-200{border-color:#fecaca}.border-blue-200{border-color:#bfdbfe}.border-gray-200{border-color:#e2e8f0}.icon-bg-green{background-color:#10b981}.icon-bg-red{background-color:#ef4444}.icon-bg-blue{background-color:#3b82f6}.icon-bg-gray{background-color:#6b7280}.no-content-message{text-align:center;padding:2rem;color:#6b7280;font-style:italic}.no-content-message p{margin:0;font-size:.875rem}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3$2.Accordion, selector: "p-accordion", inputs: ["multiple", "style", "styleClass", "expandIcon", "collapseIcon", "activeIndex", "selectOnFocus", "headerAriaLevel"], outputs: ["onClose", "onOpen", "activeIndexChange"] }, { kind: "component", type: i3$2.AccordionTab, selector: "p-accordionTab", inputs: ["id", "header", "headerStyle", "tabStyle", "contentStyle", "tabStyleClass", "headerStyleClass", "contentStyleClass", "disabled", "cache", "transitionOptions", "iconPos", "selected", "headerAriaLevel"], outputs: ["selectedChange"] }] });
3686
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DocumentHistoryComponent, isStandalone: false, selector: "document-history", inputs: { historyData: "historyData", showHistory: "showHistory" }, ngImport: i0, template: "<div class=\"document-history-container\" *ngIf=\"showHistory && historyData.length > 0\">\r\n <div class=\"history-sections\">\r\n <div class=\"history-section\" *ngFor=\"let section of processedHistoryData\">\r\n <div *ngIf=\"section.header === 'Initial Request' && section.hasValidContent\" \r\n class=\"initial-request-section\"\r\n [ngClass]=\"section.accordionClass\">\r\n <p-accordion [activeIndex]=\"activeAccordionIndex\" \r\n (onOpen)=\"onAccordionOpen()\" \r\n (onClose)=\"onAccordionClose()\">\r\n <p-accordionTab [header]=\"section.header\">\r\n <div class=\"history-timeline\" *ngIf=\"section.hasValidContent\">\r\n <div class=\"timeline-item\" *ngFor=\"let item of section.list; let i = index\">\r\n <div class=\"timeline-card\" [ngClass]=\"item.actionBgColor\">\r\n <div class=\"card-header\">\r\n <div class=\"action-info\">\r\n <div class=\"action-icon\" [ngClass]=\"item.actionIconBgColor\">\r\n <i [class]=\"item.actionIcon\"></i>\r\n </div>\r\n <span class=\"action-label\" [ngClass]=\"item.actionColor\">\r\n {{ item.label }}\r\n </span>\r\n </div>\r\n <div class=\"timestamp\">\r\n {{ item.dateTime }}\r\n </div>\r\n </div>\r\n \r\n <!-- Description -->\r\n <div class=\"card-description\" *ngIf=\"item.requestDescription\">\r\n <p class=\"description-text\">{{ item.requestDescription ?? 'No Request' }}</p>\r\n </div>\r\n \r\n <!-- Document details if URL exists -->\r\n <div class=\"document-details\" *ngIf=\"item.documentUrl\">\r\n <div class=\"document-card\">\r\n <div class=\"document-info\">\r\n <div class=\"document-icon\">\r\n <i class=\"pi pi-file\"></i>\r\n </div>\r\n <div class=\"document-text\">\r\n <div class=\"document-title\">Document</div>\r\n <div class=\"document-filename clickable\" \r\n (click)=\"downloadDocument(item.documentUrl!, item.docName)\"\r\n title=\"Click to download\">\r\n {{ item.docName || 'Document' }}\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"document-actions\">\r\n <button class=\"action-btn download-btn\" \r\n title=\"Download\"\r\n (click)=\"downloadDocument(item.documentUrl!, item.docName)\">\r\n <i class=\"pi pi-download\"></i>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- User information -->\r\n <div class=\"user-info\">\r\n <span class=\"user-name\">{{ item.userName }}</span>\r\n <span class=\"user-role\">({{ item.userRole }})</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Show message if no valid content -->\r\n <div class=\"no-content-message\" *ngIf=\"!section.hasValidContent\">\r\n <p>No initial request details available.</p>\r\n </div>\r\n </p-accordionTab>\r\n </p-accordion>\r\n </div>\r\n \r\n <!-- Document History as regular timeline -->\r\n <div *ngIf=\"section.header !== 'Initial Request'\" class=\"document-history-section\">\r\n <div class=\"section-header\" *ngIf=\"section.header\">\r\n <h4 class=\"section-title\">{{ section.header }}</h4>\r\n </div>\r\n \r\n <div class=\"history-timeline\">\r\n <div class=\"timeline-item\" *ngFor=\"let item of section.list; let i = index\">\r\n <div class=\"timeline-card\" [ngClass]=\"item.actionBgColor\">\r\n <!-- Header with icon and timestamp -->\r\n <div class=\"card-header\">\r\n <div class=\"action-info\">\r\n <div class=\"action-icon\" [ngClass]=\"item.actionIconBgColor\">\r\n <i [class]=\"item.actionIcon\"></i>\r\n </div>\r\n <span class=\"action-label\" [ngClass]=\"item.actionColor\">\r\n {{ item.label }}\r\n </span>\r\n </div>\r\n <div class=\"timestamp\">\r\n {{ item.dateTime }}\r\n </div>\r\n </div>\r\n \r\n <!-- Description -->\r\n <div class=\"card-description\" *ngIf=\"item.requestDescription\">\r\n <p class=\"description-text\">{{ item.requestDescription }}</p>\r\n </div>\r\n \r\n <!-- Document details if URL exists -->\r\n <div class=\"document-details\" *ngIf=\"item.documentUrl\">\r\n <div class=\"document-card\">\r\n <div class=\"document-info\">\r\n <div class=\"document-icon\">\r\n <i class=\"pi pi-file\"></i>\r\n </div>\r\n <div class=\"document-text\">\r\n <div class=\"document-title\">Document</div>\r\n <div class=\"document-filename clickable\" \r\n (click)=\"downloadDocument(item.documentUrl!, item.docName)\"\r\n title=\"Click to download\">\r\n {{ item.docName || 'Document' }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- User information -->\r\n <div class=\"user-info\">\r\n <span class=\"user-name\">{{ item.userName }}</span>\r\n <span class=\"user-role\">({{ item.userRole }})</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>", styles: [".document-history-container{padding:1rem;background:#fff;border-radius:8px;box-shadow:0 2px 4px #0000001a;max-height:70vh;overflow-y:auto}.document-history-container .history-header{margin-bottom:1.5rem}.document-history-container .history-header .history-title{font-size:1.5rem;font-weight:600;color:#374151;margin:0}.document-history-container .history-sections .history-section{margin-bottom:2rem}.document-history-container .history-sections .history-section .initial-request-section{margin-bottom:1.5rem}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link{background:#fff;border:1px solid;border-radius:8px;padding:1rem 1.5rem;font-weight:600;color:#1f2937;font-size:1rem}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link:focus{box-shadow:none}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link .p-accordion-header-icon{color:#6b7280;font-size:.875rem}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-header.p-highlight .p-accordion-header-link{background:#fff}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content{background:#fff;border:1px solid;border-top:none;border-radius:0 0 8px 8px;padding:1.5rem}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item{margin-bottom:0}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card{background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;padding:1rem;border-right:3px solid}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .card-header .action-info .action-icon{background:#7d879b;color:#fff;width:32px;height:32px;border-radius:50%;display:flex;align-items:center;justify-content:center}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .card-header .action-info .action-icon i{font-size:14px}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .card-header .action-info .action-label{color:#1f2937;font-weight:600}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .card-header .timestamp{color:#6b7280;font-size:.75rem}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .card-description .description-text{color:#374151;line-height:1.5}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .user-info .user-name{color:#1f2937;font-weight:500}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .user-info .user-role{color:#6b7280}.document-history-container .history-sections .history-section .initial-request-section.document-requested ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link{border-color:#d1d5db}.document-history-container .history-sections .history-section .initial-request-section.document-requested ::ng-deep .p-accordion .p-accordion-content{border-color:#d1d5db}.document-history-container .history-sections .history-section .initial-request-section.document-uploaded ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link{border-color:#86efac}.document-history-container .history-sections .history-section .initial-request-section.document-uploaded ::ng-deep .p-accordion .p-accordion-content{border-color:#86efac}.document-history-container .history-sections .history-section .initial-request-section.document-rejected ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link{border-color:#fca5a5}.document-history-container .history-sections .history-section .initial-request-section.document-rejected ::ng-deep .p-accordion .p-accordion-content{border-color:#fca5a5}.document-history-container .history-sections .history-section .initial-request-section.document-accepted ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link{border-color:#86efac}.document-history-container .history-sections .history-section .initial-request-section.document-accepted ::ng-deep .p-accordion .p-accordion-content{border-color:#86efac}.document-history-container .history-sections .history-section .document-history-section .section-header{margin-bottom:1rem}.document-history-container .history-sections .history-section .document-history-section .section-header .section-title{font-size:1.25rem;font-weight:500;color:#374151;margin:0}.document-history-container .history-sections .history-section .history-timeline .timeline-item{margin-bottom:1rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card{border-radius:8px;border:1px solid;padding:1rem;position:relative;border-right:3px solid}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card.bg-green-50{background-color:#f0fdf4;border-color:#bbf7d0;border-right-color:#10b981}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card.bg-red-50{background-color:#fef2f2;border-color:#fecaca;border-right-color:#ef4444}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card.bg-blue-50{background-color:#eff6ff;border-color:#bfdbfe;border-right-color:#3b82f6}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card.bg-gray-50{background-color:#f8fafc;border-color:#e2e8f0;border-right-color:#6b7280}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:.75rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-header .action-info{display:flex;align-items:center;gap:.5rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-header .action-info .action-icon{width:32px;height:32px;border-radius:50%;display:flex;align-items:center;justify-content:center;color:#fff}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-header .action-info .action-icon i{font-size:14px}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-header .action-info .action-label{font-weight:600;font-size:.875rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-header .timestamp{font-size:.75rem;color:#6b7280}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-description{margin-bottom:.75rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-description .description-text{margin:0;color:#374151;font-size:.875rem;line-height:1.4}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details{margin-bottom:.75rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card{background:#fff;border-radius:6px;padding:.75rem;display:flex;justify-content:space-between;align-items:center;border:1px solid #e5e7eb}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-info{display:flex;align-items:center;gap:.5rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-info .document-icon{color:#3b82f6;font-size:1.25rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-info .document-text .document-title{font-weight:500;color:#374151;font-size:.875rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-info .document-text .document-filename{color:#3b82f6;font-size:.75rem;word-break:break-word}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-info .document-text .document-filename.clickable{cursor:pointer;text-decoration:underline}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-info .document-text .document-filename.clickable:hover{color:#2563eb;text-decoration:none}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions{display:flex;gap:.25rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn{width:24px;height:24px;border:none;border-radius:4px;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:.75rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn.edit-btn{background:#3b82f6;color:#fff}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn.edit-btn:hover{background:#2563eb}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn.delete-btn{background:#ef4444;color:#fff}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn.delete-btn:hover{background:#dc2626}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn.download-btn{background:#10b981;color:#fff}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn.download-btn:hover{background:#059669}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .user-info{text-align:right;font-size:.75rem;color:#374151}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .user-info .user-name{font-weight:500}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .user-info .user-role{color:#6b7280}.text-green-600{color:#059669}.text-red-600{color:#dc2626}.text-blue-600{color:#2563eb}.text-gray-600{color:#4b5563}.bg-green-50{background-color:#f0fdf4}.bg-red-50{background-color:#fef2f2}.bg-blue-50{background-color:#eff6ff}.bg-gray-50{background-color:#f8fafc}.border-green-200{border-color:#bbf7d0}.border-red-200{border-color:#fecaca}.border-blue-200{border-color:#bfdbfe}.border-gray-200{border-color:#e2e8f0}.icon-bg-green{background-color:#10b981}.icon-bg-red{background-color:#ef4444}.icon-bg-blue{background-color:#3b82f6}.icon-bg-gray{background-color:#6b7280}.no-content-message{text-align:center;padding:2rem;color:#6b7280;font-style:italic}.no-content-message p{margin:0;font-size:.875rem}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3$2.Accordion, selector: "p-accordion", inputs: ["multiple", "style", "styleClass", "expandIcon", "collapseIcon", "activeIndex", "selectOnFocus", "headerAriaLevel"], outputs: ["onClose", "onOpen", "activeIndexChange"] }, { kind: "component", type: i3$2.AccordionTab, selector: "p-accordionTab", inputs: ["id", "header", "headerStyle", "tabStyle", "contentStyle", "tabStyleClass", "headerStyleClass", "contentStyleClass", "disabled", "cache", "transitionOptions", "iconPos", "selected", "headerAriaLevel"], outputs: ["selectedChange"] }] });
3523
3687
  }
3524
3688
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentHistoryComponent, decorators: [{
3525
3689
  type: Component,
3526
- args: [{ selector: 'document-history', standalone: false, template: "<div class=\"document-history-container\" *ngIf=\"showHistory && historyData.length > 0\">\r\n <div class=\"history-sections\">\r\n <div class=\"history-section\" *ngFor=\"let section of processedHistoryData\">\r\n <div *ngIf=\"section.header === 'Initial Request'\" \r\n class=\"initial-request-section\"\r\n [ngClass]=\"section.accordionClass\">\r\n <p-accordion [activeIndex]=\"activeAccordionIndex\" \r\n (onOpen)=\"onAccordionOpen()\" \r\n (onClose)=\"onAccordionClose()\">\r\n <p-accordionTab [header]=\"section.header\">\r\n <div class=\"history-timeline\" *ngIf=\"section.hasValidContent\">\r\n <div class=\"timeline-item\" *ngFor=\"let item of section.list; let i = index\">\r\n <div class=\"timeline-card\" [ngClass]=\"item.actionBgColor\">\r\n <div class=\"card-header\">\r\n <div class=\"action-info\">\r\n <div class=\"action-icon\" [ngClass]=\"item.actionIconBgColor\">\r\n <i [class]=\"item.actionIcon\"></i>\r\n </div>\r\n <span class=\"action-label\" [ngClass]=\"item.actionColor\">\r\n {{ item.label }}\r\n </span>\r\n </div>\r\n <div class=\"timestamp\">\r\n {{ item.dateTime }}\r\n </div>\r\n </div>\r\n \r\n <!-- Description -->\r\n <div class=\"card-description\" *ngIf=\"item.requestDescription\">\r\n <p class=\"description-text\">{{ item.requestDescription ?? 'No Request' }}</p>\r\n </div>\r\n \r\n <!-- Document details if URL exists -->\r\n <div class=\"document-details\" *ngIf=\"item.documentUrl\">\r\n <div class=\"document-card\">\r\n <div class=\"document-info\">\r\n <div class=\"document-icon\">\r\n <i class=\"pi pi-file\"></i>\r\n </div>\r\n <div class=\"document-text\">\r\n <div class=\"document-title\">Document</div>\r\n <div class=\"document-filename clickable\" \r\n (click)=\"downloadDocument(item.documentUrl!, item.docName)\"\r\n title=\"Click to download\">\r\n {{ item.docName || 'Document' }}\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"document-actions\">\r\n <button class=\"action-btn download-btn\" \r\n title=\"Download\"\r\n (click)=\"downloadDocument(item.documentUrl!, item.docName)\">\r\n <i class=\"pi pi-download\"></i>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- User information -->\r\n <div class=\"user-info\">\r\n <span class=\"user-name\">{{ item.userName }}</span>\r\n <span class=\"user-role\">({{ item.userRole }})</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Show message if no valid content -->\r\n <div class=\"no-content-message\" *ngIf=\"!section.hasValidContent\">\r\n <p>No initial request details available.</p>\r\n </div>\r\n </p-accordionTab>\r\n </p-accordion>\r\n </div>\r\n \r\n <!-- Document History as regular timeline -->\r\n <div *ngIf=\"section.header !== 'Initial Request'\" class=\"document-history-section\">\r\n <div class=\"section-header\" *ngIf=\"section.header\">\r\n <h4 class=\"section-title\">{{ section.header }}</h4>\r\n </div>\r\n \r\n <div class=\"history-timeline\">\r\n <div class=\"timeline-item\" *ngFor=\"let item of section.list; let i = index\">\r\n <div class=\"timeline-card\" [ngClass]=\"item.actionBgColor\">\r\n <!-- Header with icon and timestamp -->\r\n <div class=\"card-header\">\r\n <div class=\"action-info\">\r\n <div class=\"action-icon\" [ngClass]=\"item.actionIconBgColor\">\r\n <i [class]=\"item.actionIcon\"></i>\r\n </div>\r\n <span class=\"action-label\" [ngClass]=\"item.actionColor\">\r\n {{ item.label }}\r\n </span>\r\n </div>\r\n <div class=\"timestamp\">\r\n {{ item.dateTime }}\r\n </div>\r\n </div>\r\n \r\n <!-- Description -->\r\n <div class=\"card-description\" *ngIf=\"item.requestDescription\">\r\n <p class=\"description-text\">{{ item.requestDescription }}</p>\r\n </div>\r\n \r\n <!-- Document details if URL exists -->\r\n <div class=\"document-details\" *ngIf=\"item.documentUrl\">\r\n <div class=\"document-card\">\r\n <div class=\"document-info\">\r\n <div class=\"document-icon\">\r\n <i class=\"pi pi-file\"></i>\r\n </div>\r\n <div class=\"document-text\">\r\n <div class=\"document-title\">Document</div>\r\n <div class=\"document-filename clickable\" \r\n (click)=\"downloadDocument(item.documentUrl!, item.docName)\"\r\n title=\"Click to download\">\r\n {{ item.docName || 'Document' }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- User information -->\r\n <div class=\"user-info\">\r\n <span class=\"user-name\">{{ item.userName }}</span>\r\n <span class=\"user-role\">({{ item.userRole }})</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>", styles: [".document-history-container{padding:1rem;background:#fff;border-radius:8px;box-shadow:0 2px 4px #0000001a;max-height:70vh;overflow-y:auto}.document-history-container .history-header{margin-bottom:1.5rem}.document-history-container .history-header .history-title{font-size:1.5rem;font-weight:600;color:#374151;margin:0}.document-history-container .history-sections .history-section{margin-bottom:2rem}.document-history-container .history-sections .history-section .initial-request-section{margin-bottom:1.5rem}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link{background:#fff;border:1px solid;border-radius:8px;padding:1rem 1.5rem;font-weight:600;color:#1f2937;font-size:1rem}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link:focus{box-shadow:none}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link .p-accordion-header-icon{color:#6b7280;font-size:.875rem}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-header.p-highlight .p-accordion-header-link{background:#fff}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content{background:#fff;border:1px solid;border-top:none;border-radius:0 0 8px 8px;padding:1.5rem}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item{margin-bottom:0}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card{background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;padding:1rem;border-right:3px solid}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .card-header .action-info .action-icon{background:#7d879b;color:#fff;width:32px;height:32px;border-radius:50%;display:flex;align-items:center;justify-content:center}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .card-header .action-info .action-icon i{font-size:14px}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .card-header .action-info .action-label{color:#1f2937;font-weight:600}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .card-header .timestamp{color:#6b7280;font-size:.75rem}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .card-description .description-text{color:#374151;line-height:1.5}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .user-info .user-name{color:#1f2937;font-weight:500}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .user-info .user-role{color:#6b7280}.document-history-container .history-sections .history-section .initial-request-section.document-requested ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link{border-color:#d1d5db}.document-history-container .history-sections .history-section .initial-request-section.document-requested ::ng-deep .p-accordion .p-accordion-content{border-color:#d1d5db}.document-history-container .history-sections .history-section .initial-request-section.document-uploaded ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link{border-color:#86efac}.document-history-container .history-sections .history-section .initial-request-section.document-uploaded ::ng-deep .p-accordion .p-accordion-content{border-color:#86efac}.document-history-container .history-sections .history-section .initial-request-section.document-rejected ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link{border-color:#fca5a5}.document-history-container .history-sections .history-section .initial-request-section.document-rejected ::ng-deep .p-accordion .p-accordion-content{border-color:#fca5a5}.document-history-container .history-sections .history-section .initial-request-section.document-accepted ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link{border-color:#86efac}.document-history-container .history-sections .history-section .initial-request-section.document-accepted ::ng-deep .p-accordion .p-accordion-content{border-color:#86efac}.document-history-container .history-sections .history-section .document-history-section .section-header{margin-bottom:1rem}.document-history-container .history-sections .history-section .document-history-section .section-header .section-title{font-size:1.25rem;font-weight:500;color:#374151;margin:0}.document-history-container .history-sections .history-section .history-timeline .timeline-item{margin-bottom:1rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card{border-radius:8px;border:1px solid;padding:1rem;position:relative;border-right:3px solid}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card.bg-green-50{background-color:#f0fdf4;border-color:#bbf7d0;border-right-color:#10b981}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card.bg-red-50{background-color:#fef2f2;border-color:#fecaca;border-right-color:#ef4444}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card.bg-blue-50{background-color:#eff6ff;border-color:#bfdbfe;border-right-color:#3b82f6}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card.bg-gray-50{background-color:#f8fafc;border-color:#e2e8f0;border-right-color:#6b7280}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:.75rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-header .action-info{display:flex;align-items:center;gap:.5rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-header .action-info .action-icon{width:32px;height:32px;border-radius:50%;display:flex;align-items:center;justify-content:center;color:#fff}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-header .action-info .action-icon i{font-size:14px}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-header .action-info .action-label{font-weight:600;font-size:.875rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-header .timestamp{font-size:.75rem;color:#6b7280}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-description{margin-bottom:.75rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-description .description-text{margin:0;color:#374151;font-size:.875rem;line-height:1.4}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details{margin-bottom:.75rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card{background:#fff;border-radius:6px;padding:.75rem;display:flex;justify-content:space-between;align-items:center;border:1px solid #e5e7eb}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-info{display:flex;align-items:center;gap:.5rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-info .document-icon{color:#3b82f6;font-size:1.25rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-info .document-text .document-title{font-weight:500;color:#374151;font-size:.875rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-info .document-text .document-filename{color:#3b82f6;font-size:.75rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-info .document-text .document-filename.clickable{cursor:pointer;text-decoration:underline}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-info .document-text .document-filename.clickable:hover{color:#2563eb;text-decoration:none}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions{display:flex;gap:.25rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn{width:24px;height:24px;border:none;border-radius:4px;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:.75rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn.edit-btn{background:#3b82f6;color:#fff}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn.edit-btn:hover{background:#2563eb}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn.delete-btn{background:#ef4444;color:#fff}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn.delete-btn:hover{background:#dc2626}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn.download-btn{background:#10b981;color:#fff}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn.download-btn:hover{background:#059669}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .user-info{text-align:right;font-size:.75rem;color:#374151}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .user-info .user-name{font-weight:500}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .user-info .user-role{color:#6b7280}.text-green-600{color:#059669}.text-red-600{color:#dc2626}.text-blue-600{color:#2563eb}.text-gray-600{color:#4b5563}.bg-green-50{background-color:#f0fdf4}.bg-red-50{background-color:#fef2f2}.bg-blue-50{background-color:#eff6ff}.bg-gray-50{background-color:#f8fafc}.border-green-200{border-color:#bbf7d0}.border-red-200{border-color:#fecaca}.border-blue-200{border-color:#bfdbfe}.border-gray-200{border-color:#e2e8f0}.icon-bg-green{background-color:#10b981}.icon-bg-red{background-color:#ef4444}.icon-bg-blue{background-color:#3b82f6}.icon-bg-gray{background-color:#6b7280}.no-content-message{text-align:center;padding:2rem;color:#6b7280;font-style:italic}.no-content-message p{margin:0;font-size:.875rem}\n"] }]
3690
+ args: [{ selector: 'document-history', standalone: false, template: "<div class=\"document-history-container\" *ngIf=\"showHistory && historyData.length > 0\">\r\n <div class=\"history-sections\">\r\n <div class=\"history-section\" *ngFor=\"let section of processedHistoryData\">\r\n <div *ngIf=\"section.header === 'Initial Request' && section.hasValidContent\" \r\n class=\"initial-request-section\"\r\n [ngClass]=\"section.accordionClass\">\r\n <p-accordion [activeIndex]=\"activeAccordionIndex\" \r\n (onOpen)=\"onAccordionOpen()\" \r\n (onClose)=\"onAccordionClose()\">\r\n <p-accordionTab [header]=\"section.header\">\r\n <div class=\"history-timeline\" *ngIf=\"section.hasValidContent\">\r\n <div class=\"timeline-item\" *ngFor=\"let item of section.list; let i = index\">\r\n <div class=\"timeline-card\" [ngClass]=\"item.actionBgColor\">\r\n <div class=\"card-header\">\r\n <div class=\"action-info\">\r\n <div class=\"action-icon\" [ngClass]=\"item.actionIconBgColor\">\r\n <i [class]=\"item.actionIcon\"></i>\r\n </div>\r\n <span class=\"action-label\" [ngClass]=\"item.actionColor\">\r\n {{ item.label }}\r\n </span>\r\n </div>\r\n <div class=\"timestamp\">\r\n {{ item.dateTime }}\r\n </div>\r\n </div>\r\n \r\n <!-- Description -->\r\n <div class=\"card-description\" *ngIf=\"item.requestDescription\">\r\n <p class=\"description-text\">{{ item.requestDescription ?? 'No Request' }}</p>\r\n </div>\r\n \r\n <!-- Document details if URL exists -->\r\n <div class=\"document-details\" *ngIf=\"item.documentUrl\">\r\n <div class=\"document-card\">\r\n <div class=\"document-info\">\r\n <div class=\"document-icon\">\r\n <i class=\"pi pi-file\"></i>\r\n </div>\r\n <div class=\"document-text\">\r\n <div class=\"document-title\">Document</div>\r\n <div class=\"document-filename clickable\" \r\n (click)=\"downloadDocument(item.documentUrl!, item.docName)\"\r\n title=\"Click to download\">\r\n {{ item.docName || 'Document' }}\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"document-actions\">\r\n <button class=\"action-btn download-btn\" \r\n title=\"Download\"\r\n (click)=\"downloadDocument(item.documentUrl!, item.docName)\">\r\n <i class=\"pi pi-download\"></i>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- User information -->\r\n <div class=\"user-info\">\r\n <span class=\"user-name\">{{ item.userName }}</span>\r\n <span class=\"user-role\">({{ item.userRole }})</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Show message if no valid content -->\r\n <div class=\"no-content-message\" *ngIf=\"!section.hasValidContent\">\r\n <p>No initial request details available.</p>\r\n </div>\r\n </p-accordionTab>\r\n </p-accordion>\r\n </div>\r\n \r\n <!-- Document History as regular timeline -->\r\n <div *ngIf=\"section.header !== 'Initial Request'\" class=\"document-history-section\">\r\n <div class=\"section-header\" *ngIf=\"section.header\">\r\n <h4 class=\"section-title\">{{ section.header }}</h4>\r\n </div>\r\n \r\n <div class=\"history-timeline\">\r\n <div class=\"timeline-item\" *ngFor=\"let item of section.list; let i = index\">\r\n <div class=\"timeline-card\" [ngClass]=\"item.actionBgColor\">\r\n <!-- Header with icon and timestamp -->\r\n <div class=\"card-header\">\r\n <div class=\"action-info\">\r\n <div class=\"action-icon\" [ngClass]=\"item.actionIconBgColor\">\r\n <i [class]=\"item.actionIcon\"></i>\r\n </div>\r\n <span class=\"action-label\" [ngClass]=\"item.actionColor\">\r\n {{ item.label }}\r\n </span>\r\n </div>\r\n <div class=\"timestamp\">\r\n {{ item.dateTime }}\r\n </div>\r\n </div>\r\n \r\n <!-- Description -->\r\n <div class=\"card-description\" *ngIf=\"item.requestDescription\">\r\n <p class=\"description-text\">{{ item.requestDescription }}</p>\r\n </div>\r\n \r\n <!-- Document details if URL exists -->\r\n <div class=\"document-details\" *ngIf=\"item.documentUrl\">\r\n <div class=\"document-card\">\r\n <div class=\"document-info\">\r\n <div class=\"document-icon\">\r\n <i class=\"pi pi-file\"></i>\r\n </div>\r\n <div class=\"document-text\">\r\n <div class=\"document-title\">Document</div>\r\n <div class=\"document-filename clickable\" \r\n (click)=\"downloadDocument(item.documentUrl!, item.docName)\"\r\n title=\"Click to download\">\r\n {{ item.docName || 'Document' }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- User information -->\r\n <div class=\"user-info\">\r\n <span class=\"user-name\">{{ item.userName }}</span>\r\n <span class=\"user-role\">({{ item.userRole }})</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>", styles: [".document-history-container{padding:1rem;background:#fff;border-radius:8px;box-shadow:0 2px 4px #0000001a;max-height:70vh;overflow-y:auto}.document-history-container .history-header{margin-bottom:1.5rem}.document-history-container .history-header .history-title{font-size:1.5rem;font-weight:600;color:#374151;margin:0}.document-history-container .history-sections .history-section{margin-bottom:2rem}.document-history-container .history-sections .history-section .initial-request-section{margin-bottom:1.5rem}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link{background:#fff;border:1px solid;border-radius:8px;padding:1rem 1.5rem;font-weight:600;color:#1f2937;font-size:1rem}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link:focus{box-shadow:none}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link .p-accordion-header-icon{color:#6b7280;font-size:.875rem}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-header.p-highlight .p-accordion-header-link{background:#fff}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content{background:#fff;border:1px solid;border-top:none;border-radius:0 0 8px 8px;padding:1.5rem}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item{margin-bottom:0}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card{background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;padding:1rem;border-right:3px solid}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .card-header .action-info .action-icon{background:#7d879b;color:#fff;width:32px;height:32px;border-radius:50%;display:flex;align-items:center;justify-content:center}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .card-header .action-info .action-icon i{font-size:14px}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .card-header .action-info .action-label{color:#1f2937;font-weight:600}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .card-header .timestamp{color:#6b7280;font-size:.75rem}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .card-description .description-text{color:#374151;line-height:1.5}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .user-info .user-name{color:#1f2937;font-weight:500}.document-history-container .history-sections .history-section .initial-request-section ::ng-deep .p-accordion .p-accordion-content .history-timeline .timeline-item .timeline-card .user-info .user-role{color:#6b7280}.document-history-container .history-sections .history-section .initial-request-section.document-requested ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link{border-color:#d1d5db}.document-history-container .history-sections .history-section .initial-request-section.document-requested ::ng-deep .p-accordion .p-accordion-content{border-color:#d1d5db}.document-history-container .history-sections .history-section .initial-request-section.document-uploaded ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link{border-color:#86efac}.document-history-container .history-sections .history-section .initial-request-section.document-uploaded ::ng-deep .p-accordion .p-accordion-content{border-color:#86efac}.document-history-container .history-sections .history-section .initial-request-section.document-rejected ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link{border-color:#fca5a5}.document-history-container .history-sections .history-section .initial-request-section.document-rejected ::ng-deep .p-accordion .p-accordion-content{border-color:#fca5a5}.document-history-container .history-sections .history-section .initial-request-section.document-accepted ::ng-deep .p-accordion .p-accordion-header .p-accordion-header-link{border-color:#86efac}.document-history-container .history-sections .history-section .initial-request-section.document-accepted ::ng-deep .p-accordion .p-accordion-content{border-color:#86efac}.document-history-container .history-sections .history-section .document-history-section .section-header{margin-bottom:1rem}.document-history-container .history-sections .history-section .document-history-section .section-header .section-title{font-size:1.25rem;font-weight:500;color:#374151;margin:0}.document-history-container .history-sections .history-section .history-timeline .timeline-item{margin-bottom:1rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card{border-radius:8px;border:1px solid;padding:1rem;position:relative;border-right:3px solid}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card.bg-green-50{background-color:#f0fdf4;border-color:#bbf7d0;border-right-color:#10b981}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card.bg-red-50{background-color:#fef2f2;border-color:#fecaca;border-right-color:#ef4444}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card.bg-blue-50{background-color:#eff6ff;border-color:#bfdbfe;border-right-color:#3b82f6}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card.bg-gray-50{background-color:#f8fafc;border-color:#e2e8f0;border-right-color:#6b7280}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:.75rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-header .action-info{display:flex;align-items:center;gap:.5rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-header .action-info .action-icon{width:32px;height:32px;border-radius:50%;display:flex;align-items:center;justify-content:center;color:#fff}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-header .action-info .action-icon i{font-size:14px}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-header .action-info .action-label{font-weight:600;font-size:.875rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-header .timestamp{font-size:.75rem;color:#6b7280}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-description{margin-bottom:.75rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .card-description .description-text{margin:0;color:#374151;font-size:.875rem;line-height:1.4}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details{margin-bottom:.75rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card{background:#fff;border-radius:6px;padding:.75rem;display:flex;justify-content:space-between;align-items:center;border:1px solid #e5e7eb}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-info{display:flex;align-items:center;gap:.5rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-info .document-icon{color:#3b82f6;font-size:1.25rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-info .document-text .document-title{font-weight:500;color:#374151;font-size:.875rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-info .document-text .document-filename{color:#3b82f6;font-size:.75rem;word-break:break-word}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-info .document-text .document-filename.clickable{cursor:pointer;text-decoration:underline}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-info .document-text .document-filename.clickable:hover{color:#2563eb;text-decoration:none}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions{display:flex;gap:.25rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn{width:24px;height:24px;border:none;border-radius:4px;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:.75rem}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn.edit-btn{background:#3b82f6;color:#fff}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn.edit-btn:hover{background:#2563eb}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn.delete-btn{background:#ef4444;color:#fff}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn.delete-btn:hover{background:#dc2626}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn.download-btn{background:#10b981;color:#fff}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .document-details .document-card .document-actions .action-btn.download-btn:hover{background:#059669}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .user-info{text-align:right;font-size:.75rem;color:#374151}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .user-info .user-name{font-weight:500}.document-history-container .history-sections .history-section .history-timeline .timeline-item .timeline-card .user-info .user-role{color:#6b7280}.text-green-600{color:#059669}.text-red-600{color:#dc2626}.text-blue-600{color:#2563eb}.text-gray-600{color:#4b5563}.bg-green-50{background-color:#f0fdf4}.bg-red-50{background-color:#fef2f2}.bg-blue-50{background-color:#eff6ff}.bg-gray-50{background-color:#f8fafc}.border-green-200{border-color:#bbf7d0}.border-red-200{border-color:#fecaca}.border-blue-200{border-color:#bfdbfe}.border-gray-200{border-color:#e2e8f0}.icon-bg-green{background-color:#10b981}.icon-bg-red{background-color:#ef4444}.icon-bg-blue{background-color:#3b82f6}.icon-bg-gray{background-color:#6b7280}.no-content-message{text-align:center;padding:2rem;color:#6b7280;font-style:italic}.no-content-message p{margin:0;font-size:.875rem}\n"] }]
3527
3691
  }], ctorParameters: () => [{ type: DocumentHistoryStyleService }], propDecorators: { historyData: [{
3528
3692
  type: Input
3529
3693
  }], showHistory: [{
@@ -3632,6 +3796,77 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
3632
3796
  }]
3633
3797
  }] });
3634
3798
 
3799
+ /**
3800
+ * Directive to conditionally show or hide elements based on user permissions.
3801
+ * @class HasPermissionDirective
3802
+ * @typedef {HasPermissionDirective}
3803
+ */
3804
+ class HasPermissionDirective {
3805
+ el;
3806
+ renderer;
3807
+ sessionService;
3808
+ /**
3809
+ * The required permission(s) to display the element.
3810
+ * Accepts a single string or an array of strings.
3811
+ * @type {string | string[]}
3812
+ */
3813
+ permission;
3814
+ /**
3815
+ * Creates an instance of HasPermissionDirective.
3816
+ * @param {ElementRef} el - Reference to the host element.
3817
+ * @param {Renderer2} renderer - Angular Renderer for DOM manipulation.
3818
+ * @param {SessionService} sessionService - Service to retrieve user permissions.
3819
+ */
3820
+ constructor(el, renderer, sessionService) {
3821
+ this.el = el;
3822
+ this.renderer = renderer;
3823
+ this.sessionService = sessionService;
3824
+ }
3825
+ /**
3826
+ * Lifecycle hook that is called when input properties change.
3827
+ * @param {SimpleChanges} changes - The changes in input properties.
3828
+ */
3829
+ ngOnChanges(changes) {
3830
+ if (changes['permission']) {
3831
+ this.checkPermission();
3832
+ }
3833
+ }
3834
+ /**
3835
+ * Checks if the user has the required permission(s).
3836
+ * Hides the element if the permission is not found.
3837
+ */
3838
+ checkPermission() {
3839
+ // If no permission is required (empty string, null, or undefined), show the element
3840
+ if (!this.permission || this.permission === '' || (Array.isArray(this.permission) && this.permission.length === 0)) {
3841
+ this.renderer.removeStyle(this.el.nativeElement, 'display');
3842
+ return;
3843
+ }
3844
+ const userPermissionsObjects = this.sessionService.getUserPermissions();
3845
+ const userPermissionNames = userPermissionsObjects?.map((perm) => perm.name) || [];
3846
+ const requiredPermissions = Array.isArray(this.permission)
3847
+ ? this.permission
3848
+ : [this.permission];
3849
+ const hasPermission = requiredPermissions.some(permission => userPermissionNames.includes(permission));
3850
+ if (!hasPermission) {
3851
+ this.renderer.setStyle(this.el.nativeElement, 'display', 'none');
3852
+ }
3853
+ else {
3854
+ this.renderer.removeStyle(this.el.nativeElement, 'display');
3855
+ }
3856
+ }
3857
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: HasPermissionDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: SessionService }], target: i0.ɵɵFactoryTarget.Directive });
3858
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.14", type: HasPermissionDirective, isStandalone: false, selector: "[permission]", inputs: { permission: "permission" }, usesOnChanges: true, ngImport: i0 });
3859
+ }
3860
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: HasPermissionDirective, decorators: [{
3861
+ type: Directive,
3862
+ args: [{
3863
+ selector: '[permission]',
3864
+ standalone: false
3865
+ }]
3866
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: SessionService }], propDecorators: { permission: [{
3867
+ type: Input
3868
+ }] } });
3869
+
3635
3870
  class DocumentActionsComponent {
3636
3871
  documentActionsService;
3637
3872
  SHARED = SHARED;
@@ -3644,14 +3879,22 @@ class DocumentActionsComponent {
3644
3879
  showAcceptDialog = false;
3645
3880
  showRejectDialog = false;
3646
3881
  acceptNote = SHARED.EMPTY;
3647
- rejectNote = SHARED.EMPTY;
3882
+ _rejectNote = SHARED.EMPTY;
3648
3883
  // Computed properties for template
3649
3884
  cardClass = SHARED.CARD_PENDING;
3650
3885
  rejectButtonClass = SHARED.BUTTON_DEFAULT_REJECT;
3651
3886
  acceptButtonClass = SHARED.BUTTON_DEFAULT_ACCEPT;
3887
+ isRejectNoteEmpty = true;
3652
3888
  constructor(documentActionsService) {
3653
3889
  this.documentActionsService = documentActionsService;
3654
3890
  }
3891
+ get rejectNote() {
3892
+ return this._rejectNote;
3893
+ }
3894
+ set rejectNote(value) {
3895
+ this._rejectNote = value;
3896
+ this.updateRejectNoteEmpty();
3897
+ }
3655
3898
  ngOnChanges(changes) {
3656
3899
  this.updateComputedProperties();
3657
3900
  }
@@ -3662,6 +3905,13 @@ class DocumentActionsComponent {
3662
3905
  this.cardClass = this.documentActionsService.calculateCardClass(this.currentStatus, this.statusId);
3663
3906
  this.rejectButtonClass = this.documentActionsService.calculateRejectButtonClass(this.currentStatus, this.statusId);
3664
3907
  this.acceptButtonClass = this.documentActionsService.calculateAcceptButtonClass(this.currentStatus, this.statusId);
3908
+ this.updateRejectNoteEmpty();
3909
+ }
3910
+ /**
3911
+ * Updates the isRejectNoteEmpty property based on current rejectNote value
3912
+ */
3913
+ updateRejectNoteEmpty() {
3914
+ this.isRejectNoteEmpty = !this.rejectNote || this.rejectNote.trim() === SHARED.EMPTY;
3665
3915
  }
3666
3916
  onAcceptClick() {
3667
3917
  this.showAcceptDialog = true;
@@ -3689,11 +3939,11 @@ class DocumentActionsComponent {
3689
3939
  this.rejectNote = SHARED.EMPTY;
3690
3940
  }
3691
3941
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentActionsComponent, deps: [{ token: DocumentActionsService }], target: i0.ɵɵFactoryTarget.Component });
3692
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DocumentActionsComponent, isStandalone: false, selector: "document-actions", inputs: { documentId: "documentId", currentStatus: "currentStatus", isLoading: "isLoading", isUploaded: "isUploaded", statusId: "statusId" }, outputs: { actionPerformed: "actionPerformed" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"document-actions-container\" *ngIf=\"isUploaded\">\r\n <div class=\"actions-card\" [ngClass]=\"cardClass\">\r\n <div class=\"actions-buttons\">\r\n <!-- Reject Button -->\r\n <button \r\n class=\"action-btn reject-btn\" \r\n [ngClass]=\"rejectButtonClass\"\r\n (click)=\"onRejectClick()\"\r\n [disabled]=\"currentStatus === SHARED.STATUS_REJECTED_LOWERCASE || isLoading\">\r\n <i class=\"pi pi-times\" *ngIf=\"currentStatus === SHARED.STATUS_REJECTED_LOWERCASE\"></i>\r\n <span>{{ currentStatus === SHARED.STATUS_REJECTED_LOWERCASE ? SHARED.BUTTON_LABEL_REJECTED : SHARED.BUTTON_LABEL_REJECT }}</span>\r\n </button>\r\n\r\n <!-- Accept Button -->\r\n <button \r\n class=\"action-btn accept-btn\" \r\n [ngClass]=\"acceptButtonClass\"\r\n (click)=\"onAcceptClick()\"\r\n [disabled]=\"currentStatus === SHARED.STATUS_ACCEPTED || isLoading\">\r\n <i class=\"pi pi-check\" *ngIf=\"currentStatus === SHARED.STATUS_ACCEPTED\"></i>\r\n <i class=\"pi pi-spin pi-spinner\" *ngIf=\"isLoading\"></i>\r\n <span>{{ currentStatus === SHARED.STATUS_ACCEPTED ? SHARED.BUTTON_LABEL_ACCEPTED : SHARED.BUTTON_LABEL_ACCEPT }}</span>\r\n </button>\r\n\r\n <!-- Delete Button -->\r\n <button \r\n class=\"action-btn delete-btn\" \r\n (click)=\"onDeleteClick()\"\r\n [disabled]=\"isLoading\">\r\n <i class=\"pi pi-trash\"></i>\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Accept Confirmation Dialog -->\r\n<p-dialog \r\n [(visible)]=\"showAcceptDialog\" \r\n [header]=\"SHARED.ACCEPT_CONFIRM_HEADER\" \r\n [modal]=\"true\" \r\n [draggable]=\"false\" \r\n [closable]=\"true\"\r\n [style]=\"{ width: '25rem', height: '25rem' }\"\r\n 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 \r\n id=\"acceptNote\"\r\n pInputTextarea \r\n [(ngModel)]=\"acceptNote\" \r\n [placeholder]=\"SHARED.ACCEPT_NOTE_PLACEHOLDER\"\r\n rows=\"6\"\r\n class=\"note-textarea\">\r\n </textarea>\r\n </div>\r\n <ng-template pTemplate=\"footer\">\r\n <div class=\"dialog-footer\">\r\n <button \r\n pButton \r\n [label]=\"SHARED.CANCEL_BUTTON_LABEL\" \r\n class=\"p-button-secondary\" \r\n (click)=\"onCancel()\">\r\n </button>\r\n <button \r\n pButton \r\n [label]=\"SHARED.ACCEPT_BUTTON_LABEL\" \r\n class=\"p-button-success\" \r\n (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 \r\n [(visible)]=\"showRejectDialog\" \r\n [header]=\"SHARED.REJECT_CONFIRM_HEADER\" \r\n [modal]=\"true\" \r\n [draggable]=\"false\" \r\n [closable]=\"true\"\r\n [style]=\"{ width: '25rem', height: '25rem' }\"\r\n 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 \r\n id=\"rejectNote\"\r\n pInputTextarea \r\n [(ngModel)]=\"rejectNote\" \r\n [placeholder]=\"SHARED.REJECT_NOTE_PLACEHOLDER\"\r\n rows=\"6\"\r\n class=\"note-textarea\">\r\n </textarea>\r\n </div>\r\n <ng-template pTemplate=\"footer\">\r\n <div class=\"dialog-footer\">\r\n <button \r\n pButton \r\n [label]=\"SHARED.CANCEL_BUTTON_LABEL\" \r\n class=\"p-button-secondary\" \r\n (click)=\"onCancel()\">\r\n </button>\r\n <button \r\n pButton \r\n [label]=\"SHARED.REJECT_BUTTON_LABEL\" \r\n class=\"p-button-danger\" \r\n (click)=\"onRejectConfirm()\">\r\n </button>\r\n </div>\r\n </ng-template>\r\n</p-dialog> ", styles: [".document-actions-container{margin:1rem 0}.actions-card{border-radius:8px;padding:1rem;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: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3$1.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.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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i7$1.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"] }] });
3942
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DocumentActionsComponent, isStandalone: false, selector: "document-actions", inputs: { documentId: "documentId", currentStatus: "currentStatus", isLoading: "isLoading", isUploaded: "isUploaded", statusId: "statusId" }, outputs: { actionPerformed: "actionPerformed" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"document-actions-container\" *ngIf=\"isUploaded\">\r\n <div class=\"actions-card\" [ngClass]=\"cardClass\">\r\n <div class=\"actions-buttons\">\r\n <!-- Reject Button -->\r\n <button \r\n class=\"action-btn reject-btn\" \r\n [ngClass]=\"rejectButtonClass\"\r\n (click)=\"onRejectClick()\"\r\n [disabled]=\"currentStatus === SHARED.STATUS_REJECTED_LOWERCASE || isLoading\">\r\n <i class=\"pi pi-times\" *ngIf=\"currentStatus === SHARED.STATUS_REJECTED_LOWERCASE\"></i>\r\n <span>{{ currentStatus === SHARED.STATUS_REJECTED_LOWERCASE ? SHARED.BUTTON_LABEL_REJECTED : SHARED.BUTTON_LABEL_REJECT }}</span>\r\n </button>\r\n\r\n <!-- Accept Button -->\r\n <button \r\n class=\"action-btn accept-btn\" \r\n [ngClass]=\"acceptButtonClass\"\r\n (click)=\"onAcceptClick()\"\r\n [disabled]=\"currentStatus === SHARED.STATUS_ACCEPTED || isLoading\">\r\n <i class=\"pi pi-check\" *ngIf=\"currentStatus === SHARED.STATUS_ACCEPTED\"></i>\r\n <i class=\"pi pi-spin pi-spinner\" *ngIf=\"isLoading\"></i>\r\n <span>{{ currentStatus === SHARED.STATUS_ACCEPTED ? SHARED.BUTTON_LABEL_ACCEPTED : SHARED.BUTTON_LABEL_ACCEPT }}</span>\r\n </button>\r\n\r\n <!-- Delete Button -->\r\n <button \r\n class=\"action-btn delete-btn\" \r\n (click)=\"onDeleteClick()\"\r\n [disabled]=\"isLoading\"\r\n [permission]=\"'Documents-DELETE'\">\r\n <i class=\"pi pi-trash\"></i>\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Accept Confirmation Dialog -->\r\n<p-dialog \r\n [(visible)]=\"showAcceptDialog\" \r\n [header]=\"SHARED.ACCEPT_CONFIRM_HEADER\" \r\n [modal]=\"true\" \r\n [draggable]=\"false\" \r\n [closable]=\"true\"\r\n [style]=\"{ width: '25rem', height: '25rem' }\"\r\n 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 \r\n id=\"acceptNote\"\r\n pInputTextarea \r\n [(ngModel)]=\"acceptNote\" \r\n [placeholder]=\"SHARED.ACCEPT_NOTE_PLACEHOLDER\"\r\n rows=\"6\"\r\n class=\"note-textarea\">\r\n </textarea>\r\n </div>\r\n <ng-template pTemplate=\"footer\">\r\n <div class=\"dialog-footer\">\r\n <button \r\n pButton \r\n [label]=\"SHARED.CANCEL_BUTTON_LABEL\" \r\n class=\"p-button-secondary\" \r\n (click)=\"onCancel()\">\r\n </button>\r\n <button \r\n pButton \r\n [label]=\"SHARED.ACCEPT_BUTTON_LABEL\" \r\n class=\"p-button-success\" \r\n (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 \r\n [(visible)]=\"showRejectDialog\" \r\n [header]=\"SHARED.REJECT_CONFIRM_HEADER\" \r\n [modal]=\"true\" \r\n [draggable]=\"false\" \r\n [closable]=\"true\"\r\n [style]=\"{ width: '25rem', height: '25rem' }\"\r\n 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 \r\n id=\"rejectNote\"\r\n pInputTextarea \r\n [(ngModel)]=\"rejectNote\" \r\n [placeholder]=\"SHARED.REJECT_NOTE_PLACEHOLDER\"\r\n rows=\"6\"\r\n class=\"note-textarea\">\r\n </textarea>\r\n </div>\r\n <ng-template pTemplate=\"footer\">\r\n <div class=\"dialog-footer\">\r\n <button \r\n pButton \r\n [label]=\"SHARED.CANCEL_BUTTON_LABEL\" \r\n class=\"p-button-secondary\" \r\n (click)=\"onCancel()\">\r\n </button>\r\n <button \r\n pButton \r\n [label]=\"SHARED.REJECT_BUTTON_LABEL\" \r\n class=\"p-button-danger\" \r\n [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:1rem 0}.actions-card{border-radius:8px;padding:1rem;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: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3$1.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.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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i7$1.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: HasPermissionDirective, selector: "[permission]", inputs: ["permission"] }] });
3693
3943
  }
3694
3944
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentActionsComponent, decorators: [{
3695
3945
  type: Component,
3696
- args: [{ selector: 'document-actions', standalone: false, template: "<div class=\"document-actions-container\" *ngIf=\"isUploaded\">\r\n <div class=\"actions-card\" [ngClass]=\"cardClass\">\r\n <div class=\"actions-buttons\">\r\n <!-- Reject Button -->\r\n <button \r\n class=\"action-btn reject-btn\" \r\n [ngClass]=\"rejectButtonClass\"\r\n (click)=\"onRejectClick()\"\r\n [disabled]=\"currentStatus === SHARED.STATUS_REJECTED_LOWERCASE || isLoading\">\r\n <i class=\"pi pi-times\" *ngIf=\"currentStatus === SHARED.STATUS_REJECTED_LOWERCASE\"></i>\r\n <span>{{ currentStatus === SHARED.STATUS_REJECTED_LOWERCASE ? SHARED.BUTTON_LABEL_REJECTED : SHARED.BUTTON_LABEL_REJECT }}</span>\r\n </button>\r\n\r\n <!-- Accept Button -->\r\n <button \r\n class=\"action-btn accept-btn\" \r\n [ngClass]=\"acceptButtonClass\"\r\n (click)=\"onAcceptClick()\"\r\n [disabled]=\"currentStatus === SHARED.STATUS_ACCEPTED || isLoading\">\r\n <i class=\"pi pi-check\" *ngIf=\"currentStatus === SHARED.STATUS_ACCEPTED\"></i>\r\n <i class=\"pi pi-spin pi-spinner\" *ngIf=\"isLoading\"></i>\r\n <span>{{ currentStatus === SHARED.STATUS_ACCEPTED ? SHARED.BUTTON_LABEL_ACCEPTED : SHARED.BUTTON_LABEL_ACCEPT }}</span>\r\n </button>\r\n\r\n <!-- Delete Button -->\r\n <button \r\n class=\"action-btn delete-btn\" \r\n (click)=\"onDeleteClick()\"\r\n [disabled]=\"isLoading\">\r\n <i class=\"pi pi-trash\"></i>\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Accept Confirmation Dialog -->\r\n<p-dialog \r\n [(visible)]=\"showAcceptDialog\" \r\n [header]=\"SHARED.ACCEPT_CONFIRM_HEADER\" \r\n [modal]=\"true\" \r\n [draggable]=\"false\" \r\n [closable]=\"true\"\r\n [style]=\"{ width: '25rem', height: '25rem' }\"\r\n 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 \r\n id=\"acceptNote\"\r\n pInputTextarea \r\n [(ngModel)]=\"acceptNote\" \r\n [placeholder]=\"SHARED.ACCEPT_NOTE_PLACEHOLDER\"\r\n rows=\"6\"\r\n class=\"note-textarea\">\r\n </textarea>\r\n </div>\r\n <ng-template pTemplate=\"footer\">\r\n <div class=\"dialog-footer\">\r\n <button \r\n pButton \r\n [label]=\"SHARED.CANCEL_BUTTON_LABEL\" \r\n class=\"p-button-secondary\" \r\n (click)=\"onCancel()\">\r\n </button>\r\n <button \r\n pButton \r\n [label]=\"SHARED.ACCEPT_BUTTON_LABEL\" \r\n class=\"p-button-success\" \r\n (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 \r\n [(visible)]=\"showRejectDialog\" \r\n [header]=\"SHARED.REJECT_CONFIRM_HEADER\" \r\n [modal]=\"true\" \r\n [draggable]=\"false\" \r\n [closable]=\"true\"\r\n [style]=\"{ width: '25rem', height: '25rem' }\"\r\n 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 \r\n id=\"rejectNote\"\r\n pInputTextarea \r\n [(ngModel)]=\"rejectNote\" \r\n [placeholder]=\"SHARED.REJECT_NOTE_PLACEHOLDER\"\r\n rows=\"6\"\r\n class=\"note-textarea\">\r\n </textarea>\r\n </div>\r\n <ng-template pTemplate=\"footer\">\r\n <div class=\"dialog-footer\">\r\n <button \r\n pButton \r\n [label]=\"SHARED.CANCEL_BUTTON_LABEL\" \r\n class=\"p-button-secondary\" \r\n (click)=\"onCancel()\">\r\n </button>\r\n <button \r\n pButton \r\n [label]=\"SHARED.REJECT_BUTTON_LABEL\" \r\n class=\"p-button-danger\" \r\n (click)=\"onRejectConfirm()\">\r\n </button>\r\n </div>\r\n </ng-template>\r\n</p-dialog> ", styles: [".document-actions-container{margin:1rem 0}.actions-card{border-radius:8px;padding:1rem;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"] }]
3946
+ args: [{ selector: 'document-actions', standalone: false, template: "<div class=\"document-actions-container\" *ngIf=\"isUploaded\">\r\n <div class=\"actions-card\" [ngClass]=\"cardClass\">\r\n <div class=\"actions-buttons\">\r\n <!-- Reject Button -->\r\n <button \r\n class=\"action-btn reject-btn\" \r\n [ngClass]=\"rejectButtonClass\"\r\n (click)=\"onRejectClick()\"\r\n [disabled]=\"currentStatus === SHARED.STATUS_REJECTED_LOWERCASE || isLoading\">\r\n <i class=\"pi pi-times\" *ngIf=\"currentStatus === SHARED.STATUS_REJECTED_LOWERCASE\"></i>\r\n <span>{{ currentStatus === SHARED.STATUS_REJECTED_LOWERCASE ? SHARED.BUTTON_LABEL_REJECTED : SHARED.BUTTON_LABEL_REJECT }}</span>\r\n </button>\r\n\r\n <!-- Accept Button -->\r\n <button \r\n class=\"action-btn accept-btn\" \r\n [ngClass]=\"acceptButtonClass\"\r\n (click)=\"onAcceptClick()\"\r\n [disabled]=\"currentStatus === SHARED.STATUS_ACCEPTED || isLoading\">\r\n <i class=\"pi pi-check\" *ngIf=\"currentStatus === SHARED.STATUS_ACCEPTED\"></i>\r\n <i class=\"pi pi-spin pi-spinner\" *ngIf=\"isLoading\"></i>\r\n <span>{{ currentStatus === SHARED.STATUS_ACCEPTED ? SHARED.BUTTON_LABEL_ACCEPTED : SHARED.BUTTON_LABEL_ACCEPT }}</span>\r\n </button>\r\n\r\n <!-- Delete Button -->\r\n <button \r\n class=\"action-btn delete-btn\" \r\n (click)=\"onDeleteClick()\"\r\n [disabled]=\"isLoading\"\r\n [permission]=\"'Documents-DELETE'\">\r\n <i class=\"pi pi-trash\"></i>\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Accept Confirmation Dialog -->\r\n<p-dialog \r\n [(visible)]=\"showAcceptDialog\" \r\n [header]=\"SHARED.ACCEPT_CONFIRM_HEADER\" \r\n [modal]=\"true\" \r\n [draggable]=\"false\" \r\n [closable]=\"true\"\r\n [style]=\"{ width: '25rem', height: '25rem' }\"\r\n 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 \r\n id=\"acceptNote\"\r\n pInputTextarea \r\n [(ngModel)]=\"acceptNote\" \r\n [placeholder]=\"SHARED.ACCEPT_NOTE_PLACEHOLDER\"\r\n rows=\"6\"\r\n class=\"note-textarea\">\r\n </textarea>\r\n </div>\r\n <ng-template pTemplate=\"footer\">\r\n <div class=\"dialog-footer\">\r\n <button \r\n pButton \r\n [label]=\"SHARED.CANCEL_BUTTON_LABEL\" \r\n class=\"p-button-secondary\" \r\n (click)=\"onCancel()\">\r\n </button>\r\n <button \r\n pButton \r\n [label]=\"SHARED.ACCEPT_BUTTON_LABEL\" \r\n class=\"p-button-success\" \r\n (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 \r\n [(visible)]=\"showRejectDialog\" \r\n [header]=\"SHARED.REJECT_CONFIRM_HEADER\" \r\n [modal]=\"true\" \r\n [draggable]=\"false\" \r\n [closable]=\"true\"\r\n [style]=\"{ width: '25rem', height: '25rem' }\"\r\n 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 \r\n id=\"rejectNote\"\r\n pInputTextarea \r\n [(ngModel)]=\"rejectNote\" \r\n [placeholder]=\"SHARED.REJECT_NOTE_PLACEHOLDER\"\r\n rows=\"6\"\r\n class=\"note-textarea\">\r\n </textarea>\r\n </div>\r\n <ng-template pTemplate=\"footer\">\r\n <div class=\"dialog-footer\">\r\n <button \r\n pButton \r\n [label]=\"SHARED.CANCEL_BUTTON_LABEL\" \r\n class=\"p-button-secondary\" \r\n (click)=\"onCancel()\">\r\n </button>\r\n <button \r\n pButton \r\n [label]=\"SHARED.REJECT_BUTTON_LABEL\" \r\n class=\"p-button-danger\" \r\n [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:1rem 0}.actions-card{border-radius:8px;padding:1rem;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"] }]
3697
3947
  }], ctorParameters: () => [{ type: DocumentActionsService }], propDecorators: { documentId: [{
3698
3948
  type: Input
3699
3949
  }], currentStatus: [{
@@ -4091,6 +4341,20 @@ class DocumentListComponent {
4091
4341
  this.categoryCompletionCounts = SHARED.EMPTY_ARRAY;
4092
4342
  return;
4093
4343
  }
4344
+ // Handle empty response - create a default category to show "No records found"
4345
+ if (this.documentListResponse.length === 0) {
4346
+ this.documentCategories = [{
4347
+ label: SHARED.EMPTY,
4348
+ categoryDescription: SHARED.NO_DOCUMENTS_FOUND,
4349
+ list: SHARED.EMPTY_ARRAY,
4350
+ totalDocs: 0,
4351
+ acceptedDocs: 0,
4352
+ completed: '0/0'
4353
+ }];
4354
+ this.categoryTables = [this.documentTableBuilder.buildDocumentTable([])];
4355
+ this.categoryCompletionCounts = ['0/0'];
4356
+ return;
4357
+ }
4094
4358
  this.documentCategories = [...this.documentListResponse];
4095
4359
  this.categoryTables = this.documentListResponse.map(category => this.documentTableBuilder.buildDocumentTable(category.list));
4096
4360
  this.categoryCompletionCounts = this.documentListResponse.map(category => this.getCompletionCount(category));
@@ -4122,6 +4386,8 @@ class DocumentListComponent {
4122
4386
  this.documentHttpService.deleteDocument(rowData._id, this.contextId).subscribe({
4123
4387
  next: (response) => {
4124
4388
  console.log('Document deleted successfully:', response);
4389
+ // Refresh all data with current filters preserved
4390
+ this.documentHelperService.refreshAllDataWithCurrentFilters(this.contextId);
4125
4391
  },
4126
4392
  error: (error) => {
4127
4393
  console.error('Error deleting document:', error);