From 71e25653861c2d9228577e90c729a845145fe53c Mon Sep 17 00:00:00 2001
From: shamoon <4887959+shamoon@users.noreply.github.com>
Date: Fri, 18 Oct 2024 22:35:57 -0700
Subject: [PATCH] Enhancement: auto-focus default select field in custom field
dropdown (#7961)
---
...ustom-fields-query-dropdown.component.html | 2 +-
...om-fields-query-dropdown.component.spec.ts | 26 +++++++++++++--
.../custom-fields-query-dropdown.component.ts | 33 +++++++++++++++----
.../filter-editor.component.spec.ts | 18 +++++-----
4 files changed, 61 insertions(+), 18 deletions(-)
diff --git a/src-ui/src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html b/src-ui/src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html
index 9da2886f4..9cc095d7d 100644
--- a/src-ui/src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html
+++ b/src-ui/src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html
@@ -41,7 +41,7 @@
} @else if (getCustomFieldByID(atom.field)?.data_type === CustomFieldDataType.Select) {
- {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [CustomFieldsQueryDropdownComponent],
- imports: [NgbDropdownModule, NgxBootstrapIconsModule.pick(allIcons)],
+ imports: [
+ NgbDropdownModule,
+ NgxBootstrapIconsModule.pick(allIcons),
+ NgSelectModule,
+ FormsModule,
+ ReactiveFormsModule,
+ ],
providers: [
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
@@ -181,6 +194,15 @@ describe('CustomFieldsQueryDropdownComponent', () => {
expect(component.name).toBe('test_title')
})
+ it('should add a default atom on open and focus the select field', fakeAsync(() => {
+ expect(component.selectionModel.queries.length).toBe(0)
+ component.onOpenChange(true)
+ fixture.detectChanges()
+ tick()
+ expect(component.selectionModel.queries.length).toBe(1)
+ expect(window.document.activeElement.tagName).toBe('INPUT')
+ }))
+
describe('CustomFieldQueriesModel', () => {
let model: CustomFieldQueriesModel
diff --git a/src-ui/src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.ts b/src-ui/src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.ts
index 011ae1bc1..dbd269b3b 100644
--- a/src-ui/src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.ts
+++ b/src-ui/src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.ts
@@ -4,9 +4,12 @@ import {
Input,
OnDestroy,
Output,
+ QueryList,
ViewChild,
+ ViewChildren,
} from '@angular/core'
import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap'
+import { NgSelectComponent } from '@ng-select/ng-select'
import { Subject, first, takeUntil } from 'rxjs'
import { CustomField, CustomFieldDataType } from 'src/app/data/custom-field'
import {
@@ -184,6 +187,8 @@ export class CustomFieldsQueryDropdownComponent implements OnDestroy {
@ViewChild('dropdown') dropdown: NgbDropdown
+ @ViewChildren(NgSelectComponent) fieldSelects!: QueryList
+
private _selectionModel: CustomFieldQueriesModel
@Input()
@@ -227,16 +232,32 @@ export class CustomFieldsQueryDropdownComponent implements OnDestroy {
}
public onOpenChange(open: boolean) {
- if (open && this.selectionModel.queries.length === 0) {
- this.selectionModel.addExpression()
+ if (open) {
+ if (this.selectionModel.queries.length === 0) {
+ this.selectionModel.addAtom(
+ new CustomFieldQueryAtom([
+ null,
+ CustomFieldQueryOperator.Exists,
+ 'true',
+ ])
+ )
+ }
+ if (
+ this.selectionModel.queries.length === 1 &&
+ (
+ (this.selectionModel.queries[0] as CustomFieldQueryExpression)
+ ?.value[0] as CustomFieldQueryAtom
+ )?.field === null
+ ) {
+ setTimeout(() => {
+ this.fieldSelects.first?.focus()
+ }, 0)
+ }
}
}
public get isActive(): boolean {
- return (
- (this.selectionModel.queries[0] as CustomFieldQueryExpression)?.value
- ?.length > 0
- )
+ return this.selectionModel.isValid()
}
private getFields() {
diff --git a/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.spec.ts b/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.spec.ts
index 19a53f76c..402465d1b 100644
--- a/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.spec.ts
+++ b/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.spec.ts
@@ -101,7 +101,10 @@ import {
CustomFieldQueryLogicalOperator,
CustomFieldQueryOperator,
} from 'src/app/data/custom-field-query'
-import { CustomFieldQueryAtom } from 'src/app/utils/custom-field-query-element'
+import {
+ CustomFieldQueryAtom,
+ CustomFieldQueryExpression,
+} from 'src/app/utils/custom-field-query-element'
const tags: Tag[] = [
{
@@ -1441,15 +1444,12 @@ describe('FilterEditorComponent', () => {
By.css('button')
)
customFieldToggleButton.triggerEventHandler('click')
+ tick()
fixture.detectChanges()
- const customFieldButtons = customFieldsQueryDropdown.queryAll(
- By.css('button')
- )
- customFieldButtons[1].triggerEventHandler('click')
- fixture.detectChanges()
- const query = component.customFieldQueriesModel
- .queries[0] as CustomFieldQueryAtom
- query.field = custom_fields[0].id
+ const expression = component.customFieldQueriesModel
+ .queries[0] as CustomFieldQueryExpression
+ const atom = expression.value[0] as CustomFieldQueryAtom
+ atom.field = custom_fields[0].id
const fieldSelect: NgSelectComponent = customFieldsQueryDropdown.queryAll(
By.directive(NgSelectComponent)
)[0].componentInstance