cat-documents-ng 1.0.4 → 1.0.6

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.
Files changed (210) hide show
  1. package/ng-package.json +10 -0
  2. package/package.json +5 -11
  3. package/src/Shared/components/confirmation-dialog/confirmation-dialog.component.html +3 -0
  4. package/src/Shared/components/confirmation-dialog/confirmation-dialog.component.scss +13 -0
  5. package/src/Shared/components/confirmation-dialog/confirmation-dialog.component.spec.ts +70 -0
  6. package/src/Shared/components/confirmation-dialog/confirmation-dialog.component.ts +133 -0
  7. package/src/Shared/components/table-primary/table-primary.component.html +66 -0
  8. package/src/Shared/components/table-primary/table-primary.component.scss +227 -0
  9. package/src/Shared/components/table-primary/table-primary.component.spec.ts +23 -0
  10. package/src/Shared/components/table-primary/table-primary.component.ts +143 -0
  11. package/src/Shared/components/table-primary/table-primary.model.ts +21 -0
  12. package/src/Shared/constant/ERROR.ts +55 -0
  13. package/src/Shared/constant/PERMISSIONS.ts +17 -0
  14. package/src/Shared/constant/SHARED.ts +936 -0
  15. package/{Shared/constant/URLS.d.ts → src/Shared/constant/URLS.ts} +31 -25
  16. package/src/Shared/services/app-config.service.spec.ts +19 -0
  17. package/src/Shared/services/app-config.service.ts +73 -0
  18. package/{Shared/services/global-error.handler.d.ts → src/Shared/services/global-error.handler.ts} +11 -9
  19. package/src/Shared/services/session.service.spec.ts +16 -0
  20. package/src/Shared/services/session.service.ts +76 -0
  21. package/src/Shared/shared.module.ts +25 -0
  22. package/src/lib/document/components/csv-viewer/csv-viewer.component.ts +1 -0
  23. package/src/lib/document/components/document-actions/document-actions.component.html +59 -0
  24. package/src/lib/document/components/document-actions/document-actions.component.scss +362 -0
  25. package/src/lib/document/components/document-actions/document-actions.component.spec.ts +297 -0
  26. package/src/lib/document/components/document-actions/document-actions.component.ts +163 -0
  27. package/src/lib/document/components/document-container/document-container.component.html +36 -0
  28. package/src/lib/document/components/document-container/document-container.component.scss +144 -0
  29. package/src/lib/document/components/document-container/document-container.component.spec.ts +110 -0
  30. package/src/lib/document/components/document-container/document-container.component.ts +363 -0
  31. package/src/lib/document/components/document-content-viewer/document-content-viewer.component.html +332 -0
  32. package/src/lib/document/components/document-content-viewer/document-content-viewer.component.scss +1877 -0
  33. package/src/lib/document/components/document-content-viewer/document-content-viewer.component.spec.ts +258 -0
  34. package/src/lib/document/components/document-content-viewer/document-content-viewer.component.ts +664 -0
  35. package/src/lib/document/components/document-history/document-history.component.html +96 -0
  36. package/src/lib/document/components/document-history/document-history.component.scss +392 -0
  37. package/src/lib/document/components/document-history/document-history.component.spec.ts +93 -0
  38. package/src/lib/document/components/document-history/document-history.component.ts +373 -0
  39. package/src/lib/document/components/document-list/document-list.component.html +46 -0
  40. package/src/lib/document/components/document-list/document-list.component.scss +513 -0
  41. package/src/lib/document/components/document-list/document-list.component.spec.ts +486 -0
  42. package/src/lib/document/components/document-list/document-list.component.ts +682 -0
  43. package/src/lib/document/components/document-list-item/document-list-item.component.html +36 -0
  44. package/src/lib/document/components/document-list-item/document-list-item.component.scss +34 -0
  45. package/src/lib/document/components/document-list-item/document-list-item.component.spec.ts +75 -0
  46. package/src/lib/document/components/document-list-item/document-list-item.component.ts +40 -0
  47. package/src/lib/document/components/document-search/document-search.component.html +64 -0
  48. package/src/lib/document/components/document-search/document-search.component.scss +206 -0
  49. package/src/lib/document/components/document-search/document-search.component.spec.ts +82 -0
  50. package/src/lib/document/components/document-search/document-search.component.ts +163 -0
  51. package/src/lib/document/components/document-status/document-status.component.html +31 -0
  52. package/src/lib/document/components/document-status/document-status.component.scss +192 -0
  53. package/src/lib/document/components/document-status/document-status.component.spec.ts +23 -0
  54. package/src/lib/document/components/document-status/document-status.component.ts +87 -0
  55. package/src/lib/document/components/document-upload/document-upload.component.html +160 -0
  56. package/src/lib/document/components/document-upload/document-upload.component.scss +235 -0
  57. package/src/lib/document/components/document-upload/document-upload.component.spec.ts +95 -0
  58. package/src/lib/document/components/document-upload/document-upload.component.ts +668 -0
  59. package/src/lib/document/components/document-viewer/document-viewer.component.html +50 -0
  60. package/src/lib/document/components/document-viewer/document-viewer.component.scss +187 -0
  61. package/src/lib/document/components/document-viewer/document-viewer.component.spec.ts +79 -0
  62. package/src/lib/document/components/document-viewer/document-viewer.component.ts +261 -0
  63. package/src/lib/document/components/document-zoom-controls/document-zoom-controls.component.html +48 -0
  64. package/src/lib/document/components/document-zoom-controls/document-zoom-controls.component.scss +320 -0
  65. package/src/lib/document/components/document-zoom-controls/document-zoom-controls.component.spec.ts +59 -0
  66. package/src/lib/document/components/document-zoom-controls/document-zoom-controls.component.ts +150 -0
  67. package/src/lib/document/components/documents-menu/documents-menu.component.html +44 -0
  68. package/src/lib/document/components/documents-menu/documents-menu.component.scss +363 -0
  69. package/src/lib/document/components/documents-menu/documents-menu.component.spec.ts +23 -0
  70. package/src/lib/document/components/documents-menu/documents-menu.component.ts +316 -0
  71. package/src/lib/document/components/folder-block/folder-block.component.html +46 -0
  72. package/src/lib/document/components/folder-block/folder-block.component.scss +9 -0
  73. package/src/lib/document/components/folder-block/folder-block.component.spec.ts +70 -0
  74. package/{lib/document/components/folder-block/folder-block.component.d.ts → src/lib/document/components/folder-block/folder-block.component.ts} +28 -12
  75. package/src/lib/document/components/folder-container/folder-container.component.html +56 -0
  76. package/src/lib/document/components/folder-container/folder-container.component.scss +20 -0
  77. package/src/lib/document/components/folder-container/folder-container.component.spec.ts +27 -0
  78. package/src/lib/document/components/folder-container/folder-container.component.ts +328 -0
  79. package/src/lib/document/components/linked-document/linked-document.component.html +23 -0
  80. package/src/lib/document/components/linked-document/linked-document.component.scss +10 -0
  81. package/src/lib/document/components/linked-document/linked-document.component.spec.ts +61 -0
  82. package/src/lib/document/components/linked-document/linked-document.component.ts +49 -0
  83. package/src/lib/document/components/request-document/request-document.component.html +86 -0
  84. package/src/lib/document/components/request-document/request-document.component.scss +16 -0
  85. package/src/lib/document/components/request-document/request-document.component.ts +278 -0
  86. package/src/lib/document/components/sidebar/sidebar.component.html +75 -0
  87. package/src/lib/document/components/sidebar/sidebar.component.scss +157 -0
  88. package/src/lib/document/components/sidebar/sidebar.component.spec.ts +114 -0
  89. package/src/lib/document/components/sidebar/sidebar.component.ts +223 -0
  90. package/src/lib/document/components/user-list/user-list.component.html +33 -0
  91. package/src/lib/document/components/user-list/user-list.component.scss +118 -0
  92. package/src/lib/document/components/user-list/user-list.component.spec.ts +23 -0
  93. package/src/lib/document/components/user-list/user-list.component.ts +181 -0
  94. package/src/lib/document/constant/DOCUMENT_HISTORY.ts +52 -0
  95. package/src/lib/document/directives/document.directive.ts +32 -0
  96. package/src/lib/document/directives/permission.directive.spec.ts +0 -0
  97. package/src/lib/document/directives/permission.directive.ts +72 -0
  98. package/src/lib/document/document.module.ts +351 -0
  99. package/{lib/document/models/document-alert.model.d.ts → src/lib/document/models/document-alert.model.ts} +11 -4
  100. package/src/lib/document/models/document-category.model.ts +30 -0
  101. package/src/lib/document/models/document-history.model.ts +109 -0
  102. package/src/lib/document/models/document-list-response.model.ts +37 -0
  103. package/src/lib/document/models/document-type.model.ts +44 -0
  104. package/src/lib/document/models/document.model.ts +53 -0
  105. package/{lib/document/models/folder.model.d.ts → src/lib/document/models/folder.model.ts} +10 -4
  106. package/src/lib/document/models/status-data.model.ts +31 -0
  107. package/src/lib/document/models/uploaded-file-response.model.ts +7 -0
  108. package/src/lib/document/models/user-list.model.ts +10 -0
  109. package/src/lib/document/services/csv-parser.service.spec.ts +97 -0
  110. package/src/lib/document/services/csv-parser.service.ts +303 -0
  111. package/src/lib/document/services/document-actions.service.ts +125 -0
  112. package/src/lib/document/services/document-content-type.service.ts +193 -0
  113. package/src/lib/document/services/document-history-style.service.ts +138 -0
  114. package/src/lib/document/services/document-history.service.ts +129 -0
  115. package/src/lib/document/services/document-http.service.spec.ts +119 -0
  116. package/src/lib/document/services/document-http.service.ts +497 -0
  117. package/src/lib/document/services/document-list.service.ts +195 -0
  118. package/src/lib/document/services/document-menu.service.ts +277 -0
  119. package/src/lib/document/services/document-scroll.service.ts +138 -0
  120. package/src/lib/document/services/document-severity.service.ts +98 -0
  121. package/src/lib/document/services/document-table-builder.service.ts +82 -0
  122. package/src/lib/document/services/document-upload-business.service.ts +326 -0
  123. package/src/lib/document/services/document-upload-data.service.ts +82 -0
  124. package/src/lib/document/services/document-upload-form.service.ts +149 -0
  125. package/src/lib/document/services/document-upload.service.spec.ts +99 -0
  126. package/src/lib/document/services/document-upload.service.ts +209 -0
  127. package/src/lib/document/services/document-viewer.service.ts +279 -0
  128. package/src/lib/document/services/document-zoom.service.spec.ts +56 -0
  129. package/src/lib/document/services/document-zoom.service.ts +164 -0
  130. package/src/lib/document/services/document.service.ts +356 -0
  131. package/src/lib/document/services/eml-parser.service.ts +444 -0
  132. package/src/lib/document/services/excel-parser.service.spec.ts +66 -0
  133. package/src/lib/document/services/excel-parser.service.ts +483 -0
  134. package/src/lib/document/services/file-format.service.spec.ts +16 -0
  135. package/src/lib/document/services/file-format.service.ts +63 -0
  136. package/src/lib/document/services/status-calculator.service.ts +44 -0
  137. package/src/lib/document/services/user-list.service.ts +77 -0
  138. package/src/lib/document/state/document.query.ts +378 -0
  139. package/{lib/document/state/document.service.d.ts → src/lib/document/state/document.service.ts} +46 -15
  140. package/src/lib/document/state/document.state.ts +100 -0
  141. package/src/lib/document/state/document.store.ts +200 -0
  142. package/{public-api.d.ts → src/public-api.ts} +4 -0
  143. package/tsconfig.lib.json +15 -0
  144. package/tsconfig.lib.prod.json +11 -0
  145. package/tsconfig.spec.json +15 -0
  146. package/Shared/components/confirmation-dialog/confirmation-dialog.component.d.ts +0 -44
  147. package/Shared/components/table-primary/table-primary.component.d.ts +0 -31
  148. package/Shared/components/table-primary/table-primary.model.d.ts +0 -19
  149. package/Shared/constant/ERROR.d.ts +0 -52
  150. package/Shared/constant/SHARED.d.ts +0 -546
  151. package/Shared/services/app-config.service.d.ts +0 -51
  152. package/Shared/services/session.service.d.ts +0 -46
  153. package/Shared/shared.module.d.ts +0 -14
  154. package/fesm2022/cat-documents-ng.mjs +0 -11392
  155. package/fesm2022/cat-documents-ng.mjs.map +0 -1
  156. package/index.d.ts +0 -5
  157. package/lib/document/components/document-actions/document-actions.component.d.ts +0 -78
  158. package/lib/document/components/document-container/document-container.component.d.ts +0 -162
  159. package/lib/document/components/document-content-viewer/document-content-viewer.component.d.ts +0 -291
  160. package/lib/document/components/document-history/document-history.component.d.ts +0 -160
  161. package/lib/document/components/document-list/document-list.component.d.ts +0 -299
  162. package/lib/document/components/document-list-item/document-list-item.component.d.ts +0 -28
  163. package/lib/document/components/document-search/document-search.component.d.ts +0 -77
  164. package/lib/document/components/document-status/document-status.component.d.ts +0 -24
  165. package/lib/document/components/document-upload/document-upload.component.d.ts +0 -321
  166. package/lib/document/components/document-viewer/document-viewer.component.d.ts +0 -137
  167. package/lib/document/components/document-zoom-controls/document-zoom-controls.component.d.ts +0 -33
  168. package/lib/document/components/documents-menu/documents-menu.component.d.ts +0 -110
  169. package/lib/document/components/folder-container/folder-container.component.d.ts +0 -162
  170. package/lib/document/components/linked-document/linked-document.component.d.ts +0 -39
  171. package/lib/document/components/request-document/request-document.component.d.ts +0 -69
  172. package/lib/document/components/sidebar/sidebar.component.d.ts +0 -109
  173. package/lib/document/components/user-list/user-list.component.d.ts +0 -34
  174. package/lib/document/constant/DOCUMENT_HISTORY.d.ts +0 -41
  175. package/lib/document/directives/document.directive.d.ts +0 -20
  176. package/lib/document/directives/permission.directive.d.ts +0 -38
  177. package/lib/document/document.module.d.ts +0 -60
  178. package/lib/document/models/document-category.model.d.ts +0 -24
  179. package/lib/document/models/document-history.model.d.ts +0 -94
  180. package/lib/document/models/document-list-response.model.d.ts +0 -33
  181. package/lib/document/models/document-type.model.d.ts +0 -37
  182. package/lib/document/models/document.model.d.ts +0 -44
  183. package/lib/document/models/status-data.model.d.ts +0 -27
  184. package/lib/document/models/uploaded-file-response.model.d.ts +0 -7
  185. package/lib/document/models/user-list.model.d.ts +0 -8
  186. package/lib/document/services/csv-parser.service.d.ts +0 -88
  187. package/lib/document/services/document-actions.service.d.ts +0 -48
  188. package/lib/document/services/document-content-type.service.d.ts +0 -85
  189. package/lib/document/services/document-history-style.service.d.ts +0 -34
  190. package/lib/document/services/document-history.service.d.ts +0 -42
  191. package/lib/document/services/document-http.service.d.ts +0 -179
  192. package/lib/document/services/document-list.service.d.ts +0 -74
  193. package/lib/document/services/document-menu.service.d.ts +0 -122
  194. package/lib/document/services/document-scroll.service.d.ts +0 -55
  195. package/lib/document/services/document-table-builder.service.d.ts +0 -38
  196. package/lib/document/services/document-upload-business.service.d.ts +0 -107
  197. package/lib/document/services/document-upload-data.service.d.ts +0 -40
  198. package/lib/document/services/document-upload-form.service.d.ts +0 -41
  199. package/lib/document/services/document-upload.service.d.ts +0 -99
  200. package/lib/document/services/document-viewer.service.d.ts +0 -97
  201. package/lib/document/services/document-zoom.service.d.ts +0 -81
  202. package/lib/document/services/document.service.d.ts +0 -161
  203. package/lib/document/services/eml-parser.service.d.ts +0 -116
  204. package/lib/document/services/excel-parser.service.d.ts +0 -169
  205. package/lib/document/services/file-format.service.d.ts +0 -34
  206. package/lib/document/services/status-calculator.service.d.ts +0 -20
  207. package/lib/document/services/user-list.service.d.ts +0 -29
  208. package/lib/document/state/document.query.d.ts +0 -243
  209. package/lib/document/state/document.state.d.ts +0 -61
  210. package/lib/document/state/document.store.d.ts +0 -56
@@ -0,0 +1,61 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+ import { LinkedDocumentComponent } from './linked-document.component';
3
+ import { DocumentModel } from '../../models/document.model';
4
+ import { Component, Input } from '@angular/core';
5
+
6
+ /**
7
+ * A mock child component used for testing the LinkedDocumentComponent.
8
+ * It mimics a real child component that receives document-related inputs.
9
+ */
10
+ @Component({
11
+ selector: 'app-mock-child',
12
+ template: ''
13
+ })
14
+ class MockChildComponent {
15
+ /**
16
+ * Represents the currently selected document.
17
+ */
18
+ @Input() selectedDocument?: DocumentModel;
19
+
20
+ /**
21
+ * A list of available documents.
22
+ */
23
+ @Input() documentList?: DocumentModel[];
24
+ }
25
+
26
+ describe('LinkedDocumentComponent', () => {
27
+ let component: LinkedDocumentComponent;
28
+ let fixture: ComponentFixture<LinkedDocumentComponent>;
29
+
30
+ beforeEach(async () => {
31
+ await TestBed.configureTestingModule({
32
+ declarations: [LinkedDocumentComponent],
33
+ }).compileComponents();
34
+ });
35
+
36
+ beforeEach(() => {
37
+ fixture = TestBed.createComponent(LinkedDocumentComponent);
38
+ component = fixture.componentInstance;
39
+ fixture.detectChanges();
40
+ });
41
+
42
+ /**
43
+ * Ensures that the component is created successfully.
44
+ */
45
+ it('should create', () => {
46
+ expect(component).toBeTruthy();
47
+ });
48
+
49
+ /**
50
+ * Tests whether the `handleDocumentClick` method correctly emits
51
+ * the `selectedDocumentChange` event with the expected document data.
52
+ */
53
+ it('should emit selectedDocumentChange event when handleDocumentClick is called', () => {
54
+ spyOn(component.selectedDocumentChange, 'emit');
55
+ const document: DocumentModel = { _id: '1', fileName: 'Doc1' };
56
+
57
+ component.handleDocumentClick(document);
58
+
59
+ expect(component.selectedDocumentChange.emit).toHaveBeenCalledWith(document);
60
+ });
61
+ });
@@ -0,0 +1,49 @@
1
+ import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core';
2
+ import { DocumentQuery } from '../../state/document.query';
3
+ import { DocumentModel } from '../../models/document.model';
4
+ import { DocumentListItem } from '../../models/document-list-response.model';
5
+ /**
6
+ * Description placeholder
7
+ * @class LinkedDocumentComponent
8
+ * @typedef {LinkedDocumentComponent}
9
+ * @implements {OnChanges}
10
+ */
11
+ @Component({
12
+ selector: 'app-linked-document',
13
+ templateUrl: './linked-document.component.html',
14
+ styleUrl: './linked-document.component.scss',
15
+ standalone : false
16
+ })
17
+ export class LinkedDocumentComponent {
18
+ /**
19
+ * Selected document for view.
20
+ * @type {?DocumentModel}
21
+ */
22
+ @Input() selectedDocument?: DocumentListItem;
23
+ /**
24
+ * Whole document list.
25
+ * @type {?DocumentModel[]}
26
+ */
27
+ @Input() documentList?: DocumentListItem[];
28
+ /**
29
+ * Changed selected document.
30
+ * @type {*}
31
+ */
32
+ @Output() selectedDocumentChange = new EventEmitter<DocumentListItem>();
33
+
34
+ /**
35
+ * Filtered documents.
36
+ * @type {DocumentModel[]}
37
+ */
38
+ filteredDocuments: DocumentModel[] = [];
39
+
40
+ /**
41
+ * Handle the click on the document.
42
+ * @param {DocumentModel} document - Clicked document.
43
+ */
44
+ handleDocumentClick(document: DocumentListItem): void {
45
+ this.selectedDocument = document;
46
+ this.selectedDocumentChange.emit(this.selectedDocument);
47
+ }
48
+
49
+ }
@@ -0,0 +1,86 @@
1
+ <div class="document-upload-container">
2
+ <!-- Assignment Section (same structure as upload, without files) -->
3
+ <div class="assignment-section">
4
+ <h4>Assign to Applicant(s) or Application <span class="text-red-500">*</span> </h4>
5
+ <div class="radio-group">
6
+ <div class="radio-item">
7
+ <p-radioButton
8
+ name="assignmentType"
9
+ value="Applicant"
10
+ [(ngModel)]="selectedAssignmentType"
11
+ (onClick)="onAssignmentTypeChange()"
12
+ [inputId]="'req-applicant'"
13
+ ></p-radioButton>
14
+ <label [for]="'req-applicant'" class="radio-label">Applicant(s)</label>
15
+ </div>
16
+ <div class="radio-item">
17
+ <p-radioButton
18
+ name="assignmentType"
19
+ value="Application"
20
+ [(ngModel)]="selectedAssignmentType"
21
+ (onClick)="onAssignmentTypeChange()"
22
+ [inputId]="'req-application'"
23
+ ></p-radioButton>
24
+ <label [for]="'req-application'" class="radio-label">Application</label>
25
+ </div>
26
+ </div>
27
+ </div>
28
+
29
+ <!-- Applicant Selection (only when Applicant is selected) -->
30
+ <div class="applicant-section" *ngIf="selectedAssignmentType === 'Applicant'">
31
+ <h4>Select Applicant(s) <span class="text-red-500">*</span></h4>
32
+ <div class="grid">
33
+ <div
34
+ *ngFor="let applicant of filteredApplicantList"
35
+ class="applicant-item col-12 md:col-6"
36
+ >
37
+ <p-radioButton
38
+ name="reqSelectedApplicant"
39
+ [value]="applicant._id"
40
+ [(ngModel)]="selectedApplicant"
41
+ [inputId]="'req-applicant-' + applicant._id"
42
+ (onClick)="onApplicantSelectionChange()"
43
+ ></p-radioButton>
44
+ <label [for]="'req-applicant-' + applicant._id" class="applicant-label">
45
+ {{ applicant.name }}
46
+ </label>
47
+ </div>
48
+ </div>
49
+ </div>
50
+
51
+ <!-- Category Selection -->
52
+ <div class="category-section">
53
+ <h4>Category <span class="text-red-500">*</span></h4>
54
+ <p-dropdown
55
+ [options]="categoryOptions"
56
+ [(ngModel)]="selectedCategory"
57
+ placeholder="Select Category type"
58
+ optionLabel="label"
59
+ optionValue="_id"
60
+ (onChange)="onCategoryChange()"
61
+ [disabled]="!categoryOptions.length"
62
+ class="w-full"
63
+ ></p-dropdown>
64
+ </div>
65
+
66
+ <!-- Document Type Selection -->
67
+ <div class="document-type-section">
68
+ <h4>Document Type <span class="text-red-500">*</span></h4>
69
+ <p-dropdown
70
+ [options]="documentTypeOptions"
71
+ [(ngModel)]="selectedDocumentType"
72
+ placeholder="Select Document type"
73
+ optionLabel="label"
74
+ optionValue="_id"
75
+ (onChange)="onDocumentTypeChange()"
76
+ [disabled]="!documentTypeOptions.length || !selectedCategory"
77
+ class="w-full"
78
+ ></p-dropdown>
79
+ </div>
80
+
81
+ <!-- Description Field -->
82
+ <div class="description-section">
83
+ <h6>Description <span class="text-red-500">*</span></h6>
84
+ <textarea pInputTextarea [(ngModel)]="description" (ngModelChange)="onDescriptionChange()" rows="4" placeholder="Add description" class="w-full"></textarea>
85
+ </div>
86
+ </div>
@@ -0,0 +1,16 @@
1
+ .request-document-form {
2
+ .form-row {
3
+ display: flex;
4
+ flex-direction: column;
5
+ margin-bottom: 1rem;
6
+ }
7
+ label {
8
+ font-weight: 600;
9
+ margin-bottom: 0.5rem;
10
+ }
11
+ select, textarea {
12
+ padding: 0.5rem;
13
+ }
14
+ }
15
+
16
+
@@ -0,0 +1,278 @@
1
+ import { ChangeDetectorRef, Component, EventEmitter, Input, OnDestroy, OnInit, Output, SimpleChanges, OnChanges } from '@angular/core';
2
+ import { SHARED } from '../../../../Shared/constant/SHARED';
3
+ import { Subject, takeUntil } from 'rxjs';
4
+ import { UserListModel } from '../../models/user-list.model';
5
+ import { DocumentCategory } from '../../models/document-category.model';
6
+ import { DocumentTypeModel } from '../../models/document-type.model';
7
+ import { DocumentUploadService } from '../../services/document-upload.service';
8
+ import { DocumentUploadFormService } from '../../services/document-upload-form.service';
9
+ import { DocumentUploadDataService } from '../../services/document-upload-data.service';
10
+ import { DocumentHttpService } from '../../services/document-http.service';
11
+ import { SessionService } from '../../../../Shared/services/session.service';
12
+
13
+ @Component({
14
+ selector: 'lib-request-document',
15
+ templateUrl: './request-document.component.html',
16
+ standalone: false
17
+ })
18
+ export class RequestDocumentComponent implements OnInit, OnChanges, OnDestroy {
19
+ @Input() contextId: string = SHARED.EMPTY;
20
+ @Input() isRequestSaveBtnClicked: boolean = false;
21
+ @Input() isRequestSidebarClosed: boolean = false;
22
+
23
+ @Output() onFormValidationChange = new EventEmitter<void>();
24
+ @Output() onRequestSuccess = new EventEmitter<void>();
25
+ @Output() onRequestError = new EventEmitter<any>();
26
+ @Output() hasUnsavedChangesChange = new EventEmitter<boolean>();
27
+
28
+ selectedAssignmentType: 'Applicant' | 'Application' | null = null;
29
+ selectedApplicant: string = SHARED.EMPTY;
30
+ selectedCategory: string = SHARED.EMPTY;
31
+ selectedDocumentType: string = SHARED.EMPTY;
32
+ description: string = SHARED.EMPTY;
33
+
34
+ applicantList: UserListModel[] = SHARED.EMPTY_ARRAY;
35
+ filteredApplicantList: UserListModel[] = SHARED.EMPTY_ARRAY;
36
+ categoryOptions: DocumentCategory[] = SHARED.EMPTY_ARRAY;
37
+ documentTypeOptions: DocumentTypeModel[] = SHARED.EMPTY_ARRAY;
38
+
39
+ isLoadingApplicants: boolean = false;
40
+ isLoadingCategories: boolean = false;
41
+ isLoadingDocumentTypes: boolean = false;
42
+ isSaving: boolean = false;
43
+ isFormValid: boolean = false;
44
+
45
+ private destroy$ = new Subject<void>();
46
+
47
+ constructor(
48
+ public documentUpload: DocumentUploadService,
49
+ private formService: DocumentUploadFormService,
50
+ private dataService: DocumentUploadDataService,
51
+ private cdr: ChangeDetectorRef,
52
+ private documentHttpService : DocumentHttpService,
53
+ private sessionService: SessionService
54
+ ) {}
55
+
56
+ ngOnInit(): void {
57
+ this.resetForm();
58
+ }
59
+
60
+ ngOnChanges(changes: SimpleChanges): void {
61
+ if (changes['isRequestSaveBtnClicked'] && changes['isRequestSaveBtnClicked'].currentValue) {
62
+ this.saveRequestDocument();
63
+ }
64
+ if (changes['isRequestSidebarClosed'] && changes['isRequestSidebarClosed'].currentValue) {
65
+ if (this.isRequestSidebarClosed) {
66
+ this.resetForm();
67
+ }
68
+ }
69
+ }
70
+
71
+ onAssignmentTypeChange(): void {
72
+ this.resetSelections();
73
+ this.loadCategories();
74
+ // Always ensure applicants are loaded; filtering will apply based on assignment type
75
+ this.loadApplicants();
76
+ this.validateAndEmit();
77
+ this.emitUnsavedChanges();
78
+ }
79
+
80
+ onCategoryChange(): void {
81
+ this.resetDocumentType();
82
+ if (this.selectedCategory) this.loadDocumentTypes();
83
+ this.validateAndEmit();
84
+ this.emitUnsavedChanges();
85
+ }
86
+
87
+ onDocumentTypeChange(): void { this.validateAndEmit(); this.emitUnsavedChanges(); }
88
+ onApplicantSelectionChange(): void { this.validateAndEmit(); this.emitUnsavedChanges(); }
89
+ onDescriptionChange(): void { this.validateAndEmit(); this.emitUnsavedChanges(); }
90
+
91
+ loadApplicants(): void {
92
+ this.isLoadingApplicants = true;
93
+ this.dataService.loadApplicants(
94
+ this.contextId,
95
+ (applicants) => this.handleApplicantsLoaded(applicants),
96
+ (error) => this.handleError('Failed to Load Applicants', error, () => this.isLoadingApplicants = false)
97
+ ).pipe(takeUntil(this.destroy$)).subscribe({
98
+ next: (applicants) => {
99
+ // When assignment type is not yet selected, just cache the list
100
+ if (!this.selectedAssignmentType) {
101
+ this.applicantList = applicants;
102
+ this.filteredApplicantList = applicants;
103
+ this.isLoadingApplicants = false;
104
+ return;
105
+ }
106
+ this.handleApplicantsLoaded(applicants);
107
+ },
108
+ error: (error) => this.handleError('Failed to Load Applicants', error, () => this.isLoadingApplicants = false)
109
+ });
110
+ }
111
+
112
+ loadCategories(): void {
113
+ this.isLoadingCategories = true;
114
+ this.dataService.loadCategories(
115
+ this.selectedAssignmentType!,
116
+ (categories) => this.handleCategoriesLoaded(categories),
117
+ (error) => this.handleError('Failed to Load Categories', error, () => this.isLoadingCategories = false)
118
+ ).pipe(takeUntil(this.destroy$)).subscribe({
119
+ next: (categories) => this.handleCategoriesLoaded(categories),
120
+ error: (error) => this.handleError('Failed to Load Categories', error, () => this.isLoadingCategories = false)
121
+ });
122
+ }
123
+
124
+ loadDocumentTypes(): void {
125
+ this.isLoadingDocumentTypes = true;
126
+ this.dataService.loadDocumentTypes(
127
+ this.selectedCategory,
128
+ (documentTypes) => this.handleDocumentTypesLoaded(documentTypes),
129
+ (error) => this.handleError('Failed to Load Document Types', error, () => this.isLoadingDocumentTypes = false)
130
+ ).pipe(takeUntil(this.destroy$)).subscribe({
131
+ next: (documentTypes) => this.handleDocumentTypesLoaded(documentTypes),
132
+ error: (error) => this.handleError('Failed to Load Document Types', error, () => this.isLoadingDocumentTypes = false)
133
+ });
134
+ }
135
+
136
+ getSaveButtonDisabled(): boolean {
137
+ return !this.isFormValid || this.isSaving;
138
+ }
139
+
140
+ saveRequestDocument(): void {
141
+ if (!this.isFormValid) {
142
+ this.formService.showWarningMessage('Incomplete Form', 'Please complete all required fields.');
143
+ return;
144
+ }
145
+ if (!this.description || !this.description.trim()) {
146
+ this.formService.showWarningMessage('Description Required', 'Please add a description.');
147
+ return;
148
+ }
149
+ // build request payload expected by backend
150
+ const requestedDocumentForId = this.selectedAssignmentType === SHARED.APPLICANT
151
+ ? this.selectedApplicant
152
+ : this.contextId;
153
+ const requesterId = this.sessionService.getUserSession()?.accountId;
154
+ const requestPayload = {
155
+ applicationId: this.contextId,
156
+ requestedDocumentForId: requestedDocumentForId,
157
+ requestedDocumentType: this.selectedDocumentType,
158
+ requesterId: requesterId,
159
+ selectedAssignmentType: this.selectedAssignmentType,
160
+ description: this.description.trim()
161
+ };
162
+
163
+ this.isSaving = true;
164
+ this.documentHttpService.documentRequest(requestPayload).subscribe({
165
+ next: () => {
166
+ this.isSaving = false;
167
+ this.onRequestSuccess.emit();
168
+ this.resetForm();
169
+ },
170
+ error: (error) => {
171
+ this.isSaving = false;
172
+ this.onRequestError.emit(error);
173
+ }
174
+ });
175
+ }
176
+
177
+ resetForm(): void {
178
+ this.selectedAssignmentType = null;
179
+ this.selectedApplicant = SHARED.EMPTY;
180
+ this.selectedCategory = SHARED.EMPTY;
181
+ this.selectedDocumentType = SHARED.EMPTY;
182
+ this.description = SHARED.EMPTY;
183
+ this.filteredApplicantList = [];
184
+ this.categoryOptions = [];
185
+ this.documentTypeOptions = [];
186
+ this.isSaving = false;
187
+ this.isFormValid = false;
188
+ this.cdr.detectChanges();
189
+ this.hasUnsavedChangesChange.emit(false);
190
+ }
191
+
192
+ resetSelections(): void {
193
+ this.selectedApplicant = this.selectedCategory = this.selectedDocumentType = SHARED.EMPTY;
194
+ this.documentTypeOptions = SHARED.EMPTY_ARRAY;
195
+ }
196
+
197
+ resetDocumentType(): void {
198
+ this.selectedDocumentType = SHARED.EMPTY;
199
+ this.documentTypeOptions = SHARED.EMPTY_ARRAY;
200
+ }
201
+
202
+ handleApplicantLoading(): void {
203
+ if (this.selectedAssignmentType === SHARED.APPLICANT) {
204
+ this.loadApplicants();
205
+ } else {
206
+ this.filterApplicants();
207
+ }
208
+ }
209
+
210
+ handleApplicantsLoaded(applicants: UserListModel[]): void {
211
+ this.applicantList = this.documentUpload.sortListByProperty(applicants, 'name');
212
+ this.filterApplicants();
213
+ this.isLoadingApplicants = false;
214
+ this.validateForm();
215
+ }
216
+
217
+ handleCategoriesLoaded(categories: DocumentCategory[]): void {
218
+ this.categoryOptions = this.documentUpload.sortListByProperty(categories, 'label');
219
+ this.isLoadingCategories = false;
220
+ this.validateForm();
221
+ }
222
+
223
+ handleDocumentTypesLoaded(documentTypes: DocumentTypeModel[]): void {
224
+ this.documentTypeOptions = this.documentUpload.sortListByProperty(documentTypes, 'label', 'name');
225
+ this.isLoadingDocumentTypes = false;
226
+ this.validateForm();
227
+ }
228
+
229
+ filterApplicants(): void {
230
+ this.filteredApplicantList = this.dataService.handleApplicantsLoaded(
231
+ this.applicantList, this.selectedAssignmentType
232
+ );
233
+ }
234
+
235
+ validateForm(): void {
236
+ const baseValid = Boolean(
237
+ this.selectedAssignmentType &&
238
+ this.selectedCategory &&
239
+ this.selectedDocumentType &&
240
+ this.description && this.description.trim()
241
+ );
242
+ const needsApplicant = this.selectedAssignmentType === SHARED.APPLICANT;
243
+ const hasRequiredFields = needsApplicant ? (baseValid && !!this.selectedApplicant) : baseValid;
244
+ const previousState = this.isFormValid;
245
+ this.isFormValid = hasRequiredFields;
246
+ if (previousState !== this.isFormValid) {
247
+ this.onFormValidationChange.emit();
248
+ }
249
+ }
250
+
251
+ validateAndEmit(): void {
252
+ this.validateForm();
253
+ this.onFormValidationChange.emit();
254
+ }
255
+
256
+ /** Emits unsaved changes state based on any field being non-empty */
257
+ private emitUnsavedChanges(): void {
258
+ const hasChanges = Boolean(
259
+ (this.selectedAssignmentType && this.selectedAssignmentType !== SHARED.EMPTY) ||
260
+ (this.selectedApplicant && this.selectedApplicant !== SHARED.EMPTY) ||
261
+ (this.selectedCategory && this.selectedCategory !== SHARED.EMPTY) ||
262
+ (this.selectedDocumentType && this.selectedDocumentType !== SHARED.EMPTY) ||
263
+ (this.description && this.description.trim() !== SHARED.EMPTY)
264
+ );
265
+ this.hasUnsavedChangesChange.emit(hasChanges);
266
+ }
267
+
268
+ handleError(_title: string, _error: any, resetLoading: () => void): void {
269
+ resetLoading();
270
+ }
271
+
272
+ ngOnDestroy(): void {
273
+ this.destroy$.next();
274
+ this.destroy$.complete();
275
+ }
276
+ }
277
+
278
+
@@ -0,0 +1,75 @@
1
+ <!-- PrimeNG Sidebar with proper backdrop handling -->
2
+ <div *ngIf="visible" class="backdrop-shadow" (click)="handleClose()"></div>
3
+
4
+ <p-sidebar
5
+ [(visible)]="visible"
6
+ [position]="position"
7
+ [style]="{width: width}"
8
+ [dismissible]="true"
9
+ [showCloseIcon]="false"
10
+ [appendTo]="'body'"
11
+ [blockScroll]="blockScroll"
12
+ (visibleChange)="onVisibleChange($event)"
13
+ (onShow)="onShow.emit()"
14
+ (onHide)="onSidebarHide()"
15
+ >
16
+ <ng-template pTemplate="header" *ngIf="title || showCloseButton || showSaveButton">
17
+ <div class="sidebar-header">
18
+ <h3 *ngIf="title" class="sidebar-title">{{ title }}</h3>
19
+ <div class="header-content">
20
+ <ng-content select="[header]"></ng-content>
21
+
22
+ <p-messages
23
+ *ngIf="showSuccessMessage"
24
+ severity="success"
25
+ [closable]="false"
26
+ [style]="{'margin-bottom': '0.5rem'}"
27
+ class="ml-3"
28
+ >
29
+ <ng-template pTemplate="message">
30
+ <span>{{ successMessage }}</span>
31
+ </ng-template>
32
+ </p-messages>
33
+
34
+ <p-messages
35
+ *ngIf="showErrorMessage"
36
+ severity="error"
37
+ [closable]="false"
38
+ [style]="{'margin-bottom': '0.5rem'}"
39
+ class="ml-3"
40
+ >
41
+ <ng-template pTemplate="message">
42
+ <span>{{ errorMessage }}</span>
43
+ </ng-template>
44
+ </p-messages>
45
+
46
+ <div class="header-actions mr-3">
47
+ <button
48
+ *ngIf="showSaveButton"
49
+ pButton
50
+ type="button"
51
+ [label]="saveButtonText"
52
+ [disabled]="saveButtonDisabled"
53
+ class="p-button-primary"
54
+ (click)="onSave.emit()"
55
+ ></button>
56
+
57
+ <button
58
+ *ngIf="showCloseButton"
59
+ pButton
60
+ type="button"
61
+ icon="pi pi-times"
62
+ class="p-button-text p-button-rounded"
63
+ (click)="handleClose()"
64
+ ></button>
65
+ </div>
66
+ </div>
67
+ </div>
68
+ </ng-template>
69
+
70
+ <ng-template pTemplate="content">
71
+ <div class="sidebar-content">
72
+ <ng-content></ng-content>
73
+ </div>
74
+ </ng-template>
75
+ </p-sidebar>