@@ -2,116 +2,245 @@ import * as React from 'react';
22import { observer } from 'mobx-react-lite' ;
33import { ConfigContext , localize , getIcon } from '@ali/ide-core-browser' ;
44import { ProgressBar } from '@ali/ide-core-browser/lib/components/progressbar' ;
5- import { ValidateInput } from '@ali/ide-components' ;
5+ import { Input , ValidateInput , CheckBox , Popover , PopoverTriggerType } from '@ali/ide-components' ;
66import { ViewState } from '@ali/ide-core-browser' ;
77import * as cls from 'classnames' ;
88import * as styles from '@ali/ide-search/lib/browser/search.module.less' ;
99import { SEARCH_STATE } from '@ali/ide-search/lib/common' ;
1010import { ContentSearchClientService } from '@ali/ide-search/lib/browser/search.service' ;
1111import { SearchTree } from './search-tree.view' ;
1212
13- export const Search = observer (
14- ( { viewState } : React . PropsWithChildren < { viewState : ViewState } > ) => {
15- const searchOptionRef = React . createRef < HTMLDivElement > ( ) ;
16- const configContext = React . useContext ( ConfigContext ) ;
17- const { injector } = configContext ;
18- const searchBrowserService = injector . get ( ContentSearchClientService ) ;
13+ function getIncludeRuleContent ( ) {
14+ return (
15+ < div className = { cls ( styles . include_rule_content ) } >
16+ < ul >
17+ < li > , : { localize ( 'search.help.concatRule' ) } </ li >
18+ < li > * : { localize ( 'search.help.matchOneOrMoreRule' ) } </ li >
19+ < li > ? : { localize ( 'search.help.matchOne' ) } </ li >
20+ < li > ** : { localize ( 'search.help.matchAny' ) } </ li >
21+ < li > { } : { localize ( 'search.help.matchWithGroup' ) } </ li >
22+ < li > [] : { localize ( 'search.help.matchRange' ) } </ li >
23+ </ ul >
24+ </ div >
25+ ) ;
26+ }
1927
20- const [ searchPanelLayout , setSearchPanelLayout ] = React . useState ( { height : 0 , width : 0 } ) ;
21- const searchTreeRef = React . useRef ( ) ;
28+ function getExcludeRuleContent ( excludeList : string [ ] ) {
29+ return (
30+ < div className = { cls ( styles . exclude_rule_content ) } >
31+ < div >
32+ { excludeList . map ( ( exclude , index ) => {
33+ if ( index === excludeList . length - 1 ) {
34+ return exclude ;
35+ }
36+ return `${ exclude } , ` ;
37+ } ) }
38+ </ div >
39+ </ div >
40+ ) ;
41+ }
2242
23- const searchResults = searchBrowserService . searchResults ;
24- const resultTotal = searchBrowserService . resultTotal ;
25- const searchState = searchBrowserService . searchState ;
26- const doReplaceAll = searchBrowserService . doReplaceAll ;
27- const updateUIState = searchBrowserService . updateUIState ;
28- const UIState = searchBrowserService . UIState ;
29- const searchError = searchBrowserService . searchError ;
30- const isSearchDoing = searchBrowserService . isSearchDoing ;
31- const validateMessage = searchBrowserService . validateMessage ;
32- const isShowValidateMessage = searchBrowserService . isShowValidateMessage ;
43+ export const Search = observer ( ( {
44+ viewState,
45+ } : React . PropsWithChildren < { viewState : ViewState } > ,
46+ ) => {
47+ const searchOptionRef = React . createRef < HTMLDivElement > ( ) ;
48+ const configContext = React . useContext ( ConfigContext ) ;
49+ const { injector } = configContext ;
50+ const searchBrowserService = injector . get ( ContentSearchClientService ) ;
3351
34- React . useEffect ( ( ) => {
35- setSearchPanelLayout ( {
36- width : ( searchOptionRef . current && searchOptionRef . current . clientWidth ) || 0 ,
37- height : ( searchOptionRef . current && searchOptionRef . current . clientHeight ) || 0 ,
38- } ) ;
39- } , [ UIState , searchOptionRef . current , searchResults . size > 0 ] ) ;
52+ const [ searchPanelLayout , setSearchPanelLayout ] = React . useState ( { height : 0 , width : 0 } ) ;
53+ const searchTreeRef = React . useRef ( ) ;
4054
41- const collapsePanelContainerStyle = {
42- width : viewState . width || '100%' ,
43- height : viewState . height ,
44- } ;
55+ const searchResults = searchBrowserService . searchResults ;
56+ const resultTotal = searchBrowserService . resultTotal ;
57+ const searchState = searchBrowserService . searchState ;
58+ const doReplaceAll = searchBrowserService . doReplaceAll ;
59+ const updateUIState = searchBrowserService . updateUIState ;
60+ const UIState = searchBrowserService . UIState ;
61+ const searchError = searchBrowserService . searchError ;
62+ const isSearchDoing = searchBrowserService . isSearchDoing ;
63+ const validateMessage = searchBrowserService . validateMessage ;
64+ const isShowValidateMessage = searchBrowserService . isShowValidateMessage ;
4565
46- return (
47- < div className = { styles . wrap } style = { collapsePanelContainerStyle } >
48- < div className = { styles [ 'loading-wrap' ] } >
49- < ProgressBar loading = { isSearchDoing } />
50- </ div >
51- < div className = { styles . search_options } ref = { searchOptionRef } >
52- < div className = { styles . search_and_replace_container } >
53- < div className = { styles . search_and_replace_fields } >
54- < div className = { styles . search_field_container } >
55- < p className = { styles . search_input_title } > { localize ( 'search.input.title' ) } </ p >
56- < div
57- className = { cls ( styles . search_field , { [ styles . focus ] : UIState . isSearchFocus } ) }
58- >
59- < ValidateInput
60- id = "search-input-field"
61- title = { localize ( 'search.input.placeholder' ) }
62- type = "text"
63- value = { searchBrowserService . searchValue }
64- placeholder = { localize ( 'search.input.placeholder' ) }
65- onFocus = { ( ) => updateUIState ( { isSearchFocus : true } ) }
66- onBlur = { ( ) => updateUIState ( { isSearchFocus : false } ) }
67- onKeyUp = { searchBrowserService . search }
68- onChange = { searchBrowserService . onSearchInputChange }
69- ref = { searchBrowserService . searchInputEl }
70- validateMessage = { isShowValidateMessage ? validateMessage : undefined }
71- addonAfter = { [
72- < span
73- key = { localize ( 'caseDescription' ) }
74- className = { cls ( getIcon ( 'ab' ) , styles [ 'match-case' ] , styles . option , {
75- [ styles . select ] : UIState . isMatchCase ,
76- } ) }
77- title = { localize ( 'caseDescription' ) }
78- onClick = { ( e ) => updateUIState ( { isMatchCase : ! UIState . isMatchCase } , e ) }
79- /> ,
80- < span
81- key = { localize ( 'wordsDescription' ) }
82- className = { cls ( getIcon ( 'abl' ) , styles [ 'whole-word' ] , styles . option , {
83- [ styles . select ] : UIState . isWholeWord ,
84- } ) }
85- title = { localize ( 'wordsDescription' ) }
86- onClick = { ( e ) => updateUIState ( { isWholeWord : ! UIState . isWholeWord } , e ) }
87- /> ,
88- ] }
89- />
90- </ div >
66+ React . useEffect ( ( ) => {
67+ setSearchPanelLayout ( {
68+ width : searchOptionRef . current && searchOptionRef . current . clientWidth || 0 ,
69+ height : searchOptionRef . current && searchOptionRef . current . clientHeight || 0 ,
70+ } ) ;
71+ } , [ UIState , searchOptionRef . current , searchResults . size > 0 ] ) ;
72+
73+ const collapsePanelContainerStyle = {
74+ width : viewState . width || '100%' ,
75+ height : viewState . height ,
76+ } ;
77+
78+ return (
79+ < div className = { styles . wrap } style = { collapsePanelContainerStyle } >
80+ < div className = { styles [ 'loading-wrap' ] } >
81+ < ProgressBar loading = { isSearchDoing } />
82+ </ div >
83+ < div className = { styles . search_options } ref = { searchOptionRef } >
84+ < div className = { styles . search_and_replace_container } >
85+ < div className = { styles . search_and_replace_fields } >
86+ < div className = { styles . search_field_container } >
87+ < p className = { styles . search_input_title } >
88+ { localize ( 'search.input.title' ) }
89+ < CheckBox
90+ insertClass = { cls ( styles . checkbox ) }
91+ label = { localize ( 'search.input.checkbox' ) }
92+ checked = { UIState . isDetailOpen }
93+ id = 'search-input'
94+ onChange = { ( ) => { updateUIState ( { isDetailOpen : ! UIState . isDetailOpen } ) ; } }
95+ />
96+ </ p >
97+ < div className = { cls ( styles . search_field , { [ styles . focus ] : UIState . isSearchFocus } ) } >
98+ < ValidateInput
99+ id = 'search-input-field'
100+ title = { localize ( 'search.input.placeholder' ) }
101+ type = 'text'
102+ value = { searchBrowserService . searchValue }
103+ placeholder = { localize ( 'search.input.placeholder' ) }
104+ onFocus = { ( ) => updateUIState ( { isSearchFocus : true } ) }
105+ onBlur = { ( ) => updateUIState ( { isSearchFocus : false } ) }
106+ onKeyUp = { searchBrowserService . search }
107+ onChange = { searchBrowserService . onSearchInputChange }
108+ ref = { searchBrowserService . searchInputEl }
109+ validateMessage = { isShowValidateMessage ? validateMessage : undefined }
110+ addonAfter = { [
111+ < span
112+ key = { localize ( 'caseDescription' ) }
113+ className = { cls ( getIcon ( 'ab' ) , styles [ 'match-case' ] , styles . option , { [ styles . select ] : UIState . isMatchCase } ) }
114+ title = { localize ( 'caseDescription' ) }
115+ onClick = { ( e ) => updateUIState ( { isMatchCase : ! UIState . isMatchCase } , e ) }
116+ > </ span > ,
117+ < span
118+ key = { localize ( 'wordsDescription' ) }
119+ className = { cls ( getIcon ( 'abl' ) , styles [ 'whole-word' ] , styles . option , { [ styles . select ] : UIState . isWholeWord } ) }
120+ title = { localize ( 'wordsDescription' ) }
121+ onClick = { ( e ) => updateUIState ( { isWholeWord : ! UIState . isWholeWord } , e ) }
122+ > </ span > ,
123+ ] }
124+ />
91125 </ div >
126+ { /* <div className='search-notification '>
127+ <div>This is only a subset of all results. Use a more specific search term to narrow down the result list.</div>
128+ </div> */ }
92129 </ div >
93130 </ div >
94131 </ div >
95- { searchResults && searchResults . size > 0 && ! searchError ? (
96- < SearchTree
97- searchPanelLayout = { searchPanelLayout }
98- viewState = { viewState }
99- ref = { searchTreeRef }
100- />
101- ) : (
102- < div
103- className = { cls (
104- { [ styles . result_describe ] : searchState === SEARCH_STATE . done } ,
105- { [ styles . result_error ] : searchState === SEARCH_STATE . error || searchError }
106- ) }
107- >
108- { searchState === SEARCH_STATE . done && ! searchError
109- ? localize ( 'noResultsFound' ) . replace ( '-' , '' )
110- : '' }
111- { searchError }
132+
133+ < div className = { cls ( styles . search_details ) } >
134+ { UIState . isDetailOpen ?
135+ < div className = 'glob_field-container' >
136+ < div className = { cls ( styles . glob_field ) } >
137+ < div className = { cls ( styles . label ) } >
138+ < span className = { styles . limit } > { localize ( 'search.includes' ) } </ span >
139+ < span className = { cls ( styles . include_rule ) } >
140+ < Popover
141+ id = { 'show_include_rule' }
142+ title = { localize ( 'search.help.supportRule' ) }
143+ content = { getIncludeRuleContent ( ) }
144+ trigger = { PopoverTriggerType . hover }
145+ delay = { 500 }
146+ >
147+ { localize ( 'search.help.showIncludeRule' ) }
148+ </ Popover >
149+ </ span >
150+ </ div >
151+ < Input
152+ value = { searchBrowserService . includeValue }
153+ type = 'text'
154+ placeholder = { localize ( 'search.includes.description' ) }
155+ onKeyUp = { searchBrowserService . search }
156+ onChange = { searchBrowserService . onSearchIncludeChange }
157+ />
158+ </ div >
159+ < div className = { cls ( styles . glob_field , styles . search_excludes ) } >
160+ < div className = { styles . label } >
161+ < span className = { styles . limit } > { localize ( 'search.excludes' ) } </ span >
162+ < div className = { styles . checkbox_wrap } >
163+ < CheckBox
164+ insertClass = { cls ( styles . checkbox ) }
165+ label = { localize ( 'search.excludes.default.enable' ) }
166+ checked = { ! UIState . isIncludeIgnored }
167+ id = 'search-input-isIncludeIgnored'
168+ onChange = { ( ) => { updateUIState ( { isIncludeIgnored : ! UIState . isIncludeIgnored } ) ; } }
169+ />
170+ < Popover
171+ title = { localize ( 'search.help.excludeList' ) }
172+ insertClass = { cls ( styles . search_excludes_description ) }
173+ id = { 'search_excludes' }
174+ action = { localize ( 'search.help.modify' ) }
175+ onClickAction = { searchBrowserService . openPreference }
176+ content = { getExcludeRuleContent ( searchBrowserService . getPreferenceSearchExcludes ( ) ) }
177+ trigger = { PopoverTriggerType . hover }
178+ delay = { 500 }
179+ >
180+ < span className = { cls ( getIcon ( 'question-circle' ) ) } > </ span >
181+ </ Popover >
182+ </ div >
183+
184+ </ div >
185+ < Input
186+ type = 'text'
187+ value = { searchBrowserService . excludeValue }
188+ placeholder = { localize ( 'search.includes.description' ) }
189+ onKeyUp = { searchBrowserService . search }
190+ onChange = { searchBrowserService . onSearchExcludeChange }
191+ />
192+ </ div >
193+ </ div > : ''
194+ }
195+ </ div >
196+
197+ { /* <div className={styles.search_and_replace_container}>
198+ <div className={styles.search_and_replace_fields}>
199+ <p className={styles.search_input_title}>
200+ {localize('search.replace.title')}
201+ <span
202+ className={styles.replace_all}
203+ onClick={doReplaceAll}
204+ >
205+ {resultTotal.resultNum > 0 ? localize('search.replaceAll.label') : ''}
206+ </span>
207+ </p>
208+ <div className={styles.replace_field}>
209+ <Input
210+ value={searchBrowserService.replaceValue}
211+ id='replace-input-field'
212+ title={localize('search.replace.label')}
213+ type='text'
214+ placeholder={localize('search.replace.label')}
215+ onKeyUp={searchBrowserService.search}
216+ onChange={searchBrowserService.onReplaceInputChange}
217+ ref={searchBrowserService.replaceInputEl}
218+ />
219+ <div className={styles['replace-all-button_container']}>
220+ <span title={localize('replaceAll.confirmation.title')} className={`${styles['replace-all-button']} ${styles.disabled}` }></span>
221+ </div>
222+ </div>
112223 </div>
113- ) }
224+ </div> */ }
225+
114226 </ div >
115- ) ;
116- }
117- ) ;
227+ {
228+ ( searchResults && searchResults . size > 0 && ! searchError ) ? < SearchTree
229+ searchPanelLayout = { searchPanelLayout }
230+ viewState = { viewState }
231+ ref = { searchTreeRef }
232+ /> : < div
233+ className = { cls (
234+ { [ styles . result_describe ] : searchState === SEARCH_STATE . done } ,
235+ { [ styles . result_error ] : searchState === SEARCH_STATE . error || searchError } ,
236+ ) }
237+ >
238+ {
239+ searchState === SEARCH_STATE . done && ! searchError ? localize ( 'noResultsFound' ) . replace ( '-' , '' ) : ''
240+ }
241+ { searchError }
242+ </ div >
243+ }
244+ </ div >
245+ ) ;
246+ } ) ;
0 commit comments