1 import {Component, OnInit, AfterViewInit, ViewChild, ChangeDetectorRef, OnDestroy} from '@angular/core';
2 import {filter, takeUntil} from 'rxjs/operators';
3 import {Subject, Observable, of} from 'rxjs';
4 import {NgbTabset, NgbTabChangeEvent} from '@ng-bootstrap/ng-bootstrap';
5 import {Router, ActivatedRoute, ParamMap, RouterEvent, NavigationEnd} from '@angular/router';
6 import {StaffCommonModule} from '@eg/staff/common.module';
7 import {IdlService, IdlObject} from '@eg/core/idl.service';
8 import {PcrudService} from '@eg/core/pcrud.service';
9 import {AcqProviderSummaryPaneComponent} from './summary-pane.component';
10 import {ProviderDetailsComponent} from './provider-details.component';
11 import {ProviderHoldingsComponent} from './provider-holdings.component';
12 import {ProviderResultsComponent} from './provider-results.component';
13 import {ProviderRecordService} from './provider-record.service';
14 import {FmRecordEditorComponent} from '@eg/share/fm-editor/fm-editor.component';
15 import {StringComponent} from '@eg/share/string/string.component';
16 import {ToastService} from '@eg/share/toast/toast.service';
17 import {AuthService} from '@eg/core/auth.service';
18 import {StoreService} from '@eg/core/store.service';
19 import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component';
22 templateUrl: './acq-provider.component.html'
25 export class AcqProviderComponent implements OnInit, AfterViewInit, OnDestroy {
28 showSearchForm = false;
30 validTabTypes = ['details', 'addresses', 'contacts', 'attributes', 'holdings', 'edi_accounts', 'purchase_orders', 'invoices'];
31 defaultTabType = 'details';
32 @ViewChild('acqSearchProviderSummary', { static: true }) providerSummaryPane: AcqProviderSummaryPaneComponent;
33 @ViewChild('acqProviderResults', { static: true }) acqProviderResults: ProviderResultsComponent;
34 @ViewChild('providerDetails', { static: false }) providerDetails: ProviderDetailsComponent;
35 @ViewChild('providerHoldings', { static: false }) providerHoldings: ProviderHoldingsComponent;
36 @ViewChild('createDialog', { static: true }) createDialog: FmRecordEditorComponent;
37 @ViewChild('createString', { static: false }) createString: StringComponent;
38 @ViewChild('createErrString', { static: false }) createErrString: StringComponent;
39 @ViewChild('leaveConfirm', { static: true }) leaveConfirm: ConfirmDialogComponent;
41 onTabChange: ($event: NgbTabChangeEvent) => void;
43 onDesireSummarize: ($event: number, updateSummaryOnly?: boolean, hideSearchForm?: boolean) => void;
44 onSummaryToggled: ($event: boolean) => void;
46 previousUrl: string = null;
47 public destroyed = new Subject<any>();
48 _alreadyDeactivated = false;
51 private router: Router,
52 private route: ActivatedRoute,
53 private auth: AuthService,
54 private pcrud: PcrudService,
55 private idl: IdlService,
56 private providerRecord: ProviderRecordService,
57 private toast: ToastService,
58 private store: StoreService,
59 private changeDetector: ChangeDetectorRef
61 this.router.events.pipe(
62 filter((event: RouterEvent) => event instanceof NavigationEnd),
63 takeUntil(this.destroyed)
64 ).subscribe(routeEvent => {
65 if (routeEvent instanceof NavigationEnd) {
66 if (this.previousUrl != null &&
67 routeEvent.url === '/staff/acq/provider') {
68 this.acqProviderResults.resetSearch();
69 this.showSearchForm = true;
72 this.previousUrl = routeEvent.url;
80 const tabTypeParam = this.route.snapshot.paramMap.get('tab');
81 const idParam = this.route.snapshot.paramMap.get('id');
84 this.store.getLocalItem('eg.acq.provider.default_tab') || 'details';
86 const keepSearchForm = history.state.hasOwnProperty('keepSearchForm') ?
87 history.state.keepSearchForm :
90 this.showSearchForm = true;
94 if (!keepSearchForm) {
95 this.showSearchForm = false;
99 this.activeTab = this.defaultTabType;
100 this.router.navigate(['/staff', 'acq', 'provider', this.id, this.activeTab]);
105 if (!keepSearchForm) {
106 this.showSearchForm = false;
108 if (this.validTabTypes.includes(tabTypeParam)) {
109 this.activeTab = tabTypeParam;
111 this.activeTab = this.defaultTabType;
112 this.router.navigate(['/staff', 'acq', 'provider', this.id, this.activeTab]);
115 this.showSearchForm = true;
118 this.onTabChange = ($event) => {
119 $event.preventDefault();
120 this.canDeactivate().subscribe(canLeave => {
121 if (!canLeave) { return; }
122 this._alreadyDeactivated = true; // don't trigger again on the route change
123 if (this.validTabTypes.includes($event.nextId)) {
124 this.activeTab = $event.nextId;
125 const id = this.route.snapshot.paramMap.get('id');
126 this.router.navigate(['/staff', 'acq', 'provider', this.id, $event.nextId]);
131 this.onDesireSummarize = ($event, updateSummaryOnly = false, hideSearchForm = true) => {
133 this.providerRecord.fetch(this.id).then(() => {
134 // $event is a provider ID
135 this.providerSummaryPane.update($event);
136 if (this.providerDetails) {
137 this.providerDetails.refresh();
139 if (updateSummaryOnly) {
142 this.providerRecord.announceProviderUpdated();
143 if (hideSearchForm) {
144 this.showSearchForm = false;
146 this.activeTab = this.defaultTabType;
147 this.router.navigate(
148 ['/staff', 'acq', 'provider', this.id, this.activeTab],
149 { state: { keepSearchForm: !hideSearchForm } }
154 this.onSummaryToggled = ($event) => {
155 // in case this is useful for a better implementation of reflowing the UI
160 this.changeDetector.detectChanges();
163 ngOnDestroy(): void {
164 this.destroyed.next();
165 this.destroyed.complete();
169 this.defaultTabType = this.activeTab;
170 this.store.setLocalItem('eg.acq.provider.default_tab', this.activeTab);
174 this.createDialog.mode = 'create';
175 const provider = this.idl.create('acqpro');
176 provider.active(true);
177 provider.owner(this.auth.user().ws_ou());
178 provider.default_copy_count(1);
179 this.createDialog.record = provider;
180 this.createDialog.recordId = null;
181 this.createDialog.open({size: 'lg'}).subscribe(
183 this.createString.current()
184 .then(str => this.toast.success(str));
185 this.onDesireSummarize(ok.id());
188 if (!rejection.dismissed) {
189 this.createErrString.current()
190 .then(str => this.toast.danger(str));
196 canDeactivate(): Observable<boolean> {
197 if (this._alreadyDeactivated) {
199 this._alreadyDeactivated = false;
202 if ((this.providerHoldings && this.providerHoldings.isDirty()) ||
203 (this.providerDetails && this.providerDetails.isDirty())) {
204 return this.leaveConfirm.open();