Skip to content

Commit 06bac08

Browse files
authored
Merge branch 'main' into feature/integration-tests
2 parents dfbd4af + cf6e824 commit 06bac08

File tree

22 files changed

+422
-19
lines changed

22 files changed

+422
-19
lines changed

config/legacy-url-mappings.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
stack: &stack [ '9.0+', '8.19', '8.18', '8.17', '8.16', '8.15', '8.14', '8.13', '8.12', '8.11', '8.10', '8.9', '8.8', '8.7', '8.6', '8.5', '8.4', '8.3', '8.2', '8.1', '8.0', '7.17' ]
88

99
mappings:
10-
en/apm/agent/android/: [ '1.0.0' , '0.x' ]
10+
en/apm/agent/android/: [ '1.2.0' , '0.x' ]
1111
en/apm/agent/dotnet/: [ '1.32.0', '1.8' ]
1212
en/apm/agent/go/: [ '2.7.1', '1.x', '0.5' ]
1313
en/apm/agent/java/: ['1.54.0', '0.7', '0.6']

src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/AskAiAnswer.test.tsx renamed to src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/AskAi/AskAiAnswer.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const mockSendQuestion = jest.fn(() => Promise.resolve())
1111
const mockRetry = jest.fn()
1212
const mockAbort = jest.fn()
1313

14-
jest.mock('./search.store', () => ({
14+
jest.mock('../search.store', () => ({
1515
useAskAiTerm: jest.fn(() => 'What is Elasticsearch?'),
1616
}))
1717

src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/AskAiAnswer.tsx renamed to src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/AskAi/AskAiAnswer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useAskAiTerm } from './search.store'
1+
import { useAskAiTerm } from '../search.store'
22
import { LlmGatewayMessage, useLlmGateway } from './useLlmGateway'
33
import {
44
EuiFlexGroup,

src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/AskAiSuggestions.tsx renamed to src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/AskAi/AskAiSuggestions.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useSearchActions, useSearchTerm } from './search.store'
1+
import { useSearchActions, useSearchTerm } from '../search.store'
22
import { EuiButton, EuiSpacer, EuiText, useEuiTheme } from '@elastic/eui'
33
import { css } from '@emotion/react'
44
import * as React from 'react'
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import { useSearchTerm } from '../search.store'
2+
import { useSearchQuery } from './useSearchQuery'
3+
import {
4+
EuiButton,
5+
EuiLoadingSpinner,
6+
EuiSpacer,
7+
EuiText,
8+
useEuiTheme,
9+
} from '@elastic/eui'
10+
import { css } from '@emotion/react'
11+
import * as React from 'react'
12+
13+
export const SearchResults = () => {
14+
const searchTerm = useSearchTerm()
15+
const { data, error, isLoading } = useSearchQuery()
16+
const { euiTheme } = useEuiTheme()
17+
18+
if (!searchTerm) {
19+
return
20+
}
21+
22+
if (error) {
23+
return <div>Error loading search results: {error.message}</div>
24+
}
25+
26+
if (isLoading) {
27+
return (
28+
<div>
29+
<EuiLoadingSpinner size="s" /> Loading search results...
30+
</div>
31+
)
32+
}
33+
34+
if (!data || data.results.length === 0) {
35+
return <EuiText size="xs">No results found for "{searchTerm}"</EuiText>
36+
}
37+
38+
const buttonCss = css`
39+
border: none;
40+
vertical-align: top;
41+
justify-content: flex-start;
42+
block-size: 100%;
43+
padding-block: 4px;
44+
& > span {
45+
justify-content: flex-start;
46+
align-items: flex-start;
47+
}
48+
svg {
49+
color: ${euiTheme.colors.textSubdued};
50+
}
51+
.euiIcon {
52+
margin-top: 4px;
53+
}
54+
`
55+
56+
const trimDescription = (description: string) => {
57+
const limit = 200
58+
return description.length > limit
59+
? description.slice(0, limit) + '...'
60+
: description
61+
}
62+
63+
return (
64+
<div
65+
css={`
66+
li:not(:first-child) {
67+
margin-top: ${euiTheme.size.xs};
68+
}
69+
`}
70+
>
71+
<EuiText size="xs">Search Results for "{searchTerm}"</EuiText>
72+
<EuiSpacer size="s" />
73+
<ul>
74+
{data.results.map((result) => (
75+
<li key={result.url}>
76+
<EuiButton
77+
css={buttonCss}
78+
iconType="document"
79+
color="text"
80+
size="s"
81+
fullWidth
82+
>
83+
<div
84+
css={css`
85+
width: 100%;
86+
text-align: left;
87+
`}
88+
>
89+
{result.title}
90+
<EuiSpacer size="xs" />
91+
<EuiText
92+
css={css`
93+
text-wrap: pretty;
94+
`}
95+
textAlign="left"
96+
size="xs"
97+
color="subdued"
98+
>
99+
{trimDescription(result.description)}
100+
</EuiText>
101+
</div>
102+
</EuiButton>
103+
{/*<EuiIcon type="document" color="subdued" />*/}
104+
{/*<EuiText>{result.title}</EuiText>*/}
105+
</li>
106+
))}
107+
</ul>
108+
</div>
109+
)
110+
}

src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/SearchSuggestions.tsx renamed to src/Elastic.Documentation.Site/Assets/web-components/SearchOrAskAi/Search/SearchSuggestions.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useModalActions } from './modal.store'
1+
import { useModalActions } from '../modal.store'
22
import {
33
EuiButton,
44
EuiSpacer,
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { useSearchTerm } from '../search.store'
2+
import { useQuery } from '@tanstack/react-query'
3+
import { useDebounce } from '@uidotdev/usehooks'
4+
import { z } from 'zod'
5+
6+
const SearchResultItem = z.object({
7+
url: z.string(),
8+
title: z.string(),
9+
description: z.string(),
10+
score: z.number(),
11+
})
12+
13+
const SearchResponse = z.object({
14+
results: z.array(SearchResultItem),
15+
totalResults: z.number(),
16+
})
17+
18+
type SearchResponse = z.infer<typeof SearchResponse>
19+
20+
export const useSearchQuery = () => {
21+
const searchTerm = useSearchTerm()
22+
const trimmedSearchTerm = searchTerm.trim()
23+
const debouncedSearchTerm = useDebounce(trimmedSearchTerm, 300)
24+
return useQuery<SearchResponse>({
25+
queryKey: ['search', { searchTerm: debouncedSearchTerm }],
26+
queryFn: async () => {
27+
const response = await fetch(
28+
'/_api/v1/search?q=' + encodeURIComponent(debouncedSearchTerm)
29+
)
30+
if (!response.ok) {
31+
throw new Error(
32+
'Failed to fetch search results: ' + response.statusText
33+
)
34+
}
35+
const data = await response.json()
36+
return SearchResponse.parse(data)
37+
},
38+
enabled: !!trimmedSearchTerm && trimmedSearchTerm.length >= 1,
39+
refetchOnWindowFocus: false,
40+
staleTime: 1000 * 60 * 10, // 10 minutes
41+
})
42+
}

0 commit comments

Comments
 (0)