[open-ils-commits] [GIT] Evergreen ILS branch master updated. 5bfdbe9867666ef31f4f9faddfa9afaa10d6bdfd

Evergreen Git git at git.evergreen-ils.org
Sun Feb 23 10:37:12 EST 2020


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Evergreen ILS".

The branch, master has been updated
       via  5bfdbe9867666ef31f4f9faddfa9afaa10d6bdfd (commit)
      from  eea266a15ded37c91ae272db33fac0548035f8d5 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 5bfdbe9867666ef31f4f9faddfa9afaa10d6bdfd
Author: Bill Erickson <berickxx at gmail.com>
Date:   Tue Jan 21 16:06:01 2020 -0500

    LP1860460 Copy delete override repairs, perm failed handler
    
    * Teach the Angular holdings module vol/copy delete dialog to correctly
      report failure events to the user and handle permission overrides.
    
    * Add support for automatically launching the op-change dialog when a
      permission failed event is returned by an API call for any /eg2/staff/
      interface.
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Jennifer Weston <jennifer.weston at equinoxinitiative.org>
    Signed-off-by: Jane Sandberg <sandbej at linnbenton.edu>

diff --git a/Open-ILS/src/eg2/src/app/core/auth.service.ts b/Open-ILS/src/eg2/src/app/core/auth.service.ts
index a173d6304a..9ad471fb02 100644
--- a/Open-ILS/src/eg2/src/app/core/auth.service.ts
+++ b/Open-ILS/src/eg2/src/app/core/auth.service.ts
@@ -130,6 +130,11 @@ export class AuthService {
         let service = 'open-ils.auth';
         let method = 'open-ils.auth.login';
 
+        if (isOpChange && this.opChangeIsActive()) {
+            // Enforce one op-change at a time.
+            this.undoOpChange();
+        }
+
         return this.net.request(
             'open-ils.auth_proxy',
             'open-ils.auth_proxy.enabled')
diff --git a/Open-ILS/src/eg2/src/app/core/net.service.ts b/Open-ILS/src/eg2/src/app/core/net.service.ts
index dd2bebbd64..42dae19b1c 100644
--- a/Open-ILS/src/eg2/src/app/core/net.service.ts
+++ b/Open-ILS/src/eg2/src/app/core/net.service.ts
@@ -73,7 +73,7 @@ export class NetService {
     permFailed$: EventEmitter<NetRequest>;
     authExpired$: EventEmitter<AuthExpiredEvent>;
 
-    // If true, permission failures are emitted via permFailed$
+    // If true, permission failures are emitted via permFailed
     // and the active request is marked as superseded.
     permFailedHasHandler: Boolean = false;
 
diff --git a/Open-ILS/src/eg2/src/app/staff/nav.component.ts b/Open-ILS/src/eg2/src/app/staff/nav.component.ts
index f143727a33..5627f762ba 100644
--- a/Open-ILS/src/eg2/src/app/staff/nav.component.ts
+++ b/Open-ILS/src/eg2/src/app/staff/nav.component.ts
@@ -1,12 +1,15 @@
-import {Component, OnInit, ViewChild} from '@angular/core';
+import {Component, OnInit, OnDestroy, ViewChild} from '@angular/core';
 import {ActivatedRoute, Router} from '@angular/router';
 import {Location} from '@angular/common';
+import {Subscription} from 'rxjs';
 import {OrgService} from '@eg/core/org.service';
 import {AuthService} from '@eg/core/auth.service';
 import {PcrudService} from '@eg/core/pcrud.service';
 import {LocaleService} from '@eg/core/locale.service';
 import {PrintService} from '@eg/share/print/print.service';
 import {StoreService} from '@eg/core/store.service';
+import {NetRequest, NetService} from '@eg/core/net.service';
+import {OpChangeComponent} from '@eg/staff/share/op-change/op-change.component';
 
 @Component({
     selector: 'eg-staff-nav-bar',
@@ -14,7 +17,7 @@ import {StoreService} from '@eg/core/store.service';
     templateUrl: 'nav.component.html'
 })
 
-export class StaffNavComponent implements OnInit {
+export class StaffNavComponent implements OnInit, OnDestroy {
 
     // Locales that have Angular staff translations
     locales: any[];
@@ -23,9 +26,13 @@ export class StaffNavComponent implements OnInit {
     // When active, show a link to the experimental Angular staff catalog
     showAngularCatalog: boolean;
 
+    @ViewChild('navOpChange', {static: false}) opChange: OpChangeComponent;
+    permFailedSub: Subscription;
+
     constructor(
         private router: Router,
         private store: StoreService,
+        private net: NetService,
         private org: OrgService,
         private auth: AuthService,
         private pcrud: PcrudService,
@@ -54,6 +61,19 @@ export class StaffNavComponent implements OnInit {
             .then(settings => this.showAngularCatalog =
                 Boolean(settings['ui.staff.angular_catalog.enabled']));
         }
+
+        // Wire up our op-change component as the general purpose
+        // permission failed handler.
+        this.net.permFailedHasHandler = true;
+        this.permFailedSub =
+            this.net.permFailed$.subscribe(
+                (req: NetRequest) => this.opChange.escalateRequest(req));
+    }
+
+    ngOnDestroy() {
+        if (this.permFailedSub) {
+            this.permFailedSub.unsubscribe();
+        }
     }
 
     user() {
diff --git a/Open-ILS/src/eg2/src/app/staff/share/holdings/delete-volcopy-dialog.component.html b/Open-ILS/src/eg2/src/app/staff/share/holdings/delete-volcopy-dialog.component.html
index 5bde3a7928..f7709cda1c 100644
--- a/Open-ILS/src/eg2/src/app/staff/share/holdings/delete-volcopy-dialog.component.html
+++ b/Open-ILS/src/eg2/src/app/staff/share/holdings/delete-volcopy-dialog.component.html
@@ -1,33 +1,36 @@
 
-
 <eg-string #successMsg
     text="Successfully Holdings" i18n-text></eg-string>
 <eg-string #errorMsg 
     text="Failed To Delete Holdings" i18n-text></eg-string>
 
+<eg-confirm-dialog #confirmOverride
+  i18n-dialogTitle dialogTitle="One or more items could not be deleted. Override?"
+  i18n-dialogBody dialogBody="Reason(s) include: {{deleteEventDesc}}">
+</eg-confirm-dialog>
 
 <ng-template #dialogContent>
-    <div class="modal-header bg-info">
-      <h4 class="modal-title">
-        <span i18n>Delete Holdings</span>
-      </h4>
-      <button type="button" class="close" 
-        i18n-aria-label aria-label="Close" (click)="close()">
-        <span aria-hidden="true">×</span>
+  <div class="modal-header bg-info">
+    <h4 class="modal-title">
+      <span i18n>Delete Holdings</span>
+    </h4>
+    <button type="button" class="close" 
+      i18n-aria-label aria-label="Close" (click)="close()">
+      <span aria-hidden="true">×</span>
+    </button>
+  </div>
+  <div class="modal-body">
+    <p i18n>Delete {{numCallNums}} call numbers and {{numCopies}} copies?</p>
+  </div>
+  <div class="modal-footer">
+    <ng-container>
+      <button type="button" class="btn btn-warning" 
+        (click)="close()" i18n>Cancel</button>
+      <button type="button" class="btn btn-success" 
+        (click)="deleteHoldings()" i18n>
+        Delete Holdings
       </button>
-    </div>
-    <div class="modal-body">
-      <p i18n>Delete {{numCallNums}} call numbers and {{numCopies}} copies?</p>
-    </div>
-    <div class="modal-footer">
-      <ng-container>
-        <button type="button" class="btn btn-warning" 
-          (click)="close()" i18n>Cancel</button>
-        <button type="button" class="btn btn-success" 
-          (click)="deleteHoldings()" i18n>
-          Delete Holdings
-        </button>
-      </ng-container>
-    </div>
-  </ng-template>
-  
+    </ng-container>
+  </div>
+</ng-template>
+
diff --git a/Open-ILS/src/eg2/src/app/staff/share/holdings/delete-volcopy-dialog.component.ts b/Open-ILS/src/eg2/src/app/staff/share/holdings/delete-volcopy-dialog.component.ts
index 3941d34881..76fbd58ede 100644
--- a/Open-ILS/src/eg2/src/app/staff/share/holdings/delete-volcopy-dialog.component.ts
+++ b/Open-ILS/src/eg2/src/app/staff/share/holdings/delete-volcopy-dialog.component.ts
@@ -2,13 +2,14 @@ import {Component, OnInit, Input, ViewChild, Renderer2} from '@angular/core';
 import {Observable, throwError} from 'rxjs';
 import {IdlObject} from '@eg/core/idl.service';
 import {NetService} from '@eg/core/net.service';
-import {EventService} from '@eg/core/event.service';
+import {EgEvent, EventService} from '@eg/core/event.service';
 import {PcrudService} from '@eg/core/pcrud.service';
 import {ToastService} from '@eg/share/toast/toast.service';
 import {AuthService} from '@eg/core/auth.service';
 import {NgbModal, NgbModalOptions} from '@ng-bootstrap/ng-bootstrap';
 import {DialogComponent} from '@eg/share/dialog/dialog.component';
 import {StringComponent} from '@eg/share/string/string.component';
+import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component';
 
 
 /**
@@ -38,6 +39,7 @@ export class DeleteHoldingDialogComponent
     numCopies: number;
     numSucceeded: number;
     numFailed: number;
+    deleteEventDesc: string;
 
     @ViewChild('successMsg', { static: true })
         private successMsg: StringComponent;
@@ -45,6 +47,9 @@ export class DeleteHoldingDialogComponent
     @ViewChild('errorMsg', { static: true })
         private errorMsg: StringComponent;
 
+    @ViewChild('confirmOverride', {static: false})
+        private confirmOverride: ConfirmDialogComponent;
+
     constructor(
         private modal: NgbModal, // required for passing to parent
         private toast: ToastService,
@@ -89,23 +94,28 @@ export class DeleteHoldingDialogComponent
         return super.open(args);
     }
 
-    deleteHoldings() {
+    deleteHoldings(override?: boolean) {
+
+        this.deleteEventDesc = '';
 
-        const flags = {
+        const flags: any = {
             force_delete_copies: this.forceDeleteCopies
         };
 
+        let method = 'open-ils.cat.asset.volume.fleshed.batch.update';
+        if (override) {
+            method = `${method}.override`;
+            flags.events = ['TITLE_LAST_COPY', 'COPY_DELETE_WARNING'];
+        }
+
         this.net.request(
-            'open-ils.cat',
-            'open-ils.cat.asset.volume.fleshed.batch.update.override',
+            'open-ils.cat', method,
             this.auth.token(), this.callNums, 1, flags
         ).toPromise().then(
             result => {
                 const evt = this.evt.parse(result);
                 if (evt) {
-                    console.warn(evt);
-                    this.errorMsg.current().then(msg => this.toast.warning(msg));
-                    this.numFailed++;
+                    this.handleDeleteEvent(evt, override);
                 } else {
                     this.numSucceeded++;
                     this.close(this.numSucceeded > 0);
@@ -118,6 +128,29 @@ export class DeleteHoldingDialogComponent
             }
         );
     }
+
+    handleDeleteEvent(evt: EgEvent, override?: boolean): Promise<any> {
+
+        if (override) { // override failed
+            console.warn(evt);
+            this.numFailed++;
+            return this.errorMsg.current().then(msg => this.toast.warning(msg));
+        }
+
+        this.deleteEventDesc = evt.desc;
+
+        return this.confirmOverride.open().toPromise().then(confirmed => {
+            if (confirmed) {
+                return this.deleteHoldings(true);
+
+            } else {
+                // User canceled the delete confirmation dialog
+                this.numFailed++;
+                this.errorMsg.current().then(msg => this.toast.warning(msg));
+                this.close(this.numSucceeded > 0);
+            }
+        });
+    }
 }
 
 
diff --git a/Open-ILS/src/eg2/src/app/staff/share/op-change/op-change.component.ts b/Open-ILS/src/eg2/src/app/staff/share/op-change/op-change.component.ts
index 95d4db87e7..7b854ab599 100644
--- a/Open-ILS/src/eg2/src/app/staff/share/op-change/op-change.component.ts
+++ b/Open-ILS/src/eg2/src/app/staff/share/op-change/op-change.component.ts
@@ -3,6 +3,7 @@ import {ToastService} from '@eg/share/toast/toast.service';
 import {AuthService} from '@eg/core/auth.service';
 import {DialogComponent} from '@eg/share/dialog/dialog.component';
 import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
+import {NetRequest, NetService} from '@eg/core/net.service';
 
 @Component({
   selector: 'eg-op-change',
@@ -19,16 +20,18 @@ export class OpChangeComponent
     @Input() successMessage: string;
     @Input() failMessage: string;
 
+    requestToEscalate: NetRequest;
+
     constructor(
         private modal: NgbModal, // required for passing to parent
         private renderer: Renderer2,
         private toast: ToastService,
+        private net: NetService,
         private auth: AuthService) {
         super(modal);
     }
 
     ngOnInit() {
-
         // Focus the username any time the dialog is opened.
         this.onOpen$.subscribe(
             val => this.renderer.selectRootElement('#username').focus()
@@ -56,6 +59,10 @@ export class OpChangeComponent
                     ok2 => {
                         this.close();
                         this.toast.success(this.successMessage);
+                        if (this.requestToEscalate) {
+                            // Allow a breath for the dialog to clean up.
+                            setTimeout(() => this.sendEscalatedRequest());
+                        }
                     }
                 );
             },
@@ -72,6 +79,37 @@ export class OpChangeComponent
             err => this.toast.danger(this.failMessage)
         );
     }
+
+    escalateRequest(req: NetRequest) {
+        this.requestToEscalate = req;
+        this.open({});
+    }
+
+    // Resend a net request using the credentials just created
+    // via operator change.
+    sendEscalatedRequest() {
+        const sourceReq = this.requestToEscalate;
+        delete this.requestToEscalate;
+
+        console.debug('Op-Change escalating request', sourceReq);
+
+        // Clone the source request, modifying the params to
+        // use the op-change'd authtoken
+        const req = new NetRequest(
+            sourceReq.service,
+            sourceReq.method,
+            [this.auth.token()].concat(sourceReq.params.splice(1))
+        );
+
+        // Relay responses received for our escalated request to
+        // the caller via the original request observer.
+        this.net.requestCompiled(req)
+        .subscribe(
+            res => sourceReq.observer.next(res),
+            err => sourceReq.observer.error(err),
+            ()  => sourceReq.observer.complete()
+        ).add(_ => this.auth.undoOpChange());
+    }
 }
 
 

-----------------------------------------------------------------------

Summary of changes:
 Open-ILS/src/eg2/src/app/core/auth.service.ts      |  5 +++
 Open-ILS/src/eg2/src/app/core/net.service.ts       |  2 +-
 Open-ILS/src/eg2/src/app/staff/nav.component.ts    | 24 +++++++++-
 .../holdings/delete-volcopy-dialog.component.html  | 51 ++++++++++++----------
 .../holdings/delete-volcopy-dialog.component.ts    | 49 +++++++++++++++++----
 .../staff/share/op-change/op-change.component.ts   | 40 ++++++++++++++++-
 6 files changed, 135 insertions(+), 36 deletions(-)


hooks/post-receive
-- 
Evergreen ILS


More information about the open-ils-commits mailing list