diff --git a/src/app/adf-roles/df-role-details/df-role-details.component.ts b/src/app/adf-roles/df-role-details/df-role-details.component.ts index a52d768b2..e27a5d42f 100644 --- a/src/app/adf-roles/df-role-details/df-role-details.component.ts +++ b/src/app/adf-roles/df-role-details/df-role-details.component.ts @@ -259,9 +259,62 @@ export class DfRoleDetailsComponent implements OnInit { } onSubmit() { - if (this.roleForm.invalid) return; + // Clear validators for all hidden items before validation + const serviceAccess = this.roleForm.get('serviceAccess') as FormArray; + serviceAccess.controls.forEach((control, index) => { + if (!this.visibilityArray[index]) { + console.log(`Clearing validators for hidden item at index ${index}`); + control.get('service')?.clearValidators(); + control.get('component')?.clearValidators(); + control.get('access')?.clearValidators(); + control.get('requester')?.clearValidators(); + control.get('service')?.updateValueAndValidity(); + control.get('component')?.updateValueAndValidity(); + control.get('access')?.updateValueAndValidity(); + control.get('requester')?.updateValueAndValidity(); + } + }); + + if (this.roleForm.invalid) { + // Mark all controls as touched to show validation errors + this.roleForm.markAllAsTouched(); + + console.log('Form is invalid:', this.roleForm.errors); + console.log('Form controls validity:', { + name: this.roleForm.get('name')?.errors, + description: this.roleForm.get('description')?.errors, + active: this.roleForm.get('active')?.errors, + serviceAccess: this.roleForm.get('serviceAccess')?.errors, + lookupKeys: this.roleForm.get('lookupKeys')?.errors, + }); + + serviceAccess.controls.forEach((control, index) => { + console.log(`ServiceAccess[${index}] valid:`, control.valid, 'visibility:', this.visibilityArray[index]); + if (control.invalid) { + console.log(`ServiceAccess[${index}] errors:`, control.errors); + console.log(`ServiceAccess[${index}] controls errors:`, { + service: control.get('service')?.errors, + component: control.get('component')?.errors, + access: control.get('access')?.errors, + requester: control.get('requester')?.errors, + }); + console.log(`ServiceAccess[${index}] controls valid:`, { + service: control.get('service')?.valid, + component: control.get('component')?.valid, + access: control.get('access')?.valid, + requester: control.get('requester')?.valid, + }); + console.log(`ServiceAccess[${index}] values:`, control.value); + } + }); + + return; + } const formValue = this.roleForm.getRawValue(); - if (formValue.name === '' || formValue.name === null) return; + if (formValue.name === '' || formValue.name === null) { + console.log('Form name is empty'); + return; + } const payload: RolePayload = { id: formValue.id, name: formValue.name, diff --git a/src/app/adf-roles/df-roles-access/df-roles-access.component.html b/src/app/adf-roles/df-roles-access/df-roles-access.component.html index f1633c5c4..c755ea6de 100644 --- a/src/app/adf-roles/df-roles-access/df-roles-access.component.html +++ b/src/app/adf-roles/df-roles-access/df-roles-access.component.html @@ -21,7 +21,7 @@ + [formGroupName]="getFormArrayIndex(i)"> {{ 'roles.accessOverview.tableHeadings.service' | transloco @@ -29,7 +29,8 @@ + (selectionChange)="getComponents(getFormArrayIndex(i))" + required> All {{ option.name }} + + Service is required + @@ -48,18 +52,21 @@ + [formGroupName]="getFormArrayIndex(i)"> {{ 'roles.accessOverview.tableHeadings.component' | transloco }} - + {{ option }} + + Component is required + @@ -71,7 +78,7 @@ + [formGroupName]="getFormArrayIndex(i)"> {{ 'roles.accessOverview.tableHeadings.access' | transloco @@ -80,7 +87,8 @@ formControlName="access" multiple panelWidth="null" - (selectionChange)="accessChange(i, $event.value)"> + (selectionChange)="accessChange(getFormArrayIndex(i), $event.value)" + required> (+{{ - (formArray.controls[i].value.access.length || 0) - 1 + (formArray.controls[getFormArrayIndex(i)]?.value.access.length || 0) - 1 }} {{ - formArray.controls[i].value.access.length === 2 + formArray.controls[getFormArrayIndex(i)]?.value.access.length === 2 ? 'other' : 'others' }}) + + Access is required + @@ -112,7 +123,7 @@ + [formGroupName]="getFormArrayIndex(i)"> {{ 'roles.accessOverview.tableHeadings.requester' | transloco @@ -140,12 +151,12 @@ + [formGroupName]="getFormArrayIndex(i)"> @@ -165,7 +176,7 @@ + [formGroupName]="getFormArrayIndex(i)"> @@ -177,7 +188,7 @@ mat-cell *matCellDef="let element; let i = dataIndex" [attr.colspan]="6" - [formGroupName]="i"> + [formGroupName]="getFormArrayIndex(i)">
@@ -220,7 +231,7 @@ + (change)="filterOpChange($event, getFormArrayIndex(i))"> AND OR @@ -229,13 +240,13 @@
diff --git a/src/app/adf-roles/df-roles-access/df-roles-access.component.ts b/src/app/adf-roles/df-roles-access/df-roles-access.component.ts index 64c7eeea8..88f78c961 100644 --- a/src/app/adf-roles/df-roles-access/df-roles-access.component.ts +++ b/src/app/adf-roles/df-roles-access/df-roles-access.component.ts @@ -204,6 +204,19 @@ export class DfRolesAccessComponent implements OnInit { return components || []; } + getFormArrayIndex(visibleIndex: number): number { + let visibleCount = 0; + for (let i = 0; i < this.visible.length; i++) { + if (this.visible[i]) { + if (visibleCount === visibleIndex) { + return i; + } + visibleCount++; + } + } + return -1; + } + filterOptions(event: Event, index: number) { const input = (event.target as HTMLInputElement).value.toLowerCase(); const serviceId = this.formArray.at(index).get('service')?.value; @@ -294,6 +307,7 @@ export class DfRolesAccessComponent implements OnInit { }) ); this.visible.push(true); + console.log('FormArray after add:', this.formArray.value, 'Visible:', this.visible); this.updateDataSource(); } @@ -323,9 +337,40 @@ export class DfRolesAccessComponent implements OnInit { } remove(index: number) { + console.log('Remove called with index:', index, 'Visible array before:', [...this.visible]); if (index >= 0 && index < this.formArray.length) { + // Find the actual form array index for the nth visible item BEFORE updating visible array + let visibleCount = 0; + let actualIndex = -1; + for (let i = 0; i < this.visible.length; i++) { + if (this.visible[i]) { + if (visibleCount === index) { + actualIndex = i; + break; + } + visibleCount++; + } + } + console.log('Actual form array index to hide:', actualIndex); + this.visible = this.updateNthTrueToFalse(this.visible, index); + + // Clear validators for the hidden item + if (actualIndex !== -1 && actualIndex < this.formArray.length) { + const formGroup = this.formArray.at(actualIndex); + console.log('Clearing validators for form group at index:', actualIndex); + formGroup.get('service')?.clearValidators(); + formGroup.get('component')?.clearValidators(); + formGroup.get('access')?.clearValidators(); + formGroup.get('requester')?.clearValidators(); + formGroup.get('service')?.updateValueAndValidity(); + formGroup.get('component')?.updateValueAndValidity(); + formGroup.get('access')?.updateValueAndValidity(); + formGroup.get('requester')?.updateValueAndValidity(); + console.log('Form group validity after clearing:', formGroup.valid); + } } + console.log('FormArray after remove:', this.formArray.value, 'Visible:', this.visible); this.updateDataSource(); }