terriajs
Version:
Geospatial data visualization platform.
181 lines (155 loc) • 5.39 kB
text/typescript
import {
action,
computed,
IReactionDisposer,
observable,
reaction,
makeObservable,
runInAction
} from "mobx";
import filterOutUndefined from "../Core/filterOutUndefined";
import LocationSearchProviderMixin from "../ModelMixins/SearchProviders/LocationSearchProviderMixin";
import SearchProviderMixin from "../ModelMixins/SearchProviders/SearchProviderMixin";
import CatalogSearchProvider from "../Models/SearchProviders/CatalogSearchProvider";
import SearchProviderResults from "../Models/SearchProviders/SearchProviderResults";
import Terria from "../Models/Terria";
import CatalogSearchProviderMixin from "../ModelMixins/SearchProviders/CatalogSearchProviderMixin";
interface SearchStateOptions {
terria: Terria;
catalogSearchProvider?: CatalogSearchProviderMixin.Instance;
}
export default class SearchState {
catalogSearchText: string = "";
isWaitingToStartCatalogSearch: boolean = false;
locationSearchText: string = "";
isWaitingToStartLocationSearch: boolean = false;
unifiedSearchText: string = "";
isWaitingToStartUnifiedSearch: boolean = false;
showLocationSearchResults: boolean = false;
showMobileLocationSearch: boolean = false;
showMobileCatalogSearch: boolean = false;
locationSearchResults: SearchProviderResults[] = [];
catalogSearchResults: SearchProviderResults | undefined;
unifiedSearchResults: SearchProviderResults[] = [];
private _catalogSearchDisposer: IReactionDisposer;
private _locationSearchDisposer: IReactionDisposer;
private _unifiedSearchDisposer: IReactionDisposer;
private _workbenchItemsSubscription: IReactionDisposer;
private readonly terria: Terria;
constructor(options: SearchStateOptions) {
makeObservable(this);
this.terria = options.terria;
runInAction(() => {
this.terria.searchBarModel.catalogSearchProvider =
options.catalogSearchProvider ||
new CatalogSearchProvider("catalog-search-provider", options.terria);
});
const self = this;
this._catalogSearchDisposer = reaction(
() => self.catalogSearchText,
() => {
self.isWaitingToStartCatalogSearch = true;
if (self.catalogSearchProvider) {
self.catalogSearchResults = self.catalogSearchProvider.search("");
}
}
);
this._locationSearchDisposer = reaction(
() => self.locationSearchText,
() => {
self.isWaitingToStartLocationSearch = true;
self.locationSearchResults = self.locationSearchProviders.map(
(provider) => {
return provider.search("");
}
);
}
);
this._unifiedSearchDisposer = reaction(
() => this.unifiedSearchText,
() => {
this.isWaitingToStartUnifiedSearch = true;
this.unifiedSearchResults = this.unifiedSearchProviders.map(
(provider) => {
return provider.search("");
}
);
}
);
this._workbenchItemsSubscription = reaction(
() => this.terria.workbench.items,
() => {
this.showLocationSearchResults = false;
}
);
}
dispose(): void {
this._catalogSearchDisposer();
this._locationSearchDisposer();
this._unifiedSearchDisposer();
this._workbenchItemsSubscription();
}
get supportsAutocomplete(): boolean {
return this.locationSearchProviders.every((provider) =>
provider.supportsAutocomplete()
);
}
private get locationSearchProviders(): LocationSearchProviderMixin.Instance[] {
return this.terria.searchBarModel.locationSearchProvidersArray;
}
get catalogSearchProvider(): CatalogSearchProviderMixin.Instance | undefined {
return this.terria.searchBarModel.catalogSearchProvider;
}
get unifiedSearchProviders(): SearchProviderMixin.Instance[] {
return filterOutUndefined([
this.catalogSearchProvider,
...this.locationSearchProviders
]);
}
searchCatalog(): void {
if (this.isWaitingToStartCatalogSearch) {
this.isWaitingToStartCatalogSearch = false;
if (this.catalogSearchResults) {
this.catalogSearchResults.isCanceled = true;
}
if (this.catalogSearchProvider) {
this.catalogSearchResults = this.catalogSearchProvider.search(
this.catalogSearchText
);
}
}
}
setCatalogSearchText(newText: string): void {
this.catalogSearchText = newText;
}
searchLocations(): void {
if (this.isWaitingToStartLocationSearch) {
this.isWaitingToStartLocationSearch = false;
this.locationSearchResults.forEach((results) => {
results.isCanceled = true;
});
this.locationSearchResults = this.locationSearchProviders.map(
(searchProvider) => searchProvider.search(this.locationSearchText)
);
}
}
searchUnified(): void {
if (this.isWaitingToStartUnifiedSearch) {
this.isWaitingToStartUnifiedSearch = false;
this.unifiedSearchResults.forEach((results) => {
results.isCanceled = true;
});
this.unifiedSearchResults = this.unifiedSearchProviders.map(
(searchProvider) => searchProvider.search(this.unifiedSearchText)
);
}
}
}