-
Notifications
You must be signed in to change notification settings - Fork 374
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(tag): support search tags (#7450)
- Loading branch information
1 parent
89382b4
commit 4c15caf
Showing
12 changed files
with
530 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
import React, { useMemo, useState } from 'react'; | ||
import { gettext } from '../../../utils/constants'; | ||
import { KeyCodes } from '../../../constants'; | ||
import { isModG, isModShiftG } from '../../../metadata/utils/hotkey'; | ||
import SFTableSearcherInput from './searcher-input'; | ||
import { checkHasSearchResult } from '../utils/search'; | ||
|
||
const SFTableSearcher = ({ recordsCount, columnsCount, searchResult, searchCells, closeSearcher, focusNextMatchedCell, focusPreviousMatchedCell }) => { | ||
const [isSearchActive, setIsSearchActive] = useState(false); | ||
const [hasSearchValue, setHasSearchValue] = useState(false); | ||
|
||
const hasSearchResult = useMemo(() => { | ||
return checkHasSearchResult(searchResult); | ||
}, [searchResult]); | ||
|
||
const onToggleSearch = () => { | ||
setIsSearchActive(!isSearchActive); | ||
}; | ||
|
||
const handleCloseSearcher = () => { | ||
setIsSearchActive(false); | ||
closeSearcher && closeSearcher(); | ||
}; | ||
|
||
const onKeyDown = (e) => { | ||
const isEmptySearchResult = !hasSearchResult; | ||
if (e.keyCode === KeyCodes.Escape) { | ||
e.preventDefault(); | ||
handleCloseSearcher(); | ||
} else if (isModG(e)) { | ||
e.preventDefault(); | ||
if (isEmptySearchResult) return; | ||
focusNextMatchedCell && focusNextMatchedCell(); | ||
} else if (isModShiftG(e)) { | ||
e.preventDefault(); | ||
if (isEmptySearchResult) return; | ||
focusPreviousMatchedCell && focusPreviousMatchedCell(); | ||
} | ||
}; | ||
|
||
const renderSearchPollButton = () => { | ||
return ( | ||
<span className="input-icon-addon search-poll-button"> | ||
{hasSearchValue && | ||
<span className="search-description"> | ||
{hasSearchResult ? | ||
(searchResult.currentSelectIndex + 1 + ' of ' + searchResult.matchedCells.length) : '0 of 0' | ||
} | ||
</span> | ||
} | ||
{hasSearchResult && | ||
<> | ||
<i className="sf3-font sf3-font-down rotate-180 search-upward" | ||
onClick={focusPreviousMatchedCell ? focusPreviousMatchedCell : () => {}}> | ||
</i> | ||
<i className="sf3-font sf3-font-down search-backward" | ||
onClick={focusNextMatchedCell ? focusNextMatchedCell : () => {}}> | ||
</i> | ||
</> | ||
} | ||
</span> | ||
); | ||
}; | ||
|
||
return ( | ||
<div className="sf-table-searcher-container"> | ||
{!isSearchActive && ( | ||
<span | ||
className='sf-table-searcher-btn' | ||
onClick={onToggleSearch} | ||
onKeyDown={onToggleSearch} | ||
role="button" | ||
title={gettext('Search')} | ||
aria-label={gettext('Search')} | ||
tabIndex={0} | ||
> | ||
<i className='active-search m-0 sf3-font sf3-font-search'></i> | ||
</span> | ||
)} | ||
{isSearchActive && ( | ||
<div className='sf-table-searcher-input-wrapper'> | ||
<i className='input-icon-addon sf3-font sf3-font-search' /> | ||
<SFTableSearcherInput | ||
recordsCount={recordsCount} | ||
columnsCount={columnsCount} | ||
onKeyDown={onKeyDown} | ||
setHasSearchValue={setHasSearchValue} | ||
searchCells={searchCells} | ||
/> | ||
{renderSearchPollButton()} | ||
<span className="btn-close-searcher-wrapper input-icon-addon" onClick={handleCloseSearcher}> | ||
<i className='btn-close-searcher sf3-font sf3-font-x-01'></i> | ||
</span> | ||
</div> | ||
)} | ||
</div> | ||
); | ||
}; | ||
|
||
export default SFTableSearcher; |
59 changes: 59 additions & 0 deletions
59
frontend/src/components/sf-table/searcher/searcher-input.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import React, { useRef, useState } from 'react'; | ||
import { gettext } from '../../../utils/constants'; | ||
|
||
const SFTableSearcherInput = ({ recordsCount, columnsCount, setHasSearchValue, searchCells, onKeyDown }) => { | ||
const [searchValue, setSearchValue] = useState(''); | ||
|
||
const isInputtingChinese = useRef(false); | ||
const inputTimer = useRef(null); | ||
|
||
const getSearchDelayTime = () => { | ||
const viewCellsCount = (recordsCount || 0) * (columnsCount || 0); | ||
let delayTime = viewCellsCount * 0.1; | ||
delayTime = delayTime > 500 ? 500 : Math.floor(delayTime); | ||
if (delayTime < 100) { | ||
delayTime = 100; | ||
} | ||
return delayTime; | ||
}; | ||
|
||
const onChangeSearchValue = (e) => { | ||
inputTimer.current && clearTimeout(inputTimer.current); | ||
const text = e.target.value; | ||
const wait = getSearchDelayTime(); | ||
const currSearchValue = text || ''; | ||
const trimmedSearchValue = currSearchValue.trim(); | ||
setSearchValue(currSearchValue); | ||
setHasSearchValue(!!trimmedSearchValue); | ||
if (!isInputtingChinese.current) { | ||
inputTimer.current = setTimeout(() => { | ||
searchCells && searchCells(trimmedSearchValue); | ||
}, wait); | ||
} | ||
}; | ||
|
||
const onCompositionStart = () => { | ||
isInputtingChinese.current = true; | ||
}; | ||
|
||
const onCompositionEnd = (e) => { | ||
isInputtingChinese.current = false; | ||
onChangeSearchValue(e); | ||
}; | ||
|
||
return ( | ||
<input | ||
className='sf-table-searcher-input form-control' | ||
type='text' | ||
autoFocus | ||
value={searchValue} | ||
onChange={onChangeSearchValue} | ||
placeholder={gettext('Search')} | ||
onKeyDown={onKeyDown} | ||
onCompositionStart={onCompositionStart} | ||
onCompositionEnd={onCompositionEnd} | ||
/> | ||
); | ||
}; | ||
|
||
export default SFTableSearcherInput; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.