@sunbird-cb/access-settings 0.0.1-cbrelease-4.8.26

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 (64) hide show
  1. package/README.md +24 -0
  2. package/esm2022/lib/_common/access-control/access-control.component.mjs +561 -0
  3. package/esm2022/lib/_common/access-control/access-control.module.mjs +125 -0
  4. package/esm2022/lib/_common/dialogs/access-control-guide/access-control-guide.component.mjs +27 -0
  5. package/esm2022/lib/_common/dialogs/confirm-dialog/confirm-dialog.component.mjs +27 -0
  6. package/esm2022/lib/_common/dialogs/entity-selections/entity-selections.component.mjs +371 -0
  7. package/esm2022/lib/_common/dialogs/invite-users/invite-users.component.mjs +116 -0
  8. package/esm2022/lib/_common/pagination/pagination.component.mjs +168 -0
  9. package/esm2022/lib/_constants/app.constants.mjs +6 -0
  10. package/esm2022/lib/_directives/drag-drop.directive.mjs +53 -0
  11. package/esm2022/lib/_models/access-control.model.mjs +31 -0
  12. package/esm2022/lib/_models/pagination.model.mjs +2 -0
  13. package/esm2022/lib/_services/access-control.service.mjs +195 -0
  14. package/esm2022/lib/_services/cadre-mapping.service.mjs +164 -0
  15. package/esm2022/lib/access-settings.component.mjs +13 -0
  16. package/esm2022/lib/access-settings.module.mjs +21 -0
  17. package/esm2022/lib/components/bulk-upload-karmayogi/bulk-upload-karmayogi.component.mjs +391 -0
  18. package/esm2022/lib/components/list-table/list-table.component.mjs +148 -0
  19. package/esm2022/lib/components/snackbar/snackbar.component.mjs +19 -0
  20. package/esm2022/public-api.mjs +10 -0
  21. package/esm2022/sunbird-cb-access-settings.mjs +5 -0
  22. package/fesm2022/sunbird-cb-access-settings.mjs +2331 -0
  23. package/fesm2022/sunbird-cb-access-settings.mjs.map +1 -0
  24. package/index.d.ts +6 -0
  25. package/lib/_common/access-control/access-control.component.d.ts +71 -0
  26. package/lib/_common/access-control/access-control.component.d.ts.map +1 -0
  27. package/lib/_common/access-control/access-control.module.d.ts +36 -0
  28. package/lib/_common/access-control/access-control.module.d.ts.map +1 -0
  29. package/lib/_common/dialogs/access-control-guide/access-control-guide.component.d.ts +16 -0
  30. package/lib/_common/dialogs/access-control-guide/access-control-guide.component.d.ts.map +1 -0
  31. package/lib/_common/dialogs/confirm-dialog/confirm-dialog.component.d.ts +15 -0
  32. package/lib/_common/dialogs/confirm-dialog/confirm-dialog.component.d.ts.map +1 -0
  33. package/lib/_common/dialogs/entity-selections/entity-selections.component.d.ts +65 -0
  34. package/lib/_common/dialogs/entity-selections/entity-selections.component.d.ts.map +1 -0
  35. package/lib/_common/dialogs/invite-users/invite-users.component.d.ts +40 -0
  36. package/lib/_common/dialogs/invite-users/invite-users.component.d.ts.map +1 -0
  37. package/lib/_common/pagination/pagination.component.d.ts +31 -0
  38. package/lib/_common/pagination/pagination.component.d.ts.map +1 -0
  39. package/lib/_constants/app.constants.d.ts +6 -0
  40. package/lib/_constants/app.constants.d.ts.map +1 -0
  41. package/lib/_directives/drag-drop.directive.d.ts +12 -0
  42. package/lib/_directives/drag-drop.directive.d.ts.map +1 -0
  43. package/lib/_models/access-control.model.d.ts +106 -0
  44. package/lib/_models/access-control.model.d.ts.map +1 -0
  45. package/lib/_models/pagination.model.d.ts +6 -0
  46. package/lib/_models/pagination.model.d.ts.map +1 -0
  47. package/lib/_services/access-control.service.d.ts +72 -0
  48. package/lib/_services/access-control.service.d.ts.map +1 -0
  49. package/lib/_services/cadre-mapping.service.d.ts +71 -0
  50. package/lib/_services/cadre-mapping.service.d.ts.map +1 -0
  51. package/lib/access-settings.component.d.ts +9 -0
  52. package/lib/access-settings.component.d.ts.map +1 -0
  53. package/lib/access-settings.module.d.ts +12 -0
  54. package/lib/access-settings.module.d.ts.map +1 -0
  55. package/lib/components/bulk-upload-karmayogi/bulk-upload-karmayogi.component.d.ts +31 -0
  56. package/lib/components/bulk-upload-karmayogi/bulk-upload-karmayogi.component.d.ts.map +1 -0
  57. package/lib/components/list-table/list-table.component.d.ts +40 -0
  58. package/lib/components/list-table/list-table.component.d.ts.map +1 -0
  59. package/lib/components/snackbar/snackbar.component.d.ts +13 -0
  60. package/lib/components/snackbar/snackbar.component.d.ts.map +1 -0
  61. package/package.json +28 -0
  62. package/public-api.d.ts +7 -0
  63. package/public-api.d.ts.map +1 -0
  64. package/sunbird-cb-access-settings.d.ts.map +1 -0
@@ -0,0 +1,2331 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Component, inject, ChangeDetectionStrategy, NgModule, EventEmitter, Directive, Output, HostBinding, HostListener, signal, Injectable, Input, ViewChild } from '@angular/core';
3
+ import * as i1 from '@angular/material/legacy-snack-bar';
4
+ import { MAT_LEGACY_SNACK_BAR_DATA, MatLegacySnackBarModule } from '@angular/material/legacy-snack-bar';
5
+ import * as i2 from '@angular/material/icon';
6
+ import { MatIconModule } from '@angular/material/icon';
7
+ import * as i3 from '@angular/common';
8
+ import { CommonModule } from '@angular/common';
9
+ import * as i2$1 from '@angular/forms';
10
+ import { FormControl, Validators, ReactiveFormsModule, FormsModule } from '@angular/forms';
11
+ import * as i1$3 from '@angular/material/dialog';
12
+ import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
13
+ import { MatRippleModule } from '@angular/material/core';
14
+ import * as i13 from '@angular/material/expansion';
15
+ import { MatExpansionModule } from '@angular/material/expansion';
16
+ import * as i11 from '@angular/material/tabs';
17
+ import { MatTabsModule } from '@angular/material/tabs';
18
+ import * as i6 from '@angular/material/table';
19
+ import { MatTableDataSource, MatTableModule } from '@angular/material/table';
20
+ import * as i7$1 from '@angular/material/sort';
21
+ import { MatSort, MatSortModule } from '@angular/material/sort';
22
+ import * as i16 from '@angular/material/tooltip';
23
+ import { MatTooltipModule } from '@angular/material/tooltip';
24
+ import * as i7 from '@angular/material/legacy-form-field';
25
+ import { MatLegacyFormFieldModule } from '@angular/material/legacy-form-field';
26
+ import * as i8 from '@angular/material/legacy-input';
27
+ import { MatLegacyInputModule } from '@angular/material/legacy-input';
28
+ import { MatLegacyMenuModule } from '@angular/material/legacy-menu';
29
+ import * as i5$2 from '@angular/material/legacy-radio';
30
+ import { MatLegacyRadioModule } from '@angular/material/legacy-radio';
31
+ import * as i4 from '@angular/material/legacy-select';
32
+ import { MatLegacySelectModule } from '@angular/material/legacy-select';
33
+ import * as i12 from '@angular/material/legacy-progress-spinner';
34
+ import { MatLegacyProgressSpinnerModule } from '@angular/material/legacy-progress-spinner';
35
+ import * as i4$1 from '@angular/material/legacy-checkbox';
36
+ import { MatLegacyCheckboxModule } from '@angular/material/legacy-checkbox';
37
+ import * as i9 from '@angular/material/legacy-slide-toggle';
38
+ import { MatLegacySlideToggleModule } from '@angular/material/legacy-slide-toggle';
39
+ import * as i5$1 from '@angular/material/legacy-button';
40
+ import { MatLegacyButtonModule } from '@angular/material/legacy-button';
41
+ import { toNumber } from 'lodash';
42
+ import * as i1$1 from '@angular/common/http';
43
+ import { SelectionModel } from '@angular/cdk/collections';
44
+ import * as i1$2 from '@angular/cdk/a11y';
45
+ import * as i5 from '@angular/material/legacy-core';
46
+ import { Subject } from 'rxjs';
47
+ import { takeUntil } from 'rxjs/operators';
48
+ import { v4 } from 'uuid';
49
+
50
+ class AccessSettingsComponent {
51
+ constructor() { }
52
+ ngOnInit() { }
53
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AccessSettingsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
54
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: AccessSettingsComponent, selector: "sb-uic-access-settings", ngImport: i0, template: ` <p>access settings works!</p> `, isInline: true, styles: ["::ng-deep .mdc-tooltip{--mdc-plain-tooltip-container-color: #616161;--mdc-plain-tooltip-supporting-text-color: #ffffff;--mdc-plain-tooltip-container-shape: 4px;--mdc-plain-tooltip-container-size: 340px;--mdc-plain-tooltip-supporting-text-padding: 8px}\n"] }); }
55
+ }
56
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AccessSettingsComponent, decorators: [{
57
+ type: Component,
58
+ args: [{ selector: "sb-uic-access-settings", template: ` <p>access settings works!</p> `, styles: ["::ng-deep .mdc-tooltip{--mdc-plain-tooltip-container-color: #616161;--mdc-plain-tooltip-supporting-text-color: #ffffff;--mdc-plain-tooltip-container-shape: 4px;--mdc-plain-tooltip-container-size: 340px;--mdc-plain-tooltip-supporting-text-padding: 8px}\n"] }]
59
+ }], ctorParameters: function () { return []; } });
60
+
61
+ class SnackbarComponent {
62
+ constructor(snackBarRef) {
63
+ this.snackBarRef = snackBarRef;
64
+ this.data = inject(MAT_LEGACY_SNACK_BAR_DATA);
65
+ }
66
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SnackbarComponent, deps: [{ token: i1.MatLegacySnackBarRef }], target: i0.ɵɵFactoryTarget.Component }); }
67
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SnackbarComponent, selector: "sb-uic-snackbar", ngImport: i0, template: "<div class=\"snackbar-wrapper\">\n <div class=\"flex items-center justify-between\">\n <div class=\"message flex items-center gap-4\">\n <ng-container *ngIf=\"data?.type === 'success'\">\n <mat-icon class=\"text-white\">check</mat-icon>\n </ng-container>\n\n <ng-container *ngIf=\"data?.type === 'error'\">\n <img src=\"/assets/icons/error-icon.svg\" alt=\"error\" width=\"24\" height=\"24\" style=\"filter: brightness(0) invert(1)\" />\n </ng-container>\n\n <span class=\"text-white\">{{ data?.message }}</span>\n </div>\n\n <div class=\"close\">\n <mat-icon class=\"cursor-pointer text-white\" (click)=\"snackBarRef.dismiss()\"> close </mat-icon>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
68
+ }
69
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SnackbarComponent, decorators: [{
70
+ type: Component,
71
+ args: [{ selector: "sb-uic-snackbar", changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"snackbar-wrapper\">\n <div class=\"flex items-center justify-between\">\n <div class=\"message flex items-center gap-4\">\n <ng-container *ngIf=\"data?.type === 'success'\">\n <mat-icon class=\"text-white\">check</mat-icon>\n </ng-container>\n\n <ng-container *ngIf=\"data?.type === 'error'\">\n <img src=\"/assets/icons/error-icon.svg\" alt=\"error\" width=\"24\" height=\"24\" style=\"filter: brightness(0) invert(1)\" />\n </ng-container>\n\n <span class=\"text-white\">{{ data?.message }}</span>\n </div>\n\n <div class=\"close\">\n <mat-icon class=\"cursor-pointer text-white\" (click)=\"snackBarRef.dismiss()\"> close </mat-icon>\n </div>\n </div>\n</div>\n" }]
72
+ }], ctorParameters: function () { return [{ type: i1.MatLegacySnackBarRef }]; } });
73
+
74
+ class AccessSettingsModule {
75
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AccessSettingsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
76
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: AccessSettingsModule, declarations: [AccessSettingsComponent, SnackbarComponent], imports: [MatIconModule, CommonModule], exports: [AccessSettingsComponent] }); }
77
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AccessSettingsModule, imports: [MatIconModule, CommonModule] }); }
78
+ }
79
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AccessSettingsModule, decorators: [{
80
+ type: NgModule,
81
+ args: [{
82
+ declarations: [AccessSettingsComponent, SnackbarComponent],
83
+ imports: [MatIconModule, CommonModule],
84
+ exports: [AccessSettingsComponent]
85
+ }]
86
+ }] });
87
+
88
+ class DragDropDirective {
89
+ constructor() {
90
+ this.fileDropped = new EventEmitter();
91
+ this.opacity = "1";
92
+ }
93
+ // Dragover listener
94
+ onDragOver(evt) {
95
+ evt.preventDefault();
96
+ evt.stopPropagation();
97
+ this.opacity = "0.4";
98
+ }
99
+ // Dragleave listener
100
+ onDragLeave(evt) {
101
+ evt.preventDefault();
102
+ evt.stopPropagation();
103
+ this.opacity = "1.0";
104
+ }
105
+ // Drop listener
106
+ ondrop(evt) {
107
+ evt.preventDefault();
108
+ evt.stopPropagation();
109
+ const files = evt.dataTransfer.files[0];
110
+ this.opacity = "1.0";
111
+ if (files) {
112
+ this.fileDropped.emit(files);
113
+ }
114
+ }
115
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DragDropDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
116
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: DragDropDirective, selector: "[wsAuthDragDrop]", outputs: { fileDropped: "fileDropped" }, host: { listeners: { "dragover": "onDragOver($event)", "dragleave": "onDragLeave($event)", "drop": "ondrop($event)" }, properties: { "style.opacity": "this.opacity" } }, ngImport: i0 }); }
117
+ }
118
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DragDropDirective, decorators: [{
119
+ type: Directive,
120
+ args: [{
121
+ selector: "[wsAuthDragDrop]",
122
+ }]
123
+ }], propDecorators: { fileDropped: [{
124
+ type: Output
125
+ }], opacity: [{
126
+ type: HostBinding,
127
+ args: ["style.opacity"]
128
+ }], onDragOver: [{
129
+ type: HostListener,
130
+ args: ["dragover", ["$event"]]
131
+ }], onDragLeave: [{
132
+ type: HostListener,
133
+ args: ["dragleave", ["$event"]]
134
+ }], ondrop: [{
135
+ type: HostListener,
136
+ args: ["drop", ["$event"]]
137
+ }] } });
138
+
139
+ const ENDPOINTS = {
140
+ SEARCH_USER_WITH_ADMIN: (query) => `/apis/proxies/v8/user/v1/autocomplete/${query}`,
141
+ SEARCH_USER: `/apis/proxies/v8/user/v1/admin/search`,
142
+ SEARCH_ORG: "/apis/proxies/v8/org/v1/admin/search",
143
+ VALIDATE_USER: "/apis/proxies/v8/user/v1/search",
144
+ GROUPS: "/apis/proxies/v8/user/v1/groups",
145
+ CADRE_CONFIG: "/apis/proxies/v8/data/v2/system/settings/get/cadreConfig",
146
+ DESIGNATION_LIST: "/apis/proxies/v8/designation/search",
147
+ SEARCH_V4: "/apis/proxies/v8/sunbirdigot/v4/search",
148
+ CREATE_USERGROUPS_CONTROL: "/apis/proxies/v8/accessSetttings/v1/upsert",
149
+ GET_ACCESS_CONTROL: (id) => `/apis/proxies/v8/accessSetttings/read/${id}`,
150
+ ACTION_CONTENT_V3: `apis/proxies/v8/action/content/v3/`
151
+ };
152
+ class AccessControlService {
153
+ constructor(http) {
154
+ this.http = http;
155
+ this.accessControlConfig = signal(null);
156
+ this.holdServiceCadrebatch = signal({
157
+ service: [],
158
+ batch: [],
159
+ cadre: []
160
+ });
161
+ }
162
+ fetchUserListWithAdmin(queryString) {
163
+ return this.http.get(ENDPOINTS.SEARCH_USER_WITH_ADMIN(queryString));
164
+ }
165
+ fetchUserList(query, pagination, userIds) {
166
+ let request = {
167
+ filters: {
168
+ "profileDetails.profileStatus": ["VERIFIED", "NOT-VERIFIED"],
169
+ status: 1
170
+ },
171
+ limit: pagination.limit || 5,
172
+ offset: pagination.offset || 0,
173
+ query: query,
174
+ sort_by: {
175
+ firstName: "asc"
176
+ }
177
+ };
178
+ if (userIds?.length) {
179
+ request.filters = { ...request.filters, userId: userIds };
180
+ }
181
+ return this.http.post(ENDPOINTS.SEARCH_USER, { request: request });
182
+ }
183
+ fetchOrgList(query, pagination) {
184
+ const request = {
185
+ request: {
186
+ filters: {},
187
+ sort_by: {
188
+ channel: "asc"
189
+ },
190
+ fields: ["channel", "identifier"],
191
+ // limit: pagination.limit || 5,
192
+ // offset: pagination.offset || 0,
193
+ query: query
194
+ }
195
+ };
196
+ return this.http.post(ENDPOINTS.SEARCH_ORG, request);
197
+ }
198
+ validateUser(request) {
199
+ return this.http.post(ENDPOINTS.VALIDATE_USER, request);
200
+ }
201
+ fetchGroupsList() {
202
+ return this.http.get(ENDPOINTS.GROUPS);
203
+ }
204
+ fetchCadreConfig() {
205
+ return this.http.get(ENDPOINTS.CADRE_CONFIG);
206
+ }
207
+ fetchDesignation(query) {
208
+ const payload = {
209
+ filterCriteriaMap: {
210
+ status: "Active"
211
+ },
212
+ requestedFields: ["designation", "id"],
213
+ searchString: query
214
+ };
215
+ return this.http.post(ENDPOINTS.DESIGNATION_LIST, payload);
216
+ }
217
+ fetchDesignationsWithOrg(categories, query) {
218
+ const payload = {
219
+ request: {
220
+ filters: {
221
+ status: "Live",
222
+ category: "designation",
223
+ categories: categories,
224
+ objectType: "Term"
225
+ },
226
+ fields: ["identifier", "name"],
227
+ query: query,
228
+ sort_by: {
229
+ lastUpdatedOn: "desc",
230
+ objectType: "Term"
231
+ },
232
+ facets: []
233
+ }
234
+ };
235
+ return this.http.post(ENDPOINTS.SEARCH_V4, payload);
236
+ }
237
+ applyUserGroupAccessControl(request) {
238
+ return this.http.put(ENDPOINTS.CREATE_USERGROUPS_CONTROL, request);
239
+ }
240
+ fetchUserGroupAccessControl(id) {
241
+ return this.http.get(ENDPOINTS.GET_ACCESS_CONTROL(id));
242
+ }
243
+ updateContentV3(meta, id) {
244
+ return this.http.patch(`${ENDPOINTS.ACTION_CONTENT_V3}update/${id}`, meta);
245
+ }
246
+ downloadFile(data, filename = "data") {
247
+ const csvData = this.convertToCSV(data, ["email", "status", "mobile", "message"]);
248
+ const blob = new Blob([`\ufeff${csvData}`], { type: "text/csv;charset=utf-8;" });
249
+ const dwldLink = document.createElement("a");
250
+ const url = URL.createObjectURL(blob);
251
+ const isSafariBrowser = navigator.userAgent.indexOf("Safari") !== -1 && navigator.userAgent.indexOf("Chrome") === -1;
252
+ if (isSafariBrowser) {
253
+ // if Safari open in new window to save file with random filename.
254
+ dwldLink.setAttribute("target", "_blank");
255
+ }
256
+ dwldLink.setAttribute("href", url);
257
+ dwldLink.setAttribute("download", `${filename}.csv`);
258
+ dwldLink.style.visibility = "hidden";
259
+ document.body.appendChild(dwldLink);
260
+ dwldLink.click();
261
+ document.body.removeChild(dwldLink);
262
+ }
263
+ convertToCSV(objArray, headerList) {
264
+ const array = typeof objArray !== "object" ? JSON.parse(objArray) : objArray;
265
+ let str = "";
266
+ let row = "S.No,";
267
+ for (const index in headerList) {
268
+ if (headerList[index]) {
269
+ row += `${headerList[index]} ,`;
270
+ }
271
+ }
272
+ row = row.slice(0, -1);
273
+ str += `${row}\r\n`;
274
+ // for (let i = 0; i < array.length; i += 1) {
275
+ for (const iIndex in array) {
276
+ if (array[iIndex]) {
277
+ let line = `${toNumber(iIndex) + 1} `;
278
+ for (const index in headerList) {
279
+ if (headerList[index]) {
280
+ const head = headerList[index];
281
+ line += `, ${array[iIndex][head]}`;
282
+ }
283
+ }
284
+ str += `${line}\r\n`;
285
+ }
286
+ }
287
+ return str;
288
+ }
289
+ createRequestContent(apiResponse, accessSettingsEnabled) {
290
+ return {
291
+ request: {
292
+ content: {
293
+ appIcon: apiResponse.appIcon || "",
294
+ posterImage: apiResponse.posterImage || "",
295
+ code: apiResponse.code || "",
296
+ contentType: apiResponse.contentType || "",
297
+ createdBy: apiResponse.createdBy || "",
298
+ creatorContacts: apiResponse.creatorContacts || [],
299
+ creatorIDs: apiResponse.creatorIDs || [],
300
+ createdFor: apiResponse.createdFor || [],
301
+ creator: apiResponse.creator || "",
302
+ framework: apiResponse.framework || "",
303
+ mimeType: apiResponse.mimeType || "",
304
+ name: apiResponse.name || "",
305
+ organisation: apiResponse.organisation || [],
306
+ isExternal: apiResponse.isExternal || false,
307
+ primaryCategory: apiResponse.primaryCategory || "",
308
+ courseCategory: apiResponse.courseCategory || "",
309
+ license: apiResponse.license || "",
310
+ ownershipType: apiResponse.ownershipType || [],
311
+ cumulativeTracking: apiResponse.cumulativeTracking || false,
312
+ language: apiResponse.language || [],
313
+ accessSetting: apiResponse.accessSetting || "",
314
+ versionKey: apiResponse.versionKey || "",
315
+ accessSettingsEnabled: accessSettingsEnabled || false
316
+ }
317
+ }
318
+ };
319
+ }
320
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AccessControlService, deps: [{ token: i1$1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
321
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AccessControlService, providedIn: "root" }); }
322
+ }
323
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AccessControlService, decorators: [{
324
+ type: Injectable,
325
+ args: [{
326
+ providedIn: "root"
327
+ }]
328
+ }], ctorParameters: function () { return [{ type: i1$1.HttpClient }]; } });
329
+
330
+ class PaginationComponent {
331
+ constructor() {
332
+ this._currentPage = 1;
333
+ this.defaultPaginationSize = 10;
334
+ this.defaultPaginationSizeOptions = [];
335
+ this.totalItemsCount = 0;
336
+ this.pageChange = new EventEmitter();
337
+ this.pagination = [];
338
+ this.showingArray = [];
339
+ this.lastPage = 0;
340
+ this.firstPage = 0;
341
+ this.previousPage = 0;
342
+ }
343
+ set currentPage(value) {
344
+ if (this._currentPage !== value) {
345
+ this._currentPage = value;
346
+ this.paginationInListing();
347
+ }
348
+ }
349
+ get currentPage() {
350
+ return this._currentPage;
351
+ }
352
+ ngOnInit() {
353
+ this.paginationInListing();
354
+ }
355
+ ngOnChanges(changes) {
356
+ if (changes.totalItemsCount &&
357
+ changes.totalItemsCount.previousValue &&
358
+ changes.totalItemsCount.currentValue !==
359
+ changes.totalItemsCount.previousValue) {
360
+ this.paginationInListing();
361
+ }
362
+ }
363
+ paginationInListing() {
364
+ let lower = 0;
365
+ let upper = 0;
366
+ let limit = this.defaultPaginationSize;
367
+ let items = this.totalItemsCount;
368
+ this.showingArray = [];
369
+ for (let i = 0; i < items; i++) {
370
+ if (upper !== items && upper < items) {
371
+ lower = upper;
372
+ if (upper != items && (upper = lower + limit) <= items) {
373
+ upper = lower + limit;
374
+ }
375
+ else {
376
+ upper = items;
377
+ }
378
+ this.showingArray.push([lower, upper]);
379
+ }
380
+ }
381
+ let dividedPagination = Math.ceil(this.totalItemsCount / limit);
382
+ let paginationLength = this.paginationDup(this.currentPage, dividedPagination);
383
+ let currentIndex = this.showingArray[this.currentPage - 1];
384
+ let lowerPagination = this.totalItemsCount ? currentIndex[0] + 1 : "";
385
+ let upperPagination = this.totalItemsCount ? currentIndex[1] : "";
386
+ this.lastPage = paginationLength[paginationLength.length - 1];
387
+ this.firstPage = paginationLength[0];
388
+ this.pagination = {
389
+ dividedPagination: dividedPagination,
390
+ paginationLength: paginationLength,
391
+ lower: lowerPagination,
392
+ upper: upperPagination,
393
+ };
394
+ }
395
+ paginationDup(c, m) {
396
+ let current = c;
397
+ let last = m;
398
+ let delta = 5;
399
+ let left = current - delta;
400
+ let right = current + delta + 1;
401
+ let range = [];
402
+ let l;
403
+ this.rangeWithDots = [];
404
+ for (let i = 1; i <= last; i++) {
405
+ if (i == 1 || i == last || (i >= left && i < right)) {
406
+ range.push(i);
407
+ }
408
+ }
409
+ for (let i of range) {
410
+ if (l) {
411
+ if (i - l === 2) {
412
+ this.rangeWithDots.push(l + 1);
413
+ }
414
+ else if (i - l !== 1) {
415
+ this.rangeWithDots.push("...");
416
+ }
417
+ }
418
+ this.rangeWithDots.push(i);
419
+ l = i;
420
+ }
421
+ return this.rangeWithDots;
422
+ }
423
+ goToPage(page) {
424
+ this.currentPage = page;
425
+ this.pageChange.emit({
426
+ currentPage: this.currentPage,
427
+ previousPage: this.previousPage,
428
+ limit: this.defaultPaginationSize,
429
+ });
430
+ this.paginationInListing();
431
+ }
432
+ // TODO: May need to implement in future
433
+ navigateToLastPage(page) {
434
+ if (page != this.currentPage) {
435
+ this.goToPage(page);
436
+ }
437
+ }
438
+ // TODO: May need to implement in future
439
+ navigateToFirstPage(page) {
440
+ if (page != this.currentPage) {
441
+ this.goToPage(page);
442
+ }
443
+ }
444
+ navigateToNextPage(page) {
445
+ if (page <=
446
+ (this.pagination.paginationLength &&
447
+ this.pagination.paginationLength[this.pagination.paginationLength.length - 1])) {
448
+ this.currentPage = this.currentPage + 1;
449
+ this.previousPage = page;
450
+ this.goToPage(this.currentPage);
451
+ }
452
+ }
453
+ navigateToPrevPage(page) {
454
+ if (page <=
455
+ (this.pagination.paginationLength &&
456
+ this.pagination.paginationLength[this.pagination.paginationLength.length - 1])) {
457
+ this.currentPage = this.currentPage - 1;
458
+ this.previousPage = page;
459
+ this.goToPage(this.currentPage);
460
+ }
461
+ }
462
+ onChangePageSize(event) {
463
+ this.defaultPaginationSize = event.value;
464
+ this.currentPage = 1;
465
+ this.previousPage = 0;
466
+ this.paginationInListing();
467
+ this.pageChange.emit({
468
+ currentPage: this.currentPage,
469
+ previousPage: this.previousPage,
470
+ limit: this.defaultPaginationSize,
471
+ });
472
+ }
473
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: PaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
474
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: PaginationComponent, selector: "sb-uic-pagination", inputs: { defaultPaginationSize: "defaultPaginationSize", defaultPaginationSizeOptions: "defaultPaginationSizeOptions", totalItemsCount: "totalItemsCount", currentPage: "currentPage" }, outputs: { pageChange: "pageChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"ws-pagination-wrapper px-4 mt-3\">\n <div class=\"pagination-size-select mat-full-radius-select flex items-center gap-2\">\n <span class=\"text-xs font-normal hidden md:block\">Show Entries</span>\n <mat-form-field appearance=\"outline\">\n <mat-select [(value)]=\"defaultPaginationSize\" (selectionChange)=\"onChangePageSize($event)\">\n <ng-container *ngFor=\"let option of defaultPaginationSizeOptions\">\n <mat-option [value]=\"option\">{{option}}</mat-option>\n </ng-container>\n </mat-select>\n </mat-form-field>\n </div>\n <ul class=\"pagination\">\n <div class=\"pagination-listing flex items-center\">\n <ng-container\n *ngFor=\"let count of pagination?.paginationLength; let last = last; let first = first; let i = index\">\n <li class=\"page-item\" *ngIf=\"first\" (click)=\"navigateToPrevPage(currentPage)\"\n [ngClass]=\"{disabled: currentPage === firstPage}\">\n <a class=\"page-link\" aria-label=\"Previous\">\n <span aria-hidden=\"true\"><mat-icon>keyboard_arrow_left</mat-icon></span>\n </a>\n </li>\n <li class=\"page-item flex items-center justify-center\" [ngClass]=\"count == currentPage ? 'active' : '' \"\n (click)=\"goToPage(count)\">\n <a class=\"page-link\">{{count}}</a>\n </li>\n <li class=\"page-item\" *ngIf=\"last\" (click)=\"navigateToNextPage(currentPage)\"\n [ngClass]=\"{disabled: currentPage === lastPage}\">\n <a class=\" page-link\" aria-label=\"Next\">\n <span aria-hidden=\"true\"><mat-icon>keyboard_arrow_right</mat-icon></span>\n </a>\n </li>\n\n </ng-container>\n </div>\n </ul>\n</div>", styles: [".ws-pagination-wrapper{display:flex;align-items:center;justify-content:space-between;background-color:#fff;border-top:1px solid rgba(0,0,0,.0784313725)}.ws-pagination-wrapper .pagination-size-select span{font-family:Lato;line-height:100%;color:#666}ul{list-style:none;gap:4px}ul li{width:32px;height:24px;text-align:center}ul li a{color:#666;font-size:14px;border:0;font-family:Lato;font-weight:400;font-size:12px;line-height:14.4px;letter-spacing:0%;text-align:center}ul li:hover{border-radius:99px;cursor:pointer;background-color:#f5f5f5}ul li.active{background:#1b4ca1;border-radius:99px}ul li.active a{color:#fff!important}::ng-deep .pagination-size-select.mat-full-radius-select mat-form-field{height:40px!important;max-width:80px!important}::ng-deep .pagination-size-select.mat-full-radius-select .mat-form-field-appearance-outline .mat-form-field-infix{padding:0 0 8px!important}::ng-deep .pagination-size-select.mat-full-radius-select .mat-form-field-wrapper{padding-bottom:0!important}.page-item.disabled{pointer-events:none;opacity:.5;cursor:not-allowed}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i7.MatLegacyFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "component", type: i4.MatLegacySelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i5.MatLegacyOption, selector: "mat-option", exportAs: ["matOption"] }] }); }
475
+ }
476
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: PaginationComponent, decorators: [{
477
+ type: Component,
478
+ args: [{ selector: "sb-uic-pagination", template: "<div class=\"ws-pagination-wrapper px-4 mt-3\">\n <div class=\"pagination-size-select mat-full-radius-select flex items-center gap-2\">\n <span class=\"text-xs font-normal hidden md:block\">Show Entries</span>\n <mat-form-field appearance=\"outline\">\n <mat-select [(value)]=\"defaultPaginationSize\" (selectionChange)=\"onChangePageSize($event)\">\n <ng-container *ngFor=\"let option of defaultPaginationSizeOptions\">\n <mat-option [value]=\"option\">{{option}}</mat-option>\n </ng-container>\n </mat-select>\n </mat-form-field>\n </div>\n <ul class=\"pagination\">\n <div class=\"pagination-listing flex items-center\">\n <ng-container\n *ngFor=\"let count of pagination?.paginationLength; let last = last; let first = first; let i = index\">\n <li class=\"page-item\" *ngIf=\"first\" (click)=\"navigateToPrevPage(currentPage)\"\n [ngClass]=\"{disabled: currentPage === firstPage}\">\n <a class=\"page-link\" aria-label=\"Previous\">\n <span aria-hidden=\"true\"><mat-icon>keyboard_arrow_left</mat-icon></span>\n </a>\n </li>\n <li class=\"page-item flex items-center justify-center\" [ngClass]=\"count == currentPage ? 'active' : '' \"\n (click)=\"goToPage(count)\">\n <a class=\"page-link\">{{count}}</a>\n </li>\n <li class=\"page-item\" *ngIf=\"last\" (click)=\"navigateToNextPage(currentPage)\"\n [ngClass]=\"{disabled: currentPage === lastPage}\">\n <a class=\" page-link\" aria-label=\"Next\">\n <span aria-hidden=\"true\"><mat-icon>keyboard_arrow_right</mat-icon></span>\n </a>\n </li>\n\n </ng-container>\n </div>\n </ul>\n</div>", styles: [".ws-pagination-wrapper{display:flex;align-items:center;justify-content:space-between;background-color:#fff;border-top:1px solid rgba(0,0,0,.0784313725)}.ws-pagination-wrapper .pagination-size-select span{font-family:Lato;line-height:100%;color:#666}ul{list-style:none;gap:4px}ul li{width:32px;height:24px;text-align:center}ul li a{color:#666;font-size:14px;border:0;font-family:Lato;font-weight:400;font-size:12px;line-height:14.4px;letter-spacing:0%;text-align:center}ul li:hover{border-radius:99px;cursor:pointer;background-color:#f5f5f5}ul li.active{background:#1b4ca1;border-radius:99px}ul li.active a{color:#fff!important}::ng-deep .pagination-size-select.mat-full-radius-select mat-form-field{height:40px!important;max-width:80px!important}::ng-deep .pagination-size-select.mat-full-radius-select .mat-form-field-appearance-outline .mat-form-field-infix{padding:0 0 8px!important}::ng-deep .pagination-size-select.mat-full-radius-select .mat-form-field-wrapper{padding-bottom:0!important}.page-item.disabled{pointer-events:none;opacity:.5;cursor:not-allowed}\n"] }]
479
+ }], propDecorators: { defaultPaginationSize: [{
480
+ type: Input
481
+ }], defaultPaginationSizeOptions: [{
482
+ type: Input
483
+ }], totalItemsCount: [{
484
+ type: Input
485
+ }], currentPage: [{
486
+ type: Input
487
+ }], pageChange: [{
488
+ type: Output
489
+ }] } });
490
+
491
+ class ListTableComponent {
492
+ constructor(_liveAnnouncer) {
493
+ this._liveAnnouncer = _liveAnnouncer;
494
+ this.data = [];
495
+ this.count = 0;
496
+ this.initialPaginationSize = 5;
497
+ this.initialPaginationSizeOptions = [5, 10, 25, 100];
498
+ this.selectedDataChange = new EventEmitter();
499
+ this.pageChange = new EventEmitter();
500
+ this.removeSelectedData = new EventEmitter();
501
+ this.dataSource = new MatTableDataSource(this.data);
502
+ this.selection = new SelectionModel(true, []);
503
+ this.selectedTablerow = [];
504
+ this.currentPage = 1;
505
+ }
506
+ ngOnInit() { }
507
+ ngOnChanges(changes) {
508
+ // Handle data input change
509
+ if (changes["data"]?.currentValue?.length) {
510
+ const mappedUsers = changes["data"].currentValue.map((user) => ({
511
+ firstName: user?.firstName || user?.profileDetails?.personalDetails?.firstname || "",
512
+ mobile: user?.mobile || user?.profileDetails?.personalDetails?.mobile || "",
513
+ email: user?.email || user?.profileDetails?.personalDetails?.primaryEmail || "",
514
+ ministry: user?.ministry || user?.organisations[0]?.orgName || "",
515
+ invited_on: user?.invited_on || "",
516
+ status: user?.status || "",
517
+ userId: user?.userId || ""
518
+ }));
519
+ this.data = mappedUsers;
520
+ this.dataSource = new MatTableDataSource(mappedUsers);
521
+ }
522
+ if (changes["count"]?.currentValue !== undefined) {
523
+ this.count = changes["count"].currentValue;
524
+ }
525
+ if (changes["selected"]?.currentValue) {
526
+ this.selection.clear();
527
+ if (changes["selected"].currentValue.length > 0) {
528
+ this.dataSource.data.forEach(row => {
529
+ if (changes["selected"].currentValue.some((sel) => sel.userId === row.userId)) {
530
+ this.selection.select(row);
531
+ }
532
+ });
533
+ }
534
+ this.selectedTablerow = this.selection.selected;
535
+ }
536
+ }
537
+ ngAfterViewInit() {
538
+ if (this.tableConfig?.canSortColumn) {
539
+ this.dataSource.sort = this.sort;
540
+ }
541
+ }
542
+ setPaginatedUsers(page) {
543
+ const startIndex = (page - 1) * this.initialPaginationSize;
544
+ const endIndex = startIndex + this.initialPaginationSize;
545
+ const paginatedUsers = this.data.slice(startIndex, endIndex);
546
+ this.dataSource = new MatTableDataSource(paginatedUsers);
547
+ }
548
+ isAllSelected() {
549
+ const numSelected = this.selection.selected.length;
550
+ const numRows = this.dataSource.data.length;
551
+ return numSelected === numRows;
552
+ }
553
+ masterToggle() {
554
+ this.isAllSelected() ? this.selection.clear() : this.dataSource.data.forEach(row => this.selection.select(row));
555
+ this.selectedTablerow = this.selection.selected;
556
+ this.selectedDataChange.emit(this.selectedTablerow);
557
+ }
558
+ toggleSelection(row) {
559
+ this.selection.toggle(row);
560
+ this.selectedTablerow = this.selection.selected;
561
+ this.selectedDataChange.emit(this.selectedTablerow);
562
+ }
563
+ onPageChange(event) {
564
+ this.pageChange.emit(event);
565
+ }
566
+ removeUserFromSelected() {
567
+ if (!this.selectedTablerow.length) {
568
+ return;
569
+ }
570
+ const removedList = [...this.selectedTablerow];
571
+ const remainingList = this.data.filter(user => !this.selectedTablerow.some(selected => selected.userId === user.userId));
572
+ this.data = remainingList;
573
+ this.count = remainingList.length;
574
+ this.selectedTablerow = [];
575
+ this.selection.clear();
576
+ this.dataSource = new MatTableDataSource(remainingList);
577
+ if (this.tableConfig?.type === "selectedUsers") {
578
+ this.removeSelectedData.emit({
579
+ remainingList,
580
+ removedList
581
+ });
582
+ }
583
+ }
584
+ onSortChange(sortState) {
585
+ if (sortState.direction) {
586
+ this._liveAnnouncer.announce(`Sorted ${sortState.direction}ending`);
587
+ }
588
+ else {
589
+ this._liveAnnouncer.announce("Sorting cleared");
590
+ }
591
+ }
592
+ refreshSelected() {
593
+ this.selection.clear();
594
+ }
595
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ListTableComponent, deps: [{ token: i1$2.LiveAnnouncer }], target: i0.ɵɵFactoryTarget.Component }); }
596
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ListTableComponent, selector: "sb-uic-list-table", inputs: { data: "data", count: "count", initialPaginationSize: "initialPaginationSize", initialPaginationSizeOptions: "initialPaginationSizeOptions", tableConfig: "tableConfig", selected: "selected", bulkUploadEntriesCount: "bulkUploadEntriesCount" }, outputs: { selectedDataChange: "selectedDataChange", pageChange: "pageChange", removeSelectedData: "removeSelectedData" }, viewQueries: [{ propertyName: "sort", first: true, predicate: MatSort, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"wrapper-user-table\">\n <div class=\"selections-meta\">\n <div class=\"flex items-center justify-between p-2\">\n <div class=\"flex items-center gap-2 selection-count\" *ngIf=\"tableConfig?.canShowSelectedItems || false\">\n <span class=\"\">{{selectedTablerow.length}}</span>\n <span class=\"text-sm font-normal\">Items Selected</span>\n </div>\n <div class=\"flex items-center gap-2 actions-selections ml-auto\">\n <button mat-button color=\"primary\" class=\"text-sm font-normal action-refresh-btn\" (click)=\"refreshSelected()\"\n *ngIf=\"tableConfig?.canShowRefreshBtn || false\">\n <mat-icon>refresh</mat-icon>\n Refresh\n </button>\n\n <button mat-button color=\"warn\" class=\"text-sm font-bold action-delete-btn\"\n (click)=\"removeUserFromSelected()\" *ngIf=\"tableConfig?.canShowDeleteBtn || false\">\n <mat-icon>delete</mat-icon>\n Delete\n </button>\n </div>\n </div>\n </div>\n\n <table mat-table [dataSource]=\"dataSource\" matSort (matSortChange)=\"onSortChange($event)\">\n <!-- Checkbox Column -->\n <ng-container matColumnDef=\"select\">\n <th mat-header-cell *matHeaderCellDef>\n <ng-container *ngIf=\"tableConfig?.canShowMasterSelect\">\n <mat-checkbox (change)=\"$event ? masterToggle() : null\"\n [checked]=\"selection.hasValue() && isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\">\n </mat-checkbox>\n </ng-container>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"toggleSelection(row)\"\n [checked]=\"selection.isSelected(row)\">\n </mat-checkbox>\n </td>\n </ng-container>\n\n <!-- first_name Column -->\n <ng-container matColumnDef=\"firstName\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header> First Name </th>\n <td mat-cell *matCellDef=\"let element\"> {{element?.firstName}} </td>\n </ng-container>\n\n <!-- Email Column -->\n <ng-container matColumnDef=\"email\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header> Email </th>\n <td mat-cell *matCellDef=\"let element\"> {{element?.email}} </td>\n </ng-container>\n\n <!-- ministry Column -->\n <ng-container matColumnDef=\"ministry\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header> Ministry </th>\n <td mat-cell *matCellDef=\"let element\">\n <span class=\"truncated-text \">\n {{element?.ministry}}\n </span>\n </td>\n </ng-container>\n\n <!-- mobile_no Column -->\n <ng-container matColumnDef=\"mobile\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header> Mobile No </th>\n <td mat-cell *matCellDef=\"let element\">\n {{element?.mobile}}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"invited_on\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header> Invited On </th>\n <td mat-cell *matCellDef=\"let element\">\n {{element?.invited_on}}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"status\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header> Status </th>\n <td mat-cell *matCellDef=\"let element\">\n <!-- {{element?.status}} -->\n <div class=\"success-status flex items-center justify-center\">Success</div>\n <!-- <div class=\"rejected-status flex items-center justify-center\">Rejected</div> -->\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"tableConfig?.displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: tableConfig?.displayedColumns;\" (click)=\"selection.toggle(row)\">\n </tr>\n </table>\n <div *ngIf=\"!dataSource.data.length\" class=\"no-data-center\">\n <div class=\"no-data p-4 flex flex-column items-center justify-center\">\n <img src=\"/assets/icons/no-events.png\" alt=\"no-data\">\n <span class=\"font-bold\">No information to display yet</span>\n </div>\n </div>\n <ng-container *ngIf=\"count && tableConfig?.canShowPagination\">\n <div class=\"pagination-users\">\n <sb-uic-pagination [defaultPaginationSize]=\"initialPaginationSize\"\n [defaultPaginationSizeOptions]=\"initialPaginationSizeOptions\" [totalItemsCount]=\"count\"\n [currentPage]=\"1\" (pageChange)=\"onPageChange($event)\">\n </sb-uic-pagination>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"bulkUploadEntriesCount\">\n <div class=\"text-xs text-[#666666] p-4 border-t border-black/15\">\n {{bulkUploadEntriesCount?.success}}/{{bulkUploadEntriesCount?.totalCount}} entries uploaded successfully\n </div>\n </ng-container>\n\n\n</div>", styles: ["::ng-deep .mat-column-select{text-align:center}::ng-deep .mat-column-email{width:213px}.truncated-text{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;line-height:1.4em;max-height:2.8em;width:213px}.wrapper-user-table{margin-top:16px;border:1px solid rgba(0,0,0,.1607843137);border-radius:4px}.selection-count span{font-family:Lato;font-weight:400}.selection-count span:first-child{background:#d1dbec;border:1px solid rgba(0,0,0,.1607843137);border-radius:50%;padding:4px;height:18px;width:18px;display:flex;align-items:center;justify-content:center;font-size:10px;color:#0009}.selection-count span:nth-child(2){font-size:14px;color:#000000de}.actions-selections{height:22px}.actions-selections button{font-family:Lato;font-weight:400;font-size:14px;background:none;border:none;padding:8px 4px;min-width:unset}.actions-selections button.action-refresh-btn{color:#1b4ca1!important}.actions-selections button.action-refresh-btn mat-icon{color:#1b4ca1!important}.actions-selections button.action-delete-btn{color:#d13924}.actions-selections button.action-delete-btn mat-icon{color:#d13924}.actions-selections button ::ng-deep .mat-button-wrapper{display:flex;align-items:center;gap:4px;height:22px}:host ::ng-deep .mat-mdc-table .mat-mdc-header-cell,:host ::ng-deep .mat-mdc-table .mat-mdc-cell{border-top:1px solid rgba(0,0,0,.1607843137);border-right:1px solid rgba(0,0,0,.1607843137)}:host ::ng-deep .mat-mdc-header-cell{font-family:Montserrat;font-weight:600;font-size:14px;color:#1b2133}.success-status{width:62px;height:22px;border-radius:4px;padding:4px 12px;font-family:Lato;font-weight:400;font-size:12px;background:#1d8923;text-align:center;color:#fff}.no-data span{font-family:Lato;font-size:8.98px;color:#000000de}\n"], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i4$1.MatLegacyCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i5$1.MatLegacyButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i6.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { kind: "directive", type: i6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i7$1.MatSort, selector: "[matSort]", inputs: ["matSortDisabled", "matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i7$1.MatSortHeader, selector: "[mat-sort-header]", inputs: ["disabled", "mat-sort-header", "arrowPosition", "start", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: PaginationComponent, selector: "sb-uic-pagination", inputs: ["defaultPaginationSize", "defaultPaginationSizeOptions", "totalItemsCount", "currentPage"], outputs: ["pageChange"] }] }); }
597
+ }
598
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ListTableComponent, decorators: [{
599
+ type: Component,
600
+ args: [{ selector: "sb-uic-list-table", template: "<div class=\"wrapper-user-table\">\n <div class=\"selections-meta\">\n <div class=\"flex items-center justify-between p-2\">\n <div class=\"flex items-center gap-2 selection-count\" *ngIf=\"tableConfig?.canShowSelectedItems || false\">\n <span class=\"\">{{selectedTablerow.length}}</span>\n <span class=\"text-sm font-normal\">Items Selected</span>\n </div>\n <div class=\"flex items-center gap-2 actions-selections ml-auto\">\n <button mat-button color=\"primary\" class=\"text-sm font-normal action-refresh-btn\" (click)=\"refreshSelected()\"\n *ngIf=\"tableConfig?.canShowRefreshBtn || false\">\n <mat-icon>refresh</mat-icon>\n Refresh\n </button>\n\n <button mat-button color=\"warn\" class=\"text-sm font-bold action-delete-btn\"\n (click)=\"removeUserFromSelected()\" *ngIf=\"tableConfig?.canShowDeleteBtn || false\">\n <mat-icon>delete</mat-icon>\n Delete\n </button>\n </div>\n </div>\n </div>\n\n <table mat-table [dataSource]=\"dataSource\" matSort (matSortChange)=\"onSortChange($event)\">\n <!-- Checkbox Column -->\n <ng-container matColumnDef=\"select\">\n <th mat-header-cell *matHeaderCellDef>\n <ng-container *ngIf=\"tableConfig?.canShowMasterSelect\">\n <mat-checkbox (change)=\"$event ? masterToggle() : null\"\n [checked]=\"selection.hasValue() && isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\">\n </mat-checkbox>\n </ng-container>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"toggleSelection(row)\"\n [checked]=\"selection.isSelected(row)\">\n </mat-checkbox>\n </td>\n </ng-container>\n\n <!-- first_name Column -->\n <ng-container matColumnDef=\"firstName\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header> First Name </th>\n <td mat-cell *matCellDef=\"let element\"> {{element?.firstName}} </td>\n </ng-container>\n\n <!-- Email Column -->\n <ng-container matColumnDef=\"email\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header> Email </th>\n <td mat-cell *matCellDef=\"let element\"> {{element?.email}} </td>\n </ng-container>\n\n <!-- ministry Column -->\n <ng-container matColumnDef=\"ministry\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header> Ministry </th>\n <td mat-cell *matCellDef=\"let element\">\n <span class=\"truncated-text \">\n {{element?.ministry}}\n </span>\n </td>\n </ng-container>\n\n <!-- mobile_no Column -->\n <ng-container matColumnDef=\"mobile\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header> Mobile No </th>\n <td mat-cell *matCellDef=\"let element\">\n {{element?.mobile}}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"invited_on\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header> Invited On </th>\n <td mat-cell *matCellDef=\"let element\">\n {{element?.invited_on}}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"status\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header> Status </th>\n <td mat-cell *matCellDef=\"let element\">\n <!-- {{element?.status}} -->\n <div class=\"success-status flex items-center justify-center\">Success</div>\n <!-- <div class=\"rejected-status flex items-center justify-center\">Rejected</div> -->\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"tableConfig?.displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: tableConfig?.displayedColumns;\" (click)=\"selection.toggle(row)\">\n </tr>\n </table>\n <div *ngIf=\"!dataSource.data.length\" class=\"no-data-center\">\n <div class=\"no-data p-4 flex flex-column items-center justify-center\">\n <img src=\"/assets/icons/no-events.png\" alt=\"no-data\">\n <span class=\"font-bold\">No information to display yet</span>\n </div>\n </div>\n <ng-container *ngIf=\"count && tableConfig?.canShowPagination\">\n <div class=\"pagination-users\">\n <sb-uic-pagination [defaultPaginationSize]=\"initialPaginationSize\"\n [defaultPaginationSizeOptions]=\"initialPaginationSizeOptions\" [totalItemsCount]=\"count\"\n [currentPage]=\"1\" (pageChange)=\"onPageChange($event)\">\n </sb-uic-pagination>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"bulkUploadEntriesCount\">\n <div class=\"text-xs text-[#666666] p-4 border-t border-black/15\">\n {{bulkUploadEntriesCount?.success}}/{{bulkUploadEntriesCount?.totalCount}} entries uploaded successfully\n </div>\n </ng-container>\n\n\n</div>", styles: ["::ng-deep .mat-column-select{text-align:center}::ng-deep .mat-column-email{width:213px}.truncated-text{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;line-height:1.4em;max-height:2.8em;width:213px}.wrapper-user-table{margin-top:16px;border:1px solid rgba(0,0,0,.1607843137);border-radius:4px}.selection-count span{font-family:Lato;font-weight:400}.selection-count span:first-child{background:#d1dbec;border:1px solid rgba(0,0,0,.1607843137);border-radius:50%;padding:4px;height:18px;width:18px;display:flex;align-items:center;justify-content:center;font-size:10px;color:#0009}.selection-count span:nth-child(2){font-size:14px;color:#000000de}.actions-selections{height:22px}.actions-selections button{font-family:Lato;font-weight:400;font-size:14px;background:none;border:none;padding:8px 4px;min-width:unset}.actions-selections button.action-refresh-btn{color:#1b4ca1!important}.actions-selections button.action-refresh-btn mat-icon{color:#1b4ca1!important}.actions-selections button.action-delete-btn{color:#d13924}.actions-selections button.action-delete-btn mat-icon{color:#d13924}.actions-selections button ::ng-deep .mat-button-wrapper{display:flex;align-items:center;gap:4px;height:22px}:host ::ng-deep .mat-mdc-table .mat-mdc-header-cell,:host ::ng-deep .mat-mdc-table .mat-mdc-cell{border-top:1px solid rgba(0,0,0,.1607843137);border-right:1px solid rgba(0,0,0,.1607843137)}:host ::ng-deep .mat-mdc-header-cell{font-family:Montserrat;font-weight:600;font-size:14px;color:#1b2133}.success-status{width:62px;height:22px;border-radius:4px;padding:4px 12px;font-family:Lato;font-weight:400;font-size:12px;background:#1d8923;text-align:center;color:#fff}.no-data span{font-family:Lato;font-size:8.98px;color:#000000de}\n"] }]
601
+ }], ctorParameters: function () { return [{ type: i1$2.LiveAnnouncer }]; }, propDecorators: { data: [{
602
+ type: Input
603
+ }], count: [{
604
+ type: Input
605
+ }], initialPaginationSize: [{
606
+ type: Input
607
+ }], initialPaginationSizeOptions: [{
608
+ type: Input
609
+ }], tableConfig: [{
610
+ type: Input
611
+ }], selected: [{
612
+ type: Input
613
+ }], bulkUploadEntriesCount: [{
614
+ type: Input
615
+ }], selectedDataChange: [{
616
+ type: Output
617
+ }], pageChange: [{
618
+ type: Output
619
+ }], removeSelectedData: [{
620
+ type: Output
621
+ }], sort: [{
622
+ type: ViewChild,
623
+ args: [MatSort]
624
+ }] } });
625
+
626
+ class BulkUploadKarmayogiComponent {
627
+ constructor(accessControlService, snackBar) {
628
+ this.accessControlService = accessControlService;
629
+ this.snackBar = snackBar;
630
+ this.currrentFilterType = "success";
631
+ this.contacts = [];
632
+ this.properties = "";
633
+ this.flag = false;
634
+ this.fileUploading = false;
635
+ this.isSuccessUserlist = [];
636
+ this.isErrorUserlist = [];
637
+ this.fileName = "";
638
+ this.currentDate = new Date();
639
+ this.bulkUploadConfig =
640
+ this.accessControlService.accessControlConfig().bulkUploadKarmayogi;
641
+ }
642
+ downloadSample() {
643
+ const sampleFilePath = this.bulkUploadConfig.downloadSampleFile;
644
+ if (sampleFilePath) {
645
+ const link = document.createElement("a");
646
+ link.href = sampleFilePath.path;
647
+ link.download = sampleFilePath.fileName || "sample.csv";
648
+ document.body.appendChild(link);
649
+ link.click();
650
+ document.body.removeChild(link);
651
+ }
652
+ }
653
+ onDrop(input) {
654
+ this.fileUploading = true;
655
+ const files = [input];
656
+ const fileTypes = ["csv"]; // acceptable file types
657
+ if (files && files.length) {
658
+ const extension = files[0].name.split(".").pop().toLowerCase(); // file extension from input file
659
+ const isSuccess = fileTypes.indexOf(extension) > -1; // is extension in acceptable types
660
+ // console.log(isSuccess)
661
+ console.log("Filename: " + files[0].name);
662
+ this.fileName = files[0].name;
663
+ // console.log('Type: ' + files[0].type)
664
+ // console.log('Size: ' + files[0].size + ' bytes')
665
+ if (isSuccess) {
666
+ const fileToRead = files[0];
667
+ const fileReader = new FileReader();
668
+ fileReader.onload = (event) => {
669
+ this.onFileLoad(event);
670
+ };
671
+ fileReader.readAsText(fileToRead, "UTF-8");
672
+ }
673
+ else {
674
+ this.fileUploading = false;
675
+ this.snackBar.openFromComponent(SnackbarComponent, {
676
+ data: {
677
+ message: "Unsupported File Format. Please upload a CSV file.",
678
+ type: "error",
679
+ },
680
+ duration: 3000,
681
+ panelClass: "course-error-snackbar",
682
+ });
683
+ }
684
+ }
685
+ else {
686
+ this.fileUploading = false;
687
+ this.snackBar.openFromComponent(SnackbarComponent, {
688
+ data: {
689
+ message: "Unsupported File Format. Please upload a CSV file.",
690
+ type: "error",
691
+ },
692
+ duration: 3000,
693
+ panelClass: "course-error-snackbar",
694
+ });
695
+ }
696
+ }
697
+ async onFileLoad(fileLoadedEvent) {
698
+ this.isSuccessUserlist = [];
699
+ this.isErrorUserlist = [];
700
+ const textFromFileLoaded = fileLoadedEvent.target.result;
701
+ this.csvContent = textFromFileLoaded;
702
+ // Flag is for extracting first line
703
+ let flag = false;
704
+ // Main Data
705
+ const objarray = [];
706
+ // Properties
707
+ const prop = [];
708
+ // Total Length
709
+ let size = 0;
710
+ for (const line of this.csvContent.split(/[\r\n]+/)) {
711
+ if (flag) {
712
+ const obj = {};
713
+ for (let k = 0; k < size; k += 1) {
714
+ // Dynamic Object Properties
715
+ obj[prop[k]] = line.split(",")[k];
716
+ }
717
+ objarray.push(obj);
718
+ }
719
+ else {
720
+ // First Line of CSV will be having Properties
721
+ for (let k = 0; k < line.split(",").length; k += 1) {
722
+ size = line.split(",").length;
723
+ // Removing all the spaces to make them usefull, also removing any " characters
724
+ prop.push(line.split(",")[k].replace(/ /g, "").replace(/"/g, ""));
725
+ }
726
+ flag = true;
727
+ }
728
+ }
729
+ this.contacts = objarray;
730
+ if (this.contacts && this.contacts.length > 0) {
731
+ const headerValues = Object.keys(this.contacts[0]);
732
+ if (headerValues.length < 0 || headerValues.length > 2) {
733
+ // NOSONAR
734
+ this.fileUploading = false;
735
+ this.snackBar.openFromComponent(SnackbarComponent, {
736
+ data: {
737
+ message: "Field Mismatch. Please ensure your uploaded file matches the sample template provided.",
738
+ type: "error",
739
+ },
740
+ duration: 3000,
741
+ panelClass: "course-error-snackbar",
742
+ });
743
+ return;
744
+ }
745
+ if (!headerValues.includes("Emailid") ||
746
+ !headerValues.includes("Mobilenumber")) {
747
+ this.fileUploading = false;
748
+ this.snackBar.openFromComponent(SnackbarComponent, {
749
+ data: {
750
+ message: "Field Mismatch. Please ensure your uploaded file matches the sample template provided.",
751
+ type: "error",
752
+ },
753
+ duration: 3000,
754
+ panelClass: "course-error-snackbar",
755
+ });
756
+ return;
757
+ }
758
+ }
759
+ this.properties = [];
760
+ this.properties = prop;
761
+ // console.log(this.properties)
762
+ const emailIds = [];
763
+ const mobileNumbers = [];
764
+ const bothEmailAndMobile = {};
765
+ this.contacts = this.contacts.filter((ele) => ele.Emailid || ele.Mobilenumber);
766
+ if (this.contacts.length > 30) {
767
+ this.snackBar.openFromComponent(SnackbarComponent, {
768
+ data: { message: "More than 30 users are not allowed", type: "error" },
769
+ duration: 3000,
770
+ panelClass: "course-error-snackbar",
771
+ });
772
+ this.fileUploading = false;
773
+ }
774
+ else {
775
+ await this.contacts.forEach((element) => {
776
+ const emailPattern = new RegExp(`^[\\w\-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$`);
777
+ const mobilePattern = new RegExp(/^(6|7|8|9)\d{9}$/);
778
+ const emailTest = element.Emailid
779
+ ? emailPattern.test(element.Emailid)
780
+ : true;
781
+ const mobileTest = element.Mobilenumber
782
+ ? mobilePattern.test(element.Mobilenumber)
783
+ : true;
784
+ element["email"] = element.Emailid;
785
+ element["mobile"] = element.Mobilenumber;
786
+ if (mobileTest && element.Mobilenumber) {
787
+ mobileNumbers.push(element.Mobilenumber);
788
+ }
789
+ if (emailTest && element.Emailid) {
790
+ emailIds.push(element.Emailid.toLowerCase());
791
+ }
792
+ if (emailTest && mobileTest) {
793
+ element["status"] = "Success";
794
+ element["userStatus"] = true;
795
+ bothEmailAndMobile[element.Emailid.toLowerCase()] = element;
796
+ }
797
+ else {
798
+ if (emailTest || mobileTest) {
799
+ element["status"] = "Success";
800
+ element["userStatus"] = true;
801
+ if ((!emailTest && element.Mobilenumber !== "") ||
802
+ (!emailTest && element.Mobilenumber === "")) {
803
+ element["status"] = "Error";
804
+ element["userStatus"] = false;
805
+ element["message"] = emailPattern.test(element.Emailid)
806
+ ? ""
807
+ : "Invalid Email id";
808
+ }
809
+ if ((!mobileTest && element.Emailid !== "") ||
810
+ (!mobileTest && element.Emailid === "")) {
811
+ element["status"] = "Error";
812
+ element["userStatus"] = false;
813
+ element["message"] = mobilePattern.test(element.Mobilenumber)
814
+ ? ""
815
+ : "Invalid Mobile number";
816
+ }
817
+ }
818
+ else {
819
+ if (!emailTest && !mobileTest) {
820
+ element["status"] = "Error";
821
+ element["userStatus"] = false;
822
+ element["message"] = "Invalid Email id and Mobile number";
823
+ }
824
+ else {
825
+ element["status"] = "Error";
826
+ element["userStatus"] = false;
827
+ element["message"] = emailPattern.test(element.Emailid)
828
+ ? ""
829
+ : "Invalid Email id";
830
+ element["message"] = mobilePattern.test(element.Mobilenumber)
831
+ ? ""
832
+ : "Invalid Mobile number";
833
+ }
834
+ }
835
+ }
836
+ });
837
+ this.flag = true;
838
+ const emailResponseData = await this.callUserCheckApi(emailIds, "primaryEmail");
839
+ const mobileResponseData = await this.callUserCheckApi(mobileNumbers, "mobile");
840
+ if (emailResponseData && mobileResponseData) {
841
+ this.manageData(emailResponseData, mobileResponseData);
842
+ }
843
+ else {
844
+ this.fileUploading = false;
845
+ this.snackBar.openFromComponent(SnackbarComponent, {
846
+ data: {
847
+ message: "Something went wrong! Please try again",
848
+ type: "error",
849
+ },
850
+ duration: 3000,
851
+ panelClass: "course-error-snackbar",
852
+ });
853
+ }
854
+ }
855
+ }
856
+ async callUserCheckApi(userData, key) {
857
+ const request = {
858
+ request: {
859
+ filters: {},
860
+ fields: [
861
+ "userId",
862
+ "email",
863
+ "firstName",
864
+ "lastName",
865
+ "phone",
866
+ "rootOrgId",
867
+ "channel",
868
+ "roles",
869
+ "profileDetails",
870
+ "createdDate",
871
+ "rootOrgName",
872
+ "organisations",
873
+ "username",
874
+ ],
875
+ },
876
+ };
877
+ if (key === "primaryEmail") {
878
+ request.request.filters = {
879
+ ...request.request.filters,
880
+ email: userData,
881
+ };
882
+ }
883
+ else {
884
+ request.request.filters = {
885
+ ...request.request.filters,
886
+ phone: userData,
887
+ };
888
+ }
889
+ return this.accessControlService
890
+ .validateUser(request)
891
+ .toPromise()
892
+ .then(async (res) => {
893
+ if (res.result.response) {
894
+ return await res.result.response;
895
+ }
896
+ })
897
+ .catch((_err) => { })
898
+ .finally(() => Promise.resolve());
899
+ }
900
+ manageData(userEmailData, userMobileData) {
901
+ this.isSuccessUserlist = [];
902
+ this.isErrorUserlist = [];
903
+ const userEmailMap = {};
904
+ const userEmailMapUserId = {};
905
+ const userMobileMap = {};
906
+ if (userEmailData.count) {
907
+ userEmailData.content.forEach(async (e) => {
908
+ if (e.profileDetails) {
909
+ userEmailMap[e.profileDetails.personalDetails.primaryEmail.toLowerCase()] = e;
910
+ userEmailMapUserId[e.userId] = e;
911
+ }
912
+ });
913
+ }
914
+ if (userMobileData.count) {
915
+ userMobileData.content.forEach(async (e) => {
916
+ if (e.profileDetails) {
917
+ userMobileMap[e.profileDetails.personalDetails.mobile] = e;
918
+ }
919
+ });
920
+ }
921
+ this.contacts.forEach(async (e) => {
922
+ if (e.userStatus) {
923
+ if (e.email && e.mobile) {
924
+ const userData = userEmailMap[e.email.toLowerCase()];
925
+ if (userData &&
926
+ userData.profileDetails.personalDetails &&
927
+ userData.profileDetails.personalDetails.mobile) {
928
+ if (String(userData.profileDetails.personalDetails.mobile) ===
929
+ String(e.mobile)) {
930
+ e["userId"] = userData.userId;
931
+ e["ministry"] = userData.rootOrgName;
932
+ e["fullName"] = userData.firstName || userData.firstname;
933
+ }
934
+ else {
935
+ e["status"] = "Error";
936
+ e["userStatus"] = false;
937
+ e["message"] = "Given credentials are not matching";
938
+ }
939
+ }
940
+ else {
941
+ e["status"] = "Error";
942
+ e["userStatus"] = false;
943
+ e["message"] = "Given credentials are not matching";
944
+ }
945
+ }
946
+ else if (e.email && userEmailMap[e.email.toLowerCase()]) {
947
+ const userData = userEmailMap[e.email.toLowerCase()];
948
+ e["mobile"] = userData.profileDetails.personalDetails.mobile;
949
+ e["userId"] = userData.userId;
950
+ e["ministry"] = userData.rootOrgName;
951
+ e["fullName"] = userData.firstName || userData.firstname;
952
+ }
953
+ else if (e.mobile && userMobileMap[e.mobile]) {
954
+ const userData = userMobileMap[e.mobile];
955
+ e["email"] = userData.profileDetails.personalDetails.primaryEmail;
956
+ e["userId"] = userData.userId;
957
+ e["ministry"] = userData.rootOrgName;
958
+ e["fullName"] = userData.firstName || userData.firstname;
959
+ }
960
+ else {
961
+ e["status"] = "Error";
962
+ e["userStatus"] = false;
963
+ e["message"] = "Given credentials are not matching";
964
+ }
965
+ }
966
+ });
967
+ this.fileUploading = false;
968
+ this.isSuccessUserlist = this.contacts.filter((ele) => ele.userStatus);
969
+ this.isErrorUserlist = this.contacts.filter((ele) => !ele.userStatus);
970
+ // this.successUserData.emit(this.isSuccessUserlist);
971
+ this.currrentFilterType = this.isSuccessUserlist.length
972
+ ? "success"
973
+ : "error";
974
+ if (this.currrentFilterType === "success") {
975
+ // this.displayedColumns = [
976
+ // "fullName",
977
+ // "email",
978
+ // "ministry",
979
+ // "status",
980
+ // "mobile",
981
+ // ];
982
+ // this.dataSource = new MatTableDataSource<IUserElement>(
983
+ // this.isSuccessUserlist
984
+ // );
985
+ }
986
+ else if (this.currrentFilterType === "error") {
987
+ // this.displayedColumns = ["email", "status", "mobile", "message"];
988
+ // this.dataSource = new MatTableDataSource<IUserElement>(
989
+ // this.isErrorUserlist
990
+ // );
991
+ }
992
+ }
993
+ onFilterChange(type) {
994
+ this.currrentFilterType = type;
995
+ }
996
+ downloadErrorFile() {
997
+ this.accessControlService.downloadFile(this.isErrorUserlist, "userErrordata");
998
+ }
999
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: BulkUploadKarmayogiComponent, deps: [{ token: AccessControlService }, { token: i1.MatLegacySnackBar }], target: i0.ɵɵFactoryTarget.Component }); }
1000
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: BulkUploadKarmayogiComponent, selector: "sb-uic-bulk-upload-karmayogi", ngImport: i0, template: "<div class=\"bulk-upload-wrapper\">\n <div class=\"flex gap-4 py-4 px-5 wrapper-border\">\n <div class=\"instructions-download py-4 px-5 border-dotted flex-1\">\n <div class=\"mb-6 text-style\">Open & follow these instruction</div>\n <div class=\"instructions-list\">\n <ul class=\"numbered-list\">\n <ng-container *ngFor=\"let item of bulkUploadConfig?.uploadInstructions\">\n <li>{{item}}</li>\n </ng-container>\n </ul>\n </div>\n <div class=\"download-sample mt-6\">\n <button mat-flat-button (click)=\"downloadSample()\"\n class=\"rounded-full px-4 py-2 font-bold text-sm mat-btn-outline cursor-pointer\">\n Download Sample File\n </button>\n </div>\n </div>\n\n <div class=\"bulk-upload-select py-4 px-5 border-dotted flex-1\">\n <div class=\"right_upload_inner flex flex-col items-center justify-center\" wsAuthDragDrop\n (fileDropped)=\"onDrop($event)\">\n <div class=\"flex flex-row items-center justify-center margin-bottom-s\">\n <mat-icon class=\"svg-ico\" svgIcon=\"excel-sheet\"></mat-icon>\n </div>\n <div class=\"items-center justify-center flex flex-col\">\n <a class=\"new-color cursor-pointer text-sm font-bold mb-1 mt-7\" (click)=\"fileInput.click()\">Browse\n files</a>\n <p class=\"mt-2 text-sm\">Or</p>\n <p class=\"mt-2 ws-mat-black60-text text-base\">Drag file to upload</p>\n <p class=\"text-xs ws-mat-black87-text margin-remove\">Max size: 100 MB</p>\n <p class=\"text-xs ws-mat-black60-text margin-remove\">Supported file types: CSV</p>\n </div>\n <input type=\"file\" #fileInput class=\"inputfile\" accept=\".csv\"\n (change)=\"onDrop($event.target.files[0]); fileInput.value = null\" />\n <div *ngIf=\"file\" class=\"flex flex-middle justify-center flex-column position-relative pt-5 px-5\">\n <mat-icon class=\"ws-mat-primary-text\" svgIcon=\"excel-sheet\">\n </mat-icon>\n <p class=\"margin-left-xs mat-h3 font-weight-500 margin-remove-bottom break\">\n <ng-container *ngIf=\"file; else elseBlock\">\n <span class=\"flex-wrap\"> {{ file?.name }}</span>\n </ng-container>\n <ng-template #elseBlock>\n <span i18n>No file uploaded</span>\n </ng-template>\n </p>\n\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"filter-by-select my-4\">\n <div class=\"flex gap-4 items-center\">\n <div class=\"text-title\">Filter By</div>\n <div class=\"flex gap-2\">\n <button mat-flat-button (click)=\"onFilterChange('success')\"\n [ngClass]=\"currrentFilterType === 'success' ? 'new-bg-color text-white mat-btn-flat': 'mat-btn-outline' \"\n class=\"rounded-full px-4 py-2 font-bold text-sm cursor-pointer \">\n Success\n </button>\n <button (click)=\"onFilterChange('error')\" mat-flat-button\n [ngClass]=\"currrentFilterType === 'error' ? 'new-bg-color text-white mat-btn-flat': 'mat-btn-outline' \"\n class=\"rounded-full px-4 py-2 font-bold text-sm cursor-pointer\">\n Error\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"list-table-bulk-upload\">\n <ng-container *ngIf=\"currrentFilterType === 'success'\">\n <div class=\"flex items-center gap-2 selection-count mb-4 p-2\">\n <span class=\"\">{{isSuccessUserlist.length}}</span>\n <span class=\"text-sm font-normal\">Items Selected</span>\n </div>\n <sb-uic-list-table [data]=\"isSuccessUserlist\" [count]=\"1\"\n [initialPaginationSize]=\"bulkUploadConfig['bulkUploadTable']?.initialPaginationSize\"\n [tableConfig]=\"bulkUploadConfig['bulkUploadTable']\"\n [bulkUploadEntriesCount]=\"{totalCount: isSuccessUserlist?.length + isErrorUserlist?.length, success: isSuccessUserlist?.length}\">\n </sb-uic-list-table>\n </ng-container>\n\n <ng-container *ngIf=\"currrentFilterType === 'error'\">\n <div class=\"wrapper-border rounded-sm p-4\">\n <div class=\"log-history-text\">Log History</div>\n </div>\n <div class=\"information-list py-4 px-6\">\n <!-- <ng-container *ngFor=\"let item of isErrorUserlist\"> -->\n <ng-container>\n <div class=\"rounded-lg wrapper-border py-5 px-4 mb-4\">\n <div class=\"flex items-center justify-between\">\n <div class=\"error-log-title flex gap-2 items-center\">\n <span class=\"text-title text-dark\">File Information</span>\n <img src=\"/assets/icons/icon-wrapper.svg\" alt=\"tooltip-icon\">\n </div>\n <button mat-flat-button (click)=\"downloadErrorFile()\"\n class=\"rounded-full px-4 py-2 font-bold text-sm mat-btn-outline cursor-pointer\">\n <mat-icon class=\"new-color\">file_download</mat-icon>\n Download error log\n </button>\n </div>\n <div class=\"my-4 meta-info\">\n <div class=\"flex gap-2 items-center\">\n <span class=\"text-title text-dark\">{{fileName}}</span>\n <img src=\"/assets/icons/error-icon.svg\" alt=\"error-icon\">\n </div>\n <div class=\"text-style text-dark\">Theress an error occurred while uploading this file.</div>\n </div>\n <div class=\"flex gap-x-6 gap-y-4 falied-records-info\">\n <div class=\"flex flex-column gap-4 flex-grow-1\">\n <div>\n <p class=\"text-sm text-gray-500\">Name</p>\n <p class=\"font-medium break-all text-dark\">\n {{fileName}}</p>\n </div>\n <div>\n <p class=\"text-sm text-gray-500\">Total Records</p>\n <p class=\"font-medium text-dark\">{{isSuccessUserlist?.length +\n isErrorUserlist?.length}}</p>\n </div>\n <div>\n <p class=\"text-sm text-gray-500 mt-2\">Failed Records</p>\n <p class=\"font-medium text-dark\">{{isErrorUserlist?.length}}</p>\n </div>\n </div>\n <div class=\"flex flex-column gap-4 flex-grow-1\">\n <div>\n <p class=\"text-sm text-gray-500\">Status</p>\n <p class=\"text-red-600 font-normal\">FAILED</p>\n </div>\n <div>\n <p class=\"text-sm text-gray-500\">Created On</p>\n <p class=\"font-medium text-dark\">{{currentDate | date: 'medium'}}</p>\n </div>\n <div>\n <p class=\"text-sm text-gray-500 mt-2\">Updated On</p>\n <p class=\"font-medium text-dark\">{{currentDate | date: 'medium'}}</p>\n </div>\n </div>\n <div class=\"flex flex-column gap-4 flex-grow-1\">\n <div>\n <p class=\"text-sm text-gray-500\">Success Records</p>\n <p class=\"font-medium text-dark\">{{isSuccessUserlist?.length}}</p>\n </div>\n\n </div>\n </div>\n\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n</div>", styles: [".wrapper-border{border:1px solid rgba(0,0,0,.0784313725)}.numbered-list{list-style:none;counter-reset:list-counter;padding-left:0}.numbered-list li{counter-increment:list-counter;margin-bottom:16px}.numbered-list li:before{content:counter(list-counter) \". \"}.text-style,.numbered-list li{color:#000000de;font-family:Lato;font-weight:400;font-size:14px}.border-dotted{border:1px dashed rgba(0,0,0,.1607843137)}.svg-ico{width:75px;height:75px}.inputfile{width:.1px;height:.1px;opacity:0;overflow:hidden;position:absolute;z-index:-1}.inputfile+label{font-size:1.25em;color:#fff;display:inline-block;cursor:pointer}.browse_link{color:#1b4ca1;padding:6px 15px;text-align:center;border-radius:4px}.or-text{margin-bottom:0!important}.ws-mat-black87-text{color:#000000de}.text-title,.log-history-text{font-family:Montserrat;font-weight:600;font-size:16px;text-align:center;color:#1b4ca1}.selection-count{border:1px solid rgba(0,0,0,.0784313725);background:#d1dbec}.selection-count span{font-family:Lato;font-weight:400}.selection-count span:first-child{background:#d1dbec;border:1px solid rgba(0,0,0,.1607843137);border-radius:50%;padding:4px;height:18px;width:18px;display:flex;align-items:center;justify-content:center;font-size:10px;color:#0009}.selection-count span:nth-child(2){font-size:14px;color:#000000de}.log-history-text{font-size:14px;color:#1b2133;text-align:start}.information-list{border:1px solid rgba(0,0,0,.0784313725)}.meta-info{background:#d1392429;border:1px solid rgba(0,0,0,.0784313725);border-radius:12px;padding:18px 16px}.falied-records-info p{margin-bottom:8px!important}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i5$1.MatLegacyButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: ListTableComponent, selector: "sb-uic-list-table", inputs: ["data", "count", "initialPaginationSize", "initialPaginationSizeOptions", "tableConfig", "selected", "bulkUploadEntriesCount"], outputs: ["selectedDataChange", "pageChange", "removeSelectedData"] }, { kind: "directive", type: DragDropDirective, selector: "[wsAuthDragDrop]", outputs: ["fileDropped"] }, { kind: "pipe", type: i3.DatePipe, name: "date" }] }); }
1001
+ }
1002
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: BulkUploadKarmayogiComponent, decorators: [{
1003
+ type: Component,
1004
+ args: [{ selector: "sb-uic-bulk-upload-karmayogi", template: "<div class=\"bulk-upload-wrapper\">\n <div class=\"flex gap-4 py-4 px-5 wrapper-border\">\n <div class=\"instructions-download py-4 px-5 border-dotted flex-1\">\n <div class=\"mb-6 text-style\">Open & follow these instruction</div>\n <div class=\"instructions-list\">\n <ul class=\"numbered-list\">\n <ng-container *ngFor=\"let item of bulkUploadConfig?.uploadInstructions\">\n <li>{{item}}</li>\n </ng-container>\n </ul>\n </div>\n <div class=\"download-sample mt-6\">\n <button mat-flat-button (click)=\"downloadSample()\"\n class=\"rounded-full px-4 py-2 font-bold text-sm mat-btn-outline cursor-pointer\">\n Download Sample File\n </button>\n </div>\n </div>\n\n <div class=\"bulk-upload-select py-4 px-5 border-dotted flex-1\">\n <div class=\"right_upload_inner flex flex-col items-center justify-center\" wsAuthDragDrop\n (fileDropped)=\"onDrop($event)\">\n <div class=\"flex flex-row items-center justify-center margin-bottom-s\">\n <mat-icon class=\"svg-ico\" svgIcon=\"excel-sheet\"></mat-icon>\n </div>\n <div class=\"items-center justify-center flex flex-col\">\n <a class=\"new-color cursor-pointer text-sm font-bold mb-1 mt-7\" (click)=\"fileInput.click()\">Browse\n files</a>\n <p class=\"mt-2 text-sm\">Or</p>\n <p class=\"mt-2 ws-mat-black60-text text-base\">Drag file to upload</p>\n <p class=\"text-xs ws-mat-black87-text margin-remove\">Max size: 100 MB</p>\n <p class=\"text-xs ws-mat-black60-text margin-remove\">Supported file types: CSV</p>\n </div>\n <input type=\"file\" #fileInput class=\"inputfile\" accept=\".csv\"\n (change)=\"onDrop($event.target.files[0]); fileInput.value = null\" />\n <div *ngIf=\"file\" class=\"flex flex-middle justify-center flex-column position-relative pt-5 px-5\">\n <mat-icon class=\"ws-mat-primary-text\" svgIcon=\"excel-sheet\">\n </mat-icon>\n <p class=\"margin-left-xs mat-h3 font-weight-500 margin-remove-bottom break\">\n <ng-container *ngIf=\"file; else elseBlock\">\n <span class=\"flex-wrap\"> {{ file?.name }}</span>\n </ng-container>\n <ng-template #elseBlock>\n <span i18n>No file uploaded</span>\n </ng-template>\n </p>\n\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"filter-by-select my-4\">\n <div class=\"flex gap-4 items-center\">\n <div class=\"text-title\">Filter By</div>\n <div class=\"flex gap-2\">\n <button mat-flat-button (click)=\"onFilterChange('success')\"\n [ngClass]=\"currrentFilterType === 'success' ? 'new-bg-color text-white mat-btn-flat': 'mat-btn-outline' \"\n class=\"rounded-full px-4 py-2 font-bold text-sm cursor-pointer \">\n Success\n </button>\n <button (click)=\"onFilterChange('error')\" mat-flat-button\n [ngClass]=\"currrentFilterType === 'error' ? 'new-bg-color text-white mat-btn-flat': 'mat-btn-outline' \"\n class=\"rounded-full px-4 py-2 font-bold text-sm cursor-pointer\">\n Error\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"list-table-bulk-upload\">\n <ng-container *ngIf=\"currrentFilterType === 'success'\">\n <div class=\"flex items-center gap-2 selection-count mb-4 p-2\">\n <span class=\"\">{{isSuccessUserlist.length}}</span>\n <span class=\"text-sm font-normal\">Items Selected</span>\n </div>\n <sb-uic-list-table [data]=\"isSuccessUserlist\" [count]=\"1\"\n [initialPaginationSize]=\"bulkUploadConfig['bulkUploadTable']?.initialPaginationSize\"\n [tableConfig]=\"bulkUploadConfig['bulkUploadTable']\"\n [bulkUploadEntriesCount]=\"{totalCount: isSuccessUserlist?.length + isErrorUserlist?.length, success: isSuccessUserlist?.length}\">\n </sb-uic-list-table>\n </ng-container>\n\n <ng-container *ngIf=\"currrentFilterType === 'error'\">\n <div class=\"wrapper-border rounded-sm p-4\">\n <div class=\"log-history-text\">Log History</div>\n </div>\n <div class=\"information-list py-4 px-6\">\n <!-- <ng-container *ngFor=\"let item of isErrorUserlist\"> -->\n <ng-container>\n <div class=\"rounded-lg wrapper-border py-5 px-4 mb-4\">\n <div class=\"flex items-center justify-between\">\n <div class=\"error-log-title flex gap-2 items-center\">\n <span class=\"text-title text-dark\">File Information</span>\n <img src=\"/assets/icons/icon-wrapper.svg\" alt=\"tooltip-icon\">\n </div>\n <button mat-flat-button (click)=\"downloadErrorFile()\"\n class=\"rounded-full px-4 py-2 font-bold text-sm mat-btn-outline cursor-pointer\">\n <mat-icon class=\"new-color\">file_download</mat-icon>\n Download error log\n </button>\n </div>\n <div class=\"my-4 meta-info\">\n <div class=\"flex gap-2 items-center\">\n <span class=\"text-title text-dark\">{{fileName}}</span>\n <img src=\"/assets/icons/error-icon.svg\" alt=\"error-icon\">\n </div>\n <div class=\"text-style text-dark\">Theress an error occurred while uploading this file.</div>\n </div>\n <div class=\"flex gap-x-6 gap-y-4 falied-records-info\">\n <div class=\"flex flex-column gap-4 flex-grow-1\">\n <div>\n <p class=\"text-sm text-gray-500\">Name</p>\n <p class=\"font-medium break-all text-dark\">\n {{fileName}}</p>\n </div>\n <div>\n <p class=\"text-sm text-gray-500\">Total Records</p>\n <p class=\"font-medium text-dark\">{{isSuccessUserlist?.length +\n isErrorUserlist?.length}}</p>\n </div>\n <div>\n <p class=\"text-sm text-gray-500 mt-2\">Failed Records</p>\n <p class=\"font-medium text-dark\">{{isErrorUserlist?.length}}</p>\n </div>\n </div>\n <div class=\"flex flex-column gap-4 flex-grow-1\">\n <div>\n <p class=\"text-sm text-gray-500\">Status</p>\n <p class=\"text-red-600 font-normal\">FAILED</p>\n </div>\n <div>\n <p class=\"text-sm text-gray-500\">Created On</p>\n <p class=\"font-medium text-dark\">{{currentDate | date: 'medium'}}</p>\n </div>\n <div>\n <p class=\"text-sm text-gray-500 mt-2\">Updated On</p>\n <p class=\"font-medium text-dark\">{{currentDate | date: 'medium'}}</p>\n </div>\n </div>\n <div class=\"flex flex-column gap-4 flex-grow-1\">\n <div>\n <p class=\"text-sm text-gray-500\">Success Records</p>\n <p class=\"font-medium text-dark\">{{isSuccessUserlist?.length}}</p>\n </div>\n\n </div>\n </div>\n\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n</div>", styles: [".wrapper-border{border:1px solid rgba(0,0,0,.0784313725)}.numbered-list{list-style:none;counter-reset:list-counter;padding-left:0}.numbered-list li{counter-increment:list-counter;margin-bottom:16px}.numbered-list li:before{content:counter(list-counter) \". \"}.text-style,.numbered-list li{color:#000000de;font-family:Lato;font-weight:400;font-size:14px}.border-dotted{border:1px dashed rgba(0,0,0,.1607843137)}.svg-ico{width:75px;height:75px}.inputfile{width:.1px;height:.1px;opacity:0;overflow:hidden;position:absolute;z-index:-1}.inputfile+label{font-size:1.25em;color:#fff;display:inline-block;cursor:pointer}.browse_link{color:#1b4ca1;padding:6px 15px;text-align:center;border-radius:4px}.or-text{margin-bottom:0!important}.ws-mat-black87-text{color:#000000de}.text-title,.log-history-text{font-family:Montserrat;font-weight:600;font-size:16px;text-align:center;color:#1b4ca1}.selection-count{border:1px solid rgba(0,0,0,.0784313725);background:#d1dbec}.selection-count span{font-family:Lato;font-weight:400}.selection-count span:first-child{background:#d1dbec;border:1px solid rgba(0,0,0,.1607843137);border-radius:50%;padding:4px;height:18px;width:18px;display:flex;align-items:center;justify-content:center;font-size:10px;color:#0009}.selection-count span:nth-child(2){font-size:14px;color:#000000de}.log-history-text{font-size:14px;color:#1b2133;text-align:start}.information-list{border:1px solid rgba(0,0,0,.0784313725)}.meta-info{background:#d1392429;border:1px solid rgba(0,0,0,.0784313725);border-radius:12px;padding:18px 16px}.falied-records-info p{margin-bottom:8px!important}\n"] }]
1005
+ }], ctorParameters: function () { return [{ type: AccessControlService }, { type: i1.MatLegacySnackBar }]; } });
1006
+
1007
+ class InviteUsersComponent {
1008
+ constructor(dialogRef, accessControlService, snackbar) {
1009
+ this.dialogRef = dialogRef;
1010
+ this.accessControlService = accessControlService;
1011
+ this.snackbar = snackbar;
1012
+ this.data = inject(MAT_DIALOG_DATA);
1013
+ this.searchControl = new FormControl("");
1014
+ this.filterValue = "add_karmayogis";
1015
+ this.usersList = [];
1016
+ this.totalUsers = 0;
1017
+ this.holdSelectedUsers = [];
1018
+ this.finalSelectedUsers = [];
1019
+ this.usersFinalList = [];
1020
+ this.usersLoading = false;
1021
+ this.activeTab = 0;
1022
+ }
1023
+ ngOnInit() {
1024
+ this.usersTableConfig = this.accessControlService.accessControlConfig().usersTableConfig;
1025
+ if (this.data && this.data.selected) {
1026
+ if (!this.isArrayOfObjects(this.data?.selected)) {
1027
+ this.getUsersList("", 5, 0, this.data?.selected);
1028
+ }
1029
+ }
1030
+ }
1031
+ onClose() {
1032
+ this.dialogRef.close();
1033
+ }
1034
+ search() {
1035
+ this.holdSelectedUsers = [];
1036
+ this.getUsersList(this.searchControl.value);
1037
+ }
1038
+ onFilterChange(event) {
1039
+ this.filterValue = event.value;
1040
+ }
1041
+ getUsersList(query, limit, offset, userIds) {
1042
+ this.usersLoading = true;
1043
+ this.accessControlService.fetchUserList(query, { limit: limit, offset: offset }, userIds).subscribe({
1044
+ next: response => {
1045
+ if (response?.result && response?.result?.response?.content) {
1046
+ this.usersList = response.result.response.content;
1047
+ this.totalUsers = response.result.response.count;
1048
+ if (userIds.length) {
1049
+ this.finalSelectedUsers = response.result.response.content;
1050
+ }
1051
+ }
1052
+ else {
1053
+ this.usersList = [];
1054
+ this.totalUsers = 0;
1055
+ }
1056
+ },
1057
+ complete: () => {
1058
+ this.usersLoading = false;
1059
+ }
1060
+ });
1061
+ }
1062
+ onSelectingUser(event) {
1063
+ this.holdSelectedUsers = event;
1064
+ }
1065
+ selectUsers() {
1066
+ this.finalSelectedUsers = this.holdSelectedUsers;
1067
+ this.snackbar.openFromComponent(SnackbarComponent, {
1068
+ data: { message: `Users added to Selected tab`, type: "success" },
1069
+ duration: 3000,
1070
+ panelClass: "course-success-snackbar"
1071
+ });
1072
+ this.activeTab = 1;
1073
+ }
1074
+ onPageChange(event) {
1075
+ const limit = event.limit;
1076
+ const offset = (event.currentPage - 1) * limit;
1077
+ this.getUsersList(this.searchControl.value, limit, offset);
1078
+ }
1079
+ removedUserData(event) {
1080
+ this.finalSelectedUsers = [...event.remainingList];
1081
+ this.holdSelectedUsers = this.finalSelectedUsers;
1082
+ }
1083
+ onSelectingUserToApply(users) {
1084
+ this.usersFinalList = users;
1085
+ }
1086
+ applySelections() {
1087
+ this.dialogRef.close({
1088
+ rule: this.data.rule,
1089
+ condition: this.data.condition,
1090
+ selected: this.usersFinalList
1091
+ });
1092
+ }
1093
+ isArrayOfObjects(arr) {
1094
+ return Array.isArray(arr) && arr.every(item => typeof item === "object" && item !== null && !Array.isArray(item));
1095
+ }
1096
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: InviteUsersComponent, deps: [{ token: i1$3.MatDialogRef }, { token: AccessControlService }, { token: i1.MatLegacySnackBar }], target: i0.ɵɵFactoryTarget.Component }); }
1097
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: InviteUsersComponent, selector: "sb-uic-invite-users", ngImport: i0, template: "<div class=\"flex justify-between dialog-heading items-center\">\n <h2 mat-dialog-title class=\"mb-0\">Users</h2>\n <button mat-icon-button class=\"close-button\" (click)=\"onClose()\">\n <mat-icon>close</mat-icon>\n </button>\n</div>\n\n<div mat-dialog-content>\n <div class=\"\">\n <!-- Filter Options -->\n <div class=\"filter-options\">\n <mat-radio-group [(ngModel)]=\"filterValue\" aria-label=\"Filter options\" (change)=\"onFilterChange($event)\">\n <mat-radio-button class=\"text-dark\" value=\"add_karmayogis\">Add Karmayogis</mat-radio-button>\n <mat-radio-button class=\"text-dark\" value=\"bulk_upload_karmayogis\">Bulk Upload Karmayogis</mat-radio-button>\n </mat-radio-group>\n </div>\n </div>\n\n <ng-container *ngIf=\"filterValue === 'add_karmayogis'\">\n <!-- Search Box -->\n <div class=\"search-container flex items-center gap-4 mb-4\">\n <div class=\"mat-full-radius flex-grow\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-icon matPrefix>search</mat-icon>\n <input matInput placeholder=\"Search by Name, Email and Phone Number\" [formControl]=\"searchControl\" (keyup.enter)=\"search()\" />\n </mat-form-field>\n </div>\n <button mat-flat-button class=\"flex items-center rounded-full new-bg-color font-bold text-sm text-white search-button\" (click)=\"search()\">Search</button>\n </div>\n\n <div class=\"contents-wrapper\">\n <ng-container>\n <mat-tab-group mat-stretch-tabs=\"false\" mat-align-tabs=\"start\" [(selectedIndex)]=\"activeTab\" dynamicHeight>\n <mat-tab label=\"All Learners\" class=\"mb-3\">\n <ng-container *ngIf=\"usersLoading\">\n <div class=\"spinner-loader flex items-center justify-center\">\n <mat-spinner></mat-spinner>\n </div>\n </ng-container>\n <div [ngClass]=\"{ hidden: usersLoading }\">\n <ng-container *ngIf=\"usersList && usersList.length > 0; else noData\">\n <sb-uic-list-table\n [data]=\"usersList\"\n [count]=\"totalUsers\"\n [initialPaginationSize]=\"usersTableConfig['allLearners']?.initialPaginationSize\"\n [tableConfig]=\"usersTableConfig['allLearners']\"\n (selectedDataChange)=\"onSelectingUser($event)\"\n (pageChange)=\"onPageChange($event)\"\n [selected]=\"finalSelectedUsers\"></sb-uic-list-table>\n </ng-container>\n </div>\n </mat-tab>\n <mat-tab label=\" Selected Users\" class=\"mb-3\">\n <ng-container *ngIf=\"usersLoading\">\n <div class=\"spinner-loader flex items-center justify-center\">\n <mat-spinner></mat-spinner>\n </div>\n </ng-container>\n <ng-container *ngIf=\"!usersLoading\">\n <ng-container *ngIf=\"finalSelectedUsers && finalSelectedUsers.length > 0; else noData\">\n <sb-uic-list-table\n [data]=\"finalSelectedUsers\"\n [count]=\"finalSelectedUsers.length || 0\"\n [initialPaginationSize]=\"usersTableConfig['selectedUsers']?.initialPaginationSize\"\n [tableConfig]=\"usersTableConfig['selectedUsers']\"\n (selectedDataChange)=\"onSelectingUserToApply($event)\"\n (removeSelectedData)=\"removedUserData($event)\"\n [selected]=\"usersFinalList\"></sb-uic-list-table>\n </ng-container>\n </ng-container>\n </mat-tab>\n </mat-tab-group>\n </ng-container>\n\n <ng-template #noData>\n <div class=\"no-data p-4 flex flex-column items-center justify-center\">\n <img src=\"/assets/icons/no-events.png\" alt=\"no-data\" />\n <span class=\"font-bold\">No information to display yet</span>\n </div>\n </ng-template>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"filterValue === 'bulk_upload_karmayogis'\">\n <sb-uic-bulk-upload-karmayogi></sb-uic-bulk-upload-karmayogi>\n </ng-container>\n</div>\n\n<mat-dialog-actions>\n <ng-container *ngIf=\"filterValue === 'add_karmayogis'\">\n <ng-container *ngIf=\"activeTab === 0 && usersList.length\">\n <button\n mat-flat-button\n (click)=\"selectUsers()\"\n class=\"flex items-center justify-center rounded-full new-bg-color font-bold text-sm text-white w-full mt-2\"\n [disabled]=\"holdSelectedUsers?.length === 0\">\n Select Users\n </button>\n </ng-container>\n <ng-container *ngIf=\"activeTab === 1 && usersFinalList.length\">\n <button\n mat-flat-button\n (click)=\"applySelections()\"\n class=\"flex items-center justify-center rounded-full new-bg-color font-bold text-sm text-white w-full mt-2\">\n Apply\n </button>\n </ng-container>\n </ng-container>\n</mat-dialog-actions>\n", styles: [":host{display:block}.dialog-heading{border-bottom:2px solid rgba(0,0,0,.12);padding:0 16px}::ng-deep .mat-mdc-dialog-container .mdc-dialog__title{margin-bottom:8px!important;font-family:Montserrat;font-weight:600;font-size:16px;color:#000000de;padding:0 24px 9px 0}.close-button{margin-right:-8px}::ng-deep .mat-form-field-wrapper{padding-bottom:0!important}.search-button{padding:4px 24px}.filter-options{margin-bottom:15px}.filter-options .mat-radio-button{margin-right:24px}.no-data span{font-family:Lato;font-size:8.98px;color:#000000de}:host ::ng-deep .mat-mdc-tab.mdc-tab--active .mdc-tab__text-label{font-family:Montserrat;font-weight:600;font-size:16px;color:#1b4ca1}:host ::ng-deep .mat-mdc-tab .mdc-tab__text-label{color:#241c15a6;font-family:Lato;font-weight:400;font-size:16px}.mt-4{margin-top:1rem!important}.spinner-loader{height:200px}:host ::ng-deep .mat-mdc-dialog-content{max-height:75vh!important}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5$2.MatLegacyRadioGroup, selector: "mat-radio-group", exportAs: ["matRadioGroup"] }, { kind: "component", type: i5$2.MatLegacyRadioButton, selector: "mat-radio-button", inputs: ["disableRipple", "tabIndex"], exportAs: ["matRadioButton"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i1$3.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$3.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i1$3.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "component", type: i7.MatLegacyFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i7.MatLegacyPrefix, selector: "[matPrefix]" }, { kind: "directive", type: i8.MatLegacyInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", exportAs: ["matInput"] }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i5$1.MatLegacyButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i11.MatTab, selector: "mat-tab", inputs: ["disabled"], exportAs: ["matTab"] }, { kind: "component", type: i11.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "disableRipple", "fitInkBarToContent", "mat-stretch-tabs"], exportAs: ["matTabGroup"] }, { kind: "component", type: i12.MatLegacyProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: ListTableComponent, selector: "sb-uic-list-table", inputs: ["data", "count", "initialPaginationSize", "initialPaginationSizeOptions", "tableConfig", "selected", "bulkUploadEntriesCount"], outputs: ["selectedDataChange", "pageChange", "removeSelectedData"] }, { kind: "component", type: BulkUploadKarmayogiComponent, selector: "sb-uic-bulk-upload-karmayogi" }] }); }
1098
+ }
1099
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: InviteUsersComponent, decorators: [{
1100
+ type: Component,
1101
+ args: [{ selector: "sb-uic-invite-users", template: "<div class=\"flex justify-between dialog-heading items-center\">\n <h2 mat-dialog-title class=\"mb-0\">Users</h2>\n <button mat-icon-button class=\"close-button\" (click)=\"onClose()\">\n <mat-icon>close</mat-icon>\n </button>\n</div>\n\n<div mat-dialog-content>\n <div class=\"\">\n <!-- Filter Options -->\n <div class=\"filter-options\">\n <mat-radio-group [(ngModel)]=\"filterValue\" aria-label=\"Filter options\" (change)=\"onFilterChange($event)\">\n <mat-radio-button class=\"text-dark\" value=\"add_karmayogis\">Add Karmayogis</mat-radio-button>\n <mat-radio-button class=\"text-dark\" value=\"bulk_upload_karmayogis\">Bulk Upload Karmayogis</mat-radio-button>\n </mat-radio-group>\n </div>\n </div>\n\n <ng-container *ngIf=\"filterValue === 'add_karmayogis'\">\n <!-- Search Box -->\n <div class=\"search-container flex items-center gap-4 mb-4\">\n <div class=\"mat-full-radius flex-grow\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-icon matPrefix>search</mat-icon>\n <input matInput placeholder=\"Search by Name, Email and Phone Number\" [formControl]=\"searchControl\" (keyup.enter)=\"search()\" />\n </mat-form-field>\n </div>\n <button mat-flat-button class=\"flex items-center rounded-full new-bg-color font-bold text-sm text-white search-button\" (click)=\"search()\">Search</button>\n </div>\n\n <div class=\"contents-wrapper\">\n <ng-container>\n <mat-tab-group mat-stretch-tabs=\"false\" mat-align-tabs=\"start\" [(selectedIndex)]=\"activeTab\" dynamicHeight>\n <mat-tab label=\"All Learners\" class=\"mb-3\">\n <ng-container *ngIf=\"usersLoading\">\n <div class=\"spinner-loader flex items-center justify-center\">\n <mat-spinner></mat-spinner>\n </div>\n </ng-container>\n <div [ngClass]=\"{ hidden: usersLoading }\">\n <ng-container *ngIf=\"usersList && usersList.length > 0; else noData\">\n <sb-uic-list-table\n [data]=\"usersList\"\n [count]=\"totalUsers\"\n [initialPaginationSize]=\"usersTableConfig['allLearners']?.initialPaginationSize\"\n [tableConfig]=\"usersTableConfig['allLearners']\"\n (selectedDataChange)=\"onSelectingUser($event)\"\n (pageChange)=\"onPageChange($event)\"\n [selected]=\"finalSelectedUsers\"></sb-uic-list-table>\n </ng-container>\n </div>\n </mat-tab>\n <mat-tab label=\" Selected Users\" class=\"mb-3\">\n <ng-container *ngIf=\"usersLoading\">\n <div class=\"spinner-loader flex items-center justify-center\">\n <mat-spinner></mat-spinner>\n </div>\n </ng-container>\n <ng-container *ngIf=\"!usersLoading\">\n <ng-container *ngIf=\"finalSelectedUsers && finalSelectedUsers.length > 0; else noData\">\n <sb-uic-list-table\n [data]=\"finalSelectedUsers\"\n [count]=\"finalSelectedUsers.length || 0\"\n [initialPaginationSize]=\"usersTableConfig['selectedUsers']?.initialPaginationSize\"\n [tableConfig]=\"usersTableConfig['selectedUsers']\"\n (selectedDataChange)=\"onSelectingUserToApply($event)\"\n (removeSelectedData)=\"removedUserData($event)\"\n [selected]=\"usersFinalList\"></sb-uic-list-table>\n </ng-container>\n </ng-container>\n </mat-tab>\n </mat-tab-group>\n </ng-container>\n\n <ng-template #noData>\n <div class=\"no-data p-4 flex flex-column items-center justify-center\">\n <img src=\"/assets/icons/no-events.png\" alt=\"no-data\" />\n <span class=\"font-bold\">No information to display yet</span>\n </div>\n </ng-template>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"filterValue === 'bulk_upload_karmayogis'\">\n <sb-uic-bulk-upload-karmayogi></sb-uic-bulk-upload-karmayogi>\n </ng-container>\n</div>\n\n<mat-dialog-actions>\n <ng-container *ngIf=\"filterValue === 'add_karmayogis'\">\n <ng-container *ngIf=\"activeTab === 0 && usersList.length\">\n <button\n mat-flat-button\n (click)=\"selectUsers()\"\n class=\"flex items-center justify-center rounded-full new-bg-color font-bold text-sm text-white w-full mt-2\"\n [disabled]=\"holdSelectedUsers?.length === 0\">\n Select Users\n </button>\n </ng-container>\n <ng-container *ngIf=\"activeTab === 1 && usersFinalList.length\">\n <button\n mat-flat-button\n (click)=\"applySelections()\"\n class=\"flex items-center justify-center rounded-full new-bg-color font-bold text-sm text-white w-full mt-2\">\n Apply\n </button>\n </ng-container>\n </ng-container>\n</mat-dialog-actions>\n", styles: [":host{display:block}.dialog-heading{border-bottom:2px solid rgba(0,0,0,.12);padding:0 16px}::ng-deep .mat-mdc-dialog-container .mdc-dialog__title{margin-bottom:8px!important;font-family:Montserrat;font-weight:600;font-size:16px;color:#000000de;padding:0 24px 9px 0}.close-button{margin-right:-8px}::ng-deep .mat-form-field-wrapper{padding-bottom:0!important}.search-button{padding:4px 24px}.filter-options{margin-bottom:15px}.filter-options .mat-radio-button{margin-right:24px}.no-data span{font-family:Lato;font-size:8.98px;color:#000000de}:host ::ng-deep .mat-mdc-tab.mdc-tab--active .mdc-tab__text-label{font-family:Montserrat;font-weight:600;font-size:16px;color:#1b4ca1}:host ::ng-deep .mat-mdc-tab .mdc-tab__text-label{color:#241c15a6;font-family:Lato;font-weight:400;font-size:16px}.mt-4{margin-top:1rem!important}.spinner-loader{height:200px}:host ::ng-deep .mat-mdc-dialog-content{max-height:75vh!important}\n"] }]
1102
+ }], ctorParameters: function () { return [{ type: i1$3.MatDialogRef }, { type: AccessControlService }, { type: i1.MatLegacySnackBar }]; } });
1103
+
1104
+ var NsAccessControlConfig;
1105
+ (function (NsAccessControlConfig) {
1106
+ let SelectionType;
1107
+ (function (SelectionType) {
1108
+ SelectionType["Users"] = "user";
1109
+ SelectionType["Organizations"] = "rootOrgId";
1110
+ SelectionType["Group"] = "group";
1111
+ SelectionType["Designation"] = "designation";
1112
+ SelectionType["VerificationStatus"] = "profilestatus";
1113
+ SelectionType["Cadre"] = "Cadre";
1114
+ SelectionType["Service"] = "service";
1115
+ SelectionType["Batch"] = "batch";
1116
+ })(SelectionType = NsAccessControlConfig.SelectionType || (NsAccessControlConfig.SelectionType = {}));
1117
+ let IActions;
1118
+ (function (IActions) {
1119
+ IActions["Confirm"] = "confirm";
1120
+ IActions["Reject"] = "reject";
1121
+ })(IActions = NsAccessControlConfig.IActions || (NsAccessControlConfig.IActions = {}));
1122
+ let IAccessTypes;
1123
+ (function (IAccessTypes) {
1124
+ IAccessTypes["Public"] = "public";
1125
+ IAccessTypes["Custom"] = "custom";
1126
+ })(IAccessTypes = NsAccessControlConfig.IAccessTypes || (NsAccessControlConfig.IAccessTypes = {}));
1127
+ let IAccessSetting;
1128
+ (function (IAccessSetting) {
1129
+ IAccessSetting["ALL_USERS"] = "allUsers";
1130
+ IAccessSetting["MDO_SPECIFIC"] = "mdoSpecific";
1131
+ IAccessSetting["CUSTOME_USER"] = "customeUser";
1132
+ })(IAccessSetting = NsAccessControlConfig.IAccessSetting || (NsAccessControlConfig.IAccessSetting = {}));
1133
+ })(NsAccessControlConfig || (NsAccessControlConfig = {}));
1134
+
1135
+ const BATCH_RANGES = [
1136
+ { label: "1960-1990", start: 1960, end: 1990 },
1137
+ { label: "1991-2020", start: 1991, end: 2020 },
1138
+ { label: "2021-2025", start: 2021, end: 2025 }
1139
+ ];
1140
+
1141
+ class EntitySelectionsComponent {
1142
+ constructor(dialogRef, accessControlService) {
1143
+ this.dialogRef = dialogRef;
1144
+ this.accessControlService = accessControlService;
1145
+ this.destroy$ = new Subject();
1146
+ this.isLoading = false;
1147
+ this.searchControl = new FormControl("");
1148
+ this.filterValue = "all";
1149
+ this.alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ#".split("");
1150
+ this.dataList = [];
1151
+ this.selectedData = [];
1152
+ this.groupedEntityData = {};
1153
+ this.selectionType = "";
1154
+ this.selectionTypeEnum = NsAccessControlConfig.SelectionType;
1155
+ this.radioSelections = [];
1156
+ this.data = inject(MAT_DIALOG_DATA);
1157
+ }
1158
+ ngOnInit() {
1159
+ // If data was passed to the dialog, initialize selections
1160
+ this.accessControlCriteriaSelection = this.accessControlService.accessControlConfig().accessControlCriteriaSelection;
1161
+ if (this.data) {
1162
+ this.selectionType = this.data?.condition?.entity;
1163
+ }
1164
+ if (this.data && this.data.selected) {
1165
+ this.selectedData = this.data.selected;
1166
+ }
1167
+ // Subscribe to search control changes
1168
+ this.searchControl.valueChanges.pipe(takeUntil(this.destroy$)).subscribe((query) => {
1169
+ if (this.selectionType) {
1170
+ switch (this.selectionType) {
1171
+ case this.selectionTypeEnum.Service:
1172
+ this.getServicesList(query);
1173
+ break;
1174
+ case this.selectionTypeEnum.Cadre:
1175
+ this.getCadreList(query);
1176
+ break;
1177
+ case this.selectionTypeEnum.Batch:
1178
+ this.getBatchList(query);
1179
+ break;
1180
+ }
1181
+ }
1182
+ });
1183
+ this.initializeDisplay();
1184
+ }
1185
+ initializeDisplay() {
1186
+ switch (this.selectionType) {
1187
+ case NsAccessControlConfig.SelectionType.Organizations:
1188
+ this.radioSelections = this.accessControlCriteriaSelection.organizationRadioSelection;
1189
+ break;
1190
+ case NsAccessControlConfig.SelectionType.Designation:
1191
+ const selectionIds = this.data?.rule?.conditions?.find((c) => c.entity === NsAccessControlConfig.SelectionType.Organizations)?.selections;
1192
+ if (selectionIds?.length) {
1193
+ this.getDesignationsList("");
1194
+ }
1195
+ this.radioSelections = this.accessControlCriteriaSelection.designationRadioSelection;
1196
+ break;
1197
+ case NsAccessControlConfig.SelectionType.Service:
1198
+ this.radioSelections = this.accessControlCriteriaSelection.servicesRadioSelection;
1199
+ this.getServicesList(this.searchControl.value);
1200
+ break;
1201
+ case NsAccessControlConfig.SelectionType.Cadre:
1202
+ this.radioSelections = [{ value: "all", label: "All" }];
1203
+ this.getCadreList(this.searchControl.value);
1204
+ break;
1205
+ case NsAccessControlConfig.SelectionType.Batch:
1206
+ this.radioSelections = [{ value: "all", label: "All" }];
1207
+ this.getBatchList(this.searchControl.value);
1208
+ break;
1209
+ case NsAccessControlConfig.SelectionType.Group:
1210
+ this.getGroupList();
1211
+ break;
1212
+ case NsAccessControlConfig.SelectionType.VerificationStatus:
1213
+ this.getVerificationStatus();
1214
+ break;
1215
+ }
1216
+ }
1217
+ onClose() {
1218
+ this.dialogRef.close();
1219
+ }
1220
+ getSelectionValue(item) {
1221
+ if (typeof item !== "object" || item === null) {
1222
+ return item;
1223
+ }
1224
+ else if (this.selectionType === NsAccessControlConfig.SelectionType.Cadre ||
1225
+ this.selectionType === NsAccessControlConfig.SelectionType.Service ||
1226
+ this.selectionType === NsAccessControlConfig.SelectionType.Designation) {
1227
+ return item?.name;
1228
+ }
1229
+ return item?.id || item?.identifier || item;
1230
+ }
1231
+ isSelected(item) {
1232
+ const value = this.getSelectionValue(item);
1233
+ return this.selectedData.includes(value);
1234
+ }
1235
+ toggleSelection(item) {
1236
+ const value = this.getSelectionValue(item);
1237
+ const index = this.selectedData.indexOf(value);
1238
+ if (index > -1) {
1239
+ this.selectedData.splice(index, 1);
1240
+ }
1241
+ else {
1242
+ this.selectedData.push(value);
1243
+ }
1244
+ }
1245
+ onFilterChange(event) {
1246
+ this.filterValue = event.value;
1247
+ this.getFilteredEntityGrouped();
1248
+ }
1249
+ search() {
1250
+ switch (this.selectionType) {
1251
+ case NsAccessControlConfig.SelectionType.Designation:
1252
+ this.getDesignationsList(this.searchControl.value);
1253
+ break;
1254
+ case NsAccessControlConfig.SelectionType.Organizations:
1255
+ this.getOrganisationsList(this.searchControl.value);
1256
+ break;
1257
+ case NsAccessControlConfig.SelectionType.Service:
1258
+ this.getServicesList(this.searchControl.value);
1259
+ break;
1260
+ case NsAccessControlConfig.SelectionType.Cadre:
1261
+ this.getCadreList(this.searchControl.value);
1262
+ break;
1263
+ case NsAccessControlConfig.SelectionType.Batch:
1264
+ this.getCadreList(this.searchControl.value);
1265
+ break;
1266
+ }
1267
+ }
1268
+ getFilteredEntityGrouped() {
1269
+ let filtered = this.dataList;
1270
+ // Filter by radio selection only
1271
+ if (this.filterValue === "selected") {
1272
+ filtered = filtered.filter(org => this.isSelected(org));
1273
+ }
1274
+ else if (this.filterValue === "notSelected") {
1275
+ filtered = filtered.filter(org => !this.isSelected(org));
1276
+ }
1277
+ // For batch, group by range and chunk each range
1278
+ if (this.selectionType === this.selectionTypeEnum.Batch) {
1279
+ const batchGrouped = this.groupBatchByRange(filtered);
1280
+ const chunked = {};
1281
+ for (const key in batchGrouped) {
1282
+ chunked[key] = this.chunkArray(batchGrouped[key], 8);
1283
+ }
1284
+ this.groupedEntityData = chunked;
1285
+ return;
1286
+ }
1287
+ // For all other types, group by letter and chunk each group
1288
+ const grouped = {};
1289
+ const temp = {};
1290
+ for (const org of filtered) {
1291
+ let entity = org?.channel || org?.name || org?.designation;
1292
+ let letter = entity?.charAt(0)?.toUpperCase() || "#";
1293
+ if (!/^[A-Z]$/.test(letter)) {
1294
+ letter = "#";
1295
+ }
1296
+ if (!temp[letter])
1297
+ temp[letter] = [];
1298
+ temp[letter].push(org);
1299
+ }
1300
+ for (const letter in temp) {
1301
+ grouped[letter] = this.chunkArray(temp[letter], 7);
1302
+ }
1303
+ this.groupedEntityData = grouped;
1304
+ }
1305
+ scrollToSection(letter) {
1306
+ const section = document.getElementById(`section-${letter}`);
1307
+ if (section) {
1308
+ this.selectedCharacterRange = letter;
1309
+ section.scrollIntoView({ behavior: "smooth", inline: "start" });
1310
+ }
1311
+ }
1312
+ updateAlphabet() {
1313
+ const chars = new Set();
1314
+ for (const data of this.dataList) {
1315
+ let letter = "#";
1316
+ const value = data?.channel || data?.name || data?.designation;
1317
+ letter = value.charAt(0)?.toUpperCase() || "#";
1318
+ if (!/^[A-Z]$/.test(letter)) {
1319
+ letter = "#";
1320
+ }
1321
+ chars.add(letter);
1322
+ }
1323
+ const sorted = Array.from(chars)
1324
+ .filter(c => c !== "#")
1325
+ .sort();
1326
+ if (chars.has("#"))
1327
+ sorted.push("#");
1328
+ this.alphabet = sorted;
1329
+ }
1330
+ get checkIfData() {
1331
+ return ((this.groupedEntityData && Object.keys(this.groupedEntityData).length > 0) ||
1332
+ (this.selectionType === NsAccessControlConfig.SelectionType.Group && this.dataList.length > 0) ||
1333
+ (this.selectionType === NsAccessControlConfig.SelectionType.VerificationStatus && this.dataList.length > 0));
1334
+ }
1335
+ getOrganisationsList(query) {
1336
+ this.isLoading = true;
1337
+ this.accessControlService.fetchOrgList(query).subscribe({
1338
+ next: response => {
1339
+ if (response?.result && response?.result?.response?.content) {
1340
+ this.dataList = response.result.response.content;
1341
+ this.updateAlphabet();
1342
+ this.getFilteredEntityGrouped();
1343
+ }
1344
+ else {
1345
+ this.dataList = [];
1346
+ this.alphabet = [];
1347
+ }
1348
+ },
1349
+ complete: () => {
1350
+ this.isLoading = false;
1351
+ }
1352
+ });
1353
+ }
1354
+ getDesignationsList(query) {
1355
+ this.isLoading = true;
1356
+ const selectionIds = this.data?.rule?.conditions?.find((c) => c.entity === NsAccessControlConfig.SelectionType.Organizations)?.selections;
1357
+ if (selectionIds?.length) {
1358
+ const categories = selectionIds.map((ele) => `${ele}_odcs_designation`);
1359
+ this.accessControlService
1360
+ .fetchDesignationsWithOrg(categories, query)
1361
+ .pipe(takeUntil(this.destroy$))
1362
+ .subscribe({
1363
+ next: response => {
1364
+ if (response?.result && response?.result?.Term) {
1365
+ this.dataList = response?.result?.Term;
1366
+ this.updateAlphabet();
1367
+ this.getFilteredEntityGrouped();
1368
+ }
1369
+ else {
1370
+ this.dataList = [];
1371
+ this.alphabet = [];
1372
+ }
1373
+ },
1374
+ complete: () => {
1375
+ this.isLoading = false;
1376
+ }
1377
+ });
1378
+ }
1379
+ else {
1380
+ this.accessControlService
1381
+ .fetchDesignation(query)
1382
+ .pipe(takeUntil(this.destroy$))
1383
+ .subscribe({
1384
+ next: response => {
1385
+ if (response?.result && response?.result?.result?.data) {
1386
+ this.dataList = response?.result?.result?.data;
1387
+ this.updateAlphabet();
1388
+ this.getFilteredEntityGrouped();
1389
+ }
1390
+ else {
1391
+ this.dataList = [];
1392
+ this.alphabet = [];
1393
+ }
1394
+ },
1395
+ complete: () => {
1396
+ this.isLoading = false;
1397
+ }
1398
+ });
1399
+ }
1400
+ }
1401
+ getServicesList(query) {
1402
+ const baseList = this.accessControlService.holdServiceCadrebatch().service;
1403
+ this.dataList = query ? baseList.filter(service => service.name?.toLowerCase().includes(query.toLowerCase())) : baseList;
1404
+ this.updateAlphabet();
1405
+ this.getFilteredEntityGrouped();
1406
+ }
1407
+ getCadreList(query) {
1408
+ const baseList = this.accessControlService.holdServiceCadrebatch().cadre;
1409
+ this.dataList = query ? baseList.filter(cadre => cadre.name?.toLowerCase().includes(query.toLowerCase())) : baseList;
1410
+ this.updateAlphabet();
1411
+ this.getFilteredEntityGrouped();
1412
+ }
1413
+ getBatchList(query) {
1414
+ const baseList = this.accessControlService.holdServiceCadrebatch().batch;
1415
+ this.dataList = query ? baseList.filter(batch => batch.toString().includes(query)) : baseList;
1416
+ this.updateBatchRanges();
1417
+ this.getFilteredEntityGrouped();
1418
+ }
1419
+ getGroupList() {
1420
+ this.isLoading = true;
1421
+ this.accessControlService
1422
+ .fetchGroupsList()
1423
+ .pipe(takeUntil(this.destroy$))
1424
+ .subscribe({
1425
+ next: (response) => {
1426
+ if (response?.result && response?.result?.response) {
1427
+ this.dataList = response.result.response;
1428
+ }
1429
+ },
1430
+ complete: () => {
1431
+ this.isLoading = false;
1432
+ }
1433
+ });
1434
+ }
1435
+ getVerificationStatus() {
1436
+ this.dataList = this.accessControlCriteriaSelection.verificationStatus;
1437
+ }
1438
+ updateBatchRanges() {
1439
+ this.batchRanges = BATCH_RANGES.map(range => range.label);
1440
+ }
1441
+ groupBatchByRange(batchList) {
1442
+ const grouped = {};
1443
+ for (const range of BATCH_RANGES) {
1444
+ grouped[range.label] = batchList.filter(year => year >= range.start && year <= range.end);
1445
+ }
1446
+ return grouped;
1447
+ }
1448
+ getModalTitle() {
1449
+ switch (this.selectionType) {
1450
+ case NsAccessControlConfig.SelectionType.Designation:
1451
+ return "Select Designation";
1452
+ case NsAccessControlConfig.SelectionType.Organizations:
1453
+ return "Select Organisation";
1454
+ case NsAccessControlConfig.SelectionType.Service:
1455
+ return "Select Services";
1456
+ case NsAccessControlConfig.SelectionType.Cadre:
1457
+ return "Select Cadre";
1458
+ case NsAccessControlConfig.SelectionType.Batch:
1459
+ return "Select Batch";
1460
+ case NsAccessControlConfig.SelectionType.Group:
1461
+ return "Select Group";
1462
+ case NsAccessControlConfig.SelectionType.VerificationStatus:
1463
+ return "Verification Status";
1464
+ }
1465
+ return "";
1466
+ }
1467
+ applySelections() {
1468
+ this.dialogRef.close({
1469
+ rule: this.data.rule,
1470
+ condition: this.data.condition,
1471
+ selected: this.selectedData
1472
+ });
1473
+ }
1474
+ chunkArray(array, chunkSize) {
1475
+ const results = [];
1476
+ for (let i = 0; i < array.length; i += chunkSize) {
1477
+ results.push(array.slice(i, i + chunkSize));
1478
+ }
1479
+ return results;
1480
+ }
1481
+ ngOnDestroy() {
1482
+ this.destroy$.next();
1483
+ this.destroy$.complete();
1484
+ }
1485
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EntitySelectionsComponent, deps: [{ token: i1$3.MatDialogRef }, { token: AccessControlService }], target: i0.ɵɵFactoryTarget.Component }); }
1486
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: EntitySelectionsComponent, selector: "sb-uic-entity-selections", ngImport: i0, template: "<div class=\"flex justify-between dialog-heading items-center\">\n <h2 mat-dialog-title class=\"mb-0\">{{ getModalTitle() }}</h2>\n <button mat-icon-button class=\"close-button\" (click)=\"onClose()\">\n <mat-icon>close</mat-icon>\n </button>\n</div>\n\n<div mat-dialog-content>\n <ng-container\n *ngIf=\"\n selectionType === selectionTypeEnum.Designation ||\n selectionType === selectionTypeEnum.Service ||\n selectionType === selectionTypeEnum.Cadre ||\n selectionType === selectionTypeEnum.Batch ||\n selectionType === selectionTypeEnum.Organizations\n \">\n <!-- Search Box -->\n <div class=\"search-container flex items-center gap-4\">\n <div class=\"mat-full-radius flex-grow\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-icon matPrefix>search</mat-icon>\n <input matInput placeholder=\"Type here to search...\" [formControl]=\"searchControl\" (keyup.enter)=\"search()\" />\n </mat-form-field>\n </div>\n <button\n mat-flat-button\n [disabled]=\"!searchControl.value\"\n class=\"flex items-center rounded-full new-bg-color font-bold text-sm text-white search-button\"\n (click)=\"search()\">\n Search\n </button>\n </div>\n\n <div class=\"p-4 mt-2\">\n <!-- Filter Options -->\n <ng-container *ngIf=\"dataList.length && this.selectionType !== selectionTypeEnum.Cadre && this.selectionType !== selectionTypeEnum.Batch\">\n <div class=\"filter-options\">\n <mat-radio-group [(ngModel)]=\"filterValue\" aria-label=\"Filter options\" (change)=\"onFilterChange($event)\">\n <ng-container *ngFor=\"let item of radioSelections\">\n <mat-radio-button [value]=\"item?.value\">{{ item?.label }}</mat-radio-button>\n </ng-container>\n </mat-radio-group>\n </div>\n </ng-container>\n\n <div class=\"org-container\">\n <!-- A-Z Filter Bar -->\n <ng-container *ngIf=\"isLoading\">\n <div class=\"spinner-loader flex items-center justify-center\">\n <mat-spinner></mat-spinner>\n </div>\n </ng-container>\n <ng-container *ngIf=\"!isLoading\">\n <ng-container *ngIf=\"checkIfData\">\n <div class=\"alphabet-filter\" *ngIf=\"this.selectionType !== selectionTypeEnum.Batch\">\n <ng-container *ngFor=\"let letter of alphabet; let i = index; let last = last\">\n <button\n mat-button\n class=\"letter-button\"\n (click)=\"scrollToSection(letter)\"\n [ngClass]=\"{\n 'active-range-btn': selectedCharacterRange === letter\n }\">\n {{ letter }}\n </button>\n <div class=\"divider-apl\" *ngIf=\"!last\"></div>\n </ng-container>\n </div>\n <div class=\"alphabet-filter\" *ngIf=\"this.selectionType === selectionTypeEnum.Batch\">\n <ng-container *ngFor=\"let letter of batchRanges; let i = index; let last = last\">\n <button\n mat-button\n class=\"range-button px-4\"\n (click)=\"scrollToSection(letter)\"\n [ngClass]=\"{\n 'active-range-btn': selectedCharacterRange === letter\n }\">\n {{ letter }}\n </button>\n <div class=\"divider-apl\" *ngIf=\"!last\"></div>\n </ng-container>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"checkIfData; else noData\">\n <div class=\"flex overflow-x-auto\">\n <ng-container *ngFor=\"let group of groupedEntityData | keyvalue\">\n <div class=\"org-column p-2 mr-4\" [attr.id]=\"'section-' + group.key\">\n <div class=\"org-list\">\n <div class=\"batch-range-columns\">\n <ng-container *ngIf=\"group.value && group.value.length\">\n <ng-container *ngFor=\"let column of group.value\">\n <div class=\"batch-column\">\n <div *ngFor=\"let entity of column\" class=\"org-card py-2\">\n <ng-container\n *ngIf=\"\n selectionType === selectionTypeEnum.Designation ||\n selectionType === selectionTypeEnum.Organizations ||\n selectionType === selectionTypeEnum.Service ||\n selectionType === selectionTypeEnum.Cadre\n \">\n <mat-checkbox\n [checked]=\"isSelected(entity)\"\n (change)=\"toggleSelection(entity)\"\n [title]=\"entity?.name || entity?.designation || entity?.channel\">\n {{ entity?.name || entity?.designation || entity?.channel }}\n </mat-checkbox>\n </ng-container>\n <ng-container *ngIf=\"selectionType === selectionTypeEnum.Batch\">\n <mat-checkbox [checked]=\"isSelected(entity)\" (change)=\"toggleSelection(entity)\" [title]=\"entity\">\n {{ entity }}\n </mat-checkbox>\n </ng-container>\n </div>\n </div>\n </ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n\n <ng-template #noData>\n <div class=\"no-data p-4 flex flex-column items-center justify-center\">\n <img src=\"/assets/icons/no-events.png\" alt=\"no-data\" />\n <span class=\"font-bold\">No information to display yet</span>\n </div>\n </ng-template>\n </ng-container>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"selectionType === selectionTypeEnum.Group\">\n <ng-container *ngIf=\"isLoading\">\n <div class=\"spinner-loader flex items-center justify-center\">\n <mat-spinner></mat-spinner>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"!isLoading\">\n <div class=\"flex gap-16 items-center p-4 options-checkbox\">\n <ng-container *ngFor=\"let group of dataList\">\n <mat-checkbox [checked]=\"isSelected(group)\" (change)=\"toggleSelection(group)\" [title]=\"group\">\n {{ group }}\n </mat-checkbox>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"selectionType === selectionTypeEnum.VerificationStatus\">\n <div class=\"flex gap-16 items-center p-4 options-checkbox\">\n <ng-container *ngFor=\"let group of dataList\">\n <mat-checkbox [checked]=\"isSelected(group)\" (change)=\"toggleSelection(group)\" [title]=\"group\">\n {{ group }}\n </mat-checkbox>\n </ng-container>\n </div>\n </ng-container>\n</div>\n\n<mat-dialog-actions>\n <ng-container *ngIf=\"checkIfData\">\n <div class=\"flex gap-4 items-center ml-auto mr-1 apply-button-container my-2\">\n <div class=\"text-xs\">{{ selectedData.length }} items selected</div>\n <button\n mat-flat-button\n [disabled]=\"selectedData.length === 0\"\n (click)=\"applySelections()\"\n class=\"flex items-center justify-center rounded-full new-bg-color font-bold text-sm text-white mt-2\">\n Apply\n </button>\n </div>\n </ng-container>\n</mat-dialog-actions>\n", styles: [":host{display:block}.dialog-heading{border-bottom:2px solid rgba(0,0,0,.12);padding:0 16px}::ng-deep .mat-mdc-dialog-container .mdc-dialog__title{margin-bottom:8px!important;font-family:Montserrat;font-weight:600;font-size:16px;color:#000000de;padding:0 0 9px}.close-button{margin-right:-8px}::ng-deep .mat-form-field-wrapper{padding-bottom:0!important}.search-button{padding:4px 24px}.filter-options{margin-bottom:15px}.filter-options .mat-radio-button{margin-right:24px}.org-container{display:flex;flex-direction:column}.alphabet-filter{display:flex;flex-wrap:wrap;justify-content:flex-start;align-items:center;padding:8px 0}.alphabet-filter .divider-apl{width:1px;height:14px;background-color:#00000029}.alphabet-filter .letter-button,.alphabet-filter .range-button{min-width:30px;padding:0;margin:2px;line-height:30px;font-family:Lato;font-weight:400;font-size:12px;color:#0009}.alphabet-filter .letter-button.active-range-btn,.alphabet-filter .active-range-btn.range-button{font-weight:700;font-size:14px;color:#000}.alphabet-filter .range-button{padding:0 16px!important}.organization-scroll{flex:1;overflow-x:auto;white-space:nowrap}.org-row{display:flex;flex-direction:row}.org-column .org-list{display:flex;flex-direction:column;gap:6px}.org-column .org-card .mat-checkbox ::ng-deep .mat-checkbox-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;width:180px;font-family:Lato;font-weight:700;font-size:14px;line-height:14px;color:#000000de}:host ::ng-deep .mat-mdc-dialog-content{max-height:79vh!important}.apply-button-container div:first-child{color:#0009}.apply-button-container button{padding:0 54px}.spinner-loader{height:200px}.no-data span{font-family:Lato;font-size:8.98px;color:#000000de}.batch-range-title{font-weight:700;margin-bottom:8px}.batch-range-columns{display:flex;flex-direction:row;gap:24px}.batch-column{display:flex;flex-direction:column;min-width:180px}.options-checkbox .mat-checkbox ::ng-deep .mat-checkbox-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;font-family:Lato;font-weight:700;font-size:14px;line-height:14px;color:#000000de}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5$2.MatLegacyRadioGroup, selector: "mat-radio-group", exportAs: ["matRadioGroup"] }, { kind: "component", type: i5$2.MatLegacyRadioButton, selector: "mat-radio-button", inputs: ["disableRipple", "tabIndex"], exportAs: ["matRadioButton"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i1$3.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$3.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i1$3.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "component", type: i4$1.MatLegacyCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i7.MatLegacyFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i7.MatLegacyPrefix, selector: "[matPrefix]" }, { kind: "directive", type: i8.MatLegacyInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", exportAs: ["matInput"] }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i5$1.MatLegacyButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i12.MatLegacyProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { kind: "pipe", type: i3.KeyValuePipe, name: "keyvalue" }] }); }
1487
+ }
1488
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EntitySelectionsComponent, decorators: [{
1489
+ type: Component,
1490
+ args: [{ selector: "sb-uic-entity-selections", template: "<div class=\"flex justify-between dialog-heading items-center\">\n <h2 mat-dialog-title class=\"mb-0\">{{ getModalTitle() }}</h2>\n <button mat-icon-button class=\"close-button\" (click)=\"onClose()\">\n <mat-icon>close</mat-icon>\n </button>\n</div>\n\n<div mat-dialog-content>\n <ng-container\n *ngIf=\"\n selectionType === selectionTypeEnum.Designation ||\n selectionType === selectionTypeEnum.Service ||\n selectionType === selectionTypeEnum.Cadre ||\n selectionType === selectionTypeEnum.Batch ||\n selectionType === selectionTypeEnum.Organizations\n \">\n <!-- Search Box -->\n <div class=\"search-container flex items-center gap-4\">\n <div class=\"mat-full-radius flex-grow\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-icon matPrefix>search</mat-icon>\n <input matInput placeholder=\"Type here to search...\" [formControl]=\"searchControl\" (keyup.enter)=\"search()\" />\n </mat-form-field>\n </div>\n <button\n mat-flat-button\n [disabled]=\"!searchControl.value\"\n class=\"flex items-center rounded-full new-bg-color font-bold text-sm text-white search-button\"\n (click)=\"search()\">\n Search\n </button>\n </div>\n\n <div class=\"p-4 mt-2\">\n <!-- Filter Options -->\n <ng-container *ngIf=\"dataList.length && this.selectionType !== selectionTypeEnum.Cadre && this.selectionType !== selectionTypeEnum.Batch\">\n <div class=\"filter-options\">\n <mat-radio-group [(ngModel)]=\"filterValue\" aria-label=\"Filter options\" (change)=\"onFilterChange($event)\">\n <ng-container *ngFor=\"let item of radioSelections\">\n <mat-radio-button [value]=\"item?.value\">{{ item?.label }}</mat-radio-button>\n </ng-container>\n </mat-radio-group>\n </div>\n </ng-container>\n\n <div class=\"org-container\">\n <!-- A-Z Filter Bar -->\n <ng-container *ngIf=\"isLoading\">\n <div class=\"spinner-loader flex items-center justify-center\">\n <mat-spinner></mat-spinner>\n </div>\n </ng-container>\n <ng-container *ngIf=\"!isLoading\">\n <ng-container *ngIf=\"checkIfData\">\n <div class=\"alphabet-filter\" *ngIf=\"this.selectionType !== selectionTypeEnum.Batch\">\n <ng-container *ngFor=\"let letter of alphabet; let i = index; let last = last\">\n <button\n mat-button\n class=\"letter-button\"\n (click)=\"scrollToSection(letter)\"\n [ngClass]=\"{\n 'active-range-btn': selectedCharacterRange === letter\n }\">\n {{ letter }}\n </button>\n <div class=\"divider-apl\" *ngIf=\"!last\"></div>\n </ng-container>\n </div>\n <div class=\"alphabet-filter\" *ngIf=\"this.selectionType === selectionTypeEnum.Batch\">\n <ng-container *ngFor=\"let letter of batchRanges; let i = index; let last = last\">\n <button\n mat-button\n class=\"range-button px-4\"\n (click)=\"scrollToSection(letter)\"\n [ngClass]=\"{\n 'active-range-btn': selectedCharacterRange === letter\n }\">\n {{ letter }}\n </button>\n <div class=\"divider-apl\" *ngIf=\"!last\"></div>\n </ng-container>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"checkIfData; else noData\">\n <div class=\"flex overflow-x-auto\">\n <ng-container *ngFor=\"let group of groupedEntityData | keyvalue\">\n <div class=\"org-column p-2 mr-4\" [attr.id]=\"'section-' + group.key\">\n <div class=\"org-list\">\n <div class=\"batch-range-columns\">\n <ng-container *ngIf=\"group.value && group.value.length\">\n <ng-container *ngFor=\"let column of group.value\">\n <div class=\"batch-column\">\n <div *ngFor=\"let entity of column\" class=\"org-card py-2\">\n <ng-container\n *ngIf=\"\n selectionType === selectionTypeEnum.Designation ||\n selectionType === selectionTypeEnum.Organizations ||\n selectionType === selectionTypeEnum.Service ||\n selectionType === selectionTypeEnum.Cadre\n \">\n <mat-checkbox\n [checked]=\"isSelected(entity)\"\n (change)=\"toggleSelection(entity)\"\n [title]=\"entity?.name || entity?.designation || entity?.channel\">\n {{ entity?.name || entity?.designation || entity?.channel }}\n </mat-checkbox>\n </ng-container>\n <ng-container *ngIf=\"selectionType === selectionTypeEnum.Batch\">\n <mat-checkbox [checked]=\"isSelected(entity)\" (change)=\"toggleSelection(entity)\" [title]=\"entity\">\n {{ entity }}\n </mat-checkbox>\n </ng-container>\n </div>\n </div>\n </ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n\n <ng-template #noData>\n <div class=\"no-data p-4 flex flex-column items-center justify-center\">\n <img src=\"/assets/icons/no-events.png\" alt=\"no-data\" />\n <span class=\"font-bold\">No information to display yet</span>\n </div>\n </ng-template>\n </ng-container>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"selectionType === selectionTypeEnum.Group\">\n <ng-container *ngIf=\"isLoading\">\n <div class=\"spinner-loader flex items-center justify-center\">\n <mat-spinner></mat-spinner>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"!isLoading\">\n <div class=\"flex gap-16 items-center p-4 options-checkbox\">\n <ng-container *ngFor=\"let group of dataList\">\n <mat-checkbox [checked]=\"isSelected(group)\" (change)=\"toggleSelection(group)\" [title]=\"group\">\n {{ group }}\n </mat-checkbox>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"selectionType === selectionTypeEnum.VerificationStatus\">\n <div class=\"flex gap-16 items-center p-4 options-checkbox\">\n <ng-container *ngFor=\"let group of dataList\">\n <mat-checkbox [checked]=\"isSelected(group)\" (change)=\"toggleSelection(group)\" [title]=\"group\">\n {{ group }}\n </mat-checkbox>\n </ng-container>\n </div>\n </ng-container>\n</div>\n\n<mat-dialog-actions>\n <ng-container *ngIf=\"checkIfData\">\n <div class=\"flex gap-4 items-center ml-auto mr-1 apply-button-container my-2\">\n <div class=\"text-xs\">{{ selectedData.length }} items selected</div>\n <button\n mat-flat-button\n [disabled]=\"selectedData.length === 0\"\n (click)=\"applySelections()\"\n class=\"flex items-center justify-center rounded-full new-bg-color font-bold text-sm text-white mt-2\">\n Apply\n </button>\n </div>\n </ng-container>\n</mat-dialog-actions>\n", styles: [":host{display:block}.dialog-heading{border-bottom:2px solid rgba(0,0,0,.12);padding:0 16px}::ng-deep .mat-mdc-dialog-container .mdc-dialog__title{margin-bottom:8px!important;font-family:Montserrat;font-weight:600;font-size:16px;color:#000000de;padding:0 0 9px}.close-button{margin-right:-8px}::ng-deep .mat-form-field-wrapper{padding-bottom:0!important}.search-button{padding:4px 24px}.filter-options{margin-bottom:15px}.filter-options .mat-radio-button{margin-right:24px}.org-container{display:flex;flex-direction:column}.alphabet-filter{display:flex;flex-wrap:wrap;justify-content:flex-start;align-items:center;padding:8px 0}.alphabet-filter .divider-apl{width:1px;height:14px;background-color:#00000029}.alphabet-filter .letter-button,.alphabet-filter .range-button{min-width:30px;padding:0;margin:2px;line-height:30px;font-family:Lato;font-weight:400;font-size:12px;color:#0009}.alphabet-filter .letter-button.active-range-btn,.alphabet-filter .active-range-btn.range-button{font-weight:700;font-size:14px;color:#000}.alphabet-filter .range-button{padding:0 16px!important}.organization-scroll{flex:1;overflow-x:auto;white-space:nowrap}.org-row{display:flex;flex-direction:row}.org-column .org-list{display:flex;flex-direction:column;gap:6px}.org-column .org-card .mat-checkbox ::ng-deep .mat-checkbox-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;width:180px;font-family:Lato;font-weight:700;font-size:14px;line-height:14px;color:#000000de}:host ::ng-deep .mat-mdc-dialog-content{max-height:79vh!important}.apply-button-container div:first-child{color:#0009}.apply-button-container button{padding:0 54px}.spinner-loader{height:200px}.no-data span{font-family:Lato;font-size:8.98px;color:#000000de}.batch-range-title{font-weight:700;margin-bottom:8px}.batch-range-columns{display:flex;flex-direction:row;gap:24px}.batch-column{display:flex;flex-direction:column;min-width:180px}.options-checkbox .mat-checkbox ::ng-deep .mat-checkbox-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;font-family:Lato;font-weight:700;font-size:14px;line-height:14px;color:#000000de}\n"] }]
1491
+ }], ctorParameters: function () { return [{ type: i1$3.MatDialogRef }, { type: AccessControlService }]; } });
1492
+
1493
+ class ConfirmDialogComponent {
1494
+ constructor(dialogRef) {
1495
+ this.dialogRef = dialogRef;
1496
+ this.data = inject(MAT_DIALOG_DATA);
1497
+ }
1498
+ confirmNo() {
1499
+ this.dialogRef.close({ action: NsAccessControlConfig.IActions.Reject });
1500
+ }
1501
+ confirmYes() {
1502
+ this.dialogRef.close({ action: NsAccessControlConfig.IActions.Confirm });
1503
+ }
1504
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ConfirmDialogComponent, deps: [{ token: i1$3.MatDialogRef }], target: i0.ɵɵFactoryTarget.Component }); }
1505
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ConfirmDialogComponent, selector: "sb-uic-confirm-dialog", ngImport: i0, template: "<div class=\"dialog-confirm p-4\">\n <div class=\"flex items-center justify-center flex-column\">\n <div class=\"icon mb-6\" [ngSwitch]=\"data.type\">\n <mat-icon *ngSwitchCase=\"'delete'\">delete</mat-icon>\n <mat-icon *ngSwitchCase=\"'confirm-access-type'\" svgIcon=\"radio-on\"></mat-icon>\n </div>\n\n <div [ngSwitch]=\"data?.type\">\n <ng-container *ngSwitchCase=\"'delete'\">\n <div class=\"confirm-title text-center\">Are you sure you want to delete {{ data?.additionalData || \"\" }} ?</div>\n <div class=\"confirm-desc text-center\">\n Once deleted, it cannot be restored, and any access permissions associated with it will be removed. This action is irreversible.\n </div>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'confirm-access-type'\">\n <div class=\"confirm-title text-center\">Are you sure you want to opt for \"Public\" access?</div>\n <div class=\"confirm-desc text-center\">Or else please cancel and select <strong>\"Custom\"</strong> for the restricted content access.</div>\n </ng-container>\n </div>\n\n <div class=\"confirm-actions flex items-center gap-4 mt-4\" [ngSwitch]=\"data?.type\">\n <ng-container *ngSwitchCase=\"'delete'\">\n <button mat-flat-button class=\"mat-btn-outline mt-2 gap-2\" (click)=\"confirmNo()\">No</button>\n <button mat-flat-button class=\"new-bg-color text-white mt-2\" (click)=\"confirmYes()\">Yes</button>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'confirm-access-type'\">\n <button mat-flat-button class=\"mat-btn-outline mt-2 gap-2\" (click)=\"confirmNo()\">Cancel</button>\n <button mat-flat-button class=\"new-bg-color text-white mt-2\" (click)=\"confirmYes()\">Yes</button>\n </ng-container>\n </div>\n </div>\n</div>\n", styles: [".confirm-title{font-family:Montserrat;font-weight:600;font-size:14px;color:#1b2133}.confirm-desc{font-family:Lato;font-weight:400;font-size:14px;color:#0009}.icon mat-icon{font-size:56px;height:56px;width:56px;color:#1b4ca1}.confirm-actions button{padding:0 32px!important}\n"], dependencies: [{ kind: "directive", type: i3.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i3.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i5$1.MatLegacyButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }] }); }
1506
+ }
1507
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ConfirmDialogComponent, decorators: [{
1508
+ type: Component,
1509
+ args: [{ selector: "sb-uic-confirm-dialog", template: "<div class=\"dialog-confirm p-4\">\n <div class=\"flex items-center justify-center flex-column\">\n <div class=\"icon mb-6\" [ngSwitch]=\"data.type\">\n <mat-icon *ngSwitchCase=\"'delete'\">delete</mat-icon>\n <mat-icon *ngSwitchCase=\"'confirm-access-type'\" svgIcon=\"radio-on\"></mat-icon>\n </div>\n\n <div [ngSwitch]=\"data?.type\">\n <ng-container *ngSwitchCase=\"'delete'\">\n <div class=\"confirm-title text-center\">Are you sure you want to delete {{ data?.additionalData || \"\" }} ?</div>\n <div class=\"confirm-desc text-center\">\n Once deleted, it cannot be restored, and any access permissions associated with it will be removed. This action is irreversible.\n </div>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'confirm-access-type'\">\n <div class=\"confirm-title text-center\">Are you sure you want to opt for \"Public\" access?</div>\n <div class=\"confirm-desc text-center\">Or else please cancel and select <strong>\"Custom\"</strong> for the restricted content access.</div>\n </ng-container>\n </div>\n\n <div class=\"confirm-actions flex items-center gap-4 mt-4\" [ngSwitch]=\"data?.type\">\n <ng-container *ngSwitchCase=\"'delete'\">\n <button mat-flat-button class=\"mat-btn-outline mt-2 gap-2\" (click)=\"confirmNo()\">No</button>\n <button mat-flat-button class=\"new-bg-color text-white mt-2\" (click)=\"confirmYes()\">Yes</button>\n </ng-container>\n\n <ng-container *ngSwitchCase=\"'confirm-access-type'\">\n <button mat-flat-button class=\"mat-btn-outline mt-2 gap-2\" (click)=\"confirmNo()\">Cancel</button>\n <button mat-flat-button class=\"new-bg-color text-white mt-2\" (click)=\"confirmYes()\">Yes</button>\n </ng-container>\n </div>\n </div>\n</div>\n", styles: [".confirm-title{font-family:Montserrat;font-weight:600;font-size:14px;color:#1b2133}.confirm-desc{font-family:Lato;font-weight:400;font-size:14px;color:#0009}.icon mat-icon{font-size:56px;height:56px;width:56px;color:#1b4ca1}.confirm-actions button{padding:0 32px!important}\n"] }]
1510
+ }], ctorParameters: function () { return [{ type: i1$3.MatDialogRef }]; } });
1511
+
1512
+ class AccessControlGuideComponent {
1513
+ constructor(dialogRef, accessControlService) {
1514
+ this.dialogRef = dialogRef;
1515
+ this.accessControlService = accessControlService;
1516
+ }
1517
+ ngOnInit() {
1518
+ this.accessControlGuideConfig = this.accessControlService.accessControlConfig().accessControlGuide;
1519
+ }
1520
+ onClose() {
1521
+ this.dialogRef.close();
1522
+ }
1523
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AccessControlGuideComponent, deps: [{ token: i1$3.MatDialogRef }, { token: AccessControlService }], target: i0.ɵɵFactoryTarget.Component }); }
1524
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: AccessControlGuideComponent, selector: "sb-uic-access-control-guide", ngImport: i0, template: "<div class=\"flex justify-between dialog-heading items-center\">\n <h2 mat-dialog-title class=\"mb-0\">Access Control Guide</h2>\n <button mat-icon-button class=\"close-button\" (click)=\"onClose()\">\n <mat-icon>close</mat-icon>\n </button>\n</div>\n<div mat-dialog-content>\n <div class=\"video-wrapper\">\n <video src=\"\"></video>\n </div>\n\n <div class=\"guide-information\">\n <mat-tab-group dynamicHeight mat-stretch-tabs=\"false\" mat-align-tabs=\"start\">\n <mat-tab label=\"Summary\" *ngIf=\"accessControlGuideConfig?.canShowSummaryTab\">\n <div class=\"about-guide text-xs text-dark py-4\">\n {{ accessControlGuideConfig?.summaryText || \"\" }}\n </div>\n </mat-tab>\n <mat-tab label=\"Transcript\" *ngIf=\"accessControlGuideConfig?.canShowTranscriptTab\">No data yet </mat-tab>\n </mat-tab-group>\n </div>\n</div>\n", styles: [".dialog-heading{border-bottom:2px solid rgba(0,0,0,.12);padding:0 16px}.dialog-heading h2{font-family:Montserrat;font-weight:600;font-size:20px;margin-bottom:12px;padding-left:16px}:host ::ng-deep .mat-mdc-dialog-content{max-height:79vh!important}::ng-deep .mat-mdc-tab .mdc-tab__text-label{color:#241c15a6;font-family:Lato;font-weight:400;font-size:16px}::ng-deep .mat-mdc-tab.mdc-tab--active:hover .mdc-tab-indicator__content--underline{border-color:#1b4ca1;--mat-tab-header-active-label-text-color: #1b4ca1 !important}:host ::ng-deep .mat-mdc-tab.mdc-tab--active .mdc-tab__text-label{font-family:Lato;font-weight:700;font-size:14px;color:#000000de}.mat-mdc-tab-header{--mdc-tab-indicator-active-indicator-height: 2.5px !important}\n"], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i1$3.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$3.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: i5$1.MatLegacyButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i11.MatTab, selector: "mat-tab", inputs: ["disabled"], exportAs: ["matTab"] }, { kind: "component", type: i11.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "disableRipple", "fitInkBarToContent", "mat-stretch-tabs"], exportAs: ["matTabGroup"] }] }); }
1525
+ }
1526
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AccessControlGuideComponent, decorators: [{
1527
+ type: Component,
1528
+ args: [{ selector: "sb-uic-access-control-guide", template: "<div class=\"flex justify-between dialog-heading items-center\">\n <h2 mat-dialog-title class=\"mb-0\">Access Control Guide</h2>\n <button mat-icon-button class=\"close-button\" (click)=\"onClose()\">\n <mat-icon>close</mat-icon>\n </button>\n</div>\n<div mat-dialog-content>\n <div class=\"video-wrapper\">\n <video src=\"\"></video>\n </div>\n\n <div class=\"guide-information\">\n <mat-tab-group dynamicHeight mat-stretch-tabs=\"false\" mat-align-tabs=\"start\">\n <mat-tab label=\"Summary\" *ngIf=\"accessControlGuideConfig?.canShowSummaryTab\">\n <div class=\"about-guide text-xs text-dark py-4\">\n {{ accessControlGuideConfig?.summaryText || \"\" }}\n </div>\n </mat-tab>\n <mat-tab label=\"Transcript\" *ngIf=\"accessControlGuideConfig?.canShowTranscriptTab\">No data yet </mat-tab>\n </mat-tab-group>\n </div>\n</div>\n", styles: [".dialog-heading{border-bottom:2px solid rgba(0,0,0,.12);padding:0 16px}.dialog-heading h2{font-family:Montserrat;font-weight:600;font-size:20px;margin-bottom:12px;padding-left:16px}:host ::ng-deep .mat-mdc-dialog-content{max-height:79vh!important}::ng-deep .mat-mdc-tab .mdc-tab__text-label{color:#241c15a6;font-family:Lato;font-weight:400;font-size:16px}::ng-deep .mat-mdc-tab.mdc-tab--active:hover .mdc-tab-indicator__content--underline{border-color:#1b4ca1;--mat-tab-header-active-label-text-color: #1b4ca1 !important}:host ::ng-deep .mat-mdc-tab.mdc-tab--active .mdc-tab__text-label{font-family:Lato;font-weight:700;font-size:14px;color:#000000de}.mat-mdc-tab-header{--mdc-tab-indicator-active-indicator-height: 2.5px !important}\n"] }]
1529
+ }], ctorParameters: function () { return [{ type: i1$3.MatDialogRef }, { type: AccessControlService }]; } });
1530
+
1531
+ class CadreMappingService {
1532
+ constructor() {
1533
+ this.allCadres = new Map();
1534
+ this.allServices = new Map();
1535
+ this.cadreToServiceMap = new Map();
1536
+ this.serviceToCadresMap = new Map();
1537
+ this.batchYearToCadresMap = new Map();
1538
+ this.batchYearToServicesMap = new Map();
1539
+ }
1540
+ addToMapSet(map, key, value) {
1541
+ if (!map.has(key)) {
1542
+ map.set(key, new Set());
1543
+ }
1544
+ map.get(key)?.add(value);
1545
+ }
1546
+ initialize(data) {
1547
+ // Clear existing data
1548
+ this.allCadres.clear();
1549
+ this.allServices.clear();
1550
+ this.cadreToServiceMap.clear();
1551
+ this.serviceToCadresMap.clear();
1552
+ this.batchYearToCadresMap.clear();
1553
+ this.batchYearToServicesMap.clear();
1554
+ // Build lookups
1555
+ data?.civilServiceType?.civilServiceTypeList.forEach(cst => {
1556
+ if (cst) {
1557
+ cst.serviceList.forEach(service => {
1558
+ const { id: serviceId, commonBatchStartYear, commonBatchEndYear } = service;
1559
+ this.allServices.set(serviceId, service);
1560
+ // Add years to service-batch map
1561
+ for (let y = commonBatchStartYear; y <= commonBatchEndYear; y++) {
1562
+ this.addToMapSet(this.batchYearToServicesMap, y, serviceId);
1563
+ }
1564
+ service.cadreList?.forEach(cadre => {
1565
+ const { id: cadreId, startBatchYear, endBatchYear } = cadre;
1566
+ this.allCadres.set(cadreId, cadre);
1567
+ // Map cadre <-> service
1568
+ this.addToMapSet(this.cadreToServiceMap, cadreId, serviceId);
1569
+ this.addToMapSet(this.serviceToCadresMap, serviceId, cadreId);
1570
+ // Add years to cadre-batch map
1571
+ for (let y = startBatchYear; y <= endBatchYear; y++) {
1572
+ this.addToMapSet(this.batchYearToCadresMap, y, cadreId);
1573
+ }
1574
+ });
1575
+ });
1576
+ }
1577
+ });
1578
+ }
1579
+ getAllBatchYears() {
1580
+ return Array.from(this.batchYearToCadresMap.keys()).sort((a, b) => a - b);
1581
+ }
1582
+ getAllCadres() {
1583
+ return Array.from(this.allCadres.values()).map(c => ({
1584
+ id: c.id,
1585
+ name: c.name
1586
+ }));
1587
+ }
1588
+ getAllServices() {
1589
+ return Array.from(this.allServices.values()).map(s => ({
1590
+ id: s.id,
1591
+ name: s.name
1592
+ }));
1593
+ }
1594
+ getServicesByCadres(cadreIds) {
1595
+ const serviceIdsSet = new Set();
1596
+ cadreIds.forEach(cadreId => {
1597
+ const services = this.cadreToServiceMap.get(cadreId) || new Set();
1598
+ services.forEach(serviceId => serviceIdsSet.add(serviceId));
1599
+ });
1600
+ return Array.from(serviceIdsSet).map(id => {
1601
+ const s = this.allServices.get(id);
1602
+ return { id: s.id, name: s.name };
1603
+ });
1604
+ }
1605
+ getCadresByServices(serviceIds) {
1606
+ const cadreIdsSet = new Set();
1607
+ serviceIds.forEach(serviceId => {
1608
+ const cadres = this.serviceToCadresMap.get(serviceId) || new Set();
1609
+ cadres.forEach(cadreId => cadreIdsSet.add(cadreId));
1610
+ });
1611
+ return Array.from(cadreIdsSet).map(id => {
1612
+ const c = this.allCadres.get(id);
1613
+ return { id: c.id, name: c.name };
1614
+ });
1615
+ }
1616
+ getCadresByBatchYears(years) {
1617
+ const cadreIdsSet = new Set();
1618
+ years.forEach(year => {
1619
+ const cadres = this.batchYearToCadresMap.get(year) || new Set();
1620
+ cadres.forEach(cadreId => cadreIdsSet.add(cadreId));
1621
+ });
1622
+ return Array.from(cadreIdsSet).map(id => {
1623
+ const c = this.allCadres.get(id);
1624
+ return { id: c.id, name: c.name };
1625
+ });
1626
+ }
1627
+ getServicesByBatchYears(years) {
1628
+ const serviceIdsSet = new Set();
1629
+ years.forEach(year => {
1630
+ const services = this.batchYearToServicesMap.get(year) || new Set();
1631
+ services.forEach(serviceId => serviceIdsSet.add(serviceId));
1632
+ });
1633
+ return Array.from(serviceIdsSet).map(id => {
1634
+ const s = this.allServices.get(id);
1635
+ return { id: s.id, name: s.name };
1636
+ });
1637
+ }
1638
+ getServicesByCadresAndBatch(cadreIds, year) {
1639
+ const services = this.getServicesByCadres(cadreIds);
1640
+ return services.filter(service => {
1641
+ const fullService = this.allServices.get(service.id);
1642
+ return year >= fullService.commonBatchStartYear && year <= fullService.commonBatchEndYear;
1643
+ });
1644
+ }
1645
+ getCadresByServicesAndBatch(serviceIds, year) {
1646
+ const cadres = this.getCadresByServices(serviceIds);
1647
+ return cadres.filter(cadre => {
1648
+ const fullCadre = this.allCadres.get(cadre.id);
1649
+ return year >= fullCadre.startBatchYear && year <= fullCadre.endBatchYear;
1650
+ });
1651
+ }
1652
+ getBatchYearsByCadres(cadreIds) {
1653
+ const batchYearsSet = new Set();
1654
+ cadreIds.forEach(cadreId => {
1655
+ const cadre = this.allCadres.get(cadreId);
1656
+ if (cadre) {
1657
+ for (let y = cadre.startBatchYear; y <= cadre.endBatchYear; y++) {
1658
+ batchYearsSet.add(y);
1659
+ }
1660
+ }
1661
+ });
1662
+ return Array.from(batchYearsSet).sort((a, b) => a - b);
1663
+ }
1664
+ getBatchYearsByServices(serviceIds) {
1665
+ const batchYearsSet = new Set();
1666
+ serviceIds.forEach(serviceId => {
1667
+ const service = this.allServices.get(serviceId);
1668
+ if (service) {
1669
+ for (let y = service.commonBatchStartYear; y <= service.commonBatchEndYear; y++) {
1670
+ batchYearsSet.add(y);
1671
+ }
1672
+ }
1673
+ });
1674
+ return Array.from(batchYearsSet).sort((a, b) => a - b);
1675
+ }
1676
+ getBatchYearsByServicesAndCadres(serviceIds, cadreIds) {
1677
+ const serviceYears = this.getBatchYearsByServices(serviceIds);
1678
+ const cadreYears = this.getBatchYearsByCadres(cadreIds);
1679
+ // Find intersection of years
1680
+ const commonYears = serviceYears.filter(year => cadreYears.includes(year));
1681
+ return commonYears.sort((a, b) => a - b);
1682
+ }
1683
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CadreMappingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1684
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CadreMappingService, providedIn: "root" }); }
1685
+ }
1686
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CadreMappingService, decorators: [{
1687
+ type: Injectable,
1688
+ args: [{
1689
+ providedIn: "root"
1690
+ }]
1691
+ }] });
1692
+
1693
+ class AccessControlComponent {
1694
+ constructor(dialog, fb, accessControlService, cadreMappingService, snackbar) {
1695
+ this.dialog = dialog;
1696
+ this.fb = fb;
1697
+ this.accessControlService = accessControlService;
1698
+ this.cadreMappingService = cadreMappingService;
1699
+ this.snackbar = snackbar;
1700
+ this.contentId = "";
1701
+ this.accessControlData = new EventEmitter();
1702
+ this.accessType = NsAccessControlConfig.IAccessTypes.Public;
1703
+ this.ACCESS_TYPE_ENUM = NsAccessControlConfig.IAccessTypes;
1704
+ this.isLoading = false;
1705
+ this.isVisibilityEnabled = false;
1706
+ this.filterCriteria = false;
1707
+ this.defaultConditionRelationship = "AND";
1708
+ this.defaultUserGroupRelationship = "OR";
1709
+ this.isSaveFltrBtnDisabled = false;
1710
+ this.isApplyBtnDisabled = false;
1711
+ this.isApplying = false;
1712
+ this.isSaving = false;
1713
+ }
1714
+ ngOnInit() {
1715
+ this.initForm();
1716
+ this.getAccessControl();
1717
+ this.accessControlService.accessControlConfig.set(this.config);
1718
+ this.accessControlCriteriaSelection = this.config?.accessControlCriteriaSelection;
1719
+ this.usersTableConfig = this.config?.usersTableConfig;
1720
+ if (!this.contentId) {
1721
+ this.callSnackbar("Content id is required", "error");
1722
+ }
1723
+ if (this.content) {
1724
+ if (this.content?.status === "Draft") {
1725
+ this.isApplyBtnDisabled = true;
1726
+ }
1727
+ if (this.content?.status === "Live") {
1728
+ this.isSaveFltrBtnDisabled = true;
1729
+ }
1730
+ if (this.content?.accessSettingsEnabled) {
1731
+ this.accessType = NsAccessControlConfig.IAccessTypes.Custom;
1732
+ }
1733
+ else {
1734
+ if (this.content?.accessSetting === NsAccessControlConfig.IAccessSetting.ALL_USERS) {
1735
+ this.accessType = NsAccessControlConfig.IAccessTypes.Public;
1736
+ }
1737
+ else if (this.content?.accessSetting === NsAccessControlConfig.IAccessSetting.MDO_SPECIFIC ||
1738
+ this.content?.accessSetting === NsAccessControlConfig.IAccessSetting.CUSTOME_USER) {
1739
+ this.accessType = NsAccessControlConfig.IAccessTypes.Custom;
1740
+ }
1741
+ }
1742
+ }
1743
+ }
1744
+ fetchCadreConfigData() {
1745
+ this.isLoading = true;
1746
+ this.accessControlService.fetchCadreConfig().subscribe({
1747
+ next: (response) => {
1748
+ if (response?.result && response?.result?.response && Object.keys(response?.result?.response)?.length) {
1749
+ this.cadreConfigData = response.result.response?.value;
1750
+ this.cadreMappingService.initialize(this.cadreConfigData);
1751
+ this.accessControlService.holdServiceCadrebatch.set({
1752
+ service: this.cadreMappingService.getAllServices(),
1753
+ batch: this.cadreMappingService.getAllBatchYears(),
1754
+ cadre: this.cadreMappingService.getAllCadres()
1755
+ });
1756
+ }
1757
+ },
1758
+ complete: () => {
1759
+ this.isLoading = false;
1760
+ }
1761
+ });
1762
+ }
1763
+ initForm() {
1764
+ this.accessControlForm = this.fb.group({
1765
+ userGroup: this.fb.array([])
1766
+ });
1767
+ }
1768
+ get userGroup() {
1769
+ return this.accessControlForm.get("userGroup");
1770
+ }
1771
+ ruleConditions(ruleIndex) {
1772
+ return this.userGroup.at(ruleIndex).get("conditions");
1773
+ }
1774
+ onAccessTypeChange(event) {
1775
+ if (!this.cadreConfigData) {
1776
+ this.fetchCadreConfigData();
1777
+ }
1778
+ if (event.value === NsAccessControlConfig.IAccessTypes.Public) {
1779
+ const dialogRef = this.dialog.open(ConfirmDialogComponent, {
1780
+ width: "470px",
1781
+ data: { type: "confirm-access-type" }
1782
+ });
1783
+ dialogRef.afterClosed().subscribe(result => {
1784
+ if (result?.action === NsAccessControlConfig.IActions.Confirm) {
1785
+ this.accessType = NsAccessControlConfig.IAccessTypes.Public;
1786
+ this.updateContentAccessSetting();
1787
+ }
1788
+ else {
1789
+ this.accessType = NsAccessControlConfig.IAccessTypes.Custom;
1790
+ }
1791
+ });
1792
+ }
1793
+ else {
1794
+ this.updateContentAccessSetting();
1795
+ }
1796
+ if (event.value === NsAccessControlConfig.IAccessTypes.Custom) {
1797
+ this.isVisibilityEnabled = false;
1798
+ }
1799
+ }
1800
+ addUserGroup() {
1801
+ const ruleGroup = this.fb.group({
1802
+ id: [v4()],
1803
+ name: [`User Group ${this.userGroup.length + 1}`],
1804
+ description: [`Description for UserGroup ${this.userGroup.length + 1}`],
1805
+ conditions: this.fb.array([this.createConditionGroup(v4(), this.userGroup.length - 1)])
1806
+ });
1807
+ this.userGroup.push(ruleGroup);
1808
+ }
1809
+ addCondition(userGroupIndex) {
1810
+ const conditions = this.ruleConditions(userGroupIndex);
1811
+ const accessSetting = this.content?.accessSetting;
1812
+ // Check if organization/users already exists based on access setting
1813
+ if (accessSetting === NsAccessControlConfig.IAccessSetting.MDO_SPECIFIC || accessSetting === NsAccessControlConfig.IAccessSetting.CUSTOME_USER) {
1814
+ const entityType = accessSetting === NsAccessControlConfig.IAccessSetting.MDO_SPECIFIC
1815
+ ? NsAccessControlConfig.SelectionType.Organizations
1816
+ : NsAccessControlConfig.SelectionType.Users;
1817
+ const existingEntity = conditions.controls.some(ctrl => ctrl.get("entity")?.value === entityType);
1818
+ if (existingEntity) {
1819
+ this.callSnackbar(`${entityType.toUpperCase()} is already added in this user group`, "error");
1820
+ return;
1821
+ }
1822
+ }
1823
+ // Check if the last condition's selections are empty
1824
+ if (conditions.length > 0) {
1825
+ const lastCondition = conditions.at(conditions.length - 1);
1826
+ const selections = lastCondition.get("selections")?.value || [];
1827
+ if (selections.length === 0) {
1828
+ this.callSnackbar("Please select a value for the current condition before adding another one.", "error");
1829
+ return;
1830
+ }
1831
+ }
1832
+ conditions.push(this.createConditionGroup(v4(), userGroupIndex));
1833
+ }
1834
+ createConditionGroup(id, userGroupIndex) {
1835
+ let entity = "";
1836
+ const accessSetting = this.content?.accessSetting;
1837
+ if (accessSetting === NsAccessControlConfig.IAccessSetting.MDO_SPECIFIC || accessSetting === NsAccessControlConfig.IAccessSetting.CUSTOME_USER) {
1838
+ entity =
1839
+ accessSetting === NsAccessControlConfig.IAccessSetting.MDO_SPECIFIC
1840
+ ? NsAccessControlConfig.SelectionType.Organizations
1841
+ : NsAccessControlConfig.SelectionType.Users;
1842
+ this.accessControlCriteriaSelection.optionsEntity.forEach((ele) => {
1843
+ ele.disabled = ele.value !== entity;
1844
+ });
1845
+ }
1846
+ return this.fb.group({
1847
+ id: [id],
1848
+ entity: [entity, Validators.required],
1849
+ conditionType: [{ value: "is", disabled: true }, Validators.required],
1850
+ selections: [[]]
1851
+ });
1852
+ }
1853
+ onEntityChange(userGroupIndex, conditionIndex) {
1854
+ const conditions = this.ruleConditions(userGroupIndex);
1855
+ const condition = conditions.at(conditionIndex);
1856
+ const selectedEntity = condition?.get("entity")?.value;
1857
+ // Check if the same entity is already selected in another condition of this user group
1858
+ const isDuplicate = conditions.controls.some((ctrl, index) => {
1859
+ return index !== conditionIndex && ctrl.get("entity")?.value === selectedEntity;
1860
+ });
1861
+ if (isDuplicate) {
1862
+ this.callSnackbar(`${selectedEntity?.toUpperCase()} is already selected in this user group`, "error");
1863
+ condition.get("entity")?.setValue("");
1864
+ return;
1865
+ }
1866
+ if (condition?.value?.selections?.length) {
1867
+ condition.get("selections")?.setValue([]);
1868
+ }
1869
+ }
1870
+ getAvailableEntities(userGroupIndex, currentConditionIndex) {
1871
+ const conditions = this.ruleConditions(userGroupIndex);
1872
+ const selectedEntities = conditions.controls
1873
+ .map((ctrl, idx) => (idx !== currentConditionIndex ? ctrl.get("entity")?.value : null))
1874
+ .filter(e => !!e);
1875
+ return this.accessControlCriteriaSelection?.optionsEntity.filter(option => !selectedEntities.includes(option.value));
1876
+ }
1877
+ removeUserGroup(index) {
1878
+ const group = this.userGroup.at(index);
1879
+ const dialogRef = this.dialog.open(ConfirmDialogComponent, {
1880
+ width: "470px",
1881
+ data: { additionalData: group?.value?.name, type: "delete" }
1882
+ });
1883
+ dialogRef.afterClosed().subscribe(result => {
1884
+ if (result?.action === NsAccessControlConfig.IActions.Confirm) {
1885
+ this.userGroup.removeAt(index);
1886
+ }
1887
+ });
1888
+ }
1889
+ resetUserGroup(index) {
1890
+ const group = this.userGroup.at(index);
1891
+ if (group) {
1892
+ group.get("name")?.setValue(`User Group ${index + 1}`);
1893
+ group.get("description")?.setValue(`Description for UserGroup ${index + 1}`);
1894
+ const conditions = group.get("conditions");
1895
+ for (let i = 0; i < conditions.length; i++) {
1896
+ const id = conditions.at(i).get("id")?.value;
1897
+ conditions.setControl(i, this.createConditionGroup(id, index));
1898
+ }
1899
+ }
1900
+ }
1901
+ removeCondition(userGroupIndex, conditionIndex) {
1902
+ const conditions = this.ruleConditions(userGroupIndex);
1903
+ const dialogRef = this.dialog.open(ConfirmDialogComponent, {
1904
+ width: "470px",
1905
+ data: { additionalData: "this condition", type: "delete" }
1906
+ });
1907
+ dialogRef.afterClosed().subscribe(result => {
1908
+ if (result?.action === NsAccessControlConfig.IActions.Confirm) {
1909
+ conditions.removeAt(conditionIndex);
1910
+ }
1911
+ });
1912
+ }
1913
+ resetCondition(userGroupIndex, conditionIndex) {
1914
+ const conditions = this.ruleConditions(userGroupIndex);
1915
+ const condition = conditions.at(conditionIndex);
1916
+ if (condition) {
1917
+ const id = condition.get("id")?.value || v4();
1918
+ conditions.setControl(conditionIndex, this.createConditionGroup(id, userGroupIndex));
1919
+ }
1920
+ }
1921
+ manageSelections(condition, rule, userGroupIndex) {
1922
+ switch (condition.value.entity) {
1923
+ case NsAccessControlConfig.SelectionType.Users:
1924
+ this.openInviteUserDialog(condition?.value, rule?.value);
1925
+ break;
1926
+ case NsAccessControlConfig.SelectionType.Organizations:
1927
+ case NsAccessControlConfig.SelectionType.Designation:
1928
+ case NsAccessControlConfig.SelectionType.Service:
1929
+ case NsAccessControlConfig.SelectionType.Cadre:
1930
+ case NsAccessControlConfig.SelectionType.Batch:
1931
+ case NsAccessControlConfig.SelectionType.Group:
1932
+ case NsAccessControlConfig.SelectionType.VerificationStatus:
1933
+ this.processCadreConfigMapping(userGroupIndex);
1934
+ this.openSelectionDialog(rule?.value, condition?.value);
1935
+ break;
1936
+ default:
1937
+ console.warn("Unsupported entity type:", condition.value.entity);
1938
+ }
1939
+ }
1940
+ openSelectionDialog(rule, condition) {
1941
+ const originalSelections = [...(condition.selections || [])];
1942
+ const dialogRef = this.dialog.open(EntitySelectionsComponent, {
1943
+ width: "1032px",
1944
+ data: { rule: rule, condition: condition, selected: condition.selections }
1945
+ });
1946
+ dialogRef.afterClosed().subscribe(result => {
1947
+ if (result) {
1948
+ // Find the rule FormGroup in the FormArray
1949
+ const ruleIndex = this.userGroup.controls.findIndex((ctrl) => ctrl.get("id")?.value === result.rule.id);
1950
+ if (ruleIndex !== -1) {
1951
+ const ruleGroup = this.userGroup.at(ruleIndex);
1952
+ const conditions = ruleGroup.get("conditions");
1953
+ const conditionIndex = conditions.controls.findIndex((ctrl) => ctrl.get("id")?.value === result.condition.id);
1954
+ if (conditionIndex !== -1) {
1955
+ const conditionGroup = conditions.at(conditionIndex);
1956
+ conditionGroup.get("selections")?.setValue(result.selected);
1957
+ if (condition.entity === NsAccessControlConfig.SelectionType.Organizations &&
1958
+ !this.areSelectionsEqual(originalSelections, result.selected)) {
1959
+ const designationCondition = conditions.controls.find(ctrl => ctrl.get("entity")?.value === NsAccessControlConfig.SelectionType.Designation);
1960
+ if (designationCondition) {
1961
+ designationCondition.get("selections")?.setValue([]);
1962
+ }
1963
+ }
1964
+ this.processCadreConfigMapping(ruleIndex);
1965
+ }
1966
+ }
1967
+ }
1968
+ });
1969
+ }
1970
+ areSelectionsEqual(content_1, content_2) {
1971
+ if (content_1.length !== content_2.length)
1972
+ return false;
1973
+ return content_1.every(item => content_2.includes(item));
1974
+ }
1975
+ processCadreConfigMapping(userGroupIndex) {
1976
+ const ruleGroup = this.userGroup.at(userGroupIndex);
1977
+ const conditionValue = ruleGroup.get("conditions").value;
1978
+ if (conditionValue && conditionValue.length) {
1979
+ const services = conditionValue.find((ele) => ele.entity === "service");
1980
+ const cadre = conditionValue.find((ele) => ele.entity === "cadre");
1981
+ const batch = conditionValue.find((ele) => ele.entity === "batch");
1982
+ const serviceSelections = services?.selections || [];
1983
+ const cadreSelections = cadre?.selections || [];
1984
+ const batchSelections = batch?.selections || [];
1985
+ // Case 1: Only service selected
1986
+ if (serviceSelections?.length && !cadreSelections?.length && !batchSelections?.length) {
1987
+ this.accessControlService.holdServiceCadrebatch.update(prev => ({
1988
+ ...prev,
1989
+ service: this.cadreMappingService.getAllServices(),
1990
+ cadre: this.cadreMappingService.getCadresByServices(serviceSelections),
1991
+ batch: this.cadreMappingService.getBatchYearsByServices(serviceSelections)
1992
+ }));
1993
+ }
1994
+ // Case 2: Only cadre selected
1995
+ else if (!serviceSelections?.length && cadreSelections?.length && !batchSelections?.length) {
1996
+ this.accessControlService.holdServiceCadrebatch.update(prev => ({
1997
+ ...prev,
1998
+ cadre: this.cadreMappingService.getAllCadres(),
1999
+ service: this.cadreMappingService.getServicesByCadres(cadreSelections),
2000
+ batch: this.cadreMappingService.getBatchYearsByServices(cadreSelections)
2001
+ }));
2002
+ }
2003
+ // Case 3: Only batch selected
2004
+ else if (!serviceSelections?.length && !cadreSelections?.length && batchSelections?.length) {
2005
+ this.accessControlService.holdServiceCadrebatch.update(prev => ({
2006
+ ...prev,
2007
+ batch: this.cadreMappingService.getAllBatchYears(),
2008
+ service: this.cadreMappingService.getServicesByBatchYears(batchSelections),
2009
+ cadre: this.cadreMappingService.getCadresByBatchYears(batchSelections)
2010
+ }));
2011
+ }
2012
+ // Case 4: Service and Cadre selected
2013
+ else if (serviceSelections?.length && cadreSelections?.length && !batchSelections?.length) {
2014
+ this.accessControlService.holdServiceCadrebatch.update(prev => ({
2015
+ ...prev,
2016
+ service: this.cadreMappingService.getServicesByCadres(cadreSelections),
2017
+ cadre: this.cadreMappingService.getCadresByServices(serviceSelections),
2018
+ batch: this.cadreMappingService.getBatchYearsByServicesAndCadres(serviceSelections, cadreSelections)
2019
+ }));
2020
+ }
2021
+ // Case 5: Service and Batch selected
2022
+ else if (serviceSelections?.length && !cadreSelections?.length && batchSelections?.length) {
2023
+ this.accessControlService.holdServiceCadrebatch.update(prev => ({
2024
+ ...prev,
2025
+ cadre: this.cadreMappingService.getCadresByServicesAndBatch(serviceSelections, batchSelections),
2026
+ service: this.cadreMappingService.getServicesByCadresAndBatch(cadreSelections, batchSelections),
2027
+ batch: this.cadreMappingService.getBatchYearsByServicesAndCadres(serviceSelections, cadreSelections)
2028
+ }));
2029
+ }
2030
+ // Case 6: Cadre and Batch selected
2031
+ else if (!serviceSelections?.length && cadreSelections?.length && batchSelections?.length) {
2032
+ this.accessControlService.holdServiceCadrebatch.update(prev => ({
2033
+ ...prev,
2034
+ service: this.cadreMappingService.getServicesByCadresAndBatch(cadreSelections, batchSelections),
2035
+ cadre: this.cadreMappingService.getCadresByServicesAndBatch(serviceSelections, batchSelections),
2036
+ batch: this.cadreMappingService.getBatchYearsByServicesAndCadres(serviceSelections, cadreSelections)
2037
+ }));
2038
+ }
2039
+ else {
2040
+ this.accessControlService.holdServiceCadrebatch.set({
2041
+ service: this.cadreMappingService.getAllServices(),
2042
+ batch: this.cadreMappingService.getAllBatchYears(),
2043
+ cadre: this.cadreMappingService.getAllCadres()
2044
+ });
2045
+ }
2046
+ }
2047
+ }
2048
+ openInviteUserDialog(condition, rule) {
2049
+ const dialogRef = this.dialog.open(InviteUsersComponent, {
2050
+ width: "1090px",
2051
+ data: { condition: condition, rule: rule, selected: condition.selections }
2052
+ });
2053
+ dialogRef.afterClosed().subscribe(result => {
2054
+ if (result) {
2055
+ // Find the rule FormGroup in the FormArray
2056
+ const ruleIndex = this.userGroup.controls.findIndex((ctrl) => ctrl.get("id")?.value === result.rule.id);
2057
+ if (ruleIndex !== -1) {
2058
+ const ruleGroup = this.userGroup.at(ruleIndex);
2059
+ const conditions = ruleGroup.get("conditions");
2060
+ const conditionIndex = conditions.controls.findIndex((ctrl) => ctrl.get("id")?.value === result.condition.id);
2061
+ if (conditionIndex !== -1) {
2062
+ const conditionGroup = conditions.at(conditionIndex);
2063
+ // const userIds = result.selected && result.selected.map((user: any) => user?.userId);
2064
+ conditionGroup.get("selections")?.setValue(result.selected);
2065
+ }
2066
+ }
2067
+ }
2068
+ });
2069
+ }
2070
+ callSnackbar(message, type) {
2071
+ if (type === "success") {
2072
+ this.snackbar.openFromComponent(SnackbarComponent, {
2073
+ data: { message: message, type: "success" },
2074
+ duration: 3000,
2075
+ panelClass: "course-success-snackbar"
2076
+ });
2077
+ }
2078
+ else if (type === "error") {
2079
+ this.snackbar.openFromComponent(SnackbarComponent, {
2080
+ data: { message: message, type: "error" },
2081
+ duration: 3000,
2082
+ panelClass: "course-error-snackbar"
2083
+ });
2084
+ }
2085
+ }
2086
+ async applyAccessControlValue() {
2087
+ if (this.content?.status === "Draft")
2088
+ this.isSaving = true;
2089
+ else if (this.content?.status === "Live")
2090
+ this.isApplying = true;
2091
+ const payload = await this.processRequestCreation();
2092
+ this.accessControlService.applyUserGroupAccessControl(payload).subscribe({
2093
+ next: response => {
2094
+ if (response?.result && response?.result?.accessControl) {
2095
+ this.accessControlData.emit({ userGroup: response.result.accessControl?.userGroup, accessType: this.accessType });
2096
+ this.callSnackbar("Access Control saved successfully", "success");
2097
+ }
2098
+ else {
2099
+ this.callSnackbar("Could not save access control, Please try again.", "error");
2100
+ }
2101
+ if (this.content?.status === "Draft")
2102
+ this.isSaving = false;
2103
+ else if (this.content?.status === "Live")
2104
+ this.isApplying = false;
2105
+ },
2106
+ error: () => {
2107
+ this.callSnackbar("Could not save access control, Please try again.", "error");
2108
+ if (this.content?.status === "Draft")
2109
+ this.isSaving = false;
2110
+ else if (this.content?.status === "Live")
2111
+ this.isApplying = false;
2112
+ }
2113
+ });
2114
+ }
2115
+ processRequestCreation() {
2116
+ return new Promise((resolve, reject) => {
2117
+ try {
2118
+ const data = this.accessControlForm.value;
2119
+ const userGroups = data.userGroup.map((group) => ({
2120
+ userGroupName: group.name,
2121
+ userGroupCriteriaList: group.conditions.map((condition) => {
2122
+ let criteriaValue;
2123
+ if (condition?.entity === NsAccessControlConfig.SelectionType.Users && condition?.selected?.length && condition?.selected[0]?.userId) {
2124
+ const userIds = condition.selected?.map((user) => user?.userId) || [];
2125
+ criteriaValue = userIds;
2126
+ }
2127
+ else {
2128
+ criteriaValue = condition.selections?.map(String) || [];
2129
+ }
2130
+ return {
2131
+ criteriaKey: condition.entity,
2132
+ criteriaValue
2133
+ };
2134
+ })
2135
+ }));
2136
+ const requestPayload = {
2137
+ contentId: this.contentId,
2138
+ accessControl: {
2139
+ version: 1,
2140
+ userGroups
2141
+ }
2142
+ };
2143
+ resolve(requestPayload);
2144
+ }
2145
+ catch (error) {
2146
+ reject(error);
2147
+ }
2148
+ });
2149
+ }
2150
+ openInstructonsDialog() {
2151
+ this.dialog.open(AccessControlGuideComponent, {
2152
+ width: "960px"
2153
+ });
2154
+ }
2155
+ async getAccessControl() {
2156
+ const response = await this.accessControlService
2157
+ .fetchUserGroupAccessControl(this.contentId)
2158
+ .toPromise()
2159
+ .catch(() => {
2160
+ this.accessControlData.emit({ userGroup: this.accessControlForm.value?.userGroup, accessType: this.accessType });
2161
+ });
2162
+ if (response?.result?.accessControl) {
2163
+ this.processAccessControlResult(response.result.accessControl);
2164
+ this.accessControlData.emit({ userGroup: response.result.accessControl?.userGroup, accessType: this.accessType });
2165
+ }
2166
+ }
2167
+ processAccessControlResult(accessControl) {
2168
+ if (!accessControl?.userGroups?.length)
2169
+ return;
2170
+ while (this.userGroup.length) {
2171
+ this.userGroup.removeAt(0);
2172
+ }
2173
+ accessControl.userGroups.forEach((group) => {
2174
+ const conditions = this.fb.array([]);
2175
+ group.userGroupCriteriaList.forEach((criteria) => {
2176
+ const condition = this.createConditionGroup(v4(), this.userGroup.length);
2177
+ // Map API keys to form entity values
2178
+ const entityMap = {
2179
+ rootOrgId: NsAccessControlConfig.SelectionType.Organizations,
2180
+ user: NsAccessControlConfig.SelectionType.Users,
2181
+ group: NsAccessControlConfig.SelectionType.Group,
2182
+ designation: NsAccessControlConfig.SelectionType.Designation,
2183
+ profilestatus: NsAccessControlConfig.SelectionType.VerificationStatus,
2184
+ Cadre: NsAccessControlConfig.SelectionType.Cadre,
2185
+ service: NsAccessControlConfig.SelectionType.Service,
2186
+ batch: NsAccessControlConfig.SelectionType.Batch
2187
+ };
2188
+ // Set the form values
2189
+ condition.patchValue({
2190
+ entity: entityMap[criteria.criteriaKey] || criteria.criteriaKey,
2191
+ selections: criteria.criteriaValue
2192
+ });
2193
+ conditions.push(condition);
2194
+ });
2195
+ const ruleGroup = this.fb.group({
2196
+ id: [group.userGroupId || v4()],
2197
+ name: [group.userGroupName],
2198
+ description: [`Description for ${group.userGroupName}`],
2199
+ conditions: conditions
2200
+ });
2201
+ this.userGroup.push(ruleGroup);
2202
+ });
2203
+ if (!this.cadreConfigData) {
2204
+ this.fetchCadreConfigData();
2205
+ }
2206
+ }
2207
+ async updateContentAccessSetting() {
2208
+ const accessTypeBoolean = this.accessType === NsAccessControlConfig.IAccessTypes.Public ? false : true;
2209
+ const request = this.accessControlService.createRequestContent(this.content, accessTypeBoolean);
2210
+ await this.accessControlService.updateContentV3(request, this.contentId).toPromise();
2211
+ }
2212
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AccessControlComponent, deps: [{ token: i1$3.MatDialog }, { token: i2$1.FormBuilder }, { token: AccessControlService }, { token: CadreMappingService }, { token: i1.MatLegacySnackBar }], target: i0.ɵɵFactoryTarget.Component }); }
2213
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: AccessControlComponent, selector: "sb-uic-access-control", inputs: { config: "config", contentId: "contentId", content: "content" }, outputs: { accessControlData: "accessControlData" }, ngImport: i0, template: "<div class=\"py-4 px-10\">\n <div class=\"p-4 as-container\">\n <div class=\"flex items-center justify-between\">\n <span class=\"text-xl font-bold primary-text-color\">Access Control</span>\n <div class=\"flex gap-2 items-center\">\n <span class=\"text-sm primary-text-color cursor-pointer\" (click)=\"openInstructonsDialog()\">How to use access control?</span>\n <img src=\"/assets/icons/support-i.svg\" alt=\"support i\" class=\"img-icon-24\" />\n </div>\n </div>\n <div class=\"light-grey-border p-4 mt-4\">\n <mat-radio-group [(ngModel)]=\"accessType\" (change)=\"onAccessTypeChange($event)\">\n <div class=\"radio-container flex gap-5 mb-4\">\n <ng-container *ngFor=\"let item of accessControlCriteriaSelection?.accessTypes\">\n <mat-radio-button [value]=\"item.value\">\n <div class=\"flex gap-2 items-center\">\n <span>{{ item?.name }}</span>\n <mat-icon svgIcon=\"info-outline\" [matTooltip]=\"item?.tooltip\"></mat-icon>\n </div>\n </mat-radio-button>\n </ng-container>\n </div>\n </mat-radio-group>\n <ng-container *ngIf=\"accessType === ACCESS_TYPE_ENUM.Public\">\n <div class=\"info-container\">\n <label class=\"text-sm\">This event will be visible to all Karmayogis.</label>\n </div>\n </ng-container>\n <ng-container *ngIf=\"accessType === ACCESS_TYPE_ENUM.Custom\">\n <div class=\"visibiliy-container light-grey-border p-4\">\n <div class=\"flex justify-between items-center\">\n <span class=\"text-lg font-bold\">Visibility</span>\n <mat-slide-toggle [(ngModel)]=\"isVisibilityEnabled\"></mat-slide-toggle>\n </div>\n <ng-container *ngIf=\"!isVisibilityEnabled\">\n <label class=\"text-sm\">Karmayogis will NOT be able to search and view the description page of the event.</label>\n </ng-container>\n <ng-container *ngIf=\"isVisibilityEnabled\">\n <label class=\"text-sm\"\n >Karmayogis will be able to search and view the description page of the event but will not able to enroll if Karmayogi do not satisfy the\n conditions defined in the access control below.</label\n >\n </ng-container>\n </div>\n <!-- <div class=\"flex justify-between items-center mt-4 mb-4\">\n <button mat-button class=\"new-secondary-button-no-border button-with-corners\" type=\"button\" (click)=\"filterCriteria = !filterCriteria\">\n <div class=\"flex gap-2 flex-middle\">\n <span class=\"text-m\">Filter criteria</span>\n <mat-icon class=\"primary-text-color\">{{ filterCriteria ? \"visibility_on\" : \"visibility_off\" }}</mat-icon>\n </div>\n </button>\n </div> -->\n\n <ng-container *ngIf=\"filterCriteria\">\n <div class=\"filter-criteria-container light-grey-border p-4 mt-4 flex flex-middle justify-between mb-4\">\n <div class=\"info\">\n <span class=\"text-sm\">Define the conditions that Karmayogis must satisfy to enroll in the event.</span>\n </div>\n <button mat-button class=\"new-secondary-button-no-border button-with-corners\" type=\"button\">\n <div class=\"flex gap-2 flex-middle\">\n <span class=\"text-m\">Refresh</span>\n <mat-icon class=\"primary-text-color\">refresh</mat-icon>\n </div>\n </button>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"accessControlForm && userGroup?.length > 0 && !isLoading\">\n <form [formGroup]=\"accessControlForm\">\n <mat-accordion class=\"example-headers-align access-usergroup-accordion mt-3\" multi=\"true\">\n <ng-container formArrayName=\"userGroup\" *ngFor=\"let rule of userGroup?.controls; let i = index; let ruleLast = last\">\n <ng-container [formGroupName]=\"i\">\n <mat-expansion-panel class=\"access-usergroup-panel\" expanded>\n <mat-expansion-panel-header>\n <mat-panel-title class=\"items-center\">\n <span class=\"text-sm\">{{ rule.get(\"name\")?.value }}</span>\n </mat-panel-title>\n <mat-panel-description class=\"justify-end items-center\" (click)=\"$event.stopPropagation()\">\n <button mat-icon-button aria-label=\"delete user group\" (click)=\"removeUserGroup(i)\" title=\"Delete\">\n <mat-icon>delete</mat-icon>\n </button>\n <button mat-icon-button aria-label=\"refresh user group\" (click)=\"resetUserGroup(i)\" title=\"Refresh\">\n <mat-icon>refresh</mat-icon>\n </button>\n </mat-panel-description>\n </mat-expansion-panel-header>\n <ng-container *ngIf=\"rule.get('conditions') as conditionsArray\">\n <div [formArrayName]=\"'conditions'\">\n <ng-container *ngFor=\"let condition of conditionsArray?.controls; let j = index; let conditionlast = last\">\n <div class=\"condition-selection mt-2\" [formGroupName]=\"j\">\n <div class=\"select-condition-text mb-3 mt-4\">Select Condition {{ i + 1 + \".\" + (j + 1) }}</div>\n <div class=\"selections-options grid grid-cols-5 gap-4\">\n <div class=\"mat-full-radius\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-select placeholder=\"Select\" formControlName=\"entity\" (selectionChange)=\"onEntityChange(i, j)\">\n <ng-container *ngFor=\"let item of getAvailableEntities(i, j)\">\n <mat-option [value]=\"item?.value\" [disabled]=\"item?.disabled\">{{ item?.label }}</mat-option>\n </ng-container>\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"mat-full-radius\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-select placeholder=\"Select\" formControlName=\"conditionType\">\n <ng-container *ngFor=\"let item of accessControlCriteriaSelection?.optionsConditions\">\n <mat-option [value]=\"item?.value\">{{ item?.label }}</mat-option>\n </ng-container>\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"action-manage-selection\">\n <button\n mat-flat-button\n (click)=\"manageSelections(condition, rule, i)\"\n [disabled]=\"!condition.get('entity').value || !condition.get('conditionType').value\"\n class=\"rounded-full new-bg-color text-white mt-2 flex items-center gap-2\">\n <mat-icon svgIcon=\"svg_search\" class=\"mr-2\"></mat-icon>\n <span class=\"font-bold text-sm\">Manage Selections</span>\n </button>\n </div>\n <div class=\"action-options-selected\">\n <button mat-button class=\"new-secondary-button-no-border button-with-corners mt-2\" type=\"button\">\n <div class=\"flex gap-2 flex-middle mt-2\">\n <span class=\"text-m color-gr underline\">{{ condition.get(\"selections\").value.length }} items selected</span>\n </div>\n </button>\n </div>\n <div class=\"action-more-options flex justify-end\">\n <div class=\"flex gap-4\">\n <button mat-icon-button aria-label=\"delete condition\" class=\"mt-2 ml-auto\" (click)=\"removeCondition(i, j)\" title=\"Delete\">\n <mat-icon>delete</mat-icon>\n </button>\n <button mat-icon-button aria-label=\"refresh condition\" class=\"mt-2 ml-auto\" (click)=\"resetCondition(i, j)\" title=\"Refresh\">\n <mat-icon>refresh</mat-icon>\n </button>\n </div>\n </div>\n </div>\n </div>\n <div class=\"and-or mat-full-radius\" *ngIf=\"conditionsArray?.length > 1 && !conditionlast\">\n <mat-form-field appearance=\"outline\" class=\"w-max-100\">\n <mat-select placeholder=\"Select\" [(value)]=\"defaultConditionRelationship\">\n <mat-option [value]=\"'AND'\">AND</mat-option>\n <mat-option [value]=\"'OR'\">OR</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n </ng-container>\n </div>\n </ng-container>\n <div class=\"action-add-condition\">\n <button mat-button class=\"new-secondary-button-no-border button-with-corners\" type=\"button\" (click)=\"addCondition(i)\">\n <div class=\"flex gap-2 flex-middle\">\n <mat-icon class=\"primary-text-color\">add</mat-icon>\n <span class=\"text-m\">Add Condition</span>\n </div>\n </button>\n </div>\n </mat-expansion-panel>\n <div class=\"and-or mat-full-radius\" *ngIf=\"userGroup.length > 1 && !ruleLast\">\n <mat-form-field appearance=\"outline\" class=\"w-max-100\">\n <mat-select placeholder=\"Select\" [(value)]=\"defaultUserGroupRelationship\">\n <mat-option [value]=\"'AND'\">AND</mat-option>\n <mat-option [value]=\"'OR'\">OR</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n </ng-container>\n </ng-container>\n </mat-accordion>\n </form>\n </ng-container>\n\n <ng-container *ngIf=\"isLoading\">\n <div class=\"spinner-loader flex items-center justify-center\">\n <mat-spinner></mat-spinner>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"!isLoading\">\n <div class=\"text-center mb-6 mt-4\">\n <button mat-button class=\"new-secondary-button-no-border button-with-corners\" type=\"button\" (click)=\"addUserGroup()\">\n <div class=\"flex gap-2 flex-middle\">\n <mat-icon class=\"primary-text-color\">add</mat-icon>\n <span class=\"text-m\">Add User Group</span>\n </div>\n </button>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"userGroup?.length > 0\">\n <div class=\"action-save flex justify-center items-center gap-4\">\n <!-- Save Filter Button -->\n <button\n mat-flat-button\n class=\"flex rounded-full px-4 py-2 mat-btn-outline font-bold text-sm items-center gap-2\"\n [disabled]=\"isSaveFltrBtnDisabled || isSaving\"\n (click)=\"applyAccessControlValue()\">\n <mat-spinner *ngIf=\"isSaving\" diameter=\"18\" strokeWidth=\"3\" class=\"!inline !m-0 mr-2\"></mat-spinner>\n <span>Save Filter</span>\n </button>\n\n <!-- Apply Button -->\n <button\n mat-flat-button\n [disabled]=\"isApplyBtnDisabled || isApplying\"\n class=\"flex items-center rounded-full px-4 py-2 new-bg-color font-bold text-sm text-white gap-2\"\n (click)=\"applyAccessControlValue()\">\n <mat-spinner *ngIf=\"isApplying\" diameter=\"18\" strokeWidth=\"3\" class=\"!inline !m-0 mr-2\"></mat-spinner>\n <span>Apply</span>\n </button>\n </div>\n </ng-container>\n </ng-container>\n </div>\n </div>\n</div>\n", styles: [".as-container{border:1px solid #1b4ca1;border-radius:10px}.filter-criteria-container{background:#fff8ef}.access-rules-panel{background:#e8edf6!important;border-radius:4px;margin-bottom:10px;box-shadow:none!important}::ng-deep .mat-expansion-panel-body{background:#fff!important}.more-menu-icon{font-size:16px;height:16px;width:16px}.selections-options .mat-full-radius ::ng-deep .mat-form-field-appearance-outline .mat-form-field-outline{border-radius:12px!important;border:1px solid rgba(0,0,0,.1607843137)}.selections-options .mat-full-radius ::ng-deep .mat-form-field .mat-form-field-outline-end{border-radius:0 12px 12px 0!important}.selections-options .mat-full-radius ::ng-deep .mat-form-field .mat-form-field-outline-start{border-radius:12px 0 0 12px!important;flex-grow:1}.selections-options .mat-full-radius ::ng-deep .mat-form-field-wrapper{padding-bottom:0!important}.mt-2{margin-top:.5rem!important}.action-manage-selection mat-icon{font-size:18px;height:28px;width:16px}.action-manage-selection button{padding:4px 16px}.color-gr{background:#1b4ca1}.and-or ::ng-deep .mat-form-field .mat-form-field-outline-end{border:none!important}.and-or ::ng-deep .mat-form-field .mat-form-field-outline-start{border:none!important}.and-or ::ng-deep .mat-select-value{color:#1b4ca1!important;font-family:Montserrat;font-weight:600;font-size:16px}.and-or ::ng-deep .mat-form-field-wrapper{padding-bottom:0!important}.w-max-100{max-width:100px}.mat-expansion-panel-header.mat-expanded{height:50px!important}.mat-expansion-panel-header{background:#e8edf6}.mat-expansion-panel:not([class*=mat-elevation-z]){box-shadow:none!important;border:1px solid rgba(0,0,0,.0784313725)}.mr-1{margin-right:.25rem!important}::ng-deep .mat-menu-panel{border:1px solid rgba(0,0,0,.2);border-radius:12px}::ng-deep .mat-menu-content:not(:empty){padding-top:0!important;padding-bottom:0!important}:host ::ng-deep .mdc-dialog .mdc-dialog__content{padding:0 24px 24px!important}.select-condition-text{font-family:Lato;font-weight:400;font-size:12px;color:#666}::ng-deep .mat-select-panel{max-height:340px!important}.radio-container mat-icon{width:16px;height:16px;font-size:0px}.img-icon-24{width:24px;height:24px}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5$2.MatLegacyRadioGroup, selector: "mat-radio-group", exportAs: ["matRadioGroup"] }, { kind: "component", type: i5$2.MatLegacyRadioButton, selector: "mat-radio-button", inputs: ["disableRipple", "tabIndex"], exportAs: ["matRadioButton"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatLegacySlideToggle, selector: "mat-slide-toggle", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matSlideToggle"] }, { kind: "component", type: i7.MatLegacyFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "component", type: i4.MatLegacySelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i5.MatLegacyOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "directive", type: i13.MatAccordion, selector: "mat-accordion", inputs: ["multi", "hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i13.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["disabled", "expanded", "hideToggle", "togglePosition"], outputs: ["opened", "closed", "expandedChange", "afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i13.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["tabIndex", "expandedHeight", "collapsedHeight"] }, { kind: "directive", type: i13.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i13.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i2$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i2$1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i5$1.MatLegacyButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i12.MatLegacyProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: i16.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }] }); }
2214
+ }
2215
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AccessControlComponent, decorators: [{
2216
+ type: Component,
2217
+ args: [{ selector: "sb-uic-access-control", template: "<div class=\"py-4 px-10\">\n <div class=\"p-4 as-container\">\n <div class=\"flex items-center justify-between\">\n <span class=\"text-xl font-bold primary-text-color\">Access Control</span>\n <div class=\"flex gap-2 items-center\">\n <span class=\"text-sm primary-text-color cursor-pointer\" (click)=\"openInstructonsDialog()\">How to use access control?</span>\n <img src=\"/assets/icons/support-i.svg\" alt=\"support i\" class=\"img-icon-24\" />\n </div>\n </div>\n <div class=\"light-grey-border p-4 mt-4\">\n <mat-radio-group [(ngModel)]=\"accessType\" (change)=\"onAccessTypeChange($event)\">\n <div class=\"radio-container flex gap-5 mb-4\">\n <ng-container *ngFor=\"let item of accessControlCriteriaSelection?.accessTypes\">\n <mat-radio-button [value]=\"item.value\">\n <div class=\"flex gap-2 items-center\">\n <span>{{ item?.name }}</span>\n <mat-icon svgIcon=\"info-outline\" [matTooltip]=\"item?.tooltip\"></mat-icon>\n </div>\n </mat-radio-button>\n </ng-container>\n </div>\n </mat-radio-group>\n <ng-container *ngIf=\"accessType === ACCESS_TYPE_ENUM.Public\">\n <div class=\"info-container\">\n <label class=\"text-sm\">This event will be visible to all Karmayogis.</label>\n </div>\n </ng-container>\n <ng-container *ngIf=\"accessType === ACCESS_TYPE_ENUM.Custom\">\n <div class=\"visibiliy-container light-grey-border p-4\">\n <div class=\"flex justify-between items-center\">\n <span class=\"text-lg font-bold\">Visibility</span>\n <mat-slide-toggle [(ngModel)]=\"isVisibilityEnabled\"></mat-slide-toggle>\n </div>\n <ng-container *ngIf=\"!isVisibilityEnabled\">\n <label class=\"text-sm\">Karmayogis will NOT be able to search and view the description page of the event.</label>\n </ng-container>\n <ng-container *ngIf=\"isVisibilityEnabled\">\n <label class=\"text-sm\"\n >Karmayogis will be able to search and view the description page of the event but will not able to enroll if Karmayogi do not satisfy the\n conditions defined in the access control below.</label\n >\n </ng-container>\n </div>\n <!-- <div class=\"flex justify-between items-center mt-4 mb-4\">\n <button mat-button class=\"new-secondary-button-no-border button-with-corners\" type=\"button\" (click)=\"filterCriteria = !filterCriteria\">\n <div class=\"flex gap-2 flex-middle\">\n <span class=\"text-m\">Filter criteria</span>\n <mat-icon class=\"primary-text-color\">{{ filterCriteria ? \"visibility_on\" : \"visibility_off\" }}</mat-icon>\n </div>\n </button>\n </div> -->\n\n <ng-container *ngIf=\"filterCriteria\">\n <div class=\"filter-criteria-container light-grey-border p-4 mt-4 flex flex-middle justify-between mb-4\">\n <div class=\"info\">\n <span class=\"text-sm\">Define the conditions that Karmayogis must satisfy to enroll in the event.</span>\n </div>\n <button mat-button class=\"new-secondary-button-no-border button-with-corners\" type=\"button\">\n <div class=\"flex gap-2 flex-middle\">\n <span class=\"text-m\">Refresh</span>\n <mat-icon class=\"primary-text-color\">refresh</mat-icon>\n </div>\n </button>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"accessControlForm && userGroup?.length > 0 && !isLoading\">\n <form [formGroup]=\"accessControlForm\">\n <mat-accordion class=\"example-headers-align access-usergroup-accordion mt-3\" multi=\"true\">\n <ng-container formArrayName=\"userGroup\" *ngFor=\"let rule of userGroup?.controls; let i = index; let ruleLast = last\">\n <ng-container [formGroupName]=\"i\">\n <mat-expansion-panel class=\"access-usergroup-panel\" expanded>\n <mat-expansion-panel-header>\n <mat-panel-title class=\"items-center\">\n <span class=\"text-sm\">{{ rule.get(\"name\")?.value }}</span>\n </mat-panel-title>\n <mat-panel-description class=\"justify-end items-center\" (click)=\"$event.stopPropagation()\">\n <button mat-icon-button aria-label=\"delete user group\" (click)=\"removeUserGroup(i)\" title=\"Delete\">\n <mat-icon>delete</mat-icon>\n </button>\n <button mat-icon-button aria-label=\"refresh user group\" (click)=\"resetUserGroup(i)\" title=\"Refresh\">\n <mat-icon>refresh</mat-icon>\n </button>\n </mat-panel-description>\n </mat-expansion-panel-header>\n <ng-container *ngIf=\"rule.get('conditions') as conditionsArray\">\n <div [formArrayName]=\"'conditions'\">\n <ng-container *ngFor=\"let condition of conditionsArray?.controls; let j = index; let conditionlast = last\">\n <div class=\"condition-selection mt-2\" [formGroupName]=\"j\">\n <div class=\"select-condition-text mb-3 mt-4\">Select Condition {{ i + 1 + \".\" + (j + 1) }}</div>\n <div class=\"selections-options grid grid-cols-5 gap-4\">\n <div class=\"mat-full-radius\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-select placeholder=\"Select\" formControlName=\"entity\" (selectionChange)=\"onEntityChange(i, j)\">\n <ng-container *ngFor=\"let item of getAvailableEntities(i, j)\">\n <mat-option [value]=\"item?.value\" [disabled]=\"item?.disabled\">{{ item?.label }}</mat-option>\n </ng-container>\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"mat-full-radius\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-select placeholder=\"Select\" formControlName=\"conditionType\">\n <ng-container *ngFor=\"let item of accessControlCriteriaSelection?.optionsConditions\">\n <mat-option [value]=\"item?.value\">{{ item?.label }}</mat-option>\n </ng-container>\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"action-manage-selection\">\n <button\n mat-flat-button\n (click)=\"manageSelections(condition, rule, i)\"\n [disabled]=\"!condition.get('entity').value || !condition.get('conditionType').value\"\n class=\"rounded-full new-bg-color text-white mt-2 flex items-center gap-2\">\n <mat-icon svgIcon=\"svg_search\" class=\"mr-2\"></mat-icon>\n <span class=\"font-bold text-sm\">Manage Selections</span>\n </button>\n </div>\n <div class=\"action-options-selected\">\n <button mat-button class=\"new-secondary-button-no-border button-with-corners mt-2\" type=\"button\">\n <div class=\"flex gap-2 flex-middle mt-2\">\n <span class=\"text-m color-gr underline\">{{ condition.get(\"selections\").value.length }} items selected</span>\n </div>\n </button>\n </div>\n <div class=\"action-more-options flex justify-end\">\n <div class=\"flex gap-4\">\n <button mat-icon-button aria-label=\"delete condition\" class=\"mt-2 ml-auto\" (click)=\"removeCondition(i, j)\" title=\"Delete\">\n <mat-icon>delete</mat-icon>\n </button>\n <button mat-icon-button aria-label=\"refresh condition\" class=\"mt-2 ml-auto\" (click)=\"resetCondition(i, j)\" title=\"Refresh\">\n <mat-icon>refresh</mat-icon>\n </button>\n </div>\n </div>\n </div>\n </div>\n <div class=\"and-or mat-full-radius\" *ngIf=\"conditionsArray?.length > 1 && !conditionlast\">\n <mat-form-field appearance=\"outline\" class=\"w-max-100\">\n <mat-select placeholder=\"Select\" [(value)]=\"defaultConditionRelationship\">\n <mat-option [value]=\"'AND'\">AND</mat-option>\n <mat-option [value]=\"'OR'\">OR</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n </ng-container>\n </div>\n </ng-container>\n <div class=\"action-add-condition\">\n <button mat-button class=\"new-secondary-button-no-border button-with-corners\" type=\"button\" (click)=\"addCondition(i)\">\n <div class=\"flex gap-2 flex-middle\">\n <mat-icon class=\"primary-text-color\">add</mat-icon>\n <span class=\"text-m\">Add Condition</span>\n </div>\n </button>\n </div>\n </mat-expansion-panel>\n <div class=\"and-or mat-full-radius\" *ngIf=\"userGroup.length > 1 && !ruleLast\">\n <mat-form-field appearance=\"outline\" class=\"w-max-100\">\n <mat-select placeholder=\"Select\" [(value)]=\"defaultUserGroupRelationship\">\n <mat-option [value]=\"'AND'\">AND</mat-option>\n <mat-option [value]=\"'OR'\">OR</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n </ng-container>\n </ng-container>\n </mat-accordion>\n </form>\n </ng-container>\n\n <ng-container *ngIf=\"isLoading\">\n <div class=\"spinner-loader flex items-center justify-center\">\n <mat-spinner></mat-spinner>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"!isLoading\">\n <div class=\"text-center mb-6 mt-4\">\n <button mat-button class=\"new-secondary-button-no-border button-with-corners\" type=\"button\" (click)=\"addUserGroup()\">\n <div class=\"flex gap-2 flex-middle\">\n <mat-icon class=\"primary-text-color\">add</mat-icon>\n <span class=\"text-m\">Add User Group</span>\n </div>\n </button>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"userGroup?.length > 0\">\n <div class=\"action-save flex justify-center items-center gap-4\">\n <!-- Save Filter Button -->\n <button\n mat-flat-button\n class=\"flex rounded-full px-4 py-2 mat-btn-outline font-bold text-sm items-center gap-2\"\n [disabled]=\"isSaveFltrBtnDisabled || isSaving\"\n (click)=\"applyAccessControlValue()\">\n <mat-spinner *ngIf=\"isSaving\" diameter=\"18\" strokeWidth=\"3\" class=\"!inline !m-0 mr-2\"></mat-spinner>\n <span>Save Filter</span>\n </button>\n\n <!-- Apply Button -->\n <button\n mat-flat-button\n [disabled]=\"isApplyBtnDisabled || isApplying\"\n class=\"flex items-center rounded-full px-4 py-2 new-bg-color font-bold text-sm text-white gap-2\"\n (click)=\"applyAccessControlValue()\">\n <mat-spinner *ngIf=\"isApplying\" diameter=\"18\" strokeWidth=\"3\" class=\"!inline !m-0 mr-2\"></mat-spinner>\n <span>Apply</span>\n </button>\n </div>\n </ng-container>\n </ng-container>\n </div>\n </div>\n</div>\n", styles: [".as-container{border:1px solid #1b4ca1;border-radius:10px}.filter-criteria-container{background:#fff8ef}.access-rules-panel{background:#e8edf6!important;border-radius:4px;margin-bottom:10px;box-shadow:none!important}::ng-deep .mat-expansion-panel-body{background:#fff!important}.more-menu-icon{font-size:16px;height:16px;width:16px}.selections-options .mat-full-radius ::ng-deep .mat-form-field-appearance-outline .mat-form-field-outline{border-radius:12px!important;border:1px solid rgba(0,0,0,.1607843137)}.selections-options .mat-full-radius ::ng-deep .mat-form-field .mat-form-field-outline-end{border-radius:0 12px 12px 0!important}.selections-options .mat-full-radius ::ng-deep .mat-form-field .mat-form-field-outline-start{border-radius:12px 0 0 12px!important;flex-grow:1}.selections-options .mat-full-radius ::ng-deep .mat-form-field-wrapper{padding-bottom:0!important}.mt-2{margin-top:.5rem!important}.action-manage-selection mat-icon{font-size:18px;height:28px;width:16px}.action-manage-selection button{padding:4px 16px}.color-gr{background:#1b4ca1}.and-or ::ng-deep .mat-form-field .mat-form-field-outline-end{border:none!important}.and-or ::ng-deep .mat-form-field .mat-form-field-outline-start{border:none!important}.and-or ::ng-deep .mat-select-value{color:#1b4ca1!important;font-family:Montserrat;font-weight:600;font-size:16px}.and-or ::ng-deep .mat-form-field-wrapper{padding-bottom:0!important}.w-max-100{max-width:100px}.mat-expansion-panel-header.mat-expanded{height:50px!important}.mat-expansion-panel-header{background:#e8edf6}.mat-expansion-panel:not([class*=mat-elevation-z]){box-shadow:none!important;border:1px solid rgba(0,0,0,.0784313725)}.mr-1{margin-right:.25rem!important}::ng-deep .mat-menu-panel{border:1px solid rgba(0,0,0,.2);border-radius:12px}::ng-deep .mat-menu-content:not(:empty){padding-top:0!important;padding-bottom:0!important}:host ::ng-deep .mdc-dialog .mdc-dialog__content{padding:0 24px 24px!important}.select-condition-text{font-family:Lato;font-weight:400;font-size:12px;color:#666}::ng-deep .mat-select-panel{max-height:340px!important}.radio-container mat-icon{width:16px;height:16px;font-size:0px}.img-icon-24{width:24px;height:24px}\n"] }]
2218
+ }], ctorParameters: function () { return [{ type: i1$3.MatDialog }, { type: i2$1.FormBuilder }, { type: AccessControlService }, { type: CadreMappingService }, { type: i1.MatLegacySnackBar }]; }, propDecorators: { config: [{
2219
+ type: Input
2220
+ }], contentId: [{
2221
+ type: Input
2222
+ }], content: [{
2223
+ type: Input
2224
+ }], accessControlData: [{
2225
+ type: Output
2226
+ }] } });
2227
+
2228
+ class AccessControlModule {
2229
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AccessControlModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2230
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: AccessControlModule, declarations: [AccessControlComponent,
2231
+ InviteUsersComponent,
2232
+ ListTableComponent,
2233
+ PaginationComponent,
2234
+ BulkUploadKarmayogiComponent,
2235
+ DragDropDirective,
2236
+ EntitySelectionsComponent,
2237
+ ConfirmDialogComponent,
2238
+ AccessControlGuideComponent], imports: [CommonModule,
2239
+ MatLegacyRadioModule,
2240
+ MatIconModule,
2241
+ MatDialogModule,
2242
+ MatLegacyMenuModule,
2243
+ MatLegacyCheckboxModule,
2244
+ MatLegacySlideToggleModule,
2245
+ MatLegacySelectModule,
2246
+ MatRippleModule,
2247
+ MatLegacyInputModule,
2248
+ MatLegacyFormFieldModule,
2249
+ MatExpansionModule,
2250
+ ReactiveFormsModule,
2251
+ FormsModule,
2252
+ MatLegacyButtonModule,
2253
+ MatTabsModule,
2254
+ MatTableModule,
2255
+ MatLegacyProgressSpinnerModule,
2256
+ MatLegacySnackBarModule,
2257
+ MatSortModule,
2258
+ MatTooltipModule], exports: [AccessControlComponent, PaginationComponent] }); }
2259
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AccessControlModule, imports: [CommonModule,
2260
+ MatLegacyRadioModule,
2261
+ MatIconModule,
2262
+ MatDialogModule,
2263
+ MatLegacyMenuModule,
2264
+ MatLegacyCheckboxModule,
2265
+ MatLegacySlideToggleModule,
2266
+ MatLegacySelectModule,
2267
+ MatRippleModule,
2268
+ MatLegacyInputModule,
2269
+ MatLegacyFormFieldModule,
2270
+ MatExpansionModule,
2271
+ ReactiveFormsModule,
2272
+ FormsModule,
2273
+ MatLegacyButtonModule,
2274
+ MatTabsModule,
2275
+ MatTableModule,
2276
+ MatLegacyProgressSpinnerModule,
2277
+ MatLegacySnackBarModule,
2278
+ MatSortModule,
2279
+ MatTooltipModule] }); }
2280
+ }
2281
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AccessControlModule, decorators: [{
2282
+ type: NgModule,
2283
+ args: [{
2284
+ declarations: [
2285
+ AccessControlComponent,
2286
+ InviteUsersComponent,
2287
+ ListTableComponent,
2288
+ PaginationComponent,
2289
+ BulkUploadKarmayogiComponent,
2290
+ DragDropDirective,
2291
+ EntitySelectionsComponent,
2292
+ ConfirmDialogComponent,
2293
+ AccessControlGuideComponent
2294
+ ],
2295
+ imports: [
2296
+ CommonModule,
2297
+ MatLegacyRadioModule,
2298
+ MatIconModule,
2299
+ MatDialogModule,
2300
+ MatLegacyMenuModule,
2301
+ MatLegacyCheckboxModule,
2302
+ MatLegacySlideToggleModule,
2303
+ MatLegacySelectModule,
2304
+ MatRippleModule,
2305
+ MatLegacyInputModule,
2306
+ MatLegacyFormFieldModule,
2307
+ MatExpansionModule,
2308
+ ReactiveFormsModule,
2309
+ FormsModule,
2310
+ MatLegacyButtonModule,
2311
+ MatTabsModule,
2312
+ MatTableModule,
2313
+ MatLegacyProgressSpinnerModule,
2314
+ MatLegacySnackBarModule,
2315
+ MatSortModule,
2316
+ MatTooltipModule
2317
+ ],
2318
+ exports: [AccessControlComponent, PaginationComponent]
2319
+ }]
2320
+ }] });
2321
+
2322
+ /*
2323
+ * Public API Surface of access-settings
2324
+ */
2325
+
2326
+ /**
2327
+ * Generated bundle index. Do not edit.
2328
+ */
2329
+
2330
+ export { AccessControlComponent, AccessControlModule, AccessSettingsComponent, AccessSettingsModule, NsAccessControlConfig, PaginationComponent };
2331
+ //# sourceMappingURL=sunbird-cb-access-settings.mjs.map