@jorsek/ezd-client
Version:
121 lines (100 loc) • 3.65 kB
text/typescript
import { Resource, IResourceArgs } from "./Resource";
import { IFacetValue, IFilter, ISearchResponse, ISearchHit, API_SearchConfig, API_Config } from "../Types";
import { transformAndValidateSync } from "class-transformer-validator";
import { INavLink } from "src";
export interface ISearchArgs extends IResourceArgs {
rootMapId: string;
}
export class Search extends Resource {
private searchFolders: {};
private search_filters: Array<{
label: string;
key: string;
parent_taxon: string;
}>;
private search_facets: Record<string, IFacetValue[]> = {};
private rootMapId: string;
private rows_per_page: any;
constructor({ rootMapId, axios, config }: ISearchArgs) {
super({ axios, config });
this.rootMapId = rootMapId;
}
public async get_filters(): Promise<IFilter[]> {
await this.setup_search();
return this.search_filters;
}
public async get_search_facets(): Promise<Record<string, IFacetValue[]>> {
await this.setup_search();
return this.search_facets;
}
public async get_results_per_page(): Promise<any> {
await this.setup_search();
return this.rows_per_page;
}
public async executeSearch(
search_string: string,
// section?: INavLink,
filter_facets?: {
[facet_name: string]: string[];
},
page = 0,
): Promise<ISearchResponse> {
await this.setup_search();
const drilldowns = [[["dita-class", "topic"]]];
if (filter_facets) {
const drilldown_facets = [];
for (const facet_id of Object.keys(filter_facets)) {
const or_filters = [];
for (const facet of filter_facets[facet_id]) {
or_filters.push([facet_id, facet]);
}
if (or_filters.length > 0) {
drilldown_facets.push(or_filters);
}
}
drilldowns.push(...drilldown_facets);
}
const request_params = {
startOffset: page * this.rows_per_page,
endOffset: (page + 1) * this.rows_per_page - 1,
queryString: search_string,
};
const data = {
searchRequest: request_params,
};
const response = await this.axios.post(
"/search",
JSON.stringify(request_params),
{
headers: {
"Content-Type": "text/plain",
},
},
);
if (response.data.totalResults == null) {
throw "Search response missing total results";
}
let transformed = response.data.hits;
transformed = transformed.map(obj => {
obj.breadcrumbs = obj.breadcrumbs.filter(b => b.href !== "");
transformAndValidateSync(ISearchHit, obj);
return obj;
});
return { results: transformed, total_count: response.data.totalResults };
}
private async setup_search() {
const config = await this.config.get();
this.rows_per_page = config.search.results_per_page;
this.search_filters = config.search.filters;
// Adhering to unintuitive search query protocol here
this.searchFolders = config.search.folders.reduce((acc, obj) => {
acc[obj] = true;
return acc;
}, {});
const transformer = el => ({
facet_name: el.navtitle,
id: el.value,
children: el.children.length > 0 ? el.children.map(transformer) : [],
});
}
}