LP2000482 Angular 15 and Bootstrap 5 upgrade
[evergreen-equinox.git] / Open-ILS / src / eg2 / src / app / staff / acq / search / acq-search.component.ts
1 import {Component, OnInit, ViewChild, ViewChildren, QueryList, OnDestroy} from '@angular/core';
2 import {NgbNav, NgbNavChangeEvent} from '@ng-bootstrap/ng-bootstrap';
3 import {Router, ActivatedRoute, ParamMap, RouterEvent, NavigationEnd} from '@angular/router';
4 import {filter, takeUntil} from 'rxjs/operators';
5 import {Subject} from 'rxjs';
6 import {AcqSearchTerm} from './acq-search.service';
7 import {LineitemResultsComponent} from './lineitem-results.component';
8 import {PurchaseOrderResultsComponent} from './purchase-order-results.component';
9 import {InvoiceResultsComponent} from './invoice-results.component';
10 import {PicklistResultsComponent} from './picklist-results.component';
11
12 @Component({
13   templateUrl: './acq-search.component.html'
14 })
15
16 export class AcqSearchComponent implements OnInit, OnDestroy {
17
18     searchType = '';
19     validSearchTypes = ['lineitems', 'purchaseorders', 'invoices', 'selectionlists'];
20     defaultSearchType = 'lineitems';
21
22     urlSearchTerms: AcqSearchTerm[] = [];
23
24     onTabChange: ($event: NgbNavChangeEvent) => void;
25     @ViewChild('acqSearchTabs', { static: true }) tabs: NgbNav;
26     @ViewChildren(LineitemResultsComponent) liResults: QueryList<PurchaseOrderResultsComponent>;
27     @ViewChildren(PurchaseOrderResultsComponent) poResults: QueryList<PurchaseOrderResultsComponent>;
28     @ViewChildren(InvoiceResultsComponent) invResults: QueryList<PurchaseOrderResultsComponent>;
29     @ViewChildren(PicklistResultsComponent) plResults: QueryList<PicklistResultsComponent>;
30
31     previousUrl: string = null;
32     public destroyed = new Subject<any>();
33
34     constructor(
35         private router: Router,
36         private route: ActivatedRoute,
37     ) {
38         this.route.queryParamMap.subscribe((params: ParamMap) => {
39             this.urlSearchTerms = [];
40             const fields = params.getAll('f');
41             const ops = params.getAll('op');
42             const values1 = params.getAll('val1');
43             const values2 = params.getAll('val2');
44             fields.forEach((f, idx) => {
45                 const term: AcqSearchTerm = {
46                     field:  f,
47                     op:     '',
48                     value1: '',
49                     value2: ''
50                 };
51                 if (idx < ops.length) {
52                     term.op = ops[idx];
53                 }
54                 if (idx < values1.length) {
55                     term.value1 = values1[idx];
56                     if (term.value1 === 'null') {
57                         // convert the string 'null' to a true
58                         // null value, mostly for the benefit of the
59                         // open invoices navigation link
60                         term.value1 = null;
61                     }
62                 }
63                 if (idx < values2.length) {
64                     term.value2 = values2[idx];
65                 }
66                 this.urlSearchTerms.push(term);
67                 this.ngOnInit(); // TODO: probably overkill
68             });
69         });
70         this.router.events.pipe(
71             filter((event: RouterEvent) => event instanceof NavigationEnd),
72             takeUntil(this.destroyed)
73         ).subscribe(routeEvent => {
74             if (routeEvent instanceof NavigationEnd) {
75                 // force reset of grid data source if we're navigating from
76                 // a search tab to the same search tab
77                 if (this.previousUrl != null) {
78                     const prevRoute = this.previousUrl.match(/acq\/search\/([a-z]+)/);
79                     const newRoute = routeEvent.url.match(/acq\/search\/([a-z]+)/);
80                     const prevTab = prevRoute  == null ? 'lineitems' : prevRoute[1];
81                     const newTab = newRoute  == null ? 'lineitems' : newRoute[1];
82                     if (prevTab === newTab) {
83                         switch (newTab) {
84                             case 'lineitems':
85                                 this.liResults.toArray()[0].gridSource.reset();
86                                 this.liResults.toArray()[0].acqSearchForm.ngOnInit();
87                                 break;
88                             case 'purchaseorders':
89                                 this.poResults.toArray()[0].gridSource.reset();
90                                 this.poResults.toArray()[0].acqSearchForm.ngOnInit();
91                                 break;
92                             case 'invoices':
93                                 this.invResults.toArray()[0].gridSource.reset();
94                                 this.invResults.toArray()[0].acqSearchForm.ngOnInit();
95                                 break;
96                             case 'selectionlists':
97                                 this.plResults.toArray()[0].gridSource.reset();
98                                 this.plResults.toArray()[0].acqSearchForm.ngOnInit();
99                                 break;
100                         }
101                     }
102                 }
103                 this.previousUrl = routeEvent.url;
104                 this.ngOnInit(); // TODO: probably overkill
105             }
106         });
107     }
108
109     ngOnInit() {
110         const self = this;
111
112         const searchTypeParam = this.route.snapshot.paramMap.get('searchtype');
113
114         if (searchTypeParam) {
115             if (this.validSearchTypes.includes(searchTypeParam)) {
116                 this.searchType = searchTypeParam;
117             } else {
118                 this.searchType = this.defaultSearchType;
119                 this.router.navigate(['/staff', 'acq', 'search', this.searchType]);
120             }
121         } else {
122             this.searchType = this.defaultSearchType;
123         }
124
125         this.onTabChange = ($event) => {
126             if (this.validSearchTypes.includes($event.nextId)) {
127                 this.searchType = $event.nextId;
128                 this.urlSearchTerms = [];
129                 this.router.navigate(['/staff', 'acq', 'search', $event.nextId]);
130             }
131         };
132     }
133
134     ngOnDestroy(): void {
135         this.destroyed.next(null);
136         this.destroyed.complete();
137     }
138
139 }