From 8bd6aabb4a8fad5138f9cdeedc961f68e4fbbe09 Mon Sep 17 00:00:00 2001 From: Michael An <2331806369@qq.com> Date: Fri, 7 Jun 2024 14:27:36 +0800 Subject: [PATCH] change search UI delete useless ai-search-ask change search and ai-search --- .../src/components/search/ai-search-ask.css | 98 ------ .../src/components/search/ai-search-ask.js | 217 ------------ .../ai-search-widgets/ai-search-help.css | 25 -- .../ai-search-widgets/ai-search-help.js | 23 -- .../ai-search-widgets/ai-search-refrences.css | 25 -- .../ai-search-widgets/ai-search-refrences.js | 33 -- .../ai-search-widgets/ai-search-robot.js | 17 - frontend/src/components/search/ai-search.js | 331 ++++++++++-------- frontend/src/components/search/constant.js | 4 +- frontend/src/components/search/search.js | 36 +- .../src/components/toolbar/common-toolbar.js | 52 +-- .../lib-content-view/lib-content-toolbar.js | 2 + media/img/ask-ai.png | Bin 1857 -> 0 bytes 13 files changed, 242 insertions(+), 621 deletions(-) delete mode 100644 frontend/src/components/search/ai-search-ask.css delete mode 100644 frontend/src/components/search/ai-search-ask.js delete mode 100644 frontend/src/components/search/ai-search-widgets/ai-search-help.css delete mode 100644 frontend/src/components/search/ai-search-widgets/ai-search-help.js delete mode 100644 frontend/src/components/search/ai-search-widgets/ai-search-refrences.css delete mode 100644 frontend/src/components/search/ai-search-widgets/ai-search-refrences.js delete mode 100644 frontend/src/components/search/ai-search-widgets/ai-search-robot.js delete mode 100644 media/img/ask-ai.png diff --git a/frontend/src/components/search/ai-search-ask.css b/frontend/src/components/search/ai-search-ask.css deleted file mode 100644 index 31e06d6fb08..00000000000 --- a/frontend/src/components/search/ai-search-ask.css +++ /dev/null @@ -1,98 +0,0 @@ -.search-container.show.ai-search-ask { - width: 800px; -} - -.ai-search-ask .ai-search-ask-header { - display: flex; - align-items: center; - padding: 1rem; - border-bottom: 1px solid rgba(0, 40, 100, 0.12); -} - -.ai-search-ask .ai-search-ask-header .ai-search-ask-return { - padding: 0 4px; - transform: rotate(180deg); - line-height: 10px; - cursor: pointer; -} - -.ai-search-ask .ai-search-ask-header .ai-search-ask-return .seafile-multicolor-icon-arrow { - opacity: 0.6; -} - -.ai-search-ask .ai-search-ask-header .ai-search-ask-return:hover .seafile-multicolor-icon-arrow { - opacity: 0.8; -} - -.ai-search-ask .ai-search-ask-body { - display: flex; - max-height: 400px; - overflow-y: auto; -} - -.ai-search-ask .ai-search-ask-body .ai-search-ask-body-left { - flex-shrink: 0; - margin-right: 1rem; -} - -.ai-search-ask .ai-search-ask-body .ai-search-ask-body-right { - line-height: 1.8; - font-size: 14px; - width: 100%; -} - -.ai-search-ask .ai-search-ask-body .ai-search-ask-body-markdown .sf-slate-viewer-scroll-container { - padding: 0; - background: none; -} - -.ai-search-ask .ai-search-ask-body .ai-search-ask-body-markdown .sf-slate-viewer-article-container { - margin: 0; -} - -.ai-search-ask .ai-search-ask-body .ai-search-ask-body-markdown .article { - padding: 0; - border: none; -} - -.ai-search-ask .ai-search-ask-body .ai-search-ask-body-markdown .article p { - margin-top: 0; - margin-bottom: 1rem; -} - -.ai-search-ask .ai-search-ask-footer { - border-top: 1px solid rgba(0, 40, 100, 0.12); - margin: 0 1rem; - padding: 1rem 0; -} - -.ai-search-ask .ai-search-ask-footer .ai-search-ask-footer-btn { - width: 16px; - height: 16px; - position: absolute; - right: 8px; - top: 8px; - background-color: #fff; - cursor: pointer; -} - -.ai-search-ask .ai-search-ask-footer .ai-search-ask-footer-btn .seafile-multicolor-icon-send { - color: #ff8000; -} - -.ai-search-ask .ai-search-ask-footer .ai-search-ask-footer-btn:hover .seafile-multicolor-icon-send { - color: #d96d00; -} - -@media (max-width: 768px) { - - .search-container.show.ai-search-ask { - width: 100%; - } - - .ai-search-ask .search-input { - box-shadow: none; - width: 100% !important; - } - -} diff --git a/frontend/src/components/search/ai-search-ask.js b/frontend/src/components/search/ai-search-ask.js deleted file mode 100644 index e7d4c9a472f..00000000000 --- a/frontend/src/components/search/ai-search-ask.js +++ /dev/null @@ -1,217 +0,0 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import isHotkey from 'is-hotkey'; -import { MarkdownViewer } from '@seafile/seafile-editor'; -import { seafileAPI } from '../../utils/seafile-api'; -import { gettext } from '../../utils/constants'; -import toaster from '../toast'; -import Loading from '../loading'; -import Icon from '../icon'; -import { Utils } from '../../utils/utils'; -import { SEARCH_DELAY_TIME, getValueLength } from './constant'; -import AISearchRefrences from './ai-search-widgets/ai-search-refrences'; -//import AISearchHelp from './ai-search-widgets/ai-search-help'; -import AISearchRobot from './ai-search-widgets/ai-search-robot'; - -import './ai-search-ask.css'; - -const INDEX_STATE = { - RUNNING: 'running', - UNCREATED: 'uncreated', - FINISHED: 'finished' -}; - -export default class AISearchAsk extends Component { - - static propTypes = { - value: PropTypes.string, - token: PropTypes.string, - repoID: PropTypes.string, - repoName: PropTypes.string, - indexState: PropTypes.string, - onItemClickHandler: PropTypes.func.isRequired, - }; - - constructor(props) { - super(props); - this.state = { - value: props.value, - isLoading: false, - answeringResult: '', - hitFiles: [], - }; - this.timer = null; - this.isChineseInput = false; - } - - componentDidMount() { - document.addEventListener('compositionstart', this.onCompositionStart); - document.addEventListener('compositionend', this.onCompositionEnd); - this.onSearch(); - } - - componentWillUnmount() { - document.removeEventListener('compositionstart', this.onCompositionStart); - document.removeEventListener('compositionend', this.onCompositionEnd); - this.isChineseInput = false; - if (this.timer) { - clearTimeout(this.timer); - this.timer = null; - } - } - - onCompositionStart = () => { - this.isChineseInput = true; - if (this.timer) { - clearTimeout(this.timer); - this.timer = null; - } - }; - - onCompositionEnd = () => { - this.isChineseInput = false; - if (this.timer) { - clearTimeout(this.timer); - this.timer = null; - } - this.timer = setTimeout(() => { - this.onSearch(); - }, SEARCH_DELAY_TIME); - }; - - onChange = (event) => { - const newValue = event.target.value; - this.setState({ value: newValue }, () => { - if (!this.isChineseInput) { - if (this.timer) { - clearTimeout(this.timer); - this.timer = null; - } - this.timer = setTimeout(() => { - this.onSearch(); - }, SEARCH_DELAY_TIME); - } - }); - }; - - onKeydown = (event) => { - if (isHotkey('enter', event)) { - this.onSearch(); - } - }; - - formatQuestionAnsweringItems(data) { - if (!Array.isArray(data)) return []; - let items = []; - for (let i = 0; i < data.length; i++) { - items[i] = {}; - items[i]['index'] = [i]; - items[i]['name'] = data[i].substring(data[i].lastIndexOf('/') + 1); - items[i]['path'] = data[i]; - items[i]['repo_id'] = this.props.repoID; - items[i]['is_dir'] = false; - items[i]['link_content'] = decodeURI(data[i]).substring(1); - items[i]['content'] = data[i].sentence; - items[i]['thumbnail_url'] = ''; - } - return items; - } - - onSearch = () => { - const { indexState, repoID, token } = this.props; - if (indexState === INDEX_STATE.UNCREATED) { - toaster.warning(gettext('Please create index first.')); - return; - } - if (indexState === INDEX_STATE.RUNNING) { - toaster.warning(gettext('Indexing, please try again later.')); - return; - } - if (this.state.isLoading || getValueLength(this.state.value.trim()) < 3) { - return; - } - this.setState({ isLoading: true }); - const searchParams = { - q: this.state.value.trim(), - search_repo: repoID || 'all', - }; - seafileAPI.questionAnsweringFiles(searchParams, token).then(res => { - let { answering_result, hit_files } = res.data || {}; - this.setState({ - isLoading: false, - answeringResult: answering_result === 'false' ? '' : answering_result.trim(), - hitFiles: this.formatQuestionAnsweringItems(hit_files), - }); - }).catch(error => { - /* eslint-disable */ - console.log(error); - this.setState({ isLoading: false }); - let errMessage = Utils.getErrorMsg(error); - toaster.danger(errMessage); - }); - }; - - render() { - const { isLoading, answeringResult, hitFiles } = this.state; - return ( -
-
-
- -
- - - - {gettext('Return')} -
- - {isLoading ? -
- -
- : -
-
- -
-
- {answeringResult.length > 0 ? -
- -
- : -

{gettext('No result')}

- } - {/**/} - {hitFiles.length > 0 && - - } -
-
- } - -
-
- - - - -
-
-
-
- ) - } -} diff --git a/frontend/src/components/search/ai-search-widgets/ai-search-help.css b/frontend/src/components/search/ai-search-widgets/ai-search-help.css deleted file mode 100644 index a33efbc4590..00000000000 --- a/frontend/src/components/search/ai-search-widgets/ai-search-help.css +++ /dev/null @@ -1,25 +0,0 @@ -.ai-search-help { - padding: 20px 0 20px 0; - border-bottom: 1px solid rgba(0, 40, 100, 0.12); -} - -.ai-search-help .ai-search-help-title { - margin-bottom: 10px; -} - -.ai-search-help .ai-search-help-container { - display: flex; -} - -.ai-search-help .ai-search-help-container .ai-search-help-detail { - border: 1px solid #ccc; - max-width: 200px; - margin-right: 8px; - padding: 4px 8px; - border-radius: 3px; -} - -.ai-search-help .ai-search-help-detail:hover { - cursor: pointer; - background-color: rgb(245, 245, 245); -} diff --git a/frontend/src/components/search/ai-search-widgets/ai-search-help.js b/frontend/src/components/search/ai-search-widgets/ai-search-help.js deleted file mode 100644 index c5da3cb07ce..00000000000 --- a/frontend/src/components/search/ai-search-widgets/ai-search-help.js +++ /dev/null @@ -1,23 +0,0 @@ -import React from 'react'; -import Icon from '../../icon'; -import { gettext } from '../../../utils/constants'; - -import './ai-search-help.css'; - -export default function AISearchHelp() { - return ( -
-
{gettext('Is this answer helpful to you?')}
-
-
- - {gettext('Yes')} -
-
- - {gettext('No')} -
-
-
- ); -} diff --git a/frontend/src/components/search/ai-search-widgets/ai-search-refrences.css b/frontend/src/components/search/ai-search-widgets/ai-search-refrences.css deleted file mode 100644 index 79a8938128e..00000000000 --- a/frontend/src/components/search/ai-search-widgets/ai-search-refrences.css +++ /dev/null @@ -1,25 +0,0 @@ -.ai-search-refrences { - padding-top: 10px; - border-top: 1px solid rgba(0,40,100,.12); -} - -.ai-search-refrences .ai-search-refrences-title { - margin-bottom: 6px; -} - -.ai-search-refrences .ai-search-refrences-container { - display: flex; -} - -.ai-search-refrences .ai-search-refrences-container .ai-search-refrences-detail { - border: 1px solid #ccc; - max-width: 200px; - margin-right: 8px; - padding: 4px 8px; - border-radius: 3px; -} - -.ai-search-refrences .ai-search-refrences-detail:hover { - cursor: pointer; - background-color: rgb(245, 245, 245); -} diff --git a/frontend/src/components/search/ai-search-widgets/ai-search-refrences.js b/frontend/src/components/search/ai-search-widgets/ai-search-refrences.js deleted file mode 100644 index 69108dfc63a..00000000000 --- a/frontend/src/components/search/ai-search-widgets/ai-search-refrences.js +++ /dev/null @@ -1,33 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { gettext } from '../../../utils/constants'; - -import './ai-search-refrences.css'; - -function AISearchRefrences({hitFiles, onItemClickHandler}) { - return ( -
-
{gettext('Reference documents')}{':'}
-
- {hitFiles.map((hitFile, index) => { - return ( -
onItemClickHandler(hitFile)} - key={index} - > - {`${index + 1}. ${hitFile.name}`} -
- ); - })} -
-
- ); -} - -AISearchRefrences.propTypes = { - hitFiles: PropTypes.array.isRequired, - onItemClickHandler: PropTypes.func.isRequired, -}; - -export default AISearchRefrences; diff --git a/frontend/src/components/search/ai-search-widgets/ai-search-robot.js b/frontend/src/components/search/ai-search-widgets/ai-search-robot.js deleted file mode 100644 index 897eeb92c08..00000000000 --- a/frontend/src/components/search/ai-search-widgets/ai-search-robot.js +++ /dev/null @@ -1,17 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { mediaUrl } from '../../../utils/constants'; - -function AISearchRobot({style}) { - return ( -
- -
- ); -} - -AISearchRobot.propTypes = { - style: PropTypes.object, -}; - -export default AISearchRobot; diff --git a/frontend/src/components/search/ai-search.js b/frontend/src/components/search/ai-search.js index c4647a4f8ab..88e122cde24 100644 --- a/frontend/src/components/search/ai-search.js +++ b/frontend/src/components/search/ai-search.js @@ -1,7 +1,6 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import isHotkey from 'is-hotkey'; -import classnames from 'classnames'; import MediaQuery from 'react-responsive'; import { seafileAPI } from '../../utils/seafile-api'; import Icon from '../icon'; @@ -10,10 +9,8 @@ import SearchResultItem from './search-result-item'; import { Utils } from '../../utils/utils'; import { isMac } from '../../utils/extra-attributes'; import toaster from '../toast'; +import Loading from '../loading'; import Switch from '../common/switch'; -import { SEARCH_DELAY_TIME, getValueLength } from './constant'; -import AISearchAsk from './ai-search-ask'; -import AISearchRobot from './ai-search-widgets/ai-search-robot'; const INDEX_STATE = { RUNNING: 'running', @@ -21,11 +18,6 @@ const INDEX_STATE = { FINISHED: 'finished' }; -const SEARCH_MODE = { - QA: 'question-answering', - COMBINED: 'combined-search', -}; - const PER_PAGE = 10; const controlKey = isMac() ? '⌘' : 'Ctrl'; @@ -33,10 +25,13 @@ export default class AISearch extends Component { static propTypes = { repoID: PropTypes.string, + path: PropTypes.string, placeholder: PropTypes.string, onSearchedClick: PropTypes.func.isRequired, repoName: PropTypes.string, currentRepoInfo: PropTypes.object, + isViewFile: PropTypes.bool, + isLibView: PropTypes.bool, }; constructor(props) { @@ -45,6 +40,7 @@ export default class AISearch extends Component { this.state = { width: 'default', value: '', + inputValue: '', resultItems: [], highlightIndex: 0, page: 0, @@ -58,19 +54,23 @@ export default class AISearch extends Component { isSearchInputShow: false, // for mobile searchPageUrl: this.baseSearchPageURL, indexState: '', - searchMode: SEARCH_MODE.COMBINED, + searchTypesMax: 0, + highlightSearchTypesIndex: 0, }; - this.inputValue = ''; this.highlightRef = null; this.source = null; // used to cancel request; this.inputRef = React.createRef(); this.searchContainer = React.createRef(); this.searchResultListRef = React.createRef(); this.indexStateTimer = null; - this.timer = null; this.isChineseInput = false; - this.isRepoOwner = props.currentRepoInfo.owner_email === username; - this.isAdmin = props.currentRepoInfo.is_admin; + if (props.isLibView && props.currentRepoInfo) { + this.isRepoOwner = props.currentRepoInfo.owner_email === username; + this.isAdmin = props.currentRepoInfo.is_admin; + } else { + this.isRepoOwner = false; + this.isAdmin = false; + } } componentDidMount() { @@ -100,34 +100,18 @@ export default class AISearch extends Component { document.removeEventListener('compositionend', this.onCompositionEnd); document.removeEventListener('click', this.handleOutsideClick); this.isChineseInput = false; - this.clearTimer(); if (this.indexStateTimer) { clearInterval(this.indexStateTimer); this.indexStateTimer = null; } } - clearTimer = () => { - if (this.timer) { - clearTimeout(this.timer); - this.timer = null; - } - }; - onCompositionStart = () => { this.isChineseInput = true; - this.clearTimer(); }; onCompositionEnd = () => { this.isChineseInput = false; - // chrome:compositionstart -> onChange -> compositionend - // not chrome:compositionstart -> compositionend -> onChange - // The onChange event will setState and change input value, then setTimeout to initiate the search - this.clearTimer(); - this.timer = setTimeout(() => { - this.onSearch(); - }, SEARCH_DELAY_TIME); }; onDocumentKeydown = (e) => { @@ -152,6 +136,7 @@ export default class AISearch extends Component { onFocusHandler = () => { this.setState({ width: '570px', isMaskShow: true, isCloseShow: true }); + this.calculateHighlightType(); }; onCloseHandler = () => { @@ -161,6 +146,14 @@ export default class AISearch extends Component { onUp = (e) => { e.preventDefault(); e.stopPropagation(); + if (!this.state.isResultGetted) { + let highlightSearchTypesIndex = this.state.highlightSearchTypesIndex - 1; + if (highlightSearchTypesIndex < 0) { + highlightSearchTypesIndex = this.state.searchTypesMax; + } + this.setState({ highlightSearchTypesIndex }); + return; + } const { highlightIndex } = this.state; if (highlightIndex > 0) { this.setState({ highlightIndex: highlightIndex - 1 }, () => { @@ -177,6 +170,14 @@ export default class AISearch extends Component { onDown = (e) => { e.preventDefault(); e.stopPropagation(); + if (!this.state.isResultGetted) { + let highlightSearchTypesIndex = this.state.highlightSearchTypesIndex + 1; + if (highlightSearchTypesIndex > this.state.searchTypesMax) { + highlightSearchTypesIndex = 0; + } + this.setState({ highlightSearchTypesIndex }); + return; + } const { highlightIndex, resultItems } = this.state; if (highlightIndex < resultItems.length - 1) { this.setState({ highlightIndex: highlightIndex + 1 }, () => { @@ -193,6 +194,21 @@ export default class AISearch extends Component { onEnter = (e) => { e.preventDefault(); + if (!this.state.isResultGetted) { + let highlightDom = document.querySelector('.search-types-highlight'); + if (highlightDom) { + if (highlightDom.classList.contains('search-types-folder')) { + this.searchFolder(); + } + else if (highlightDom.classList.contains('search-types-repo')) { + this.searchRepo(); + } + else if (highlightDom.classList.contains('search-types-repos')) { + this.searchAllRepos(); + } + return; + } + } let item = this.state.resultItems[this.state.highlightIndex]; if (item) { if (document.activeElement) { @@ -208,6 +224,21 @@ export default class AISearch extends Component { this.props.onSearchedClick(item); }; + calculateHighlightType = () => { + let searchTypesMax = 0; + const { repoID, path, isViewFile } = this.props; + if (repoID) { + searchTypesMax++; + } + if (path && path !== '/' && !isViewFile) { + searchTypesMax++; + } + this.setState({ + searchTypesMax, + highlightSearchTypesIndex: 0, + }); + }; + keepVisitedItem = (targetItem) => { const { repoID } = this.props; let targetIndex; @@ -235,45 +266,22 @@ export default class AISearch extends Component { }; onChangeHandler = (event) => { + const newValue = event.target.value; if (this.state.showRecent) { this.setState({ showRecent: false }); } - const newValue = event.target.value; - this.setState({ value: newValue }, () => { - if (this.inputValue === newValue.trim()) return; - this.inputValue = newValue.trim(); - if (!this.isChineseInput) { - this.clearTimer(); - this.timer = setTimeout(() => { - this.onSearch(); - }, SEARCH_DELAY_TIME); + this.setState({ value: newValue }); + setTimeout(() => { + if (this.isChineseInput === false && this.state.inputValue !== newValue) { + this.setState({ + inputValue: newValue, + isLoading: false, + highlightIndex: 0, + resultItems: [], + isResultGetted: false, + }); } - }); - }; - - onKeydownHandler = (event) => { - if (isHotkey('enter', event)) { - this.onSearch(); - } - }; - - onSearch = () => { - const { value } = this.state; - const { repoID } = this.props; - if (this.inputValue === '' || getValueLength(this.inputValue) < 3) { - this.setState({ - highlightIndex: 0, - resultItems: [], - isResultGetted: false - }); - return; - } - const queryData = { - q: value, - search_repo: repoID ? repoID : 'all', - search_ftypes: 'all', - }; - this.getSearchResult(queryData); + }, 1); }; getSearchResult = (queryData) => { @@ -281,6 +289,7 @@ export default class AISearch extends Component { this.source.cancel('prev request is cancelled'); } this.setState({ + isLoading: true, isResultGetted: false, resultItems: [], highlightIndex: 0, @@ -355,10 +364,10 @@ export default class AISearch extends Component { } resetToDefault() { - this.inputValue = ''; this.setState({ width: '', value: '', + inputValue: '', isMaskShow: false, isCloseShow: false, isSettingsShown: false, @@ -370,16 +379,6 @@ export default class AISearch extends Component { }); } - openAsk = () => { - this.clearTimer(); - this.setState({ searchMode: SEARCH_MODE.QA }); - } - - closeAsk = () => { - this.clearTimer(); - this.setState({ searchMode: SEARCH_MODE.COMBINED }); - } - renderVisitedItems = (items) => { const { highlightIndex } = this.state; const results = ( @@ -390,11 +389,11 @@ export default class AISearch extends Component { const isHighlight = index === highlightIndex; return ( {this.highlightRef = ref;} : () => {}} + key={index} + item={item} + onItemClickHandler={this.onItemClickHandler} + isHighlight={isHighlight} + setRef={isHighlight ? (ref) => {this.highlightRef = ref;} : () => {}} /> ); })} @@ -412,10 +411,94 @@ export default class AISearch extends Component { ); - } + }; + + renderSearchTypes = (inputValue) => { + const highlightIndex = this.state.highlightSearchTypesIndex; + if (!this.props.repoID) { + return ( +
+
+ + {inputValue} + {gettext('in all libraries')} +
+
+ ); + } + if (this.props.repoID) { + if (this.props.path && this.props.path !== '/' && !this.props.isViewFile) { + return ( +
+
+ + {inputValue} + {gettext('in this library')} +
+
+ + {inputValue} + {gettext('in this folder')} +
+
+ + {inputValue} + {gettext('in all libraries')} +
+
+ ); + } else { + return ( +
+
+ + {inputValue} + {gettext('in this library')} +
+
+ + {inputValue} + {gettext('in all libraries')} +
+
+ ); + } + } + }; + + searchRepo = () => { + const { value } = this.state; + const queryData = { + q: value, + search_repo: this.props.repoID, + search_ftypes: 'all', + }; + this.getSearchResult(queryData); + }; + + searchFolder = () => { + const { value } = this.state; + const queryData = { + q: value, + search_repo: this.props.repoID, + search_ftypes: 'all', + search_path: this.props.path, + }; + this.getSearchResult(queryData); + }; + + searchAllRepos = () => { + const { value } = this.state; + const queryData = { + q: value, + search_repo: 'all', + search_ftypes: 'all', + }; + this.getSearchResult(queryData); + }; renderSearchResult() { - const { resultItems, highlightIndex, width, isResultGetted } = this.state; + const { resultItems, highlightIndex, width, isResultGetted, isLoading } = this.state; if (!width || width === 'default') return null; if (this.state.showRecent) { @@ -430,46 +513,23 @@ export default class AISearch extends Component { } } - const searchStrLength = getValueLength(this.inputValue); - - if (searchStrLength === 0) { - return
{gettext('Type characters to start search')}
; + if (isLoading) { + return ; } - else if (searchStrLength < 3) { - return
{gettext('Type more characters to start search')}
; + else if (this.state.inputValue.trim().length === 0) { + return
{gettext('Type characters to start search')}
; } else if (!isResultGetted) { - return ; + return this.renderSearchTypes(this.state.inputValue.trim()); } - else if (!resultItems.length) { - return ( - <> -
  • - -
    -
    {gettext('Ask AI')}{': '}{this.state.value.trim()}
    -
    -
  • -
    {gettext('No results matching')}
    - - ); + else if (resultItems.length === 0) { + return
    {gettext('No results matching')}
    ; } const results = (