diff --git a/site/search/Search.scss b/site/search/Search.scss index d5645836648..8d567ad359f 100644 --- a/site/search/Search.scss +++ b/site/search/Search.scss @@ -192,7 +192,7 @@ } .search-results__pages-list, -.search-results__explorer-views-list, +.search-results__explorer-list, .search-results__charts-list { gap: var(--grid-gap); @include sm-only { @@ -227,7 +227,7 @@ display: block; } -.search-results__explorer-view-hit a { +.search-results__explorer-hit { background-color: $blue-10; height: 100%; padding: 24px; @@ -246,6 +246,40 @@ p { color: $blue-60; } + + .search-results__explorer-hit-title { + display: inline; + color: $blue-90; + margin: 0 8px 0 0; + } + + .search-results__explorer-hit-subtitle { + margin: 0 8px 0 0; + } + + .search-results__explorer-views-list { + margin-left: 20px; + margin-top: 5px; + list-style: none; + + .search-results__explorer-view-title { + color: $blue-90; + text-decoration: underline; + } + + .search-results__explorer-view-subtitle { + color: $blue-60; + margin-top: 0px; + // text-overflow: ellipsis; + // white-space: nowrap; + // overflow: hidden; + // max-width: 100%; + } + } + + .search-results__explorer-hit-link { + @include owid-link-60; + } } .search-results__chart-hit { diff --git a/site/search/SearchPanel.tsx b/site/search/SearchPanel.tsx index 78db94f8c72..aef3b6db2e3 100644 --- a/site/search/SearchPanel.tsx +++ b/site/search/SearchPanel.tsx @@ -6,6 +6,8 @@ import { getWindowQueryParams, get, mapValues, + groupBy, + uniqBy, } from "@ourworldindata/utils" import { InstantSearch, @@ -17,6 +19,7 @@ import { Snippet, useInstantSearch, PoweredBy, + useHits, } from "react-instantsearch-hooks-web" import algoliasearch, { SearchClient } from "algoliasearch" import { @@ -121,6 +124,59 @@ function ChartHit({ hit }: { hit: IChartHit }) { ) } +function ExplorerViewHits() { + const { hits, results, sendEvent } = useHits() + + const groupedBySlug = groupBy(hits, "explorerSlug") + const grouped = Object.values(groupedBySlug).map((explorerViews) => { + const firstView = explorerViews[0] + return { + explorerSlug: firstView.explorerSlug, + explorerTitle: firstView.explorerTitle, + explorerSubtitle: firstView.explorerSubtitle, + numViewsWithinExplorer: firstView.numViewsWithinExplorer, + views: uniqBy(explorerViews, "viewTitle"), + } + }) + + return ( +
+
    + {grouped.map((group) => ( +
    +

    + {group.explorerTitle} +

    +

    + {group.explorerSubtitle} +

    +
      + {group.views.map((hit) => ( +
    • + +
    • + ))} +
    + + Explore all {group.numViewsWithinExplorer}{" "} + indicators + +
    + ))} +
+
+ ) +} + function ExplorerViewHit({ hit }: { hit: IExplorerViewHit }) { return ( -

{hit.viewTitle}

- - in {hit.explorerTitle} Data Explorer - + +

+ {hit.viewSubtitle} +

{/* Explorer subtitles are mostly useless at the moment, so we're only showing titles */}
) @@ -311,6 +372,7 @@ const SearchResults = (props: SearchResultsProps) => { const hasClickAnalyticsConsent = getPreferenceValue( PreferenceType.Analytics ) + return (
{ @@ -361,21 +423,22 @@ const SearchResults = (props: SearchResultsProps) => { - + {/* + /> */} diff --git a/site/search/searchTypes.ts b/site/search/searchTypes.ts index 301ca7bcbbb..52a54d5c298 100644 --- a/site/search/searchTypes.ts +++ b/site/search/searchTypes.ts @@ -38,10 +38,17 @@ export type IPageHit = PageRecord & Hit export type IExplorerViewHit = Hit & { objectID: string + + // Explorer-wide fields explorerSlug: string - viewTitle: string explorerTitle: string + numViewsWithinExplorer: number + + // View-specific fields + viewTitle: string + viewSubtitle: string viewQueryParams: string + viewTitleIndexWithinExplorer: number } export type IExplorerHit = Hit & { @@ -86,7 +93,7 @@ export type SearchCategoryFilter = SearchIndexName | "all" export const searchCategoryFilters: [string, SearchCategoryFilter][] = [ ["All", "all"], ["Research & Writing", SearchIndexName.Pages], - ["Data Explorers", SearchIndexName.Explorers], + ["Data Explorers", SearchIndexName.ExplorerViews], ["Charts", SearchIndexName.Charts], ]