import * as React from 'react'; import * as QueryString from 'query-string'; import { useHistory, useLocation } from 'react-router'; import { Affix, Col, Row, Tabs, Layout } from 'antd'; import { SearchablePage } from './SearchablePage'; import { fromCollectionName, fromPathName, toCollectionName, toPathName } from '../shared/EntityTypeUtil'; import { useGetSearchResultsQuery } from '../../graphql/search.generated'; import { SearchResults } from './SearchResults'; import { EntityType, PlatformNativeType } from '../../types.generated'; import { SearchFilters } from './SearchFilters'; import { SearchCfg } from '../../conf'; import { PageRoutes } from '../../conf/Global'; const { SEARCHABLE_ENTITY_TYPES, RESULTS_PER_PAGE } = SearchCfg; /** * A dedicated search page. * * TODO: Read / write filter parameters from the URL query parameters. */ export const SearchPage = () => { const history = useHistory(); const location = useLocation(); const params = QueryString.parse(location.search); const type = params.type ? fromPathName(params.type as string) : SEARCHABLE_ENTITY_TYPES[0]; const query = params.query ? (params.query as string) : ''; const page = params.page && Number(params.page as string) > 0 ? Number(params.page as string) : 1; const filters = location.state ? ((location.state as any).filters as Array<{ field: string; value: string }>) : []; const { loading, error, data } = useGetSearchResultsQuery({ variables: { input: { type, query, start: (page - 1) * RESULTS_PER_PAGE, count: RESULTS_PER_PAGE, filters, }, }, }); const onSearchTypeChange = (newType: string) => { const entityType = fromCollectionName(newType); history.push({ pathname: PageRoutes.SEARCH, search: `?type=${toPathName(entityType)}&query=${query}&page=1`, }); }; const onFilterSelect = (selected: boolean, field: string, value: string) => { const newFilters = selected ? [...filters, { field, value }] : filters.filter((filter) => filter.field !== field || filter.value !== value); history.push({ pathname: PageRoutes.SEARCH, search: `?type=${toPathName(type)}&query=${query}&page=1`, state: { filters: newFilters, }, }); }; const onResultsPageChange = (newPage: number) => { return history.push({ pathname: PageRoutes.SEARCH, search: `?type=${toPathName(type)}&query=${query}&page=${newPage}`, state: { filters: [...filters], }, }); }; const navigateToDataset = (urn: string) => { return history.push({ pathname: `${PageRoutes.DATASETS}/${urn}`, }); }; const toDatasetSearchResult = (dataset: { urn: string; name: string; origin: string; description: string; platformNativeType: PlatformNativeType; }) => { return { title: (
{dataset.name}
), preview: ( <>
{dataset.description}
Data Origin
{dataset.origin}
Platform
{dataset.platformNativeType}
), onNavigate: () => navigateToDataset(dataset.urn), }; }; const toSearchResults = (elements: any) => { switch (type) { case EntityType.Dataset: return elements.map((element: any) => toDatasetSearchResult(element)); default: throw new Error(`Search for entity of type ${type} currently not supported!`); } }; const searchResults = (data && data?.search && toSearchResults(data.search.elements)) || []; return ( onSearchTypeChange(newPath)} > {SEARCHABLE_ENTITY_TYPES.map((t) => ( ))} {loading &&

Loading results...

} {error && !data &&

Search error!

} {data && data?.search && ( )}
); };