1 import {Injectable} from '@angular/core';
2 import {ParamMap} from '@angular/router';
3 import {OrgService} from '@eg/core/org.service';
4 import {CatalogSearchContext, FacetFilter} from './search-context';
5 import {CATALOG_CCVM_FILTERS} from './catalog.service';
8 export class CatalogUrlService {
10 // consider supporting a param name prefix/namespace
12 constructor(private org: OrgService) { }
15 * Returns a URL query structure suitable for using with
16 * router.navigate(..., {queryParams:...}).
17 * No navigation is performed within.
19 toUrlParams(context: CatalogSearchContext):
20 {[key: string]: string | string[]} {
35 params.org = context.searchOrg.id();
37 params.limit = context.pager.limit;
38 if (context.pager.offset) {
39 params.offset = context.pager.offset;
42 // These fields can be copied directly into place
43 ['format', 'sort', 'available', 'global', 'identQuery', 'identQueryType']
46 // Only propagate applied values to the URL.
47 params[field] = context[field];
51 if (params.identQuery) {
52 // Ident queries (e.g. tcn search) discards all remaining filters
56 context.query.forEach((q, idx) => {
57 ['query', 'fieldClass', 'joinOp', 'matchOp'].forEach(field => {
58 // Propagate all array-based fields regardless of
59 // whether a value is applied to ensure correct
60 // correlation between values.
61 params[field][idx] = context[field][idx];
65 // CCVM filters are encoded as comma-separated lists
66 Object.keys(context.ccvmFilters).forEach(code => {
67 if (context.ccvmFilters[code] &&
68 context.ccvmFilters[code][0] !== '') {
69 params[code] = context.ccvmFilters[code].join(',');
73 // Each facet is a JSON encoded blob of class, name, and value
74 context.facetFilters.forEach(facet => {
75 params.facets.push(JSON.stringify({
86 * Creates a new search context from the active route params.
88 fromUrlParams(params: ParamMap): CatalogSearchContext {
89 const context = new CatalogSearchContext();
91 this.applyUrlParams(context, params);
96 applyUrlParams(context: CatalogSearchContext, params: ParamMap): void {
98 // Reset query/filter args. The will be reconstructed below.
101 // These fields can be copied directly into place
102 ['format', 'sort', 'available', 'global', 'identQuery', 'identQueryType']
104 const val = params.get(field);
106 context[field] = val;
110 if (params.get('limit')) {
111 context.pager.limit = +params.get('limit');
114 if (params.get('offset')) {
115 context.pager.offset = +params.get('offset');
118 ['query', 'fieldClass', 'joinOp', 'matchOp'].forEach(field => {
119 const arr = params.getAll(field);
120 if (arr && arr.length) {
121 context[field] = arr;
125 CATALOG_CCVM_FILTERS.forEach(code => {
126 const val = params.get(code);
128 context.ccvmFilters[code] = val.split(/,/);
130 context.ccvmFilters[code] = [''];
134 params.getAll('facets').forEach(blob => {
135 const facet = JSON.parse(blob);
136 context.addFacet(new FacetFilter(facet.c, facet.n, facet.v));
139 if (params.get('org')) {
140 context.searchOrg = this.org.get(+params.get('org'));