cat-documents-ng 0.2.87 → 0.2.89

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, EventEmitter, Output, ViewChild, Input, ViewEncapsulation, Component, ChangeDetectionStrategy, Directive, NgModule, APP_INITIALIZER } from '@angular/core';
2
+ import { Injectable, EventEmitter, Output, ViewChild, Input, ViewEncapsulation, Component, HostListener, ChangeDetectionStrategy, Directive, NgModule, APP_INITIALIZER } from '@angular/core';
3
3
  import * as i2$1 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
5
  import { firstValueFrom, tap, EMPTY, catchError, throwError, of, combineLatest, Subject, Observable, takeUntil, Subscription, debounceTime as debounceTime$1, distinctUntilChanged as distinctUntilChanged$1 } from 'rxjs';
@@ -44,6 +44,7 @@ import { ConfirmDialogModule } from 'primeng/confirmdialog';
44
44
  import * as i5$2 from 'primeng/inputtextarea';
45
45
  import { InputTextareaModule } from 'primeng/inputtextarea';
46
46
  import * as i8 from 'primeng/tooltip';
47
+ import { TooltipModule } from 'primeng/tooltip';
47
48
  import * as i7$2 from 'primeng/badge';
48
49
  import { BadgeModule } from 'primeng/badge';
49
50
  import * as i8$1 from 'primeng/menu';
@@ -116,6 +117,10 @@ class SHARED {
116
117
  * Represents an empty string.
117
118
  */
118
119
  static EMPTY = "";
120
+ /**
121
+ * Represents an empty string.
122
+ */
123
+ static STRING = "string";
119
124
  /**
120
125
  * Represents an true.
121
126
  * @static
@@ -286,7 +291,16 @@ class SHARED {
286
291
  static UPLOAD_FAILED = 'Upload failed';
287
292
  static USER_LIST = 'userList';
288
293
  static CATEGORIES = 'categories';
294
+ static UNSAVED_CHANGES_MESSAGE = 'You will loose all the data that was filled in the respective fields.';
295
+ static UNSAVED_CHANGES_HEADER = 'Unsaved Changes';
289
296
  static DOCUMENT_DELETED_SUCCESSFULLY = 'Document deleted successfully';
297
+ static UNSAVED_CHANGES_ICON = 'pi pi-exclamation-triangle';
298
+ static REMOVE = 'Remove';
299
+ static CANCEL = 'Cancel';
300
+ static ACCEPT_ICON = 'pi pi-times';
301
+ static REJECT_ICON = 'pi pi-check';
302
+ static ACCEPT_BUTTON_STYLE_CLASS = 'p-button-danger';
303
+ static REJECT_BUTTON_STYLE_CLASS = 'p-button-secondary';
290
304
  static Menu = [
291
305
  {
292
306
  label: 'Applicant',
@@ -1299,7 +1313,7 @@ class DocumentService {
1299
1313
  * @returns {Observable<any>} Observable that emits the newly created document.
1300
1314
  */
1301
1315
  create(entity) {
1302
- const headers = { 'Authorization': 'Bearer 514330f0-41d4-4c03-8d2e-f248a1340e8d' };
1316
+ const headers = { 'Authorization': 'Bearer a79cbca8-164c-4ec3-991d-0efb441ff126' };
1303
1317
  return this.http.post(`${this.apiUrl}${URLS.DOCUMENT_UPLOAD_FILE}`, entity, { headers }).pipe(tap((newEntity) => this.documentStore.add(newEntity)));
1304
1318
  }
1305
1319
  /**
@@ -1390,13 +1404,6 @@ class DocumentQuery extends QueryEntity {
1390
1404
  selectDocumentCategories() {
1391
1405
  return this.select((state) => state.documentCategories);
1392
1406
  }
1393
- /**
1394
- * Gets the current document categories value (synchronous).
1395
- * @returns {DocumentCategory[]} The current document categories.
1396
- */
1397
- getDocumentCategories() {
1398
- return this.getValue().documentCategories;
1399
- }
1400
1407
  // New query methods for selection state
1401
1408
  /**
1402
1409
  * Selects the currently selected menu item.
@@ -1711,7 +1718,7 @@ class DocumentHttpService {
1711
1718
  * @returns {Observable<any>} Observable that emits the transformed data for dropdown options.
1712
1719
  */
1713
1720
  getDocumentCatagories(contextId) {
1714
- let headers = new HttpHeaders({ Authorization: `Bearer 514330f0-41d4-4c03-8d2e-f248a1340e8d` });
1721
+ let headers = new HttpHeaders({ Authorization: `Bearer a79cbca8-164c-4ec3-991d-0efb441ff126` });
1715
1722
  return this.http.get(`${this.apiUrl}${URLS.DOCUMENTS_CATAGORIES}/${contextId}`, { headers }).pipe(tap((response) => {
1716
1723
  // Store only the categories array, not the entire response
1717
1724
  if (response && response.categories) {
@@ -1770,7 +1777,7 @@ class DocumentHttpService {
1770
1777
  * @returns {Observable<DocumentModel>} An observable that emits the updated DocumentModel.
1771
1778
  */
1772
1779
  updateDocumentName(documentId, payload) {
1773
- let headers = new HttpHeaders({ Authorization: `Bearer 514330f0-41d4-4c03-8d2e-f248a1340e8d` });
1780
+ let headers = new HttpHeaders({ Authorization: `Bearer a79cbca8-164c-4ec3-991d-0efb441ff126` });
1774
1781
  return this.http.put(`${this.apiUrl}${URLS.DOCUMENT_UPLOAD}/${documentId}`, payload, { headers }).pipe(catchError((error) => {
1775
1782
  return throwError(() => new Error(error));
1776
1783
  }));
@@ -1783,7 +1790,7 @@ class DocumentHttpService {
1783
1790
  getUserListByContextId(contextId) {
1784
1791
  if (!contextId)
1785
1792
  return EMPTY;
1786
- let headers = new HttpHeaders({ Authorization: `Bearer 514330f0-41d4-4c03-8d2e-f248a1340e8d` });
1793
+ let headers = new HttpHeaders({ Authorization: `Bearer a79cbca8-164c-4ec3-991d-0efb441ff126` });
1787
1794
  return this.http.get(`${this.apiUrl}${URLS.USERLIST}${contextId}`, { headers }).pipe(tap((userList) => {
1788
1795
  this.documentStore.setUserList(userList);
1789
1796
  }), catchError((error) => {
@@ -1809,7 +1816,7 @@ class DocumentHttpService {
1809
1816
  if (categoryId) {
1810
1817
  params = params.set(SHARED.CATEGORY, categoryId);
1811
1818
  }
1812
- let headers = new HttpHeaders({ Authorization: `Bearer 514330f0-41d4-4c03-8d2e-f248a1340e8d` });
1819
+ let headers = new HttpHeaders({ Authorization: `Bearer a79cbca8-164c-4ec3-991d-0efb441ff126` });
1813
1820
  return this.http.get(url, { params, headers }).pipe(tap((statusData) => {
1814
1821
  this.documentStore.setStatusData(statusData);
1815
1822
  }), catchError((error) => {
@@ -1840,7 +1847,7 @@ class DocumentHttpService {
1840
1847
  if (searchKey) {
1841
1848
  params = params.set(SHARED.SEARCH_KEY, searchKey);
1842
1849
  }
1843
- let headers = new HttpHeaders({ Authorization: `Bearer 514330f0-41d4-4c03-8d2e-f248a1340e8d` });
1850
+ let headers = new HttpHeaders({ Authorization: `Bearer a79cbca8-164c-4ec3-991d-0efb441ff126` });
1844
1851
  return this.http.get(`${this.apiUrl}${URLS.GETALL}/${contextId}`, { params, headers }).pipe(tap((response) => {
1845
1852
  if (response.documents) {
1846
1853
  this.documentStore.setDocumentList(response.documents);
@@ -1853,7 +1860,7 @@ class DocumentHttpService {
1853
1860
  if (!documentId) {
1854
1861
  return of([]);
1855
1862
  }
1856
- let headers = new HttpHeaders({ Authorization: `Bearer 514330f0-41d4-4c03-8d2e-f248a1340e8d` });
1863
+ let headers = new HttpHeaders({ Authorization: `Bearer a79cbca8-164c-4ec3-991d-0efb441ff126` });
1857
1864
  return this.http.get(`${this.apiUrl}${URLS.DOCUMENT_HISTORY}${documentId}`, { headers });
1858
1865
  }
1859
1866
  /**
@@ -1864,7 +1871,7 @@ class DocumentHttpService {
1864
1871
  getCategoriesBySource(source) {
1865
1872
  if (!source)
1866
1873
  return EMPTY;
1867
- let headers = new HttpHeaders({ Authorization: `Bearer 514330f0-41d4-4c03-8d2e-f248a1340e8d` });
1874
+ let headers = new HttpHeaders({ Authorization: `Bearer a79cbca8-164c-4ec3-991d-0efb441ff126` });
1868
1875
  return this.http.get(`${this.apiUrl}${URLS.GET_CATEGORIES_BY_SOURCE}${source}`, { headers }).pipe(catchError((error) => {
1869
1876
  return throwError(() => new Error(error));
1870
1877
  }));
@@ -1877,7 +1884,7 @@ class DocumentHttpService {
1877
1884
  getDocumentTypesByCategory(categoryId) {
1878
1885
  if (!categoryId)
1879
1886
  return EMPTY;
1880
- let headers = new HttpHeaders({ Authorization: `Bearer 514330f0-41d4-4c03-8d2e-f248a1340e8d` });
1887
+ let headers = new HttpHeaders({ Authorization: `Bearer a79cbca8-164c-4ec3-991d-0efb441ff126` });
1881
1888
  return this.http.get(`${this.apiUrl}${URLS.GET_DOCUMENT_TYPES_BY_CATEGORY}${categoryId}`, { headers }).pipe(catchError((error) => {
1882
1889
  return throwError(() => new Error(error));
1883
1890
  }));
@@ -1888,7 +1895,7 @@ class DocumentHttpService {
1888
1895
  * @returns {Observable<any>} Observable that emits the upload response.
1889
1896
  */
1890
1897
  uploadFile(formData) {
1891
- let headers = new HttpHeaders({ Authorization: `Bearer 514330f0-41d4-4c03-8d2e-f248a1340e8d` });
1898
+ let headers = new HttpHeaders({ Authorization: `Bearer a79cbca8-164c-4ec3-991d-0efb441ff126` });
1892
1899
  return this.http.post(`${this.apiUrl}${URLS.DOCUMENT_UPLOAD_FILE}`, formData, { headers }).pipe(catchError((error) => {
1893
1900
  return throwError(() => new Error(error));
1894
1901
  }));
@@ -1899,7 +1906,7 @@ class DocumentHttpService {
1899
1906
  * @returns {Observable<any>} Observable that emits the save response.
1900
1907
  */
1901
1908
  saveDocumentUpload(payload) {
1902
- let headers = new HttpHeaders({ Authorization: `Bearer 514330f0-41d4-4c03-8d2e-f248a1340e8d` });
1909
+ let headers = new HttpHeaders({ Authorization: `Bearer a79cbca8-164c-4ec3-991d-0efb441ff126` });
1903
1910
  return this.http.post(`${this.apiUrl}${URLS.SAVE_DOCUMENT_UPLOAD}`, payload, { headers }).pipe(catchError((error) => {
1904
1911
  return throwError(() => new Error(error));
1905
1912
  }));
@@ -1915,7 +1922,7 @@ class DocumentHttpService {
1915
1922
  const payload = {
1916
1923
  statusUpdateDescription: statusUpdateDescription
1917
1924
  };
1918
- let headers = new HttpHeaders({ Authorization: `Bearer 514330f0-41d4-4c03-8d2e-f248a1340e8d` });
1925
+ let headers = new HttpHeaders({ Authorization: `Bearer a79cbca8-164c-4ec3-991d-0efb441ff126` });
1919
1926
  return this.http.put(`${this.apiUrl}${URLS.UPDATE_DOCUMENT_STATUS}${documentId}/${status}`, payload, { headers }).pipe(tap((response) => {
1920
1927
  if (response && response.status) {
1921
1928
  const normalizedStatus = this.normalizeStatus(response.status);
@@ -1949,7 +1956,7 @@ class DocumentHttpService {
1949
1956
  * @returns {Observable<any>} Observable that emits the delete response
1950
1957
  */
1951
1958
  deleteDocument(documentId, contextId) {
1952
- let headers = new HttpHeaders({ Authorization: `Bearer 514330f0-41d4-4c03-8d2e-f248a1340e8d` });
1959
+ let headers = new HttpHeaders({ Authorization: `Bearer a79cbca8-164c-4ec3-991d-0efb441ff126` });
1953
1960
  return this.http.delete(`${this.apiUrl}${URLS.DELETE_DOCUMENT}${documentId}`, { headers }).pipe(tap(() => {
1954
1961
  this.getDocumentCatagories(contextId).subscribe();
1955
1962
  this.getUserListByContextId(contextId).subscribe();
@@ -2417,6 +2424,28 @@ class DocumentUploadService {
2417
2424
  return null;
2418
2425
  }
2419
2426
  }
2427
+ /**
2428
+ * Generic method to sort any list of objects by a specified property.
2429
+ * Supports fallback properties if the primary property is undefined.
2430
+ * @param list - Array of objects to sort
2431
+ * @param primaryProperty - Primary property to sort by
2432
+ * @param fallbackProperty - Optional fallback property if primary is undefined
2433
+ * @returns Sorted array
2434
+ */
2435
+ sortListByProperty(list, primaryProperty, fallbackProperty) {
2436
+ return list.sort((a, b) => {
2437
+ const valueA = a[primaryProperty] || (fallbackProperty ? a[fallbackProperty] : SHARED.EMPTY);
2438
+ const valueB = b[primaryProperty] || (fallbackProperty ? b[fallbackProperty] : SHARED.EMPTY);
2439
+ if (typeof valueA === 'string' && typeof valueB === 'string') {
2440
+ return valueA.localeCompare(valueB);
2441
+ }
2442
+ if (valueA < valueB)
2443
+ return -1;
2444
+ if (valueA > valueB)
2445
+ return 1;
2446
+ return 0;
2447
+ });
2448
+ }
2420
2449
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentUploadService, deps: [{ token: DocumentService }, { token: DocumentStore }, { token: i3.MessageService }], target: i0.ɵɵFactoryTarget.Injectable });
2421
2450
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentUploadService, providedIn: 'root' });
2422
2451
  }
@@ -3150,7 +3179,7 @@ class DocumentUploadComponent {
3150
3179
  * @param applicants - Array of loaded applicants
3151
3180
  */
3152
3181
  handleApplicantsLoaded(applicants) {
3153
- this.applicantList = applicants;
3182
+ this.applicantList = this.documentUpload.sortListByProperty(applicants, 'name');
3154
3183
  this.filterApplicants();
3155
3184
  this.isLoadingApplicants = false;
3156
3185
  this.validateForm();
@@ -3161,7 +3190,7 @@ class DocumentUploadComponent {
3161
3190
  * @param categories - Array of loaded categories
3162
3191
  */
3163
3192
  handleCategoriesLoaded(categories) {
3164
- this.categoryOptions = categories;
3193
+ this.categoryOptions = this.documentUpload.sortListByProperty(categories, 'label');
3165
3194
  this.isLoadingCategories = false;
3166
3195
  this.validateForm();
3167
3196
  }
@@ -3171,7 +3200,7 @@ class DocumentUploadComponent {
3171
3200
  * @param documentTypes - Array of loaded document types
3172
3201
  */
3173
3202
  handleDocumentTypesLoaded(documentTypes) {
3174
- this.documentTypeOptions = documentTypes;
3203
+ this.documentTypeOptions = this.documentUpload.sortListByProperty(documentTypes, 'label', 'name');
3175
3204
  this.isLoadingDocumentTypes = false;
3176
3205
  this.validateForm();
3177
3206
  }
@@ -3288,11 +3317,11 @@ class DocumentUploadComponent {
3288
3317
  this.dataService.destroy();
3289
3318
  }
3290
3319
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentUploadComponent, deps: [{ token: DocumentUploadService }, { token: DocumentService }, { token: i3.PrimeNGConfig }, { token: FileFormatService }, { token: i3.MessageService }, { token: i0.ChangeDetectorRef }, { token: DocumentUploadBusinessService }, { token: DocumentUploadFormService }, { token: DocumentUploadDataService }], target: i0.ɵɵFactoryTarget.Component });
3291
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DocumentUploadComponent, isStandalone: false, selector: "lib-document-upload", inputs: { contextId: "contextId" }, outputs: { onFormValidationChange: "onFormValidationChange", onUploadSuccess: "onUploadSuccess" }, viewQueries: [{ propertyName: "fileUploader", first: true, predicate: ["fileUploader"], descendants: true }], ngImport: i0, template: "<div class=\"document-upload-container\">\r\n <!-- Assignment Section -->\r\n <div class=\"assignment-section\">\r\n <h4>Assign to Applicant(s) or Application</h4>\r\n <div class=\"radio-group\">\r\n <div class=\"radio-item\">\r\n <p-radioButton \r\n name=\"assignmentType\" \r\n value=\"Applicant\" \r\n [(ngModel)]=\"selectedAssignmentType\"\r\n (onClick)=\"onAssignmentTypeChange()\"\r\n [inputId]=\"'applicant'\"\r\n ></p-radioButton>\r\n <label [for]=\"'applicant'\" class=\"radio-label\">Applicant(s)</label>\r\n </div>\r\n <div class=\"radio-item\">\r\n <p-radioButton \r\n name=\"assignmentType\" \r\n value=\"Application\" \r\n [(ngModel)]=\"selectedAssignmentType\"\r\n (onClick)=\"onAssignmentTypeChange()\"\r\n [inputId]=\"'application'\"\r\n ></p-radioButton>\r\n <label [for]=\"'application'\" class=\"radio-label\">Application</label>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Applicant Selection (only shown when Applicant is selected) -->\r\n <div class=\"applicant-section\" *ngIf=\"selectedAssignmentType === 'Applicant'\">\r\n <h4>Select Applicant(s)</h4>\r\n <div class=\"grid\">\r\n <div \r\n *ngFor=\"let applicant of filteredApplicantList\" \r\n class=\"applicant-item col-12 md:col-6\"\r\n >\r\n <p-radioButton \r\n name=\"selectedApplicant\"\r\n [value]=\"applicant._id\"\r\n [(ngModel)]=\"selectedApplicant\"\r\n [inputId]=\"'applicant-' + applicant._id\"\r\n (onClick)=\"onApplicantSelectionChange()\"\r\n ></p-radioButton>\r\n <label [for]=\"'applicant-' + applicant._id\" class=\"applicant-label\">\r\n {{ applicant.name }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Category Selection -->\r\n <div class=\"category-section\">\r\n <h4>Category</h4>\r\n <p-dropdown\r\n [options]=\"categoryOptions\"\r\n [(ngModel)]=\"selectedCategory\"\r\n placeholder=\"Select Category type\"\r\n optionLabel=\"label\"\r\n optionValue=\"_id\"\r\n (onChange)=\"onCategoryChange()\"\r\n [disabled]=\"!categoryOptions.length\"\r\n class=\"w-full\"\r\n ></p-dropdown>\r\n </div>\r\n\r\n <!-- Document Type Selection -->\r\n <div class=\"document-type-section\">\r\n <h4>Document Type</h4>\r\n <p-dropdown\r\n [options]=\"documentTypeOptions\"\r\n [(ngModel)]=\"selectedDocumentType\"\r\n placeholder=\"Select Document type\"\r\n optionLabel=\"label\"\r\n optionValue=\"_id\"\r\n (onChange)=\"onDocumentTypeChange()\"\r\n [disabled]=\"!documentTypeOptions.length || !selectedCategory\"\r\n class=\"w-full\"\r\n ></p-dropdown>\r\n </div>\r\n\r\n <!-- File Upload Section -->\r\n <div class=\"file-upload-section\">\r\n <h4>Upload Documents</h4>\r\n <div class=\"grid\">\r\n <div class=\"col-12 md:col-12\">\r\n <p-fileUpload \r\n #fileUploader \r\n [multiple]=\"true\" \r\n auto=\"true\" \r\n accept=\"image/png,application/pdf\" \r\n maxFileSize=\"26214400\"\r\n (onSelect)=\"onSelectedFiles($event)\"\r\n >\r\n <ng-template pTemplate=\"header\" let-chooseCallback=\"chooseCallback\" let-clearCallback=\"clearCallback\">\r\n <div class=\"docHeader p-2 flex flex-wrap justify-content-between align-items-center flex-1 gap-2\">\r\n <div class=\"flex gap-2\">\r\n <p-button \r\n (onClick)=\"choose($event, chooseCallback)\" \r\n icon=\"pi pi-images\" \r\n [rounded]=\"true\"\r\n [outlined]=\"true\" \r\n />\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-template pTemplate=\"content\" let-removeFileCallback=\"removeFileCallback\"\r\n let-removeUploadedFileCallback=\"removeUploadedFileCallback\">\r\n <div class=\"col-12 md:col-12 p-0\">\r\n <div class=\"col-12 md:col-12 p-0\" *ngIf=\"uploadedFiles.length > 0\">\r\n <div *ngFor=\"let uploadedFile of uploadedFiles; let i = index\"\r\n class=\"m-0 flex flex-column align-items-center gap-1 mt-3\">\r\n <div class=\"col-12 md:col-12 p-0 flex documentInfo\">\r\n <div class=\"documentImage\">\r\n <img src=\"../../../../assets/images/document.png\" [alt]=\"uploadedFile.file.name\" width=\"45\" height=\"50\"\r\n class=\"object-contain\" />\r\n </div>\r\n <div class=\"flex w-full flex-column mt-2 ml-2\">\r\n <div class=\"flex justify-content-between\">\r\n <div style=\"font-weight: bold;font-size: 14px\">\r\n {{ uploadedFile.file.name }}\r\n </div>\r\n <i class=\"pi pi-times cursor-pointer\" (click)=\"handleDocumentRemove(uploadedFile.file,i)\"></i>\r\n </div>\r\n <div class=\"flex justify-content-between mt-1\">\r\n <div style=\"color: #676B89; font-size: 12px; color: green;\" class=\"pi pi-verified\"> \r\n {{ uploadedFile.formattedSize }}\r\n </div>\r\n <div class=\"white-space-nowrap\" style=\"color: #0F8BFD; font-family: 14px;\"> \r\n {{ uploadedFile.progress }} % \r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"col-12 md:col-12 p-0\">\r\n <p-progressBar \r\n [value]=\"uploadedFile.progress\" \r\n [showValue]=\"false\" \r\n styleClass=\"h-1/2rem md:ml-auto relative\"\r\n [ngClass]=\"{ 'exceeded-progress-bar': uploadedFile.progress && uploadedFile.progress > 100 }\"\r\n >\r\n </p-progressBar>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-template pTemplate=\"empty\" let-chooseCallback=\"chooseCallback\">\r\n <div *ngIf=\"!uploadedFiles.length\" class=\"flex align-items-center justify-content-center flex-column\"\r\n (click)=\"triggerFileUpload()\">\r\n <i class=\"pi pi-cloud-upload border-2 border-circle p-5 text-8xl text-400 border-400\"></i>\r\n <p class=\"mt-4 mb-0\">Drag and drop files here to upload.</p>\r\n </div>\r\n </ng-template>\r\n <ng-template pTemplate=\"file\"> </ng-template>\r\n </p-fileUpload>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [".flex{display:flex}.items-center{align-items:center}.justify-center{justify-content:center}.flex-col{flex-direction:column}.text-muted-color{color:#6c757d}.p-fileupload-buttonbar{padding:0}.p-fileupload-content{background-color:#0f8bfd1a}.p-fileupload .p-fileupload-content{padding:1rem}.docHeader .p-button-icon{padding:.5rem}.document-upload-container{padding:1rem;max-height:90vh}.assignment-section,.applicant-section,.category-section,.document-type-section,.file-upload-section{margin-bottom:1.5rem}.assignment-section h4,.applicant-section h4,.category-section h4,.document-type-section h4,.file-upload-section h4{margin:0 0 .75rem;font-size:1rem;font-weight:600;color:#212529}.radio-group{display:flex;gap:.75rem}.radio-item{display:flex;align-items:center;gap:.5rem;cursor:pointer;transition:all .2s ease}.radio-item:has(.p-radiobutton-box.p-highlight) .radio-label{color:#0f8bfd;font-weight:600}.radio-label{font-size:.9rem;color:#495057;cursor:pointer;-webkit-user-select:none;user-select:none;transition:color .2s ease}::ng-deep .p-dropdown{width:100%}::ng-deep .p-dropdown .p-dropdown-label{font-size:.9rem;color:#495057}::ng-deep .p-dropdown .p-dropdown-trigger{color:#6c757d}::ng-deep .p-dropdown:not(.p-disabled):hover{border-color:#0f8bfd}::ng-deep .p-dropdown:not(.p-disabled).p-focus{border-color:#0f8bfd;box-shadow:0 0 0 2px #0f8bfd33}::ng-deep .p-radiobutton .p-radiobutton-box{border-color:#ced4da;border-radius:4px;width:18px;height:18px}::ng-deep .p-radiobutton .p-radiobutton-box:hover{border-color:#0f8bfd}::ng-deep .p-radiobutton .p-radiobutton-box.p-highlight{border-color:#0f8bfd;background-color:transparent}::ng-deep .p-radiobutton .p-radiobutton-icon{background-color:#0f8bfd;width:8px;height:8px;border-radius:2px}.applicant-section .grid{margin:0;padding:0}.applicant-section .applicant-item{display:flex;align-items:center;gap:.75rem;border-radius:.5rem;background-color:#fff;transition:all .2s ease;cursor:pointer;margin-bottom:.75rem}.applicant-section .applicant-item:has(.p-radiobutton-box.p-highlight) .applicant-label{color:#0f8bfd;font-weight:600}.applicant-section .applicant-label{font-size:.95rem;color:#495057;cursor:pointer;-webkit-user-select:none;user-select:none;flex:1;font-weight:500;margin:0;transition:color .2s ease}@media (max-width: 768px){.applicant-section .applicant-item{margin-bottom:.5rem;padding:.75rem;min-height:50px}.applicant-section .applicant-label{font-size:.9rem}.document-upload-container{padding:.75rem}.assignment-section,.applicant-section,.category-section,.document-type-section,.file-upload-section{margin-bottom:1rem}}.category-section .p-dropdown,.document-type-section .p-dropdown{width:100%!important;min-width:100%!important}.category-section .p-dropdown-panel,.document-type-section .p-dropdown-panel{width:100%!important}:host ::ng-deep .p-dropdown{width:100%!important}:host ::ng-deep .p-dropdown-panel{width:100%!important}.applicant-list{display:none}\n"], dependencies: [{ kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: i4.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "style", "styleClass", "badgeClass", "ariaLabel", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i10.FileUpload, selector: "p-fileUpload", inputs: ["name", "url", "method", "multiple", "accept", "disabled", "auto", "withCredentials", "maxFileSize", "invalidFileSizeMessageSummary", "invalidFileSizeMessageDetail", "invalidFileTypeMessageSummary", "invalidFileTypeMessageDetail", "invalidFileLimitMessageDetail", "invalidFileLimitMessageSummary", "style", "styleClass", "previewWidth", "chooseLabel", "uploadLabel", "cancelLabel", "chooseIcon", "uploadIcon", "cancelIcon", "showUploadButton", "showCancelButton", "mode", "headers", "customUpload", "fileLimit", "uploadStyleClass", "cancelStyleClass", "removeStyleClass", "chooseStyleClass", "files"], outputs: ["onBeforeUpload", "onSend", "onUpload", "onError", "onClear", "onRemove", "onSelect", "onProgress", "uploadHandler", "onImageError", "onRemoveUploadedFile"] }, { kind: "component", type: i11.ProgressBar, selector: "p-progressBar", inputs: ["value", "showValue", "styleClass", "style", "unit", "mode", "color"] }, { kind: "component", type: i12.RadioButton, selector: "p-radioButton", inputs: ["value", "formControlName", "name", "disabled", "label", "variant", "tabindex", "inputId", "ariaLabelledBy", "ariaLabel", "style", "styleClass", "labelStyleClass", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i14.Dropdown, selector: "p-dropdown", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "autoShowPanelOnPrintableCharacterKeyDown", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }], encapsulation: i0.ViewEncapsulation.None });
3320
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DocumentUploadComponent, isStandalone: false, selector: "lib-document-upload", inputs: { contextId: "contextId" }, outputs: { onFormValidationChange: "onFormValidationChange", onUploadSuccess: "onUploadSuccess" }, viewQueries: [{ propertyName: "fileUploader", first: true, predicate: ["fileUploader"], descendants: true }], ngImport: i0, template: "<div class=\"document-upload-container\">\r\n <!-- Assignment Section -->\r\n <div class=\"assignment-section\">\r\n <h4>Assign to Applicant(s) or Application <span class=\"text-red-500\">*</span> </h4>\r\n <div class=\"radio-group\">\r\n <div class=\"radio-item\">\r\n <p-radioButton \r\n name=\"assignmentType\" \r\n value=\"Applicant\" \r\n [(ngModel)]=\"selectedAssignmentType\"\r\n (onClick)=\"onAssignmentTypeChange()\"\r\n [inputId]=\"'applicant'\"\r\n ></p-radioButton>\r\n <label [for]=\"'applicant'\" class=\"radio-label\">Applicant(s) </label>\r\n </div>\r\n <div class=\"radio-item\">\r\n <p-radioButton \r\n name=\"assignmentType\" \r\n value=\"Application\" \r\n [(ngModel)]=\"selectedAssignmentType\"\r\n (onClick)=\"onAssignmentTypeChange()\"\r\n [inputId]=\"'application'\"\r\n ></p-radioButton>\r\n <label [for]=\"'application'\" class=\"radio-label\">Application</label>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Applicant Selection (only shown when Applicant is selected) -->\r\n <div class=\"applicant-section\" *ngIf=\"selectedAssignmentType === 'Applicant'\">\r\n <h4>Select Applicant(s) <span class=\"text-red-500\">*</span></h4>\r\n <div class=\"grid\">\r\n <div \r\n *ngFor=\"let applicant of filteredApplicantList\" \r\n class=\"applicant-item col-12 md:col-6\"\r\n >\r\n <p-radioButton \r\n name=\"selectedApplicant\"\r\n [value]=\"applicant._id\"\r\n [(ngModel)]=\"selectedApplicant\"\r\n [inputId]=\"'applicant-' + applicant._id\"\r\n (onClick)=\"onApplicantSelectionChange()\"\r\n ></p-radioButton>\r\n <label [for]=\"'applicant-' + applicant._id\" class=\"applicant-label\">\r\n {{ applicant.name }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Category Selection -->\r\n <div class=\"category-section\">\r\n <h4>Category <span class=\"text-red-500\">*</span></h4>\r\n <p-dropdown\r\n [options]=\"categoryOptions\"\r\n [(ngModel)]=\"selectedCategory\"\r\n placeholder=\"Select Category type\"\r\n optionLabel=\"label\"\r\n optionValue=\"_id\"\r\n (onChange)=\"onCategoryChange()\"\r\n [disabled]=\"!categoryOptions.length\"\r\n class=\"w-full\"\r\n ></p-dropdown>\r\n </div>\r\n\r\n <!-- Document Type Selection -->\r\n <div class=\"document-type-section\">\r\n <h4>Document Type <span class=\"text-red-500\">*</span></h4>\r\n <p-dropdown\r\n [options]=\"documentTypeOptions\"\r\n [(ngModel)]=\"selectedDocumentType\"\r\n placeholder=\"Select Document type\"\r\n optionLabel=\"label\"\r\n optionValue=\"_id\"\r\n (onChange)=\"onDocumentTypeChange()\"\r\n [disabled]=\"!documentTypeOptions.length || !selectedCategory\"\r\n class=\"w-full\"\r\n ></p-dropdown>\r\n </div>\r\n\r\n <!-- File Upload Section -->\r\n <div class=\"file-upload-section\">\r\n <h4>Upload Documents <span class=\"text-red-500\">*</span></h4>\r\n <div class=\"grid\">\r\n <div class=\"col-12 md:col-12\">\r\n <p-fileUpload \r\n #fileUploader \r\n [multiple]=\"true\" \r\n auto=\"true\" \r\n accept=\"image/png,application/pdf\" \r\n maxFileSize=\"26214400\"\r\n (onSelect)=\"onSelectedFiles($event)\"\r\n >\r\n <ng-template pTemplate=\"header\" let-chooseCallback=\"chooseCallback\" let-clearCallback=\"clearCallback\">\r\n <div class=\"docHeader p-2 flex flex-wrap justify-content-between align-items-center flex-1 gap-2\">\r\n <div class=\"flex gap-2\">\r\n <p-button \r\n (onClick)=\"choose($event, chooseCallback)\" \r\n icon=\"pi pi-images\" \r\n [rounded]=\"true\"\r\n [outlined]=\"true\" \r\n />\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-template pTemplate=\"content\" let-removeFileCallback=\"removeFileCallback\"\r\n let-removeUploadedFileCallback=\"removeUploadedFileCallback\">\r\n <div class=\"col-12 md:col-12 p-0\">\r\n <div class=\"col-12 md:col-12 p-0\" *ngIf=\"uploadedFiles.length > 0\">\r\n <div *ngFor=\"let uploadedFile of uploadedFiles; let i = index\"\r\n class=\"m-0 flex flex-column align-items-center gap-1 mt-3\">\r\n <div class=\"col-12 md:col-12 p-0 flex documentInfo\">\r\n <div class=\"documentImage\">\r\n <img src=\"../../../../assets/images/document.png\" [alt]=\"uploadedFile.file.name\" width=\"45\" height=\"50\"\r\n class=\"object-contain\" />\r\n </div>\r\n <div class=\"flex w-full flex-column mt-2 ml-2\">\r\n <div class=\"flex justify-content-between\">\r\n <div style=\"font-weight: bold;font-size: 14px\">\r\n {{ uploadedFile.file.name }}\r\n </div>\r\n <i class=\"pi pi-times cursor-pointer\" (click)=\"handleDocumentRemove(uploadedFile.file,i)\"></i>\r\n </div>\r\n <div class=\"flex justify-content-between mt-1\">\r\n <div style=\"color: #676B89; font-size: 12px; color: green;\" class=\"pi pi-verified\"> \r\n {{ uploadedFile.formattedSize }}\r\n </div>\r\n <div class=\"white-space-nowrap\" style=\"color: #0F8BFD; font-family: 14px;\"> \r\n {{ uploadedFile.progress }} % \r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"col-12 md:col-12 p-0\">\r\n <p-progressBar \r\n [value]=\"uploadedFile.progress ?? 0\" \r\n [showValue]=\"false\" \r\n styleClass=\"h-1/2rem md:ml-auto relative\"\r\n [ngClass]=\"{ 'exceeded-progress-bar': (uploadedFile.progress ?? 0) > 100 }\"\r\n >\r\n </p-progressBar>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-template pTemplate=\"empty\" let-chooseCallback=\"chooseCallback\">\r\n <div *ngIf=\"!uploadedFiles.length\" class=\"flex align-items-center justify-content-center flex-column\"\r\n (click)=\"triggerFileUpload()\">\r\n <i class=\"pi pi-cloud-upload border-2 border-circle p-5 text-8xl text-400 border-400\"></i>\r\n <p class=\"mt-4 mb-0\">Drag and drop files here to upload.</p>\r\n </div>\r\n </ng-template>\r\n <ng-template pTemplate=\"file\"> </ng-template>\r\n </p-fileUpload>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [".flex{display:flex}.items-center{align-items:center}.justify-center{justify-content:center}.flex-col{flex-direction:column}.text-muted-color{color:#6c757d}.p-fileupload-buttonbar{padding:0}.p-fileupload-content{background-color:#0f8bfd1a}.p-fileupload .p-fileupload-content{padding:1rem}.docHeader .p-button-icon{padding:.5rem}.document-upload-container{padding:1rem;max-height:90vh}.assignment-section,.applicant-section,.category-section,.document-type-section,.file-upload-section{margin-bottom:1.5rem}.assignment-section h4,.applicant-section h4,.category-section h4,.document-type-section h4,.file-upload-section h4{margin:0 0 .75rem;font-size:1rem;font-weight:600;color:#212529}.radio-group{display:flex;gap:.75rem}.radio-item{display:flex;align-items:center;gap:.5rem;cursor:pointer;transition:all .2s ease}.radio-item:has(.p-radiobutton-box.p-highlight) .radio-label{color:#0f8bfd;font-weight:600}.radio-label{font-size:.9rem;color:#495057;cursor:pointer;-webkit-user-select:none;user-select:none;transition:color .2s ease}::ng-deep .p-dropdown{width:100%}::ng-deep .p-dropdown .p-dropdown-label{font-size:.9rem;color:#495057}::ng-deep .p-dropdown .p-dropdown-trigger{color:#6c757d}::ng-deep .p-dropdown:not(.p-disabled):hover{border-color:#0f8bfd}::ng-deep .p-dropdown:not(.p-disabled).p-focus{border-color:#0f8bfd;box-shadow:0 0 0 2px #0f8bfd33}::ng-deep .p-radiobutton .p-radiobutton-box{border-color:#ced4da;border-radius:4px;width:18px;height:18px}::ng-deep .p-radiobutton .p-radiobutton-box:hover{border-color:#0f8bfd}::ng-deep .p-radiobutton .p-radiobutton-box.p-highlight{border-color:#0f8bfd;background-color:transparent}::ng-deep .p-radiobutton .p-radiobutton-icon{background-color:#0f8bfd;width:8px;height:8px;border-radius:2px}.applicant-section .grid{margin:0;padding:0}.applicant-section .applicant-item{display:flex;align-items:center;gap:.75rem;border-radius:.5rem;background-color:#fff;transition:all .2s ease;cursor:pointer;margin-bottom:.75rem}.applicant-section .applicant-item:has(.p-radiobutton-box.p-highlight) .applicant-label{color:#0f8bfd;font-weight:600}.applicant-section .applicant-label{font-size:.95rem;color:#495057;cursor:pointer;-webkit-user-select:none;user-select:none;flex:1;font-weight:500;margin:0;transition:color .2s ease}@media (max-width: 768px){.applicant-section .applicant-item{margin-bottom:.5rem;padding:.75rem;min-height:50px}.applicant-section .applicant-label{font-size:.9rem}.document-upload-container{padding:.75rem}.assignment-section,.applicant-section,.category-section,.document-type-section,.file-upload-section{margin-bottom:1rem}}.category-section .p-dropdown,.document-type-section .p-dropdown{width:100%!important;min-width:100%!important}.category-section .p-dropdown-panel,.document-type-section .p-dropdown-panel{width:100%!important}:host ::ng-deep .p-dropdown{width:100%!important}:host ::ng-deep .p-dropdown-panel{width:100%!important}.applicant-list{display:none}\n"], dependencies: [{ kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: i4.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "style", "styleClass", "badgeClass", "ariaLabel", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: i10.FileUpload, selector: "p-fileUpload", inputs: ["name", "url", "method", "multiple", "accept", "disabled", "auto", "withCredentials", "maxFileSize", "invalidFileSizeMessageSummary", "invalidFileSizeMessageDetail", "invalidFileTypeMessageSummary", "invalidFileTypeMessageDetail", "invalidFileLimitMessageDetail", "invalidFileLimitMessageSummary", "style", "styleClass", "previewWidth", "chooseLabel", "uploadLabel", "cancelLabel", "chooseIcon", "uploadIcon", "cancelIcon", "showUploadButton", "showCancelButton", "mode", "headers", "customUpload", "fileLimit", "uploadStyleClass", "cancelStyleClass", "removeStyleClass", "chooseStyleClass", "files"], outputs: ["onBeforeUpload", "onSend", "onUpload", "onError", "onClear", "onRemove", "onSelect", "onProgress", "uploadHandler", "onImageError", "onRemoveUploadedFile"] }, { kind: "component", type: i11.ProgressBar, selector: "p-progressBar", inputs: ["value", "showValue", "styleClass", "style", "unit", "mode", "color"] }, { kind: "component", type: i12.RadioButton, selector: "p-radioButton", inputs: ["value", "formControlName", "name", "disabled", "label", "variant", "tabindex", "inputId", "ariaLabelledBy", "ariaLabel", "style", "styleClass", "labelStyleClass", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i14.Dropdown, selector: "p-dropdown", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "autoShowPanelOnPrintableCharacterKeyDown", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }], encapsulation: i0.ViewEncapsulation.None });
3292
3321
  }
3293
3322
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentUploadComponent, decorators: [{
3294
3323
  type: Component,
3295
- args: [{ selector: 'lib-document-upload', standalone: false, encapsulation: ViewEncapsulation.None, template: "<div class=\"document-upload-container\">\r\n <!-- Assignment Section -->\r\n <div class=\"assignment-section\">\r\n <h4>Assign to Applicant(s) or Application</h4>\r\n <div class=\"radio-group\">\r\n <div class=\"radio-item\">\r\n <p-radioButton \r\n name=\"assignmentType\" \r\n value=\"Applicant\" \r\n [(ngModel)]=\"selectedAssignmentType\"\r\n (onClick)=\"onAssignmentTypeChange()\"\r\n [inputId]=\"'applicant'\"\r\n ></p-radioButton>\r\n <label [for]=\"'applicant'\" class=\"radio-label\">Applicant(s)</label>\r\n </div>\r\n <div class=\"radio-item\">\r\n <p-radioButton \r\n name=\"assignmentType\" \r\n value=\"Application\" \r\n [(ngModel)]=\"selectedAssignmentType\"\r\n (onClick)=\"onAssignmentTypeChange()\"\r\n [inputId]=\"'application'\"\r\n ></p-radioButton>\r\n <label [for]=\"'application'\" class=\"radio-label\">Application</label>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Applicant Selection (only shown when Applicant is selected) -->\r\n <div class=\"applicant-section\" *ngIf=\"selectedAssignmentType === 'Applicant'\">\r\n <h4>Select Applicant(s)</h4>\r\n <div class=\"grid\">\r\n <div \r\n *ngFor=\"let applicant of filteredApplicantList\" \r\n class=\"applicant-item col-12 md:col-6\"\r\n >\r\n <p-radioButton \r\n name=\"selectedApplicant\"\r\n [value]=\"applicant._id\"\r\n [(ngModel)]=\"selectedApplicant\"\r\n [inputId]=\"'applicant-' + applicant._id\"\r\n (onClick)=\"onApplicantSelectionChange()\"\r\n ></p-radioButton>\r\n <label [for]=\"'applicant-' + applicant._id\" class=\"applicant-label\">\r\n {{ applicant.name }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Category Selection -->\r\n <div class=\"category-section\">\r\n <h4>Category</h4>\r\n <p-dropdown\r\n [options]=\"categoryOptions\"\r\n [(ngModel)]=\"selectedCategory\"\r\n placeholder=\"Select Category type\"\r\n optionLabel=\"label\"\r\n optionValue=\"_id\"\r\n (onChange)=\"onCategoryChange()\"\r\n [disabled]=\"!categoryOptions.length\"\r\n class=\"w-full\"\r\n ></p-dropdown>\r\n </div>\r\n\r\n <!-- Document Type Selection -->\r\n <div class=\"document-type-section\">\r\n <h4>Document Type</h4>\r\n <p-dropdown\r\n [options]=\"documentTypeOptions\"\r\n [(ngModel)]=\"selectedDocumentType\"\r\n placeholder=\"Select Document type\"\r\n optionLabel=\"label\"\r\n optionValue=\"_id\"\r\n (onChange)=\"onDocumentTypeChange()\"\r\n [disabled]=\"!documentTypeOptions.length || !selectedCategory\"\r\n class=\"w-full\"\r\n ></p-dropdown>\r\n </div>\r\n\r\n <!-- File Upload Section -->\r\n <div class=\"file-upload-section\">\r\n <h4>Upload Documents</h4>\r\n <div class=\"grid\">\r\n <div class=\"col-12 md:col-12\">\r\n <p-fileUpload \r\n #fileUploader \r\n [multiple]=\"true\" \r\n auto=\"true\" \r\n accept=\"image/png,application/pdf\" \r\n maxFileSize=\"26214400\"\r\n (onSelect)=\"onSelectedFiles($event)\"\r\n >\r\n <ng-template pTemplate=\"header\" let-chooseCallback=\"chooseCallback\" let-clearCallback=\"clearCallback\">\r\n <div class=\"docHeader p-2 flex flex-wrap justify-content-between align-items-center flex-1 gap-2\">\r\n <div class=\"flex gap-2\">\r\n <p-button \r\n (onClick)=\"choose($event, chooseCallback)\" \r\n icon=\"pi pi-images\" \r\n [rounded]=\"true\"\r\n [outlined]=\"true\" \r\n />\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-template pTemplate=\"content\" let-removeFileCallback=\"removeFileCallback\"\r\n let-removeUploadedFileCallback=\"removeUploadedFileCallback\">\r\n <div class=\"col-12 md:col-12 p-0\">\r\n <div class=\"col-12 md:col-12 p-0\" *ngIf=\"uploadedFiles.length > 0\">\r\n <div *ngFor=\"let uploadedFile of uploadedFiles; let i = index\"\r\n class=\"m-0 flex flex-column align-items-center gap-1 mt-3\">\r\n <div class=\"col-12 md:col-12 p-0 flex documentInfo\">\r\n <div class=\"documentImage\">\r\n <img src=\"../../../../assets/images/document.png\" [alt]=\"uploadedFile.file.name\" width=\"45\" height=\"50\"\r\n class=\"object-contain\" />\r\n </div>\r\n <div class=\"flex w-full flex-column mt-2 ml-2\">\r\n <div class=\"flex justify-content-between\">\r\n <div style=\"font-weight: bold;font-size: 14px\">\r\n {{ uploadedFile.file.name }}\r\n </div>\r\n <i class=\"pi pi-times cursor-pointer\" (click)=\"handleDocumentRemove(uploadedFile.file,i)\"></i>\r\n </div>\r\n <div class=\"flex justify-content-between mt-1\">\r\n <div style=\"color: #676B89; font-size: 12px; color: green;\" class=\"pi pi-verified\"> \r\n {{ uploadedFile.formattedSize }}\r\n </div>\r\n <div class=\"white-space-nowrap\" style=\"color: #0F8BFD; font-family: 14px;\"> \r\n {{ uploadedFile.progress }} % \r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"col-12 md:col-12 p-0\">\r\n <p-progressBar \r\n [value]=\"uploadedFile.progress\" \r\n [showValue]=\"false\" \r\n styleClass=\"h-1/2rem md:ml-auto relative\"\r\n [ngClass]=\"{ 'exceeded-progress-bar': uploadedFile.progress && uploadedFile.progress > 100 }\"\r\n >\r\n </p-progressBar>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-template pTemplate=\"empty\" let-chooseCallback=\"chooseCallback\">\r\n <div *ngIf=\"!uploadedFiles.length\" class=\"flex align-items-center justify-content-center flex-column\"\r\n (click)=\"triggerFileUpload()\">\r\n <i class=\"pi pi-cloud-upload border-2 border-circle p-5 text-8xl text-400 border-400\"></i>\r\n <p class=\"mt-4 mb-0\">Drag and drop files here to upload.</p>\r\n </div>\r\n </ng-template>\r\n <ng-template pTemplate=\"file\"> </ng-template>\r\n </p-fileUpload>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [".flex{display:flex}.items-center{align-items:center}.justify-center{justify-content:center}.flex-col{flex-direction:column}.text-muted-color{color:#6c757d}.p-fileupload-buttonbar{padding:0}.p-fileupload-content{background-color:#0f8bfd1a}.p-fileupload .p-fileupload-content{padding:1rem}.docHeader .p-button-icon{padding:.5rem}.document-upload-container{padding:1rem;max-height:90vh}.assignment-section,.applicant-section,.category-section,.document-type-section,.file-upload-section{margin-bottom:1.5rem}.assignment-section h4,.applicant-section h4,.category-section h4,.document-type-section h4,.file-upload-section h4{margin:0 0 .75rem;font-size:1rem;font-weight:600;color:#212529}.radio-group{display:flex;gap:.75rem}.radio-item{display:flex;align-items:center;gap:.5rem;cursor:pointer;transition:all .2s ease}.radio-item:has(.p-radiobutton-box.p-highlight) .radio-label{color:#0f8bfd;font-weight:600}.radio-label{font-size:.9rem;color:#495057;cursor:pointer;-webkit-user-select:none;user-select:none;transition:color .2s ease}::ng-deep .p-dropdown{width:100%}::ng-deep .p-dropdown .p-dropdown-label{font-size:.9rem;color:#495057}::ng-deep .p-dropdown .p-dropdown-trigger{color:#6c757d}::ng-deep .p-dropdown:not(.p-disabled):hover{border-color:#0f8bfd}::ng-deep .p-dropdown:not(.p-disabled).p-focus{border-color:#0f8bfd;box-shadow:0 0 0 2px #0f8bfd33}::ng-deep .p-radiobutton .p-radiobutton-box{border-color:#ced4da;border-radius:4px;width:18px;height:18px}::ng-deep .p-radiobutton .p-radiobutton-box:hover{border-color:#0f8bfd}::ng-deep .p-radiobutton .p-radiobutton-box.p-highlight{border-color:#0f8bfd;background-color:transparent}::ng-deep .p-radiobutton .p-radiobutton-icon{background-color:#0f8bfd;width:8px;height:8px;border-radius:2px}.applicant-section .grid{margin:0;padding:0}.applicant-section .applicant-item{display:flex;align-items:center;gap:.75rem;border-radius:.5rem;background-color:#fff;transition:all .2s ease;cursor:pointer;margin-bottom:.75rem}.applicant-section .applicant-item:has(.p-radiobutton-box.p-highlight) .applicant-label{color:#0f8bfd;font-weight:600}.applicant-section .applicant-label{font-size:.95rem;color:#495057;cursor:pointer;-webkit-user-select:none;user-select:none;flex:1;font-weight:500;margin:0;transition:color .2s ease}@media (max-width: 768px){.applicant-section .applicant-item{margin-bottom:.5rem;padding:.75rem;min-height:50px}.applicant-section .applicant-label{font-size:.9rem}.document-upload-container{padding:.75rem}.assignment-section,.applicant-section,.category-section,.document-type-section,.file-upload-section{margin-bottom:1rem}}.category-section .p-dropdown,.document-type-section .p-dropdown{width:100%!important;min-width:100%!important}.category-section .p-dropdown-panel,.document-type-section .p-dropdown-panel{width:100%!important}:host ::ng-deep .p-dropdown{width:100%!important}:host ::ng-deep .p-dropdown-panel{width:100%!important}.applicant-list{display:none}\n"] }]
3324
+ args: [{ selector: 'lib-document-upload', standalone: false, encapsulation: ViewEncapsulation.None, template: "<div class=\"document-upload-container\">\r\n <!-- Assignment Section -->\r\n <div class=\"assignment-section\">\r\n <h4>Assign to Applicant(s) or Application <span class=\"text-red-500\">*</span> </h4>\r\n <div class=\"radio-group\">\r\n <div class=\"radio-item\">\r\n <p-radioButton \r\n name=\"assignmentType\" \r\n value=\"Applicant\" \r\n [(ngModel)]=\"selectedAssignmentType\"\r\n (onClick)=\"onAssignmentTypeChange()\"\r\n [inputId]=\"'applicant'\"\r\n ></p-radioButton>\r\n <label [for]=\"'applicant'\" class=\"radio-label\">Applicant(s) </label>\r\n </div>\r\n <div class=\"radio-item\">\r\n <p-radioButton \r\n name=\"assignmentType\" \r\n value=\"Application\" \r\n [(ngModel)]=\"selectedAssignmentType\"\r\n (onClick)=\"onAssignmentTypeChange()\"\r\n [inputId]=\"'application'\"\r\n ></p-radioButton>\r\n <label [for]=\"'application'\" class=\"radio-label\">Application</label>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Applicant Selection (only shown when Applicant is selected) -->\r\n <div class=\"applicant-section\" *ngIf=\"selectedAssignmentType === 'Applicant'\">\r\n <h4>Select Applicant(s) <span class=\"text-red-500\">*</span></h4>\r\n <div class=\"grid\">\r\n <div \r\n *ngFor=\"let applicant of filteredApplicantList\" \r\n class=\"applicant-item col-12 md:col-6\"\r\n >\r\n <p-radioButton \r\n name=\"selectedApplicant\"\r\n [value]=\"applicant._id\"\r\n [(ngModel)]=\"selectedApplicant\"\r\n [inputId]=\"'applicant-' + applicant._id\"\r\n (onClick)=\"onApplicantSelectionChange()\"\r\n ></p-radioButton>\r\n <label [for]=\"'applicant-' + applicant._id\" class=\"applicant-label\">\r\n {{ applicant.name }}\r\n </label>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Category Selection -->\r\n <div class=\"category-section\">\r\n <h4>Category <span class=\"text-red-500\">*</span></h4>\r\n <p-dropdown\r\n [options]=\"categoryOptions\"\r\n [(ngModel)]=\"selectedCategory\"\r\n placeholder=\"Select Category type\"\r\n optionLabel=\"label\"\r\n optionValue=\"_id\"\r\n (onChange)=\"onCategoryChange()\"\r\n [disabled]=\"!categoryOptions.length\"\r\n class=\"w-full\"\r\n ></p-dropdown>\r\n </div>\r\n\r\n <!-- Document Type Selection -->\r\n <div class=\"document-type-section\">\r\n <h4>Document Type <span class=\"text-red-500\">*</span></h4>\r\n <p-dropdown\r\n [options]=\"documentTypeOptions\"\r\n [(ngModel)]=\"selectedDocumentType\"\r\n placeholder=\"Select Document type\"\r\n optionLabel=\"label\"\r\n optionValue=\"_id\"\r\n (onChange)=\"onDocumentTypeChange()\"\r\n [disabled]=\"!documentTypeOptions.length || !selectedCategory\"\r\n class=\"w-full\"\r\n ></p-dropdown>\r\n </div>\r\n\r\n <!-- File Upload Section -->\r\n <div class=\"file-upload-section\">\r\n <h4>Upload Documents <span class=\"text-red-500\">*</span></h4>\r\n <div class=\"grid\">\r\n <div class=\"col-12 md:col-12\">\r\n <p-fileUpload \r\n #fileUploader \r\n [multiple]=\"true\" \r\n auto=\"true\" \r\n accept=\"image/png,application/pdf\" \r\n maxFileSize=\"26214400\"\r\n (onSelect)=\"onSelectedFiles($event)\"\r\n >\r\n <ng-template pTemplate=\"header\" let-chooseCallback=\"chooseCallback\" let-clearCallback=\"clearCallback\">\r\n <div class=\"docHeader p-2 flex flex-wrap justify-content-between align-items-center flex-1 gap-2\">\r\n <div class=\"flex gap-2\">\r\n <p-button \r\n (onClick)=\"choose($event, chooseCallback)\" \r\n icon=\"pi pi-images\" \r\n [rounded]=\"true\"\r\n [outlined]=\"true\" \r\n />\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-template pTemplate=\"content\" let-removeFileCallback=\"removeFileCallback\"\r\n let-removeUploadedFileCallback=\"removeUploadedFileCallback\">\r\n <div class=\"col-12 md:col-12 p-0\">\r\n <div class=\"col-12 md:col-12 p-0\" *ngIf=\"uploadedFiles.length > 0\">\r\n <div *ngFor=\"let uploadedFile of uploadedFiles; let i = index\"\r\n class=\"m-0 flex flex-column align-items-center gap-1 mt-3\">\r\n <div class=\"col-12 md:col-12 p-0 flex documentInfo\">\r\n <div class=\"documentImage\">\r\n <img src=\"../../../../assets/images/document.png\" [alt]=\"uploadedFile.file.name\" width=\"45\" height=\"50\"\r\n class=\"object-contain\" />\r\n </div>\r\n <div class=\"flex w-full flex-column mt-2 ml-2\">\r\n <div class=\"flex justify-content-between\">\r\n <div style=\"font-weight: bold;font-size: 14px\">\r\n {{ uploadedFile.file.name }}\r\n </div>\r\n <i class=\"pi pi-times cursor-pointer\" (click)=\"handleDocumentRemove(uploadedFile.file,i)\"></i>\r\n </div>\r\n <div class=\"flex justify-content-between mt-1\">\r\n <div style=\"color: #676B89; font-size: 12px; color: green;\" class=\"pi pi-verified\"> \r\n {{ uploadedFile.formattedSize }}\r\n </div>\r\n <div class=\"white-space-nowrap\" style=\"color: #0F8BFD; font-family: 14px;\"> \r\n {{ uploadedFile.progress }} % \r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"col-12 md:col-12 p-0\">\r\n <p-progressBar \r\n [value]=\"uploadedFile.progress ?? 0\" \r\n [showValue]=\"false\" \r\n styleClass=\"h-1/2rem md:ml-auto relative\"\r\n [ngClass]=\"{ 'exceeded-progress-bar': (uploadedFile.progress ?? 0) > 100 }\"\r\n >\r\n </p-progressBar>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n <ng-template pTemplate=\"empty\" let-chooseCallback=\"chooseCallback\">\r\n <div *ngIf=\"!uploadedFiles.length\" class=\"flex align-items-center justify-content-center flex-column\"\r\n (click)=\"triggerFileUpload()\">\r\n <i class=\"pi pi-cloud-upload border-2 border-circle p-5 text-8xl text-400 border-400\"></i>\r\n <p class=\"mt-4 mb-0\">Drag and drop files here to upload.</p>\r\n </div>\r\n </ng-template>\r\n <ng-template pTemplate=\"file\"> </ng-template>\r\n </p-fileUpload>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [".flex{display:flex}.items-center{align-items:center}.justify-center{justify-content:center}.flex-col{flex-direction:column}.text-muted-color{color:#6c757d}.p-fileupload-buttonbar{padding:0}.p-fileupload-content{background-color:#0f8bfd1a}.p-fileupload .p-fileupload-content{padding:1rem}.docHeader .p-button-icon{padding:.5rem}.document-upload-container{padding:1rem;max-height:90vh}.assignment-section,.applicant-section,.category-section,.document-type-section,.file-upload-section{margin-bottom:1.5rem}.assignment-section h4,.applicant-section h4,.category-section h4,.document-type-section h4,.file-upload-section h4{margin:0 0 .75rem;font-size:1rem;font-weight:600;color:#212529}.radio-group{display:flex;gap:.75rem}.radio-item{display:flex;align-items:center;gap:.5rem;cursor:pointer;transition:all .2s ease}.radio-item:has(.p-radiobutton-box.p-highlight) .radio-label{color:#0f8bfd;font-weight:600}.radio-label{font-size:.9rem;color:#495057;cursor:pointer;-webkit-user-select:none;user-select:none;transition:color .2s ease}::ng-deep .p-dropdown{width:100%}::ng-deep .p-dropdown .p-dropdown-label{font-size:.9rem;color:#495057}::ng-deep .p-dropdown .p-dropdown-trigger{color:#6c757d}::ng-deep .p-dropdown:not(.p-disabled):hover{border-color:#0f8bfd}::ng-deep .p-dropdown:not(.p-disabled).p-focus{border-color:#0f8bfd;box-shadow:0 0 0 2px #0f8bfd33}::ng-deep .p-radiobutton .p-radiobutton-box{border-color:#ced4da;border-radius:4px;width:18px;height:18px}::ng-deep .p-radiobutton .p-radiobutton-box:hover{border-color:#0f8bfd}::ng-deep .p-radiobutton .p-radiobutton-box.p-highlight{border-color:#0f8bfd;background-color:transparent}::ng-deep .p-radiobutton .p-radiobutton-icon{background-color:#0f8bfd;width:8px;height:8px;border-radius:2px}.applicant-section .grid{margin:0;padding:0}.applicant-section .applicant-item{display:flex;align-items:center;gap:.75rem;border-radius:.5rem;background-color:#fff;transition:all .2s ease;cursor:pointer;margin-bottom:.75rem}.applicant-section .applicant-item:has(.p-radiobutton-box.p-highlight) .applicant-label{color:#0f8bfd;font-weight:600}.applicant-section .applicant-label{font-size:.95rem;color:#495057;cursor:pointer;-webkit-user-select:none;user-select:none;flex:1;font-weight:500;margin:0;transition:color .2s ease}@media (max-width: 768px){.applicant-section .applicant-item{margin-bottom:.5rem;padding:.75rem;min-height:50px}.applicant-section .applicant-label{font-size:.9rem}.document-upload-container{padding:.75rem}.assignment-section,.applicant-section,.category-section,.document-type-section,.file-upload-section{margin-bottom:1rem}}.category-section .p-dropdown,.document-type-section .p-dropdown{width:100%!important;min-width:100%!important}.category-section .p-dropdown-panel,.document-type-section .p-dropdown-panel{width:100%!important}:host ::ng-deep .p-dropdown{width:100%!important}:host ::ng-deep .p-dropdown-panel{width:100%!important}.applicant-list{display:none}\n"] }]
3296
3325
  }], ctorParameters: () => [{ type: DocumentUploadService }, { type: DocumentService }, { type: i3.PrimeNGConfig }, { type: FileFormatService }, { type: i3.MessageService }, { type: i0.ChangeDetectorRef }, { type: DocumentUploadBusinessService }, { type: DocumentUploadFormService }, { type: DocumentUploadDataService }], propDecorators: { contextId: [{
3297
3326
  type: Input
3298
3327
  }], fileUploader: [{
@@ -3305,7 +3334,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
3305
3334
  }] } });
3306
3335
 
3307
3336
  class SidebarComponent {
3308
- visible = false;
3337
+ injector;
3338
+ // Add setter to log visible changes
3339
+ set visible(value) {
3340
+ this._visible = value;
3341
+ }
3342
+ get visible() {
3343
+ return this._visible;
3344
+ }
3345
+ _visible = false;
3346
+ // Flag to prevent double event emission
3347
+ isProgrammaticallyClosing = false;
3309
3348
  position = 'right';
3310
3349
  width = SHARED.WIDTH;
3311
3350
  title = SHARED.EMPTY;
@@ -3313,8 +3352,8 @@ class SidebarComponent {
3313
3352
  modal = true;
3314
3353
  dismissible = true;
3315
3354
  closeOnEscape = true;
3316
- baseZIndex = SHARED.BASEZINDEX;
3317
- autoZIndex = true;
3355
+ baseZIndex = 10000;
3356
+ autoZIndex = false;
3318
3357
  styleClass = SHARED.EMPTY;
3319
3358
  appendTo = 'body';
3320
3359
  blockScroll = true;
@@ -3324,36 +3363,77 @@ class SidebarComponent {
3324
3363
  saveButtonDisabled = false;
3325
3364
  successMessage = SHARED.SUCCESS_MESSAGE;
3326
3365
  errorMessage = SHARED.EMPTY;
3366
+ hasUnsavedChanges = false;
3327
3367
  visibleChange = new EventEmitter();
3328
3368
  onShow = new EventEmitter();
3329
3369
  onHide = new EventEmitter();
3330
3370
  onSave = new EventEmitter();
3371
+ onDiscardChanges = new EventEmitter();
3331
3372
  showSuccessMessage = false;
3332
3373
  showErrorMessage = false;
3374
+ destroy$ = new Subject();
3375
+ confirmationService;
3376
+ constructor(injector) {
3377
+ this.injector = injector;
3378
+ // Inject ConfirmationService using injector to avoid circular dependency issues
3379
+ this.confirmationService = this.injector.get(ConfirmationService);
3380
+ }
3381
+ /**
3382
+ * Handles the onHide event from PrimeNG sidebar
3383
+ */
3384
+ onSidebarHide() {
3385
+ // Only emit onHide if we're not programmatically closing
3386
+ if (!this.isProgrammaticallyClosing) {
3387
+ this.onHide.emit();
3388
+ }
3389
+ }
3390
+ /**
3391
+ * Handles the visibleChange event from PrimeNG sidebar
3392
+ */
3393
+ onVisibleChange(value) {
3394
+ // Only emit visibleChange if we're not programmatically closing
3395
+ if (!this.isProgrammaticallyClosing) {
3396
+ this.visibleChange.emit(value);
3397
+ }
3398
+ }
3333
3399
  /**
3334
3400
  * Opens the sidebar
3335
3401
  */
3336
3402
  open() {
3337
- this.visible = true;
3403
+ this._visible = true;
3338
3404
  this.clearMessages();
3339
- this.visibleChange.emit(this.visible);
3405
+ this.visibleChange.emit(this._visible);
3340
3406
  this.onShow.emit();
3341
3407
  }
3342
3408
  /**
3343
3409
  * Closes the sidebar
3344
3410
  */
3345
3411
  close() {
3346
- this.visible = false;
3412
+ this.isProgrammaticallyClosing = true;
3413
+ this._visible = false;
3414
+ this.clearMessages();
3415
+ this.visibleChange.emit(this._visible);
3416
+ this.onHide.emit();
3417
+ this.isProgrammaticallyClosing = false;
3418
+ }
3419
+ /**
3420
+ * Closes the sidebar and discards all changes
3421
+ */
3422
+ closeAndDiscardChanges() {
3423
+ this.isProgrammaticallyClosing = true;
3424
+ this._visible = false;
3347
3425
  this.clearMessages();
3348
- this.visibleChange.emit(this.visible);
3426
+ this.visibleChange.emit(this._visible);
3427
+ this.onDiscardChanges.emit();
3349
3428
  this.onHide.emit();
3429
+ this.isProgrammaticallyClosing = false;
3350
3430
  }
3351
3431
  /**
3352
3432
  * Toggles the sidebar visibility
3353
3433
  */
3354
3434
  toggle() {
3355
- this.visible = !this.visible;
3356
- if (this.visible) {
3435
+ this._visible = !this._visible;
3436
+ if (this._visible) {
3357
3437
  this.clearMessages();
3358
3438
  this.onShow.emit();
3359
3439
  }
@@ -3361,22 +3441,88 @@ class SidebarComponent {
3361
3441
  this.clearMessages();
3362
3442
  this.onHide.emit();
3363
3443
  }
3364
- this.visibleChange.emit(this.visible);
3444
+ this.visibleChange.emit(this._visible);
3365
3445
  }
3366
3446
  /**
3367
- * Handles the close button click
3447
+ * Handles the close button click with unsaved changes check
3368
3448
  */
3369
3449
  onCloseClick() {
3370
- this.close();
3450
+ if (this.hasUnsavedChanges) {
3451
+ this.showUnsavedChangesConfirmation();
3452
+ }
3453
+ else {
3454
+ this.close();
3455
+ }
3371
3456
  }
3372
3457
  /**
3373
- * Handles the mask click (when dismissible is true)
3458
+ * Handles the mask click (when dismissible is true) with unsaved changes check
3374
3459
  */
3375
3460
  onMaskClick() {
3376
3461
  if (this.dismissible) {
3462
+ if (this.hasUnsavedChanges) {
3463
+ this.showUnsavedChangesConfirmation();
3464
+ }
3465
+ else {
3466
+ this.close();
3467
+ }
3468
+ }
3469
+ }
3470
+ /**
3471
+ * Handles the escape key press with unsaved changes check
3472
+ */
3473
+ onEscapeKey(event) {
3474
+ if (this._visible && this.closeOnEscape) {
3475
+ if (this.hasUnsavedChanges) {
3476
+ event.preventDefault();
3477
+ this.showUnsavedChangesConfirmation();
3478
+ }
3479
+ else {
3480
+ this.close();
3481
+ }
3482
+ }
3483
+ }
3484
+ /**
3485
+ * Handles backdrop click with unsaved changes check
3486
+ */
3487
+ onBackdropClick(event) {
3488
+ if (this.hasUnsavedChanges) {
3489
+ this.showUnsavedChangesConfirmation();
3490
+ }
3491
+ else {
3492
+ this.close();
3493
+ }
3494
+ }
3495
+ /**
3496
+ * Handles close button click with unsaved changes check
3497
+ */
3498
+ onCloseButtonClick() {
3499
+ if (this.hasUnsavedChanges) {
3500
+ this.showUnsavedChangesConfirmation();
3501
+ }
3502
+ else {
3377
3503
  this.close();
3378
3504
  }
3379
3505
  }
3506
+ /**
3507
+ * Shows confirmation dialog for unsaved changes
3508
+ */
3509
+ showUnsavedChangesConfirmation() {
3510
+ this.confirmationService.confirm({
3511
+ message: SHARED.UNSAVED_CHANGES_MESSAGE,
3512
+ header: SHARED.UNSAVED_CHANGES_HEADER,
3513
+ icon: SHARED.UNSAVED_CHANGES_ICON,
3514
+ acceptLabel: SHARED.REMOVE,
3515
+ rejectLabel: SHARED.CANCEL,
3516
+ acceptIcon: SHARED.ACCEPT_ICON,
3517
+ rejectIcon: SHARED.REJECT_ICON,
3518
+ acceptButtonStyleClass: SHARED.ACCEPT_BUTTON_STYLE_CLASS,
3519
+ rejectButtonStyleClass: SHARED.REJECT_BUTTON_STYLE_CLASS,
3520
+ accept: () => {
3521
+ this.closeAndDiscardChanges();
3522
+ },
3523
+ reject: () => { }
3524
+ });
3525
+ }
3380
3526
  /**
3381
3527
  * Shows success message and closes sidebar after delay
3382
3528
  */
@@ -3402,13 +3548,28 @@ class SidebarComponent {
3402
3548
  this.showSuccessMessage = false;
3403
3549
  this.showErrorMessage = false;
3404
3550
  }
3405
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3406
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: SidebarComponent, isStandalone: false, selector: "lib-sidebar", inputs: { visible: "visible", position: "position", width: "width", title: "title", showCloseButton: "showCloseButton", modal: "modal", dismissible: "dismissible", closeOnEscape: "closeOnEscape", baseZIndex: "baseZIndex", autoZIndex: "autoZIndex", styleClass: "styleClass", appendTo: "appendTo", blockScroll: "blockScroll", closeIcon: "closeIcon", showSaveButton: "showSaveButton", saveButtonText: "saveButtonText", saveButtonDisabled: "saveButtonDisabled", successMessage: "successMessage", errorMessage: "errorMessage" }, outputs: { visibleChange: "visibleChange", onShow: "onShow", onHide: "onHide", onSave: "onSave" }, ngImport: i0, template: "<p-sidebar \r\n [(visible)]=\"visible\"\r\n [position]=\"position\"\r\n [style]=\"{width: width}\"\r\n [modal]=\"modal\"\r\n [dismissible]=\"dismissible\"\r\n [closeOnEscape]=\"closeOnEscape\"\r\n [baseZIndex]=\"baseZIndex\"\r\n [autoZIndex]=\"autoZIndex\"\r\n [styleClass]=\"styleClass\"\r\n [appendTo]=\"appendTo\"\r\n [blockScroll]=\"blockScroll\"\r\n (visibleChange)=\"visibleChange.emit($event)\"\r\n (onShow)=\"onShow.emit()\"\r\n (onHide)=\"onHide.emit()\"\r\n \r\n>\r\n <ng-template pTemplate=\"header\" *ngIf=\"title || showCloseButton || showSaveButton\">\r\n <div class=\"sidebar-header\">\r\n <h3 *ngIf=\"title\" class=\"sidebar-title\">{{ title }}</h3>\r\n <div class=\"header-content\">\r\n <ng-content select=\"[header]\"></ng-content>\r\n \r\n <p-messages \r\n *ngIf=\"showSuccessMessage\"\r\n severity=\"success\"\r\n [closable]=\"false\"\r\n [style]=\"{'margin-bottom': '0.5rem'}\"\r\n class=\"ml-3\"\r\n >\r\n <ng-template pTemplate=\"message\">\r\n <span>{{ successMessage }}</span>\r\n </ng-template>\r\n </p-messages>\r\n <p-messages \r\n *ngIf=\"showErrorMessage\"\r\n severity=\"error\"\r\n [closable]=\"false\"\r\n [style]=\"{'margin-bottom': '0.5rem'}\"\r\n class=\"ml-3\"\r\n >\r\n <ng-template pTemplate=\"message\">\r\n <span>{{ errorMessage }}</span>\r\n </ng-template>\r\n </p-messages>\r\n\r\n <div class=\"header-actions mr-3\">\r\n \r\n <button \r\n *ngIf=\"showSaveButton\"\r\n pButton \r\n type=\"button\" \r\n [label]=\"saveButtonText\"\r\n [disabled]=\"saveButtonDisabled\"\r\n class=\"p-button-primary\"\r\n (click)=\"onSave.emit()\"\r\n ></button>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template pTemplate=\"content\">\r\n <div class=\"sidebar-content\">\r\n <ng-content></ng-content>\r\n </div>\r\n </ng-template>\r\n</p-sidebar>\r\n", styles: [":host{display:block}.sidebar-header{display:flex;justify-content:space-between;align-items:center;padding:0;width:100%}.sidebar-title{margin:0;font-size:1.25rem;font-weight:600;color:#212529;flex:1}.header-content{display:flex;align-items:center;gap:.5rem;justify-content:space-between;width:100%}.header-actions{display:flex;align-items:center;gap:.5rem;margin-left:auto;margin-right:0}.close-button{background:none;border:none;color:#6c757d;cursor:pointer;padding:.5rem;border-radius:.375rem;transition:all .2s ease;display:flex;align-items:center;justify-content:center;min-width:2rem;min-height:2rem;margin-right:.5rem}.close-button:hover{background-color:#e9ecef;color:#495057}.close-button:focus{outline:none;box-shadow:0 0 0 3px #0f8bfd4d}.close-button i{font-size:1rem}.sidebar-content{height:100%;overflow-y:auto;padding:0}::ng-deep .p-sidebar .p-sidebar-header{border-bottom:1px solid #e9ecef;margin-bottom:1rem;background-color:#f8f9fa}::ng-deep .p-sidebar .p-sidebar-content{padding:0 1.5rem 1.5rem;height:calc(100% - 80px);overflow-y:auto}::ng-deep .p-sidebar.p-sidebar-right .p-sidebar-content{padding-left:1.5rem;padding-right:1.5rem}::ng-deep .p-sidebar.p-sidebar-left .p-sidebar-content{padding-left:1.5rem;padding-right:1.5rem}@media (max-width: 768px){::ng-deep .p-sidebar{width:100%!important;max-width:100%!important}::ng-deep .p-sidebar .p-sidebar-header{padding:1rem 1rem 0}::ng-deep .p-sidebar .p-sidebar-content{padding:0 1rem 1rem}}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i4.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "component", type: i4$1.Sidebar, selector: "p-sidebar", inputs: ["appendTo", "blockScroll", "style", "styleClass", "ariaCloseLabel", "autoZIndex", "baseZIndex", "modal", "dismissible", "showCloseIcon", "closeOnEscape", "transitionOptions", "visible", "position", "fullScreen"], outputs: ["onShow", "onHide", "visibleChange"] }, { kind: "component", type: i5.Messages, selector: "p-messages", inputs: ["value", "closable", "style", "styleClass", "enableService", "key", "escape", "severity", "showTransitionOptions", "hideTransitionOptions"], outputs: ["valueChange", "onClose"] }] });
3551
+ /**
3552
+ * Checks if there are unsaved changes
3553
+ * @returns True if there are unsaved changes, false otherwise
3554
+ */
3555
+ checkForUnsavedChanges() {
3556
+ return this.hasUnsavedChanges;
3557
+ }
3558
+ /**
3559
+ * Lifecycle hook that is called when component is destroyed.
3560
+ * Cleans up subscriptions.
3561
+ */
3562
+ ngOnDestroy() {
3563
+ this.destroy$.next();
3564
+ this.destroy$.complete();
3565
+ }
3566
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SidebarComponent, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component });
3567
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: SidebarComponent, isStandalone: false, selector: "lib-sidebar", inputs: { visible: "visible", position: "position", width: "width", title: "title", showCloseButton: "showCloseButton", modal: "modal", dismissible: "dismissible", closeOnEscape: "closeOnEscape", baseZIndex: "baseZIndex", autoZIndex: "autoZIndex", styleClass: "styleClass", appendTo: "appendTo", blockScroll: "blockScroll", closeIcon: "closeIcon", showSaveButton: "showSaveButton", saveButtonText: "saveButtonText", saveButtonDisabled: "saveButtonDisabled", successMessage: "successMessage", errorMessage: "errorMessage", hasUnsavedChanges: "hasUnsavedChanges" }, outputs: { visibleChange: "visibleChange", onShow: "onShow", onHide: "onHide", onSave: "onSave", onDiscardChanges: "onDiscardChanges" }, host: { listeners: { "document:keydown.escape": "onEscapeKey($event)" } }, ngImport: i0, template: "<!-- Custom backdrop for better control over outside clicks -->\n<div \n *ngIf=\"visible\" \n class=\"custom-sidebar-backdrop\" \n (click)=\"onBackdropClick($event)\"\n></div>\n\n<p-sidebar \n [(visible)]=\"visible\"\n [position]=\"position\"\n [style]=\"{width: width}\"\n [modal]=\"false\"\n [dismissible]=\"false\"\n [closeOnEscape]=\"false\"\n [showCloseIcon]=\"false\"\n [baseZIndex]=\"baseZIndex\"\n [autoZIndex]=\"autoZIndex\"\n [styleClass]=\"styleClass\"\n [appendTo]=\"appendTo\"\n [blockScroll]=\"blockScroll\"\n (visibleChange)=\"onVisibleChange($event)\"\n (onShow)=\"onShow.emit()\"\n (onHide)=\"onSidebarHide()\"\n>\n <ng-template pTemplate=\"header\" *ngIf=\"title || showCloseButton || showSaveButton\">\n <div class=\"sidebar-header\">\n <h3 *ngIf=\"title\" class=\"sidebar-title\">{{ title }}</h3>\n <div class=\"header-content\">\n <ng-content select=\"[header]\"></ng-content>\n \n <p-messages \n *ngIf=\"showSuccessMessage\"\n severity=\"success\"\n [closable]=\"false\"\n [style]=\"{'margin-bottom': '0.5rem'}\"\n class=\"ml-3\"\n >\n <ng-template pTemplate=\"message\">\n <span>{{ successMessage }}</span>\n </ng-template>\n </p-messages>\n <p-messages \n *ngIf=\"showErrorMessage\"\n severity=\"error\"\n [closable]=\"false\"\n [style]=\"{'margin-bottom': '0.5rem'}\"\n class=\"ml-3\"\n >\n <ng-template pTemplate=\"message\">\n <span>{{ errorMessage }}</span>\n </ng-template>\n </p-messages>\n\n <div class=\"header-actions mr-3\">\n <button \n *ngIf=\"showSaveButton\"\n pButton \n type=\"button\" \n [label]=\"saveButtonText\"\n [disabled]=\"saveButtonDisabled\"\n class=\"p-button-primary\"\n (click)=\"onSave.emit()\"\n ></button>\n\n <button \n *ngIf=\"showCloseButton\"\n pButton \n type=\"button\" \n icon=\"pi pi-times\"\n class=\"p-button-text p-button-rounded\"\n (click)=\"onCloseButtonClick()\"\n ></button>\n \n </div>\n </div>\n </div>\n </ng-template>\n\n <ng-template pTemplate=\"content\">\n <div class=\"sidebar-content\">\n <ng-content></ng-content>\n </div>\n </ng-template>\n</p-sidebar>\n", styles: [":host{display:block}.sidebar-header{display:flex;justify-content:space-between;align-items:center;padding:0;width:100%}.sidebar-title{margin:0;font-size:1.25rem;font-weight:600;color:#212529;flex:1}.header-content{display:flex;align-items:center;gap:.5rem;justify-content:space-between;width:100%}.header-actions{display:flex;align-items:center;gap:.5rem;margin-left:auto;margin-right:0}.close-button{background:none;border:none;color:#6c757d;cursor:pointer;padding:.5rem;border-radius:.375rem;transition:all .2s ease;display:flex;align-items:center;justify-content:center;min-width:2rem;min-height:2rem;margin-right:.5rem}.close-button:hover{background-color:#e9ecef;color:#495057}.close-button:focus{outline:none;box-shadow:0 0 0 3px #0f8bfd4d}.close-button i{font-size:1rem}.sidebar-content{height:100%;overflow-y:auto;padding:0}.custom-sidebar-backdrop{position:fixed;top:0;left:0;width:100vw;height:100vh;background-color:#0006;z-index:9999;cursor:pointer}::ng-deep .p-sidebar{z-index:10000!important}::ng-deep .p-confirm-dialog{z-index:10001!important}::ng-deep .p-dialog-mask{z-index:10000!important}::ng-deep .p-confirm-dialog-mask{z-index:10000!important}.header-actions .p-button-text.p-button-rounded{width:2rem;height:2rem;border-radius:50%}.header-actions .p-button-text.p-button-rounded:hover{background-color:#0000001a}::ng-deep .p-sidebar .p-sidebar-header{border-bottom:1px solid #e9ecef;margin-bottom:1rem;background-color:#f8f9fa}::ng-deep .p-sidebar .p-sidebar-content{padding:0 1.5rem 1.5rem;height:calc(100% - 80px);overflow-y:auto}::ng-deep .p-sidebar.p-sidebar-right .p-sidebar-content{padding-left:1.5rem;padding-right:1.5rem}::ng-deep .p-sidebar.p-sidebar-left .p-sidebar-content{padding-left:1.5rem;padding-right:1.5rem}@media (max-width: 768px){::ng-deep .p-sidebar{width:100%!important;max-width:100%!important}::ng-deep .p-sidebar .p-sidebar-header{padding:1rem 1rem 0}::ng-deep .p-sidebar .p-sidebar-content{padding:0 1rem 1rem}}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i4.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "component", type: i4$1.Sidebar, selector: "p-sidebar", inputs: ["appendTo", "blockScroll", "style", "styleClass", "ariaCloseLabel", "autoZIndex", "baseZIndex", "modal", "dismissible", "showCloseIcon", "closeOnEscape", "transitionOptions", "visible", "position", "fullScreen"], outputs: ["onShow", "onHide", "visibleChange"] }, { kind: "component", type: i5.Messages, selector: "p-messages", inputs: ["value", "closable", "style", "styleClass", "enableService", "key", "escape", "severity", "showTransitionOptions", "hideTransitionOptions"], outputs: ["valueChange", "onClose"] }] });
3407
3568
  }
3408
3569
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SidebarComponent, decorators: [{
3409
3570
  type: Component,
3410
- args: [{ selector: 'lib-sidebar', standalone: false, template: "<p-sidebar \r\n [(visible)]=\"visible\"\r\n [position]=\"position\"\r\n [style]=\"{width: width}\"\r\n [modal]=\"modal\"\r\n [dismissible]=\"dismissible\"\r\n [closeOnEscape]=\"closeOnEscape\"\r\n [baseZIndex]=\"baseZIndex\"\r\n [autoZIndex]=\"autoZIndex\"\r\n [styleClass]=\"styleClass\"\r\n [appendTo]=\"appendTo\"\r\n [blockScroll]=\"blockScroll\"\r\n (visibleChange)=\"visibleChange.emit($event)\"\r\n (onShow)=\"onShow.emit()\"\r\n (onHide)=\"onHide.emit()\"\r\n \r\n>\r\n <ng-template pTemplate=\"header\" *ngIf=\"title || showCloseButton || showSaveButton\">\r\n <div class=\"sidebar-header\">\r\n <h3 *ngIf=\"title\" class=\"sidebar-title\">{{ title }}</h3>\r\n <div class=\"header-content\">\r\n <ng-content select=\"[header]\"></ng-content>\r\n \r\n <p-messages \r\n *ngIf=\"showSuccessMessage\"\r\n severity=\"success\"\r\n [closable]=\"false\"\r\n [style]=\"{'margin-bottom': '0.5rem'}\"\r\n class=\"ml-3\"\r\n >\r\n <ng-template pTemplate=\"message\">\r\n <span>{{ successMessage }}</span>\r\n </ng-template>\r\n </p-messages>\r\n <p-messages \r\n *ngIf=\"showErrorMessage\"\r\n severity=\"error\"\r\n [closable]=\"false\"\r\n [style]=\"{'margin-bottom': '0.5rem'}\"\r\n class=\"ml-3\"\r\n >\r\n <ng-template pTemplate=\"message\">\r\n <span>{{ errorMessage }}</span>\r\n </ng-template>\r\n </p-messages>\r\n\r\n <div class=\"header-actions mr-3\">\r\n \r\n <button \r\n *ngIf=\"showSaveButton\"\r\n pButton \r\n type=\"button\" \r\n [label]=\"saveButtonText\"\r\n [disabled]=\"saveButtonDisabled\"\r\n class=\"p-button-primary\"\r\n (click)=\"onSave.emit()\"\r\n ></button>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <ng-template pTemplate=\"content\">\r\n <div class=\"sidebar-content\">\r\n <ng-content></ng-content>\r\n </div>\r\n </ng-template>\r\n</p-sidebar>\r\n", styles: [":host{display:block}.sidebar-header{display:flex;justify-content:space-between;align-items:center;padding:0;width:100%}.sidebar-title{margin:0;font-size:1.25rem;font-weight:600;color:#212529;flex:1}.header-content{display:flex;align-items:center;gap:.5rem;justify-content:space-between;width:100%}.header-actions{display:flex;align-items:center;gap:.5rem;margin-left:auto;margin-right:0}.close-button{background:none;border:none;color:#6c757d;cursor:pointer;padding:.5rem;border-radius:.375rem;transition:all .2s ease;display:flex;align-items:center;justify-content:center;min-width:2rem;min-height:2rem;margin-right:.5rem}.close-button:hover{background-color:#e9ecef;color:#495057}.close-button:focus{outline:none;box-shadow:0 0 0 3px #0f8bfd4d}.close-button i{font-size:1rem}.sidebar-content{height:100%;overflow-y:auto;padding:0}::ng-deep .p-sidebar .p-sidebar-header{border-bottom:1px solid #e9ecef;margin-bottom:1rem;background-color:#f8f9fa}::ng-deep .p-sidebar .p-sidebar-content{padding:0 1.5rem 1.5rem;height:calc(100% - 80px);overflow-y:auto}::ng-deep .p-sidebar.p-sidebar-right .p-sidebar-content{padding-left:1.5rem;padding-right:1.5rem}::ng-deep .p-sidebar.p-sidebar-left .p-sidebar-content{padding-left:1.5rem;padding-right:1.5rem}@media (max-width: 768px){::ng-deep .p-sidebar{width:100%!important;max-width:100%!important}::ng-deep .p-sidebar .p-sidebar-header{padding:1rem 1rem 0}::ng-deep .p-sidebar .p-sidebar-content{padding:0 1rem 1rem}}\n"] }]
3411
- }], propDecorators: { visible: [{
3571
+ args: [{ selector: 'lib-sidebar', standalone: false, template: "<!-- Custom backdrop for better control over outside clicks -->\n<div \n *ngIf=\"visible\" \n class=\"custom-sidebar-backdrop\" \n (click)=\"onBackdropClick($event)\"\n></div>\n\n<p-sidebar \n [(visible)]=\"visible\"\n [position]=\"position\"\n [style]=\"{width: width}\"\n [modal]=\"false\"\n [dismissible]=\"false\"\n [closeOnEscape]=\"false\"\n [showCloseIcon]=\"false\"\n [baseZIndex]=\"baseZIndex\"\n [autoZIndex]=\"autoZIndex\"\n [styleClass]=\"styleClass\"\n [appendTo]=\"appendTo\"\n [blockScroll]=\"blockScroll\"\n (visibleChange)=\"onVisibleChange($event)\"\n (onShow)=\"onShow.emit()\"\n (onHide)=\"onSidebarHide()\"\n>\n <ng-template pTemplate=\"header\" *ngIf=\"title || showCloseButton || showSaveButton\">\n <div class=\"sidebar-header\">\n <h3 *ngIf=\"title\" class=\"sidebar-title\">{{ title }}</h3>\n <div class=\"header-content\">\n <ng-content select=\"[header]\"></ng-content>\n \n <p-messages \n *ngIf=\"showSuccessMessage\"\n severity=\"success\"\n [closable]=\"false\"\n [style]=\"{'margin-bottom': '0.5rem'}\"\n class=\"ml-3\"\n >\n <ng-template pTemplate=\"message\">\n <span>{{ successMessage }}</span>\n </ng-template>\n </p-messages>\n <p-messages \n *ngIf=\"showErrorMessage\"\n severity=\"error\"\n [closable]=\"false\"\n [style]=\"{'margin-bottom': '0.5rem'}\"\n class=\"ml-3\"\n >\n <ng-template pTemplate=\"message\">\n <span>{{ errorMessage }}</span>\n </ng-template>\n </p-messages>\n\n <div class=\"header-actions mr-3\">\n <button \n *ngIf=\"showSaveButton\"\n pButton \n type=\"button\" \n [label]=\"saveButtonText\"\n [disabled]=\"saveButtonDisabled\"\n class=\"p-button-primary\"\n (click)=\"onSave.emit()\"\n ></button>\n\n <button \n *ngIf=\"showCloseButton\"\n pButton \n type=\"button\" \n icon=\"pi pi-times\"\n class=\"p-button-text p-button-rounded\"\n (click)=\"onCloseButtonClick()\"\n ></button>\n \n </div>\n </div>\n </div>\n </ng-template>\n\n <ng-template pTemplate=\"content\">\n <div class=\"sidebar-content\">\n <ng-content></ng-content>\n </div>\n </ng-template>\n</p-sidebar>\n", styles: [":host{display:block}.sidebar-header{display:flex;justify-content:space-between;align-items:center;padding:0;width:100%}.sidebar-title{margin:0;font-size:1.25rem;font-weight:600;color:#212529;flex:1}.header-content{display:flex;align-items:center;gap:.5rem;justify-content:space-between;width:100%}.header-actions{display:flex;align-items:center;gap:.5rem;margin-left:auto;margin-right:0}.close-button{background:none;border:none;color:#6c757d;cursor:pointer;padding:.5rem;border-radius:.375rem;transition:all .2s ease;display:flex;align-items:center;justify-content:center;min-width:2rem;min-height:2rem;margin-right:.5rem}.close-button:hover{background-color:#e9ecef;color:#495057}.close-button:focus{outline:none;box-shadow:0 0 0 3px #0f8bfd4d}.close-button i{font-size:1rem}.sidebar-content{height:100%;overflow-y:auto;padding:0}.custom-sidebar-backdrop{position:fixed;top:0;left:0;width:100vw;height:100vh;background-color:#0006;z-index:9999;cursor:pointer}::ng-deep .p-sidebar{z-index:10000!important}::ng-deep .p-confirm-dialog{z-index:10001!important}::ng-deep .p-dialog-mask{z-index:10000!important}::ng-deep .p-confirm-dialog-mask{z-index:10000!important}.header-actions .p-button-text.p-button-rounded{width:2rem;height:2rem;border-radius:50%}.header-actions .p-button-text.p-button-rounded:hover{background-color:#0000001a}::ng-deep .p-sidebar .p-sidebar-header{border-bottom:1px solid #e9ecef;margin-bottom:1rem;background-color:#f8f9fa}::ng-deep .p-sidebar .p-sidebar-content{padding:0 1.5rem 1.5rem;height:calc(100% - 80px);overflow-y:auto}::ng-deep .p-sidebar.p-sidebar-right .p-sidebar-content{padding-left:1.5rem;padding-right:1.5rem}::ng-deep .p-sidebar.p-sidebar-left .p-sidebar-content{padding-left:1.5rem;padding-right:1.5rem}@media (max-width: 768px){::ng-deep .p-sidebar{width:100%!important;max-width:100%!important}::ng-deep .p-sidebar .p-sidebar-header{padding:1rem 1rem 0}::ng-deep .p-sidebar .p-sidebar-content{padding:0 1rem 1rem}}\n"] }]
3572
+ }], ctorParameters: () => [{ type: i0.Injector }], propDecorators: { visible: [{
3412
3573
  type: Input
3413
3574
  }], position: [{
3414
3575
  type: Input
@@ -3446,6 +3607,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
3446
3607
  type: Input
3447
3608
  }], errorMessage: [{
3448
3609
  type: Input
3610
+ }], hasUnsavedChanges: [{
3611
+ type: Input
3449
3612
  }], visibleChange: [{
3450
3613
  type: Output
3451
3614
  }], onShow: [{
@@ -3454,6 +3617,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
3454
3617
  type: Output
3455
3618
  }], onSave: [{
3456
3619
  type: Output
3620
+ }], onDiscardChanges: [{
3621
+ type: Output
3622
+ }], onEscapeKey: [{
3623
+ type: HostListener,
3624
+ args: ['document:keydown.escape', ['$event']]
3457
3625
  }] } });
3458
3626
 
3459
3627
  class UserListService {
@@ -3899,11 +4067,11 @@ class DocumentSearchComponent {
3899
4067
  this.documentHelperService.clearSelectionState();
3900
4068
  }
3901
4069
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentSearchComponent, deps: [{ token: DocumentHelperService }], target: i0.ɵɵFactoryTarget.Component });
3902
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DocumentSearchComponent, isStandalone: false, selector: "document-search", inputs: { contextId: "contextId" }, outputs: { onActionClick: "onActionClick" }, ngImport: i0, template: "<div class=\"search-container\">\r\n <div class=\"search-input-wrapper\">\r\n <i class=\"pi pi-search search-icon\"></i>\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"searchTerm\"\r\n (ngModelChange)=\"onSearchInputChange($event)\"\r\n class=\"search-input\"\r\n placeholder=\"Search by document name, category, type, status or applicant name...\"\r\n [attr.aria-label]=\"'Search documents'\"\r\n />\r\n <button \r\n *ngIf=\"searchTerm\"\r\n type=\"button\"\r\n class=\"clear-button\"\r\n (click)=\"onClearSearch()\"\r\n [attr.aria-label]=\"'Clear search'\"\r\n >\r\n <i class=\"pi pi-times\"></i>\r\n </button>\r\n </div>\r\n\r\n <button \r\n type=\"button\"\r\n class=\"clear-all-filters-link\"\r\n (click)=\"onClearAllFilters()\"\r\n [attr.aria-label]=\"'Clear all'\"\r\n >\r\n Clear All\r\n <i class=\"pi pi-times\"></i>\r\n </button>\r\n\r\n <div class=\"filters-section\">\r\n <button \r\n type=\"button\"\r\n class=\"action-button\"\r\n (click)=\"onActionClick.emit()\"\r\n [attr.aria-label]=\"'Open actions menu'\"\r\n >\r\n Actions\r\n </button>\r\n </div>\r\n</div> ", styles: [".search-container{display:flex;align-items:center;gap:1rem;width:100%;justify-content:flex-start;padding:10px}.search-input-wrapper{position:relative;flex:1;display:flex;align-items:center;max-width:50%;min-width:300px}.clear-all-filters-link{background:none;border:none;color:#0f8bfd;cursor:pointer;padding:8px 12px;border-radius:4px;font-size:16px;font-weight:500;text-decoration:none!important;transition:background-color .2s ease,color .2s ease;white-space:nowrap;flex-shrink:0;display:flex;justify-content:center;align-items:center;gap:4px}.filters-section{display:flex;align-items:center;gap:1rem;flex-shrink:0;margin-left:auto}.search-icon{position:absolute;left:12px;color:#6c757d;z-index:1}.search-input{width:100%;padding:12px 40px;border:1px solid #dee2e6;border-radius:8px;font-size:14px;outline:none;transition:border-color .2s ease,box-shadow .2s ease}.search-input:focus{border-color:#0f8bfd;box-shadow:0 0 0 3px #0f8bfd1a}.search-input::placeholder{color:#6c757d}.clear-button{position:absolute;right:12px;background:none;border:none;color:#6c757d;cursor:pointer;padding:4px;border-radius:4px;transition:background-color .2s ease,color .2s ease}.clear-button:hover{background-color:#f8f9fa;color:#495057}.action-button{background-color:#0f8bfd;color:#fff;border:none;padding:12px 24px;border-radius:8px;font-size:14px;font-weight:500;cursor:pointer;transition:background-color .2s ease,transform .1s ease;white-space:nowrap}.action-button:hover{background-color:#0d7ae6;transform:translateY(-1px)}.action-button:active{transform:translateY(0)}.action-button:focus{outline:none;box-shadow:0 0 0 3px #0f8bfd4d}@media (max-width: 768px){.search-container{flex-direction:column;gap:.75rem}.search-input-wrapper{max-width:100%}.filters-section{width:100%;justify-content:center;gap:.5rem}.action-button{width:auto;justify-content:center}}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
4070
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DocumentSearchComponent, isStandalone: false, selector: "document-search", inputs: { contextId: "contextId" }, outputs: { onActionClick: "onActionClick" }, ngImport: i0, template: "<div class=\"search-container\">\r\n <div class=\"search-input-wrapper\">\r\n <i class=\"pi pi-search search-icon\"></i>\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"searchTerm\"\r\n (ngModelChange)=\"onSearchInputChange($event)\"\r\n class=\"search-input\"\r\n placeholder=\"Search by document name, category, type, status or applicant name...\"\r\n [attr.aria-label]=\"'Search documents'\"\r\n />\r\n <button \r\n *ngIf=\"searchTerm\"\r\n type=\"button\"\r\n class=\"clear-button\"\r\n (click)=\"onClearSearch()\"\r\n [attr.aria-label]=\"'Clear search'\"\r\n >\r\n <i class=\"pi pi-times\"></i>\r\n </button>\r\n </div>\r\n\r\n <button \r\n type=\"button\"\r\n class=\"clear-all-filters-link\"\r\n (click)=\"onClearAllFilters()\"\r\n [attr.aria-label]=\"'Clear all'\"\r\n >\r\n Clear All\r\n <i class=\"pi pi-times\"></i>\r\n </button>\r\n\r\n <div class=\"filters-section\">\r\n <button \r\n type=\"button\"\r\n class=\"action-button\"\r\n (click)=\"onActionClick.emit()\"\r\n [attr.aria-label]=\"'Open actions menu'\"\r\n >\r\n Upload Document\r\n </button>\r\n </div>\r\n</div> ", styles: [".search-container{display:flex;align-items:center;gap:1rem;width:100%;justify-content:flex-start;padding:10px}.search-input-wrapper{position:relative;flex:1;display:flex;align-items:center;max-width:50%;min-width:300px}.clear-all-filters-link{background:none;border:none;color:#0f8bfd;cursor:pointer;padding:8px 12px;border-radius:4px;font-size:16px;font-weight:500;text-decoration:none!important;transition:background-color .2s ease,color .2s ease;white-space:nowrap;flex-shrink:0;display:flex;justify-content:center;align-items:center;gap:4px}.filters-section{display:flex;align-items:center;gap:1rem;flex-shrink:0;margin-left:auto}.search-icon{position:absolute;left:12px;color:#6c757d;z-index:1}.search-input{width:100%;padding:12px 40px;border:1px solid #dee2e6;border-radius:8px;font-size:14px;outline:none;transition:border-color .2s ease,box-shadow .2s ease}.search-input:focus{border-color:#0f8bfd;box-shadow:0 0 0 3px #0f8bfd1a}.search-input::placeholder{color:#6c757d}.clear-button{position:absolute;right:12px;background:none;border:none;color:#6c757d;cursor:pointer;padding:4px;border-radius:4px;transition:background-color .2s ease,color .2s ease}.clear-button:hover{background-color:#f8f9fa;color:#495057}.action-button{background-color:#0f8bfd;color:#fff;border:none;padding:12px 24px;border-radius:8px;font-size:14px;font-weight:500;cursor:pointer;transition:background-color .2s ease,transform .1s ease;white-space:nowrap}.action-button:hover{background-color:#0d7ae6;transform:translateY(-1px)}.action-button:active{transform:translateY(0)}.action-button:focus{outline:none;box-shadow:0 0 0 3px #0f8bfd4d}@media (max-width: 768px){.search-container{flex-direction:column;gap:.75rem}.search-input-wrapper{max-width:100%}.filters-section{width:100%;justify-content:center;gap:.5rem}.action-button{width:auto;justify-content:center}}\n"], dependencies: [{ kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
3903
4071
  }
3904
4072
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentSearchComponent, decorators: [{
3905
4073
  type: Component,
3906
- args: [{ selector: 'document-search', standalone: false, template: "<div class=\"search-container\">\r\n <div class=\"search-input-wrapper\">\r\n <i class=\"pi pi-search search-icon\"></i>\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"searchTerm\"\r\n (ngModelChange)=\"onSearchInputChange($event)\"\r\n class=\"search-input\"\r\n placeholder=\"Search by document name, category, type, status or applicant name...\"\r\n [attr.aria-label]=\"'Search documents'\"\r\n />\r\n <button \r\n *ngIf=\"searchTerm\"\r\n type=\"button\"\r\n class=\"clear-button\"\r\n (click)=\"onClearSearch()\"\r\n [attr.aria-label]=\"'Clear search'\"\r\n >\r\n <i class=\"pi pi-times\"></i>\r\n </button>\r\n </div>\r\n\r\n <button \r\n type=\"button\"\r\n class=\"clear-all-filters-link\"\r\n (click)=\"onClearAllFilters()\"\r\n [attr.aria-label]=\"'Clear all'\"\r\n >\r\n Clear All\r\n <i class=\"pi pi-times\"></i>\r\n </button>\r\n\r\n <div class=\"filters-section\">\r\n <button \r\n type=\"button\"\r\n class=\"action-button\"\r\n (click)=\"onActionClick.emit()\"\r\n [attr.aria-label]=\"'Open actions menu'\"\r\n >\r\n Actions\r\n </button>\r\n </div>\r\n</div> ", styles: [".search-container{display:flex;align-items:center;gap:1rem;width:100%;justify-content:flex-start;padding:10px}.search-input-wrapper{position:relative;flex:1;display:flex;align-items:center;max-width:50%;min-width:300px}.clear-all-filters-link{background:none;border:none;color:#0f8bfd;cursor:pointer;padding:8px 12px;border-radius:4px;font-size:16px;font-weight:500;text-decoration:none!important;transition:background-color .2s ease,color .2s ease;white-space:nowrap;flex-shrink:0;display:flex;justify-content:center;align-items:center;gap:4px}.filters-section{display:flex;align-items:center;gap:1rem;flex-shrink:0;margin-left:auto}.search-icon{position:absolute;left:12px;color:#6c757d;z-index:1}.search-input{width:100%;padding:12px 40px;border:1px solid #dee2e6;border-radius:8px;font-size:14px;outline:none;transition:border-color .2s ease,box-shadow .2s ease}.search-input:focus{border-color:#0f8bfd;box-shadow:0 0 0 3px #0f8bfd1a}.search-input::placeholder{color:#6c757d}.clear-button{position:absolute;right:12px;background:none;border:none;color:#6c757d;cursor:pointer;padding:4px;border-radius:4px;transition:background-color .2s ease,color .2s ease}.clear-button:hover{background-color:#f8f9fa;color:#495057}.action-button{background-color:#0f8bfd;color:#fff;border:none;padding:12px 24px;border-radius:8px;font-size:14px;font-weight:500;cursor:pointer;transition:background-color .2s ease,transform .1s ease;white-space:nowrap}.action-button:hover{background-color:#0d7ae6;transform:translateY(-1px)}.action-button:active{transform:translateY(0)}.action-button:focus{outline:none;box-shadow:0 0 0 3px #0f8bfd4d}@media (max-width: 768px){.search-container{flex-direction:column;gap:.75rem}.search-input-wrapper{max-width:100%}.filters-section{width:100%;justify-content:center;gap:.5rem}.action-button{width:auto;justify-content:center}}\n"] }]
4074
+ args: [{ selector: 'document-search', standalone: false, template: "<div class=\"search-container\">\r\n <div class=\"search-input-wrapper\">\r\n <i class=\"pi pi-search search-icon\"></i>\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"searchTerm\"\r\n (ngModelChange)=\"onSearchInputChange($event)\"\r\n class=\"search-input\"\r\n placeholder=\"Search by document name, category, type, status or applicant name...\"\r\n [attr.aria-label]=\"'Search documents'\"\r\n />\r\n <button \r\n *ngIf=\"searchTerm\"\r\n type=\"button\"\r\n class=\"clear-button\"\r\n (click)=\"onClearSearch()\"\r\n [attr.aria-label]=\"'Clear search'\"\r\n >\r\n <i class=\"pi pi-times\"></i>\r\n </button>\r\n </div>\r\n\r\n <button \r\n type=\"button\"\r\n class=\"clear-all-filters-link\"\r\n (click)=\"onClearAllFilters()\"\r\n [attr.aria-label]=\"'Clear all'\"\r\n >\r\n Clear All\r\n <i class=\"pi pi-times\"></i>\r\n </button>\r\n\r\n <div class=\"filters-section\">\r\n <button \r\n type=\"button\"\r\n class=\"action-button\"\r\n (click)=\"onActionClick.emit()\"\r\n [attr.aria-label]=\"'Open actions menu'\"\r\n >\r\n Upload Document\r\n </button>\r\n </div>\r\n</div> ", styles: [".search-container{display:flex;align-items:center;gap:1rem;width:100%;justify-content:flex-start;padding:10px}.search-input-wrapper{position:relative;flex:1;display:flex;align-items:center;max-width:50%;min-width:300px}.clear-all-filters-link{background:none;border:none;color:#0f8bfd;cursor:pointer;padding:8px 12px;border-radius:4px;font-size:16px;font-weight:500;text-decoration:none!important;transition:background-color .2s ease,color .2s ease;white-space:nowrap;flex-shrink:0;display:flex;justify-content:center;align-items:center;gap:4px}.filters-section{display:flex;align-items:center;gap:1rem;flex-shrink:0;margin-left:auto}.search-icon{position:absolute;left:12px;color:#6c757d;z-index:1}.search-input{width:100%;padding:12px 40px;border:1px solid #dee2e6;border-radius:8px;font-size:14px;outline:none;transition:border-color .2s ease,box-shadow .2s ease}.search-input:focus{border-color:#0f8bfd;box-shadow:0 0 0 3px #0f8bfd1a}.search-input::placeholder{color:#6c757d}.clear-button{position:absolute;right:12px;background:none;border:none;color:#6c757d;cursor:pointer;padding:4px;border-radius:4px;transition:background-color .2s ease,color .2s ease}.clear-button:hover{background-color:#f8f9fa;color:#495057}.action-button{background-color:#0f8bfd;color:#fff;border:none;padding:12px 24px;border-radius:8px;font-size:14px;font-weight:500;cursor:pointer;transition:background-color .2s ease,transform .1s ease;white-space:nowrap}.action-button:hover{background-color:#0d7ae6;transform:translateY(-1px)}.action-button:active{transform:translateY(0)}.action-button:focus{outline:none;box-shadow:0 0 0 3px #0f8bfd4d}@media (max-width: 768px){.search-container{flex-direction:column;gap:.75rem}.search-input-wrapper{max-width:100%}.filters-section{width:100%;justify-content:center;gap:.5rem}.action-button{width:auto;justify-content:center}}\n"] }]
3907
4075
  }], ctorParameters: () => [{ type: DocumentHelperService }], propDecorators: { contextId: [{
3908
4076
  type: Input
3909
4077
  }], onActionClick: [{
@@ -3973,6 +4141,10 @@ class FolderContainerComponent {
3973
4141
  * Tracks whether the save button should be disabled
3974
4142
  */
3975
4143
  isSaveButtonDisabled = false;
4144
+ /**
4145
+ * Tracks whether there are unsaved changes in the document upload form
4146
+ */
4147
+ hasUnsavedChanges = false;
3976
4148
  constructor(documentQuery, documentHelperService) {
3977
4149
  this.documentQuery = documentQuery;
3978
4150
  this.documentHelperService = documentHelperService;
@@ -4002,18 +4174,36 @@ class FolderContainerComponent {
4002
4174
  */
4003
4175
  onFormValidationChange() {
4004
4176
  this.updateSaveButtonState();
4177
+ // Check if there are actual unsaved changes
4178
+ this.checkForUnsavedChanges();
4179
+ }
4180
+ /**
4181
+ * Checks if there are unsaved changes in the document upload form
4182
+ */
4183
+ checkForUnsavedChanges() {
4184
+ if (this.documentUploadComponent) {
4185
+ // Check if files are uploaded or form has changes
4186
+ const hasFiles = Boolean(this.documentUploadComponent.uploadedFiles && this.documentUploadComponent.uploadedFiles.length > 0);
4187
+ const hasFormChanges = Boolean((this.documentUploadComponent.selectedAssignmentType && this.documentUploadComponent.selectedAssignmentType !== SHARED.EMPTY) ||
4188
+ (this.documentUploadComponent.selectedApplicant && this.documentUploadComponent.selectedApplicant !== SHARED.EMPTY) ||
4189
+ (this.documentUploadComponent.selectedCategory && this.documentUploadComponent.selectedCategory !== SHARED.EMPTY) ||
4190
+ (this.documentUploadComponent.selectedDocumentType && this.documentUploadComponent.selectedDocumentType !== SHARED.EMPTY));
4191
+ this.hasUnsavedChanges = hasFiles || hasFormChanges;
4192
+ }
4005
4193
  }
4006
4194
  /**
4007
4195
  * Opens the document upload sidebar
4008
4196
  */
4009
4197
  openDocumentUploadSidebar() {
4010
4198
  this.isDocumentUploadSidebarOpen = true;
4199
+ this.hasUnsavedChanges = false; // Reset when opening
4011
4200
  }
4012
4201
  /**
4013
4202
  * Handles the document upload sidebar hide event
4014
4203
  */
4015
4204
  onDocumentUploadSidebarHide() {
4016
4205
  this.isDocumentUploadSidebarOpen = false;
4206
+ this.hasUnsavedChanges = false;
4017
4207
  if (this.documentUploadComponent) {
4018
4208
  this.documentUploadComponent.resetForm();
4019
4209
  }
@@ -4023,6 +4213,17 @@ class FolderContainerComponent {
4023
4213
  */
4024
4214
  onDocumentUploadSidebarClose() {
4025
4215
  this.isDocumentUploadSidebarOpen = false;
4216
+ this.hasUnsavedChanges = false;
4217
+ if (this.documentUploadComponent) {
4218
+ this.documentUploadComponent.resetForm();
4219
+ }
4220
+ }
4221
+ /**
4222
+ * Handles the document upload sidebar close with unsaved changes event
4223
+ */
4224
+ onDocumentUploadSidebarCloseWithUnsavedChanges() {
4225
+ this.isDocumentUploadSidebarOpen = false;
4226
+ this.hasUnsavedChanges = false;
4026
4227
  if (this.documentUploadComponent) {
4027
4228
  this.documentUploadComponent.resetForm();
4028
4229
  }
@@ -4041,6 +4242,7 @@ class FolderContainerComponent {
4041
4242
  */
4042
4243
  onDocumentUploadSuccess() {
4043
4244
  this.documentHelperService.refreshAllDataWithCurrentFilters(this.contextId);
4245
+ this.hasUnsavedChanges = false; // Reset after successful upload
4044
4246
  if (this.sidebarComponent) {
4045
4247
  this.sidebarComponent.showSuccess();
4046
4248
  }
@@ -4055,7 +4257,7 @@ class FolderContainerComponent {
4055
4257
  }
4056
4258
  }
4057
4259
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FolderContainerComponent, deps: [{ token: DocumentQuery }, { token: DocumentHelperService }], target: i0.ɵɵFactoryTarget.Component });
4058
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: FolderContainerComponent, isStandalone: false, selector: "lib-folder-container", inputs: { documentList: "documentList", folderList: "folderList", contextId: "contextId", userList: "userList", statusData: "statusData", categories: "categories" }, viewQueries: [{ propertyName: "documentUploadComponent", first: true, predicate: DocumentUploadComponent, descendants: true }, { propertyName: "sidebarComponent", first: true, predicate: SidebarComponent, descendants: true }], ngImport: i0, template: "\r\n<document-search [contextId]=\"contextId\" (onActionClick)=\"openDocumentUploadSidebar()\"></document-search>\r\n<div class=\"user-list-wrapper\" [@slideInOut]=\"userListAnimationState\">\r\n <lib-user-list [userList]=\"userList\" [categories]=\"categories\"></lib-user-list>\r\n</div>\r\n<lib-document-status [contextId]=\"contextId\" [statusData]=\"statusData\"></lib-document-status>\r\n\r\n<!-- Document Upload Sidebar -->\r\n<lib-sidebar\r\n [(visible)]=\"isDocumentUploadSidebarOpen\"\r\n position=\"right\"\r\n width=\"600px\"\r\n title=\"Upload Documents\"\r\n [showCloseButton]=\"true\"\r\n [showSaveButton]=\"true\"\r\n [saveButtonText]=\"'Save'\"\r\n [saveButtonDisabled]=\"isSaveButtonDisabled\"\r\n [successMessage]=\"'Document Saved Successfully'\"\r\n [modal]=\"true\"\r\n [dismissible]=\"true\"\r\n [closeOnEscape]=\"true\"\r\n [blockScroll]=\"true\"\r\n (onHide)=\"onDocumentUploadSidebarHide()\"\r\n (onSave)=\"onDocumentUploadSave()\"\r\n (onClose)=\"onDocumentUploadSidebarClose()\"\r\n>\r\n <lib-document-upload \r\n [contextId]=\"contextId\" \r\n (onFormValidationChange)=\"onFormValidationChange()\" \r\n (onUploadSuccess)=\"onDocumentUploadSuccess()\"\r\n (onUploadError)=\"onDocumentUploadError($event)\"\r\n ></lib-document-upload>\r\n</lib-sidebar>", styles: [".user-list-wrapper{overflow:hidden;margin-bottom:1rem}.user-list-wrapper ::ng-deep *{transition:opacity .2s ease-in-out}.user-list-wrapper.ng-animating{pointer-events:none}::ng-deep lib-user-list{display:block;width:100%}\n"], dependencies: [{ kind: "component", type: DocumentUploadComponent, selector: "lib-document-upload", inputs: ["contextId"], outputs: ["onFormValidationChange", "onUploadSuccess"] }, { kind: "component", type: UserListComponent, selector: "lib-user-list", inputs: ["userList", "categories"], outputs: ["userSelected"] }, { kind: "component", type: DocumentStatusComponent, selector: "lib-document-status", inputs: ["contextId", "statusData"] }, { kind: "component", type: DocumentSearchComponent, selector: "document-search", inputs: ["contextId"], outputs: ["onActionClick"] }, { kind: "component", type: SidebarComponent, selector: "lib-sidebar", inputs: ["visible", "position", "width", "title", "showCloseButton", "modal", "dismissible", "closeOnEscape", "baseZIndex", "autoZIndex", "styleClass", "appendTo", "blockScroll", "closeIcon", "showSaveButton", "saveButtonText", "saveButtonDisabled", "successMessage", "errorMessage"], outputs: ["visibleChange", "onShow", "onHide", "onSave"] }], animations: [
4260
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: FolderContainerComponent, isStandalone: false, selector: "lib-folder-container", inputs: { documentList: "documentList", folderList: "folderList", contextId: "contextId", userList: "userList", statusData: "statusData", categories: "categories" }, viewQueries: [{ propertyName: "documentUploadComponent", first: true, predicate: DocumentUploadComponent, descendants: true }, { propertyName: "sidebarComponent", first: true, predicate: SidebarComponent, descendants: true }], ngImport: i0, template: "\r\n<document-search [contextId]=\"contextId\" (onActionClick)=\"openDocumentUploadSidebar()\"></document-search>\r\n<div class=\"user-list-wrapper\" [@slideInOut]=\"userListAnimationState\">\r\n <lib-user-list [userList]=\"userList\" [categories]=\"categories\"></lib-user-list>\r\n</div>\r\n<lib-document-status [contextId]=\"contextId\" [statusData]=\"statusData\"></lib-document-status>\r\n\r\n<!-- Document Upload Sidebar -->\r\n<lib-sidebar\r\n [(visible)]=\"isDocumentUploadSidebarOpen\"\r\n position=\"right\"\r\n width=\"600px\"\r\n title=\"Upload Documents\"\r\n [showCloseButton]=\"true\"\r\n [showSaveButton]=\"true\"\r\n [saveButtonText]=\"'Save'\"\r\n [saveButtonDisabled]=\"isSaveButtonDisabled\"\r\n [successMessage]=\"'Document Saved Successfully'\"\r\n [hasUnsavedChanges]=\"hasUnsavedChanges\"\r\n (onHide)=\"onDocumentUploadSidebarHide()\"\r\n (onSave)=\"onDocumentUploadSave()\"\r\n (onDiscardChanges)=\"onDocumentUploadSidebarCloseWithUnsavedChanges()\"\r\n>\r\n <lib-document-upload \r\n [contextId]=\"contextId\" \r\n (onFormValidationChange)=\"onFormValidationChange()\" \r\n (onUploadSuccess)=\"onDocumentUploadSuccess()\"\r\n (onUploadError)=\"onDocumentUploadError($event)\"\r\n ></lib-document-upload>\r\n</lib-sidebar>", styles: [".user-list-wrapper{overflow:hidden;margin-bottom:1rem}.user-list-wrapper ::ng-deep *{transition:opacity .2s ease-in-out}.user-list-wrapper.ng-animating{pointer-events:none}::ng-deep lib-user-list{display:block;width:100%}\n"], dependencies: [{ kind: "component", type: DocumentUploadComponent, selector: "lib-document-upload", inputs: ["contextId"], outputs: ["onFormValidationChange", "onUploadSuccess"] }, { kind: "component", type: UserListComponent, selector: "lib-user-list", inputs: ["userList", "categories"], outputs: ["userSelected"] }, { kind: "component", type: DocumentStatusComponent, selector: "lib-document-status", inputs: ["contextId", "statusData"] }, { kind: "component", type: DocumentSearchComponent, selector: "document-search", inputs: ["contextId"], outputs: ["onActionClick"] }, { kind: "component", type: SidebarComponent, selector: "lib-sidebar", inputs: ["visible", "position", "width", "title", "showCloseButton", "modal", "dismissible", "closeOnEscape", "baseZIndex", "autoZIndex", "styleClass", "appendTo", "blockScroll", "closeIcon", "showSaveButton", "saveButtonText", "saveButtonDisabled", "successMessage", "errorMessage", "hasUnsavedChanges"], outputs: ["visibleChange", "onShow", "onHide", "onSave", "onDiscardChanges"] }], animations: [
4059
4261
  trigger('slideInOut', [
4060
4262
  state('visible', style({
4061
4263
  height: '*',
@@ -4109,7 +4311,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
4109
4311
  animate('300ms cubic-bezier(0.0, 0.0, 0.2, 1)')
4110
4312
  ])
4111
4313
  ])
4112
- ], template: "\r\n<document-search [contextId]=\"contextId\" (onActionClick)=\"openDocumentUploadSidebar()\"></document-search>\r\n<div class=\"user-list-wrapper\" [@slideInOut]=\"userListAnimationState\">\r\n <lib-user-list [userList]=\"userList\" [categories]=\"categories\"></lib-user-list>\r\n</div>\r\n<lib-document-status [contextId]=\"contextId\" [statusData]=\"statusData\"></lib-document-status>\r\n\r\n<!-- Document Upload Sidebar -->\r\n<lib-sidebar\r\n [(visible)]=\"isDocumentUploadSidebarOpen\"\r\n position=\"right\"\r\n width=\"600px\"\r\n title=\"Upload Documents\"\r\n [showCloseButton]=\"true\"\r\n [showSaveButton]=\"true\"\r\n [saveButtonText]=\"'Save'\"\r\n [saveButtonDisabled]=\"isSaveButtonDisabled\"\r\n [successMessage]=\"'Document Saved Successfully'\"\r\n [modal]=\"true\"\r\n [dismissible]=\"true\"\r\n [closeOnEscape]=\"true\"\r\n [blockScroll]=\"true\"\r\n (onHide)=\"onDocumentUploadSidebarHide()\"\r\n (onSave)=\"onDocumentUploadSave()\"\r\n (onClose)=\"onDocumentUploadSidebarClose()\"\r\n>\r\n <lib-document-upload \r\n [contextId]=\"contextId\" \r\n (onFormValidationChange)=\"onFormValidationChange()\" \r\n (onUploadSuccess)=\"onDocumentUploadSuccess()\"\r\n (onUploadError)=\"onDocumentUploadError($event)\"\r\n ></lib-document-upload>\r\n</lib-sidebar>", styles: [".user-list-wrapper{overflow:hidden;margin-bottom:1rem}.user-list-wrapper ::ng-deep *{transition:opacity .2s ease-in-out}.user-list-wrapper.ng-animating{pointer-events:none}::ng-deep lib-user-list{display:block;width:100%}\n"] }]
4314
+ ], template: "\r\n<document-search [contextId]=\"contextId\" (onActionClick)=\"openDocumentUploadSidebar()\"></document-search>\r\n<div class=\"user-list-wrapper\" [@slideInOut]=\"userListAnimationState\">\r\n <lib-user-list [userList]=\"userList\" [categories]=\"categories\"></lib-user-list>\r\n</div>\r\n<lib-document-status [contextId]=\"contextId\" [statusData]=\"statusData\"></lib-document-status>\r\n\r\n<!-- Document Upload Sidebar -->\r\n<lib-sidebar\r\n [(visible)]=\"isDocumentUploadSidebarOpen\"\r\n position=\"right\"\r\n width=\"600px\"\r\n title=\"Upload Documents\"\r\n [showCloseButton]=\"true\"\r\n [showSaveButton]=\"true\"\r\n [saveButtonText]=\"'Save'\"\r\n [saveButtonDisabled]=\"isSaveButtonDisabled\"\r\n [successMessage]=\"'Document Saved Successfully'\"\r\n [hasUnsavedChanges]=\"hasUnsavedChanges\"\r\n (onHide)=\"onDocumentUploadSidebarHide()\"\r\n (onSave)=\"onDocumentUploadSave()\"\r\n (onDiscardChanges)=\"onDocumentUploadSidebarCloseWithUnsavedChanges()\"\r\n>\r\n <lib-document-upload \r\n [contextId]=\"contextId\" \r\n (onFormValidationChange)=\"onFormValidationChange()\" \r\n (onUploadSuccess)=\"onDocumentUploadSuccess()\"\r\n (onUploadError)=\"onDocumentUploadError($event)\"\r\n ></lib-document-upload>\r\n</lib-sidebar>", styles: [".user-list-wrapper{overflow:hidden;margin-bottom:1rem}.user-list-wrapper ::ng-deep *{transition:opacity .2s ease-in-out}.user-list-wrapper.ng-animating{pointer-events:none}::ng-deep lib-user-list{display:block;width:100%}\n"] }]
4113
4315
  }], ctorParameters: () => [{ type: DocumentQuery }, { type: DocumentHelperService }], propDecorators: { documentList: [{
4114
4316
  type: Input
4115
4317
  }], folderList: [{
@@ -5456,11 +5658,11 @@ class DocumentActionsComponent {
5456
5658
  this.rejectNote = SHARED.EMPTY;
5457
5659
  }
5458
5660
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentActionsComponent, deps: [{ token: DocumentActionsService }], target: i0.ɵɵFactoryTarget.Component });
5459
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: DocumentActionsComponent, isStandalone: false, selector: "document-actions", inputs: { document: "document", documentId: "documentId", currentStatus: "currentStatus", isLoading: "isLoading", isUploaded: "isUploaded", statusId: "statusId" }, outputs: { actionPerformed: "actionPerformed" }, viewQueries: [{ propertyName: "confirmationDialog", first: true, predicate: ConfirmationDialogComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"document-actions-container\" >\r\n <div class=\"actions-card\" [ngClass]=\"cardClass\">\r\n <div class=\"actions-buttons\">\r\n <!-- Reject Button -->\r\n <button *ngIf=\"!document?.isUploaded\" class=\"action-btn reject-btn\" [ngClass]=\"rejectButtonClass\" (click)=\"onRejectClick()\"\r\n [disabled]=\"currentStatus === SHARED.STATUS_REJECTED_LOWERCASE || isRejecting\">\r\n <i class=\"pi pi-times\" *ngIf=\"currentStatus === SHARED.STATUS_REJECTED_LOWERCASE\"></i>\r\n <i class=\"pi pi-spin pi-spinner\" *ngIf=\"isRejecting\"></i>\r\n <span>{{ currentStatus === SHARED.STATUS_REJECTED_LOWERCASE ? SHARED.BUTTON_LABEL_REJECTED :\r\n SHARED.BUTTON_LABEL_REJECT }}</span>\r\n </button>\r\n\r\n <!-- Accept Button -->\r\n <button *ngIf=\"!document?.isUploaded\" class=\"action-btn accept-btn\" [ngClass]=\"acceptButtonClass\" (click)=\"onAcceptClick()\"\r\n [disabled]=\"currentStatus === SHARED.STATUS_ACCEPTED || isAccepting\">\r\n <i class=\"pi pi-check\" *ngIf=\"currentStatus === SHARED.STATUS_ACCEPTED\"></i>\r\n <i class=\"pi pi-spin pi-spinner\" *ngIf=\"isAccepting\"></i>\r\n <span>{{ currentStatus === SHARED.STATUS_ACCEPTED ? SHARED.BUTTON_LABEL_ACCEPTED : SHARED.BUTTON_LABEL_ACCEPT\r\n }}</span>\r\n </button>\r\n\r\n <!-- Delete Button -->\r\n @if(document?.isUploaded){\r\n <button class=\"action-btn delete-btn\" (click)=\"onDeleteClick()\" [disabled]=\"isLoading\"\r\n [permission]=\"'documents-deleteDocumentByDocumentId'\" pTooltip=\"Delete Document\" tooltipPosition=\"top\">\r\n <i class=\"pi pi-trash\"></i>\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<app-confirmation-dialog></app-confirmation-dialog>\r\n\r\n<p-dialog [(visible)]=\"showAcceptDialog\" [header]=\"SHARED.ACCEPT_CONFIRM_HEADER\" [modal]=\"true\" [draggable]=\"false\"\r\n [closable]=\"true\" [style]=\"{ width: '25rem', height: '25rem' }\" styleClass=\"confirmation-dialog\">\r\n <div class=\"dialog-content\">\r\n <label for=\"acceptNote\" class=\"note-label\">{{ SHARED.ACCEPT_NOTE_LABEL }}</label>\r\n <textarea id=\"acceptNote\" pInputTextarea [(ngModel)]=\"acceptNote\" [placeholder]=\"SHARED.ACCEPT_NOTE_PLACEHOLDER\"\r\n rows=\"6\" class=\"note-textarea\">\r\n </textarea>\r\n </div>\r\n <ng-template pTemplate=\"footer\">\r\n <div class=\"dialog-footer\">\r\n <button pButton [label]=\"SHARED.CANCEL_BUTTON_LABEL\" class=\"p-button-secondary\" (click)=\"onCancel()\">\r\n </button>\r\n <button pButton [label]=\"SHARED.ACCEPT_BUTTON_LABEL\" class=\"p-button-success\" (click)=\"onAcceptConfirm()\">\r\n </button>\r\n </div>\r\n </ng-template>\r\n</p-dialog>\r\n\r\n<p-dialog [(visible)]=\"showRejectDialog\" [header]=\"SHARED.REJECT_CONFIRM_HEADER\" [modal]=\"true\" [draggable]=\"false\"\r\n [closable]=\"true\" [style]=\"{ width: '25rem', height: '25rem' }\" styleClass=\"confirmation-dialog\">\r\n <div class=\"dialog-content\">\r\n <label for=\"rejectNote\" class=\"note-label\">{{ SHARED.REJECT_NOTE_LABEL }}</label>\r\n <textarea id=\"rejectNote\" pInputTextarea [(ngModel)]=\"rejectNote\" [placeholder]=\"SHARED.REJECT_NOTE_PLACEHOLDER\"\r\n rows=\"6\" class=\"note-textarea\">\r\n </textarea>\r\n </div>\r\n <ng-template pTemplate=\"footer\">\r\n <div class=\"dialog-footer\">\r\n <button pButton [label]=\"SHARED.CANCEL_BUTTON_LABEL\" class=\"p-button-secondary\" (click)=\"onCancel()\">\r\n </button>\r\n <button pButton [label]=\"SHARED.REJECT_BUTTON_LABEL\" class=\"p-button-danger\" [disabled]=\"isRejectNoteEmpty\"\r\n (click)=\"onRejectConfirm()\">\r\n </button>\r\n </div>\r\n </ng-template>\r\n</p-dialog>", styles: [".document-actions-container{margin:0}.actions-card{border-radius:8px;padding:.75rem;box-shadow:0 2px 4px #0000001a;transition:all .3s ease}.actions-card.pending-card{background-color:#f8f9fa;border:1px solid #e9ecef}.actions-card.accepted-card{background-color:#d4edda;border:1px solid #28a745}.actions-card.rejected-card{background-color:#f8d7da;border:1px solid #dc3545}.actions-card[class*=status-].status-approved-card{background-color:#d4edda;border:1px solid #28a745}.actions-card[class*=status-].status-rejected-card{background-color:#f8d7da;border:1px solid #dc3545}.actions-card[class*=status-].status-pending-card{background-color:#f8f9fa;border:1px solid #e9ecef}.actions-buttons{display:flex;gap:.5rem;align-items:center}.action-btn{padding:.5rem 1rem;border-radius:6px;border:1px solid;font-weight:500;cursor:pointer;transition:all .2s ease;display:flex;align-items:center;gap:.5rem;min-width:80px;justify-content:center}.action-btn:disabled{opacity:.6;cursor:not-allowed}.action-btn i{font-size:.875rem}.reject-btn.default-reject{background-color:#fff5f5;border-color:#feb2b2;color:#4a5568}.reject-btn.default-reject:hover:not(:disabled){background-color:#fed7d7;border-color:#fc8181}.reject-btn.secondary-reject{background-color:#f7fafc;border-color:#e2e8f0;color:#4a5568}.reject-btn.secondary-reject:hover:not(:disabled){background-color:#edf2f7;border-color:#cbd5e0}.reject-btn.primary-reject{background-color:#dc3545;border-color:#dc3545;color:#fff}.reject-btn.primary-reject:hover:not(:disabled){background-color:#c82333;border-color:#bd2130}.reject-btn[class*=status-].status-approved-reject{background-color:#f7fafc;border-color:#e2e8f0;color:#4a5568}.reject-btn[class*=status-].status-approved-reject:hover:not(:disabled){background-color:#edf2f7;border-color:#cbd5e0}.reject-btn[class*=status-].status-rejected-reject{background-color:#dc3545;border-color:#dc3545;color:#fff}.reject-btn[class*=status-].status-rejected-reject:hover:not(:disabled){background-color:#c82333;border-color:#bd2130}.reject-btn[class*=status-].status-pending-reject{background-color:#fff5f5;border-color:#feb2b2;color:#4a5568}.reject-btn[class*=status-].status-pending-reject:hover:not(:disabled){background-color:#fed7d7;border-color:#fc8181}.accept-btn.default-accept{background-color:#f0fff4;border-color:#9ae6b4;color:#4a5568}.accept-btn.default-accept:hover:not(:disabled){background-color:#c6f6d5;border-color:#68d391}.accept-btn.secondary-accept{background-color:#f7fafc;border-color:#e2e8f0;color:#4a5568}.accept-btn.secondary-accept:hover:not(:disabled){background-color:#edf2f7;border-color:#cbd5e0}.accept-btn.primary-accept{background-color:#28a745;border-color:#28a745;color:#fff}.accept-btn.primary-accept:hover:not(:disabled){background-color:#218838;border-color:#1e7e34}.accept-btn[class*=status-].status-approved-accept{background-color:#28a745;border-color:#28a745;color:#fff}.accept-btn[class*=status-].status-approved-accept:hover:not(:disabled){background-color:#218838;border-color:#1e7e34}.accept-btn[class*=status-].status-rejected-accept{background-color:#f7fafc;border-color:#e2e8f0;color:#4a5568}.accept-btn[class*=status-].status-rejected-accept:hover:not(:disabled){background-color:#edf2f7;border-color:#cbd5e0}.accept-btn[class*=status-].status-pending-accept{background-color:#f0fff4;border-color:#9ae6b4;color:#4a5568}.accept-btn[class*=status-].status-pending-accept:hover:not(:disabled){background-color:#c6f6d5;border-color:#68d391}.delete-btn{background-color:#fff;border-color:#e2e8f0;color:#e53e3e;padding:.5rem;min-width:auto;width:40px;height:40px}.delete-btn:hover:not(:disabled){background-color:#fed7d7;border-color:#fc8181;color:#c53030}.delete-btn i{font-size:1rem}:host ::ng-deep .confirmation-dialog .p-dialog{border-radius:8px;box-shadow:0 4px 12px #00000026;border:none;overflow:hidden}:host ::ng-deep .confirmation-dialog .p-dialog-header{padding:1.25rem 1.5rem;background-color:#fff;border-bottom:none;border-top-right-radius:10px;border-top-left-radius:10px}:host ::ng-deep .confirmation-dialog .p-dialog-header .p-dialog-header-icon{display:none}:host ::ng-deep .confirmation-dialog .p-dialog-header .p-dialog-title{font-size:1.125rem;font-weight:600;color:#2d3748;margin:0}:host ::ng-deep .confirmation-dialog .p-dialog-content{padding:1.5rem;background-color:#fff}:host ::ng-deep .confirmation-dialog .p-dialog-footer{padding:1rem 1.5rem;background-color:#f7fafc;border-top:1px solid #e2e8f0;display:flex;gap:.75rem;justify-content:flex-end;border-bottom-right-radius:10px;border-bottom-left-radius:10px}.dialog-content .note-label{display:block;margin-bottom:.75rem;font-weight:500;font-size:.875rem;color:#2d3748}.dialog-content .note-textarea{width:100%;min-height:100px;padding:.75rem;border:1px solid #e2e8f0;border-radius:6px;font-family:inherit;font-size:.875rem;line-height:1.5;resize:vertical;background-color:#fff;color:#2d3748}.dialog-content .note-textarea::placeholder{color:#a0aec0}.dialog-content .note-textarea:focus{outline:none;border-color:#3182ce;box-shadow:0 0 0 3px #3182ce1a}.dialog-footer{display:flex;gap:.75rem;justify-content:flex-end}.dialog-footer button{min-width:80px;padding:.5rem 1rem;border-radius:6px;font-weight:500;font-size:.875rem;border:1px solid;cursor:pointer;transition:all .2s ease}.dialog-footer button.p-button-secondary{background-color:#f7fafc;border-color:#e2e8f0;color:#4a5568}.dialog-footer button.p-button-secondary:hover{background-color:#edf2f7;border-color:#cbd5e0}.dialog-footer button.p-button-success{background-color:#38a169;border-color:#38a169;color:#fff}.dialog-footer button.p-button-success:hover{background-color:#2f855a;border-color:#2f855a}.dialog-footer button.p-button-danger{background-color:#e53e3e;border-color:#e53e3e;color:#fff}.dialog-footer button.p-button-danger:hover{background-color:#c53030;border-color:#c53030}\n"], dependencies: [{ kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i4.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "directive", type: i5$2.InputTextarea, selector: "[pInputTextarea]", inputs: ["autoResize", "variant"], outputs: ["onResize"] }, { kind: "directive", type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i7.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "visible", "style", "position"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "directive", type: i8.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "directive", type: HasPermissionDirective, selector: "[permission]", inputs: ["permission"] }, { kind: "component", type: ConfirmationDialogComponent, selector: "app-confirmation-dialog", inputs: ["confirmationOptions"] }] });
5661
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: DocumentActionsComponent, isStandalone: false, selector: "document-actions", inputs: { document: "document", documentId: "documentId", currentStatus: "currentStatus", isLoading: "isLoading", isUploaded: "isUploaded", statusId: "statusId" }, outputs: { actionPerformed: "actionPerformed" }, viewQueries: [{ propertyName: "confirmationDialog", first: true, predicate: ConfirmationDialogComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"document-actions-container\" *ngIf=\"!document?.isUploaded\">\r\n <div class=\"actions-card\" [ngClass]=\"cardClass\">\r\n <div class=\"actions-buttons\">\r\n <!-- Reject Button -->\r\n <button *ngIf=\"!document?.isUploaded\" class=\"action-btn reject-btn\" [ngClass]=\"rejectButtonClass\" (click)=\"onRejectClick()\"\r\n [disabled]=\"currentStatus === SHARED.STATUS_REJECTED_LOWERCASE || isRejecting\">\r\n <i class=\"pi pi-times\" *ngIf=\"currentStatus === SHARED.STATUS_REJECTED_LOWERCASE\"></i>\r\n <i class=\"pi pi-spin pi-spinner\" *ngIf=\"isRejecting\"></i>\r\n <span>{{ currentStatus === SHARED.STATUS_REJECTED_LOWERCASE ? SHARED.BUTTON_LABEL_REJECTED :\r\n SHARED.BUTTON_LABEL_REJECT }}</span>\r\n </button>\r\n\r\n <!-- Accept Button -->\r\n <button *ngIf=\"!document?.isUploaded\" class=\"action-btn accept-btn\" [ngClass]=\"acceptButtonClass\" (click)=\"onAcceptClick()\"\r\n [disabled]=\"currentStatus === SHARED.STATUS_ACCEPTED || isAccepting\">\r\n <i class=\"pi pi-check\" *ngIf=\"currentStatus === SHARED.STATUS_ACCEPTED\"></i>\r\n <i class=\"pi pi-spin pi-spinner\" *ngIf=\"isAccepting\"></i>\r\n <span>{{ currentStatus === SHARED.STATUS_ACCEPTED ? SHARED.BUTTON_LABEL_ACCEPTED : SHARED.BUTTON_LABEL_ACCEPT\r\n }}</span>\r\n </button>\r\n\r\n <!-- Delete Button -->\r\n @if(document?.isUploaded){\r\n <button class=\"action-btn delete-btn\" (click)=\"onDeleteClick()\" [disabled]=\"isLoading\"\r\n [permission]=\"'documents-deleteDocumentByDocumentId'\" pTooltip=\"Delete Document\" tooltipPosition=\"top\">\r\n <i class=\"pi pi-trash\"></i>\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<app-confirmation-dialog></app-confirmation-dialog>\r\n\r\n<p-dialog [(visible)]=\"showAcceptDialog\" [header]=\"SHARED.ACCEPT_CONFIRM_HEADER\" [modal]=\"true\" [draggable]=\"false\"\r\n [closable]=\"true\" [style]=\"{ width: '25rem', height: '25rem' }\" styleClass=\"confirmation-dialog\">\r\n <div class=\"dialog-content\">\r\n <label for=\"acceptNote\" class=\"note-label\">{{ SHARED.ACCEPT_NOTE_LABEL }}</label>\r\n <textarea id=\"acceptNote\" pInputTextarea [(ngModel)]=\"acceptNote\" [placeholder]=\"SHARED.ACCEPT_NOTE_PLACEHOLDER\"\r\n rows=\"6\" class=\"note-textarea\">\r\n </textarea>\r\n </div>\r\n <ng-template pTemplate=\"footer\">\r\n <div class=\"dialog-footer\">\r\n <button pButton [label]=\"SHARED.CANCEL_BUTTON_LABEL\" class=\"p-button-secondary\" (click)=\"onCancel()\">\r\n </button>\r\n <button pButton [label]=\"SHARED.ACCEPT_BUTTON_LABEL\" class=\"p-button-success\" (click)=\"onAcceptConfirm()\">\r\n </button>\r\n </div>\r\n </ng-template>\r\n</p-dialog>\r\n\r\n<p-dialog [(visible)]=\"showRejectDialog\" [header]=\"SHARED.REJECT_CONFIRM_HEADER\" [modal]=\"true\" [draggable]=\"false\"\r\n [closable]=\"true\" [style]=\"{ width: '25rem', height: '25rem' }\" styleClass=\"confirmation-dialog\">\r\n <div class=\"dialog-content\">\r\n <label for=\"rejectNote\" class=\"note-label\">{{ SHARED.REJECT_NOTE_LABEL }}</label>\r\n <textarea id=\"rejectNote\" pInputTextarea [(ngModel)]=\"rejectNote\" [placeholder]=\"SHARED.REJECT_NOTE_PLACEHOLDER\"\r\n rows=\"6\" class=\"note-textarea\">\r\n </textarea>\r\n </div>\r\n <ng-template pTemplate=\"footer\">\r\n <div class=\"dialog-footer\">\r\n <button pButton [label]=\"SHARED.CANCEL_BUTTON_LABEL\" class=\"p-button-secondary\" (click)=\"onCancel()\">\r\n </button>\r\n <button pButton [label]=\"SHARED.REJECT_BUTTON_LABEL\" class=\"p-button-danger\" [disabled]=\"isRejectNoteEmpty\"\r\n (click)=\"onRejectConfirm()\">\r\n </button>\r\n </div>\r\n </ng-template>\r\n</p-dialog>", styles: [".document-actions-container{margin:0}.actions-card{border-radius:8px;padding:.75rem;box-shadow:0 2px 4px #0000001a;transition:all .3s ease}.actions-card.pending-card{background-color:#f8f9fa;border:1px solid #e9ecef;width:92%;margin-left:3%}.actions-card.accepted-card{background-color:#d4edda;border:1px solid #28a745}.actions-card.rejected-card{background-color:#f8d7da;border:1px solid #dc3545}.actions-card[class*=status-].status-approved-card{background-color:#d4edda;border:1px solid #28a745}.actions-card[class*=status-].status-rejected-card{background-color:#f8d7da;border:1px solid #dc3545}.actions-card[class*=status-].status-pending-card{background-color:#f8f9fa;border:1px solid #e9ecef}.actions-buttons{display:flex;gap:.5rem;align-items:center}.action-btn{padding:.5rem 1rem;border-radius:6px;border:1px solid;font-weight:500;cursor:pointer;transition:all .2s ease;display:flex;align-items:center;gap:.5rem;min-width:80px;justify-content:center}.action-btn:disabled{opacity:.6;cursor:not-allowed}.action-btn i{font-size:.875rem}.reject-btn.default-reject{background-color:#fff5f5;border-color:#feb2b2;color:#4a5568}.reject-btn.default-reject:hover:not(:disabled){background-color:#fed7d7;border-color:#fc8181}.reject-btn.secondary-reject{background-color:#f7fafc;border-color:#e2e8f0;color:#4a5568}.reject-btn.secondary-reject:hover:not(:disabled){background-color:#edf2f7;border-color:#cbd5e0}.reject-btn.primary-reject{background-color:#dc3545;border-color:#dc3545;color:#fff}.reject-btn.primary-reject:hover:not(:disabled){background-color:#c82333;border-color:#bd2130}.reject-btn[class*=status-].status-approved-reject{background-color:#f7fafc;border-color:#e2e8f0;color:#4a5568}.reject-btn[class*=status-].status-approved-reject:hover:not(:disabled){background-color:#edf2f7;border-color:#cbd5e0}.reject-btn[class*=status-].status-rejected-reject{background-color:#dc3545;border-color:#dc3545;color:#fff}.reject-btn[class*=status-].status-rejected-reject:hover:not(:disabled){background-color:#c82333;border-color:#bd2130}.reject-btn[class*=status-].status-pending-reject{background-color:#fff5f5;border-color:#feb2b2;color:#4a5568}.reject-btn[class*=status-].status-pending-reject:hover:not(:disabled){background-color:#fed7d7;border-color:#fc8181}.accept-btn.default-accept{background-color:#f0fff4;border-color:#9ae6b4;color:#4a5568}.accept-btn.default-accept:hover:not(:disabled){background-color:#c6f6d5;border-color:#68d391}.accept-btn.secondary-accept{background-color:#f7fafc;border-color:#e2e8f0;color:#4a5568}.accept-btn.secondary-accept:hover:not(:disabled){background-color:#edf2f7;border-color:#cbd5e0}.accept-btn.primary-accept{background-color:#28a745;border-color:#28a745;color:#fff}.accept-btn.primary-accept:hover:not(:disabled){background-color:#218838;border-color:#1e7e34}.accept-btn[class*=status-].status-approved-accept{background-color:#28a745;border-color:#28a745;color:#fff}.accept-btn[class*=status-].status-approved-accept:hover:not(:disabled){background-color:#218838;border-color:#1e7e34}.accept-btn[class*=status-].status-rejected-accept{background-color:#f7fafc;border-color:#e2e8f0;color:#4a5568}.accept-btn[class*=status-].status-rejected-accept:hover:not(:disabled){background-color:#edf2f7;border-color:#cbd5e0}.accept-btn[class*=status-].status-pending-accept{background-color:#f0fff4;border-color:#9ae6b4;color:#4a5568}.accept-btn[class*=status-].status-pending-accept:hover:not(:disabled){background-color:#c6f6d5;border-color:#68d391}.delete-btn{background-color:#fff;border-color:#e2e8f0;color:#e53e3e;padding:.5rem;min-width:auto;width:40px;height:40px}.delete-btn:hover:not(:disabled){background-color:#fed7d7;border-color:#fc8181;color:#c53030}.delete-btn i{font-size:1rem}:host ::ng-deep .confirmation-dialog .p-dialog{border-radius:8px;box-shadow:0 4px 12px #00000026;border:none;overflow:hidden}:host ::ng-deep .confirmation-dialog .p-dialog-header{padding:1.25rem 1.5rem;background-color:#fff;border-bottom:none;border-top-right-radius:10px;border-top-left-radius:10px}:host ::ng-deep .confirmation-dialog .p-dialog-header .p-dialog-header-icon{display:none}:host ::ng-deep .confirmation-dialog .p-dialog-header .p-dialog-title{font-size:1.125rem;font-weight:600;color:#2d3748;margin:0}:host ::ng-deep .confirmation-dialog .p-dialog-content{padding:1.5rem;background-color:#fff}:host ::ng-deep .confirmation-dialog .p-dialog-footer{padding:1rem 1.5rem;background-color:#f7fafc;border-top:1px solid #e2e8f0;display:flex;gap:.75rem;justify-content:flex-end;border-bottom-right-radius:10px;border-bottom-left-radius:10px}.dialog-content .note-label{display:block;margin-bottom:.75rem;font-weight:500;font-size:.875rem;color:#2d3748}.dialog-content .note-textarea{width:100%;min-height:100px;padding:.75rem;border:1px solid #e2e8f0;border-radius:6px;font-family:inherit;font-size:.875rem;line-height:1.5;resize:vertical;background-color:#fff;color:#2d3748}.dialog-content .note-textarea::placeholder{color:#a0aec0}.dialog-content .note-textarea:focus{outline:none;border-color:#3182ce;box-shadow:0 0 0 3px #3182ce1a}.dialog-footer{display:flex;gap:.75rem;justify-content:flex-end}.dialog-footer button{min-width:80px;padding:.5rem 1rem;border-radius:6px;font-weight:500;font-size:.875rem;border:1px solid;cursor:pointer;transition:all .2s ease}.dialog-footer button.p-button-secondary{background-color:#f7fafc;border-color:#e2e8f0;color:#4a5568}.dialog-footer button.p-button-secondary:hover{background-color:#edf2f7;border-color:#cbd5e0}.dialog-footer button.p-button-success{background-color:#38a169;border-color:#38a169;color:#fff}.dialog-footer button.p-button-success:hover{background-color:#2f855a;border-color:#2f855a}.dialog-footer button.p-button-danger{background-color:#e53e3e;border-color:#e53e3e;color:#fff}.dialog-footer button.p-button-danger:hover{background-color:#c53030;border-color:#c53030}\n"], dependencies: [{ kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i4.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "directive", type: i5$2.InputTextarea, selector: "[pInputTextarea]", inputs: ["autoResize", "variant"], outputs: ["onResize"] }, { kind: "directive", type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i7.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "visible", "style", "position"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "directive", type: i8.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "directive", type: HasPermissionDirective, selector: "[permission]", inputs: ["permission"] }, { kind: "component", type: ConfirmationDialogComponent, selector: "app-confirmation-dialog", inputs: ["confirmationOptions"] }] });
5460
5662
  }
5461
5663
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentActionsComponent, decorators: [{
5462
5664
  type: Component,
5463
- args: [{ selector: 'document-actions', standalone: false, template: "<div class=\"document-actions-container\" >\r\n <div class=\"actions-card\" [ngClass]=\"cardClass\">\r\n <div class=\"actions-buttons\">\r\n <!-- Reject Button -->\r\n <button *ngIf=\"!document?.isUploaded\" class=\"action-btn reject-btn\" [ngClass]=\"rejectButtonClass\" (click)=\"onRejectClick()\"\r\n [disabled]=\"currentStatus === SHARED.STATUS_REJECTED_LOWERCASE || isRejecting\">\r\n <i class=\"pi pi-times\" *ngIf=\"currentStatus === SHARED.STATUS_REJECTED_LOWERCASE\"></i>\r\n <i class=\"pi pi-spin pi-spinner\" *ngIf=\"isRejecting\"></i>\r\n <span>{{ currentStatus === SHARED.STATUS_REJECTED_LOWERCASE ? SHARED.BUTTON_LABEL_REJECTED :\r\n SHARED.BUTTON_LABEL_REJECT }}</span>\r\n </button>\r\n\r\n <!-- Accept Button -->\r\n <button *ngIf=\"!document?.isUploaded\" class=\"action-btn accept-btn\" [ngClass]=\"acceptButtonClass\" (click)=\"onAcceptClick()\"\r\n [disabled]=\"currentStatus === SHARED.STATUS_ACCEPTED || isAccepting\">\r\n <i class=\"pi pi-check\" *ngIf=\"currentStatus === SHARED.STATUS_ACCEPTED\"></i>\r\n <i class=\"pi pi-spin pi-spinner\" *ngIf=\"isAccepting\"></i>\r\n <span>{{ currentStatus === SHARED.STATUS_ACCEPTED ? SHARED.BUTTON_LABEL_ACCEPTED : SHARED.BUTTON_LABEL_ACCEPT\r\n }}</span>\r\n </button>\r\n\r\n <!-- Delete Button -->\r\n @if(document?.isUploaded){\r\n <button class=\"action-btn delete-btn\" (click)=\"onDeleteClick()\" [disabled]=\"isLoading\"\r\n [permission]=\"'documents-deleteDocumentByDocumentId'\" pTooltip=\"Delete Document\" tooltipPosition=\"top\">\r\n <i class=\"pi pi-trash\"></i>\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<app-confirmation-dialog></app-confirmation-dialog>\r\n\r\n<p-dialog [(visible)]=\"showAcceptDialog\" [header]=\"SHARED.ACCEPT_CONFIRM_HEADER\" [modal]=\"true\" [draggable]=\"false\"\r\n [closable]=\"true\" [style]=\"{ width: '25rem', height: '25rem' }\" styleClass=\"confirmation-dialog\">\r\n <div class=\"dialog-content\">\r\n <label for=\"acceptNote\" class=\"note-label\">{{ SHARED.ACCEPT_NOTE_LABEL }}</label>\r\n <textarea id=\"acceptNote\" pInputTextarea [(ngModel)]=\"acceptNote\" [placeholder]=\"SHARED.ACCEPT_NOTE_PLACEHOLDER\"\r\n rows=\"6\" class=\"note-textarea\">\r\n </textarea>\r\n </div>\r\n <ng-template pTemplate=\"footer\">\r\n <div class=\"dialog-footer\">\r\n <button pButton [label]=\"SHARED.CANCEL_BUTTON_LABEL\" class=\"p-button-secondary\" (click)=\"onCancel()\">\r\n </button>\r\n <button pButton [label]=\"SHARED.ACCEPT_BUTTON_LABEL\" class=\"p-button-success\" (click)=\"onAcceptConfirm()\">\r\n </button>\r\n </div>\r\n </ng-template>\r\n</p-dialog>\r\n\r\n<p-dialog [(visible)]=\"showRejectDialog\" [header]=\"SHARED.REJECT_CONFIRM_HEADER\" [modal]=\"true\" [draggable]=\"false\"\r\n [closable]=\"true\" [style]=\"{ width: '25rem', height: '25rem' }\" styleClass=\"confirmation-dialog\">\r\n <div class=\"dialog-content\">\r\n <label for=\"rejectNote\" class=\"note-label\">{{ SHARED.REJECT_NOTE_LABEL }}</label>\r\n <textarea id=\"rejectNote\" pInputTextarea [(ngModel)]=\"rejectNote\" [placeholder]=\"SHARED.REJECT_NOTE_PLACEHOLDER\"\r\n rows=\"6\" class=\"note-textarea\">\r\n </textarea>\r\n </div>\r\n <ng-template pTemplate=\"footer\">\r\n <div class=\"dialog-footer\">\r\n <button pButton [label]=\"SHARED.CANCEL_BUTTON_LABEL\" class=\"p-button-secondary\" (click)=\"onCancel()\">\r\n </button>\r\n <button pButton [label]=\"SHARED.REJECT_BUTTON_LABEL\" class=\"p-button-danger\" [disabled]=\"isRejectNoteEmpty\"\r\n (click)=\"onRejectConfirm()\">\r\n </button>\r\n </div>\r\n </ng-template>\r\n</p-dialog>", styles: [".document-actions-container{margin:0}.actions-card{border-radius:8px;padding:.75rem;box-shadow:0 2px 4px #0000001a;transition:all .3s ease}.actions-card.pending-card{background-color:#f8f9fa;border:1px solid #e9ecef}.actions-card.accepted-card{background-color:#d4edda;border:1px solid #28a745}.actions-card.rejected-card{background-color:#f8d7da;border:1px solid #dc3545}.actions-card[class*=status-].status-approved-card{background-color:#d4edda;border:1px solid #28a745}.actions-card[class*=status-].status-rejected-card{background-color:#f8d7da;border:1px solid #dc3545}.actions-card[class*=status-].status-pending-card{background-color:#f8f9fa;border:1px solid #e9ecef}.actions-buttons{display:flex;gap:.5rem;align-items:center}.action-btn{padding:.5rem 1rem;border-radius:6px;border:1px solid;font-weight:500;cursor:pointer;transition:all .2s ease;display:flex;align-items:center;gap:.5rem;min-width:80px;justify-content:center}.action-btn:disabled{opacity:.6;cursor:not-allowed}.action-btn i{font-size:.875rem}.reject-btn.default-reject{background-color:#fff5f5;border-color:#feb2b2;color:#4a5568}.reject-btn.default-reject:hover:not(:disabled){background-color:#fed7d7;border-color:#fc8181}.reject-btn.secondary-reject{background-color:#f7fafc;border-color:#e2e8f0;color:#4a5568}.reject-btn.secondary-reject:hover:not(:disabled){background-color:#edf2f7;border-color:#cbd5e0}.reject-btn.primary-reject{background-color:#dc3545;border-color:#dc3545;color:#fff}.reject-btn.primary-reject:hover:not(:disabled){background-color:#c82333;border-color:#bd2130}.reject-btn[class*=status-].status-approved-reject{background-color:#f7fafc;border-color:#e2e8f0;color:#4a5568}.reject-btn[class*=status-].status-approved-reject:hover:not(:disabled){background-color:#edf2f7;border-color:#cbd5e0}.reject-btn[class*=status-].status-rejected-reject{background-color:#dc3545;border-color:#dc3545;color:#fff}.reject-btn[class*=status-].status-rejected-reject:hover:not(:disabled){background-color:#c82333;border-color:#bd2130}.reject-btn[class*=status-].status-pending-reject{background-color:#fff5f5;border-color:#feb2b2;color:#4a5568}.reject-btn[class*=status-].status-pending-reject:hover:not(:disabled){background-color:#fed7d7;border-color:#fc8181}.accept-btn.default-accept{background-color:#f0fff4;border-color:#9ae6b4;color:#4a5568}.accept-btn.default-accept:hover:not(:disabled){background-color:#c6f6d5;border-color:#68d391}.accept-btn.secondary-accept{background-color:#f7fafc;border-color:#e2e8f0;color:#4a5568}.accept-btn.secondary-accept:hover:not(:disabled){background-color:#edf2f7;border-color:#cbd5e0}.accept-btn.primary-accept{background-color:#28a745;border-color:#28a745;color:#fff}.accept-btn.primary-accept:hover:not(:disabled){background-color:#218838;border-color:#1e7e34}.accept-btn[class*=status-].status-approved-accept{background-color:#28a745;border-color:#28a745;color:#fff}.accept-btn[class*=status-].status-approved-accept:hover:not(:disabled){background-color:#218838;border-color:#1e7e34}.accept-btn[class*=status-].status-rejected-accept{background-color:#f7fafc;border-color:#e2e8f0;color:#4a5568}.accept-btn[class*=status-].status-rejected-accept:hover:not(:disabled){background-color:#edf2f7;border-color:#cbd5e0}.accept-btn[class*=status-].status-pending-accept{background-color:#f0fff4;border-color:#9ae6b4;color:#4a5568}.accept-btn[class*=status-].status-pending-accept:hover:not(:disabled){background-color:#c6f6d5;border-color:#68d391}.delete-btn{background-color:#fff;border-color:#e2e8f0;color:#e53e3e;padding:.5rem;min-width:auto;width:40px;height:40px}.delete-btn:hover:not(:disabled){background-color:#fed7d7;border-color:#fc8181;color:#c53030}.delete-btn i{font-size:1rem}:host ::ng-deep .confirmation-dialog .p-dialog{border-radius:8px;box-shadow:0 4px 12px #00000026;border:none;overflow:hidden}:host ::ng-deep .confirmation-dialog .p-dialog-header{padding:1.25rem 1.5rem;background-color:#fff;border-bottom:none;border-top-right-radius:10px;border-top-left-radius:10px}:host ::ng-deep .confirmation-dialog .p-dialog-header .p-dialog-header-icon{display:none}:host ::ng-deep .confirmation-dialog .p-dialog-header .p-dialog-title{font-size:1.125rem;font-weight:600;color:#2d3748;margin:0}:host ::ng-deep .confirmation-dialog .p-dialog-content{padding:1.5rem;background-color:#fff}:host ::ng-deep .confirmation-dialog .p-dialog-footer{padding:1rem 1.5rem;background-color:#f7fafc;border-top:1px solid #e2e8f0;display:flex;gap:.75rem;justify-content:flex-end;border-bottom-right-radius:10px;border-bottom-left-radius:10px}.dialog-content .note-label{display:block;margin-bottom:.75rem;font-weight:500;font-size:.875rem;color:#2d3748}.dialog-content .note-textarea{width:100%;min-height:100px;padding:.75rem;border:1px solid #e2e8f0;border-radius:6px;font-family:inherit;font-size:.875rem;line-height:1.5;resize:vertical;background-color:#fff;color:#2d3748}.dialog-content .note-textarea::placeholder{color:#a0aec0}.dialog-content .note-textarea:focus{outline:none;border-color:#3182ce;box-shadow:0 0 0 3px #3182ce1a}.dialog-footer{display:flex;gap:.75rem;justify-content:flex-end}.dialog-footer button{min-width:80px;padding:.5rem 1rem;border-radius:6px;font-weight:500;font-size:.875rem;border:1px solid;cursor:pointer;transition:all .2s ease}.dialog-footer button.p-button-secondary{background-color:#f7fafc;border-color:#e2e8f0;color:#4a5568}.dialog-footer button.p-button-secondary:hover{background-color:#edf2f7;border-color:#cbd5e0}.dialog-footer button.p-button-success{background-color:#38a169;border-color:#38a169;color:#fff}.dialog-footer button.p-button-success:hover{background-color:#2f855a;border-color:#2f855a}.dialog-footer button.p-button-danger{background-color:#e53e3e;border-color:#e53e3e;color:#fff}.dialog-footer button.p-button-danger:hover{background-color:#c53030;border-color:#c53030}\n"] }]
5665
+ args: [{ selector: 'document-actions', standalone: false, template: "<div class=\"document-actions-container\" *ngIf=\"!document?.isUploaded\">\r\n <div class=\"actions-card\" [ngClass]=\"cardClass\">\r\n <div class=\"actions-buttons\">\r\n <!-- Reject Button -->\r\n <button *ngIf=\"!document?.isUploaded\" class=\"action-btn reject-btn\" [ngClass]=\"rejectButtonClass\" (click)=\"onRejectClick()\"\r\n [disabled]=\"currentStatus === SHARED.STATUS_REJECTED_LOWERCASE || isRejecting\">\r\n <i class=\"pi pi-times\" *ngIf=\"currentStatus === SHARED.STATUS_REJECTED_LOWERCASE\"></i>\r\n <i class=\"pi pi-spin pi-spinner\" *ngIf=\"isRejecting\"></i>\r\n <span>{{ currentStatus === SHARED.STATUS_REJECTED_LOWERCASE ? SHARED.BUTTON_LABEL_REJECTED :\r\n SHARED.BUTTON_LABEL_REJECT }}</span>\r\n </button>\r\n\r\n <!-- Accept Button -->\r\n <button *ngIf=\"!document?.isUploaded\" class=\"action-btn accept-btn\" [ngClass]=\"acceptButtonClass\" (click)=\"onAcceptClick()\"\r\n [disabled]=\"currentStatus === SHARED.STATUS_ACCEPTED || isAccepting\">\r\n <i class=\"pi pi-check\" *ngIf=\"currentStatus === SHARED.STATUS_ACCEPTED\"></i>\r\n <i class=\"pi pi-spin pi-spinner\" *ngIf=\"isAccepting\"></i>\r\n <span>{{ currentStatus === SHARED.STATUS_ACCEPTED ? SHARED.BUTTON_LABEL_ACCEPTED : SHARED.BUTTON_LABEL_ACCEPT\r\n }}</span>\r\n </button>\r\n\r\n <!-- Delete Button -->\r\n @if(document?.isUploaded){\r\n <button class=\"action-btn delete-btn\" (click)=\"onDeleteClick()\" [disabled]=\"isLoading\"\r\n [permission]=\"'documents-deleteDocumentByDocumentId'\" pTooltip=\"Delete Document\" tooltipPosition=\"top\">\r\n <i class=\"pi pi-trash\"></i>\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<app-confirmation-dialog></app-confirmation-dialog>\r\n\r\n<p-dialog [(visible)]=\"showAcceptDialog\" [header]=\"SHARED.ACCEPT_CONFIRM_HEADER\" [modal]=\"true\" [draggable]=\"false\"\r\n [closable]=\"true\" [style]=\"{ width: '25rem', height: '25rem' }\" styleClass=\"confirmation-dialog\">\r\n <div class=\"dialog-content\">\r\n <label for=\"acceptNote\" class=\"note-label\">{{ SHARED.ACCEPT_NOTE_LABEL }}</label>\r\n <textarea id=\"acceptNote\" pInputTextarea [(ngModel)]=\"acceptNote\" [placeholder]=\"SHARED.ACCEPT_NOTE_PLACEHOLDER\"\r\n rows=\"6\" class=\"note-textarea\">\r\n </textarea>\r\n </div>\r\n <ng-template pTemplate=\"footer\">\r\n <div class=\"dialog-footer\">\r\n <button pButton [label]=\"SHARED.CANCEL_BUTTON_LABEL\" class=\"p-button-secondary\" (click)=\"onCancel()\">\r\n </button>\r\n <button pButton [label]=\"SHARED.ACCEPT_BUTTON_LABEL\" class=\"p-button-success\" (click)=\"onAcceptConfirm()\">\r\n </button>\r\n </div>\r\n </ng-template>\r\n</p-dialog>\r\n\r\n<p-dialog [(visible)]=\"showRejectDialog\" [header]=\"SHARED.REJECT_CONFIRM_HEADER\" [modal]=\"true\" [draggable]=\"false\"\r\n [closable]=\"true\" [style]=\"{ width: '25rem', height: '25rem' }\" styleClass=\"confirmation-dialog\">\r\n <div class=\"dialog-content\">\r\n <label for=\"rejectNote\" class=\"note-label\">{{ SHARED.REJECT_NOTE_LABEL }}</label>\r\n <textarea id=\"rejectNote\" pInputTextarea [(ngModel)]=\"rejectNote\" [placeholder]=\"SHARED.REJECT_NOTE_PLACEHOLDER\"\r\n rows=\"6\" class=\"note-textarea\">\r\n </textarea>\r\n </div>\r\n <ng-template pTemplate=\"footer\">\r\n <div class=\"dialog-footer\">\r\n <button pButton [label]=\"SHARED.CANCEL_BUTTON_LABEL\" class=\"p-button-secondary\" (click)=\"onCancel()\">\r\n </button>\r\n <button pButton [label]=\"SHARED.REJECT_BUTTON_LABEL\" class=\"p-button-danger\" [disabled]=\"isRejectNoteEmpty\"\r\n (click)=\"onRejectConfirm()\">\r\n </button>\r\n </div>\r\n </ng-template>\r\n</p-dialog>", styles: [".document-actions-container{margin:0}.actions-card{border-radius:8px;padding:.75rem;box-shadow:0 2px 4px #0000001a;transition:all .3s ease}.actions-card.pending-card{background-color:#f8f9fa;border:1px solid #e9ecef;width:92%;margin-left:3%}.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"] }]
5464
5666
  }], ctorParameters: () => [{ type: DocumentActionsService }], propDecorators: { document: [{
5465
5667
  type: Input
5466
5668
  }], documentId: [{
@@ -6808,7 +7010,8 @@ class DocumentModule {
6808
7010
  SharedModule,
6809
7011
  InputTextareaModule,
6810
7012
  ToastModule,
6811
- ConfirmDialogModule], exports: [
7013
+ ConfirmDialogModule,
7014
+ TooltipModule], exports: [
6812
7015
  /**
6813
7016
  * Exports the `DocumentContainerComponent` to be used in other modules.
6814
7017
  */
@@ -6957,7 +7160,8 @@ class DocumentModule {
6957
7160
  SharedModule,
6958
7161
  InputTextareaModule,
6959
7162
  ToastModule,
6960
- ConfirmDialogModule] });
7163
+ ConfirmDialogModule,
7164
+ TooltipModule] });
6961
7165
  }
6962
7166
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DocumentModule, decorators: [{
6963
7167
  type: NgModule,
@@ -7098,7 +7302,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
7098
7302
  SharedModule,
7099
7303
  InputTextareaModule,
7100
7304
  ToastModule,
7101
- ConfirmDialogModule
7305
+ ConfirmDialogModule,
7306
+ TooltipModule
7102
7307
  ],
7103
7308
  exports: [
7104
7309
  /**
@@ -7176,6 +7381,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
7176
7381
 
7177
7382
  /*
7178
7383
  * Public API Surface of cat-document-lib
7384
+ *
7385
+ * IMPORTANT: To ensure proper z-index values and prevent confirmation dialog visibility issues,
7386
+ * import the global styles in your host project:
7387
+ *
7388
+ * Option 1: In your styles.scss
7389
+ * @import '~cat-document-lib/lib/styles.scss';
7390
+ *
7391
+ * Option 2: In your angular.json
7392
+ * "styles": ["node_modules/cat-document-lib/lib/styles.scss"]
7179
7393
  */
7180
7394
 
7181
7395
  /**