LPXXX help and more
authorBill Erickson <berickxx@gmail.com>
Fri, 6 Dec 2019 16:54:26 +0000 (11:54 -0500)
committerBill Erickson <berickxx@gmail.com>
Fri, 6 Dec 2019 16:54:26 +0000 (11:54 -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/editor.component.html
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

index 96d71ac..c26578b 100644 (file)
@@ -4,7 +4,7 @@ import {Subscription} from 'rxjs';
 import {filter} from 'rxjs/operators';
 import {MarcRecord, MarcField, MarcSubfield} from './marcrecord';
 import {MarcEditContext, FieldFocusRequest, MARC_EDITABLE_FIELD_TYPE, 
-    UndoRedoAction} from './editor-context';
+    TextUndoRedoAction} from './editor-context';
 import {ContextMenuEntry} from '@eg/share/context-menu/context-menu.service';
 import {TagTableService} from './tagtable.service';
 
@@ -68,9 +68,9 @@ export class EditableContentComponent
     }
 
     watchForUndoRedoRequests() {
-        this.undoRedoSub = this.context.undoRedoRequest.pipe(
-            filter((action: UndoRedoAction) => this.focusRequestIsMe(action.position)))
-        .subscribe((action: UndoRedoAction) => this.processUndoRedo(action));
+        this.undoRedoSub = this.context.textUndoRedoRequest.pipe(
+            filter((action: TextUndoRedoAction) => this.focusRequestIsMe(action.position)))
+        .subscribe((action: TextUndoRedoAction) => this.processUndoRedo(action));
     }
 
     focusRequestIsMe(req: FieldFocusRequest): boolean {
@@ -219,7 +219,7 @@ export class EditableContentComponent
         const lastUndo = this.context.undoStack[0];
 
         if (lastUndo
-            && lastUndo.textContent !== undefined
+            && lastUndo instanceof TextUndoRedoAction
             && lastUndo.textContent === this.undoBackToText
             && this.focusRequestIsMe(lastUndo.position)) {
             // Most recent undo entry was a text change event within the
@@ -228,17 +228,16 @@ export class EditableContentComponent
             return;
         }
 
-        const undo = {
-            textContent: this.undoBackToText,
-            position: this.context.lastFocused
-        };
+        const undo = new TextUndoRedoAction();
+        undo.position = this.context.lastFocused;
+        undo.textContent =  this.undoBackToText;
 
         this.context.undoStack.unshift(undo);
     }
 
     // Apply the undo or redo action and track its opposite
     // action on the necessary stack
-    processUndoRedo(action: UndoRedoAction) {
+    processUndoRedo(action: TextUndoRedoAction) {
 
         // Undoing a text change
         const recoverContent = this.getContent();
index 0e48cb7..9e097af 100644 (file)
@@ -15,39 +15,41 @@ export interface FieldFocusRequest {
     sfOffset?: number; // focus a specific subfield by its offset
 }
 
-export interface UndoRedoAction {
-
+export class UndoRedoAction {
     // Which point in the record was modified.
     position: FieldFocusRequest;
 
-    isRedo?: boolean;
-
-    // Track text changes.
-    textContent?: string;
+    // Which stack do we toss this on once it's been applied?
+    isRedo: boolean;
+}
 
-    // Retain a copy of the affected field so deletion
-    // recovery can extract what's needed.
-    field?: MarcField;
+export class TextUndoRedoAction extends UndoRedoAction {
+    textContent: string;
+}
 
-    // If this is a subfield modification.
-    subfield?: MarcSubfield;
+export class StructUndoRedoAction extends UndoRedoAction {
+    /* Add or remove a part of the record (field, subfield, etc.) */
 
     // Does this action track an addition or deletion.
-    wasAddition?: boolean;
+    wasAddition: boolean;
+
+    // Field to add/delete or field to modify for subfield adds/deletes
+    field: MarcField;
+
+    // If this is a subfield modification.
+    subfield: MarcSubfield;
 
     // Position preceding the modified position to mark the position
     // of deletion recovery.
-    prevPosition?: FieldFocusRequest;
-
-    // Where should focus be returned once the undo is processed?
-    prevFocus?: FieldFocusRequest;
+    prevPosition: FieldFocusRequest;
 }
 
+
 export class MarcEditContext {
 
     recordChange: EventEmitter<MarcRecord>;
     fieldFocusRequest: EventEmitter<FieldFocusRequest>;
-    undoRedoRequest: EventEmitter<UndoRedoAction>;
+    textUndoRedoRequest: EventEmitter<TextUndoRedoAction>;
     recordType: 'biblio' | 'authority' = 'biblio';
 
     lastFocused: FieldFocusRequest = null;
@@ -71,7 +73,7 @@ export class MarcEditContext {
     constructor() {
         this.recordChange = new EventEmitter<MarcRecord>();
         this.fieldFocusRequest = new EventEmitter<FieldFocusRequest>();
-        this.undoRedoRequest = new EventEmitter<UndoRedoAction>();
+        this.textUndoRedoRequest = new EventEmitter<TextUndoRedoAction>();
     }
 
     requestFieldFocus(req: FieldFocusRequest) {
@@ -100,19 +102,19 @@ export class MarcEditContext {
     }
 
     distributeUndoRedo(action: UndoRedoAction) {
-        if (action.textContent !== undefined) {
+        if (action instanceof TextUndoRedoAction) {
             // Let the editable content component handle it.
-            this.undoRedoRequest.emit(action);
+            this.textUndoRedoRequest.emit(action);
         } else {
             // Manage structural changes within
-            this.handleStructuralUndoRedo(action);
+            this.handleStructuralUndoRedo(action as StructUndoRedoAction);
         }
     }
 
-    handleStructuralUndoRedo(action: UndoRedoAction) {
+    handleStructuralUndoRedo(action: StructUndoRedoAction) {
 
         if (action.wasAddition) {
-            // Remove the added field and focus the field before it.
+            // Remove the added field
 
             if (action.subfield) {
 
@@ -122,11 +124,17 @@ export class MarcEditContext {
 
             } else {
                 this.record.deleteFields(action.field);
-                this.requestFieldFocus(action.prevPosition);
+
+                if (this.lastFocused.fieldId === action.field.fieldId) {
+                    // If the field we are deleting is currently focused,
+                    // move focus to the previous field.  Otherwse, leave
+                    // the focus where it is.
+                    this.requestFieldFocus(action.prevPosition);
+                }
             }
 
         } else {
-            // Re-insert the removed field and focus it
+            // Re-insert the removed field and focus it.
             
             if (action.subfield) { 
 
@@ -176,14 +184,12 @@ export class MarcEditContext {
             }
         }
 
-        const action = {
-            field: field,
-            subfield: subfield,
-            wasAddition: isAddition,
-            position: position,
-            prevPosition: prevPos,
-            prevFocus: this.lastFocused
-        };
+        const action = new StructUndoRedoAction();
+        action.field = field;
+        action.subfield = subfield;
+        action.wasAddition = isAddition;
+        action.position = position;
+        action.prevPosition = prevPos;
 
         this.undoStack.unshift(action);
     }
index bd7c559..dea8581 100644 (file)
 
 <div class="row d-flex p-2 m-2">
   <div class="flex-1"></div>
+
+  <h3 class="mr-2">
+    <span class="badge badge-light p-2" i18n>
+      Record Type {{record ? record.recordType() : ''}}
+    </span>
+  </h3>
+    
   <div class="mr-2">
     <eg-combobox #sourceSelector
       [entries]="sources"
index ca090f3..f57bda5 100644 (file)
       <div class="col-lg-9 fixed-fields-container">
         <eg-fixed-fields-editor [context]="context"></eg-fixed-fields-editor>
       </div>
+      <div class="col-lg-3">
+        <div><button class="btn btn-outline-dark"
+          (click)="showHelp = !showHelp" i18n>Help</button></div>
+        <div class="mt-2"><button class="btn btn-outline-dark"
+          [disabled]="true"
+          (click)="validate()" i18n>Validate</button></div>
+        <div class="mt-2">
+          <div class="form-check">
+            <input class="form-check-input" type="checkbox" 
+              [disabled]="true"
+              [(ngModel)]="stackSubfields" id="stack-subfields-{{randId}}">
+            <label class="form-check-label" for="stack-subfields-{{randId}}">
+              Stack Subfields
+            </label>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <div *ngIf="showHelp" class="row m-2">
+      <div class="col-lg-4">
+        <ul>
+          <li>Undo: CTRL-z</li>
+          <li>Redo: CTRL-y</li>
+          <li>Add Row: CTRL+Enter</li>
+          <li>Insert Row: CTRL+Shift+Enter</li>
+        </ul>
+      </div>
+      <div class="col-lg-4">
+        <ul>
+         <li>Copy Current Row Above: CTRL+Up</li>
+         <li>Copy Current Row Below: CTRL+Down</li>
+         <li>Add Subfield: CTRL+D or CTRL+I</li>
+         <li>Remove Row: CTRL+Del</li>
+        </ul>
+      </div>
+      <div class="col-lg-4">
+        <ul>
+         <li>Remove Subfield: Shift+Del</li>
+         <li>Create/Replace 006: Shift+F6</li>
+         <li>Create/Replace 007: Shift+F7</li>
+         <li>Create/Replace 008: Shift+F8</li>
+        </ul>
+      </div>
     </div>
 
     <!-- LEADER -->
index d7fc2a1..aa03c20 100644 (file)
@@ -23,6 +23,9 @@ export class MarcRichEditorComponent implements OnInit {
     get record(): MarcRecord { return this.context.record; }
 
     dataLoaded: boolean;
+    showHelp: boolean;
+    randId = Math.floor(Math.random() * 100000);
+    stackSubfields: boolean;
 
     constructor(
         private idl: IdlService,