LP1852782 MARC editor and related lint repairs
authorBill Erickson <berickxx@gmail.com>
Tue, 10 Dec 2019 17:00:20 +0000 (12:00 -0500)
committerBill Erickson <berickxx@gmail.com>
Fri, 21 Feb 2020 16:44:38 +0000 (11:44 -0500)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Signed-off-by: Jane Sandberg <sandbej@linnbenton.edu>
Open-ILS/src/eg2/src/app/share/context-menu/context-menu-container.component.ts
Open-ILS/src/eg2/src/app/share/context-menu/context-menu.directive.ts
Open-ILS/src/eg2/src/app/share/context-menu/context-menu.service.ts
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/marcrecord.ts
Open-ILS/src/eg2/src/app/staff/share/marc-edit/tagtable.service.ts

index a5dfdce..fc218c0 100644 (file)
@@ -1,4 +1,4 @@
-import {Component, Input, Output, EventEmitter, OnInit, ViewChild, 
+import {Component, Input, Output, EventEmitter, OnInit, ViewChild,
     AfterViewInit, TemplateRef, ViewEncapsulation} from '@angular/core';
 import {ContextMenuService, ContextMenu, ContextMenuEntry} from './context-menu.service';
 
@@ -6,7 +6,7 @@ import {ContextMenuService, ContextMenu, ContextMenuEntry} from './context-menu.
   selector: 'eg-context-menu-container',
   templateUrl: './context-menu-container.component.html',
   styleUrls: ['context-menu-container.component.css'],
-  /* Our CSS affects the style of the popover, which may 
+  /* Our CSS affects the style of the popover, which may
    * be beyond our reach for standard view encapsulation */
   encapsulation: ViewEncapsulation.None
 })
@@ -19,11 +19,9 @@ export class ContextMenuContainerComponent implements OnInit, AfterViewInit {
     constructor(private menuService: ContextMenuService) {}
 
     ngOnInit() {
-
         this.menuService.showMenuRequest.subscribe(
             (menu: ContextMenu) => {
-
-            this.menuEntries = menu.entries
+            this.menuEntries = menu.entries;
         });
     }
 
index 591d9d0..14de769 100644 (file)
@@ -3,7 +3,7 @@ import {NgbPopover} from '@ng-bootstrap/ng-bootstrap';
 import {ContextMenuService, ContextMenu, ContextMenuEntry} from './context-menu.service';
 
 
-/* Import all of this stuff so we can pass it to our parent 
+/* Import all of this stuff so we can pass it to our parent
  * class via its constructor */
 import {
     Inject, Injector, Renderer2, ElementRef, TemplateRef, ViewContainerRef,
@@ -19,6 +19,10 @@ import {NgbPopoverConfig} from '@ng-bootstrap/ng-bootstrap';
 })
 export class ContextMenuDirective extends NgbPopover {
 
+    // Only one active menu is allowed at a time.
+    static activeDirective: ContextMenuDirective;
+    static menuId = 0;
+
     triggers = 'contextmenu';
     popoverClass = 'eg-context-menu';
 
@@ -31,10 +35,6 @@ export class ContextMenuDirective extends NgbPopover {
 
     @Output() menuItemSelected: EventEmitter<ContextMenuEntry>;
 
-    // Only one active menu is allowed at a time.
-    static activeDirective: ContextMenuDirective;
-    static menuId = 0;
-
     constructor(
         p1: ElementRef<HTMLElement>, p2: Renderer2, p3: Injector,
         p4: ComponentFactoryResolver, p5: ViewContainerRef, p6: NgbPopoverConfig,
@@ -49,7 +49,7 @@ export class ContextMenuDirective extends NgbPopover {
         this.menuService.menuItemSelected.subscribe(
             (entry: ContextMenuEntry) => {
 
-            // Only broadcast entry selection to my listeners if I'm 
+            // Only broadcast entry selection to my listeners if I'm
             // hosting the menu where the selection occurred.
 
             if (this.menu && this.menu.id === this.menuService.activeMenu.id) {
@@ -65,11 +65,11 @@ export class ContextMenuDirective extends NgbPopover {
         if (ContextMenuDirective.activeDirective) {
             ContextMenuDirective.activeDirective.close();
             ContextMenuDirective.activeDirective = null;
-            this.menuService.activeMenu == null;
+            this.menuService.activeMenu = null;
         }
 
         if (!this.menuEntries ||
-             this.menuEntries.length === 0) { 
+             this.menuEntries.length === 0) {
              return;
         }
 
index bfedf42..838274b 100644 (file)
@@ -1,7 +1,7 @@
 import {Injectable, EventEmitter, TemplateRef} from '@angular/core';
 import {tap} from 'rxjs/operators';
 
-/* Relay requests to/from the context menu directive and its 
+/* Relay requests to/from the context menu directive and its
  * template container component */
 
 export interface ContextMenuEntry {
@@ -16,13 +16,13 @@ export class ContextMenu {
 
 @Injectable({providedIn: 'root'})
 export class ContextMenuService {
-    
+
     showMenuRequest: EventEmitter<ContextMenu>;
     menuItemSelected: EventEmitter<ContextMenuEntry>;
 
     menuTemplate: TemplateRef<any>;
     activeMenu: ContextMenu;
-    
+
     constructor() {
         this.showMenuRequest = new EventEmitter<ContextMenu>();
         this.menuItemSelected = new EventEmitter<ContextMenuEntry>();
index 5f4b1ea..a926baa 100644 (file)
@@ -1,9 +1,9 @@
-import {ElementRef, Component, Input, Output, OnInit, OnDestroy, 
+import {ElementRef, Component, Input, Output, OnInit, OnDestroy,
     EventEmitter, AfterViewInit, Renderer2} from '@angular/core';
 import {Subscription} from 'rxjs';
 import {filter} from 'rxjs/operators';
 import {MarcRecord, MarcField, MarcSubfield} from './marcrecord';
-import {MarcEditContext, FieldFocusRequest, MARC_EDITABLE_FIELD_TYPE, 
+import {MarcEditContext, FieldFocusRequest, MARC_EDITABLE_FIELD_TYPE,
     TextUndoRedoAction} from './editor-context';
 import {ContextMenuEntry} from '@eg/share/context-menu/context-menu.service';
 import {TagTableService} from './tagtable.service';
@@ -18,7 +18,7 @@ import {TagTableService} from './tagtable.service';
   styleUrls: ['./editable-content.component.css']
 })
 
-export class EditableContentComponent 
+export class EditableContentComponent
     implements OnInit, AfterViewInit, OnDestroy {
 
     @Input() context: MarcEditContext;
@@ -43,7 +43,7 @@ export class EditableContentComponent
     editInput: any; // <input/> or <div contenteditable/>
     maxLength: number = null;
 
-    // Track the load-time content so we know what text value to 
+    // Track the load-time content so we know what text value to
     // track on our undo stack.
     undoBackToText: string;
 
@@ -91,12 +91,12 @@ export class EditableContentComponent
             if (req.fieldId !== this.field.fieldId) { return false; }
         } else if (req.target === 'ldr') {
             return this.isLeader;
-        } else if (req.target === 'ffld' && 
+        } else if (req.target === 'ffld' &&
             req.ffCode !== this.fixedFieldCode) {
             return false;
         }
 
-        if (req.sfOffset !== undefined && 
+        if (req.sfOffset !== undefined &&
             req.sfOffset !== this.subfield[2]) {
             // this is not the subfield you are looking for.
             return false;
@@ -113,7 +113,7 @@ export class EditableContentComponent
         }
 
         if (!req) {
-            // Focus request may have come from keyboard navigation, 
+            // Focus request may have come from keyboard navigation,
             // clicking, etc.  Model the event as a focus request
             // so it can be tracked the same.
             req = {
@@ -195,14 +195,14 @@ export class EditableContentComponent
     contextMenuEntries(): ContextMenuEntry[] {
         if (this.isLeader) { return; }
 
-        switch(this.fieldType) {
-            case 'tag': 
+        switch (this.fieldType) {
+            case 'tag':
                 return this.tagTable.getFieldTags();
 
-            case 'sfc': 
+            case 'sfc':
                 return this.tagTable.getSubfieldCodes(this.field.tag);
 
-            case 'sfv': 
+            case 'sfv':
                 return this.tagTable.getSubfieldValues(
                     this.field.tag, this.subfield[0]);
 
@@ -211,7 +211,7 @@ export class EditableContentComponent
                 return this.tagTable.getIndicatorValues(
                     this.field.tag, this.fieldType);
 
-            case 'ffld': 
+            case 'ffld':
                 return this.tagTable.getFfValues(
                     this.fixedFieldCode, this.record.recordType());
         }
@@ -223,7 +223,7 @@ export class EditableContentComponent
         if (this.fieldText) { return this.fieldText; } // read-only
 
         switch (this.fieldType) {
-            case 'ldr': return this.record.leader; 
+            case 'ldr': return this.record.leader;
             case 'cfld': return this.field.data;
             case 'tag': return this.field.tag;
             case 'sfc': return this.subfield[0];
@@ -231,7 +231,7 @@ export class EditableContentComponent
             case 'ind1': return this.field.ind1;
             case 'ind2': return this.field.ind2;
 
-            case 'ffld': 
+            case 'ffld':
                 // When actively editing a fixed field, track its value
                 // in a local variable instead of pulling the value
                 // from record.extractFixedField(), which applies
@@ -244,7 +244,7 @@ export class EditableContentComponent
                     !this.context.lastFocused ||
                     !this.focusRequestIsMe(this.context.lastFocused)) {
 
-                    this.ffValue = 
+                    this.ffValue =
                         this.record.extractFixedField(this.fixedFieldCode);
                 }
                 return this.ffValue;
@@ -264,7 +264,7 @@ export class EditableContentComponent
             case 'sfv': this.subfield[1] = value; break;
             case 'ind1': this.field.ind1 = value; break;
             case 'ind2': this.field.ind2 = value; break;
-            case 'ffld': 
+            case 'ffld':
                 // Track locally and propagate to the record.
                 this.ffValue = value;
                 this.record.setFixedField(this.fixedFieldCode, value);
@@ -316,7 +316,7 @@ export class EditableContentComponent
         this.setContent(action.textContent, true, true);
 
         action.textContent = recoverContent;
-        const moveTo = action.isRedo ? 
+        const moveTo = action.isRedo ?
             this.context.undoStack : this.context.redoStack;
 
         moveTo.unshift(action);
@@ -324,7 +324,7 @@ export class EditableContentComponent
 
     inputBlurred() {
         // If the text content changed during this focus session,
-        // track the new value as the value the next session of 
+        // track the new value as the value the next session of
         // text edits should return to upon undo.
         this.undoBackToText = this.getContent();
     }
@@ -370,22 +370,22 @@ export class EditableContentComponent
     // Route keydown events to the appropriate handler
     inputKeyDown(evt: KeyboardEvent) {
 
-        switch(evt.key) {
-            case 'y': 
+        switch (evt.key) {
+            case 'y':
                 if (evt.ctrlKey) { // redo
                     this.context.requestRedo();
                     evt.preventDefault();
                 }
                 return;
 
-            case 'z': 
+            case 'z':
                 if (evt.ctrlKey) { // undo
                     this.context.requestUndo();
                     evt.preventDefault();
                 }
                 return;
 
-            case 'F6': 
+            case 'F6':
                 if (evt.shiftKey) {
                     // shift+F6 => add 006
                     this.context.add00X('006');
@@ -394,7 +394,7 @@ export class EditableContentComponent
                 }
                 return;
 
-            case 'F7': 
+            case 'F7':
                 if (evt.shiftKey) {
                     // shift+F7 => add 007
                     this.context.add00X('007');
@@ -403,7 +403,7 @@ export class EditableContentComponent
                 }
                 return;
 
-            case 'F8': 
+            case 'F8':
                 if (evt.shiftKey) {
                     // shift+F8 => add/replace 008
                     this.context.insertReplace008();
@@ -419,7 +419,7 @@ export class EditableContentComponent
 
         switch (evt.key) {
 
-            case 'Enter': 
+            case 'Enter':
                 if (evt.ctrlKey) {
                     // ctrl+enter == insert stub field after focused field
                     // ctrl+shift+enter == insert stub field before focused field
@@ -431,7 +431,7 @@ export class EditableContentComponent
 
             case 'Delete':
 
-                if (evt.ctrlKey) { 
+                if (evt.ctrlKey) {
                     // ctrl+delete == delete whole field
                     this.context.deleteField(this.field);
                     evt.preventDefault();
@@ -445,7 +445,7 @@ export class EditableContentComponent
 
                 break;
 
-            case 'ArrowDown': 
+            case 'ArrowDown':
 
                 if (evt.ctrlKey) {
                     // ctrl+down == copy current field down one
@@ -502,8 +502,9 @@ export class EditableContentComponent
     }
 
     deleteField() {
-        this.context.focusNextTag(this.field) || 
+        if (!this.context.focusNextTag(this.field)) {
             this.context.focusPreviousTag(this.field);
+        }
 
         this.record.deleteFields(this.field);
     }
@@ -515,12 +516,12 @@ export class EditableContentComponent
 
         this.field.deleteExactSubfields(this.subfield);
 
-        const focus: FieldFocusRequest = 
-            {fieldId: this.field.fieldId, target: 'tag'};
+        const focus: FieldFocusRequest = {
+            fieldId: this.field.fieldId, target: 'tag'};
 
-        if (sfpos >= 0) { 
+        if (sfpos >= 0) {
             focus.target = 'sfv';
-            focus.sfOffset = sfpos; 
+            focus.sfOffset = sfpos;
         }
 
         this.context.requestFieldFocus(focus);
index 168fbda..520ddbf 100644 (file)
@@ -6,7 +6,7 @@ import {NgbPopover} from '@ng-bootstrap/ng-bootstrap';
 
 const STUB_DATA_00X = '                                        ';
 
-export type MARC_EDITABLE_FIELD_TYPE = 
+export type MARC_EDITABLE_FIELD_TYPE =
     'ldr' | 'tag' | 'cfld' | 'ind1' | 'ind2' | 'sfc' | 'sfv' | 'ffld';
 
 export interface FieldFocusRequest {
@@ -137,24 +137,24 @@ export class MarcEditContext {
 
         } else {
             // Re-insert the removed field and focus it.
-            
-            if (action.subfield) { 
+
+            if (action.subfield) {
 
                 this.insertSubfield(action.field, action.subfield, true);
                 this.focusSubfield(action.field, action.subfield[2]);
 
             } else {
-                
+
                 const fieldId = action.position.fieldId;
-                const prevField = 
+                const prevField =
                     this.record.getField(action.prevPosition.fieldId);
 
                 this.record.insertFieldsAfter(prevField, action.field);
-                
+
                 // Recover the original fieldId, which gets re-stamped
                 // in this.record.insertFields* calls.
                 action.field.fieldId = fieldId;
-                
+
                 // Focus the newly recovered field.
                 this.requestFieldFocus(action.position);
             }
@@ -211,17 +211,19 @@ export class MarcEditContext {
         this.undoStack.unshift(action);
     }
 
-    deleteField(field: MarcField) { 
+    deleteField(field: MarcField) {
         this.trackStructuralUndo(field, false);
 
-        this.focusNextTag(field) || this.focusPreviousTag(field);
+        if (!this.focusNextTag(field)) {
+            this.focusPreviousTag(field);
+        }
 
         this.record.deleteFields(field);
     }
 
     add00X(tag: string) {
 
-        const field: MarcField = 
+        const field: MarcField =
             this.record.newField({tag : tag, data : STUB_DATA_00X});
 
         this.record.insertOrderedFields(field);
@@ -274,7 +276,7 @@ export class MarcEditContext {
 
     // Adds a new empty subfield to the provided field at the
     // requested subfield position
-    insertSubfield(field: MarcField, 
+    insertSubfield(field: MarcField,
         subfield: MarcSubfield, skipTracking?: boolean) {
         const position = subfield[2];
 
@@ -297,18 +299,18 @@ export class MarcEditContext {
         const newSf: MarcSubfield = [' ', '', position];
         this.insertSubfield(field, newSf);
     }
-    
-    // Focus the requested subfield by its position.  If its 
+
+    // Focus the requested subfield by its position.  If its
     // position is less than zero, focus the field's tag instead.
     focusSubfield(field: MarcField, position: number) {
 
         const focus: FieldFocusRequest = {fieldId: field.fieldId, target: 'tag'};
 
-        if (position >= 0) { 
+        if (position >= 0) {
             // Focus the code instead of the value, because attempting to
             // focus an empty (editable) div results in nothing getting focus.
             focus.target = 'sfc';
-            focus.sfOffset = position; 
+            focus.sfOffset = position;
         }
 
         this.requestFieldFocus(focus);
@@ -331,8 +333,8 @@ export class MarcEditContext {
     // Returns true if the field has a next tag to focus
     focusNextTag(field: MarcField) {
         const nextField = this.record.getNextField(field.fieldId);
-        if (nextField) { 
-            this.focusTag(nextField); 
+        if (nextField) {
+            this.focusTag(nextField);
             return true;
         }
         return false;
index 61b7169..69e0955 100644 (file)
@@ -7,8 +7,8 @@ declare var MARC21;
 // MARC breaker delimiter
 const DELIMITER = '$';
 
-export interface MarcSubfield  // code, value, position
-    extends Array<string|number>{0: string; 1: string; 2: number}
+export interface MarcSubfield    // code, value, position
+    extends Array<string|number> { 0: string; 1: string; 2: number; }
 
 // Only contains the attributes/methods we need so far.
 export interface MarcField {
@@ -17,7 +17,7 @@ export interface MarcField {
     tag?: string;
     ind1?: string;
     ind2?: string;
-    subfields?: MarcSubfield[]; 
+    subfields?: MarcSubfield[];
 
     isControlfield(): boolean;
 
index ec5abd0..13cbd2c 100644 (file)
@@ -16,7 +16,7 @@ interface TagTableSelector {
 const defaultTagTableSelector: TagTableSelector = {
     marcFormat     : 'marc21',
     marcRecordType : 'biblio'
-}
+};
 
 @Injectable()
 export class TagTableService {
@@ -26,7 +26,7 @@ export class TagTableService {
     ffPosMap: {[rtype: string]: any[]} = {};
     ffValueMap: {[rtype: string]: any} = {};
 
-    extractedValuesCache: 
+    extractedValuesCache:
         {[valueType: string]: {[which: string]: any}} = {};
 
     constructor(
@@ -59,7 +59,7 @@ export class TagTableService {
         }
     }
 
-    toCache(dataType: string, which: string, 
+    toCache(dataType: string, which: string,
         which2: string, values: ContextMenuEntry[]): ContextMenuEntry[] {
         const base = this.extractedValuesCache[dataType];
         const part1 = base[which];
@@ -128,7 +128,7 @@ export class TagTableService {
                 selector.marcFormat = defaultTagTableSelector.marcFormat;
             }
             if (!selector.marcRecordType) {
-                selector.marcRecordType = 
+                selector.marcRecordType =
                     defaultTagTableSelector.marcRecordType;
             }
         } else {
@@ -160,15 +160,15 @@ export class TagTableService {
         })).toPromise();
     }
 
-    getSubfieldCodes(tag: string): ContextMenuEntry[] { 
+    getSubfieldCodes(tag: string): ContextMenuEntry[] {
         if (!tag || !this.tagMap[tag]) { return null; }
 
         const cached = this.fromCache('sfcodes', tag);
 
         const list = this.tagMap[tag].subfields.map(sf => ({
-            value: sf.code, 
+            value: sf.code,
             label: `${sf.code}: ${sf.description}`
-        })) 
+        }))
         .sort((a, b) => a.label < b.label ? -1 : 1);
 
         return this.toCache('sfcodes', tag, null, list);
@@ -178,7 +178,7 @@ export class TagTableService {
 
         const cached = this.fromCache('fieldtags');
         if (cached) { return cached; }
-        
+
         return Object.keys(this.tagMap)
         .filter(tag => Boolean(this.tagMap[tag]))
         .map(tag => ({
@@ -191,7 +191,7 @@ export class TagTableService {
     getSubfieldValues(tag: string, sfCode: string): ContextMenuEntry[] {
         if (!tag || !this.tagMap[tag]) { return []; }
 
-        const cached = this.fromCache('sfvalues', tag, sfCode)
+        const cached = this.fromCache('sfvalues', tag, sfCode);
         if (cached) { return cached; }
 
         const list: ContextMenuEntry[] = [];
@@ -203,18 +203,18 @@ export class TagTableService {
             sf.value_list.forEach(value => {
 
                 let label = value.description || value.code;
-                let code = value.code || label;
+                const code = value.code || label;
                 if (code !== label) { label = `${code}: ${label}`; }
 
                 list.push({value: code, label: label});
-            })
+            });
         });
 
         return this.toCache('sfvalues', tag, sfCode, list);
     }
 
     getIndicatorValues(tag: string, which: 'ind1' | 'ind2'): ContextMenuEntry[] {
-        if (!tag || !this.tagMap[tag]) { return }
+        if (!tag || !this.tagMap[tag]) { return; }
 
         const cached = this.fromCache('indicators', tag, which);
         if (cached) { return cached; }