LP#1832897: improvements to eg-fm-record-editor
authorGalen Charlton <gmc@equinoxinitiative.org>
Tue, 11 Jun 2019 23:07:37 +0000 (19:07 -0400)
committerJane Sandberg <sandbej@linnbenton.edu>
Wed, 4 Sep 2019 02:30:48 +0000 (19:30 -0700)
* Add a new optional attribute, preSave, for passing a
  callback to modify modify records (e.g.,
  to provide default values) before they are saved.
* Ensure that the components current copy of a record is
  discarded when the user closes or dismisses the modal

  This addresses an issue where editing multiple instances
  of records on an admin page could display (and/or flash)
  stale data, particularly for the new multi-select widget.

Signed-off-by: Galen Charlton <gmc@equinoxinitiative.org>
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Signed-off-by: Jane Sandberg <sandbej@linnbenton.edu>
Open-ILS/src/eg2/src/app/share/fm-editor/fm-editor.component.html
Open-ILS/src/eg2/src/app/share/fm-editor/fm-editor.component.ts

index 476c261..85c0c65 100644 (file)
@@ -9,7 +9,7 @@
     <h4 class="modal-title" i18n>Record Editor: {{recordLabel}}</h4>
     <ng-container *ngIf="isDialog()">
       <button type="button" class="close" 
-        i18n-aria-label aria-label="Close" (click)="close()">
+        i18n-aria-label aria-label="Close" (click)="closeEditor()">
         <span aria-hidden="true">&times;</span>
       </button>
     </ng-container>
   <div class="modal-footer">
     <ng-container *ngIf="isDialog()">
       <button type="button" class="btn btn-success" *ngIf="mode == 'view'"
-        (click)="close()" i18n>Close</button>
+        (click)="closeEditor()" i18n>Close</button>
       <button type="button" class="btn btn-warning ml-2" *ngIf="mode != 'view'"
         (click)="cancel()" i18n>Cancel</button>
     </ng-container>
index 6c079b8..0cd9a6f 100644 (file)
@@ -8,7 +8,7 @@ import {PcrudService} from '@eg/core/pcrud.service';
 import {DialogComponent} from '@eg/share/dialog/dialog.component';
 import {ToastService} from '@eg/share/toast/toast.service';
 import {StringComponent} from '@eg/share/string/string.component';
-import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
+import {NgbModal, NgbModalOptions} from '@ng-bootstrap/ng-bootstrap';
 import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
 import {TranslateComponent} from '@eg/staff/share/translate/translate.component';
 
@@ -160,6 +160,10 @@ export class FmRecordEditorComponent
         if (id) { this.recId = id; }
     }
 
+    // custom function for munging the record before it gets saved;
+    // will get passed mode and the record itself
+    @Input() preSave: Function;
+
     constructor(
       private modal: NgbModal, // required for passing to parent
       private idl: IdlService,
@@ -186,6 +190,19 @@ export class FmRecordEditorComponent
         }
     }
 
+    open(args?: NgbModalOptions): Observable<any> {
+        if (!args) {
+            args = {};
+        }
+        // ensure we don't hang on to our copy of the record
+        // if the user dismisses the dialog
+        args.beforeDismiss = () => {
+            this.record = undefined;
+            return true;
+        };
+        return super.open(args);
+    }
+
     isDialog(): boolean {
         return this.displayMode === 'dialog';
     }
@@ -471,12 +488,15 @@ export class FmRecordEditorComponent
 
     save() {
         const recToSave = this.idl.clone(this.record);
+        if (this.preSave) {
+            this.preSave(this.mode, recToSave);
+        }
         this.convertDatatypesToIdl(recToSave);
         this.pcrud[this.mode]([recToSave]).toPromise().then(
             result => {
                 this.onSave$.emit(result);
                 this.successStr.current().then(msg => this.toast.success(msg));
-                if (this.isDialog()) { this.close(result); }
+                if (this.isDialog()) { this.record = undefined; this.close(result); }
             },
             error => {
                 this.onError$.emit(error);
@@ -488,6 +508,12 @@ export class FmRecordEditorComponent
 
     cancel() {
         this.onCancel$.emit(this.record);
+        this.record = undefined;
+        this.close();
+    }
+
+    closeEditor() {
+        this.record = undefined;
         this.close();
     }