11import { useSearchTerm } from '../search.store'
2- import { SearchResultItem , useSearchQuery } from './useSearchQuery'
2+ import { useSearchQuery } from './useSearchQuery'
33import {
4- useEuiFontSize ,
5- EuiHighlight ,
6- EuiLink ,
4+ EuiButton ,
75 EuiLoadingSpinner ,
86 EuiSpacer ,
97 EuiText ,
108 useEuiTheme ,
11- EuiIcon ,
12- EuiPagination ,
139} from '@elastic/eui'
1410import { css } from '@emotion/react'
15- import { useDebounce } from '@uidotdev/usehooks'
1611import * as React from 'react'
17- import { useEffect , useMemo , useState } from 'react'
1812
1913export const SearchResults = ( ) => {
2014 const searchTerm = useSearchTerm ( )
21- const [ activePage , setActivePage ] = useState ( 0 )
22- const debouncedSearchTerm = useDebounce ( searchTerm , 300 )
23- useEffect ( ( ) => {
24- setActivePage ( 0 )
25- } , [ debouncedSearchTerm ] )
26- const { data, error, isLoading, isFetching } = useSearchQuery ( {
27- searchTerm,
28- pageNumber : activePage + 1 ,
29- } )
15+ const { data, error, isLoading } = useSearchQuery ( )
3016 const { euiTheme } = useEuiTheme ( )
3117
3218 if ( ! searchTerm ) {
@@ -37,193 +23,88 @@ export const SearchResults = () => {
3723 return < div > Error loading search results: { error . message } </ div >
3824 }
3925
40- return (
41- < div >
42- < div
43- css = { css `
44- display : flex;
45- gap : ${ euiTheme . size . s } ;
46- align-items : center;
47- ` }
48- >
49- { isLoading || isFetching ? (
50- < EuiLoadingSpinner size = "s" />
51- ) : (
52- < EuiIcon type = "search" color = "subdued" size = "s" />
53- ) }
54- < EuiText size = "xs" >
55- Search results for{ ' ' }
56- < span
57- css = { css `
58- font-weight : ${ euiTheme . font . weight . bold } ;
59- ` }
60- >
61- { searchTerm }
62- </ span >
63- </ EuiText >
26+ if ( isLoading ) {
27+ return (
28+ < div >
29+ < EuiLoadingSpinner size = "s" /> Loading search results...
6430 </ div >
65- < EuiSpacer size = "s" />
66- { data && (
67- < >
68- < ul >
69- { data . results . map ( ( result ) => (
70- < SearchResultListItem item = { result } />
71- ) ) }
72- </ ul >
73- < div
74- css = { css `
75- display : flex;
76- justify-content : flex-end;
77- ` }
78- >
79- < EuiPagination
80- aria-label = "Many pages example"
81- pageCount = { Math . min ( data . pageCount , 10 ) }
82- activePage = { activePage }
83- onPageClick = { ( activePage ) =>
84- setActivePage ( activePage )
85- }
86- />
87- </ div >
88- </ >
89- ) }
90- </ div >
91- )
92- }
93-
94- interface SearchResultListItemProps {
95- item : SearchResultItem
96- }
97-
98- function SearchResultListItem ( { item : result } : SearchResultListItemProps ) {
99- const { euiTheme } = useEuiTheme ( )
100- const searchTerm = useSearchTerm ( )
101- const highlightSearchTerms = useMemo (
102- ( ) => searchTerm . toLowerCase ( ) . split ( ' ' ) ,
103- [ searchTerm ]
104- )
31+ )
32+ }
10533
106- if ( highlightSearchTerms . includes ( 'esql' ) ) {
107- highlightSearchTerms . push ( 'es|ql' )
34+ if ( ! data || data . results . length === 0 ) {
35+ return < EuiText size = "xs" > No results found for " { searchTerm } " </ EuiText >
10836 }
10937
110- if ( highlightSearchTerms . includes ( 'dotnet' ) ) {
111- highlightSearchTerms . push ( '.net' )
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
11261 }
113- return (
114- < li key = { result . url } >
115- < div
116- tabIndex = { 0 }
117- css = { css `
118- display : flex;
119- align-items : flex-start;
120- gap : ${ euiTheme . size . s } ;
121- padding-inline : ${ euiTheme . size . s } ;
122- padding-block : ${ euiTheme . size . xs } ;
123- border-radius : ${ euiTheme . border . radius . small } ;
124- : hover {
125- background-color : ${ euiTheme . colors . backgroundTransparentSubdued } ;
126- ` }
127- >
128- < EuiIcon
129- type = "document"
130- color = "subdued"
131- css = { css `
132- margin-top : ${ euiTheme . size . xs } ;
133- ` }
134- />
135- < div
136- css = { css `
137- width : 100% ;
138- text-align : left;
139- ` }
140- >
141- < EuiLink
142- tabIndex = { - 1 }
143- href = { result . url }
144- css = { css `
145- .euiMark {
146- background-color : ${ euiTheme . colors
147- . backgroundLightWarning } ;
148- font-weight : inherit;
149- }
150- ` }
151- >
152- < EuiHighlight
153- search = { highlightSearchTerms }
154- highlightAll = { true }
155- >
156- { result . title }
157- </ EuiHighlight >
158- </ EuiLink >
159- < Breadcrumbs
160- parents = { result . parents }
161- highlightSearchTerms = { highlightSearchTerms }
162- />
163- </ div >
164- </ div >
165- </ li >
166- )
167- }
16862
169- function Breadcrumbs ( {
170- parents,
171- highlightSearchTerms,
172- } : {
173- parents : SearchResultItem [ 'parents' ]
174- highlightSearchTerms : string [ ]
175- } ) {
176- const { euiTheme } = useEuiTheme ( )
177- const { fontSize : smallFontsize } = useEuiFontSize ( 'xs' )
17863 return (
179- < ul
180- css = { css `
181- margin-top : 2px ;
182- display : flex;
183- gap : 0 ${ euiTheme . size . xs } ;
184- flex-wrap : wrap;
185- list-style : none;
64+ < div
65+ css = { `
66+ li:not(:first-child) {
67+ margin-top: ${ euiTheme . size . xs } ;
68+ }
18669 ` }
18770 >
188- { parents
189- . slice ( 1 ) // skip /docs
190- . map ( ( parent ) => (
191- < li
192- key = { 'breadcrumb-' + parent . url }
193- css = { css `
194- & : not (: last-child )::after {
195- content : '/' ;
196- margin-left : ${ euiTheme . size . xs } ;
197- font-size : ${ smallFontsize } ;
198- color : ${ euiTheme . colors . text } ;
199- margin-top : -1px ;
200- }
201- display : inline-flex;
202- ` }
203- >
204- < EuiLink href = { parent . url } color = "text" tabIndex = { - 1 } >
205- < EuiText
206- size = "xs"
207- color = "subdued"
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
20884 css = { css `
209- .euiMark {
210- background-color : transparent;
211- text-decoration : underline;
212- color : inherit;
213- font-weight : inherit;
214- }
85+ width : 100% ;
86+ text-align : left;
21587 ` }
21688 >
217- < EuiHighlight
218- search = { highlightSearchTerms }
219- highlightAll = { true }
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"
22098 >
221- { parent . title }
222- </ EuiHighlight >
223- </ EuiText >
224- </ EuiLink >
99+ { trimDescription ( result . description ) }
100+ </ EuiText >
101+ </ div >
102+ </ EuiButton >
103+ { /*<EuiIcon type="document" color="subdued" />*/ }
104+ { /*<EuiText>{result.title}</EuiText>*/ }
225105 </ li >
226106 ) ) }
227- </ ul >
107+ </ ul >
108+ </ div >
228109 )
229110}
0 commit comments