UNPKG

model-navigator-standalone

Version:

Standalone MDF graph model visualizer

165 lines (156 loc) 6.72 kB
import "core-js/modules/es.array.sort.js"; import "core-js/modules/es.regexp.exec.js"; import "core-js/modules/es.string.search.js"; import { createSlice, createSelector } from '@reduxjs/toolkit'; import { compareTwoStrings } from 'string-similarity'; import { getSearchSummary, calcMatchedStrings, storeSearchHistoryItem, retrieveSearchHistoryItems, clearSearchHistoryItems } from '../../components/ModelNavigator/DataDictionary/Search/DictionarySearcher/searchHelper'; // matchedResult - getSearchResultItem const initialState = { acCloseIconHidden: true, searchHistoryItems: retrieveSearchHistoryItems(), currentSearchKeyword: '', searchString: '', lastSearchError: '', searchData: null, searchResult: null, overlayPropertyHidden: true, matchedNodeIDs: [], matchedNodeIDsInNameAndDescription: [], matchedNodeIDsInProperties: [], suggestionList: [], clickedSuggestionItem: null, clickedHistoryItem: null, isSearchMode: false, isSearching: false }; // searchMode is set when SEARCH_RESULT_UPDATED - setSearchResult - mapped to onSearchResultUpdated // searchMode is cleared when SEARCH_RESULT_CLEARED - clearSearchResult - mapped to onSearchResultCleared const searchSlice = createSlice({ name: 'search', initialState, reducers: { changedVisAcCloseIcon(state, action) { const vis = action.payload; state.acCloseIconHidden = vis === 'hide' ? true : false; }, searchDataPrepared(state, action) { const searchData = action.payload; state.searchData = searchData; }, searchResultCleared(state, action) { state.isSearchMode = false; state.searchResult = null; }, searchStarted(state, action) { const searchString = action.payload; state.searchString = searchString; state.isSearching = true; }, searchCompleted(state, action) { const { result, errorMsg, save } = action.payload; state.isSearching = false; state.currentSearchKeyword = state.searchString; state.searchString = ""; if (!result || result.length === 0) { state.searchResult = null; state.lastSearchError = errorMsg || 'error'; state.suggestionList = []; } else { const summary = getSearchSummary(result); state.searchResult = { matchedNodes: result, summary }; state.lastSearchError = ''; if (save) { state.searchHistoryItems = storeSearchHistoryItem({ keywordStr: state.currentSearchKeyword, matchedCount: summary.generalMatchedNodeIDs.length }); } state.matchedNodeIDs = summary.generalMatchedNodeIDs; state.matchedNodeIDsInNameAndDescription = summary.matchedNodeIDsInNameAndDescription; state.matchedNodeIDsInProperties = summary.matchedNodeIDsInProperties; const matchedStrings = calcMatchedStrings(result); state.suggestionList = Object.keys(matchedStrings).sort((str1, str2) => compareTwoStrings(str2, state.searchString) - compareTwoStrings(str1, state.searchString)).map(s => ({ fullString: s, matchedPieceIndices: matchedStrings[s].matchedPieceIndices })); state.isSearchMode = true; } }, suggestionItemClicked(state, action) { const suggestionItem = action.payload; state.clickedSuggestionItem = suggestionItem; }, suggestionItemReset(state, action) { state.clickedSuggestionItem = null; }, suggestionsCleared(state, action) { state.clickedSuggestionItem = null; state.suggestionList = []; }, historyItemClicked(state, action) { const historyItem = action.payload; state.clickedHistoryItem = historyItem; }, clearedHistory(state, action) { state.searchHistoryItems = clearSearchHistoryItems(); }, historyItemReset(state, action) { state.clickedHistoryItem = null; } } }); export const { // reducer/actions changedVisAcCloseIcon, searchDataPrepared, searchResultCleared, searchStarted, searchCompleted, suggestionItemClicked, suggestionItemReset, suggestionsCleared, historyItemClicked, historyItemReset, clearedHistory } = searchSlice.actions; export default searchSlice.reducer; // export Selectors export const selectAcCloseIconHidden = state => state.search.acCloseIconHidden; export const selectSearchData = state => state.search.searchData; export const selectIsSearchMode = state => state.search.isSearchMode; export const selectIsSearching = state => state.search.isSearching; export const selectLastSearchError = state => state.search.lastSearchError; export const selectOverlayPropertyHidden = state => state.search.overlayPropertyHidden; export const selectCurrentSearchKeyword = state => state.search.currentSearchKeyword; export const selectSearchResult = state => state.search.searchResult; export const selectSearchHistoryItems = state => state.search.searchHistoryItems; export const selectClickedSuggestionItem = state => state.search.clickedSuggestionItem; export const selectClickedHistoryItem = state => state.search.clickedHistoryItem; export const selectSuggestionList = state => state.search.suggestionList; export const selectMatchedNodeIDs = state => state.search.matchedNodeIDs; export const selectMatchedNodeIDsInProperties = state => state.search.matchedNodeIDsInProperties; export const selectMatchedNodeIDsInNameAndDescription = state => state.search.matchedNodeIDsInNameAndDescription; export const selectSearchIsFinished = state => !state.search.isSearching && !!state.search.searchResult; // note - to use the following, must get highlightingMatchedNodeID from graphSlice, // then useSelector( (state) => selectMatchedResult(state, highlightingMatchedNodeID) ) export const selectMatchedResult = createSelector([selectSearchResult, (state, matchedNodeID) => matchedNodeID], (searchResult, matchedNodeID) => { return searchResult && searchResult.matchedNodes.find(item => item.id === matchedNodeID); }); // useSelector( (state) => selectSearchResultOfHighlighted(state, matchedNodeID) ) // export const selectSearchResultOfHighlighted = createSelector( // [selectSearchResult, (state, matchedNodeID) => matchedNodeID], // (searchResult, matchedNodeID) => { // return searchResult.find( item => item.id == matchedNodeID ); // }); export const selectMatchedNodes = createSelector([selectMatchedNodeIDs, selectMatchedNodeIDsInProperties, selectMatchedNodeIDsInNameAndDescription], (matchedNodeIDs, matchedNodeIDsInProperties, matchedNodeIDsInNameAndDescription) => ({ matchedNodeIDs, matchedNodeIDsInNameAndDescription, matchedNodeIDsInProperties }));