From 6516659d05dc80d3169462ee91a62e5cfd134292 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Mon, 13 Sep 2021 14:17:16 -0400 Subject: [PATCH] LP1846552 Shelving Location Order Angular UI Ports the copy shelving location order interface to Angular. Admin => Local Admin => Shelving Location Order. Signed-off-by: Bill Erickson Signed-off-by: Mike Rylander --- Open-ILS/src/eg2/src/app/core/pcrud.service.ts | 2 +- .../admin/local/admin-local-splash.component.html | 2 +- .../copy-loc-order-routing.module.ts | 15 ++ .../copy-loc-order/copy-loc-order.component.css | 7 + .../copy-loc-order/copy-loc-order.component.html | 59 ++++++ .../copy-loc-order/copy-loc-order.component.ts | 198 +++++++++++++++++++++ .../local/copy-loc-order/copy-loc-order.module.ts | 23 +++ .../src/app/staff/admin/local/routing.module.ts | 4 + 8 files changed, 308 insertions(+), 2 deletions(-) create mode 100644 Open-ILS/src/eg2/src/app/staff/admin/local/copy-loc-order/copy-loc-order-routing.module.ts create mode 100644 Open-ILS/src/eg2/src/app/staff/admin/local/copy-loc-order/copy-loc-order.component.css create mode 100644 Open-ILS/src/eg2/src/app/staff/admin/local/copy-loc-order/copy-loc-order.component.html create mode 100644 Open-ILS/src/eg2/src/app/staff/admin/local/copy-loc-order/copy-loc-order.component.ts create mode 100644 Open-ILS/src/eg2/src/app/staff/admin/local/copy-loc-order/copy-loc-order.module.ts diff --git a/Open-ILS/src/eg2/src/app/core/pcrud.service.ts b/Open-ILS/src/eg2/src/app/core/pcrud.service.ts index 7fb0c7ccf6..d95869edd7 100644 --- a/Open-ILS/src/eg2/src/app/core/pcrud.service.ts +++ b/Open-ILS/src/eg2/src/app/core/pcrud.service.ts @@ -299,7 +299,7 @@ export class PcrudContext { if (action === 'auto') { // object does not need updating; move along - this.nextCudRequest(); + return this.nextCudRequest(); } } diff --git a/Open-ILS/src/eg2/src/app/staff/admin/local/admin-local-splash.component.html b/Open-ILS/src/eg2/src/app/staff/admin/local/admin-local-splash.component.html index b852b981bc..5ab24963ad 100644 --- a/Open-ILS/src/eg2/src/app/staff/admin/local/admin-local-splash.component.html +++ b/Open-ILS/src/eg2/src/app/staff/admin/local/admin-local-splash.component.html @@ -61,7 +61,7 @@ + routerLink="/staff/admin/local/asset/copy_location_order"> + + + + +
+
+
Context Org Unit
+
+ + +
+
+ + + + + + Selected: {{selected().location().name()}} + ({{orgSn(selected().location().owning_lib())}}) + +
+
+ +
+
+ +
+ Select a shelving location below and use the arrows above to change its position. +
+ +
    +
  1. +
    +
    + + + {{entry.location().name()}} ({{orgSn(entry.location().owning_lib())}}) + +
    +
    +
  2. +
+ diff --git a/Open-ILS/src/eg2/src/app/staff/admin/local/copy-loc-order/copy-loc-order.component.ts b/Open-ILS/src/eg2/src/app/staff/admin/local/copy-loc-order/copy-loc-order.component.ts new file mode 100644 index 0000000000..56e9b1a341 --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/admin/local/copy-loc-order/copy-loc-order.component.ts @@ -0,0 +1,198 @@ +import {Component, Input, ViewChild, OnInit} from '@angular/core'; +import {tap, concatMap} from 'rxjs/operators'; +import {IdlService, IdlObject} from '@eg/core/idl.service'; +import {NgbTabset, NgbTabChangeEvent} from '@ng-bootstrap/ng-bootstrap'; +import {OrgService} from '@eg/core/org.service'; +import {AuthService} from '@eg/core/auth.service'; +import {PcrudService} from '@eg/core/pcrud.service'; +import {ToastService} from '@eg/share/toast/toast.service'; +import {StringComponent} from '@eg/share/string/string.component'; +import {StringService} from '@eg/share/string/string.service'; +import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component'; +import {FmRecordEditorComponent} from '@eg/share/fm-editor/fm-editor.component'; +import {ComboboxEntry} from '@eg/share/combobox/combobox.component'; + +@Component({ + templateUrl: './copy-loc-order.component.html', + styleUrls: ['copy-loc-order.component.css'] +}) +export class CopyLocOrderComponent implements OnInit { + + @ViewChild('editString') editString: StringComponent; + /* + @ViewChild('errorString') errorString: StringComponent; + @ViewChild('delConfirm') delConfirm: ConfirmDialogComponent; + */ + + locations: {[id: number]: IdlObject} = {}; + entries: IdlObject[] = []; + contextOrg: number; + selectedEntry: number; + + constructor( + private idl: IdlService, + private org: OrgService, + private auth: AuthService, + private pcrud: PcrudService, + private strings: StringService, + private toast: ToastService + ) {} + + ngOnInit() { + this.contextOrg = Number(this.auth.user().ws_ou()); + this.load(); + } + + load(): Promise { + + this.entries = []; + this.locations = {}; + + return this.pcrud.search('acpl', + {owning_lib: this.org.ancestors(this.contextOrg, true)}) + .pipe(tap(loc => this.locations[loc.id()] = loc)) + .toPromise() + + .then(_ => { + + return this.pcrud.search('acplo', + {org: this.contextOrg}, + {order_by: {acplo: 'position'}}, + {authoritative: true} + ) + .pipe(tap(e => { + e.position(Number(e.position())); + e.location(this.locations[e.location()]); + this.entries.push(e); + })) + .toPromise(); + }) + + .then(_ => { + + if (this.entries.length > 0) { return; } + + // If we have no position entries, create some now so they + // can become the basis of our new list. + + const locs = Object.values(this.locations) + .sort((o1, o2) => o1.name() < o2.name() ? -1 : 1); + + let pos = 1; + locs.forEach(loc => { + const entry = this.idl.create('acplo'); + entry.isnew(true); + entry.id(-pos); // avoid using '0' as an ID + entry.location(loc); + entry.position(pos++); + entry.org(this.contextOrg); + this.entries.push(entry); + }); + }); + } + + orgChanged(org: IdlObject) { + if (org && org.id() !== this.contextOrg) { + this.contextOrg = org.id(); + this.load(); + } + } + + orgSn(id: number): string { + return this.org.get(id).shortname(); + } + + setPositions() { + let pos = 1; + this.entries.forEach(e => { + if (e.position() !== pos) { + e.ischanged(true); + e.position(pos); + } + pos++; + }); + } + + up(toTop?: boolean) { + if (!this.selectedEntry) { return; } + + for (let idx = 0; idx < this.entries.length; idx++) { + const entry = this.entries[idx]; + + if (entry.id() === this.selectedEntry) { + + if (toTop) { + this.entries.splice(idx, 1); + this.entries.unshift(entry); + + } else { + + if (idx === 0) { + // We're already at the top of the list. + // No where to go but down. + return; + } + + // Swap places with the preceding entry + this.entries[idx] = this.entries[idx - 1]; + this.entries[idx - 1] = entry; + } + + break; + } + } + + this.setPositions(); + } + + down(toBottom?: boolean) { + if (!this.selectedEntry) { return; } + + for (let idx = 0; idx < this.entries.length; idx++) { + const entry = this.entries[idx]; + + if (entry.id() === this.selectedEntry) { + + if (toBottom) { + this.entries.splice(idx, 1); + this.entries.push(entry); + + } else { + + if (idx === this.entries.length - 1) { + // We're already at the bottom of the list. + // No where to go but up. + return; + } + + this.entries[idx] = this.entries[idx + 1]; + this.entries[idx + 1] = entry; + } + break; + } + } + + this.setPositions(); + } + + changesPending(): boolean { + return this.entries.filter(e => (e.isnew() || e.ischanged())).length > 0; + } + + selected(): IdlObject { + return this.entries.filter(e => e.id() === this.selectedEntry)[0]; + } + + save() { + // Scrub our temp ID's + this.entries.forEach(e => { if (e.isnew()) { e.id(null); } }); + + this.pcrud.autoApply(this.entries).toPromise() + .then(_ => { + this.selectedEntry = null; + this.load().then(__ => this.toast.success(this.editString.text)); + }); + } +} + + diff --git a/Open-ILS/src/eg2/src/app/staff/admin/local/copy-loc-order/copy-loc-order.module.ts b/Open-ILS/src/eg2/src/app/staff/admin/local/copy-loc-order/copy-loc-order.module.ts new file mode 100644 index 0000000000..ba8c5018d5 --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/admin/local/copy-loc-order/copy-loc-order.module.ts @@ -0,0 +1,23 @@ +import {NgModule} from '@angular/core'; +import {AdminCommonModule} from '@eg/staff/admin/common.module'; +import {CopyLocOrderRoutingModule} from './copy-loc-order-routing.module'; +import {CopyLocOrderComponent} from './copy-loc-order.component'; + +@NgModule({ + declarations: [ + CopyLocOrderComponent + ], + imports: [ + AdminCommonModule, + CopyLocOrderRoutingModule + ], + exports: [ + ], + providers: [ + ] +}) + +export class CopyLocOrderModule { +} + + diff --git a/Open-ILS/src/eg2/src/app/staff/admin/local/routing.module.ts b/Open-ILS/src/eg2/src/app/staff/admin/local/routing.module.ts index c3dd98edc5..a2eb2ff84b 100644 --- a/Open-ILS/src/eg2/src/app/staff/admin/local/routing.module.ts +++ b/Open-ILS/src/eg2/src/app/staff/admin/local/routing.module.ts @@ -18,6 +18,10 @@ const routes: Routes = [{ path: 'actor/address_alert', component: AddressAlertComponent }, { + path: 'asset/copy_location_order', + loadChildren: () => + import('./copy-loc-order/copy-loc-order.module').then(m => m.CopyLocOrderModule) +}, { path: 'asset/copy_location', component: BasicAdminPageComponent, data: [{ -- 2.11.0