Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improvements to assigning type to redaction search results #1021

Open
wants to merge 1 commit into
base: 8.12
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/components/RedactionSearchPanel/RedactionSearchPanel.js
Original file line number Diff line number Diff line change
@@ -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([]);
Expand All @@ -17,6 +16,8 @@ const RedactionSearchPanel = (props) => {
isProcessingRedactionResults,
clearRedactionSearchResults,
searchStatus,
searchTerms,
setSearchTerms
} = props;

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useState } from 'react';
import RedactionSearchPanel from './RedactionSearchPanel';
import useOnRedactionSearchCompleted from 'hooks/useOnRedactionSearchCompleted';

Expand All @@ -8,6 +8,8 @@ const ReactionSearchPanelContainer = () => {
isProcessingRedactionResults,
clearRedactionSearchResults,
searchStatus,
patternsInUse,
setPatternsInUse
} = useOnRedactionSearchCompleted();

return (
Expand All @@ -16,6 +18,8 @@ const ReactionSearchPanelContainer = () => {
isProcessingRedactionResults={isProcessingRedactionResults}
clearRedactionSearchResults={clearRedactionSearchResults}
searchStatus={searchStatus}
searchTerms={patternsInUse}
setSearchTerms={setPatternsInUse}
/>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(() => {
Expand All @@ -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([]);
Expand Down Expand Up @@ -89,6 +112,8 @@ function useOnRedactionSearchCompleted() {
isProcessingRedactionResults,
clearRedactionSearchResults,
searchStatus,
patternsInUse,
setPatternsInUse
};
}

Expand Down