mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-09 09:58:20 -05:00
Fix ngbDropdown stealing keyboard events
This commit is contained in:
parent
c6e7d06bb7
commit
b403b9d9d5
@ -36,7 +36,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="btn-group ms-auto">
|
<div class="btn-group ms-auto">
|
||||||
<button #primaryButton type="button" class="btn btn-sm btn-outline-primary d-flex"
|
<button #primaryButton type="button" class="btn btn-sm btn-outline-primary d-flex"
|
||||||
(click)="primaryAction(type, item); $event.stopPropagation()"
|
(click)="primaryAction(type, item); $event.stopImmediatePropagation()"
|
||||||
|
(keydown)="onButtonKeyDown($event)"
|
||||||
[disabled]="disablePrimaryButton(type, item)"
|
[disabled]="disablePrimaryButton(type, item)"
|
||||||
(mouseenter)="onButtonHover($event)">
|
(mouseenter)="onButtonHover($event)">
|
||||||
@if (type === DataType.Document) {
|
@if (type === DataType.Document) {
|
||||||
@ -55,7 +56,8 @@
|
|||||||
</button>
|
</button>
|
||||||
@if (type !== DataType.SavedView && type !== DataType.Workflow && type !== DataType.CustomField && type !== DataType.Group && type !== DataType.User && type !== DataType.MailAccount && type !== DataType.MailRule) {
|
@if (type !== DataType.SavedView && type !== DataType.Workflow && type !== DataType.CustomField && type !== DataType.Group && type !== DataType.User && type !== DataType.MailAccount && type !== DataType.MailRule) {
|
||||||
<button #secondaryButton type="button" class="btn btn-sm btn-outline-primary d-flex"
|
<button #secondaryButton type="button" class="btn btn-sm btn-outline-primary d-flex"
|
||||||
(click)="secondaryAction(type, item); $event.stopPropagation()"
|
(click)="secondaryAction(type, item); $event.stopImmediatePropagation()"
|
||||||
|
(keydown)="onButtonKeyDown($event)"
|
||||||
[disabled]="disableSecondaryButton(type, item)"
|
[disabled]="disableSecondaryButton(type, item)"
|
||||||
(mouseenter)="onButtonHover($event)">
|
(mouseenter)="onButtonHover($event)">
|
||||||
@if (type === DataType.Document) {
|
@if (type === DataType.Document) {
|
||||||
@ -71,7 +73,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<div ngbDropdownMenu class="w-100 mh-75 overflow-y-scroll shadow-lg" (keydown)="dropdownKeyDown($event)">
|
<div ngbDropdownMenu class="w-100 mh-75 overflow-y-scroll shadow-lg">
|
||||||
|
<div (keydown)="dropdownKeyDown($event)">
|
||||||
@if (searchResults?.total === 0) {
|
@if (searchResults?.total === 0) {
|
||||||
<h6 class="dropdown-header" i18n="@@searchResults.noResults">No results</h6>
|
<h6 class="dropdown-header" i18n="@@searchResults.noResults">No results</h6>
|
||||||
} @else {
|
} @else {
|
||||||
@ -158,6 +161,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -442,6 +442,13 @@ describe('GlobalSearchComponent', () => {
|
|||||||
expect(focusSpy).toHaveBeenCalled()
|
expect(focusSpy).toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should prevent event propagation for keyboard events on buttons that are not arrows', () => {
|
||||||
|
const event = { stopImmediatePropagation: jest.fn(), key: 'Enter' }
|
||||||
|
const stopPropagationSpy = jest.spyOn(event, 'stopImmediatePropagation')
|
||||||
|
component.onButtonKeyDown(event as any)
|
||||||
|
expect(stopPropagationSpy).toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
it('should support explicit advanced search', () => {
|
it('should support explicit advanced search', () => {
|
||||||
const qfSpy = jest.spyOn(documentListViewService, 'quickFilter')
|
const qfSpy = jest.spyOn(documentListViewService, 'quickFilter')
|
||||||
component.query = 'test'
|
component.query = 'test'
|
||||||
|
@ -292,6 +292,7 @@ export class GlobalSearchComponent implements OnInit {
|
|||||||
) {
|
) {
|
||||||
if (event.key === 'ArrowDown') {
|
if (event.key === 'ArrowDown') {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
event.stopImmediatePropagation()
|
||||||
if (this.currentItemIndex < this.searchResults.total - 1) {
|
if (this.currentItemIndex < this.searchResults.total - 1) {
|
||||||
this.currentItemIndex++
|
this.currentItemIndex++
|
||||||
this.setCurrentItem()
|
this.setCurrentItem()
|
||||||
@ -301,6 +302,7 @@ export class GlobalSearchComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
} else if (event.key === 'ArrowUp') {
|
} else if (event.key === 'ArrowUp') {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
event.stopImmediatePropagation()
|
||||||
if (this.currentItemIndex > 0) {
|
if (this.currentItemIndex > 0) {
|
||||||
this.currentItemIndex--
|
this.currentItemIndex--
|
||||||
this.setCurrentItem()
|
this.setCurrentItem()
|
||||||
@ -310,14 +312,25 @@ export class GlobalSearchComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
} else if (event.key === 'ArrowRight') {
|
} else if (event.key === 'ArrowRight') {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
event.stopImmediatePropagation()
|
||||||
this.secondaryButtons.get(this.domIndex)?.nativeElement.focus()
|
this.secondaryButtons.get(this.domIndex)?.nativeElement.focus()
|
||||||
} else if (event.key === 'ArrowLeft') {
|
} else if (event.key === 'ArrowLeft') {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
event.stopImmediatePropagation()
|
||||||
this.primaryButtons.get(this.domIndex).nativeElement.focus()
|
this.primaryButtons.get(this.domIndex).nativeElement.focus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onButtonKeyDown(event: KeyboardEvent) {
|
||||||
|
// prevents ngBootstrap issue with keydown events
|
||||||
|
if (
|
||||||
|
!['ArrowDown', 'ArrowUp', 'ArrowRight', 'ArrowLeft'].includes(event.key)
|
||||||
|
) {
|
||||||
|
event.stopImmediatePropagation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public onDropdownOpenChange(open: boolean) {
|
public onDropdownOpenChange(open: boolean) {
|
||||||
if (!open) {
|
if (!open) {
|
||||||
this.reset()
|
this.reset()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user