tango-app-ui-manage-tickets 3.7.0-beta.69 → 3.7.0-beta.70

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 (177) hide show
  1. package/.eslintrc.json +37 -0
  2. package/ng-package.json +7 -0
  3. package/package.json +12 -25
  4. package/src/lib/components/add-csm-modal/add-csm-modal.component.html +32 -0
  5. package/src/lib/components/add-csm-modal/add-csm-modal.component.scss +14 -0
  6. package/src/lib/components/add-csm-modal/add-csm-modal.component.spec.ts +23 -0
  7. package/src/lib/components/add-csm-modal/add-csm-modal.component.ts +94 -0
  8. package/src/lib/components/audit-log/audit-log.component.html +1 -0
  9. package/src/lib/components/audit-log/audit-log.component.scss +0 -0
  10. package/src/lib/components/audit-log/audit-log.component.spec.ts +23 -0
  11. package/src/lib/components/audit-log/audit-log.component.ts +10 -0
  12. package/src/lib/components/audit-mapping-list/audit-mapping-list.component.html +234 -0
  13. package/src/lib/components/audit-mapping-list/audit-mapping-list.component.scss +186 -0
  14. package/src/lib/components/audit-mapping-list/audit-mapping-list.component.spec.ts +23 -0
  15. package/src/lib/components/audit-mapping-list/audit-mapping-list.component.ts +536 -0
  16. package/src/lib/components/audit-metrics/audit-metrics.component.html +345 -0
  17. package/src/lib/components/audit-metrics/audit-metrics.component.scss +34 -0
  18. package/src/lib/components/audit-metrics/audit-metrics.component.spec.ts +23 -0
  19. package/src/lib/components/audit-metrics/audit-metrics.component.ts +292 -0
  20. package/src/lib/components/audit-report-popup/audit-report-popup.component.html +111 -0
  21. package/src/lib/components/audit-report-popup/audit-report-popup.component.scss +101 -0
  22. package/src/lib/components/audit-report-popup/audit-report-popup.component.spec.ts +23 -0
  23. package/src/lib/components/audit-report-popup/audit-report-popup.component.ts +397 -0
  24. package/src/lib/components/audit-retag/audit-retag.component.html +129 -0
  25. package/src/lib/components/audit-retag/audit-retag.component.scss +146 -0
  26. package/src/lib/components/audit-retag/audit-retag.component.spec.ts +23 -0
  27. package/src/lib/components/audit-retag/audit-retag.component.ts +497 -0
  28. package/src/lib/components/comment-model/comment-model.component.html +24 -0
  29. package/src/lib/components/comment-model/comment-model.component.scss +20 -0
  30. package/src/lib/components/comment-model/comment-model.component.spec.ts +23 -0
  31. package/src/lib/components/comment-model/comment-model.component.ts +53 -0
  32. package/src/lib/components/count/count.component.html +54 -0
  33. package/src/lib/components/count/count.component.scss +14 -0
  34. package/src/lib/components/count/count.component.spec.ts +23 -0
  35. package/src/lib/components/count/count.component.ts +82 -0
  36. package/src/lib/components/custom-select/custom-select.component.html +134 -0
  37. package/src/lib/components/custom-select/custom-select.component.scss +204 -0
  38. package/src/lib/components/custom-select/custom-select.component.spec.ts +23 -0
  39. package/src/lib/components/custom-select/custom-select.component.ts +189 -0
  40. package/src/lib/components/filter-options/filter-options.component.html +51 -0
  41. package/src/lib/components/filter-options/filter-options.component.scss +102 -0
  42. package/src/lib/components/filter-options/filter-options.component.spec.ts +23 -0
  43. package/src/lib/components/filter-options/filter-options.component.ts +38 -0
  44. package/src/lib/components/footfall-dic/footfall-dic.component.html +1275 -0
  45. package/src/lib/components/footfall-dic/footfall-dic.component.scss +273 -0
  46. package/src/lib/components/footfall-dic/footfall-dic.component.spec.ts +23 -0
  47. package/src/lib/components/footfall-dic/footfall-dic.component.ts +1206 -0
  48. package/src/lib/components/footfall-dicview/footfall-dicview.component.html +1136 -0
  49. package/src/lib/components/footfall-dicview/footfall-dicview.component.scss +416 -0
  50. package/src/lib/components/footfall-dicview/footfall-dicview.component.spec.ts +23 -0
  51. package/src/lib/components/footfall-dicview/footfall-dicview.component.ts +1168 -0
  52. package/src/lib/components/footfall-popup/footfall-popup.component.html +61 -0
  53. package/src/lib/components/footfall-popup/footfall-popup.component.scss +20 -0
  54. package/src/lib/components/footfall-popup/footfall-popup.component.spec.ts +23 -0
  55. package/src/lib/components/footfall-popup/footfall-popup.component.ts +12 -0
  56. package/src/lib/components/group-select/group-select.component.html +44 -0
  57. package/src/lib/components/group-select/group-select.component.scss +144 -0
  58. package/src/lib/components/group-select/group-select.component.spec.ts +23 -0
  59. package/src/lib/components/group-select/group-select.component.ts +145 -0
  60. package/src/lib/components/re-trigger/re-trigger.component.html +53 -0
  61. package/src/lib/components/re-trigger/re-trigger.component.scss +16 -0
  62. package/src/lib/components/re-trigger/re-trigger.component.spec.ts +23 -0
  63. package/src/lib/components/re-trigger/re-trigger.component.ts +96 -0
  64. package/src/lib/components/reactive-select/reactive-select.component.html +18 -0
  65. package/src/lib/components/reactive-select/reactive-select.component.scss +52 -0
  66. package/src/lib/components/reactive-select/reactive-select.component.spec.ts +23 -0
  67. package/src/lib/components/reactive-select/reactive-select.component.ts +104 -0
  68. package/src/lib/components/remove-audit/remove-audit.component.html +38 -0
  69. package/src/lib/components/remove-audit/remove-audit.component.scss +27 -0
  70. package/src/lib/components/remove-audit/remove-audit.component.spec.ts +23 -0
  71. package/src/lib/components/remove-audit/remove-audit.component.ts +81 -0
  72. package/src/lib/components/start-audit/start-audit.component.html +174 -0
  73. package/src/lib/components/start-audit/start-audit.component.scss +185 -0
  74. package/src/lib/components/start-audit/start-audit.component.spec.ts +23 -0
  75. package/src/lib/components/start-audit/start-audit.component.ts +772 -0
  76. package/src/lib/components/tango-manage-tickets/tango-manage-tickets.component.html +43 -0
  77. package/src/lib/components/tango-manage-tickets/tango-manage-tickets.component.scss +35 -0
  78. package/src/lib/components/tango-manage-tickets/tango-manage-tickets.component.spec.ts +23 -0
  79. package/src/lib/components/tango-manage-tickets/tango-manage-tickets.component.ts +118 -0
  80. package/src/lib/components/ticket-filter-panel/ticket-filter-panel.component.html +386 -0
  81. package/src/lib/components/ticket-filter-panel/ticket-filter-panel.component.scss +87 -0
  82. package/src/lib/components/ticket-filter-panel/ticket-filter-panel.component.spec.ts +23 -0
  83. package/src/lib/components/ticket-filter-panel/ticket-filter-panel.component.ts +493 -0
  84. package/src/lib/components/ticket-footfall-new/ticket-footfall-new.component.html +3751 -0
  85. package/src/lib/components/ticket-footfall-new/ticket-footfall-new.component.scss +1240 -0
  86. package/src/lib/components/ticket-footfall-new/ticket-footfall-new.component.spec.ts +23 -0
  87. package/src/lib/components/ticket-footfall-new/ticket-footfall-new.component.ts +2863 -0
  88. package/src/lib/components/ticketclosepopup/ticketclosepopup.component.html +100 -0
  89. package/src/lib/components/ticketclosepopup/ticketclosepopup.component.scss +34 -0
  90. package/src/lib/components/ticketclosepopup/ticketclosepopup.component.spec.ts +23 -0
  91. package/src/lib/components/ticketclosepopup/ticketclosepopup.component.ts +48 -0
  92. package/src/lib/components/tickets/tickets.component.html +451 -0
  93. package/src/lib/components/tickets/tickets.component.scss +131 -0
  94. package/src/lib/components/tickets/tickets.component.spec.ts +23 -0
  95. package/src/lib/components/tickets/tickets.component.ts +809 -0
  96. package/src/lib/components/viewcategory/viewcategory.component.html +38 -0
  97. package/src/lib/components/viewcategory/viewcategory.component.scss +29 -0
  98. package/src/lib/components/viewcategory/viewcategory.component.spec.ts +23 -0
  99. package/src/lib/components/viewcategory/viewcategory.component.ts +79 -0
  100. package/src/lib/services/audit.service.spec.ts +16 -0
  101. package/src/lib/services/audit.service.ts +98 -0
  102. package/src/lib/services/excel.service.ts +48 -0
  103. package/src/lib/services/ticket.service.spec.ts +16 -0
  104. package/src/lib/services/ticket.service.ts +501 -0
  105. package/src/lib/services/timer.service.spec.ts +16 -0
  106. package/src/lib/services/timer.service.ts +92 -0
  107. package/src/lib/tango-manage-tickets-routing.module.ts +37 -0
  108. package/src/lib/tango-manage-tickets.module.ts +68 -0
  109. package/{public-api.d.ts → src/public-api.ts} +8 -2
  110. package/tsconfig.lib.json +14 -0
  111. package/tsconfig.lib.prod.json +10 -0
  112. package/tsconfig.spec.json +14 -0
  113. package/esm2022/lib/components/add-csm-modal/add-csm-modal.component.mjs +0 -98
  114. package/esm2022/lib/components/audit-log/audit-log.component.mjs +0 -11
  115. package/esm2022/lib/components/audit-mapping-list/audit-mapping-list.component.mjs +0 -498
  116. package/esm2022/lib/components/audit-metrics/audit-metrics.component.mjs +0 -298
  117. package/esm2022/lib/components/audit-report-popup/audit-report-popup.component.mjs +0 -389
  118. package/esm2022/lib/components/audit-retag/audit-retag.component.mjs +0 -480
  119. package/esm2022/lib/components/comment-model/comment-model.component.mjs +0 -58
  120. package/esm2022/lib/components/count/count.component.mjs +0 -89
  121. package/esm2022/lib/components/custom-select/custom-select.component.mjs +0 -187
  122. package/esm2022/lib/components/filter-options/filter-options.component.mjs +0 -41
  123. package/esm2022/lib/components/footfall-dic/footfall-dic.component.mjs +0 -1061
  124. package/esm2022/lib/components/footfall-dicview/footfall-dicview.component.mjs +0 -1014
  125. package/esm2022/lib/components/footfall-popup/footfall-popup.component.mjs +0 -15
  126. package/esm2022/lib/components/group-select/group-select.component.mjs +0 -155
  127. package/esm2022/lib/components/re-trigger/re-trigger.component.mjs +0 -96
  128. package/esm2022/lib/components/reactive-select/reactive-select.component.mjs +0 -108
  129. package/esm2022/lib/components/remove-audit/remove-audit.component.mjs +0 -81
  130. package/esm2022/lib/components/start-audit/start-audit.component.mjs +0 -758
  131. package/esm2022/lib/components/tango-manage-tickets/tango-manage-tickets.component.mjs +0 -131
  132. package/esm2022/lib/components/ticket-filter-panel/ticket-filter-panel.component.mjs +0 -435
  133. package/esm2022/lib/components/ticket-footfall-new/ticket-footfall-new.component.mjs +0 -2414
  134. package/esm2022/lib/components/ticketclosepopup/ticketclosepopup.component.mjs +0 -43
  135. package/esm2022/lib/components/tickets/tickets.component.mjs +0 -847
  136. package/esm2022/lib/components/viewcategory/viewcategory.component.mjs +0 -89
  137. package/esm2022/lib/services/audit.service.mjs +0 -88
  138. package/esm2022/lib/services/excel.service.mjs +0 -45
  139. package/esm2022/lib/services/ticket.service.mjs +0 -319
  140. package/esm2022/lib/services/timer.service.mjs +0 -84
  141. package/esm2022/lib/tango-manage-tickets-routing.module.mjs +0 -44
  142. package/esm2022/lib/tango-manage-tickets.module.mjs +0 -109
  143. package/esm2022/public-api.mjs +0 -6
  144. package/esm2022/tango-app-ui-manage-tickets.mjs +0 -5
  145. package/fesm2022/tango-app-ui-manage-tickets.mjs +0 -9848
  146. package/fesm2022/tango-app-ui-manage-tickets.mjs.map +0 -1
  147. package/index.d.ts +0 -5
  148. package/lib/components/add-csm-modal/add-csm-modal.component.d.ts +0 -30
  149. package/lib/components/audit-log/audit-log.component.d.ts +0 -5
  150. package/lib/components/audit-mapping-list/audit-mapping-list.component.d.ts +0 -73
  151. package/lib/components/audit-metrics/audit-metrics.component.d.ts +0 -59
  152. package/lib/components/audit-report-popup/audit-report-popup.component.d.ts +0 -52
  153. package/lib/components/audit-retag/audit-retag.component.d.ts +0 -59
  154. package/lib/components/comment-model/comment-model.component.d.ts +0 -17
  155. package/lib/components/count/count.component.d.ts +0 -23
  156. package/lib/components/custom-select/custom-select.component.d.ts +0 -35
  157. package/lib/components/filter-options/filter-options.component.d.ts +0 -15
  158. package/lib/components/footfall-dic/footfall-dic.component.d.ts +0 -143
  159. package/lib/components/footfall-dicview/footfall-dicview.component.d.ts +0 -132
  160. package/lib/components/footfall-popup/footfall-popup.component.d.ts +0 -8
  161. package/lib/components/group-select/group-select.component.d.ts +0 -33
  162. package/lib/components/re-trigger/re-trigger.component.d.ts +0 -32
  163. package/lib/components/reactive-select/reactive-select.component.d.ts +0 -32
  164. package/lib/components/remove-audit/remove-audit.component.d.ts +0 -16
  165. package/lib/components/start-audit/start-audit.component.d.ts +0 -86
  166. package/lib/components/tango-manage-tickets/tango-manage-tickets.component.d.ts +0 -28
  167. package/lib/components/ticket-filter-panel/ticket-filter-panel.component.d.ts +0 -79
  168. package/lib/components/ticket-footfall-new/ticket-footfall-new.component.d.ts +0 -291
  169. package/lib/components/ticketclosepopup/ticketclosepopup.component.d.ts +0 -15
  170. package/lib/components/tickets/tickets.component.d.ts +0 -88
  171. package/lib/components/viewcategory/viewcategory.component.d.ts +0 -16
  172. package/lib/services/audit.service.d.ts +0 -36
  173. package/lib/services/excel.service.d.ts +0 -10
  174. package/lib/services/ticket.service.d.ts +0 -87
  175. package/lib/services/timer.service.d.ts +0 -22
  176. package/lib/tango-manage-tickets-routing.module.d.ts +0 -7
  177. package/lib/tango-manage-tickets.module.d.ts +0 -38
@@ -0,0 +1,23 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { TicketFilterPanelComponent } from './ticket-filter-panel.component';
4
+
5
+ describe('TicketFilterPanelComponent', () => {
6
+ let component: TicketFilterPanelComponent;
7
+ let fixture: ComponentFixture<TicketFilterPanelComponent>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ declarations: [TicketFilterPanelComponent]
12
+ })
13
+ .compileComponents();
14
+
15
+ fixture = TestBed.createComponent(TicketFilterPanelComponent);
16
+ component = fixture.componentInstance;
17
+ fixture.detectChanges();
18
+ });
19
+
20
+ it('should create', () => {
21
+ expect(component).toBeTruthy();
22
+ });
23
+ });
@@ -0,0 +1,493 @@
1
+ import { Component, ElementRef, EventEmitter, HostListener, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
2
+ import { FormBuilder, FormGroup, Validators } from '@angular/forms';
3
+ import { TicketService } from '../../services/ticket.service';
4
+
5
+ type Condition = 'gt' | 'lt' | 'gte' | 'lte' | 'between';
6
+
7
+ @Component({
8
+ selector: 'lib-ticket-filter-panel',
9
+ templateUrl: './ticket-filter-panel.component.html',
10
+ styleUrl: './ticket-filter-panel.component.scss'
11
+ })
12
+ export class TicketFilterPanelComponent implements OnChanges {
13
+ @Output() apply = new EventEmitter<any>();
14
+ @Output() panelClosed = new EventEmitter<void>(); // ✅ not `close`
15
+ @Input() permissionType: string | null = null;
16
+ @Input() userType: string | null = null; // e.g. 'tango' or others
17
+ @Input() client :any;
18
+ @HostListener('document:click', ['$event'])
19
+ onDocumentClick(event: MouseEvent): void {
20
+
21
+ // 1️⃣ Always close dropdowns first
22
+ this.dropdownState.status = false;
23
+ this.dropdownState.reviewer = false;
24
+ this.dropdownState.approver = false;
25
+
26
+ // 2️⃣ If filter is not open → nothing to close
27
+ if (!this.isOpen) return;
28
+
29
+ // 3️⃣ Check if clicked inside filter card
30
+ const clickedInside = this.eRef.nativeElement.contains(event.target);
31
+
32
+ // 4️⃣ If clicked OUTSIDE → close entire filter panel
33
+ if (!clickedInside) {
34
+ this.isOpen = false;
35
+ this.panelClosed.emit();
36
+ this.filterForm.reset({
37
+ status: [],
38
+ reviewerCondition: null,
39
+ reviewerFrom: null,
40
+ reviewerTo: null,
41
+
42
+ approverCondition: null,
43
+ approverFrom: null,
44
+ approverTo: null,
45
+
46
+ tangoCondition: null,
47
+ tangoFrom: null,
48
+ tangoTo: null,
49
+
50
+ reviewedBy: [],
51
+ approvedBy: []
52
+ });
53
+ this.onReset();
54
+ }
55
+ }
56
+ isOpen = false; // controls visibility
57
+
58
+ // called from parent via #filterPanel.open()
59
+ open() {
60
+ this.isOpen = true;
61
+ }
62
+
63
+ // called from close button inside the panel
64
+ close() {
65
+ this.isOpen = false;
66
+ this.panelClosed.emit();
67
+ }
68
+
69
+ showPanel = false; // you can also control this from parent
70
+
71
+ statusOptions: any[] = [
72
+ 'Open',
73
+ 'In-Progress',
74
+ 'Closed',
75
+ // 'Open - Accuracy Issue',
76
+ // 'Closed - Accuracy Issue',
77
+ 'Expired',
78
+ ];
79
+
80
+
81
+ conditionOptions = [
82
+ { value: 'gt', label: '> Greater than' },
83
+ { value: 'lt', label: '< Lesser than' },
84
+ { value: 'gte', label: '>= Greater than or equal to' },
85
+ { value: 'lte', label: '<= Lesser than or equal to' },
86
+ { value: 'between', label: 'Between' },
87
+ ];
88
+
89
+ filterForm: FormGroup;
90
+
91
+ constructor(private fb: FormBuilder,private eRef: ElementRef,private service:TicketService) {
92
+ this.filterForm = this.fb.group({
93
+ status: [[]],
94
+
95
+ reviewerCondition: [null as Condition | null],
96
+ reviewerFrom: [null,[Validators.min(0), Validators.max(100)]],
97
+ reviewerTo: [null,[Validators.min(0), Validators.max(100)]],
98
+
99
+ approverCondition: [null as Condition | null],
100
+ approverFrom: [null,[Validators.min(0), Validators.max(100)]],
101
+ approverTo: [null,[Validators.min(0), Validators.max(100)]],
102
+
103
+ tangoCondition: [null as Condition | null],
104
+ tangoFrom: [null,[Validators.min(0), Validators.max(100)]],
105
+ tangoTo: [null,[Validators.min(0), Validators.max(100)]],
106
+
107
+ reviewedBy: [[]],
108
+ approvedBy: [[]],
109
+ });
110
+ this.onReset();
111
+ }
112
+ limitValue(event: any, controlName: string) {
113
+ let value = Number(event.target.value);
114
+
115
+ if (value < 0) value = 0;
116
+ if (value > 100) value = 100;
117
+
118
+ event.target.value = value;
119
+ this.filterForm.get(controlName)?.setValue(value, { emitEvent: false });
120
+ }
121
+
122
+ get isTango(): boolean {
123
+ return this.userType === 'tango';
124
+ }
125
+
126
+ // SHOW / HIDE RULES
127
+
128
+ // Reviewer accuracy and "Reviewed by" visible for tango + reviewer
129
+ get showReviewerAccuracy(): boolean {
130
+ return this.isTango || this.permissionType === 'review';
131
+ }
132
+
133
+ get showReviewedBy(): boolean {
134
+ return this.permissionType === 'review';
135
+ }
136
+
137
+ // Approver accuracy and "Approved by" visible for tango + approver
138
+ get showApproverAccuracy(): boolean {
139
+ return this.isTango || this.permissionType === 'approve';
140
+ }
141
+
142
+ get showApprovedBy(): boolean {
143
+ return this.permissionType === 'approve';
144
+ }
145
+
146
+ // Tango accuracy only for tango users
147
+ get showTangoAccuracy(): boolean {
148
+ return this.isTango;
149
+ }
150
+ statusDropdownOpen = false;
151
+ isStatusSelected(status: string): boolean {
152
+ const selected: string[] = this.filterForm.value.status || [];
153
+ return selected.includes(status);
154
+ }
155
+
156
+ onStatusChange(event: Event, status: string) {
157
+ const checkbox = event.target as HTMLInputElement;
158
+ const selected: string[] = this.filterForm.value.status || [];
159
+ let next: string[];
160
+
161
+ if (checkbox.checked) {
162
+ next = selected.includes(status) ? selected : [...selected, status];
163
+ } else {
164
+ next = selected.filter(s => s !== status);
165
+ }
166
+
167
+ this.filterForm.patchValue({ status: next });
168
+ }
169
+
170
+ toggleStatusDropdown(event?: MouseEvent) {
171
+ if (event) {
172
+ event.stopPropagation(); // avoid document click closing it
173
+ }
174
+ this.statusDropdownOpen = !this.statusDropdownOpen;
175
+ }
176
+
177
+ // Are all statuses currently selected?
178
+ areAllStatusesSelected(): boolean {
179
+ const selected: string[] = this.filterForm.value.status || [];
180
+ return selected.length > 0 && selected.length === this.statusOptions.length;
181
+ }
182
+
183
+ // Handle "Select All" checkbox change
184
+ onStatusSelectAllChange(event: Event) {
185
+ const checkbox = event.target as HTMLInputElement;
186
+
187
+ if (checkbox.checked) {
188
+ // Select every status
189
+ this.filterForm.patchValue({ status: [...this.statusOptions] });
190
+ } else {
191
+ // Clear all
192
+ this.filterForm.patchValue({ status: [] });
193
+ }
194
+ }
195
+ get selectedStatuses(): string[] {
196
+ return this.filterForm.value.status || [];
197
+ }
198
+
199
+ isBetween(controlName: string): boolean {
200
+ return this.filterForm.get(controlName)?.value === 'between';
201
+ }
202
+ ngOnChanges(changes: SimpleChanges): void {
203
+ if (changes['client'] || changes['permissionType'] || changes['userType']) {
204
+ this.loadReviewerList();
205
+ }
206
+ }
207
+ // full user list you already have
208
+ userList: any[] = [];
209
+
210
+
211
+ reviewerSearchTerm: string = '';
212
+
213
+ // ✅ simple computed list for *ngFor
214
+ get filteredReviewerList(): { email: string; name?: string }[] {
215
+ const term = (this.reviewerSearchTerm || '').trim().toLowerCase();
216
+
217
+ if (!term) {
218
+ return this.userList;
219
+ }
220
+
221
+ return this.userList.filter(u => {
222
+ const email = (u.email || '').toLowerCase();
223
+ const name = (u.name || '').toLowerCase();
224
+ return email.includes(term) || name.includes(term);
225
+ });
226
+ }
227
+ approverSearchTerm:any;
228
+ get filteredApproverList(): any[] {
229
+ const term = (this.approverSearchTerm || '').trim().toLowerCase();
230
+ if (!term) {
231
+ return this.userList;
232
+ }
233
+
234
+ return this.userList.filter((u: any) => {
235
+ const email = (u.email || '').toLowerCase();
236
+ const name = (u.name || '').toLowerCase();
237
+ return email.includes(term) || name.includes(term);
238
+ });
239
+ }
240
+
241
+ onApproverSearch(value: string) {
242
+ this.approverSearchTerm = value;
243
+ }
244
+ private loadReviewerList(): void {
245
+ if (!this.client) {
246
+ this.userList = [];
247
+ return;
248
+ }
249
+
250
+ let type: string;
251
+
252
+ if (this.userType === 'tango') {
253
+ type = 'tango'; // or 'all'
254
+ } else if (this.permissionType === 'review') {
255
+ type = 'review';
256
+ } else if (this.permissionType === 'approve') {
257
+ type = 'approve';
258
+ } else {
259
+ this.userList = [];
260
+ return;
261
+ }
262
+
263
+ this.service.getReviewerApi(this.client, type,'').subscribe({
264
+ next: (res: any) => {
265
+ if (res && res.code === 200) {
266
+ this.userList = res.data;
267
+ } else {
268
+ this.userList = [];
269
+ }
270
+ },
271
+ error: () => {
272
+ this.userList = [];
273
+ }
274
+ });
275
+ }
276
+
277
+ // open flags
278
+ reviewerDropdownOpen = false;
279
+ approverDropdownOpen = false;
280
+
281
+ // convenience getters
282
+ get selectedReviewedBy(): string[] {
283
+ return this.filterForm.value.reviewedBy || [];
284
+ }
285
+
286
+ get selectedApprovedBy(): string[] {
287
+ return this.filterForm.value.approvedBy || [];
288
+ }
289
+
290
+ // --- Reviewed By helpers ---
291
+
292
+ toggleReviewerDropdown(event?: MouseEvent) {
293
+ if (event) event.stopPropagation();
294
+ this.reviewerDropdownOpen = !this.reviewerDropdownOpen;
295
+ }
296
+
297
+ isReviewerSelected(email: string): boolean {
298
+ return this.selectedReviewedBy.includes(email);
299
+ }
300
+
301
+ onReviewerChange(event: Event, email: string) {
302
+ const checkbox = event.target as HTMLInputElement;
303
+ const selected = [...this.selectedReviewedBy];
304
+
305
+ if (checkbox.checked) {
306
+ if (!selected.includes(email)) selected.push(email);
307
+ } else {
308
+ const i = selected.indexOf(email);
309
+ if (i >= 0) selected.splice(i, 1);
310
+ }
311
+
312
+ this.filterForm.patchValue({ reviewedBy: selected });
313
+ }
314
+
315
+ areAllReviewersSelected(): boolean {
316
+ return (
317
+ this.userList.length > 0 &&
318
+ this.selectedReviewedBy.length === this.userList.length
319
+ );
320
+ }
321
+
322
+ onReviewerSelectAll(event: Event) {
323
+ const checkbox = event.target as HTMLInputElement;
324
+
325
+ if (checkbox.checked) {
326
+ this.filterForm.patchValue({
327
+ reviewedBy: this.userList.map((u:any) => u.email),
328
+ });
329
+ } else {
330
+ this.filterForm.patchValue({ reviewedBy: [] });
331
+ }
332
+ }
333
+
334
+ // --- Approved By helpers ---
335
+
336
+ toggleApproverDropdown(event?: MouseEvent) {
337
+ if (event) event.stopPropagation();
338
+ this.approverDropdownOpen = !this.approverDropdownOpen;
339
+ }
340
+
341
+ isApproverSelected(email: string): boolean {
342
+ return this.selectedApprovedBy.includes(email);
343
+ }
344
+
345
+ onApproverChange(event: Event, email: string) {
346
+ const checkbox = event.target as HTMLInputElement;
347
+ const selected = [...this.selectedApprovedBy];
348
+
349
+ if (checkbox.checked) {
350
+ if (!selected.includes(email)) selected.push(email);
351
+ } else {
352
+ const i = selected.indexOf(email);
353
+ if (i >= 0) selected.splice(i, 1);
354
+ }
355
+
356
+ this.filterForm.patchValue({ approvedBy: selected });
357
+ }
358
+
359
+ areAllApproversSelected(): boolean {
360
+ return (
361
+ this.userList.length > 0 &&
362
+ this.selectedApprovedBy.length === this.userList.length
363
+ );
364
+ }
365
+
366
+ onApproverSelectAll(event: Event) {
367
+ const checkbox = event.target as HTMLInputElement;
368
+
369
+ if (checkbox.checked) {
370
+ this.filterForm.patchValue({
371
+ approvedBy: this.userList.map((u:any) => u.email),
372
+ });
373
+ } else {
374
+ this.filterForm.patchValue({ approvedBy: [] });
375
+ }
376
+ }
377
+
378
+ onReset(): void {
379
+ this.filterForm.reset({
380
+ status: [],
381
+ reviewerCondition: null,
382
+ reviewerFrom: null,
383
+ reviewerTo: null,
384
+
385
+ approverCondition: null,
386
+ approverFrom: null,
387
+ approverTo: null,
388
+
389
+ tangoCondition: null,
390
+ tangoFrom: null,
391
+ tangoTo: null,
392
+
393
+ reviewedBy: [],
394
+ approvedBy: []
395
+ });
396
+
397
+ // 2️⃣ Reset search terms
398
+ this.reviewerSearchTerm = '';
399
+ this.approverSearchTerm = '';
400
+
401
+ // 3️⃣ Build empty payload to send back
402
+ const payload = {
403
+ filterByStatus: [],
404
+ filterByReviewer: null,
405
+ filterByApprover: null,
406
+ filterByTango: null,
407
+ filterByReviewedBy: [],
408
+ fileterByApprovedBy: []
409
+ };
410
+
411
+ // 4️⃣ Emit the now-empty filter result
412
+ this.apply.emit(payload);
413
+
414
+ // 5️⃣ Close the filter panel
415
+ this.close();
416
+ }
417
+
418
+ private mapAccuracy(
419
+ condition: Condition | null,
420
+ from: number | null,
421
+ to: number | null
422
+ ): string | null {
423
+
424
+ // nothing selected
425
+ if (!condition || from == null) return null;
426
+
427
+ // "between" → "90 to 100"
428
+ if (condition === 'between') {
429
+ if (to == null) return null;
430
+ return `${from} to ${to}`;
431
+ }
432
+
433
+ // other conditions (gt, lt, gte, lte)
434
+ const opMap: Record<Condition, string> = {
435
+ gt: '>',
436
+ lt: '<',
437
+ gte: '>=',
438
+ lte: '<=',
439
+ between: '', // already handled above
440
+ };
441
+
442
+ return `${opMap[condition]}${from}`; // e.g. ">= 90"
443
+ }
444
+
445
+ onApply(): void {
446
+
447
+ const raw = this.filterForm.value;
448
+
449
+ const reviewerStr = this.mapAccuracy(raw.reviewerCondition, raw.reviewerFrom, raw.reviewerTo);
450
+ const approverStr = this.mapAccuracy(raw.approverCondition, raw.approverFrom, raw.approverTo);
451
+ const tangoStr = this.mapAccuracy(raw.tangoCondition, raw.tangoFrom, raw.tangoTo);
452
+
453
+ const payload = {
454
+ filterByStatus: raw.status || [],
455
+
456
+ filterByReviewer: reviewerStr,
457
+ filterByApprover: approverStr,
458
+ filterByTango: tangoStr,
459
+
460
+ filterByReviewedBy: raw.reviewedBy || [],
461
+ fileterByApprovedBy: raw.approvedBy || [],
462
+ };
463
+ this.apply.emit(payload);
464
+ this.close();
465
+ this.showPanel = false;
466
+ }
467
+
468
+ dropdownState = {
469
+ status: false,
470
+ reviewer: false,
471
+ approver: false
472
+ };
473
+ // @HostListener('document:click')
474
+ closeAll() {
475
+ this.dropdownState.status = false;
476
+ this.dropdownState.reviewer = false;
477
+ this.dropdownState.approver = false;
478
+ }
479
+
480
+ toggleDropdown(type: 'status' | 'reviewer' | 'approver', event: MouseEvent) {
481
+ event.stopPropagation();
482
+
483
+ // Close all before opening a new one
484
+ this.closeAll();
485
+
486
+ // Toggle only the selected one
487
+ this.dropdownState[type] = !this.dropdownState[type];
488
+ }
489
+
490
+ isDropdownOpen(type: 'status' | 'reviewer' | 'approver') {
491
+ return this.dropdownState[type];
492
+ }
493
+ }