LPXXX Angular Volcopy
authorBill Erickson <berickxx@gmail.com>
Tue, 9 Jun 2020 17:12:03 +0000 (13:12 -0400)
committerBill Erickson <berickxx@gmail.com>
Tue, 9 Jun 2020 17:12:03 +0000 (13:12 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/staff/cat/volcopy/vol-edit.component.css
Open-ILS/src/eg2/src/app/staff/cat/volcopy/vol-edit.component.html
Open-ILS/src/eg2/src/app/staff/cat/volcopy/vol-edit.component.ts
Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.component.html
Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.component.ts

index c109cac..fabadae 100644 (file)
@@ -9,3 +9,18 @@ input[type="number"] {
   border-top: 1px solid rgba(0,0,0,.125);
   border-bottom: 1px solid rgba(0,0,0,.125);
 }
+
+
+.clear-button {
+  border: none;
+  background-color: rgba(0, 0, 0, 0.0);
+  padding-left: .25rem;
+  padding-right: .25rem;
+  line-height: inherit;
+}
+
+.clear-button .material-icons {
+  font-size: 15px;
+  color: grey;
+}
+
index 0360b00..30d7e78 100644 (file)
@@ -1,3 +1,9 @@
+<eg-confirm-dialog 
+  #confirmDelVol
+  i18n-dialogTitle i18n-dialogBody
+  dialogTitle="Delete Call Number?"
+  dialogBody="Delete {{deleteVolCount}} Call Number(s) and {{deleteCopyCount}} Associated Item(s)?">
+</eg-confirm-dialog>
 
 <div class="row d-flex vol-row border border-info mb-2">
   <div class="p-1" [ngStyle]="{flex: flexAt(1)}">
     <ng-container *ngFor="let copyNode of volNode.children; let copyIdx = index">
       <div class="row d-flex mt-1" [ngClass]="{'vol-row': copyIdx == 0}">
         <div class="p-1" [ngStyle]="{flex: flexAt(1)}">
-          <span *ngIf="copyIdx == 0">{{orgNode.target.shortname()}}</span>
+          <ng-container *ngIf="copyIdx == 0">
+            <span>{{orgNode.target.shortname()}}</span>
+            <button class="clear-button" (click)="deleteVol(volNode)"
+              title="Delete Call Number" i18n-title>
+              <span class="material-icons">clear</span>
+            </button>
+          </ng-container>
         </div>
         <div class="p-1" [ngStyle]="{flex: flexAt(2)}">
           <ng-container *ngIf="copyIdx == 0 && volIdx == 0">
                                                (ngModelChange)="barcodeChanged(copyNode.target, $event)"
             (keyup.enter)="selectNextBarcode(copyNode.target.id())"
             (keyup.shift.enter)="selectNextBarcode(copyNode.target.id(), true)"
+            (focus)="$event.target.select()"
             [ngModel]="copyNode.target.barcode()"
             (ngModelChange)="applyCopyValue(copyNode.target, 'barcode', $event)"/>
           <div *ngIf="copyNode.target._dupe_barcode"
index 46d3dff..4c3f715 100644 (file)
@@ -9,6 +9,7 @@ import {PcrudService} from '@eg/core/pcrud.service';
 import {VolCopyContext, HoldingsTreeNode} from './volcopy';
 import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
 import {HoldingsService} from '@eg/staff/share/holdings/holdings.service';
+import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component';
 
 @Component({
   selector: 'eg-vol-edit',
@@ -45,6 +46,14 @@ export class VolEditComponent implements OnInit {
 
     autoId = -1;
 
+    volsToDelete: IdlObject[] = [];
+    copiesToDelete: IdlObject[] = [];
+    deleteVolCount: number = null;
+    deleteCopyCount: number = null;
+
+    @ViewChild('confirmDelVol', {static: false})
+        confirmDelVol: ConfirmDialogComponent;
+
     constructor(
         private renderer: Renderer2,
         private idl: IdlService,
@@ -56,6 +65,11 @@ export class VolEditComponent implements OnInit {
 
     ngOnInit() {
 
+        this.volsToDelete = [];
+        this.copiesToDelete = [];
+        this.deleteVolCount = null;
+        this.deleteCopyCount = null;
+
         this.fetchRecordVolLabels()
         .then(_ => this.fetchBibParts())
         .then(_ => this.addStubCopies());
@@ -411,5 +425,62 @@ export class VolEditComponent implements OnInit {
             });
         }
     }
+
+    deleteVol(volNode: HoldingsTreeNode) {
+        this.deleteVolCount = 1;
+        this.deleteCopyCount = volNode.children.length;
+
+        this.confirmDelVol.open().toPromise().then(confirmed => {
+            if (confirmed) { this.deleteOneVol(volNode); }
+        });
+    }
+
+    deleteOneVol(volNode: HoldingsTreeNode) {
+        let deleteVolIdx = null;
+        const targetVol = volNode.target;
+
+        // FOR loops allow for early exit
+        const orgNodes = this.context.orgNodes();
+        for (let orgIdx = 0; orgIdx < orgNodes.length; orgIdx++) {
+            const orgNode = orgNodes[orgIdx];
+
+            for (let volIdx = 0; volIdx < orgNode.children.length; volIdx++) {
+                const vol = orgNode.children[volIdx].target;
+
+                if (vol.id() === targetVol.id()) {
+                    deleteVolIdx = volIdx;
+
+                    if (vol.isnew()) {
+                        // New volumes, which can only have new copies
+                        // may simply be removed from the holdings
+                        // tree to delete them.
+                        break;
+                    }
+
+                    // Mark volume and attached copies as deleted
+                    // and track for later deletion.
+                    targetVol.isdeleted(true);
+                    this.volsToDelete.push(targetVol);
+
+                    volNode.children.forEach(copyNode => {
+                        const copy = copyNode.target;
+                        if (copy.isnew()) {
+                            // New copies can simply be discarded.
+                        } else {
+                            copy.isdeleted(true);
+                            this.copiesToDelete.push(copy);
+                        }
+                    });
+                }
+
+                if (deleteVolIdx) { break; }
+            }
+
+            if (deleteVolIdx !== null) {
+                orgNode.children.splice(deleteVolIdx, 1);
+                break;
+            }
+        }
+    }
 }
 
index df54f57..274eb68 100644 (file)
@@ -1,5 +1,13 @@
 <eg-staff-banner bannerText="Holdings Editor" i18n-bannerText></eg-staff-banner>
 
+<ng-container *ngIf="loading">
+  <div class="row">
+    <div class="col-lg-6 offset-lg-3">
+      <eg-progress-inline #loadingProgress></eg-progress-inline>
+    </div>
+  </div>
+</ng-container>
+
 <ng-container *ngIf="!loading">
 
   <eg-bib-summary *ngIf="recordId" [recordId]="recordId"></eg-bib-summary>
index a080c3f..f0916c4 100644 (file)
@@ -6,6 +6,7 @@ import {OrgService} from '@eg/core/org.service';
 import {PcrudService} from '@eg/core/pcrud.service';
 import {HoldingsService} from '@eg/staff/share/holdings/holdings.service';
 import {VolCopyContext} from './volcopy';
+import {ProgressInlineComponent} from '@eg/share/dialog/progress-inline.component';
 
 const COPY_FLESH = {
     flesh: 1,
@@ -32,6 +33,8 @@ export class VolCopyComponent implements OnInit {
 
     session: string;
     loading = true;
+    @ViewChild('loadingProgress', {static: false})
+    loadingProgress: ProgressInlineComponent;
 
     constructor(
         private router: Router,
@@ -62,11 +65,17 @@ export class VolCopyComponent implements OnInit {
         this.loading = true;
         this.context.reset();
         this.fetchHoldings()
+        .then(_ => this.loadingProgress.increment())
         .then(_ => this.holdings.fetchCallNumberClasses())
+        .then(_ => this.loadingProgress.increment())
         .then(_ => this.holdings.fetchCallNumberPrefixes())
+        .then(_ => this.loadingProgress.increment())
         .then(_ => this.holdings.fetchCallNumberSuffixes())
+        .then(_ => this.loadingProgress.increment())
         .then(_ => this.context.sortHoldings())
+        .then(_ => this.loadingProgress.increment())
         .then(_ => this.setRecordId())
+        .then(_ => this.loadingProgress.increment())
         .then(_ => this.loading = false);
     }