From e77201af000f6ed55668957626b92f8394aa8404 Mon Sep 17 00:00:00 2001 From: Kenedy Anderson Date: Sun, 11 Jun 2023 20:07:19 -0700 Subject: [PATCH] improving selecting type for search results --- .../RedactionSearchPanel.js | 5 +- .../RedactionSearchPanelContainer.js | 6 ++- .../useOnRedactionSearchCompleted.js | 49 ++++++++++++++----- 3 files changed, 45 insertions(+), 15 deletions(-) diff --git a/src/components/RedactionSearchPanel/RedactionSearchPanel.js b/src/components/RedactionSearchPanel/RedactionSearchPanel.js index 1e0939014..e7e67bc8b 100644 --- a/src/components/RedactionSearchPanel/RedactionSearchPanel.js +++ b/src/components/RedactionSearchPanel/RedactionSearchPanel.js @@ -1,10 +1,9 @@ -import React, { useContext, useState } from 'react'; +import React, { useContext } from 'react'; import RedactionSearchOverlay from 'src/components/RedactionSearchOverlay'; import { RedactionPanelContext } from 'components/RedactionPanel/RedactionPanelContext'; import RedactionSearchResults from 'components/RedactionSearchResults'; const RedactionSearchPanel = (props) => { - const [searchTerms, setSearchTerms] = useState([]); const { isRedactionSearchActive, setIsRedactionSearchActive } = useContext(RedactionPanelContext); const onCancelSearch = () => { setSearchTerms([]); @@ -17,6 +16,8 @@ const RedactionSearchPanel = (props) => { isProcessingRedactionResults, clearRedactionSearchResults, searchStatus, + searchTerms, + setSearchTerms } = props; return ( diff --git a/src/components/RedactionSearchPanel/RedactionSearchPanelContainer.js b/src/components/RedactionSearchPanel/RedactionSearchPanelContainer.js index c913e155f..b383b3005 100644 --- a/src/components/RedactionSearchPanel/RedactionSearchPanelContainer.js +++ b/src/components/RedactionSearchPanel/RedactionSearchPanelContainer.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState } from 'react'; import RedactionSearchPanel from './RedactionSearchPanel'; import useOnRedactionSearchCompleted from 'hooks/useOnRedactionSearchCompleted'; @@ -8,6 +8,8 @@ const ReactionSearchPanelContainer = () => { isProcessingRedactionResults, clearRedactionSearchResults, searchStatus, + patternsInUse, + setPatternsInUse } = useOnRedactionSearchCompleted(); return ( @@ -16,6 +18,8 @@ const ReactionSearchPanelContainer = () => { isProcessingRedactionResults={isProcessingRedactionResults} clearRedactionSearchResults={clearRedactionSearchResults} searchStatus={searchStatus} + searchTerms={patternsInUse} + setSearchTerms={setPatternsInUse} /> ); }; diff --git a/src/hooks/useOnRedactionSearchCompleted/useOnRedactionSearchCompleted.js b/src/hooks/useOnRedactionSearchCompleted/useOnRedactionSearchCompleted.js index 0592978c2..751ee7ac7 100644 --- a/src/hooks/useOnRedactionSearchCompleted/useOnRedactionSearchCompleted.js +++ b/src/hooks/useOnRedactionSearchCompleted/useOnRedactionSearchCompleted.js @@ -5,10 +5,27 @@ import core from 'core'; import { redactionTypeMap } from 'constants/redactionTypes'; import SearchStatus from 'constants/searchStatus'; +//This runs the pattern against the ambient string of the search result (containing the match with surrounding words). +//That's so that the pattern can properly use lookbehinds or lookaheads. However, it does require the actual match to +//be in the resultStr, to make sure we're not matching something before or after the result. +function patternMatchesResult(searchResult, pattern) { + //First check if the pattern matches the result string, if so we don't need to test further. + if (pattern.test(searchResult.resultStr)) { + return true; + } + const result = pattern.exec(searchResult.ambientStr); + if (result !== null && result.index >= searchResult.resultStrStart && result.index <= searchResult.resultStrEnd) { + return true + } + return false +} + + function useOnRedactionSearchCompleted() { const [searchStatus, setSearchStatus] = useState(SearchStatus['SEARCH_NOT_INITIATED']); const [redactionSearchResults, setRedactionSearchResults] = useState([]); const [isProcessingRedactionResults, setIsProcessingRedactionResults] = useState(false); + const [patternsInUse, setPatternsInUse] = useState([]); const redactionSearchPatterns = useSelector((state) => selectors.getRedactionSearchPatterns(state), shallowEqual); const searchPatterns = useMemo(() => { @@ -23,22 +40,28 @@ function useOnRedactionSearchCompleted() { }, [redactionSearchPatterns]); const mapResultToType = useCallback((result) => { - // Iterate through the patterns and return the first match - const { resultStr } = result; - const searchPatternKeys = Object.keys(searchPatterns); - - const resultType = searchPatternKeys.find((key) => { - const { regex } = searchPatterns[key]; - return regex.test(resultStr); - }); - - // If it didn't match any of the patterns, return the default type which is text - result.type = resultType === undefined ? redactionTypeMap['TEXT'] : resultType; + if (patternsInUse.length === 1) { + result.type = patternsInUse[0].type + } else { + // Iterate through the patterns and return the first match + let resultType = undefined + for (let pattern of patternsInUse) { + if (pattern.type === 'text') { + continue; + } + if (patternMatchesResult(result, pattern.regex)) { + resultType = pattern.type + break; + } + } + // If it didn't match any of the patterns, return the default type which is text + result.type = resultType === undefined ? redactionTypeMap['TEXT'] : resultType; + } // And also set the icon to display in the panel. If no icon provided use the text icon const { icon = 'icon-form-field-text' } = searchPatterns[result.type] || {}; result.icon = icon; return result; - }, [searchPatterns]);// Dependency is an object but it is memoized so it will not re-create unless the patterns change + }, [searchPatterns, patternsInUse]); const clearRedactionSearchResults = useCallback(() => { setRedactionSearchResults([]); @@ -89,6 +112,8 @@ function useOnRedactionSearchCompleted() { isProcessingRedactionResults, clearRedactionSearchResults, searchStatus, + patternsInUse, + setPatternsInUse }; }