@spotinst/spinnaker-deck
Version:
Spinnaker-Deck service, forked with support to Spotinst
61 lines (51 loc) • 2.45 kB
text/typescript
import { isEmpty } from 'lodash';
import { uniqBy } from 'lodash';
import { Observable, Subject } from 'rxjs';
import { IQueryParams, UrlBuilder } from 'core/navigation';
import { ISearchResultSet } from './infrastructureSearch.service';
import { ISearchResult, ISearchResults } from '../search.service';
import { SearchStatus } from '../searchResult/SearchResults';
import { SearchResultType } from '../searchResult/searchResultType';
import { searchResultTypeRegistry } from '../searchResult/searchResultType.registry';
export class InfrastructureSearchServiceV2 {
private static EMPTY_RESULTS: ISearchResultSet[] = searchResultTypeRegistry
.getAll()
.map((type) => ({ type, results: [], status: SearchStatus.FINISHED }));
public static search(apiParams: IQueryParams): Observable<ISearchResultSet> {
if (isEmpty(apiParams)) {
return Observable.from(this.EMPTY_RESULTS);
}
const params = { ...apiParams };
const types = searchResultTypeRegistry.getAll();
const otherResults$ = new Subject<ISearchResultSet>();
/** Add the href and displayName attributes */
const addComputedAttributes = (result: ISearchResult, type: SearchResultType): ISearchResult => {
return {
...result,
href: UrlBuilder.buildFromMetadata(result),
displayName: type.displayFormatter(result),
};
};
const makeResultSet = (searchResults: ISearchResults<any>, type: SearchResultType): ISearchResultSet => {
// Add URLs to each search result (discard duplicate results)
const results = uniqBy(
searchResults.results.map((result) => addComputedAttributes(result, type)),
(r) => r.href,
);
const query: string = apiParams.key as string;
return { type, results, status: SearchStatus.FINISHED, query };
};
const emitErrorResultSet = (error: any, type: SearchResultType): Observable<ISearchResultSet> => {
return Observable.of({ error, type, results: [], status: SearchStatus.ERROR });
};
return Observable.from(types)
.mergeMap((type: SearchResultType) => {
return type
.search(params, otherResults$)
.map((searchResults: ISearchResults<any>) => makeResultSet(searchResults, type))
.catch((error: any) => emitErrorResultSet(error, type));
})
.do((result: ISearchResultSet<any>) => otherResults$.next(result))
.finally(() => otherResults$.complete());
}
}