X-Git-Url: https://git.arvados.org/arvados-workbench2.git/blobdiff_plain/36b4e36f75ea0035b6b0de6aaaad4edd3231371c..25216cc7acedc987c26a159f0b640210c0ef101e:/src/store/search-bar/search-bar-reducer.ts?ds=sidebyside diff --git a/src/store/search-bar/search-bar-reducer.ts b/src/store/search-bar/search-bar-reducer.ts index a9560437..5e16c9a0 100644 --- a/src/store/search-bar/search-bar-reducer.ts +++ b/src/store/search-bar/search-bar-reducer.ts @@ -2,16 +2,28 @@ // // SPDX-License-Identifier: AGPL-3.0 -import { searchBarActions, SearchBarActions } from '~/store/search-bar/search-bar-actions'; -import { GroupContentsResource } from '~/services/groups-service/groups-service'; -import { SearchBarAdvanceFormData } from '~/models/search-bar'; +import { + getQueryFromAdvancedData, + searchBarActions, + SearchBarActions +} from 'store/search-bar/search-bar-actions'; +import { GroupContentsResource } from 'services/groups-service/groups-service'; +import { SearchBarAdvancedFormData } from 'models/search-bar'; + +type SearchResult = GroupContentsResource; +export type SearchBarSelectedItem = { + id: string, + query: string +}; interface SearchBar { currentView: string; open: boolean; - searchResults: GroupContentsResource[]; + searchResults: SearchResult[]; searchValue: string; - savedQueries: SearchBarAdvanceFormData[]; + savedQueries: SearchBarAdvancedFormData[]; + recentQueries: string[]; + selectedItem: SearchBarSelectedItem; } export enum SearchView { @@ -25,16 +37,111 @@ const initialState: SearchBar = { open: false, searchResults: [], searchValue: '', - savedQueries: [] + savedQueries: [], + recentQueries: [], + selectedItem: { + id: '', + query: '' + } +}; + +const makeSelectedItem = (id: string, query?: string): SearchBarSelectedItem => ({ id, query: query ? query : id }); + +const makeQueryList = (recentQueries: string[], savedQueries: SearchBarAdvancedFormData[]) => { + const recentIds = recentQueries.map((q, idx) => makeSelectedItem(`RQ-${idx}-${q}`, q)); + const savedIds = savedQueries.map((q, idx) => makeSelectedItem(`SQ-${idx}-${q.queryName}`, getQueryFromAdvancedData(q))); + return recentIds.concat(savedIds); }; export const searchBarReducer = (state = initialState, action: SearchBarActions): SearchBar => searchBarActions.match(action, { - SET_CURRENT_VIEW: currentView => ({ ...state, currentView }), + SET_CURRENT_VIEW: currentView => ({ + ...state, + currentView, + open: true + }), OPEN_SEARCH_VIEW: () => ({ ...state, open: true }), CLOSE_SEARCH_VIEW: () => ({ ...state, open: false }), - SET_SEARCH_RESULTS: (searchResults) => ({ ...state, searchResults }), - SET_SEARCH_VALUE: (searchValue) => ({ ...state, searchValue }), + SET_SEARCH_RESULTS: searchResults => ({ + ...state, + searchResults, + selectedItem: makeSelectedItem(searchResults.length > 0 + ? searchResults.findIndex(r => r.uuid === state.selectedItem.id) >= 0 + ? state.selectedItem.id + : state.searchValue + : state.searchValue + ) + }), + SET_SEARCH_VALUE: searchValue => ({ + ...state, + searchValue + }), SET_SAVED_QUERIES: savedQueries => ({ ...state, savedQueries }), + SET_RECENT_QUERIES: recentQueries => ({ ...state, recentQueries }), + UPDATE_SAVED_QUERY: searchQuery => ({ ...state, savedQueries: searchQuery }), + SET_SELECTED_ITEM: item => ({ ...state, selectedItem: makeSelectedItem(item) }), + MOVE_UP: () => { + let selectedItem = state.selectedItem; + if (state.currentView === SearchView.AUTOCOMPLETE) { + const idx = state.searchResults.findIndex(r => r.uuid === selectedItem.id); + if (idx > 0) { + selectedItem = makeSelectedItem(state.searchResults[idx - 1].uuid); + } else { + selectedItem = makeSelectedItem(state.searchValue); + } + } else if (state.currentView === SearchView.BASIC) { + const items = makeQueryList(state.recentQueries, state.savedQueries); + + const idx = items.findIndex(i => i.id === selectedItem.id); + if (idx > 0) { + selectedItem = items[idx - 1]; + } + } + return { + ...state, + selectedItem + }; + }, + MOVE_DOWN: () => { + let selectedItem = state.selectedItem; + if (state.currentView === SearchView.AUTOCOMPLETE) { + const idx = state.searchResults.findIndex(r => r.uuid === selectedItem.id); + if (idx >= 0 && idx < state.searchResults.length - 1) { + selectedItem = makeSelectedItem(state.searchResults[idx + 1].uuid); + } else if (idx < 0 && state.searchResults.length > 0) { + selectedItem = makeSelectedItem(state.searchResults[0].uuid); + } + } else if (state.currentView === SearchView.BASIC) { + const items = makeQueryList(state.recentQueries, state.savedQueries); + + const idx = items.findIndex(i => i.id === selectedItem.id); + if (idx >= 0 && idx < items.length - 1) { + selectedItem = items[idx + 1]; + } + + if (idx < 0 && items.length > 0) { + selectedItem = items[0]; + } + } + return { + ...state, + selectedItem + }; + }, + SELECT_FIRST_ITEM: () => { + let selectedItem = state.selectedItem; + if (state.currentView === SearchView.AUTOCOMPLETE) { + selectedItem = makeSelectedItem(state.searchValue); + } else if (state.currentView === SearchView.BASIC) { + const items = makeQueryList(state.recentQueries, state.savedQueries); + if (items.length > 0) { + selectedItem = items[0]; + } + } + return { + ...state, + selectedItem + }; + }, default: () => state - }); \ No newline at end of file + });