LPXXX editor continued
authorBill Erickson <berickxx@gmail.com>
Fri, 22 Nov 2019 21:14:48 +0000 (16:14 -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>
12 files changed:
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.css
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/editor-context.ts
Open-ILS/src/eg2/src/app/staff/share/marc-edit/editor.component.ts
Open-ILS/src/eg2/src/app/staff/share/marc-edit/rich-editor.component.html
Open-ILS/src/eg2/src/app/staff/share/marc-edit/rich-editor.component.ts
Open-ILS/src/eg2/src/app/staff/share/marc-edit/tagtable.service.ts
Open-ILS/src/eg2/src/styles.css

index 88b31f2..d9f69a3 100644 (file)
@@ -1,20 +1,19 @@
 
-:host >>> .popover {
+.context-menu {
   font-family: 'Lucida Console', Monaco, monospace;
   max-width: 550px;
 }
 
-:host >>> .popover-body {
+.context-menu .popover-body {
   max-height: 400px;
   overflow-y: auto;
   overflow-x: auto;
 }
 
-:host >>> .popover-body .menu-entry {
+.context-menu .popover-body .menu-entry {
   white-space: nowrap;
 }
 
-:host >>> .popover-body .menu-entry:hover {
-  background-color: #f8f9fa; /* bootstrap color */
+.context-menu .popover-body .menu-entry:hover {
+  background-color: #f8f9fa; 
 }
-
index b9d301b..999e1c1 100644 (file)
@@ -1,29 +1,6 @@
 
 <ng-template #menuTemplate>
   <div *ngFor="let entry of menuEntries" class="menu-entry {{entryClasses}}">
-    <a (click)="entryClicked(entry)">
-      <span>{{entry.label}}</span>
-    </a>
+    <a (click)="entryClicked(entry)"><span>{{entry.label}}</span></a>
   </div>
 </ng-template>
-
-<!--
-<div class="form-inline d-flex">
-  <div class="flex-4">
-    <span id='label-{{randId}}' class="text-left font-weight-bold">
-      {{fieldLabel}}
-    </span>
-  </div>
-  <input 
-    [attr.aria-labelledby]="'label-' + randId"
-    class="form-control rounded-0 flex-5" type="text" 
-    (change)="valueChange()"
-    [(ngModel)]="fieldValue" 
-    [attr.maxlength]="fieldLength" [attr.size]="fieldLength"
-    [ngbPopover]="menuContent"
-    #p="ngbPopover" triggers="manual"
-    (contextmenu)="contextMenu($event, p)"
-    />
-</div>
--->
-
index 91938e6..aa3801c 100644 (file)
@@ -1,5 +1,5 @@
-import {Component, Input, Output, OnInit, EventEmitter, Directive, 
-    ComponentFactoryResolver, ViewChild, TemplateRef} from '@angular/core';
+import {Component, Input, Output, OnInit, EventEmitter, Directive, ViewChild,
+    ViewEncapsulation, ComponentFactoryResolver, TemplateRef} from '@angular/core';
 import {NgbPopover} from '@ng-bootstrap/ng-bootstrap';
 
 /**
@@ -23,7 +23,10 @@ export interface ContextMenuEntry {
 @Component({
   selector: 'eg-context-menu',
   templateUrl: './context-menu.component.html',
-  styleUrls: ['context-menu.component.css']
+  styleUrls: ['context-menu.component.css'],
+  /* Our CSS affects the style of the popover, which may 
+   * be beyond our reach for standard view encapsulation */
+  encapsulation: ViewEncapsulation.None
 })
 
 export class ContextMenuComponent implements OnInit {
@@ -57,6 +60,7 @@ export class ContextMenuDirective extends NgbPopover {
     menuComp: ContextMenuComponent;
 
     triggers = 'contextmenu';
+    popoverClass = 'context-menu';
 
     @Input() set egContextMenu(menuComp: ContextMenuComponent) {
         this.menuComp = menuComp;
index d84ad8a..7a1c050 100644 (file)
@@ -10,13 +10,13 @@ div[contenteditable] {
 
 .sf-delimiter { 
   /* match angjs color */
-  color: rgb(0, 0, 255); 
+  color: rgb(0, 0, 255)!important
   /* snuggle up to my subfield code */
   margin-right: -1rem; 
 }
 
 .sf-code { 
   /* match angjs color */
-  color: rgb(0, 0, 255); 
+  color: rgb(0, 0, 255)!important
 }
 
index bf326cf..40b8a59 100644 (file)
@@ -1,10 +1,16 @@
 
+<eg-context-menu #contextMenu 
+  [menuEntries]="contextMenuEntries"
+  (entrySelected)="contextMenuChange($event.value)">
+</eg-context-menu>
+
 <ng-container *ngIf="bigText">
   <div contenteditable
     id='{{randId}}' 
     spellcheck="false"
     class="d-inline-block p-1 pt-2 text-dark text-break {{moreClasses}}"
     [attr.tabindex]="fieldText ? -1 : ''"
+    [egContextMenu]="contextMenu"
     (keydown)="inputKeyDown($event)"
     (focus)="focusBigText()"
     (input)="bigTextValueChange()">
@@ -20,6 +26,7 @@
     [maxlength]="maxLength || ''"
     [disabled]="fieldText" 
     [attr.tabindex]="fieldText ? -1 : ''"
+    [egContextMenu]="contextMenu"
     (keydown)="inputKeyDown($event)"
     (focus)="$event.target.select()"
     [ngModel]="getContent()"
index 0eaf5e9..75332bc 100644 (file)
@@ -3,6 +3,8 @@ import {ElementRef, Component, Input, Output, OnInit, EventEmitter,
 import {filter} from 'rxjs/operators';
 import {MarcRecord, MarcField, MarcSubfield} from './marcrecord';
 import {MarcEditContext, FieldFocusRequest} from './editor-context';
+import {ContextMenuEntry} from '@eg/share/context-menu/context-menu.component';
+import {TagTableService} from './tagtable.service';
 
 /**
  * MARC Tag Editor Component
@@ -39,9 +41,11 @@ export class EditableContentComponent implements OnInit, AfterViewInit {
     editInput: any; // <input/> or <div contenteditable/>
     maxLength: number = null;
 
-    constructor(private renderer: Renderer2) {
-        this.randId = Math.floor(Math.random() * 100000);
-    }
+    contextMenuEntries: ContextMenuEntry[];
+
+    constructor(
+        private renderer: Renderer2,
+        private tagTable: TagTableService) {}
 
     ngOnInit() {
         this.setupFieldType();
@@ -93,6 +97,8 @@ export class EditableContentComponent implements OnInit, AfterViewInit {
             case 'sfc':
                 this.maxLength = 1;
                 this.watchForFocusRequests();
+                this.contextMenuEntries = 
+                    this.tagTable.getSubfieldCodes(this.field.tag);
                 break;
 
             case 'sfv':
@@ -316,6 +322,11 @@ export class EditableContentComponent implements OnInit, AfterViewInit {
 
         evt.preventDefault();
     }
+
+
+    contextMenuChange(value: string) {
+        this.setContent(value);
+    }
 }
 
 
index c51b456..1861b34 100644 (file)
@@ -16,8 +16,7 @@ export class MarcEditContext {
 
     recordChange: EventEmitter<MarcRecord>;
     fieldFocusRequest: EventEmitter<FieldFocusRequest>;
-
-    popOvers: NgbPopover[] = [];
+    recordType: 'biblio' | 'authority' = 'biblio';
 
     private _record: MarcRecord;
     set record(r: MarcRecord) {
@@ -37,13 +36,6 @@ export class MarcEditContext {
         this.fieldFocusRequest = new EventEmitter<FieldFocusRequest>();
     }
 
-    // NgbPopovers don't always close when we want them to,
-    // specifcially when context-clicking to open other popovers.
-    closePopovers() {
-    // TODO
-        this.popOvers.forEach(p => p.close());
-    }
-
     requestFieldFocus(req: FieldFocusRequest) {
         // timeout allows for new components to be built before the
         // focus request is emitted.
index f75e453..e1c1c2e 100644 (file)
@@ -35,6 +35,8 @@ export class MarcEditorComponent implements OnInit {
     sources: ComboboxEntry[];
     context: MarcEditContext;
 
+    @Input() recordType: 'biblio' | 'authority' = 'biblio';
+
     @Input() set recordId(id: number) {
         if (!id) { return; }
         if (this.record && this.record.id === id) { return; }
@@ -89,6 +91,8 @@ export class MarcEditorComponent implements OnInit {
 
     ngOnInit() {
 
+        this.context.recordType = this.recordType;
+
         this.store.getItem('cat.marcedit.flateditor').then(
             useFlat => this.editorTab = useFlat ? 'flat' : 'rich');
 
index 464844a..df18818 100644 (file)
@@ -1,6 +1,10 @@
 
 <ng-container *ngIf="!dataLoaded">
-  <eg-progress-inline></eg-progress-inline>
+  <div class="row mt-5">
+    <div class="offset-lg-3 col-lg-6">
+      <eg-progress-inline></eg-progress-inline>
+    </div>
+  </div>
 </ng-container>
 
 <ng-container *ngIf="dataLoaded">
index f03ce49..d7fc2a1 100644 (file)
@@ -41,7 +41,7 @@ export class MarcRichEditorComponent implements OnInit {
         if (!this.record) { return Promise.resolve(); }
 
         return Promise.all([
-            this.tagTable.loadTagTable({marcRecordType: this.record.recordType()}),
+            this.tagTable.loadTagTable({marcRecordType: this.context.recordType}),
             this.tagTable.getFFPosTable(this.record.recordType()),
             this.tagTable.getFFValueTable(this.record.recordType())
         ]).then(_ => this.dataLoaded = true);
index 024b1e9..3a8513a 100644 (file)
@@ -98,12 +98,22 @@ export class TagTableService {
             selector = defaultTagTableSelector;
         }
 
-        // TODO load from local store cache
+        const cacheKey = 'FFValueTable_' + selector.marcRecordType;
 
-        return this.fetchTagTable(selector);
+        this.tagMap = this.store.getLocalItem(cacheKey);
+
+        if (this.tagMap) {
+            return Promise.resolve(this.tagMap);
+        }
+
+        return this.fetchTagTable(selector).then(_ => {
+            this.store.setLocalItem(cacheKey, this.tagMap);
+            return this.tagMap;
+        });
     }
 
     fetchTagTable(selector?: TagTableSelector): Promise<any> {
+        this.tagMap = [];
         return this.net.request(
             'open-ils.cat',
             'open-ils.cat.tag_table.all.retrieve.local',
@@ -116,8 +126,7 @@ export class TagTableService {
     getSubfieldCodes(tag: string): ValueLabelPair[] { 
         if (!tag || !this.tagMap[tag]) { return null; }
 
-        return this.tagMap[tag].subfields
-        .map(sf => ({
+        return this.tagMap[tag].subfields.map(sf => ({
             value: sf.code, 
             label: `${sf.code}: ${sf.description}`
         })) 
index ef97e2a..53512d5 100644 (file)
@@ -219,3 +219,25 @@ body>.dropdown-menu {z-index: 2100;}
   background-color: #c9efe4;
   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; 
+}
+*/