@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,346 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+ import { CreateModifyRoleComponent } from './create-modify-role.component';
3
+ import { TenantApplicationsService } from '../../services/tenant-applications.service';
4
+ import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
5
+ import { FormControlType, FormModel } from '@ieeesa-npm/presentation';
6
+ import { HttpErrorResponse } from '@angular/common/http';
7
+ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
8
+ import {
9
+ MAT_DIALOG_DATA,
10
+ MatDialog,
11
+ MatDialogModule,
12
+ } from '@angular/material/dialog';
13
+ import { HttpClientTestingModule } from '@angular/common/http/testing';
14
+ import { AlertsService, GlobalErrorHandlerService } from '@ieeesa-npm/utility';
15
+ import { TenantsMocks } from '../../assets/tenants-mock';
16
+ import { Observable } from 'rxjs';
17
+ import { SharedService } from '@ieeesa-npm/shared';
18
+ import { TenantFunctionType } from '../../models/tenant-function-type.model';
19
+
20
+ describe('CreateModifyRoleComponent', () => {
21
+ let component: CreateModifyRoleComponent;
22
+ let fixture: ComponentFixture<CreateModifyRoleComponent>;
23
+ let tenantAppService: TenantApplicationsService;
24
+ let globalErrorHandlerService: GlobalErrorHandlerService;
25
+ let sharedService: SharedService;
26
+ let alertsService: AlertsService;
27
+ const formBuilder: FormBuilder = new FormBuilder();
28
+ const mockFormGroup = formBuilder.group({
29
+ appTitle: ['SA Collaboration portal'],
30
+ roleType: [
31
+ {
32
+ id: 'RT_SAAPPS_bb35eeba-50b3-452f-9839-83d78c78a197',
33
+ name: 'System',
34
+ order: 1,
35
+ },
36
+ [Validators.required],
37
+ ],
38
+ roleName: ['test role', [Validators.required]],
39
+ });
40
+ const dialogOptions = {
41
+ heading: 'New Role',
42
+ isCloseNeeded: true,
43
+ componentReference: CreateModifyRoleComponent,
44
+ modalType: 1,
45
+ };
46
+ const mockFormModel: FormModel = {
47
+ formGroup: [
48
+ {
49
+ legend: '',
50
+ controls: [
51
+ {
52
+ type: FormControlType.TEXT_AREA,
53
+ controlName: 'appTitle',
54
+ },
55
+ {
56
+ type: FormControlType.SELECT,
57
+ controlName: 'roleType',
58
+ },
59
+ {
60
+ type: FormControlType.INPUT,
61
+ controlName: 'roleName',
62
+ },
63
+ ],
64
+ },
65
+ ],
66
+ };
67
+ const mockServerErrorResponse = new HttpErrorResponse({
68
+ error: 'test',
69
+ });
70
+ beforeEach(() => {
71
+ TestBed.configureTestingModule({
72
+ imports: [
73
+ CreateModifyRoleComponent,
74
+ BrowserAnimationsModule,
75
+ ReactiveFormsModule,
76
+ HttpClientTestingModule,
77
+ MatDialogModule,
78
+ ],
79
+ providers: [
80
+ TenantApplicationsService,
81
+ AlertsService,
82
+ { provide: MAT_DIALOG_DATA, useValue: dialogOptions },
83
+ MatDialog,
84
+ SharedService,
85
+ ],
86
+ });
87
+ fixture = TestBed.createComponent(CreateModifyRoleComponent);
88
+ component = fixture.componentInstance;
89
+ component.createRoleFormGroup = mockFormModel;
90
+ component.selectedTenantInfo = TenantsMocks?.tenantInfoMock;
91
+ tenantAppService = TestBed.inject(TenantApplicationsService);
92
+ globalErrorHandlerService = TestBed.inject(GlobalErrorHandlerService);
93
+ alertsService = TestBed.inject(AlertsService);
94
+ sharedService = TestBed.inject(SharedService);
95
+ fixture.detectChanges();
96
+ });
97
+
98
+ it('should create', () => {
99
+ expect(component).toBeTruthy();
100
+ });
101
+
102
+ describe('#ngOnInit', () => {
103
+ it('should initialize the create role form group', () => {
104
+ component.createRoleFormGroup = mockFormModel;
105
+ component.selectedRole = TenantsMocks.mockUserRoles.body[0];
106
+ tenantAppService.setSelectedRoleInformation(
107
+ TenantsMocks.mockUserRoles.body[0]
108
+ );
109
+ spyOn(tenantAppService, 'getSelectedRoleInformation').and.returnValue(
110
+ TenantsMocks.mockUserRoles.body[0]
111
+ );
112
+ component.ngOnInit();
113
+ expect(
114
+ component.createRoleFormGroup?.formGroup[0]?.controls?.length
115
+ ).toBe(3);
116
+ });
117
+ it('should get selected roles information', () => {
118
+ spyOn(tenantAppService, 'getSelectedRoleInformation').and.returnValue(
119
+ TenantsMocks.mockUserRoles.body[0]
120
+ );
121
+ tenantAppService.setSelectedRoleInformation(TenantsMocks.mockRoleInfo);
122
+ tenantAppService.setRolesInfo(TenantsMocks.mockUserRoles.body);
123
+ component.ngOnInit();
124
+ expect(component.selectedRole).toEqual(
125
+ TenantsMocks.mockUserRoles.body[0]
126
+ );
127
+ });
128
+ it('should construct role type field when tenantFunctionType is EDIT_ROLE', () => {
129
+ component.tenantFunctionType = TenantFunctionType.EDIT_ROLE;
130
+ const fieldConfig = component.getRoleTypeField();
131
+ expect(fieldConfig).toEqual({
132
+ type: FormControlType?.TEXT_AREA,
133
+ label: component.createRoleTexts?.label?.roleType,
134
+ controlName: 'roleType',
135
+ isReadonly: true,
136
+ value: component.selectedRole?.roleTypeName,
137
+ ariaLabel: component.createRoleTexts?.label?.ariaLabel?.roleType,
138
+ ariaDescribedById:
139
+ component.createRoleTexts?.label?.ariaDescribedById?.roleType,
140
+ isResize: true,
141
+ ariaMultiline: false
142
+ });
143
+ });
144
+ it('should display role name in edit role form when tenantFunctionType is EDIT_ROLE', () => {
145
+ component.tenantFunctionType = TenantFunctionType.EDIT_ROLE;
146
+ tenantAppService.setRolesInfo(TenantsMocks.mockUserRoles.body);
147
+ tenantAppService.setSelectedRoleInformation(TenantsMocks.mockRoleInfo);
148
+ spyOn(tenantAppService, 'getSelectedRoleInformation').and.returnValue(
149
+ TenantsMocks.mockUserRoles.body[0]
150
+ );
151
+ component.ngOnInit();
152
+ expect(component.selectedRole).toEqual(
153
+ TenantsMocks.mockUserRoles.body[0]
154
+ );
155
+ });
156
+ });
157
+ describe('#getCreateModifyRoleFormGroupRef', () => {
158
+ it('initialize create role form group', () => {
159
+ const mockFormGroup = formBuilder.group({
160
+ appTitle: ['SA Collaboration portal'],
161
+ roleType: ['System', [Validators.required]],
162
+ roleName: ['test', [Validators.required]],
163
+ });
164
+ component.createRoleFormGroup = mockFormModel;
165
+ fixture.detectChanges();
166
+ component.getCreateModifyRoleFormGroupRef([mockFormGroup]);
167
+ expect(component.createModifyRoleFormGroupRef).toEqual(mockFormGroup);
168
+ });
169
+ });
170
+ describe('#getCreateModifyRolePayload', () => {
171
+ it('should prepare the create role payload on form submit', () => {
172
+ component.createRoleFormGroup = mockFormModel;
173
+ component.selectedTenantInfo = TenantsMocks.tenantInfoMock;
174
+ const payload = component.getCreateModifyRolePayload(
175
+ mockFormGroup?.getRawValue()
176
+ );
177
+ expect(payload).toEqual(TenantsMocks.createRoleMockPayload);
178
+ });
179
+ it('should prepare the edit role payload on form submit', () => {
180
+ component.createRoleFormGroup = mockFormModel;
181
+ component.selectedRole = TenantsMocks.mockUserRoles.body[0];
182
+ component.tenantFunctionType = TenantFunctionType.EDIT_ROLE;
183
+ const payload = component.getCreateModifyRolePayload(
184
+ mockFormGroup?.getRawValue()
185
+ );
186
+ expect(payload.payload.roleId).toEqual(
187
+ TenantsMocks.editRoleMockPayload.payload.roleId
188
+ );
189
+ });
190
+ });
191
+ describe('#onCreateModifyRoleFormChange', () => {
192
+ it('should call onCreateTenantFormChange whenever the form control value changes', () => {
193
+ component.onCreateModifyRoleFormChange([mockFormGroup]);
194
+ expect(component.createModifyRoleFormGroupRef).toEqual(mockFormGroup);
195
+ });
196
+ });
197
+ describe('#onCreateModifyRoleFormSubmit', () => {
198
+ it('should call createRole when tenantFunctionType is CREATE_ROLE and save button is clicked', () => {
199
+ component.tenantFunctionType = TenantFunctionType.CREATE_ROLE;
200
+ const createRoleSpy = spyOn(
201
+ tenantAppService,
202
+ 'createRole'
203
+ ).and.returnValue(
204
+ new Observable((subscriber) => {
205
+ subscriber.next(TenantsMocks.createRoleMockResponse);
206
+ })
207
+ );
208
+ component.onCreateModifyRoleFormSubmit([mockFormGroup]);
209
+ expect(createRoleSpy).toHaveBeenCalled();
210
+ });
211
+ it('should call editRole when tenantFunctionType is EDIT_ROLE and save button is clicked', () => {
212
+ component.tenantFunctionType = TenantFunctionType.EDIT_ROLE;
213
+ const editRoleSpy = spyOn(tenantAppService, 'editRole').and.returnValue(
214
+ new Observable((subscriber) => {
215
+ subscriber.next(TenantsMocks.editRoleMockResponse);
216
+ })
217
+ );
218
+ component.onCreateModifyRoleFormSubmit([mockFormGroup]);
219
+ expect(editRoleSpy).toHaveBeenCalled();
220
+ });
221
+ });
222
+
223
+ describe('#createRole', () => {
224
+ it('should submit the create role form', () => {
225
+ component.createModifyRolePayload = TenantsMocks.createRoleMockPayload;
226
+ const submitResponseSpy = spyOn(
227
+ component.submitFormResponse,
228
+ 'emit'
229
+ ).and.callThrough();
230
+ const createRoleSpy = spyOn(
231
+ tenantAppService,
232
+ 'createRole'
233
+ ).and.returnValue(
234
+ new Observable((subscriber) => {
235
+ subscriber.next(TenantsMocks.createRoleMockResponse);
236
+ })
237
+ );
238
+ component.createRole();
239
+ expect(createRoleSpy).toHaveBeenCalled();
240
+ expect(submitResponseSpy).toHaveBeenCalled();
241
+ });
242
+ it('should throw error while creating the role', () => {
243
+ const submitResponseSpy = spyOn(
244
+ component.submitFormResponse,
245
+ 'emit'
246
+ ).and.callThrough();
247
+ const submitResponseErrorSpy = spyOn(
248
+ tenantAppService,
249
+ 'createRole'
250
+ ).and.returnValue(
251
+ new Observable((subscriber) => {
252
+ subscriber.error(mockServerErrorResponse);
253
+ })
254
+ );
255
+ spyOn(globalErrorHandlerService, 'handleError');
256
+ component.createRole();
257
+ expect(submitResponseErrorSpy).toHaveBeenCalled();
258
+ expect(submitResponseSpy).not.toHaveBeenCalled();
259
+ });
260
+ });
261
+
262
+ describe('#editRole', () => {
263
+ it('should submit the edit role form', () => {
264
+ component.createModifyRolePayload = TenantsMocks.editRoleMockPayload;
265
+ const submitResponseSpy = spyOn(
266
+ component.submitFormResponse,
267
+ 'emit'
268
+ ).and.callThrough();
269
+ const editRoleSpy = spyOn(tenantAppService, 'editRole').and.returnValue(
270
+ new Observable((subscriber) => {
271
+ subscriber.next(TenantsMocks.editRoleMockResponse);
272
+ })
273
+ );
274
+ component.editRole();
275
+ expect(editRoleSpy).toHaveBeenCalled();
276
+ expect(submitResponseSpy).toHaveBeenCalled();
277
+ });
278
+ it('should throw error while updating the role', () => {
279
+ const submitResponseSpy = spyOn(
280
+ component.submitFormResponse,
281
+ 'emit'
282
+ ).and.callThrough();
283
+ const editRoleSpy = spyOn(tenantAppService, 'editRole').and.returnValue(
284
+ new Observable((subscriber) => {
285
+ subscriber.error(mockServerErrorResponse);
286
+ })
287
+ );
288
+ spyOn(globalErrorHandlerService, 'handleError');
289
+ component.editRole();
290
+ expect(editRoleSpy).toHaveBeenCalled();
291
+ expect(submitResponseSpy).not.toHaveBeenCalled();
292
+ });
293
+ });
294
+ describe('#onFormCancel', () => {
295
+ it('should emit formCancel event', () => {
296
+ const formCancelEmitSpy = spyOn(
297
+ component.formCancel,
298
+ 'emit'
299
+ ).and.callThrough();
300
+ component.onFormCancel();
301
+ expect(formCancelEmitSpy).toHaveBeenCalled();
302
+ });
303
+ });
304
+ describe('#handleErrors', () => {
305
+ it('should handle HttpErrorResponse and call globalErrorHandlerService.handleError', () => {
306
+ spyOn(globalErrorHandlerService, 'handleError');
307
+ const errorResponse = new HttpErrorResponse({ status: 500 });
308
+ const parseErrorMessageSpy = spyOn(sharedService, 'parseErrorMessage');
309
+ component.handleErrors(errorResponse);
310
+ expect(parseErrorMessageSpy).not.toHaveBeenCalled();
311
+ expect(globalErrorHandlerService.handleError).toHaveBeenCalledWith(
312
+ errorResponse
313
+ );
314
+ });
315
+ it('should handle errors and show custom error message', () => {
316
+ const mockErrorResponse = {
317
+ error: {
318
+ status: false,
319
+ message: 'role already exists.',
320
+ body: { errorCodes: ['3012'] },
321
+ },
322
+ status: 400,
323
+ statusText: 'OK',
324
+ };
325
+ const createRoleSpy = spyOn(tenantAppService, 'createRole');
326
+ createRoleSpy.and.returnValue(
327
+ new Observable((subscriber) => {
328
+ subscriber.error(new HttpErrorResponse(mockErrorResponse));
329
+ })
330
+ );
331
+ spyOn(alertsService, 'showMessage').and.callThrough();
332
+ const parseErrorMessageSpy = spyOn(sharedService, 'parseErrorMessage');
333
+ component.handleErrors(new HttpErrorResponse(mockErrorResponse));
334
+ expect(parseErrorMessageSpy).toHaveBeenCalled();
335
+ });
336
+ });
337
+ describe('#ngOnDestroy', () => {
338
+ it('should unsubscribe on ngOnDestroy', () => {
339
+ spyOn(component.destroy$, 'next');
340
+ spyOn(component.destroy$, 'unsubscribe');
341
+ component.ngOnDestroy();
342
+ expect(component.destroy$.next).toHaveBeenCalledWith(true);
343
+ expect(component.destroy$.unsubscribe).toHaveBeenCalled();
344
+ });
345
+ });
346
+ });
@@ -0,0 +1,321 @@
1
+ import {
2
+ Component,
3
+ EventEmitter,
4
+ OnDestroy,
5
+ OnInit,
6
+ Output,
7
+ ViewChild,
8
+ ViewEncapsulation,
9
+ } from '@angular/core';
10
+ import { CommonModule } from '@angular/common';
11
+ import { Subject, takeUntil } from 'rxjs';
12
+ import * as screenTexts from '../../assets/constants.json';
13
+ import { FormGroup, Validators } from '@angular/forms';
14
+ import {
15
+ AlignType,
16
+ DynamicFormComponent,
17
+ FieldConfig,
18
+ FormControlType,
19
+ FormGrid,
20
+ FormModel,
21
+ SelectOption,
22
+ } from '@ieeesa-npm/presentation';
23
+ import { TenantApplicationsService } from '../../services/tenant-applications.service';
24
+ import { FormStatus, SharedService } from '@ieeesa-npm/shared';
25
+ import { TenantFunctionType } from '../../models/tenant-function-type.model';
26
+ import { TenantBasicInfo } from '../../models/tenant.model';
27
+ import {
28
+ RoleDetails,
29
+ Role,
30
+ CreateModifyRoleRequestPayload,
31
+ CreateModifyRoleResponse,
32
+ } from '../../models/roles-and-permissions.model';
33
+ import { RoleTypeOption } from '../../models/role-type.model';
34
+ import { RolesValidation } from '../../assets/tenant-validations';
35
+ import { AlertType, GlobalErrorHandlerService } from '@ieeesa-npm/utility';
36
+ import { HttpErrorResponse } from '@angular/common/http';
37
+ @Component({
38
+ selector: 'ieeesa-create-modify-role',
39
+ standalone: true,
40
+ imports: [CommonModule, DynamicFormComponent],
41
+ templateUrl: './create-modify-role.component.html',
42
+ styleUrls: ['./create-modify-role.component.scss'],
43
+ encapsulation: ViewEncapsulation.None,
44
+ })
45
+ export class CreateModifyRoleComponent implements OnInit, OnDestroy {
46
+ destroy$ = new Subject<boolean>();
47
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
48
+ constants: any = screenTexts;
49
+ createRoleTexts = this.constants?.createRole;
50
+ leftButtonLabel = this.createRoleTexts?.label?.leftButtonLabel;
51
+ rightButtonLabel = this.createRoleTexts?.label?.rightButtonLabel;
52
+ colWidth: FormGrid = { xs: 12, xl: 12, sm: 12, md: 12, lg: 12 };
53
+ createRoleFormGroup!: FormModel;
54
+ createModifyRoleFormGroupRef!: FormGroup;
55
+ actionButtonAlign = AlignType.LEFT;
56
+ @ViewChild(DynamicFormComponent)
57
+ dynamicFormComponent!: DynamicFormComponent;
58
+ @Output() submitFormResponse = new EventEmitter();
59
+ @Output() formCancel = new EventEmitter();
60
+ tenantFunctionType!: TenantFunctionType;
61
+ selectedTenantInfo!: TenantBasicInfo | undefined;
62
+ createModifyRolePayload!: CreateModifyRoleRequestPayload;
63
+ roleTypeOptions!: SelectOption[];
64
+ selectedRoleDetails!: RoleDetails;
65
+ selectedRole!: Role;
66
+ constructor(
67
+ // eslint-disable-next-line no-unused-vars
68
+ private tenantAppService: TenantApplicationsService,
69
+ // eslint-disable-next-line no-unused-vars
70
+ private sharedService: SharedService,
71
+ // eslint-disable-next-line no-unused-vars
72
+ private globalErrorHandlerService: GlobalErrorHandlerService // eslint-disable-next-line no-empty-function
73
+ ) {}
74
+
75
+ ngOnInit(): void {
76
+ this.tenantFunctionType = this.tenantAppService?.getTenantFunctionType();
77
+ this.selectedTenantInfo =
78
+ this.tenantAppService?.getSelectedTenantInformation();
79
+ this.roleTypeOptions =
80
+ this.tenantAppService?.getRoleTypeOption() as RoleTypeOption[];
81
+ this.selectedRoleDetails =
82
+ this.tenantAppService?.getSelectedRoleInformation() as Role;
83
+ if (this.selectedRoleDetails) {
84
+ this.selectedRole = this.tenantAppService?.roles?.find(
85
+ ({ roleId }) => roleId === this.selectedRoleDetails?.roleId
86
+ ) as Role;
87
+ }
88
+ this.initializeCreateRoleFormGroup();
89
+ }
90
+
91
+ /**
92
+ * Constructs and returns the role type form field based on credit or edit role.
93
+ * @return {FieldConfig} -role type form field.
94
+ * @memberof CreateModifyRoleComponent
95
+ */
96
+ getRoleTypeField(): FieldConfig {
97
+ let roleTypeField: FieldConfig;
98
+ if (this.tenantFunctionType === TenantFunctionType.EDIT_ROLE) {
99
+ roleTypeField = {
100
+ type: FormControlType?.TEXT_AREA,
101
+ label: this.createRoleTexts?.label?.roleType,
102
+ controlName: 'roleType',
103
+ isReadonly: true,
104
+ value: this.selectedRole?.roleTypeName,
105
+ ariaMultiline: false,
106
+ ariaLabel: this.createRoleTexts?.label?.ariaLabel?.roleType,
107
+ ariaDescribedById:
108
+ this.createRoleTexts?.label?.ariaDescribedById?.roleType,
109
+ isResize: true,
110
+ };
111
+ } else {
112
+ roleTypeField = {
113
+ type: FormControlType?.SELECT,
114
+ label: this.createRoleTexts?.label?.roleType + '*',
115
+ controlName: 'roleType',
116
+ isSortNeeded: false,
117
+ value: '',
118
+ validation: [Validators.required],
119
+ dropdownOptions: this.roleTypeOptions,
120
+ supportMessage: this.createRoleTexts?.supportText?.roleType,
121
+ requiredErrorMessage: this.createRoleTexts?.message?.error?.required,
122
+ ariaLabel: this.createRoleTexts?.label?.ariaLabel?.roleType,
123
+ ariaDescribedById:
124
+ this.createRoleTexts?.label?.ariaDescribedById?.roleType,
125
+ };
126
+ }
127
+ return roleTypeField;
128
+ }
129
+ /**
130
+ * Initialize the create/edit role form group array.
131
+ * @memberof CreateModifyRoleComponent
132
+ */
133
+ initializeCreateRoleFormGroup(): void {
134
+ this.createRoleFormGroup = {
135
+ formGroup: [
136
+ {
137
+ legend: '',
138
+ controls: [
139
+ {
140
+ type: FormControlType.TEXT_AREA,
141
+ label: this.createRoleTexts?.label?.appTitle,
142
+ controlName: 'appTitle',
143
+ value: this.selectedTenantInfo?.appTitle,
144
+ ariaLabel: this.createRoleTexts?.label?.ariaLabel?.appTitle,
145
+ ariaDescribedById:
146
+ this.createRoleTexts?.label?.ariaDescribedById?.appTitle,
147
+ isReadonly: true,
148
+ ariaMultiline: false,
149
+ isResize: true,
150
+ },
151
+ this.getRoleTypeField(),
152
+ {
153
+ type: FormControlType.INPUT,
154
+ label: this.createRoleTexts?.label?.roleName + '*',
155
+ controlName: 'roleName',
156
+ value:
157
+ this.tenantFunctionType === TenantFunctionType.EDIT_ROLE
158
+ ? this.selectedRole?.roleName
159
+ : '',
160
+ validation: [
161
+ Validators.required,
162
+ Validators.maxLength(RolesValidation.roleNameMaxLength),
163
+ ],
164
+ supportMessage: this.createRoleTexts?.supportText?.roleName,
165
+ requiredErrorMessage:
166
+ this.createRoleTexts?.message?.error?.required,
167
+ maxErrorMessage:
168
+ this.createRoleTexts?.message?.error?.limit?.roleNameMaxChars,
169
+ ariaLabel: this.createRoleTexts?.label?.ariaLabel?.roleName,
170
+ ariaDescribedById:
171
+ this.createRoleTexts?.label?.ariaDescribedById?.roleName,
172
+ },
173
+ ],
174
+ },
175
+ ],
176
+ };
177
+ }
178
+ /**
179
+ * Gets create/edit role form group reference.
180
+ * @param {FormGroup[]} form
181
+ * @memberof CreateModifyRoleComponent
182
+ */
183
+ getCreateModifyRoleFormGroupRef(form: FormGroup[]): void {
184
+ this.createModifyRoleFormGroupRef = form[0];
185
+ }
186
+ /**
187
+ * Updates createModifyRoleFormGroupRef on add role form change event.
188
+ * @param {FormGroup[]} form
189
+ * @memberof CreateModifyRoleComponent
190
+ */
191
+ onCreateModifyRoleFormChange(form: FormGroup[]): void {
192
+ this.createModifyRoleFormGroupRef = form[0];
193
+ }
194
+ /**
195
+ * Creates a new role on form submission and the form is valid.
196
+ * @param {FormGroup[]} form
197
+ * @memberof CreateModifyRoleComponent
198
+ */
199
+ onCreateModifyRoleFormSubmit(form: FormGroup[]): void {
200
+ form[0]?.markAllAsTouched();
201
+ if (form[0].status === FormStatus.VALID) {
202
+ this.createModifyRolePayload = this.getCreateModifyRolePayload(
203
+ form[0].getRawValue()
204
+ );
205
+ // eslint-disable-next-line no-unused-expressions
206
+ this.tenantFunctionType === TenantFunctionType.EDIT_ROLE
207
+ ? this.editRole()
208
+ : this.createRole();
209
+ }
210
+ }
211
+ /**
212
+ * Constructs create/edit role payload from the form data and returns.
213
+ * @param {*} formData
214
+ * @return {CreateModifyRoleRequestPayload}
215
+ * @memberof CreateModifyRoleComponent
216
+ */
217
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
218
+ getCreateModifyRolePayload(formData: any): CreateModifyRoleRequestPayload {
219
+ const payload: CreateModifyRoleRequestPayload = {
220
+ payload: {
221
+ appId: this.selectedTenantInfo?.appId as string,
222
+ roleName: formData?.roleName,
223
+ },
224
+ };
225
+ if (this.tenantFunctionType === TenantFunctionType.EDIT_ROLE) {
226
+ payload.payload.roleId = this.selectedRole?.roleId;
227
+ } else {
228
+ payload.payload.roleType = formData?.roleType?.id;
229
+ }
230
+ return payload;
231
+ }
232
+ /**
233
+ * Post the creates new role form data to the server on form submission to create a new role.
234
+ * @param {CreateRoleRequestPayload} createModifyRolePayload
235
+ * @memberof CreateModifyRoleComponent
236
+ */
237
+ createRole(): void {
238
+ this.tenantAppService
239
+ .createRole(this.createModifyRolePayload)
240
+ .pipe(takeUntil(this.destroy$))
241
+ .subscribe({
242
+ next: (response: CreateModifyRoleResponse) => {
243
+ if (response.status) {
244
+ this.tenantAppService.setNewlyCreatedRoleInfo(
245
+ this.createModifyRolePayload?.payload
246
+ );
247
+ this.submitFormResponse.emit(response);
248
+ }
249
+ },
250
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
251
+ error: (error: any) => {
252
+ this.handleErrors(error);
253
+ },
254
+ });
255
+ }
256
+ /**
257
+ * Post the edited role form data to server on form submission to update the selected role information.
258
+ * @param {CreateModifyRoleRequestPayload} createModifyRolePayload
259
+ * @memberof CreateModifyRoleComponent
260
+ */
261
+ editRole(): void {
262
+ this.tenantAppService
263
+ .editRole(this.createModifyRolePayload)
264
+ .pipe(takeUntil(this.destroy$))
265
+ .subscribe({
266
+ next: (response: CreateModifyRoleResponse) => {
267
+ if (response.status) {
268
+ this.tenantAppService.setNewlyCreatedRoleInfo(
269
+ this.createModifyRolePayload?.payload
270
+ );
271
+ this.submitFormResponse.emit(response);
272
+ }
273
+ },
274
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
275
+ error: (error: any) => {
276
+ this.handleErrors(error);
277
+ },
278
+ });
279
+ }
280
+ /**
281
+ * Captures the server side errors and handles it based on the custom or Http errors.
282
+ * @param {HttpErrorResponse} error
283
+ * @return -returns nothing
284
+ * @memberof CreateModifyRoleComponent
285
+ */
286
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
287
+ handleErrors(error: any): void {
288
+ const errorCodes = error?.error?.body?.errorCodes;
289
+ if (Array.isArray(errorCodes) && !error?.error?.status) {
290
+ if (errorCodes[0] === '3012') {
291
+ const roleName = this.createModifyRolePayload?.payload?.roleName;
292
+ const errorMessage = this.sharedService?.parseErrorMessage(
293
+ errorCodes,
294
+ this.createRoleTexts?.errors
295
+ );
296
+ this.sharedService.showAlertMessage(
297
+ AlertType.ERROR,
298
+ `${roleName} ${errorMessage}`
299
+ );
300
+ }
301
+ } else if (error && error instanceof HttpErrorResponse) {
302
+ this.globalErrorHandlerService?.handleError(error);
303
+ }
304
+ }
305
+ /**
306
+ * Emits form cancel event.
307
+ * @memberof CreateModifyRoleComponent
308
+ */
309
+ onFormCancel(): void {
310
+ this.formCancel.emit();
311
+ }
312
+
313
+ /**
314
+ * Implementation of ngOnDestroy lifecycle hook method to unsubscribe the open observable subscriptions.
315
+ * @memberof CreateModifyRoleComponent
316
+ */
317
+ ngOnDestroy(): void {
318
+ this.destroy$.next(true);
319
+ this.destroy$.unsubscribe();
320
+ }
321
+ }
@@ -0,0 +1,18 @@
1
+ <ieeesa-dynamic-form
2
+ *ngIf="createTenantFormGroup"
3
+ class="ieeesa-create-tenant-form"
4
+ [leftButtonLabel]="leftButtonLabel"
5
+ [rightButtonLabel]="rightButtonLabel"
6
+ [isLegendVisible]="false"
7
+ [colWidth]="colWidth"
8
+ [actionButtonAlign]="actionButtonAlign"
9
+ [formGroups]="createTenantFormGroup"
10
+ [isLeftButtonNeeded]="true"
11
+ (formSubmit)="onCreateTenantFormSubmit($event)"
12
+ (formChange)="onCreateTenantFormChange($event)"
13
+ (formLeftButtonClicked)="onFormCancel()"
14
+ (formGroupsReference)="getCreateTenantFormGroupRef($event)"
15
+ (formFileUpload)="onFormFileUpload($event)"
16
+ (formColorPickerChange)="onColorPickerChange($event)"
17
+ (formRadioOptionSelected)="onRadioOptionSelected($event)"
18
+ ></ieeesa-dynamic-form>