From 7b4518ea58da76582adcfa89407192a7fb003c06 Mon Sep 17 00:00:00 2001 From: JoinTyang <41655440+JoinTyang@users.noreply.github.com> Date: Wed, 8 Nov 2023 10:26:38 +0800 Subject: [PATCH] combine normal and semantic search (#5743) --- frontend/src/components/search/search.js | 155 +++++++++++------------ 1 file changed, 75 insertions(+), 80 deletions(-) diff --git a/frontend/src/components/search/search.js b/frontend/src/components/search/search.js index bcb4dc66a0..d50e875502 100644 --- a/frontend/src/components/search/search.js +++ b/frontend/src/components/search/search.js @@ -15,11 +15,6 @@ const INDEX_STATE = { FINISHED: 'finished' }; -const SEARCH_MODE = { - SIMILARITY: 'similarity', - NORMAL: 'normal', -}; - const propTypes = { repoID: PropTypes.string, placeholder: PropTypes.string, @@ -51,8 +46,7 @@ class Search extends Component { isCloseShow: false, isSearchInputShow: false, // for mobile searchPageUrl: this.baseSearchPageURL, - searchMode: SEARCH_MODE.NORMAL, - indexState: INDEX_STATE.UNCREATED, + indexState: '', }; this.inputValue = ''; this.highlightRef = null; @@ -66,6 +60,22 @@ class Search extends Component { componentDidMount() { document.addEventListener('keydown', this.onDocumentKeydown); + if (enableSeafileAI && this.props.isLibView) { + this.queryLibraryIndexState(); + } + } + + queryLibraryIndexState() { + seafileAPI.queryLibraryIndexState(this.props.repoID).then(res => { + const { state: indexState, task_id: taskId } = res.data; + this.setState({ indexState }, () => { + if (indexState === INDEX_STATE.RUNNING) { + this.queryIndexTaskStatus(taskId); + } + }); + }).catch(error => { + this.setState({ indexState: INDEX_STATE.UNCREATED }); + }); } componentWillUnmount() { @@ -96,21 +106,7 @@ class Search extends Component { }; onFocusHandler = () => { - const { searchMode, indexState: currentIndexState } = this.state; - const { repoID } = this.props; - this.setState({ width: '570px', isMaskShow: true, isCloseShow: true }, () => { - if (searchMode !== SEARCH_MODE.SIMILARITY) return; - if (currentIndexState === INDEX_STATE.FINISHED) return; - seafileAPI.queryLibraryIndexState(repoID).then(res => { - const { state: indexState, task_id: taskId } = res.data; - this.setState({ indexState }, () => { - if (indexState !== INDEX_STATE.RUNNING) return; - this.queryIndexTaskStatus(taskId); - }); - }).catch(error => { - this.setState({ indexState: INDEX_STATE.UNCREATED }); - }); - }); + this.setState({ width: '570px', isMaskShow: true, isCloseShow: true }); }; onCloseHandler = () => { @@ -167,18 +163,17 @@ class Search extends Component { }; onChangeHandler = (event) => { - const { searchMode } = this.state; const newValue = event.target.value; this.setState({ value: newValue }, () => { if (this.inputValue === newValue.trim()) return; this.inputValue = newValue.trim(); - this.onSearch(searchMode === SEARCH_MODE.NORMAL); + this.onSearch(!this.props.isLibView || !enableSeafileAI); }); }; onKeydownHandler = (event) => { if (isHotkey('enter', event)) { - if (this.state.searchMode === SEARCH_MODE.NORMAL) return; + if (!enableSeafileAI || !this.props.isLibView) return; this.onSearch(true); } }; @@ -255,10 +250,10 @@ class Search extends Component { this.updateSearchPageURL(queryData); queryData['per_page'] = PER_PAGE; queryData['page'] = page; - if (this.state.searchMode === SEARCH_MODE.NORMAL) { + if (!enableSeafileAI || !this.props.isLibView) { this.onNormalSearch(queryData, cancelToken, page); } else { - this.onSimilaritySearch(queryData, cancelToken, page); + this.onCombinedSearch(queryData, cancelToken, page); } } }; @@ -326,6 +321,51 @@ class Search extends Component { }); }; + onCombinedSearch = (queryData, cancelToken, page) => { + const { indexState } = this.state; + 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; + } + + let results = [] + seafileAPI.searchFiles(queryData, cancelToken).then(res => { + if (res.data.total > 0) { + results = [...results, ...this.formatResultItems(res.data.results)] + } + seafileAPI.similaritySearchFiles(queryData, cancelToken).then(res => { + this.source = null; + if (res.data && res.data.children_list) { + results = [...results, ...this.formatSimilarityItems(res.data.children_list)] + } + + let tempPathObj = {} + let searchResults = [] + results.forEach(item => { + if (!tempPathObj[item.path]) { + tempPathObj[item.path] = true + searchResults.push(item) + } + }) + this.setState({ + resultItems: searchResults, + isResultGetted: true, + isLoading: false, + page: page + 1, + hasMore: false, + }); + }) + }).catch(error => { + /* eslint-disable */ + console.log(error); + this.setState({ isLoading: false }); + }); + }; + onResultListScroll = (e) => { // Load less than 100 results if (!this.state.hasMore || this.state.isLoading || this.state.resultItems.length > 100) { @@ -416,9 +456,9 @@ class Search extends Component { } renderSearchResult() { - const { resultItems, highlightIndex, indexState, searchMode, width } = this.state; - if (!width) return null; - if (searchMode === SEARCH_MODE.SIMILARITY && indexState === INDEX_STATE.UNCREATED) { + const { resultItems, highlightIndex, indexState, width } = this.state; + if (!width || width === 'default') return null; + if (enableSeafileAI && indexState === INDEX_STATE.UNCREATED) { return (