LP#1942220: add confirmation step to deleting LIs
authorGalen Charlton <gmc@equinoxOLI.org>
Tue, 7 Dec 2021 19:25:42 +0000 (14:25 -0500)
committerBill Erickson <berickxx@gmail.com>
Thu, 12 May 2022 14:27:29 +0000 (10:27 -0400)
- also tidy up when the action is avaialble
- also tidy up handling of selected LIs post-deletion
- also reload the page only once
- add TODO about decreasing parallelism
- TODO: toss up spinner?

Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>
Open-ILS/src/eg2/src/app/staff/acq/lineitem/delete-lineitems-dialog.component.html [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/acq/lineitem/delete-lineitems-dialog.component.ts [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/acq/lineitem/lineitem-list.component.html
Open-ILS/src/eg2/src/app/staff/acq/lineitem/lineitem-list.component.ts
Open-ILS/src/eg2/src/app/staff/acq/lineitem/lineitem.module.ts

diff --git a/Open-ILS/src/eg2/src/app/staff/acq/lineitem/delete-lineitems-dialog.component.html b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/delete-lineitems-dialog.component.html
new file mode 100644 (file)
index 0000000..c819dc0
--- /dev/null
@@ -0,0 +1,28 @@
+<ng-template #dialogContent>
+  <form class="form-validated">
+    <div class="modal-header bg-info">
+      <h3 class="modal-title" i18n>Confirm Deletion of Lineitems</h3>
+      <button type="button" class="close"
+        i18n-aria-label aria-label="Close" (click)="close()">
+        <span aria-hidden="true">&times;</span>
+      </button>
+    </div>
+    <div class="modal-body">
+      <h4 i18n>Lineitem(s) selected:
+        <span *ngFor="let id of ids; last as isLast">
+          {{id}}<span *ngIf="!isLast">,</span>
+        </span>
+      </h4>
+      <h4 i18n>Are you sure you want to delete the selected lineitems?</h4>
+      <h4 i18n>Please click "Apply" to delete lineitems or "Exit Dialog"
+               to exit without deleting lineitems.</h4>
+    </div>
+    <div class="modal-footer">
+      <button type="button" class="btn btn-success"
+        (click)="close(true)" i18n>Apply</button>
+      <button type="button" class="btn btn-warning"
+        (click)="close()" i18n>Exit Dialog</button>
+    </div>
+  </form>
+</ng-template>
+
diff --git a/Open-ILS/src/eg2/src/app/staff/acq/lineitem/delete-lineitems-dialog.component.ts b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/delete-lineitems-dialog.component.ts
new file mode 100644 (file)
index 0000000..21c6ece
--- /dev/null
@@ -0,0 +1,17 @@
+import {Component, Input, ViewChild, TemplateRef, OnInit} from '@angular/core';
+import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
+import {DialogComponent} from '@eg/share/dialog/dialog.component';
+import {IdlService, IdlObject} from '@eg/core/idl.service';
+import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
+
+@Component({
+  selector: 'eg-acq-delete-lineitems-dialog',
+  templateUrl: './delete-lineitems-dialog.component.html'
+})
+
+export class DeleteLineitemsDialogComponent extends DialogComponent {
+    @Input() ids: number[];
+    constructor(private modal: NgbModal) { super(modal); }
+}
+
+
index c4e3c8d..a560505 100644 (file)
@@ -1,6 +1,7 @@
 
 <!-- BATCH ACTIONS -->
 <eg-acq-cancel-dialog recordType="li" #cancelDialog></eg-acq-cancel-dialog>
+<eg-acq-delete-lineitems-dialog #deleteLineitemsDialog></eg-acq-delete-lineitems-dialog>
 <eg-acq-claim-policy-dialog #claimPolicyDialog></eg-acq-claim-policy-dialog>
 
 <div class="row mt-3" *ngIf="poId || picklistId">
@@ -11,7 +12,7 @@
         <a ngbDropdownItem routerLink="../brief-record"
           queryParamsHandling="merge" i18n>Add Brief Record</a>
         <button ngbDropdownItem (click)="deleteLineitems()" 
-          [disabled]="!canDeleteLis()" i18n>Delete Selected Lineitems</button>
+          [disabled]="!canDeleteLis() || !selectedIds().length" i18n>Delete Selected Lineitems</button>
         <div class="dropdown-divider"></div>
         <h6 class="dropdown-header" i18n>Selection List Actions</h6>
         <button ngbDropdownItem (click)="createPo()" 
index 3a0bc03..c739bb3 100644 (file)
@@ -1,6 +1,6 @@
 import {Component, OnInit, Input, Output, ViewChild} from '@angular/core';
 import {Router, ActivatedRoute, ParamMap} from '@angular/router';
-import {Observable, from} from 'rxjs';
+import {Observable, from, of} from 'rxjs';
 import {tap, concatMap} from 'rxjs/operators';
 import {Pager} from '@eg/share/util/pager';
 import {EgEvent, EventService} from '@eg/core/event.service';
@@ -12,6 +12,7 @@ import {LineitemService} from './lineitem.service';
 import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
 import {HoldingsService} from '@eg/staff/share/holdings/holdings.service';
 import {CancelDialogComponent} from './cancel-dialog.component';
+import {DeleteLineitemsDialogComponent} from './delete-lineitems-dialog.component';
 import {ClaimPolicyDialogComponent} from './claim-policy-dialog.component';
 
 const DELETABLE_STATES = [
@@ -104,6 +105,7 @@ export class LineitemListComponent implements OnInit {
                       // TODO: route guard might be better
 
     @ViewChild('cancelDialog') cancelDialog: CancelDialogComponent;
+    @ViewChild('deleteLineitemsDialog') deleteLineitemsDialog: DeleteLineitemsDialogComponent;
     @ViewChild('claimPolicyDialog') claimPolicyDialog: ClaimPolicyDialogComponent;
 
     constructor(
@@ -617,16 +619,29 @@ export class LineitemListComponent implements OnInit {
     deleteLineitems() {
         const ids = Object.keys(this.selected).filter(id => this.selected[id]);
 
-        const method = this.poId ?
-            'open-ils.acq.purchase_order.lineitem.delete' :
-            'open-ils.acq.picklist.lineitem.delete';
-
-        from(ids)
-        .pipe(concatMap(id =>
-            this.net.request('open-ils.acq', method, this.auth.token(), id)
-        ))
-        .pipe(concatMap(_ => from(this.load())))
-        .subscribe();
+        this.deleteLineitemsDialog.ids = ids.map(i => Number(i));
+        this.deleteLineitemsDialog.open().subscribe(doIt => {
+            if (!doIt) { return; }
+
+            const method = this.poId ?
+                'open-ils.acq.purchase_order.lineitem.delete' :
+                'open-ils.acq.picklist.lineitem.delete';
+
+            from(ids)
+            .pipe(concatMap(id =>
+                this.net.request('open-ils.acq', method, this.auth.token(), id)
+                // TODO: cap parallelism
+            ))
+            .pipe(concatMap(_ => of(true) ))
+            .subscribe(r => {}, err => {}, () => {
+                ids.forEach(id => {
+                    delete this.liService.liCache[id];
+                    delete this.selected[id];
+                });
+                this.batchSelectAll = false;
+                this.load();
+            });
+        });
     }
 
     liHasRealCopies(li: IdlObject): boolean {
index e86b6af..db48e9d 100644 (file)
@@ -16,6 +16,7 @@ import {LineitemCopyAttrsComponent} from './copy-attrs.component';
 import {LineitemHistoryComponent} from './history.component';
 import {BriefRecordComponent} from './brief-record.component';
 import {CancelDialogComponent} from './cancel-dialog.component';
+import {DeleteLineitemsDialogComponent} from './delete-lineitems-dialog.component';
 import {ClaimPolicyDialogComponent} from './claim-policy-dialog.component';
 import {MarcEditModule} from '@eg/staff/share/marc-edit/marc-edit.module';
 
@@ -31,6 +32,7 @@ import {MarcEditModule} from '@eg/staff/share/marc-edit/marc-edit.module';
     LineitemCopyAttrsComponent,
     LineitemHistoryComponent,
     CancelDialogComponent,
+    DeleteLineitemsDialogComponent,
     ClaimPolicyDialogComponent,
     BriefRecordComponent,
     LineitemWorksheetComponent
@@ -38,6 +40,7 @@ import {MarcEditModule} from '@eg/staff/share/marc-edit/marc-edit.module';
   exports: [
     LineitemListComponent,
     CancelDialogComponent,
+    DeleteLineitemsDialogComponent,
     ClaimPolicyDialogComponent
   ],
   imports: [