@ieeesa-npm/tenants 0.4.2 → 0.4.4

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 (138) hide show
  1. package/.eslintrc.json +31 -0
  2. package/ng-package.json +8 -0
  3. package/package.json +12 -25
  4. package/src/lib/assets/constants.json +454 -0
  5. package/src/lib/assets/tenant-validations.ts +18 -0
  6. package/src/lib/assets/tenants-mock.ts +1240 -0
  7. package/src/lib/components/create-modify-group-type/create-modify-group-type.component.html +15 -0
  8. package/src/lib/components/create-modify-group-type/create-modify-group-type.component.scss +44 -0
  9. package/src/lib/components/create-modify-group-type/create-modify-group-type.component.spec.ts +574 -0
  10. package/src/lib/components/create-modify-group-type/create-modify-group-type.component.ts +602 -0
  11. package/src/lib/components/create-modify-role/create-modify-role.component.html +15 -0
  12. package/src/lib/components/create-modify-role/create-modify-role.component.scss +83 -0
  13. package/src/lib/components/create-modify-role/create-modify-role.component.spec.ts +346 -0
  14. package/src/lib/components/create-modify-role/create-modify-role.component.ts +321 -0
  15. package/src/lib/components/create-tenant-application/create-tenant-application.component.html +18 -0
  16. package/src/lib/components/create-tenant-application/create-tenant-application.component.scss +73 -0
  17. package/src/lib/components/create-tenant-application/create-tenant-application.component.spec.ts +775 -0
  18. package/src/lib/components/create-tenant-application/create-tenant-application.component.ts +638 -0
  19. package/src/lib/components/roles-and-permissions-mapping/roles-and-permissions-mapping.component.html +22 -0
  20. package/src/lib/components/roles-and-permissions-mapping/roles-and-permissions-mapping.component.scss +79 -0
  21. package/src/lib/components/roles-and-permissions-mapping/roles-and-permissions-mapping.component.spec.ts +716 -0
  22. package/src/lib/components/roles-and-permissions-mapping/roles-and-permissions-mapping.component.ts +504 -0
  23. package/src/lib/components/tenant-basic-details/tenant-basic-details.component.html +44 -0
  24. package/src/lib/components/tenant-basic-details/tenant-basic-details.component.scss +16 -0
  25. package/src/lib/components/tenant-basic-details/tenant-basic-details.component.spec.ts +115 -0
  26. package/src/lib/components/tenant-basic-details/tenant-basic-details.component.ts +109 -0
  27. package/src/lib/components/view-tenant-details/view-tenant-details.component.html +195 -0
  28. package/src/lib/components/view-tenant-details/view-tenant-details.component.scss +163 -0
  29. package/src/lib/components/view-tenant-details/view-tenant-details.component.spec.ts +1221 -0
  30. package/src/lib/components/view-tenant-details/view-tenant-details.component.ts +876 -0
  31. package/src/lib/components/view-tenant-group-types/view-tenant-group-types.component.html +10 -0
  32. package/src/lib/components/view-tenant-group-types/view-tenant-group-types.component.scss +44 -0
  33. package/src/lib/components/view-tenant-group-types/view-tenant-group-types.component.spec.ts +410 -0
  34. package/src/lib/components/view-tenant-group-types/view-tenant-group-types.component.ts +219 -0
  35. package/src/lib/components/view-tenants-list/view-tenants-list.component.html +32 -0
  36. package/src/lib/components/view-tenants-list/view-tenants-list.component.scss +35 -0
  37. package/src/lib/components/view-tenants-list/view-tenants-list.component.spec.ts +464 -0
  38. package/src/lib/components/view-tenants-list/view-tenants-list.component.ts +388 -0
  39. package/src/lib/models/app-type-config.model.ts +14 -0
  40. package/src/lib/models/app-type.model.ts +5 -0
  41. package/src/lib/models/create-group-type-config.model.ts +18 -0
  42. package/src/lib/models/create-group-type.model.ts +46 -0
  43. package/src/lib/models/feature-permission-id.model.ts +6 -0
  44. package/src/lib/models/features.model.ts +15 -0
  45. package/src/lib/models/form-status.model.ts +5 -0
  46. package/src/lib/models/permission-type.model.ts +9 -0
  47. package/src/lib/models/role-menu-action.model.ts +5 -0
  48. package/src/lib/models/role-type.model.ts +34 -0
  49. package/src/lib/models/roles-and-permissions-table-type.model.ts +5 -0
  50. package/src/lib/models/roles-and-permissions.model.ts +113 -0
  51. package/src/lib/models/route-config.model.ts +4 -0
  52. package/src/lib/models/table-column-schema-view-tenant-list.model.ts +21 -0
  53. package/src/lib/models/tenant-function-type.model.ts +10 -0
  54. package/src/lib/models/tenant.model.ts +47 -0
  55. package/src/lib/models/tenants-permission.model.ts +9 -0
  56. package/src/lib/models/update-tenant-status.model.ts +12 -0
  57. package/src/lib/models/view-tenant-group-types.model.ts +34 -0
  58. package/src/lib/services/tenant-applications.service.spec.ts +1245 -0
  59. package/src/lib/services/tenant-applications.service.ts +798 -0
  60. package/src/lib/services/tenant-permissions-map.service.spec.ts +25 -0
  61. package/src/lib/services/tenant-permissions-map.service.ts +28 -0
  62. package/src/lib/services/tenant-permissions.service.spec.ts +62 -0
  63. package/src/lib/services/tenant-permissions.service.ts +49 -0
  64. package/src/lib/tenant-applications.component.html +0 -0
  65. package/src/lib/tenant-applications.component.scss +0 -0
  66. package/src/lib/tenant-applications.component.spec.ts +28 -0
  67. package/src/lib/tenant-applications.component.ts +12 -0
  68. package/src/lib/tenant-applications.module.ts +8 -0
  69. package/{public-api.d.ts → src/public-api.ts} +40 -30
  70. package/tsconfig.lib.json +14 -0
  71. package/tsconfig.lib.prod.json +10 -0
  72. package/tsconfig.spec.json +14 -0
  73. package/esm2022/ieeesa-npm-tenants.mjs +0 -5
  74. package/esm2022/lib/assets/constants.json +0 -390
  75. package/esm2022/lib/assets/tenant-validations.mjs +0 -13
  76. package/esm2022/lib/components/create-modify-role/create-modify-role.component.mjs +0 -280
  77. package/esm2022/lib/components/create-tenant-application/create-tenant-application.component.mjs +0 -512
  78. package/esm2022/lib/components/roles-and-permissions-mapping/roles-and-permissions-mapping.component.mjs +0 -391
  79. package/esm2022/lib/components/tenant-basic-details/tenant-basic-details.component.mjs +0 -95
  80. package/esm2022/lib/components/view-tenant-details/view-tenant-details.component.mjs +0 -708
  81. package/esm2022/lib/components/view-tenant-group-types/view-tenant-group-types.component.mjs +0 -174
  82. package/esm2022/lib/components/view-tenants-list/view-tenants-list.component.mjs +0 -334
  83. package/esm2022/lib/models/app-type-config.model.mjs +0 -2
  84. package/esm2022/lib/models/app-type.model.mjs +0 -7
  85. package/esm2022/lib/models/feature-permission-id.model.mjs +0 -8
  86. package/esm2022/lib/models/features.model.mjs +0 -2
  87. package/esm2022/lib/models/form-status.model.mjs +0 -7
  88. package/esm2022/lib/models/permission-type.model.mjs +0 -12
  89. package/esm2022/lib/models/role-menu-action.model.mjs +0 -7
  90. package/esm2022/lib/models/role-type.model.mjs +0 -2
  91. package/esm2022/lib/models/roles-and-permissions-table-type.model.mjs +0 -7
  92. package/esm2022/lib/models/roles-and-permissions.model.mjs +0 -2
  93. package/esm2022/lib/models/route-config.model.mjs +0 -2
  94. package/esm2022/lib/models/table-column-schema-view-tenant-list.model.mjs +0 -16
  95. package/esm2022/lib/models/tenant-function-type.model.mjs +0 -10
  96. package/esm2022/lib/models/tenant.model.mjs +0 -2
  97. package/esm2022/lib/models/tenants-permission.model.mjs +0 -2
  98. package/esm2022/lib/models/update-tenant-status.model.mjs +0 -2
  99. package/esm2022/lib/models/view-tenant-group-types.model.mjs +0 -9
  100. package/esm2022/lib/services/tenant-applications.service.mjs +0 -542
  101. package/esm2022/lib/services/tenant-permissions-map.service.mjs +0 -36
  102. package/esm2022/lib/services/tenant-permissions.service.mjs +0 -38
  103. package/esm2022/lib/tenant-applications.component.mjs +0 -14
  104. package/esm2022/lib/tenant-applications.module.mjs +0 -16
  105. package/esm2022/public-api.mjs +0 -34
  106. package/fesm2022/ieeesa-npm-tenants.mjs +0 -3565
  107. package/fesm2022/ieeesa-npm-tenants.mjs.map +0 -1
  108. package/index.d.ts +0 -5
  109. package/lib/assets/tenant-validations.d.ts +0 -11
  110. package/lib/components/create-modify-role/create-modify-role.component.d.ts +0 -103
  111. package/lib/components/create-tenant-application/create-tenant-application.component.d.ts +0 -128
  112. package/lib/components/roles-and-permissions-mapping/roles-and-permissions-mapping.component.d.ts +0 -106
  113. package/lib/components/tenant-basic-details/tenant-basic-details.component.d.ts +0 -408
  114. package/lib/components/view-tenant-details/view-tenant-details.component.d.ts +0 -216
  115. package/lib/components/view-tenant-group-types/view-tenant-group-types.component.d.ts +0 -58
  116. package/lib/components/view-tenants-list/view-tenants-list.component.d.ts +0 -134
  117. package/lib/models/app-type-config.model.d.ts +0 -14
  118. package/lib/models/app-type.model.d.ts +0 -4
  119. package/lib/models/feature-permission-id.model.d.ts +0 -4
  120. package/lib/models/features.model.d.ts +0 -15
  121. package/lib/models/form-status.model.d.ts +0 -4
  122. package/lib/models/permission-type.model.d.ts +0 -8
  123. package/lib/models/role-menu-action.model.d.ts +0 -4
  124. package/lib/models/role-type.model.d.ts +0 -27
  125. package/lib/models/roles-and-permissions-table-type.model.d.ts +0 -4
  126. package/lib/models/roles-and-permissions.model.d.ts +0 -119
  127. package/lib/models/route-config.model.d.ts +0 -4
  128. package/lib/models/table-column-schema-view-tenant-list.model.d.ts +0 -20
  129. package/lib/models/tenant-function-type.model.d.ts +0 -7
  130. package/lib/models/tenant.model.d.ts +0 -51
  131. package/lib/models/tenants-permission.model.d.ts +0 -9
  132. package/lib/models/update-tenant-status.model.d.ts +0 -14
  133. package/lib/models/view-tenant-group-types.model.d.ts +0 -27
  134. package/lib/services/tenant-applications.service.d.ts +0 -357
  135. package/lib/services/tenant-permissions-map.service.d.ts +0 -13
  136. package/lib/services/tenant-permissions.service.d.ts +0 -22
  137. package/lib/tenant-applications.component.d.ts +0 -5
  138. package/lib/tenant-applications.module.d.ts +0 -6
@@ -0,0 +1,876 @@
1
+ import {
2
+ Component,
3
+ Input,
4
+ OnDestroy,
5
+ OnInit,
6
+ ViewEncapsulation,
7
+ } from '@angular/core';
8
+ import { CommonModule } from '@angular/common';
9
+ import {
10
+ AlertType,
11
+ BreakpointObserverService,
12
+ GlobalErrorHandlerService,
13
+ ModalType,
14
+ } from '@ieeesa-npm/utility';
15
+ import {
16
+ AccordionInfo,
17
+ ModalComponent,
18
+ Menu,
19
+ PaginatorConfig,
20
+ SlideToggleComponent,
21
+ TableActions,
22
+ AlignType,
23
+ ModalConfirmationComponent,
24
+ IconButtonComponent,
25
+ RadioOption,
26
+ IconButton,
27
+ SlideToggleOption,
28
+ TableColumnSchema,
29
+ TableColumnType,
30
+ AccordionComponent,
31
+ AccordionDetails,
32
+ DataTableComponent,
33
+ TableColumnMenuInfo,
34
+ } from '@ieeesa-npm/presentation';
35
+ import { MatButtonModule } from '@angular/material/button';
36
+ import { Subject, takeUntil } from 'rxjs';
37
+ import * as screenText from '../../assets/constants.json';
38
+ import { ActivatedRoute, Params, RouterModule } from '@angular/router';
39
+ import { MatDividerModule } from '@angular/material/divider';
40
+ import { TenantApplicationsService } from '../../services/tenant-applications.service';
41
+ import {
42
+ TenantsPermissions,
43
+ UserPermission,
44
+ } from '../../models/tenants-permission.model';
45
+ import { SharedService } from '@ieeesa-npm/shared';
46
+ import { TenantsRoutesConfig } from '../../models/route-config.model';
47
+ import { Features } from '../../models/features.model';
48
+ import {
49
+ TenantBasicInfo,
50
+ TenantDetailsResponse,
51
+ } from '../../models/tenant.model';
52
+ import { TenantFunctionType } from '../../models/tenant-function-type.model';
53
+ import { CreateTenantApplicationComponent } from '../create-tenant-application/create-tenant-application.component';
54
+ import { PageEvent } from '@angular/material/paginator';
55
+ import { MatDialog } from '@angular/material/dialog';
56
+ import {
57
+ UpdateTenantStatusRequestPayload,
58
+ UpdateTenantStatusResponse,
59
+ } from '../../models/update-tenant-status.model';
60
+ import { FeaturePermissionId } from '../../models/feature-permission-id.model';
61
+ import {
62
+ AppTypeConfig,
63
+ GetAppTypesResponse,
64
+ } from '../../models/app-type-config.model';
65
+ import { TenantBasicDetailsComponent } from '../tenant-basic-details/tenant-basic-details.component';
66
+ import {
67
+ GetRolesAndPermissionsPayload,
68
+ GetRolesAndPermissionsResponse,
69
+ GetRolesResponse,
70
+ Role,
71
+ RolesAndPermissionsMapping,
72
+ RolesAndPermissions,
73
+ DeleteRoleRequestPayload,
74
+ DeleteRoleResponse,
75
+ PaginationInfo,
76
+ RoleDetails,
77
+ } from '../../models/roles-and-permissions.model';
78
+ import { PermissionType } from '../../models/permission-type.model';
79
+ import { CreateModifyRoleComponent } from '../create-modify-role/create-modify-role.component';
80
+ import { RoleMenuAction } from '../../models/role-menu-action.model';
81
+ import { RolesAndPermissionsMappingComponent } from '../roles-and-permissions-mapping/roles-and-permissions-mapping.component';
82
+ import { ViewTenantGroupTypesComponent } from '../view-tenant-group-types/view-tenant-group-types.component';
83
+ import {
84
+ GetRoleTypesPayload,
85
+ RoleTypeConfiguration,
86
+ RoleTypeOption,
87
+ RoleTypeResponse,
88
+ } from '../../models/role-type.model';
89
+ import { CreateModifyGroupTypeComponent } from '../create-modify-group-type/create-modify-group-type.component';
90
+
91
+ @Component({
92
+ // eslint-disable-next-line @angular-eslint/component-selector
93
+ selector: 'ieeesa-view-tenant-details',
94
+ standalone: true,
95
+ imports: [
96
+ CommonModule,
97
+ RouterModule,
98
+ SlideToggleComponent,
99
+ AccordionComponent,
100
+ MatDividerModule,
101
+ TenantBasicDetailsComponent,
102
+ IconButtonComponent,
103
+ MatButtonModule,
104
+ DataTableComponent,
105
+ ViewTenantGroupTypesComponent,
106
+ ],
107
+ templateUrl: './view-tenant-details.component.html',
108
+ styleUrls: ['./view-tenant-details.component.scss'],
109
+ encapsulation: ViewEncapsulation.None,
110
+ })
111
+ export class ViewTenantDetailsComponent implements OnInit, OnDestroy {
112
+ destroy$: Subject<boolean> = new Subject<boolean>();
113
+ @Input() apiBaseURL!: string;
114
+ @Input() userPermissions!: UserPermission[];
115
+ @Input() routePaths!: TenantsRoutesConfig;
116
+ isMobileView = false;
117
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
118
+ constants: any = screenText;
119
+ tenantLabels = this.constants?.viewTenants?.label;
120
+ slideToggleOption = {
121
+ id: 1,
122
+ label: this.constants?.viewTenants?.label?.active,
123
+ checked: true,
124
+ disabled: false,
125
+ };
126
+ editButton: IconButton = this.constants?.viewTenants?.buttons;
127
+ tenantDetails!: TenantBasicInfo;
128
+ accordionInfoList: AccordionInfo[] = JSON.parse(
129
+ JSON.stringify(this.constants?.viewTenants?.tenantAccordionInfo)
130
+ );
131
+ appId = '';
132
+ iconSize = this.constants?.viewRolesAndPermissions?.columnActionIconSize;
133
+ rolesAndPermissionsTableCaption =
134
+ this.constants?.viewRolesAndPermissions?.tableCaption;
135
+ rolesAndPermissionsTableHeaderName =
136
+ this.constants?.viewRolesAndPermissions?.tableColumnsHeaderText;
137
+ rolesAndPermissionsTableSupportMessage =
138
+ this.constants?.viewRolesAndPermissions?.scrollbarSupportMessage;
139
+ permissionsColumnClassNumber = 1;
140
+ menuItems: Menu[] =
141
+ this.constants?.viewRolesAndPermissions?.columnActionMenuItems;
142
+ columnSchema: TableColumnSchema[] = [];
143
+ tableData: RolesAndPermissions[] = [];
144
+ isRolesAndPermissionsExpanded = false;
145
+ paginatorConfig: PaginatorConfig = {
146
+ recordsPerPage: this.constants?.viewRolesAndPermissions?.pageSizeOptions[0],
147
+ pageSizeOptions: this.constants?.viewRolesAndPermissions?.pageSizeOptions,
148
+ totalRecords: 0,
149
+ };
150
+ tablePagination!: PaginationInfo;
151
+ rolesAndPermissionsClassName =
152
+ '.ieeesa-view-tenant-info__roles-and-permissions';
153
+ headerElementClassName = '.ieeesa-header';
154
+ tableActions: TableActions = {
155
+ isPaginationNeeded: true,
156
+ };
157
+ viewTenantsRouteUrl!: string;
158
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
159
+ dialogRef: any;
160
+ accordionDetails = AccordionDetails;
161
+ appTypeOptions!: RadioOption[];
162
+ isBasicDetailsExpanded = false;
163
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
164
+ createGroupTypeScreenTexts: any = this.constants?.createGroupType;
165
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
166
+ editTenantScreenTexts: any = this.constants?.editTenant;
167
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
168
+ deleteRoleScreenTexts: any = this.constants?.deleteRole;
169
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
170
+ mapRolesAndPermissionsScreenTexts: any =
171
+ this.constants?.mapRolesAndPermissions;
172
+ alignmentType = AlignType;
173
+ userTenantsPermissions!: TenantsPermissions[];
174
+ permissionType = PermissionType;
175
+ functionType!: TenantFunctionType;
176
+ createRoleScreenTexts = this.constants?.createRole;
177
+ roleMenuElement!: HTMLElement;
178
+ selectedRoleInfo: RoleDetails = {
179
+ roleId: '',
180
+ roleName: '',
181
+ };
182
+ isGroupTypesExpanded = false;
183
+ roleTypeOptions: RoleTypeOption[] = [];
184
+ constructor(
185
+ // eslint-disable-next-line no-unused-vars
186
+ public dialog: MatDialog,
187
+ // eslint-disable-next-line no-unused-vars
188
+ private breakpointObserverService: BreakpointObserverService,
189
+ // eslint-disable-next-line no-unused-vars
190
+ private tenantAppService: TenantApplicationsService,
191
+ // eslint-disable-next-line no-unused-vars
192
+ public globalErrorHandlerService: GlobalErrorHandlerService,
193
+ // eslint-disable-next-line no-unused-vars
194
+ private sharedService: SharedService,
195
+ // eslint-disable-next-line no-unused-vars
196
+ private activatedRoute: ActivatedRoute
197
+ ) {
198
+ this.breakpointObserverService
199
+ .getBreakpoint()
200
+ .pipe(takeUntil(this.destroy$))
201
+ .subscribe((result: { matches: boolean }) => {
202
+ this.isMobileView = result?.matches;
203
+ });
204
+ }
205
+
206
+ /**
207
+ * Initializes view tenant details component.
208
+ * @return -returns nothing
209
+ * @memberof ViewTenantDetailsComponent
210
+ */
211
+ ngOnInit(): void {
212
+ this.tenantDetails =
213
+ this.tenantAppService?.getSelectedTenantInformation() as TenantBasicInfo;
214
+ this.slideToggleOption.checked = this.tenantDetails?.status as boolean;
215
+ this.slideToggleOption.label = this.tenantDetails?.status
216
+ ? this.tenantLabels?.active
217
+ : this.tenantLabels?.inactive;
218
+ this.routePaths = this.routePaths ?? this.constants?.routeConfigPath;
219
+ this.viewTenantsRouteUrl = `/${this.routePaths?.viewTenants}`;
220
+ this.tenantAppService?.setAppConfig(this.apiBaseURL, this.userPermissions);
221
+ this.userTenantsPermissions = this.tenantAppService?.filterPermission(
222
+ this.userPermissions
223
+ );
224
+ this.appId = this.tenantAppService.getSelectedTenantInformation()
225
+ ?.appId as string;
226
+ this.tablePagination = {
227
+ offset: 0,
228
+ pageSize: this.paginatorConfig.pageSizeOptions[0],
229
+ };
230
+ this.getApplicationTypes();
231
+ this.activatedRoute?.queryParams
232
+ ?.pipe(takeUntil(this.destroy$))
233
+ ?.subscribe((params: Params) => {
234
+ this.appId = params['id'];
235
+ this.getTenantDetails(this.appId);
236
+ });
237
+ }
238
+ /**
239
+ * Gets the selected tenant details from server.
240
+ * @memberof ViewTenantDetailsComponent
241
+ */
242
+ getTenantDetails(appId: string): void {
243
+ this.tenantAppService
244
+ .getTenantDetails(appId)
245
+ .pipe(takeUntil(this.destroy$))
246
+ .subscribe({
247
+ next: (response: TenantDetailsResponse) => {
248
+ if (response?.status) {
249
+ this.tenantDetails = response?.body as TenantBasicInfo;
250
+ this.tenantAppService.setSelectedTenantInformation(
251
+ this.tenantDetails
252
+ );
253
+ this.slideToggleOption.checked = this.tenantDetails
254
+ .status as boolean;
255
+ this.slideToggleOption.label = this.tenantDetails.status
256
+ ? this.tenantLabels?.active
257
+ : this.tenantLabels?.inactive;
258
+ const features = this.tenantDetails.features as Features[];
259
+ features.map((feature: Features) => {
260
+ if (
261
+ feature?.featureId ===
262
+ FeaturePermissionId.MEETINGS_AND_EVENTS ||
263
+ feature?.featureId === FeaturePermissionId.BALLOTS
264
+ )
265
+ this.accordionInfoList.push({
266
+ id: this.accordionInfoList.length + 1,
267
+ isDisabled: false,
268
+ title: feature?.featureName,
269
+ });
270
+ });
271
+ }
272
+ },
273
+ error: (error) => {
274
+ this.sharedService.handleErrors(
275
+ error,
276
+ this.constants?.viewTenants.errors
277
+ );
278
+ },
279
+ });
280
+ }
281
+
282
+ /**
283
+ * Display the corresponding tenant basic or feature details based on selected accordion.
284
+ * @param {AccordionInfo} accordionInfo
285
+ * @param {boolean} expanded
286
+ * @memberof ViewTenantDetailsComponent
287
+ */
288
+ showTenantDetails(accordionInfo: AccordionInfo, expanded: boolean): void {
289
+ const accordionId = accordionInfo.id as number;
290
+ switch (accordionId) {
291
+ case 1: {
292
+ this.isBasicDetailsExpanded = expanded;
293
+ if (expanded) {
294
+ this.getApplicationTypes();
295
+ }
296
+ break;
297
+ }
298
+ case 2: {
299
+ this.isRolesAndPermissionsExpanded = expanded;
300
+ if (expanded) {
301
+ this.columnSchema = [];
302
+ this.paginatorConfig.recordsPerPage =
303
+ this.constants?.viewRolesAndPermissions?.pageSizeOptions[0];
304
+ this.tablePagination.offset = 0;
305
+ this.tablePagination.pageSize = this.paginatorConfig.recordsPerPage;
306
+ this.getRolesAndInitializeTableSchema();
307
+ }
308
+ break;
309
+ }
310
+ case 3: {
311
+ this.isGroupTypesExpanded = expanded;
312
+ break;
313
+ }
314
+ }
315
+ }
316
+ /**
317
+ * Fetches the configured roles of the selected tenant and creates the column schema.
318
+ * @memberof ViewTenantDetailsComponent
319
+ */
320
+ getRolesAndInitializeTableSchema(): void {
321
+ this.tenantAppService
322
+ .getRoles(this.appId)
323
+ .pipe(takeUntil(this.destroy$))
324
+ .subscribe({
325
+ next: (response: GetRolesResponse) => {
326
+ if (response?.status) {
327
+ this.getRolesAndPermissionsAndInitializeTableView({
328
+ payload: {
329
+ offset: this.tablePagination.offset,
330
+ pageSize: this.tablePagination.pageSize,
331
+ },
332
+ });
333
+ const rolesList = this.tenantAppService.sortRolesByRoleType(
334
+ response?.body as Role[]
335
+ );
336
+ this.tenantAppService.setRolesInfo(rolesList);
337
+ const cellValue =
338
+ this.constants.viewRolesAndPermissions.tableCellValue;
339
+ this.columnSchema = [
340
+ {
341
+ id: 0,
342
+ columnDef: 'permissions',
343
+ heading:
344
+ this.constants.viewRolesAndPermissions.tableColumn
345
+ .permissions,
346
+ columnType: TableColumnType.TEXT,
347
+ cellData: (rolesAndPermissions: RolesAndPermissions) =>
348
+ rolesAndPermissions.permission,
349
+ isStickyColumn: true,
350
+ },
351
+ ];
352
+ rolesList.map((role: Role, index) => {
353
+ this.columnSchema.push({
354
+ id: index + 1,
355
+ columnDef: role.roleId,
356
+ heading: role.roleName,
357
+ columnType: TableColumnType.TEXT,
358
+ hasColumnActions: true,
359
+ cellData: (rolesAndPermissions: RolesAndPermissions) => {
360
+ return rolesAndPermissions.roleIdsList.find(
361
+ (roleId: string) => role.roleId === roleId
362
+ )
363
+ ? cellValue.yes
364
+ : cellValue.no;
365
+ },
366
+ });
367
+ });
368
+ }
369
+ },
370
+ error: (error) => {
371
+ this.sharedService.handleErrors(
372
+ error,
373
+ this.constants?.viewTenants?.errors
374
+ );
375
+ },
376
+ });
377
+ }
378
+ /**
379
+ * Fetches the roles and permissions mappings for the selected tenant and and initialize table view.
380
+ * @param {GetRolesAndPermissionsPayload} payload
381
+ * @memberof ViewTenantDetailsComponent
382
+ */
383
+ getRolesAndPermissionsAndInitializeTableView(
384
+ payload: GetRolesAndPermissionsPayload
385
+ ): void {
386
+ this.tenantAppService
387
+ .getRolesAndPermissionsMappings(this.appId, payload)
388
+ .pipe(takeUntil(this.destroy$))
389
+ .subscribe({
390
+ next: (response: GetRolesAndPermissionsResponse) => {
391
+ if (response?.status) {
392
+ this.tableData = [];
393
+ this.paginatorConfig.totalRecords = response?.body
394
+ ?.totalRecords as number;
395
+ const rolesAndPermissionsList = response?.body
396
+ ?.rolePermissionDetails as RolesAndPermissionsMapping[];
397
+ rolesAndPermissionsList.map((permission) => {
398
+ let roleIdsList: string[] = [];
399
+ roleIdsList = permission.roleList.map((role) => role.roleId);
400
+ this.tableData.push({
401
+ permission: permission.permissionName,
402
+ roleIdsList: roleIdsList,
403
+ });
404
+ });
405
+ }
406
+ },
407
+ error: (error) => {
408
+ this.sharedService.handleErrors(
409
+ error,
410
+ this.constants?.viewTenants?.errors
411
+ );
412
+ },
413
+ });
414
+ }
415
+ /**
416
+ * Fetch the roles and permissions records based on offset and page size while the pagination changes.
417
+ * @param {PageEvent} pageEvent
418
+ * @memberof ViewTenantDetailsComponent
419
+ */
420
+ onTablePaginationChange(pageEvent: PageEvent): void {
421
+ this.tablePagination = {
422
+ offset: pageEvent.pageIndex,
423
+ pageSize: pageEvent.pageSize,
424
+ };
425
+ this.getRolesAndPermissionsAndInitializeTableView({
426
+ payload: {
427
+ offset: pageEvent.pageIndex,
428
+ pageSize: pageEvent.pageSize,
429
+ },
430
+ });
431
+ }
432
+ /**
433
+ * Captures the selected role's information and performs edit or delete action basis on the selected menu item.
434
+ * @param {TableColumnMenuInfo} roleMenuInfo
435
+ * @memberof ViewTenantDetailsComponent
436
+ */
437
+ onRoleMenuClick(roleMenuInfo: TableColumnMenuInfo) {
438
+ this.selectedRoleInfo.roleId = roleMenuInfo?.tableColumnInfo?.columnDef;
439
+ this.selectedRoleInfo.roleName = roleMenuInfo?.tableColumnInfo?.heading;
440
+ this.tenantAppService?.setSelectedRoleInformation(this.selectedRoleInfo);
441
+ if (roleMenuInfo?.menuActionInfo?.id === RoleMenuAction.DELETE_ROLE) {
442
+ this.openDeleteRoleModal();
443
+ } else if (roleMenuInfo?.menuActionInfo?.id === RoleMenuAction.EDIT_ROLE) {
444
+ this.openEditRoleForm();
445
+ }
446
+ }
447
+ /**
448
+ * Keeps track of the accordion based on the element's ID in DOM tree.
449
+ * @memberof ViewTenantDetailsComponent
450
+ */
451
+ trackByAccordionFn(index: number, item: AccordionInfo): number {
452
+ return item?.id as number;
453
+ }
454
+ /**
455
+ * Gets the role types and updates the form control.
456
+ * @memberof ViewTenantDetailsComponent
457
+ */
458
+ getRoleTypes(): void {
459
+ const payload: GetRoleTypesPayload = {
460
+ payload: {
461
+ appId: this.tenantDetails?.appId as string,
462
+ configFieldName: 'role_type',
463
+ },
464
+ };
465
+ this.tenantAppService
466
+ .getRoleTypes(payload)
467
+ .pipe(takeUntil(this.destroy$))
468
+ .subscribe({
469
+ next: (response: RoleTypeResponse) => {
470
+ if (response?.status) {
471
+ this.roleTypeOptions = this.tenantAppService.getRoleTypeOptions(
472
+ response?.body as RoleTypeConfiguration[]
473
+ );
474
+ this.tenantAppService?.setRoleTypeOption(this.roleTypeOptions);
475
+ if (this.functionType === TenantFunctionType.CREATE_ROLE) {
476
+ this.openCreateRoleForm();
477
+ }
478
+ }
479
+ },
480
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
481
+ error: (error: any) => {
482
+ this.sharedService.handleErrors(
483
+ error,
484
+ this.createRoleScreenTexts?.errors
485
+ );
486
+ },
487
+ });
488
+ }
489
+ /**
490
+ * Sets the dialog options for create role modal and calls openModal method.
491
+ * @return -returns nothing
492
+ * @memberof ViewTenantDetailsComponent
493
+ */
494
+ openCreateRoleForm(): void {
495
+ this.tenantAppService?.setTenantFunctionType(
496
+ TenantFunctionType?.CREATE_ROLE
497
+ );
498
+ this.functionType = TenantFunctionType.CREATE_ROLE;
499
+ if (this.roleTypeOptions.length > 0) {
500
+ const dialogOptions = {
501
+ heading: this.constants?.createRole?.heading,
502
+ isCloseNeeded: true,
503
+ componentReference: CreateModifyRoleComponent,
504
+ modalType: ModalType.FORM,
505
+ };
506
+ this.openModal(dialogOptions, 'ieeesa-create-modify-role');
507
+ } else {
508
+ this.getRoleTypes();
509
+ }
510
+ }
511
+ /**
512
+ * Sets the dialog options for create group type modal and calls openModal method.
513
+ * @return -returns nothing
514
+ * @memberof ViewTenantDetailsComponent
515
+ */
516
+ openCreateGroupTypeForm(): void {
517
+ this.tenantAppService?.setTenantFunctionType(
518
+ TenantFunctionType?.CREATE_GROUP_TYPE
519
+ );
520
+ this.functionType = TenantFunctionType.CREATE_GROUP_TYPE;
521
+ const dialogOptions = {
522
+ heading: this.constants?.createGroupType?.heading,
523
+ isCloseNeeded: true,
524
+ componentReference: CreateModifyGroupTypeComponent,
525
+ modalType: ModalType.FORM,
526
+ };
527
+ this.openModal(dialogOptions, 'ieeesa-create-modify-group-type');
528
+ }
529
+ /**
530
+ * Sets the dialog options for edit role modal and calls openModal method.
531
+ * @return -returns nothing
532
+ * @memberof ViewTenantDetailsComponent
533
+ */
534
+ openEditRoleForm(): void {
535
+ this.tenantAppService?.setTenantFunctionType(TenantFunctionType?.EDIT_ROLE);
536
+ this.functionType = TenantFunctionType.EDIT_ROLE;
537
+ const dialogOptions = {
538
+ heading: this.selectedRoleInfo?.roleName,
539
+ isCloseNeeded: true,
540
+ componentReference: CreateModifyRoleComponent,
541
+ modalType: ModalType.FORM,
542
+ };
543
+ this.openModal(dialogOptions, 'ieeesa-create-modify-role');
544
+ }
545
+ /**
546
+ * Sets the dialog options for edit tenant modal and calls openModal method.
547
+ * @return -returns nothing
548
+ * @memberof ViewTenantDetailsComponent
549
+ */
550
+ openEditTenantForm(): void {
551
+ this.tenantAppService?.setTenantFunctionType(TenantFunctionType?.EDIT);
552
+ this.functionType = TenantFunctionType.EDIT;
553
+ const dialogOptions = {
554
+ heading: this.tenantDetails?.appTitle,
555
+ isCloseNeeded: true,
556
+ componentReference: CreateTenantApplicationComponent,
557
+ modalType: ModalType.FORM,
558
+ };
559
+ this.openModal(dialogOptions, 'ieeesa-edit-tenant');
560
+ }
561
+
562
+ /**
563
+ * Opens modal component with received params and handles form submission success and errors.
564
+ * @param {*} dialogOptions
565
+ * @param {string} [className]
566
+ * @return -returns nothing
567
+ * @memberof ViewTenantsDetailsComponent
568
+ */
569
+ openModal(
570
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
571
+ dialogOptions: any,
572
+ className?: string
573
+ ): void {
574
+ className = className ?? '';
575
+ this.dialogRef = this.dialog?.open(ModalComponent, {
576
+ data: dialogOptions,
577
+ width: '',
578
+ panelClass: ['ieeesa-modal-dialog', className],
579
+ ariaModal: true,
580
+ });
581
+ this.dialogRef?.componentInstance?.submitFormResponse
582
+ .pipe(takeUntil(this.destroy$))
583
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, no-unused-vars
584
+ .subscribe((result: any) => {
585
+ this.dialogRef?.close();
586
+ switch (this.functionType) {
587
+ case TenantFunctionType?.EDIT: {
588
+ this.sharedService.showAlertMessage(
589
+ AlertType?.SUCCESS,
590
+ `${this.tenantDetails?.appTitle} ${this.editTenantScreenTexts?.message?.success?.submission}`
591
+ );
592
+ this.tenantDetails = {
593
+ ...(this.tenantAppService.getSelectedTenantInformation() as TenantBasicInfo),
594
+ };
595
+ break;
596
+ }
597
+ case TenantFunctionType?.CREATE_ROLE: {
598
+ const promptMessage = this.createRoleScreenTexts?.message?.success;
599
+ const roleInfo = this.tenantAppService?.getNewlyCreatedRoleInfo();
600
+ this.sharedService.showAlertMessage(
601
+ AlertType?.SUCCESS,
602
+ `${promptMessage?.submission1} ${roleInfo?.roleName} ${promptMessage?.submission2} ${this.tenantDetails?.appTitle}. ${promptMessage?.submission3}`
603
+ );
604
+ this.getRolesAndInitializeTableSchema();
605
+ break;
606
+ }
607
+ case TenantFunctionType?.EDIT_ROLE: {
608
+ const promptMessage = this.createRoleScreenTexts?.message?.success;
609
+ const roleInfo = this.tenantAppService?.getNewlyCreatedRoleInfo();
610
+ this.sharedService.showAlertMessage(
611
+ AlertType?.SUCCESS,
612
+ `${roleInfo?.roleName} ${promptMessage?.modify} ${this.tenantDetails?.appTitle}.`
613
+ );
614
+ this.getRolesAndInitializeTableSchema();
615
+ break;
616
+ }
617
+ case TenantFunctionType?.CREATE_GROUP_TYPE: {
618
+ this.sharedService.showAlertMessage(
619
+ AlertType?.SUCCESS,
620
+ `${this.createGroupTypeScreenTexts?.message?.success?.submissionPart1} ${this.tenantAppService.newlyCreatedGroupType.configFieldValue.name} ${this.createGroupTypeScreenTexts?.message?.success?.submissionPart2} ${this.tenantDetails?.appTitle}. `
621
+ );
622
+ this.tenantAppService.isGroupTypeAddedOrModified.next(true);
623
+ break;
624
+ }
625
+ }
626
+ });
627
+ this.dialogRef?.componentInstance?.formCancel
628
+ .pipe(takeUntil(this.destroy$))
629
+ .subscribe(() => {
630
+ this.dialogRef?.close();
631
+ if (
632
+ this.tenantAppService.getTenantFunctionType() ===
633
+ TenantFunctionType.MAP_PERMISSION_AND_ROLE
634
+ )
635
+ this.getRolesAndInitializeTableSchema();
636
+ });
637
+ this.dialogRef?.componentInstance?.modalConfirm
638
+ .pipe(takeUntil(this.destroy$))
639
+ .subscribe(() => {
640
+ if (
641
+ this.tenantAppService.getTenantFunctionType() ===
642
+ TenantFunctionType.MAP_PERMISSION_AND_ROLE
643
+ )
644
+ this.getRolesAndInitializeTableSchema();
645
+ });
646
+ }
647
+ /**
648
+ * Calls openTenantStatusConfirmationModal to change the status of tenant on slide toggle change.
649
+ * @param {SlideToggleOption} slideToggleOption
650
+ * @memberof ViewTenantDetailsComponent
651
+ */
652
+ onSlideToggleChange(slideToggleOption: SlideToggleOption): void {
653
+ this.openTenantStatusConfirmationModal(slideToggleOption?.checked);
654
+ }
655
+ /**
656
+ * Opens the confirmation modal to inactivate/reactivate the tenant.
657
+ * @param {boolean} isActivate
658
+ * @memberof ViewTenantDetailsComponent
659
+ */
660
+ openTenantStatusConfirmationModal(isActivate: boolean): void {
661
+ const confirmationInfo = this.constants?.viewTenants?.confirmationInfo;
662
+ const statusText = isActivate
663
+ ? confirmationInfo?.promptMessageActivate
664
+ : confirmationInfo?.promptMessageInactivate;
665
+ const updateTenantStatusModalOptions = {
666
+ leftButtonLabel: confirmationInfo?.leftButtonLabel,
667
+ rightButtonLabel: confirmationInfo?.rightButtonLabel,
668
+ promptMessage: `${confirmationInfo?.promptMessage} ${statusText} ${this.tenantDetails?.appTitle}?`,
669
+ actionButtonAlign: this.alignmentType?.MIDDLE,
670
+ };
671
+ this.dialogRef = this.dialog?.open(ModalConfirmationComponent, {
672
+ data: updateTenantStatusModalOptions,
673
+ width: 'auto',
674
+ autoFocus: 'dialog',
675
+ ariaLabel: confirmationInfo?.ariaLabel?.alert,
676
+ });
677
+ this.dialogRef
678
+ .afterClosed()
679
+ .pipe(takeUntil(this.destroy$))
680
+ .subscribe((result: boolean) => {
681
+ if (result) {
682
+ this.updateTenantStatus(isActivate);
683
+ } else {
684
+ this.setSlideToggleStatus(isActivate);
685
+ }
686
+ });
687
+ }
688
+ /**
689
+ * Opens the map permissions and roles modal.
690
+ * @memberof ViewTenantDetailsComponent
691
+ * @returns {void}
692
+ */
693
+ openMapRolesAndPermissionsForm(): void {
694
+ this.tenantAppService?.setTenantFunctionType(
695
+ TenantFunctionType?.MAP_PERMISSION_AND_ROLE
696
+ );
697
+ const dialogOptions = {
698
+ heading: this.mapRolesAndPermissionsScreenTexts.heading,
699
+ isCloseNeeded: true,
700
+ modalType: ModalType.FORM,
701
+ componentReference: RolesAndPermissionsMappingComponent,
702
+ };
703
+ this.openModal(dialogOptions, 'ieeesa-map-permissions-and-roles');
704
+ }
705
+ /**
706
+ * Updates the tenant status to the server using http request and display success/error message based on request response (success or failure).
707
+ * @param {boolean} isActivate
708
+ * @memberof ViewTenantDetailsComponent
709
+ */
710
+ updateTenantStatus(isActivate: boolean): void {
711
+ const updateTenantStatusRequestPayload: UpdateTenantStatusRequestPayload = {
712
+ payload: {
713
+ appId: this.tenantDetails?.appId,
714
+ status: isActivate,
715
+ },
716
+ };
717
+ this.tenantAppService
718
+ .updateTenantStatus(updateTenantStatusRequestPayload)
719
+ .pipe(takeUntil(this.destroy$))
720
+ .subscribe({
721
+ next: (res: UpdateTenantStatusResponse) => {
722
+ this.dialogRef?.close();
723
+ if (res?.status) {
724
+ this.slideToggleOption.label = isActivate
725
+ ? this.tenantLabels?.active
726
+ : this.tenantLabels?.inactive;
727
+ this.tenantDetails.status = isActivate;
728
+ this.tenantDetails = Object.assign({}, this.tenantDetails);
729
+ }
730
+ },
731
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
732
+ error: (error: any) => {
733
+ this.setSlideToggleStatus(isActivate);
734
+ this.sharedService.handleErrors(
735
+ error,
736
+ this.constants?.viewTenants?.errors
737
+ );
738
+ },
739
+ });
740
+ }
741
+ /**
742
+ * Sets slide toggle checked status and label.
743
+ * @param {boolean} isActivate
744
+ * @memberof ViewTenantDetailsComponent
745
+ */
746
+ setSlideToggleStatus(isActivate: boolean): void {
747
+ this.slideToggleOption.checked = !isActivate;
748
+ this.slideToggleOption.label = !isActivate
749
+ ? this.tenantLabels?.active
750
+ : this.tenantLabels?.inactive;
751
+ }
752
+
753
+ /**
754
+ * Gets the application/tenant types.
755
+ * @memberof ViewTenantDetailsComponent
756
+ */
757
+ getApplicationTypes(): void {
758
+ this.tenantAppService
759
+ .getApplicationTypes()
760
+ .pipe(takeUntil(this.destroy$))
761
+ .subscribe({
762
+ next: (response: GetAppTypesResponse) => {
763
+ if (response?.status) {
764
+ this.appTypeOptions =
765
+ this.tenantAppService.getApplicationTypeOptions(
766
+ response?.body as AppTypeConfig[]
767
+ );
768
+ this.tenantAppService.setApplicationType(
769
+ this.appTypeOptions as RadioOption[]
770
+ );
771
+ }
772
+ },
773
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
774
+ error: (error: any) => {
775
+ this.sharedService.handleErrors(
776
+ error,
777
+ this.constants?.viewTenants?.errors
778
+ );
779
+ },
780
+ });
781
+ }
782
+ /**
783
+ * Validates permission based access for provided feature.
784
+ * @param {PermissionType} permissionType
785
+ * @return {boolean}
786
+ * @memberof ViewTenantDetailsComponent
787
+ */
788
+ validateAccess(permissionType: PermissionType): boolean {
789
+ return this.tenantAppService.validateAccess(
790
+ permissionType,
791
+ this.userTenantsPermissions
792
+ );
793
+ }
794
+ /**
795
+ * Posts the details of the role to be deleted to the server using http request and display success/error message based on request response (success or failure).
796
+ * @memberof ViewTenantDetailsComponent
797
+ */
798
+ deleteRole(): void {
799
+ const deleteRoleRequestPayload: DeleteRoleRequestPayload = {
800
+ payload: {
801
+ appId: this.tenantDetails?.appId,
802
+ roleId: this.selectedRoleInfo?.roleId,
803
+ },
804
+ };
805
+ this.tenantAppService
806
+ .deleteRole(deleteRoleRequestPayload)
807
+ .pipe(takeUntil(this.destroy$))
808
+ .subscribe({
809
+ next: (res: DeleteRoleResponse) => {
810
+ if (res?.status) {
811
+ this.sharedService.showAlertMessage(
812
+ AlertType?.SUCCESS,
813
+ `${this.selectedRoleInfo?.roleName} ${this.deleteRoleScreenTexts?.message?.success?.submission} ${this.tenantDetails?.appTitle}.`
814
+ );
815
+ this.getRolesAndInitializeTableSchema();
816
+ }
817
+ },
818
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
819
+ error: (error: any) => {
820
+ this.sharedService.handleErrors(
821
+ error,
822
+ this.constants?.viewTenants?.errors
823
+ );
824
+ },
825
+ });
826
+ }
827
+ /**
828
+ * Sets the role menu HTMLElement.
829
+ * @param {HTMLElement} menuButton
830
+ * @memberof ViewTenantDetailsComponent
831
+ */
832
+ selectedRoleMenuElement(menuButton: HTMLElement): void {
833
+ this.roleMenuElement = menuButton;
834
+ }
835
+ /**
836
+ * Opens the confirmation modal to get user confirmation to delete the role.
837
+ * @memberof ViewTenantDetailsComponent
838
+ */
839
+ openDeleteRoleModal(): void {
840
+ const confirmationInfo = this.constants?.viewTenants?.confirmationInfo;
841
+ const deleteRoleModalOptions = {
842
+ leftButtonLabel: confirmationInfo?.leftButtonLabel,
843
+ rightButtonLabel: confirmationInfo?.rightButtonLabel,
844
+ promptMessage: `${confirmationInfo?.deleteRoleConfirmationMessage} ${this.selectedRoleInfo?.roleName}? ${confirmationInfo?.deleteRolePromptMessage} ${this.tenantDetails?.appTitle}.`,
845
+ actionButtonAlign: this.alignmentType?.MIDDLE,
846
+ };
847
+ this.dialogRef = this.dialog?.open(ModalConfirmationComponent, {
848
+ data: deleteRoleModalOptions,
849
+ width: '25%',
850
+ panelClass: [
851
+ 'ieeesa-modal-confirm-dialog',
852
+ 'ieeesa-delete-role-confirm-dialog',
853
+ ],
854
+ autoFocus: 'dialog',
855
+ ariaLabel: confirmationInfo?.ariaLabel?.alert,
856
+ });
857
+ this.dialogRef
858
+ .afterClosed()
859
+ .pipe(takeUntil(this.destroy$))
860
+ .subscribe((result: boolean) => {
861
+ if (result) {
862
+ this.deleteRole();
863
+ } else this.roleMenuElement?.focus();
864
+ });
865
+ }
866
+ /**
867
+ * Performs necessary cleanup tasks, such as unsubscribing from subscription when the component is being destroyed.
868
+ * @memberof ViewTenantDetailsComponent
869
+ */
870
+ ngOnDestroy(): void {
871
+ this.roleTypeOptions = [];
872
+ this.tenantAppService?.setRoleTypeOption(this.roleTypeOptions);
873
+ this.destroy$?.next(true);
874
+ this.destroy$?.unsubscribe();
875
+ }
876
+ }