LPXXX Delete Field; more keyboard
authorBill Erickson <berickxx@gmail.com>
Wed, 20 Nov 2019 22:15:01 +0000 (17:15 -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/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

index 2b202df..3660f37 100644 (file)
@@ -1,8 +1,8 @@
 import {ElementRef, Component, Input, Output, OnInit, EventEmitter, 
     AfterViewInit, Renderer2} from '@angular/core';
-import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
+import {filter} from 'rxjs/operators';
 import {MarcRecord, MarcField} from './marcrecord';
-import {MarcEditContext} from './editor-context';
+import {MarcEditContext, FieldFocusRequest} from './editor-context';
 
 /**
  * MARC Tag Editor Component
@@ -44,10 +44,39 @@ export class EditableContentComponent implements OnInit, AfterViewInit {
     }
 
     ngOnInit() {
-        this.setupDataType();
+        this.setupFieldType();
     }
 
-    setupDataType() {
+    watchForFocusRequests() {
+
+        if (!this.field) {
+            // LDR tag has no field associated
+            return;
+        }
+
+        this.context.fieldFocusRequest.subscribe((req: FieldFocusRequest) => {
+
+            if (req.fieldId !== this.field.fieldId) { return ; }
+            if (!this.editInput) { return; }
+
+            if (req.sfOffset === undefined) {
+
+                if (this.fieldType === 'tag') {
+                    // Focus tag input
+                    this.editInput.select();
+                }
+                return;
+
+            } 
+            
+            // TODO: focus editable content input at subfield offset
+            if (this.fieldType === 'sfv') { 
+            } else if (this.fieldType === 'sfc') {
+            }
+        });
+    }
+
+    setupFieldType() {
         const content = this.getContent();
 
         switch (this.fieldType) {
@@ -57,24 +86,21 @@ export class EditableContentComponent implements OnInit, AfterViewInit {
 
             case 'tag':
                 this.maxLength = 3;
-
-                // Arrow navigation focuses tags
-                if (this.field) { // LDR tag does not have a field
-                    this.context.fieldFocusRequest.subscribe(fieldId => {
-                        if (fieldId === this.field.fieldId && this.editInput) {
-                            this.editInput.select();
-                        }
-                    });
-                }
+                this.watchForFocusRequests();
                 break;
 
             case 'ind':
+                this.maxLength = 1;
+                break;
+
             case 'sfc':
                 this.maxLength = 1;
+                this.watchForFocusRequests();
                 break;
 
             case 'sfv':
                 this.bigText = true;
+                this.watchForFocusRequests();
                 break;
         }
     }
@@ -137,9 +163,36 @@ export class EditableContentComponent implements OnInit, AfterViewInit {
     }
 
     inputKeyDown(evt: KeyboardEvent) {
-        switch (evt.key) {                                                     
+        
+        if (this.fieldType === 'ldr') {
+            // This may be overkill, we'll see
+            return;
+        }
+
+        switch (evt.key) {
+
+            case 'Enter':
+                // No part of a marc Record wants bare newlines
+                evt.preventDefault();
+                break;
+
+            case 'Delete':
+                if (evt.ctrlKey) { // Delete field
+
+                    const field = 
+                        this.record.getNextField(this.field.fieldId) ||
+                        this.record.getPreviousField(this.field.fieldId);
+                    if (field) {
+                        this.context.requestFieldFocus({fieldId: field.fieldId});
+                    }
+
+                    this.record.deleteFields(this.field);
+                }
+
+                evt.preventDefault();
+                break;
 
-            case 'ArrowDown':  
+            case 'ArrowDown':
 
                 if (evt.ctrlKey) { // Copy field down
 
@@ -152,7 +205,7 @@ export class EditableContentComponent implements OnInit, AfterViewInit {
 
                     const field = this.record.getNextField(this.field.fieldId);
                     if (field) {
-                        this.context.requestFieldFocus(field.fieldId);
+                        this.context.requestFieldFocus({fieldId: field.fieldId});
                     }
                 }
                 evt.preventDefault();
@@ -171,7 +224,7 @@ export class EditableContentComponent implements OnInit, AfterViewInit {
 
                     const field = this.record.getPreviousField(this.field.fieldId);
                     if (field) {
-                        this.context.requestFieldFocus(field.fieldId);
+                        this.context.requestFieldFocus({fieldId: field.fieldId});
                     }
                 }
                 evt.preventDefault();
index 990fd79..ca33605 100644 (file)
@@ -4,10 +4,17 @@ import {NgbPopover} from '@ng-bootstrap/ng-bootstrap';
 
 /* Per-instance MARC editor context. */
 
+export interface FieldFocusRequest {
+    fieldId: number;
+    // If specified, the subfield value at the specified
+    // will be focused.  Otherwise, the tag is focused.
+    sfOffset?: number;
+}
+
 export class MarcEditContext {
 
     recordChange: EventEmitter<MarcRecord>;
-    fieldFocusRequest: EventEmitter<number>;
+    fieldFocusRequest: EventEmitter<FieldFocusRequest>;
 
     popOvers: NgbPopover[] = [];
 
@@ -26,7 +33,7 @@ export class MarcEditContext {
 
     constructor() {
         this.recordChange = new EventEmitter<MarcRecord>();
-        this.fieldFocusRequest = new EventEmitter<number>();
+        this.fieldFocusRequest = new EventEmitter<FieldFocusRequest>();
     }
 
     // NgbPopovers don't always close when we want them to,
@@ -35,8 +42,8 @@ export class MarcEditContext {
         this.popOvers.forEach(p => p.close());
     }
 
-    requestFieldFocus(id: number) {
-        this.fieldFocusRequest.emit(id);
+    requestFieldFocus(req: FieldFocusRequest) {
+        this.fieldFocusRequest.emit(req);
     }
 }
 
index 9be8122..8170558 100644 (file)
@@ -19,6 +19,8 @@ export interface MarcField {
     subfields?: string[][]; 
 
     isControlfield(): boolean;
+
+    deleteExactSubfields(subfields: string[][]): number;
 }
 
 export class MarcRecord {
@@ -102,6 +104,10 @@ export class MarcRecord {
         this.stampFieldIds();
     }
 
+    deleteFields(...fields: MarcField[]) {
+        this.record.deleteFields.apply(this.record, fields);
+    }
+
     getField(id: number): MarcField {
         return this.fields.filter(f => f.fieldId === id)[0];
     }