Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion components/Search.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
top: 0;
right: 0;
width: 0;
border-radius: 3px;
border-radius: 0 0 0 3px;
background: var(--color-canvas-default);
box-shadow: 0 1px 15px rgba(0, 0, 0, 0.15);
transition: width 0.3s ease-in-out;
Expand Down
184 changes: 116 additions & 68 deletions components/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export function Search({
const { t } = useTranslation('search')
const { currentVersion } = useVersion()
const { languages } = useLanguages()
const initialRender = useRef(true)

// Figure out language and version for index
const { searchVersions, nonEnterpriseDefaultVersion } = useMainContext()
Expand All @@ -61,6 +62,18 @@ export function Search({
}
}, [])

// If the version changed from the dropdown version or language picker
// close the search pane and clear the query
// If the version changed from the search result window, keep the query
// and results but reset the versionFromSearchPane value
useEffect(() => {
if (initialRender.current) {
initialRender.current = false
} else {
closeSearch()
}
}, [currentVersion, language])

// When the user finishes typing, update the results
async function onSearch(e: React.ChangeEvent<HTMLInputElement>) {
const xquery = e.target?.value?.trim()
Expand Down Expand Up @@ -116,6 +129,9 @@ export function Search({
function closeSearch() {
setQuery('')
setResults(null)
if (inputRef.current) {
inputRef.current.value = ''
}
}

// Prevent the page from refreshing when you "submit" the form
Expand Down Expand Up @@ -143,6 +159,7 @@ export function Search({
results={results}
closeSearch={closeSearch}
debug={'debug' in router.query}
query={query}
/>
</div>
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */}
Expand Down Expand Up @@ -212,15 +229,34 @@ function ShowSearchResults({
results,
closeSearch,
debug,
query,
}: {
anchorRef: RefObject<HTMLElement>
isHeaderSearch: boolean
isLoading: boolean
results: SearchResult[] | null
closeSearch: () => void
debug: boolean
query: string | string[]
}) {
const { t } = useTranslation('search')
const router = useRouter()
const { currentVersion } = useVersion()
const { allVersions } = useMainContext()
const searchVersion = allVersions[currentVersion].versionTitle
const latestVersions = new Set(
Object.keys(allVersions)
.map((version) => allVersions[version].latestVersion)
.filter((version) => version !== currentVersion)
)

const versions = Array.from(latestVersions).map((version) => {
return {
title: allVersions[version].versionTitle,
version: version,
}
})
const redirectQuery = query ? `?query=${query}` : ''

if (results !== null) {
if (results.length === 0) {
Expand Down Expand Up @@ -263,76 +299,88 @@ function ShowSearchResults({
}
}
>
<div data-testid="search-results" className="mt-n2 mb-n2">
<div data-testid="search-results">
<div className="my-4">
<p className="ml-4">
You're searching the <span className="color-fg-attention">{searchVersion}</span>{' '}
version. Didn't find what you're looking for? Click a different version to try
again.
</p>
{versions.map(({ title, version }) => {
return (
<button key={version} className="btn mr-2 mt-4 ml-4" type="button">
<a href={`/${router.locale}/${version}${redirectQuery}`}>{title}</a>
</button>
)
})}
</div>
<ActionList
items={results
.slice(0, results.length - 1)
.map(({ url, breadcrumbs, title, content, score, popularity }) => {
return {
key: url,
text: title,
renderItem: () => (
<ActionList.Item as="div">
<Link href={url} className="no-underline color-fg-default">
<li
key={url}
data-testid="search-result"
className={cx('list-style-none')}
>
<div className={cx('py-2 px-3')}>
{/* Breadcrumbs in search records don't include the page title. These fields may contain <mark> elements that we need to render */}
<Label variant="small" sx={{ bg: 'accent.emphasis' }}>
{breadcrumbs.length === 0
? title.replace(/<\/?[^>]+(>|$)|(\/)/g, '')
: breadcrumbs
.split(' / ')
.slice(0, 1)
.join(' ')
.replace(/<\/?[^>]+(>|$)|(\/)/g, '')}
</Label>
{debug && (
<small className="float-right">
score: {score.toFixed(4)} popularity: {popularity.toFixed(4)}
</small>
items={results.map(({ url, breadcrumbs, title, content, score, popularity }) => {
return {
key: url,
text: title,
renderItem: () => (
<ActionList.Item as="div">
<Link href={url} className="no-underline color-fg-default">
<li
key={url}
data-testid="search-result"
className={cx('list-style-none')}
>
<div className={cx('py-2 px-3')}>
{/* Breadcrumbs in search records don't include the page title. These fields may contain <mark> elements that we need to render */}
<Label variant="small" sx={{ bg: 'accent.emphasis' }}>
{breadcrumbs.length === 0
? title.replace(/<\/?[^>]+(>|$)|(\/)/g, '')
: breadcrumbs
.split(' / ')
.slice(0, 1)
.join(' ')
.replace(/<\/?[^>]+(>|$)|(\/)/g, '')}
</Label>
{debug && (
<small className="float-right">
score: {score.toFixed(4)} popularity: {popularity.toFixed(4)}
</small>
)}
<div
className={cx(
styles.searchResultTitle,
'mt-2 d-block f4 text-semibold'
)}
dangerouslySetInnerHTML={{
__html: title,
}}
/>
<div
className={cx(
styles.searchResultContent,
'mt-1 d-block overflow-hidden'
)}
<div
className={cx(
styles.searchResultTitle,
'mt-2 d-block f4 text-semibold'
)}
dangerouslySetInnerHTML={{
__html: title,
}}
/>
<div
className={cx(
styles.searchResultContent,
'mt-1 d-block overflow-hidden'
)}
style={{ maxHeight: '2.5rem' }}
dangerouslySetInnerHTML={{ __html: content }}
/>
<div
className={'d-block mt-2 opacity-60 text-small'}
dangerouslySetInnerHTML={
breadcrumbs.length === 0
? { __html: `${title}`.replace(/<\/?[^>]+(>|$)|(\/)/g, '') }
: {
__html: breadcrumbs
.split(' / ')
.slice(0, breadcrumbs.length - 1)
.join(' / ')
.replace(/<\/?[^>]+(>|$)/g, ''),
}
}
/>
</div>
</li>
</Link>
</ActionList.Item>
),
}
})}
style={{ maxHeight: '2.5rem' }}
dangerouslySetInnerHTML={{ __html: content }}
/>
<div
className={'d-block mt-2 opacity-60 text-small'}
dangerouslySetInnerHTML={
breadcrumbs.length === 0
? { __html: `${title}`.replace(/<\/?[^>]+(>|$)|(\/)/g, '') }
: {
__html: breadcrumbs
.split(' / ')
.slice(0, breadcrumbs.length - 1)
.join(' / ')
.replace(/<\/?[^>]+(>|$)/g, ''),
}
}
/>
</div>
</li>
</Link>
</ActionList.Item>
),
}
})}
/>
</div>
</Overlay>
Expand Down
2 changes: 2 additions & 0 deletions components/context/MainContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ export type ProductGroupT = {
type VersionItem = {
version: string
versionTitle: string
currentRelease: string
latestVersion: string
}

export type ProductTreeNode = {
Expand Down