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,157 @@
1
+ :host {
2
+ display: block;
3
+ }
4
+ .backdrop-shadow {
5
+ position: fixed;
6
+ top: 0;
7
+ left: 0;
8
+ width: 100%;
9
+ height: 100%;
10
+ background: rgba(0, 0, 0, 0.5);
11
+ /* Shadow effect */
12
+ z-index: 1000;
13
+ /* Ensure it appears below the sidebar */
14
+ }
15
+ .sidebar-header {
16
+ display: flex;
17
+ justify-content: flex-end;
18
+ align-items: center;
19
+ padding: 0;
20
+ width: 100%;
21
+ gap: 1rem;
22
+ ::ng-deep{
23
+ .p-messages{
24
+ .p-message-success{
25
+ margin-left: 2rem;
26
+ font-size: 15px;
27
+ }
28
+ .p-message-wrapper{
29
+ padding: 1rem 1rem;
30
+
31
+ }
32
+ }
33
+ }
34
+ }
35
+
36
+ .sidebar-title {
37
+ margin: 0;
38
+ font-size: 1.25rem;
39
+ font-weight: 600;
40
+ color: #212529;
41
+ flex: 0 1 auto;
42
+ white-space: nowrap;
43
+ min-width: 0;
44
+ }
45
+
46
+ .header-content {
47
+ display: flex;
48
+ align-items: center;
49
+ gap: 1rem;
50
+ justify-content: space-between;
51
+ width: 100%;
52
+ }
53
+
54
+ .header-actions {
55
+ display: flex;
56
+ align-items: center;
57
+ gap: 0.5rem;
58
+ margin-left: auto;
59
+ margin-right: 0;
60
+ }
61
+
62
+ .close-button {
63
+ background: none;
64
+ border: none;
65
+ color: #6c757d;
66
+ cursor: pointer;
67
+ padding: 0.5rem;
68
+ border-radius: 0.375rem;
69
+ transition: all 0.2s ease;
70
+ display: flex;
71
+ align-items: center;
72
+ justify-content: center;
73
+ min-width: 2rem;
74
+ min-height: 2rem;
75
+ margin-right: 0.5rem;
76
+
77
+ &:hover {
78
+ background-color: #e9ecef;
79
+ color: #495057;
80
+ }
81
+
82
+ &:focus {
83
+ outline: none;
84
+ box-shadow: 0 0 0 3px rgba(15, 139, 253, 0.3);
85
+ }
86
+
87
+ i {
88
+ font-size: 1rem;
89
+ }
90
+ }
91
+
92
+ .sidebar-content {
93
+ height: 100%;
94
+ overflow-y: auto;
95
+ padding: 0;
96
+ }
97
+
98
+ /* Custom close button styles */
99
+ .header-actions {
100
+ .p-button-text.p-button-rounded {
101
+ width: 2rem;
102
+ height: 2rem;
103
+ border-radius: 50%;
104
+
105
+ &:hover {
106
+ background-color: rgba(0, 0, 0, 0.1);
107
+ }
108
+ }
109
+ }
110
+
111
+ // Custom PrimeNG Sidebar Styles
112
+ ::ng-deep {
113
+ .p-sidebar {
114
+ .p-sidebar-header {
115
+ // padding: 1.5rem 1.5rem 0 1.5rem;
116
+ border-bottom: 1px solid #e9ecef;
117
+ margin-bottom: 1rem;
118
+ background-color: #f8f9fa;
119
+ }
120
+
121
+ .p-sidebar-content {
122
+ padding: 0 1.5rem 1.5rem 1.5rem;
123
+ height: calc(100% - 80px);
124
+ overflow-y: auto;
125
+ }
126
+
127
+ &.p-sidebar-right {
128
+ .p-sidebar-content {
129
+ padding-left: 1.5rem;
130
+ padding-right: 1.5rem;
131
+ }
132
+ }
133
+
134
+ &.p-sidebar-left {
135
+ .p-sidebar-content {
136
+ padding-left: 1.5rem;
137
+ padding-right: 1.5rem;
138
+ }
139
+ }
140
+ }
141
+
142
+ // Responsive adjustments
143
+ @media (max-width: 768px) {
144
+ .p-sidebar {
145
+ width: 100% !important;
146
+ max-width: 100% !important;
147
+
148
+ .p-sidebar-header {
149
+ padding: 1rem 1rem 0 1rem;
150
+ }
151
+
152
+ .p-sidebar-content {
153
+ padding: 0 1rem 1rem 1rem;
154
+ }
155
+ }
156
+ }
157
+ }
@@ -0,0 +1,114 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+ import { SidebarComponent } from './sidebar.component';
3
+ import { SidebarModule } from 'primeng/sidebar';
4
+ import { ConfirmDialogModule } from 'primeng/confirmdialog';
5
+ import { ConfirmationService } from 'primeng/api';
6
+ import { Injector } from '@angular/core';
7
+
8
+ describe('SidebarComponent', () => {
9
+ let component: SidebarComponent;
10
+ let fixture: ComponentFixture<SidebarComponent>;
11
+ let mockConfirmationService: jasmine.SpyObj<ConfirmationService>;
12
+ let mockInjector: jasmine.SpyObj<Injector>;
13
+
14
+ beforeEach(async () => {
15
+ mockConfirmationService = jasmine.createSpyObj('ConfirmationService', ['confirm']);
16
+ mockInjector = jasmine.createSpyObj('Injector', ['get']);
17
+ mockInjector.get.and.returnValue(mockConfirmationService);
18
+
19
+ await TestBed.configureTestingModule({
20
+ declarations: [ SidebarComponent ],
21
+ imports: [ SidebarModule, ConfirmDialogModule ],
22
+ providers: [
23
+ ConfirmationService
24
+ ]
25
+ })
26
+ .compileComponents();
27
+ });
28
+
29
+ beforeEach(() => {
30
+ fixture = TestBed.createComponent(SidebarComponent);
31
+ component = fixture.componentInstance;
32
+
33
+ // Mock the injector
34
+ (component as any).injector = mockInjector;
35
+ (component as any).confirmationService = mockConfirmationService;
36
+
37
+ fixture.detectChanges();
38
+ });
39
+
40
+ it('should create', () => {
41
+ expect(component).toBeTruthy();
42
+ });
43
+
44
+ it('should open sidebar when open() is called', () => {
45
+ component.open();
46
+ expect(component.visible).toBe(true);
47
+ });
48
+
49
+ it('should close sidebar when close() is called', () => {
50
+ component.visible = true;
51
+ component.close();
52
+ expect(component.visible).toBe(false);
53
+ });
54
+
55
+ it('should show confirmation dialog when close button is clicked with unsaved changes', () => {
56
+ component.visible = true;
57
+ component.hasUnsavedChanges = true;
58
+
59
+ component.handleClose();
60
+
61
+ expect(mockConfirmationService.confirm).toHaveBeenCalled();
62
+ expect(component.visible).toBe(true); // Should still be open
63
+ });
64
+
65
+ it('should close sidebar when close button is clicked without unsaved changes', () => {
66
+ component.visible = true;
67
+ component.hasUnsavedChanges = false;
68
+
69
+ component.handleClose();
70
+
71
+ expect(component.visible).toBe(false);
72
+ expect(mockConfirmationService.confirm).not.toHaveBeenCalled();
73
+ });
74
+
75
+ it('should close and emit onClose when confirmation is accepted', () => {
76
+ component.visible = true;
77
+ component.hasUnsavedChanges = true;
78
+
79
+ // Simulate confirmation accepted
80
+ mockConfirmationService.confirm.and.callFake((options: any) => {
81
+ options.accept();
82
+ });
83
+
84
+ spyOn(component.onClose, 'emit');
85
+ component.handleClose();
86
+
87
+ expect(component.visible).toBe(false);
88
+ expect(mockConfirmationService.confirm).toHaveBeenCalled();
89
+ expect(component.onClose.emit).toHaveBeenCalled();
90
+ });
91
+
92
+ it('should keep sidebar open when confirmation is rejected', () => {
93
+ component.visible = true;
94
+ component.hasUnsavedChanges = true;
95
+
96
+ // Simulate confirmation rejected
97
+ mockConfirmationService.confirm.and.callFake((options: any) => {
98
+ options.reject();
99
+ });
100
+
101
+ component.handleClose();
102
+
103
+ expect(component.visible).toBe(true);
104
+ expect(mockConfirmationService.confirm).toHaveBeenCalled();
105
+ });
106
+
107
+ it('should check for unsaved changes correctly', () => {
108
+ component.hasUnsavedChanges = true;
109
+ expect(component.checkForUnsavedChanges()).toBe(true);
110
+
111
+ component.hasUnsavedChanges = false;
112
+ expect(component.checkForUnsavedChanges()).toBe(false);
113
+ });
114
+ });
@@ -0,0 +1,223 @@
1
+ import { Component, Input, Output, EventEmitter, OnDestroy, HostListener } from '@angular/core';
2
+ import { SHARED } from '../../../../Shared/constant/SHARED';
3
+ import { Subject } from 'rxjs';
4
+ import { ConfirmationService } from 'primeng/api';
5
+ import { ConfirmationDialogComponent } from '../../../../Shared/components/confirmation-dialog/confirmation-dialog.component';
6
+
7
+ // Interface for confirmation options
8
+ interface ConfirmationOptions {
9
+ message: string;
10
+ header?: string;
11
+ icon?: string;
12
+ acceptLabel?: string;
13
+ rejectLabel?: string;
14
+ acceptIcon?: string;
15
+ rejectIcon?: string;
16
+ acceptButtonClass?: string;
17
+ rejectButtonClass?: string;
18
+ }
19
+
20
+ @Component({
21
+ selector: 'lib-sidebar',
22
+ templateUrl: './sidebar.component.html',
23
+ styleUrls: ['./sidebar.component.scss'],
24
+ standalone: false
25
+ })
26
+ export class SidebarComponent implements OnDestroy {
27
+ // Flag to prevent multiple confirmations
28
+ private isShowingConfirmation: boolean = false;
29
+
30
+ @Input() set visible(value: boolean) {
31
+ this._visible = value;
32
+ }
33
+
34
+ get visible(): boolean {
35
+ return this._visible;
36
+ }
37
+
38
+ private _visible: boolean = false;
39
+
40
+ @Input() position: 'left' | 'right' = 'right';
41
+ @Input() width: string = SHARED.WIDTH;
42
+ @Input() title: string = SHARED.EMPTY;
43
+ @Input() showCloseButton: boolean = true;
44
+ @Input() modal: boolean = true;
45
+ @Input() dismissible: boolean = true;
46
+ @Input() styleClass: string = SHARED.EMPTY;
47
+ @Input() appendTo: string = 'body';
48
+ @Input() blockScroll: boolean = true;
49
+ @Input() closeIcon: string = SHARED.CLOSE_ICON;
50
+ @Input() showSaveButton: boolean = false;
51
+ @Input() saveButtonText: string = SHARED.SAVE;
52
+ @Input() saveButtonDisabled: boolean = false;
53
+ @Input() successMessage: string = SHARED.SUCCESS_MESSAGE;
54
+ @Input() errorMessage: string = SHARED.EMPTY;
55
+ @Input() hasUnsavedChanges: boolean = false;
56
+
57
+ @Output() visibleChange = new EventEmitter<boolean>();
58
+ @Output() onShow = new EventEmitter<void>();
59
+ @Output() onHide = new EventEmitter<void>();
60
+ @Output() onSave = new EventEmitter<void>();
61
+ @Output() onClose = new EventEmitter<void>();
62
+
63
+ showSuccessMessage: boolean = false;
64
+ showErrorMessage: boolean = false;
65
+ private destroy$ = new Subject<void>();
66
+
67
+ unsavedChangesConfirmationOptions: ConfirmationOptions = {
68
+ message: SHARED.UNSAVED_CHANGES_MESSAGE,
69
+ acceptLabel: SHARED.YES,
70
+ rejectLabel: SHARED.NO,
71
+ acceptIcon: SHARED.ACCEPT_ICON,
72
+ rejectIcon: SHARED.REJECT_ICON,
73
+ acceptButtonClass: SHARED.ACCEPT_BUTTON_STYLE_CLASS,
74
+ rejectButtonClass: SHARED.REJECT_BUTTON_STYLE_CLASS
75
+ };
76
+
77
+ constructor(private confirmationService: ConfirmationService) {}
78
+
79
+ /**
80
+ * Handles the onHide event from PrimeNG sidebar
81
+ * Only emits when actually closing, not when showing confirmation
82
+ */
83
+ onSidebarHide(): void {
84
+ if (!this.isShowingConfirmation) {
85
+ this.onHide.emit();
86
+ }
87
+ }
88
+
89
+ /**
90
+ * Handles the visibleChange event from PrimeNG sidebar
91
+ * Intercepts automatic closing to show confirmation if needed
92
+ */
93
+ onVisibleChange(value: boolean): void {
94
+ if (!value && this.hasUnsavedChanges && !this.isShowingConfirmation) {
95
+ this._visible = true;
96
+ this.showUnsavedChangesConfirmation();
97
+ return;
98
+ }
99
+
100
+ this.visibleChange.emit(value);
101
+ }
102
+
103
+ /**
104
+ * Opens the sidebar
105
+ */
106
+ open(): void {
107
+ this._visible = true;
108
+ this.clearMessages();
109
+ this.visibleChange.emit(this._visible);
110
+ this.onShow.emit();
111
+ }
112
+
113
+ /**
114
+ * Closes the sidebar
115
+ */
116
+ close(): void {
117
+ this._visible = false;
118
+ this.clearMessages();
119
+ this.visibleChange.emit(this._visible);
120
+ this.onHide.emit();
121
+ }
122
+
123
+ /**
124
+ * Handles escape key press
125
+ * Shows confirmation if there are unsaved changes
126
+ */
127
+ @HostListener('document:keydown.escape', ['$event'])
128
+ handleEscapeKey(event: KeyboardEvent): void {
129
+ if (this.visible) {
130
+ event.preventDefault();
131
+ this.handleClose();
132
+ }
133
+ }
134
+
135
+ /**
136
+ * Handles backdrop click events
137
+ * Prevents default PrimeNG behavior and shows confirmation if needed
138
+ */
139
+ handleBackdropClick(event: Event): void {
140
+ event.preventDefault();
141
+ event.stopPropagation();
142
+ this.handleClose();
143
+ }
144
+
145
+ /**
146
+ * Handles all closing scenarios (backdrop click, escape key, close button, etc.)
147
+ * This is the single entry point for all closing logic
148
+ */
149
+ handleClose(): void {
150
+ if (this.hasUnsavedChanges && !this.isShowingConfirmation) {
151
+ this.showUnsavedChangesConfirmation();
152
+ } else {
153
+ this.close();
154
+ }
155
+ }
156
+
157
+ /**
158
+ * Shows confirmation dialog for unsaved changes
159
+ */
160
+ private showUnsavedChangesConfirmation(): void {
161
+ if (this.isShowingConfirmation) {
162
+ return;
163
+ }
164
+ this.isShowingConfirmation = true;
165
+ ConfirmationDialogComponent.confirm(
166
+ this.confirmationService,
167
+ this.unsavedChangesConfirmationOptions,
168
+ () => {
169
+ this.isShowingConfirmation = false;
170
+ this.close();
171
+ this.onClose.emit();
172
+ },
173
+ () => {
174
+ this.isShowingConfirmation = false;
175
+ }
176
+ );
177
+ }
178
+
179
+ /**
180
+ * Shows success message and closes sidebar after delay
181
+ */
182
+ showSuccess(): void {
183
+ this.showSuccessMessage = true;
184
+ this.showErrorMessage = false;
185
+ setTimeout(() => {
186
+ this.close();
187
+ }, 2000);
188
+ }
189
+
190
+ /**
191
+ * Shows error message
192
+ */
193
+ showError(message?: string): void {
194
+ this.showErrorMessage = true;
195
+ this.showSuccessMessage = false;
196
+ this.errorMessage = message || SHARED.EMPTY;
197
+ }
198
+
199
+ /**
200
+ * Clears all messages
201
+ */
202
+ clearMessages(): void {
203
+ this.showSuccessMessage = false;
204
+ this.showErrorMessage = false;
205
+ }
206
+
207
+ /**
208
+ * Checks if there are unsaved changes
209
+ * @returns True if there are unsaved changes, false otherwise
210
+ */
211
+ checkForUnsavedChanges(): boolean {
212
+ return this.hasUnsavedChanges;
213
+ }
214
+
215
+ /**
216
+ * Lifecycle hook that is called when component is destroyed.
217
+ * Cleans up subscriptions.
218
+ */
219
+ ngOnDestroy(): void {
220
+ this.destroy$.next();
221
+ this.destroy$.complete();
222
+ }
223
+ }
@@ -0,0 +1,33 @@
1
+ <div class="user-list-container" [@slideInFromTop]>
2
+ <div class="user-cards">
3
+ <div
4
+ *ngFor="let user of filteredUserData"
5
+ class="user-card"
6
+ [class.selected]="selectedUser === user.name"
7
+ [style.border-color]="selectedUser === user.name ? getAvatarColor(user.color) : 'transparent'"
8
+ (click)="onUserSelect(user.name, user._id)"
9
+ >
10
+ @if(user.name === "Application Docs"){
11
+ <div class="user-avatar" [ngClass]="'avatar-' + user.color">
12
+ <span class="initials"><i class="pi pi-user"></i></span>
13
+ </div>
14
+ }@else {
15
+ <div class="user-avatar" [ngClass]="'avatar-' + user.color">
16
+ <span class="initials">{{ user.initials }}</span>
17
+ </div>
18
+ }
19
+ <div class="user-info">
20
+ <div class="username">{{ user.name }}</div>
21
+ <div class="document-counts">
22
+ <span style="color : #16A34A;"> {{ user.approved }} approved </span><span>/ {{ user.pending }} outstanding</span>
23
+ </div>
24
+ </div>
25
+
26
+ </div>
27
+
28
+ <!-- Show message when filtered list is empty -->
29
+ <div *ngIf="filteredUserData.length === 0 && shouldShowContainer" class="no-users-message" [@slideInFromTop]>
30
+ <p>No users available for this category.</p>
31
+ </div>
32
+ </div>
33
+ </div>
@@ -0,0 +1,118 @@
1
+ .user-list-container {
2
+ padding: 1rem;
3
+ padding-bottom: 0.5rem;
4
+ }
5
+
6
+ .user-cards {
7
+ display: flex;
8
+ flex-wrap: wrap;
9
+ transition: all 0.3s ease-in-out;
10
+ }
11
+
12
+ .user-card {
13
+ display: flex;
14
+ align-items: center;
15
+ gap: 0.75rem;
16
+ padding: 1rem;
17
+ border: 2px solid transparent;
18
+ border-radius: 8px;
19
+ cursor: pointer;
20
+ transition: all 0.2s ease;
21
+ background: white;
22
+ min-width: 140px;
23
+ max-width: 300px;
24
+ height: 70px;
25
+ position: relative;
26
+ flex-shrink: 0;
27
+ }
28
+
29
+ .user-card:hover {
30
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
31
+ }
32
+
33
+ .user-card.selected {
34
+ background-color: #f8fafc;
35
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
36
+ border-width: 2px;
37
+ }
38
+
39
+ .user-avatar {
40
+ width: 40px;
41
+ height: 40px;
42
+ border-radius: 50%;
43
+ display: flex;
44
+ align-items: center;
45
+ justify-content: center;
46
+ font-weight: bold;
47
+ color: white;
48
+ font-size: 14px;
49
+ flex-shrink: 0;
50
+ font-weight: 400;
51
+ }
52
+
53
+ .avatar-orange { background-color: #FEF3C7; color: #B45309;}
54
+ .avatar-blue { background-color: #DBEAFE; color: #1D4ED8;}
55
+ .avatar-green { background-color: #22C55E1A; color: #36AA86;}
56
+ .avatar-grey { background-color: #EBECED; color: #5B6676;}
57
+ .avatar-purple { background-color: #3B82F61A; color: #3B82F6;}
58
+
59
+ .user-info {
60
+ flex: 1;
61
+ min-width: 0;
62
+ overflow: hidden;
63
+ }
64
+
65
+ .username {
66
+ font-weight: 600;
67
+ color: #1f2937;
68
+ margin-bottom: 0.25rem;
69
+ white-space: nowrap;
70
+ overflow: hidden;
71
+ text-overflow: ellipsis;
72
+ line-height: 1.2;
73
+ }
74
+
75
+ .document-counts {
76
+ font-size: 0.875rem;
77
+ color: #6b7280;
78
+ white-space: nowrap;
79
+ overflow: hidden;
80
+ text-overflow: ellipsis;
81
+ line-height: 1.35;
82
+ padding-bottom: 2px;
83
+ }
84
+
85
+ .selection-indicator {
86
+ position: absolute;
87
+ top: 8px;
88
+ right: 8px;
89
+ width: 20px;
90
+ height: 20px;
91
+ background-color: #10b981;
92
+ border-radius: 50%;
93
+ display: flex;
94
+ align-items: center;
95
+ justify-content: center;
96
+ color: white;
97
+ font-size: 12px;
98
+ flex-shrink: 0;
99
+ }
100
+
101
+ .no-users-message {
102
+ display: flex;
103
+ justify-content: center;
104
+ align-items: center;
105
+ padding: 2rem;
106
+ background: #f8fafc;
107
+ border-radius: 8px;
108
+ border: 2px dashed #d1d5db;
109
+ margin: 1rem 0;
110
+
111
+ p {
112
+ color: #6b7280;
113
+ font-size: 0.875rem;
114
+ font-weight: 500;
115
+ margin: 0;
116
+ text-align: center;
117
+ }
118
+ }
@@ -0,0 +1,23 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { UserListComponent } from './user-list.component';
4
+
5
+ describe('UserListComponent', () => {
6
+ let component: UserListComponent;
7
+ let fixture: ComponentFixture<UserListComponent>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ declarations: [UserListComponent]
12
+ })
13
+ .compileComponents();
14
+
15
+ fixture = TestBed.createComponent(UserListComponent);
16
+ component = fixture.componentInstance;
17
+ fixture.detectChanges();
18
+ });
19
+
20
+ it('should create', () => {
21
+ expect(component).toBeTruthy();
22
+ });
23
+ });