1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import { searchBarActions, SearchBarActions } from '~/store/search-bar/search-bar-actions';
6 import { GroupContentsResource } from '~/services/groups-service/groups-service';
7 import { SearchBarAdvanceFormData } from '~/models/search-bar';
9 type SearchResult = GroupContentsResource;
10 export type SearchBarSelectedItem = {
18 searchResults: SearchResult[];
20 savedQueries: SearchBarAdvanceFormData[];
21 recentQueries: string[];
22 selectedItem: SearchBarSelectedItem;
25 export enum SearchView {
27 ADVANCED = 'advanced',
28 AUTOCOMPLETE = 'autocomplete'
31 const initialState: SearchBar = {
32 currentView: SearchView.BASIC,
44 const makeSelectedItem = (id: string, query?: string): SearchBarSelectedItem => ({ id, query: query ? query : id });
46 const makeQueryList = (recentQueries: string[], savedQueries: SearchBarAdvanceFormData[]) => {
47 const recentIds = recentQueries.map((q, idx) => makeSelectedItem(`RQ-${idx}-${q}`, q));
48 const savedIds = savedQueries.map((q, idx) => makeSelectedItem(`SQ-${idx}-${q.searchQuery}`, q.searchQuery));
49 return recentIds.concat(savedIds);
52 export const searchBarReducer = (state = initialState, action: SearchBarActions): SearchBar =>
53 searchBarActions.match(action, {
54 SET_CURRENT_VIEW: currentView => ({
59 OPEN_SEARCH_VIEW: () => ({ ...state, open: true }),
60 CLOSE_SEARCH_VIEW: () => ({ ...state, open: false }),
61 SET_SEARCH_RESULTS: searchResults => ({
64 selectedItem: makeSelectedItem(searchResults.length > 0
65 ? searchResults.findIndex(r => r.uuid === state.selectedItem.id) >= 0
66 ? state.selectedItem.id
71 SET_SEARCH_VALUE: searchValue => ({
75 SET_SAVED_QUERIES: savedQueries => ({ ...state, savedQueries }),
76 SET_RECENT_QUERIES: recentQueries => ({ ...state, recentQueries }),
77 UPDATE_SAVED_QUERY: searchQuery => ({ ...state, savedQueries: searchQuery }),
78 SET_SELECTED_ITEM: item => ({ ...state, selectedItem: makeSelectedItem(item) }),
80 let selectedItem = state.selectedItem;
81 if (state.currentView === SearchView.AUTOCOMPLETE) {
82 const idx = state.searchResults.findIndex(r => r.uuid === selectedItem.id);
84 selectedItem = makeSelectedItem(state.searchResults[idx - 1].uuid);
86 selectedItem = makeSelectedItem(state.searchValue);
88 } else if (state.currentView === SearchView.BASIC) {
89 const items = makeQueryList(state.recentQueries, state.savedQueries);
91 const idx = items.findIndex(i => i.id === selectedItem.id);
93 selectedItem = items[idx - 1];
102 let selectedItem = state.selectedItem;
103 if (state.currentView === SearchView.AUTOCOMPLETE) {
104 const idx = state.searchResults.findIndex(r => r.uuid === selectedItem.id);
105 if (idx >= 0 && idx < state.searchResults.length - 1) {
106 selectedItem = makeSelectedItem(state.searchResults[idx + 1].uuid);
107 } else if (idx < 0 && state.searchResults.length > 0) {
108 selectedItem = makeSelectedItem(state.searchResults[0].uuid);
110 } else if (state.currentView === SearchView.BASIC) {
111 const items = makeQueryList(state.recentQueries, state.savedQueries);
113 const idx = items.findIndex(i => i.id === selectedItem.id);
114 if (idx >= 0 && idx < items.length - 1) {
115 selectedItem = items[idx + 1];
118 if (idx < 0 && items.length > 0) {
119 selectedItem = items[0];
127 SELECT_FIRST_ITEM: () => {
128 let selectedItem = state.selectedItem;
129 if (state.currentView === SearchView.AUTOCOMPLETE) {
130 selectedItem = makeSelectedItem(state.searchValue);
131 } else if (state.currentView === SearchView.BASIC) {
132 const items = makeQueryList(state.recentQueries, state.savedQueries);
133 if (items.length > 0) {
134 selectedItem = items[0];