improve record retrieval and refreshes
authorGalen Charlton <gmc@equinoxinitiative.org>
Fri, 14 Aug 2020 22:44:48 +0000 (18:44 -0400)
committerGalen Charlton <gmc@equinoxinitiative.org>
Fri, 14 Aug 2020 22:44:48 +0000 (18:44 -0400)
- reduce the number of redundant fetches
- use subscriptions to inform child components when
  they need to refresh themselves

Signed-off-by: Galen Charlton <gmc@equinoxinitiative.org>
Open-ILS/src/eg2/src/app/staff/acq/provider/acq-provider.component.ts
Open-ILS/src/eg2/src/app/staff/acq/provider/provider-addresses.component.ts
Open-ILS/src/eg2/src/app/staff/acq/provider/provider-attributes.component.ts
Open-ILS/src/eg2/src/app/staff/acq/provider/provider-contacts.component.ts
Open-ILS/src/eg2/src/app/staff/acq/provider/provider-details.component.ts
Open-ILS/src/eg2/src/app/staff/acq/provider/provider-edi-accounts.component.ts
Open-ILS/src/eg2/src/app/staff/acq/provider/provider-holdings.component.ts
Open-ILS/src/eg2/src/app/staff/acq/provider/provider-invoices.component.ts
Open-ILS/src/eg2/src/app/staff/acq/provider/provider-purchase-orders.component.ts
Open-ILS/src/eg2/src/app/staff/acq/provider/provider-record.service.ts
Open-ILS/src/eg2/src/app/staff/acq/provider/summary-pane.component.ts

index b928e39..3130ccb 100644 (file)
@@ -1,4 +1,4 @@
-import {Component, OnInit, AfterViewInit, ViewChild} from '@angular/core';
+import {Component, OnInit, AfterViewInit, ViewChild, ChangeDetectorRef} from '@angular/core';
 import {NgbTabset, NgbTabChangeEvent} from '@ng-bootstrap/ng-bootstrap';
 import {Router, ActivatedRoute, ParamMap, RouterEvent, NavigationEnd} from '@angular/router';
 import {StaffCommonModule} from '@eg/staff/common.module';
@@ -43,7 +43,8 @@ export class AcqProviderComponent implements OnInit, AfterViewInit {
         private idl: IdlService,
         private providerRecord: ProviderRecordService,
         private toast: ToastService,
-        private store: StoreService
+        private store: StoreService,
+        private changeDetector: ChangeDetectorRef
     ) {
     }
 
@@ -86,19 +87,21 @@ export class AcqProviderComponent implements OnInit, AfterViewInit {
         };
 
         this.onDesireSummarize = ($event, updateSummaryOnly = false) => {
-            // $event is a provider ID
-            this.providerSummaryPane.update($event);
-            if (this.providerDetails) {
-                this.providerDetails.refresh();
-            }
-            if (updateSummaryOnly) {
-                return;
-            }
             this.id = $event;
-            this.providerRecord.fetch(this.id);
-            this.showSearchForm = false;
-            this.activeTab = this.defaultTabType;
-            this.router.navigate(['/staff', 'acq', 'provider', this.id, this.activeTab]);
+            this.providerRecord.fetch(this.id).then(() => {
+                // $event is a provider ID
+                this.providerSummaryPane.update($event);
+                if (this.providerDetails) {
+                    this.providerDetails.refresh();
+                }
+                if (updateSummaryOnly) {
+                    return;
+                }
+                this.providerRecord.announceProviderUpdated();
+                this.showSearchForm = false;
+                this.activeTab = this.defaultTabType;
+                this.router.navigate(['/staff', 'acq', 'provider', this.id, this.activeTab]);
+            });
         };
 
         this.onSummaryToggled = ($event) => {
@@ -106,7 +109,9 @@ export class AcqProviderComponent implements OnInit, AfterViewInit {
         };
     }
 
-    ngAfterViewInit() {}
+    ngAfterViewInit() {
+        this.changeDetector.detectChanges();
+    }
 
     setDefaultTab() {
         this.defaultTabType = this.activeTab;
index 4095c58..c13f661 100644 (file)
@@ -1,5 +1,5 @@
-import {Component, OnInit, AfterViewInit, Input, ViewChild} from '@angular/core';
-import {empty, throwError, Observable, from} from 'rxjs';
+import {Component, OnInit, AfterViewInit, OnDestroy, Input, ViewChild} from '@angular/core';
+import {empty, throwError, Observable, from, Subscription} from 'rxjs';
 import {map} from 'rxjs/operators';
 import {Router, ActivatedRoute, ParamMap} from '@angular/router';
 import {Pager} from '@eg/share/util/pager';
@@ -43,6 +43,8 @@ export class ProviderAddressesComponent implements OnInit, AfterViewInit {
 
     permissions: {[name: string]: boolean};
 
+    subscription: Subscription;
+
     // Size of create/edito dialog.  Uses large by default.
     @Input() dialogSize: 'sm' | 'lg' = 'lg';
 
@@ -83,12 +85,21 @@ export class ProviderAddressesComponent implements OnInit, AfterViewInit {
         this.providerAddressesGrid.onRowActivate.subscribe(
             (idlThing: IdlObject) => this.showEditDialog(idlThing)
         );
+        this.subscription = this.providerRecord.providerUpdated$.subscribe(
+            id => {
+                this.providerAddressesGrid.reload();
+            }
+        );
     }
 
     ngAfterViewInit() {
         console.log('this.providerRecord',this.providerRecord);
     }
 
+    ngOnDestroy() {
+        this.subscription.unsubscribe();
+    }
+
     generateSearch(filters): any {
         const query: any = new Array();
 
index 4c1d32d..b2cef2b 100644 (file)
@@ -1,5 +1,5 @@
-import {Component, OnInit, AfterViewInit, Input, ViewChild} from '@angular/core';
-import {empty, throwError, Observable, from} from 'rxjs';
+import {Component, OnInit, AfterViewInit, OnDestroy, Input, ViewChild} from '@angular/core';
+import {empty, throwError, Observable, from, Subscription} from 'rxjs';
 import {map} from 'rxjs/operators';
 import {Router, ActivatedRoute, ParamMap} from '@angular/router';
 import {Pager} from '@eg/share/util/pager';
@@ -43,6 +43,8 @@ export class ProviderAttributesComponent implements OnInit, AfterViewInit {
 
     permissions: {[name: string]: boolean};
 
+    subscription: Subscription;
+
     // Size of create/edito dialog.  Uses large by default.
     @Input() dialogSize: 'sm' | 'lg' = 'lg';
 
@@ -82,12 +84,22 @@ export class ProviderAttributesComponent implements OnInit, AfterViewInit {
         this.providerAttributesGrid.onRowActivate.subscribe(
             (idlThing: IdlObject) => this.showEditDialog(idlThing)
         );
+        this.subscription = this.providerRecord.providerUpdated$.subscribe(
+            id => {
+                this.providerAttributesGrid.reload();
+            }
+        );
+
     }
 
     ngAfterViewInit() {
         console.log('this.providerRecord',this.providerRecord);
     }
 
+    ngOnDestroy() {
+        this.subscription.unsubscribe();
+    }
+
     getDataSource(): GridDataSource {
         const gridSource = new GridDataSource();
 
index 091fa87..70ddbc5 100644 (file)
@@ -1,5 +1,5 @@
-import {Component, OnInit, AfterViewInit, Input, Output, ViewChild, EventEmitter, ChangeDetectorRef} from '@angular/core';
-import {empty, throwError, Observable, from} from 'rxjs';
+import {Component, OnInit, AfterViewInit, OnDestroy, Input, Output, ViewChild, EventEmitter, ChangeDetectorRef} from '@angular/core';
+import {empty, throwError, Observable, from, Subscription} from 'rxjs';
 import {map} from 'rxjs/operators';
 import {Router, ActivatedRoute, ParamMap} from '@angular/router';
 import {Pager} from '@eg/share/util/pager';
@@ -50,6 +50,8 @@ export class ProviderContactsComponent implements OnInit, AfterViewInit {
 
     permissions: {[name: string]: boolean};
 
+    subscription: Subscription;
+
     // Size of create/edito dialog.  Uses large by default.
     @Input() dialogSize: 'sm' | 'lg' = 'lg';
 
@@ -64,7 +66,6 @@ export class ProviderContactsComponent implements OnInit, AfterViewInit {
         private idl: IdlService,
         private providerRecord: ProviderRecordService,
         private toast: ToastService) {
-
     }
 
     ngOnInit() {
@@ -93,6 +94,11 @@ export class ProviderContactsComponent implements OnInit, AfterViewInit {
         this.providerContactsGrid.onRowActivate.subscribe(
             (idlThing: IdlObject) => this.showEditDialog(idlThing)
         );
+        this.subscription = this.providerRecord.providerUpdated$.subscribe(
+            id => {
+                this.providerContactsGrid.reload();
+            }
+        );
     }
 
     ngAfterViewInit() {
@@ -109,6 +115,10 @@ export class ProviderContactsComponent implements OnInit, AfterViewInit {
         );
     }
 
+    ngOnDestroy() {
+        this.subscription.unsubscribe();
+    }
+
     generateSearch(filters): any {
         const query: any = new Array();
 
index 4852fd4..fbcae5c 100644 (file)
@@ -54,18 +54,12 @@ export class ProviderDetailsComponent implements OnInit {
     }
 
     updateProvider(providerId: any) {
-        this.providerRecord.refreshCurrent().then(() => {
-            this.provider = this.providerRecord.current();
-            this._deflesh();
-            this.summarize.emit(this.provider.id());
-        });
+        this.summarize.emit(this.provider.id());
     }
 
     refresh() {
-        this.providerRecord.refreshCurrent().then(() => {
-            this.provider = this.providerRecord.current();
-            this._deflesh();
-        });
+        this.provider = this.idl.clone(this.providerRecord.current());
+        this._deflesh();
     }
 
 }
index 284d7c4..18ebd8b 100644 (file)
@@ -1,5 +1,5 @@
-import {Component, OnInit, AfterViewInit, Input, Output, EventEmitter, ViewChild, ChangeDetectorRef} from '@angular/core';
-import {empty, throwError, Observable, from} from 'rxjs';
+import {Component, OnInit, AfterViewInit, OnDestroy, Input, Output, EventEmitter, ViewChild, ChangeDetectorRef} from '@angular/core';
+import {empty, throwError, Observable, from, Subscription} from 'rxjs';
 import {map} from 'rxjs/operators';
 import {Router, ActivatedRoute, ParamMap} from '@angular/router';
 import {Pager} from '@eg/share/util/pager';
@@ -54,6 +54,8 @@ export class ProviderEdiAccountsComponent implements OnInit, AfterViewInit {
 
     permissions: {[name: string]: boolean};
 
+    subscription: Subscription;
+
     // Size of create/edito dialog.  Uses large by default.
     @Input() dialogSize: 'sm' | 'lg' = 'lg';
     @Output('desireSummarize') summarize: EventEmitter<number> = new EventEmitter<number>();
@@ -101,12 +103,21 @@ export class ProviderEdiAccountsComponent implements OnInit, AfterViewInit {
         this.providerEdiAccountsGrid.onRowActivate.subscribe(
             (idlThing: IdlObject) => this.showEditDialog(idlThing)
         );
+        this.subscription = this.providerRecord.providerUpdated$.subscribe(
+            id => {
+                this.providerEdiAccountsGrid.reload();
+            }
+        );
     }
 
     ngAfterViewInit() {
         console.log('this.providerRecord',this.providerRecord);
     }
 
+    ngOnDestroy() {
+        this.subscription.unsubscribe();
+    }
+
     getDataSource(): GridDataSource {
         const gridSource = new GridDataSource();
 
index 2599826..699b200 100644 (file)
@@ -1,5 +1,5 @@
-import {Component, OnInit, AfterViewInit, Input, ViewChild} from '@angular/core';
-import {empty, throwError, Observable, from} from 'rxjs';
+import {Component, OnInit, AfterViewInit, OnDestroy, Input, ViewChild} from '@angular/core';
+import {empty, throwError, Observable, from, Subscription} from 'rxjs';
 import {map} from 'rxjs/operators';
 import {Router, ActivatedRoute, ParamMap} from '@angular/router';
 import {Pager} from '@eg/share/util/pager';
@@ -43,6 +43,8 @@ export class ProviderHoldingsComponent implements OnInit, AfterViewInit {
 
     permissions: {[name: string]: boolean};
 
+    subscription: Subscription;
+
     // Size of create/edito dialog.  Uses large by default.
     @Input() dialogSize: 'sm' | 'lg' = 'lg';
 
@@ -82,12 +84,22 @@ export class ProviderHoldingsComponent implements OnInit, AfterViewInit {
         this.providerHoldingsGrid.onRowActivate.subscribe(
             (idlThing: IdlObject) => this.showEditDialog(idlThing)
         );
+        this.subscription = this.providerRecord.providerUpdated$.subscribe(
+            id => {
+                this.providerHoldingsGrid.reload();
+            }
+        );
     }
 
     ngAfterViewInit() {
         console.log('this.providerRecord',this.providerRecord);
     }
 
+    ngOnDestroy() {
+        this.subscription.unsubscribe();
+    }
+
     updateProvider(providerId: any) {
         this.providerRecord.refreshCurrent().then(() => {
             this.provider = this.providerRecord.current();
index 6134a1b..ec39a54 100644 (file)
@@ -1,5 +1,5 @@
-import {Component, OnInit, AfterViewInit, Input, ViewChild} from '@angular/core';
-import {Observable} from 'rxjs';
+import {Component, OnInit, AfterViewInit, OnDestroy, Input, ViewChild} from '@angular/core';
+import {Observable, Subscription} from 'rxjs';
 import {map} from 'rxjs/operators';
 import {Router, ActivatedRoute, ParamMap} from '@angular/router';
 import {Pager} from '@eg/share/util/pager';
@@ -31,6 +31,8 @@ export class ProviderInvoicesComponent implements OnInit {
 
     cellTextGenerator: GridCellTextGenerator;
 
+    subscription: Subscription;
+
     constructor(
         private router: Router,
         private route: ActivatedRoute,
@@ -50,26 +52,37 @@ export class ProviderInvoicesComponent implements OnInit {
             provider: row => row.provider().code(),
             shipper: row => row.shipper().code(),
         };
+        this.subscription = this.providerRecord.providerUpdated$.subscribe(
+            id => {
+                this.resetSearch();
+            }
+        );
     }
 
     ngAfterViewInit() {
-        this.providerRecord.refreshCurrent().then(() => {
-            const provider = this.providerRecord.current();
-            if (provider) {
-                setTimeout(() => {
-                    this.acqSearch.setSearch({
-                        terms: [{
-                            field:  'acqinv:provider',
-                            op:     '',
-                            value1: provider.id(),
-                            value2: '',
-                        }],
-                        conjunction: 'all',
-                    });
-                    this.providerInvoicesGrid.reload();
+        this.resetSearch();
+    }
+
+    ngOnDestroy() {
+        this.subscription.unsubscribe();
+    }
+
+    resetSearch() {
+        const provider = this.providerRecord.current();
+        if (provider) {
+            setTimeout(() => {
+                this.acqSearch.setSearch({
+                    terms: [{
+                        field:  'acqinv:provider',
+                        op:     '',
+                        value1: provider.id(),
+                        value2: '',
+                    }],
+                    conjunction: 'all',
                 });
-            }
-        });
+                this.providerInvoicesGrid.reload();
+            });
+        }
     }
 
     // TODO - copied from InvoiceResultsComponent, could be
index 9fac4ab..e764a73 100644 (file)
@@ -1,5 +1,5 @@
-import {Component, OnInit, AfterViewInit, Input, ViewChild} from '@angular/core';
-import {Observable} from 'rxjs';
+import {Component, OnInit, AfterViewInit, OnDestroy, Input, ViewChild} from '@angular/core';
+import {Observable, Subscription} from 'rxjs';
 import {map} from 'rxjs/operators';
 import {Router, ActivatedRoute, ParamMap} from '@angular/router';
 import {Pager} from '@eg/share/util/pager';
@@ -31,6 +31,8 @@ export class ProviderPurchaseOrdersComponent implements OnInit {
 
     cellTextGenerator: GridCellTextGenerator;
 
+    subscription: Subscription;
+
     constructor(
         private router: Router,
         private route: ActivatedRoute,
@@ -50,26 +52,38 @@ export class ProviderPurchaseOrdersComponent implements OnInit {
             provider: row => row.provider().code(),
             shipper: row => row.shipper().code(),
         };
+        this.subscription = this.providerRecord.providerUpdated$.subscribe(
+            id => {
+                this.resetSearch();
+            }
+        );
     }
 
     ngAfterViewInit() {
-        this.providerRecord.refreshCurrent().then(() => {
-            const provider = this.providerRecord.current();
-            if (provider) {
-                setTimeout(() => {
-                    this.acqSearch.setSearch({
-                        terms: [{
-                            field:  'acqpo:provider',
-                            op:     '',
-                            value1: provider.id(),
-                            value2: '',
-                        }],
-                        conjunction: 'all',
-                    });
-                    this.providerPurchaseOrdersGrid.reload();
+        this.resetSearch();
+    }
+
+    resetSearch() {
+        const provider = this.providerRecord.current();
+        if (provider) {
+            setTimeout(() => {
+                this.acqSearch.setSearch({
+                    terms: [{
+                        field:  'acqpo:provider',
+                        op:     '',
+                        value1: provider.id(),
+                        value2: '',
+                    }],
+                    conjunction: 'all',
                 });
-            }
-        });
+                this.providerPurchaseOrdersGrid.reload();
+            });
+        }
+    }
+     
+
+    ngOnDestroy() {
+        this.subscription.unsubscribe();
     }
 
 }
index 990dbeb..fdb398e 100644 (file)
@@ -1,6 +1,6 @@
 import {Injectable} from '@angular/core';
 import {Observable, from} from 'rxjs';
-import {empty, throwError} from 'rxjs';
+import {empty, throwError, Subject} from 'rxjs';
 import {map} from 'rxjs/operators';
 import {PcrudService} from '@eg/core/pcrud.service';
 import {IdlService, IdlObject} from '@eg/core/idl.service';
@@ -27,6 +27,9 @@ export class ProviderRecordService {
     private currentProvider: ProviderRecord;
     private currentProviderId: number = null;
 
+    private providerUpdatedSource = new Subject<number>();
+    providerUpdated$ = this.providerUpdatedSource.asObservable();
+
     constructor(
         private idl: IdlService,
         private net: NetService,
@@ -90,6 +93,9 @@ export class ProviderRecordService {
     current(): IdlObject {
         return this.currentProvider ? this.currentProvider.record : null;
     }
+    currentProviderRecord(): ProviderRecord {
+        return this.currentProvider ? this.currentProvider : null;
+    }
 
     fetch(id: number): Promise<any> {
         return new Promise((resolve, reject) => {
@@ -115,4 +121,9 @@ export class ProviderRecordService {
     batchUpdate(list: IdlObject | IdlObject[]): Observable<any> {
         return this.pcrud.autoApply(list);
     }
+
+    announceProviderUpdated() {
+        this.providerUpdatedSource.next(this.currentProviderId);
+    }
+
 }
index 9116a8e..970e542 100644 (file)
@@ -129,35 +129,34 @@ export class AcqProviderSummaryPaneComponent implements OnInit, AfterViewInit {
         }
 
         if (newProvider) {
-            this.prov.getProviderRecord(newProvider).subscribe(providerRecord => {
-                const provider = providerRecord.record;
-                if (provider) {
-                    this.provRec = providerRecord;
-                    this.provider = provider;
-                    this.provider_id = provider.id();
-                    this.provider_name = provider.name();
-                    this.provider_code = provider.code();
-                    this.provider_owner = this.org.get(provider.owner()).shortname();
-                    this.provider_currency_type = provider.currency_type() ? provider.currency_type().label() : '';
-                    this.provider_holding_tag = provider.holding_tag();
-                    this.provider_addresses = provider.addresses();
-                    this.provider_san = provider.san();
-                    this.provider_edi_default = provider.edi_default() ? provider.edi_default().label() : '';
-                    this.provider_active = provider.active();
-                    this.provider_prepayment_required = provider.prepayment_required();
-                    this.provider_url = provider.url();
-                    this.provider_email = provider.email();
-                    this.provider_phone = provider.phone();
-                    this.provider_fax_phone = provider.fax_phone();
-                    this.provider_default_claim_policy = provider.default_claim_policy();
-                    this.provider_default_copy_count = provider.default_copy_count();
-                    this.provider_contacts = provider.contacts();
-                    this.provider_provider_notes = provider.provider_notes();
-                } else {
-                    this.provider = null;
-                    no_provider();
-                }
-            });
+            const providerRecord = this.prov.currentProviderRecord();
+            const provider = providerRecord.record;
+            if (provider) {
+                this.provRec = providerRecord;
+                this.provider = provider;
+                this.provider_id = provider.id();
+                this.provider_name = provider.name();
+                this.provider_code = provider.code();
+                this.provider_owner = this.org.get(provider.owner()).shortname();
+                this.provider_currency_type = provider.currency_type() ? provider.currency_type().label() : '';
+                this.provider_holding_tag = provider.holding_tag();
+                this.provider_addresses = provider.addresses();
+                this.provider_san = provider.san();
+                this.provider_edi_default = provider.edi_default() ? provider.edi_default().label() : '';
+                this.provider_active = provider.active();
+                this.provider_prepayment_required = provider.prepayment_required();
+                this.provider_url = provider.url();
+                this.provider_email = provider.email();
+                this.provider_phone = provider.phone();
+                this.provider_fax_phone = provider.fax_phone();
+                this.provider_default_claim_policy = provider.default_claim_policy();
+                this.provider_default_copy_count = provider.default_copy_count();
+                this.provider_contacts = provider.contacts();
+                this.provider_provider_notes = provider.provider_notes();
+            } else {
+                this.provider = null;
+                no_provider();
+            }
         } else {
             no_provider();
         }