LP1850546 Record detail shelf browse
[working/Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / catalog / catalog.service.ts
1 import {Injectable} from '@angular/core';
2 import {Router, ActivatedRoute} from '@angular/router';
3 import {IdlObject} from '@eg/core/idl.service';
4 import {OrgService} from '@eg/core/org.service';
5 import {CatalogService} from '@eg/share/catalog/catalog.service';
6 import {CatalogUrlService} from '@eg/share/catalog/catalog-url.service';
7 import {CatalogSearchContext} from '@eg/share/catalog/search-context';
8 import {BibRecordSummary} from '@eg/share/catalog/bib-record.service';
9
10 /**
11  * Shared bits needed by the staff version of the catalog.
12  */
13
14 @Injectable()
15 export class StaffCatalogService {
16
17     searchContext: CatalogSearchContext;
18     routeIndex = 0;
19     defaultSearchOrg: IdlObject;
20     defaultSearchLimit: number;
21     // Track the current template through route changes.
22     selectedTemplate: string;
23
24     // TODO: does unapi support pref-lib for result-page copy counts?
25     prefOrg: IdlObject;
26
27     // Default search tab
28     defaultTab: string;
29
30     // Cache the currently selected detail record (i.g. catalog/record/123)
31     // summary so the record detail component can avoid duplicate fetches
32     // during record tab navigation.
33     currentDetailRecordSummary: any;
34
35     constructor(
36         private router: Router,
37         private route: ActivatedRoute,
38         private org: OrgService,
39         private cat: CatalogService,
40         private catUrl: CatalogUrlService
41     ) { }
42
43     createContext(): void {
44         // Initialize the search context from the load-time URL params.
45         // Do this here so the search form and other context data are
46         // applied on every page, not just the search results page.  The
47         // search results pages will handle running the actual search.
48         this.searchContext =
49             this.catUrl.fromUrlParams(this.route.snapshot.queryParamMap);
50
51         this.searchContext.org = this.org; // service, not searchOrg
52         this.searchContext.isStaff = true;
53         this.applySearchDefaults();
54     }
55
56     cloneContext(context: CatalogSearchContext): CatalogSearchContext {
57         const params: any = this.catUrl.toUrlParams(context);
58         return this.catUrl.fromUrlHash(params);
59     }
60
61     applySearchDefaults(): void {
62         if (!this.searchContext.searchOrg) {
63             this.searchContext.searchOrg =
64                 this.defaultSearchOrg || this.org.root();
65         }
66
67         if (!this.searchContext.pager.limit) {
68             this.searchContext.pager.limit = this.defaultSearchLimit || 10;
69         }
70     }
71
72     /**
73      * Redirect to the search results page while propagating the current
74      * search paramters into the URL.  Let the search results component
75      * execute the actual search.
76      */
77     search(): void {
78         if (!this.searchContext.isSearchable()) { return; }
79
80         const params = this.catUrl.toUrlParams(this.searchContext);
81
82         // Force a new search every time this method is called, even if
83         // it's the same as the active search.  Since router navigation
84         // exits early when the route + params is identical, add a
85         // random token to the route params to force a full navigation.
86         // This also resolves a problem where only removing secondary+
87         // versions of a query param fail to cause a route navigation.
88         // (E.g. going from two query= params to one).  Investigation
89         // pending.
90         params.ridx = '' + this.routeIndex++;
91
92         this.router.navigate(
93           ['/staff/catalog/search'], {queryParams: params});
94     }
95
96     /**
97      * Redirect to the browse results page while propagating the current
98      * browse paramters into the URL.  Let the browse results component
99      * execute the actual browse.
100      */
101     browse(): void {
102         if (!this.searchContext.browseSearch.isSearchable()) { return; }
103         const params = this.catUrl.toUrlParams(this.searchContext);
104
105         // Force a new browse every time this method is called, even if
106         // it's the same as the active browse.  Since router navigation
107         // exits early when the route + params is identical, add a
108         // random token to the route params to force a full navigation.
109         // This also resolves a problem where only removing secondary+
110         // versions of a query param fail to cause a route navigation.
111         // (E.g. going from two query= params to one).
112         params.ridx = '' + this.routeIndex++;
113
114         this.router.navigate(
115             ['/staff/catalog/browse'], {queryParams: params});
116     }
117
118     // Call number browse.
119     // Redirect to cn browse page and let its component perform the search
120     cnBrowse(): void {
121         if (!this.searchContext.cnBrowseSearch.isSearchable()) { return; }
122         const params = this.catUrl.toUrlParams(this.searchContext);
123         params.ridx = '' + this.routeIndex++; // see comments above
124         this.router.navigate(['/staff/catalog/cnbrowse'], {queryParams: params});
125     }
126
127     // Params to genreate a new author search based on a reset
128     // clone of the current page params.
129     getAuthorSearchParams(summary: BibRecordSummary): any {
130         const tmpContext = this.cloneContext(this.searchContext);
131         tmpContext.reset();
132         tmpContext.termSearch.fieldClass = ['author'];
133         tmpContext.termSearch.query = [summary.display.author];
134         return this.catUrl.toUrlParams(tmpContext);
135     }
136 }
137
138