From: Bill Erickson Date: Sun, 15 Apr 2018 15:00:44 +0000 (+0000) Subject: LP#1626157 more accesskeys X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=0e17d80c06d6767dc7b58be7671894a34e290838;p=working%2FEvergreen.git LP#1626157 more accesskeys Signed-off-by: Bill Erickson --- diff --git a/Open-ILS/src/eg2/src/app/share/accesskey/accesskey-info.component.html b/Open-ILS/src/eg2/src/app/share/accesskey/accesskey-info.component.html new file mode 100644 index 0000000000..b68129b9ca --- /dev/null +++ b/Open-ILS/src/eg2/src/app/share/accesskey/accesskey-info.component.html @@ -0,0 +1,24 @@ + + + + + diff --git a/Open-ILS/src/eg2/src/app/share/accesskey/accesskey-info.component.ts b/Open-ILS/src/eg2/src/app/share/accesskey/accesskey-info.component.ts new file mode 100644 index 0000000000..d74d7a1514 --- /dev/null +++ b/Open-ILS/src/eg2/src/app/share/accesskey/accesskey-info.component.ts @@ -0,0 +1,26 @@ +/** + */ +import {Component, Input, OnInit} from '@angular/core'; +import {EgAccessKeyService} from '@eg/share/accesskey/accesskey.service'; +import {EgDialogComponent} from '@eg/share/dialog/dialog.component'; +import {NgbModal} from '@ng-bootstrap/ng-bootstrap'; + +@Component({ + selector: 'eg-accesskey-info', + templateUrl: './accesskey-info.component.html' +}) +export class EgAccessKeyInfoComponent extends EgDialogComponent { + + constructor( + // NgbModal import required for subclassing with a constructor. + private modal: NgbModal, + private keyService: EgAccessKeyService) { + super(modal); + } + + assignments(): any[] { + return this.keyService.infoIze(); + } +} + + diff --git a/Open-ILS/src/eg2/src/app/share/accesskey/accesskey.directive.ts b/Open-ILS/src/eg2/src/app/share/accesskey/accesskey.directive.ts index 440b312c6e..db75b4ff5b 100644 --- a/Open-ILS/src/eg2/src/app/share/accesskey/accesskey.directive.ts +++ b/Open-ILS/src/eg2/src/app/share/accesskey/accesskey.directive.ts @@ -1,8 +1,13 @@ /** - * Allows for in-template hotkey configuration. Reads hotkey maps and - * passes them off to the hotkey service. + * Assign access keys from within templates via tags. + * Both href and routerLink attributes are supported. * - * Listens and responds to global keyboard events. + * */ import {Directive, ElementRef, Input, OnInit} from '@angular/core'; import {EgAccessKeyService} from '@eg/share/accesskey/accesskey.service'; @@ -11,19 +16,26 @@ import {EgAccessKeyService} from '@eg/share/accesskey/accesskey.service'; selector: '[egAccessKey]' }) export class EgAccessKeyDirective implements OnInit { + + @Input() keySpec: string; + @Input() keyDesc: string; constructor( private elm: ElementRef, private keyService: EgAccessKeyService ) { } - @Input() keySpec: string; - @Input() keyDesc: string; ngOnInit() { - - console.debug(`Assigning access key '${this.keySpec}' => ${this.keyDesc}`); - } + console.debug( + `EgAccessKey assigning '${this.keySpec}' => ${this.keyDesc}`); + this.keyService.assign({ + key: this.keySpec, + desc: this.keyDesc, + action: () => {this.elm.nativeElement.click()} + }); + } } + diff --git a/Open-ILS/src/eg2/src/app/share/accesskey/accesskey.service.ts b/Open-ILS/src/eg2/src/app/share/accesskey/accesskey.service.ts index 82f7395eca..e0e1b0b22c 100644 --- a/Open-ILS/src/eg2/src/app/share/accesskey/accesskey.service.ts +++ b/Open-ILS/src/eg2/src/app/share/accesskey/accesskey.service.ts @@ -2,17 +2,62 @@ import {Injectable, EventEmitter, HostListener} from '@angular/core'; export interface EgAccessKeyAssignment { key: string, - action: () => void + desc: string, + action: Function }; @Injectable() export class EgAccessKeyService { - handlers: {[key: string] : Function} = {}; + // Assignments stored as an array with most recently assigned + // items toward the front. Most recent items have precedence. + assignments: EgAccessKeyAssignment[] = []; constructor() {} + assign(assn: EgAccessKeyAssignment): void { + this.assignments.unshift(assn); + } + + /** + * Compress a set of single-fire keyboard events into single + * string. For example: Control and 't' becomes 'ctrl+t'. + */ + compressKeys(evt: KeyboardEvent): string { + + let s = ''; + if (evt.ctrlKey || evt.metaKey) s += 'ctrl+'; + if (evt.altKey) s += 'alt+'; + s += String.fromCharCode(evt.keyCode).toLowerCase(); + + return s; + } + + /** + * Checks for a key assignment and fires the assigned action. + */ fire(evt: KeyboardEvent): void { + let keySpec = this.compressKeys(evt); + for (let i in this.assignments) { // for-loop to exit early + if (keySpec == this.assignments[i].key) { + let assign = this.assignments[i]; + console.debug(`EgAccessKey assignment found for ${assign.key}`); + assign.action(); + evt.preventDefault(); + return; + } + } + } + + /** + * Returns a simplified key assignment list containing just + * the key spec and the description. Useful for inspecting + * without exposing the actions. + */ + infoIze(): any[] { + return this.assignments.map(a => { + return {key: a.key, desc: a.desc}; + }); } } diff --git a/Open-ILS/src/eg2/src/app/share/dialog/dialog.component.ts b/Open-ILS/src/eg2/src/app/share/dialog/dialog.component.ts index 397a6db4a7..4389eb6d19 100644 --- a/Open-ILS/src/eg2/src/app/share/dialog/dialog.component.ts +++ b/Open-ILS/src/eg2/src/app/share/dialog/dialog.component.ts @@ -28,7 +28,9 @@ export class EgDialogComponent { open(): Promise { if (this.modalRef !== null) { - console.error('Dismissing existing dialog!'); + //This can happen when a dialog is dismissed by clicking + //outside of the modal. Avoid treating it like an error. + //console.debug('Dismissing existing dialog!'); this.dismiss(); } diff --git a/Open-ILS/src/eg2/src/app/staff/common.module.ts b/Open-ILS/src/eg2/src/app/staff/common.module.ts index cddd063ed7..82529f4955 100644 --- a/Open-ILS/src/eg2/src/app/staff/common.module.ts +++ b/Open-ILS/src/eg2/src/app/staff/common.module.ts @@ -7,6 +7,7 @@ import {EgConfirmDialogComponent} from '@eg/share/dialog/confirm.component'; import {EgPromptDialogComponent} from '@eg/share/dialog/prompt.component'; import {EgAccessKeyDirective} from '@eg/share/accesskey/accesskey.directive'; import {EgAccessKeyService} from '@eg/share/accesskey/accesskey.service'; +import {EgAccessKeyInfoComponent} from '@eg/share/accesskey/accesskey-info.component'; /** * Imports the EG common modules and adds modules common to all staff UI's. @@ -19,7 +20,8 @@ import {EgAccessKeyService} from '@eg/share/accesskey/accesskey.service'; EgDialogComponent, EgConfirmDialogComponent, EgPromptDialogComponent, - EgAccessKeyDirective + EgAccessKeyDirective, + EgAccessKeyInfoComponent ], imports: [ EgCommonModule @@ -31,7 +33,8 @@ import {EgAccessKeyService} from '@eg/share/accesskey/accesskey.service'; EgDialogComponent, EgConfirmDialogComponent, EgPromptDialogComponent, - EgAccessKeyDirective + EgAccessKeyDirective, + EgAccessKeyInfoComponent ] }) diff --git a/Open-ILS/src/eg2/src/app/staff/nav.component.html b/Open-ILS/src/eg2/src/app/staff/nav.component.html index 803e173730..9b5d9c20d2 100644 --- a/Open-ILS/src/eg2/src/app/staff/nav.component.html +++ b/Open-ILS/src/eg2/src/app/staff/nav.component.html @@ -2,7 +2,11 @@