LPXXX editor continued
authorBill Erickson <berickxx@gmail.com>
Fri, 22 Nov 2019 23:11:17 +0000 (18:11 -0500)
committerBill Erickson <berickxx@gmail.com>
Fri, 6 Dec 2019 15:37:03 +0000 (10:37 -0500)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/share/context-menu/context-menu.component.css
Open-ILS/src/eg2/src/app/share/context-menu/context-menu.component.html
Open-ILS/src/eg2/src/app/share/context-menu/context-menu.component.ts
Open-ILS/src/eg2/src/app/staff/share/marc-edit/editable-content.component.html
Open-ILS/src/eg2/src/app/staff/share/marc-edit/editable-content.component.ts
Open-ILS/src/eg2/src/app/staff/share/marc-edit/tagtable.service.ts
Open-ILS/src/eg2/src/styles.css

index d9f69a3..3323d2a 100644 (file)
@@ -1,19 +1,27 @@
 
-.context-menu {
+.eg-context-menu {
+  /* These fonts were applied specifically for the MARC editor
+   * context menus.  Might want to make these optional. */
   font-family: 'Lucida Console', Monaco, monospace;
+
+  /* put a hard limit on the popover width */
   max-width: 550px;
 }
 
-.context-menu .popover-body {
+.eg-context-menu .popover-body {
   max-height: 400px;
+
+  /* Text exceeding the max-height / max-width will results in scrolls.
+   * In most cases, this should not happen. */
   overflow-y: auto;
   overflow-x: auto;
 }
 
-.context-menu .popover-body .menu-entry {
+.eg-context-menu .popover-body .menu-entry {
+  /* force the menu to expand horizontally to display the text */
   white-space: nowrap;
 }
 
-.context-menu .popover-body .menu-entry:hover {
+.eg-context-menu .popover-body .menu-entry:hover {
   background-color: #f8f9fa; 
 }
index 999e1c1..d32159a 100644 (file)
@@ -1,6 +1,9 @@
 
 <ng-template #menuTemplate>
-  <div *ngFor="let entry of menuEntries" class="menu-entry {{entryClasses}}">
-    <a (click)="entryClicked(entry)"><span>{{entry.label}}</span></a>
+  <div *ngFor="let entry of menuEntries; first as isFirst" 
+    class="menu-entry {{entryClasses}}">
+    <a 
+      [attr.id]="isFirst ? randId : ''" 
+      (click)="entryClicked(entry)">{{entry.label}}</a>
   </div>
 </ng-template>
index aa3801c..df56b96 100644 (file)
@@ -1,5 +1,5 @@
-import {Component, Input, Output, OnInit, EventEmitter, Directive, ViewChild,
-    ViewEncapsulation, ComponentFactoryResolver, TemplateRef} from '@angular/core';
+import {Component, Input, Output, AfterViewInit, EventEmitter, Directive, ViewChild,
+    Renderer2, ViewEncapsulation, ComponentFactoryResolver, TemplateRef} from '@angular/core';
 import {NgbPopover} from '@ng-bootstrap/ng-bootstrap';
 
 /**
@@ -29,7 +29,7 @@ export interface ContextMenuEntry {
   encapsulation: ViewEncapsulation.None
 })
 
-export class ContextMenuComponent implements OnInit {
+export class ContextMenuComponent implements AfterViewInit {
 
     @Input() menuEntries: ContextMenuEntry[] = [];
 
@@ -38,15 +38,29 @@ export class ContextMenuComponent implements OnInit {
 
     @Output() entrySelected: EventEmitter<ContextMenuEntry>;
 
-    @ViewChild('menuTemplate', {static: false}) public menuTemplate: TemplateRef<any>;
+    @ViewChild('menuTemplate', {static: false}) 
+        public menuTemplate: TemplateRef<any>;
 
-    constructor() {
+    randId = Math.floor(Math.random() * 10000000);
+
+    constructor(private renderer: Renderer2) {
         this.entrySelected = new EventEmitter<ContextMenuEntry>();
     }
 
-    ngOnInit() {}
+    ngAfterViewInit() {
+    }
+
+    grabFocus() {
+        // ARG TODO
+        const link = this.renderer.selectRootElement(`[id='${this.randId}']`);
+        setTimeout(() => {
+            console.log('focusing ', link);
+            link.focus();
+        }, 400);
+    }
 
     entryClicked(entry: ContextMenuEntry) {
+        console.log('emitting ', entry);
         this.entrySelected.emit(entry);
     }
 }
@@ -59,8 +73,8 @@ export class ContextMenuDirective extends NgbPopover {
 
     menuComp: ContextMenuComponent;
 
-    triggers = 'contextmenu';
-    popoverClass = 'context-menu';
+    triggers = 'contextmenu'; // TODO TODO
+    popoverClass = 'eg-context-menu';
 
     @Input() set egContextMenu(menuComp: ContextMenuComponent) {
         this.menuComp = menuComp;
@@ -71,11 +85,12 @@ export class ContextMenuDirective extends NgbPopover {
 
     open() {
 
-        // Note the popover will automatically close in most cases,
-        // but context menus typically preventDefault() from firing,
-        // which prevents right-click from closing existing menus.
+        // The popover will automatically close in most cases, but
+        // context menus preventDefault(), which prevents right-click on
+        // other context menus from firing the close operation. Or at
+        // least, that's my assumption.  This fixes it.
         if (ContextMenuDirective.activeMenu) {
-           ContextMenuDirective.activeMenu.close();
+            ContextMenuDirective.activeMenu.close();
         }
 
         if (!this.menuComp.menuEntries ||
@@ -85,7 +100,11 @@ export class ContextMenuDirective extends NgbPopover {
 
         this.ngbPopover = this.menuComp.menuTemplate;
         ContextMenuDirective.activeMenu = this;
+
         super.open();
+
+        // ARG TODO
+        setTimeout(() => this.menuComp.grabFocus());
     }
 }
 
index 40b8a59..ed6c64a 100644 (file)
@@ -1,6 +1,6 @@
 
 <eg-context-menu #contextMenu 
-  [menuEntries]="contextMenuEntries"
+  [menuEntries]="contextMenuEntries()"
   (entrySelected)="contextMenuChange($event.value)">
 </eg-context-menu>
 
index 75332bc..d3602c6 100644 (file)
@@ -41,8 +41,6 @@ export class EditableContentComponent implements OnInit, AfterViewInit {
     editInput: any; // <input/> or <div contenteditable/>
     maxLength: number = null;
 
-    contextMenuEntries: ContextMenuEntry[];
-
     constructor(
         private renderer: Renderer2,
         private tagTable: TagTableService) {}
@@ -97,8 +95,6 @@ export class EditableContentComponent implements OnInit, AfterViewInit {
             case 'sfc':
                 this.maxLength = 1;
                 this.watchForFocusRequests();
-                this.contextMenuEntries = 
-                    this.tagTable.getSubfieldCodes(this.field.tag);
                 break;
 
             case 'sfv':
@@ -108,6 +104,25 @@ export class EditableContentComponent implements OnInit, AfterViewInit {
         }
     }
 
+    // These are served dynamically to handle cases where a tag or
+    // subfield is modified in place.
+    contextMenuEntries(): ContextMenuEntry[] {
+        if (!this.field) { return; } // LDR tag
+
+        switch(this.fieldType) {
+            case 'tag': return [];
+
+            case 'sfc': 
+                return this.tagTable.getSubfieldCodes(this.field.tag);
+
+            case 'sfv': 
+                return this.tagTable.getSubfieldValues(
+                    this.field.tag, this.subfield[0]);
+        }
+
+        return null;
+    }
+
     getContent(): string {
         if (this.fieldText) { return this.fieldText; } // read-only
 
@@ -323,7 +338,6 @@ export class EditableContentComponent implements OnInit, AfterViewInit {
         evt.preventDefault();
     }
 
-
     contextMenuChange(value: string) {
         this.setContent(value);
     }
index 3a8513a..1896e75 100644 (file)
@@ -153,10 +153,11 @@ export class TagTableService {
         .forEach(sf => {
             sf.value_list.forEach(value => {
 
-                const label = (value.code == value.description) ?
-                    value.code : `${value.code}: ${value.description}`;
+                let label = value.description || value.code;
+                let code = value.code || label;
+                if (code !== label) { label = `${code}: ${label}`; }
 
-                list.push({value: value.code, label: label});
+                list.push({value: code, label: label});
             })
         });
 
index 53512d5..9c120cc 100644 (file)
@@ -220,24 +220,3 @@ body>.dropdown-menu {z-index: 2100;}
   color: black;
 }
 
-/* context menu styling requires reaching up into the popup,
- * which may not wo
-.context-menu {
-  font-family: 'Lucida Console', Monaco, monospace;
-  max-width: 550px;
-}
-
-.context-menu .popover-body {
-  max-height: 400px;
-  overflow-y: auto;
-  overflow-x: auto;
-}
-
-.context-menu .popover-body .menu-entry {
-  white-space: nowrap;
-}
-
-.context-menu .popover-body .menu-entry:hover {
-  background-color: #f8f9fa; 
-}
-*/