[ACS-10222] Fixed reaching visibility dropdown for libraries using Tab key (#4897)

This commit is contained in:
AleksanderSklorz
2025-11-20 15:23:38 +01:00
committed by GitHub
parent 24c5b35ee4
commit 964d2e8cea
3 changed files with 50 additions and 13 deletions
@@ -5,9 +5,9 @@
<mat-form-field floatLabel="auto" data-automation-id="library-name-properties-wrapper" class="app-library-metadata-form-field">
<mat-label class="app-library-metadata-form-field-label">{{ 'LIBRARY.DIALOG.FORM.NAME' | translate }}</mat-label>
<input
#libraryNameInput
data-automation-id="app-library-metadata-form-name-input"
matInput
[cdkTrapFocusAutoCapture]="form.enabled"
[cdkTrapFocus]="form.enabled"
required
placeholder="{{ 'LIBRARY.DIALOG.FORM.NAME' | translate }}"
formControlName="title"
@@ -54,14 +54,21 @@
@if (canUpdateLibrary) {
<mat-card-actions align="end">
@if (form.enabled) {
<button mat-button (click)="cancel()">
<button
data-automation-id="app-library-metadata-form-cancel-button"
mat-button
(click)="cancel()">
{{ 'LIBRARY.DIALOG.CANCEL' | translate }}
</button>
<button mat-button color="primary" [disabled]="form.invalid || form.pristine" (click)="update()">
{{ 'LIBRARY.DIALOG.UPDATE' | translate }}
</button>
} @else {
<button mat-button color="primary" (click)="toggleEdit()">
<button
mat-button
color="primary"
(click)="toggleEdit()"
data-automation-id="app-library-metadata-form-edit-button">
{{ 'LIBRARY.DIALOG.EDIT' | translate }}
</button>
}
@@ -31,6 +31,8 @@ import { AppTestingModule } from '../../../testing/app-testing.module';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { Site, SiteBodyCreate, SiteEntry, SitePaging } from '@alfresco/js-api';
import { of, Subject } from 'rxjs';
import { UnitTestingUtils } from '@alfresco/adf-core';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
describe('LibraryMetadataFormComponent', () => {
let fixture: ComponentFixture<LibraryMetadataFormComponent>;
@@ -38,6 +40,11 @@ describe('LibraryMetadataFormComponent', () => {
let store: Store<any>;
let siteEntryModel: SiteBodyCreate;
let appHookService: AppHookService;
let unitTestingUtils: UnitTestingUtils;
const getNameInput = (): HTMLInputElement => unitTestingUtils.getInputByDataAutomationId('app-library-metadata-form-name-input');
const clickEditButton = (): Promise<void> => unitTestingUtils.clickMatButtonByDataAutomationId('app-library-metadata-form-edit-button');
beforeEach(() => {
TestBed.configureTestingModule({
@@ -77,6 +84,7 @@ describe('LibraryMetadataFormComponent', () => {
...siteEntryModel
} as Site
};
unitTestingUtils = new UnitTestingUtils(fixture.debugElement, TestbedHarnessEnvironment.loader(fixture));
});
it('should initialize form with node data', () => {
@@ -159,7 +167,7 @@ describe('LibraryMetadataFormComponent', () => {
component.node.entry.role = Site.RoleEnum.SiteManager;
siteEntryModel.title = ' some title ';
component.node.entry.title = siteEntryModel.title;
component.ngOnInit();
fixture.detectChanges();
component.toggleEdit();
component.update();
@@ -176,7 +184,7 @@ describe('LibraryMetadataFormComponent', () => {
it('should call markAsPristine on form when updating valid form and has permission to update', () => {
component.node.entry.role = Site.RoleEnum.SiteManager;
spyOn(component.form, 'markAsPristine');
component.ngOnInit();
fixture.detectChanges();
component.toggleEdit();
component.update();
@@ -209,7 +217,7 @@ describe('LibraryMetadataFormComponent', () => {
it('should not call markAsPristine on form when updating valid form but has not permission to update', () => {
component.node.entry.role = Site.RoleEnum.SiteConsumer;
spyOn(component.form, 'markAsPristine');
component.ngOnInit();
fixture.detectChanges();
component.toggleEdit();
component.update();
@@ -233,7 +241,7 @@ describe('LibraryMetadataFormComponent', () => {
component.node.entry.role = Site.RoleEnum.SiteManager;
spyOn(component.form, 'markAsPristine');
spyOnProperty(component.form, 'valid').and.returnValue(false);
component.ngOnInit();
fixture.detectChanges();
component.toggleEdit();
component.update();
@@ -250,7 +258,7 @@ describe('LibraryMetadataFormComponent', () => {
});
it('should enable form without id field after calling toggleEdit if form was disabled', () => {
component.toggleEdit();
fixture.detectChanges();
spyOn(component.form, 'enable');
spyOn(component.form.controls.id, 'disable');
@@ -261,6 +269,27 @@ describe('LibraryMetadataFormComponent', () => {
expect(component.form.controls.id.disable).toHaveBeenCalled();
});
it('should call focus on name input after clicking on edit button', async () => {
component.node.entry.role = Site.RoleEnum.SiteManager;
fixture.detectChanges();
const nameInput = getNameInput();
spyOn(nameInput, 'focus');
await clickEditButton();
expect(nameInput.focus).toHaveBeenCalled();
});
it('should not call focus on name input after clicking on cancel button', async () => {
component.node.entry.role = Site.RoleEnum.SiteManager;
fixture.detectChanges();
await clickEditButton();
const nameInput = getNameInput();
spyOn(nameInput, 'focus');
await unitTestingUtils.clickMatButtonByDataAutomationId('app-library-metadata-form-cancel-button');
expect(nameInput.focus).not.toHaveBeenCalled();
});
it('should cancel from changes', () => {
fixture.detectChanges();
component.toggleEdit();
@@ -348,7 +377,7 @@ describe('LibraryMetadataFormComponent', () => {
}));
it('should set proper titleErrorTranslationKey when there is error for empty title', () => {
component.ngOnInit();
fixture.detectChanges();
component.toggleEdit();
component.form.controls.title.setValue(' ');
@@ -22,7 +22,7 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, DestroyRef, inject, Input, OnChanges, OnInit, ViewEncapsulation } from '@angular/core';
import { Component, DestroyRef, ElementRef, inject, Input, OnChanges, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import {
FormControl,
FormGroupDirective,
@@ -47,7 +47,6 @@ import { TranslatePipe } from '@ngx-translate/core';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatSelectModule } from '@angular/material/select';
import { MatInputModule } from '@angular/material/input';
import { A11yModule } from '@angular/cdk/a11y';
import { MatButtonModule } from '@angular/material/button';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { NgForOf } from '@angular/common';
@@ -69,7 +68,6 @@ export class InstantErrorStateMatcher implements ErrorStateMatcher {
MatSelectModule,
MatOptionModule,
MatInputModule,
A11yModule,
MatButtonModule,
NgForOf
],
@@ -113,6 +111,8 @@ export class LibraryMetadataFormComponent implements OnInit, OnChanges {
canUpdateLibrary = false;
isAdmin = false;
@ViewChild('libraryNameInput')
private readonly libraryNameInput: ElementRef<HTMLInputElement>;
private readonly destroyRef = inject(DestroyRef);
constructor(
@@ -131,6 +131,7 @@ export class LibraryMetadataFormComponent implements OnInit, OnChanges {
emitEvent: false
});
this.form.controls.id.disable();
this.libraryNameInput.nativeElement.focus();
}
}