--- /dev/null
+import {Injectable} from '@angular/core';
+import {Params} from '@angular/router';
+import {CatalogSearchContext} from './search-context';
+
+@Injectable()
+export class EgCatalogUrlService {
+
+ // consider supporting a param name prefix/namespace
+
+ constructor() { }
+
+ /**
+ * Returns a URL query structure suitable for using with
+ * router.navigate(..., {queryParams:...}).
+ * No navigation is performed within.
+ */
+ toUrlParams(context: CatalogSearchContext): any {
+ let params = {};
+
+ params.query = [];
+ params.searchClass = [];
+ params.joiner = [];
+ params.match = [];
+
+ context.query.forEach((q, idx) => {
+ ['query', 'searchClass','joiner','match'].forEach(field => {
+ params[field][idx] = context[field][idx];
+ });
+ });
+
+ return params;
+ }
+
+ /**
+ * Creates a new search context from the active route params.
+ */
+ fromUrlParams(params: Params): CatalogSearchContext {
+ let context = new CatalogSearchContext();
+
+ this.applyUrlParams(context, params);
+
+ return context;
+ }
+
+ applyUrlParams(context: CatalogSearchContext, params: Params): void {
+
+ // These fields can be copied directly into place
+ ['limit','offset','format','sort','available','global']
+ .forEach(field => {
+ if (params[field] != undefined) {
+ context[field] = params[field];
+ }
+ });
+
+ if (typeof params.query == 'string') {
+ // Only one query set is encoded in the URL
+ context.query = [params.query];
+ if (params.searchClass) context.searchClass = [params.searchClass];
+ if (params.joiner) context.joiner = [params.joiner];
+ if (params.match) context.match = [params.match];
+
+ } else if (Array.isArray(params.query)) {
+ // Multiple query sets encoded in the URL.
+ params.query.forEach((q, idx) => {
+ context.query[idx] = params.query[idx];
+ context.searchClass[idx] = params.searchClass[idx];
+ context.joiner[idx] = params.joiner[idx];
+ context.match[idx] = params.match[idx];
+ });
+ }
+
+ /*
+
+ // Decode and propagate array-based values
+ angular.forEach(scs.ccvm_list_keys, function(field) {
+ if (url_search[field]) {
+ ctx.search_args[field] = url_search[field].split(/,/);
+ }
+ });
+
+ // if there's only a single value it will be a string.
+ if (typeof url_search.facet == 'string')
+ url_search.facet = [url_search.facet];
+ angular.forEach(url_search.facet, function(facet) {
+ console.log('parsing: ' + facet);
+ ctx.search_args.facets.push(JSON.parse(facet));
+ });
+
+ // Handle special-case values
+ if (url_search.org)
+ ctx.search_args.context_org = egCore.org.get(url_search.org);
+
+ */
+
+ }
+
+
+}
@Injectable()
export class EgCatalogService {
+ // Search context is set by the application.
searchContext: CatalogSearchContext;
+
ccvmMap: {[ccvm:string] : EgIdlObject[]} = {};
cmfMap: {[cmf:string] : EgIdlObject[]} = {};
private org: EgOrgService,
private unapi: EgUnapiService,
private pcrud: EgPcrudService
- ) {
- this.searchContext = new CatalogSearchContext();
- this.searchContext.org = this.org;
- }
+ ) {}
- search(context: CatalogSearchContext): Promise<void> {
+ search(): Promise<void> {
+ let ctx = this.searchContext;
- var fullQuery = context.compileSearch();
+ var fullQuery = ctx.compileSearch();
console.debug(`search query: ${fullQuery}`);
this.net.request(
'open-ils.search',
'open-ils.search.biblio.multiclass.query.staff', {
- limit : context.pager.limit,
- offset : context.pager.offset
+ limit : ctx.pager.limit,
+ offset : ctx.pager.offset
}, fullQuery, true
).subscribe(result => {
- context.result = result;
- context.result.records = [];
- context.pager.resultCount = result.count;
+ ctx.result = result;
+ ctx.result.records = [];
+ ctx.pager.resultCount = result.count;
let promises = [];
result.ids.forEach(blob => {
promises.push(
this.getBibSummary(blob[0],
- context.searchOrg.id(),
- context.global ?
- context.org.root().ou_typ().depth() :
- context.searchOrg.ou_type().depth()
+ ctx.searchOrg.id(),
+ ctx.global ?
+ ctx.org.root().ou_typ().depth() :
+ ctx.searchOrg.ou_type().depth()
).then(
- summary => context.result.records.push(summary)
+ summary => ctx.result.records.push(summary)
)
);
});
return str + query + ')';
}
-
- /**
- * Returns a URL query structure suitable for using with
- * router.navigate(..., {queryParams:...}).
- * No navigation is performed within.
- */
- toUrlParams(): any {
- let query = {query : ['piano']}; // TODO
-
- return query;
- }
-
- /**
- * Absorbs URL values from the active route and applies them to
- * this search context instance.
- */
- fromUrlParams(params: Params): void {
- console.log('checking params with query ' + params.query);
- }
}
import {Component, OnInit} from '@angular/core';
-import {Observable} from 'rxjs/Rx';
import {ActivatedRoute} from '@angular/router';
+import {EgOrgService} from '@eg/core/org';
import {EgCatalogService} from '@eg/share/catalog/catalog.service';
import {CatalogSearchContext} from '@eg/share/catalog/search-context';
+import {EgCatalogUrlService} from '@eg/share/catalog/catalog-url.service';
@Component({
templateUrl: 'catalog.component.html'
})
export class EgCatalogComponent implements OnInit {
+ // Main search context that lives for the duration of the catalog.
searchContext: CatalogSearchContext;
constructor(
private route: ActivatedRoute,
- private cat: EgCatalogService
+ private org: EgOrgService,
+ private cat: EgCatalogService,
+ private catUrl: EgCatalogUrlService
) {}
ngOnInit() {
- // TODO: MOVE THIS OUT OF THE CAT SERVICE
- // and pass it down to each child component that needs
- // it via @Input.
- this.searchContext = this.cat.searchContext;
+ // Initialize the search context from the load-time URL params.
+ this.cat.searchContext = this.searchContext =
+ this.catUrl.fromUrlParams(this.route.snapshot.queryParams);
- // Sync the context with the load-time URL params.
- this.searchContext.fromUrlParams(this.route.snapshot.queryParams);
- }
+ this.searchContext.org = this.org; // offer a copy of the service.
+ console.debug(this.searchContext);
+ }
}
import {EgUnapiService} from '@eg/share/unapi';
import {EgCatalogRoutingModule} from './routing.module';
import {EgCatalogService} from '@eg/share/catalog/catalog.service';
+import {EgCatalogUrlService} from '@eg/share/catalog/catalog-url.service';
import {EgCatalogComponent} from './catalog.component';
import {SearchFormComponent} from './search-form.component';
import {ResultsComponent} from './result/results.component';
import {ResultPaginationComponent} from './result/pagination.component';
import {ResultFacetsComponent} from './result/facets.component';
-import {ResultRecordComponent}
- from './result/record.component';
+import {ResultRecordComponent} from './result/record.component';
@NgModule({
declarations: [
],
providers: [
EgUnapiService,
- EgCatalogService
+ EgCatalogService,
+ EgCatalogUrlService
]
})
if (!this.searchContext.query[0]) return;
- this.cat.search(this.searchContext).then(ok => {
+ this.cat.search().then(ok => {
console.debug('search complete');
});
import {EgOrgService} from '@eg/core/org';
import {EgCatalogService} from '@eg/share/catalog/catalog.service';
import {CatalogSearchContext} from '@eg/share/catalog/search-context';
+import {EgCatalogUrlService} from '@eg/share/catalog/catalog-url.service';
@Component({
selector: 'eg-catalog-search-form',
})
export class SearchFormComponent implements OnInit {
+ searchContext: CatalogSearchContext;
ccvmMap: {[ccvm:string] : EgIdlObject[]} = {};
cmfMap: {[cmf:string] : EgIdlObject[]} = {};
- searchContext: CatalogSearchContext;
showAdvancedSearch: boolean = false;
constructor(
private router: Router,
private route: ActivatedRoute,
private org: EgOrgService,
- private cat: EgCatalogService
+ private cat: EgCatalogService,
+ private catUrl: EgCatalogUrlService
) {}
ngOnInit() {
*/
searchByForm(): void {
this.searchContext.searchOrg = this.org.get(4); // TODO: TEST BR1
+ let params = this.catUrl.toUrlParams(this.searchContext);
this.router.navigate(
- ['/staff/catalog/search'],
- {queryParams: this.searchContext.toUrlParams()}
- )
+ ['/staff/catalog/search'], {queryParams: params});
}
-
}