LPXXX Item Status Angular WIP
authorBill Erickson <berickxx@gmail.com>
Wed, 16 Jun 2021 21:55:08 +0000 (17:55 -0400)
committerBill Erickson <berickxx@gmail.com>
Tue, 29 Jun 2021 20:31:33 +0000 (16:31 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/staff/cat/item/item.module.ts
Open-ILS/src/eg2/src/app/staff/cat/item/routing.module.ts
Open-ILS/src/eg2/src/app/staff/cat/item/status.component.html [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/cat/item/status.component.ts [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/cat/item/summary.component.html [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/cat/item/summary.component.ts [new file with mode: 0644]

index 9c501fb..9da2992 100644 (file)
@@ -5,16 +5,22 @@ import {ItemRoutingModule} from './routing.module';
 import {HoldingsModule} from '@eg/staff/share/holdings/holdings.module';
 import {PatronModule} from '@eg/staff/share/patron/patron.module';
 import {MarkItemMissingPiecesComponent} from './missing-pieces.component';
+import {ItemStatusComponent} from './status.component';
+import {BarcodesModule} from '@eg/staff/share/barcodes/barcodes.module';
+import {ItemSummaryComponent} from './summary.component';
 
 @NgModule({
   declarations: [
-    MarkItemMissingPiecesComponent
+    MarkItemMissingPiecesComponent,
+    ItemSummaryComponent,
+    ItemStatusComponent
   ],
   imports: [
     StaffCommonModule,
     CommonWidgetsModule,
     ItemRoutingModule,
     HoldingsModule,
+    BarcodesModule,
     PatronModule
   ],
   providers: [
index b3e7759..c26e28f 100644 (file)
@@ -1,6 +1,7 @@
 import {NgModule} from '@angular/core';
 import {RouterModule, Routes} from '@angular/router';
 import {MarkItemMissingPiecesComponent} from './missing-pieces.component';
+import {ItemStatusComponent} from './status.component';
 
 const routes: Routes = [{
     path: 'missing_pieces',
@@ -8,6 +9,12 @@ const routes: Routes = [{
   }, {
     path: 'missing_pieces/:id',
     component: MarkItemMissingPiecesComponent
+  }, {
+    path: ':id/:tab',
+    component: ItemStatusComponent
+  }, {
+    path: ':id',
+    component: ItemStatusComponent
 }];
 
 @NgModule({
diff --git a/Open-ILS/src/eg2/src/app/staff/cat/item/status.component.html b/Open-ILS/src/eg2/src/app/staff/cat/item/status.component.html
new file mode 100644 (file)
index 0000000..ba0a811
--- /dev/null
@@ -0,0 +1,43 @@
+<eg-staff-banner i18n-bannerText bannerText="Item Status">
+</eg-staff-banner>
+
+<eg-barcode-select #barcodeSelect></eg-barcode-select>
+
+<div class="row">
+  <div class="col-lg-12 form-inline">
+    <div class="input-group">
+      <div class="input-group-prepend">
+        <span class="input-group-text" id='barcode-label' i18n>Barcode</span>
+      </div>
+      <input type="text" class="form-control" id="item-barcode-input" 
+        (keydown)="noSuchItem=false; true;"
+        (keyup.enter)="getItemByBarcode()" [(ngModel)]="itemBarcode" 
+        aria-describedby="barcode-label"/>
+    </div>
+    <button class="btn btn-outline-dark" 
+      (click)="getItemByBarcode()" i18n>Submit</button>
+  </div>
+</div>
+
+
+
+<div *ngIf="tab != 'list' && item">
+
+  <div class="mt-2 mb-2">
+    <eg-bib-summary [recordId]="item.call_number().record().id()">
+    </eg-bib-summary>
+  </div>
+
+  <ul ngbNav #itemNav="ngbNav" class="nav-tabs"
+    [activeId]="tab" (navChange)="tabChange($event)">
+    <li ngbNavItem="summary">
+      <a ngbNavLink i18n>Quick Summary</a>
+      <ng-template ngbNavContent>
+        <eg-item-summary [item]="item"></eg-item-summary>
+      </ng-template>
+    </li>
+  </ul>
+  <div [ngbNavOutlet]="itemNav"></div>
+
+</div>
+
diff --git a/Open-ILS/src/eg2/src/app/staff/cat/item/status.component.ts b/Open-ILS/src/eg2/src/app/staff/cat/item/status.component.ts
new file mode 100644 (file)
index 0000000..0d0fa46
--- /dev/null
@@ -0,0 +1,140 @@
+import {Component, Input, OnInit, AfterViewInit, ViewChild} from '@angular/core';
+import {Router, ActivatedRoute, ParamMap} from '@angular/router';
+import {IdlObject} from '@eg/core/idl.service';
+import {PcrudService} from '@eg/core/pcrud.service';
+import {AuthService} from '@eg/core/auth.service';
+import {NetService} from '@eg/core/net.service';
+import {PrintService} from '@eg/share/print/print.service';
+import {HoldingsService} from '@eg/staff/share/holdings/holdings.service';
+import {EventService} from '@eg/core/event.service';
+import {PatronPenaltyDialogComponent} from '@eg/staff/share/patron/penalty-dialog.component';
+import {BarcodeSelectComponent} from '@eg/staff/share/barcodes/barcode-select.component';
+import {CatalogService} from '@eg/share/catalog/catalog.service';
+import {NgbNav, NgbNavChangeEvent} from '@ng-bootstrap/ng-bootstrap';
+
+@Component({
+  templateUrl: 'status.component.html'
+})
+
+export class ItemStatusComponent implements OnInit, AfterViewInit {
+
+    itemId: number;
+    itemBarcode: string;
+    noSuchItem = false;
+    item: IdlObject;
+    tab: string;
+
+    @ViewChild('barcodeSelect') barcodeSelect: BarcodeSelectComponent;
+
+    constructor(
+        private router: Router,
+        private route: ActivatedRoute,
+        private net: NetService,
+        private printer: PrintService,
+        private pcrud: PcrudService,
+        private auth: AuthService,
+        private evt: EventService,
+        private cat: CatalogService,
+        private holdings: HoldingsService
+    ) {}
+
+    ngOnInit() {
+
+        this.itemId = +this.route.snapshot.paramMap.get('id');
+        this.tab = this.route.snapshot.paramMap.get('tab');
+
+        if (!this.tab) {
+            if (this.itemId) {
+                this.router.navigate([`/staff/cat/item/${this.itemId}/summary`])
+                .then(ok => {if (ok) { this.load(); }});
+                return;
+            } else {
+                this.tab = 'list';
+            }
+        }
+
+        this.load();
+    }
+
+    load() {
+
+        this.cat.fetchCcvms()
+        .then(_ => this.cat.fetchCmfs())
+        .then(_ => {
+            if (this.itemId) {
+                return this.getItemById(this.itemId);
+            }
+        })
+        .then(_ => {
+            // Avoid watching for changes until after ngOnInit is complete
+            // so we don't grab the same copy twice.
+
+            this.route.paramMap.subscribe((params: ParamMap) => {
+                this.tab = params.get('tab');
+                const id = +params.get('id');
+
+                if (id !== this.itemId) {
+                    this.itemId = id;
+                    if (id) {
+                        this.getItemById(id);
+                    }
+                }
+            });
+        });
+    }
+
+    ngAfterViewInit() {
+        this.selectInput();
+    }
+
+    tabChange(evt: NgbNavChangeEvent) {
+        this.router.navigate([`/staff/cat/item/${this.itemId}/${evt.nextId}`]);
+    }
+
+    getItemByBarcode(): Promise<any> {
+        this.itemId = null;
+        this.item = null;
+
+        if (!this.itemBarcode) { return Promise.resolve(); }
+
+        return this.barcodeSelect.getBarcode('asset', this.itemBarcode)
+        .then(res => {
+            if (!res.id) {
+                this.noSuchItem = true;
+            } else {
+                this.itemBarcode = null;
+                this.selectInput();
+                return this.getItemById(res.id);
+            }
+        });
+    }
+
+    selectInput() {
+        setTimeout(() => {
+            const node: HTMLInputElement =
+                document.getElementById('item-barcode-input') as HTMLInputElement;
+            if (node) { node.select(); }
+        });
+    }
+
+    getItemById(id: number): Promise<any> {
+
+        const flesh = {
+            flesh: 3,
+            flesh_fields: {
+                acp: ['call_number'],
+                acn: ['record'],
+                bre: ['flat_display_entries']
+            }
+        };
+
+        return this.pcrud.retrieve('acp', this.itemId, flesh)
+        .toPromise().then(item => {
+            this.item = item;
+            this.itemId = item.id();
+            this.selectInput();
+        });
+    }
+}
+
+
diff --git a/Open-ILS/src/eg2/src/app/staff/cat/item/summary.component.html b/Open-ILS/src/eg2/src/app/staff/cat/item/summary.component.html
new file mode 100644 (file)
index 0000000..ac3fd69
--- /dev/null
@@ -0,0 +1 @@
+summary
diff --git a/Open-ILS/src/eg2/src/app/staff/cat/item/summary.component.ts b/Open-ILS/src/eg2/src/app/staff/cat/item/summary.component.ts
new file mode 100644 (file)
index 0000000..6fac2c1
--- /dev/null
@@ -0,0 +1,45 @@
+import {Component, Input, OnInit, AfterViewInit, ViewChild} from '@angular/core';
+import {Router, ActivatedRoute, ParamMap} from '@angular/router';
+import {IdlObject} from '@eg/core/idl.service';
+import {PcrudService} from '@eg/core/pcrud.service';
+import {AuthService} from '@eg/core/auth.service';
+import {NetService} from '@eg/core/net.service';
+import {PrintService} from '@eg/share/print/print.service';
+import {HoldingsService} from '@eg/staff/share/holdings/holdings.service';
+import {EventService} from '@eg/core/event.service';
+import {PatronPenaltyDialogComponent} from '@eg/staff/share/patron/penalty-dialog.component';
+import {BarcodeSelectComponent} from '@eg/staff/share/barcodes/barcode-select.component';
+import {CatalogService} from '@eg/share/catalog/catalog.service';
+import {NgbNav, NgbNavChangeEvent} from '@ng-bootstrap/ng-bootstrap';
+
+@Component({
+  selector: 'eg-item-summary',
+  templateUrl: 'summary.component.html'
+})
+
+export class ItemSummaryComponent implements OnInit {
+
+    @Input() item: IdlObject;
+
+    constructor(
+        private router: Router,
+        private route: ActivatedRoute,
+        private net: NetService,
+        private printer: PrintService,
+        private pcrud: PcrudService,
+        private auth: AuthService,
+        private evt: EventService,
+        private cat: CatalogService,
+        private holdings: HoldingsService
+    ) {}
+
+    ngOnInit() {
+
+    }
+
+
+    tabChange(evt: NgbNavChangeEvent) {
+        this.router.navigate([`/staff/cat/item/${this.item.id()}/${evt.nextId}`]);
+    }
+}
+