1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
6 getQueryFromAdvancedData,
9 } from '~/store/search-bar/search-bar-actions';
10 import { GroupContentsResource } from '~/services/groups-service/groups-service';
11 import { SearchBarAdvancedFormData } from '~/models/search-bar';
13 type SearchResult = GroupContentsResource;
14 export type SearchBarSelectedItem = {
22 searchResults: SearchResult[];
24 savedQueries: SearchBarAdvancedFormData[];
25 recentQueries: string[];
26 selectedItem: SearchBarSelectedItem;
29 export enum SearchView {
31 ADVANCED = 'advanced',
32 AUTOCOMPLETE = 'autocomplete'
35 const initialState: SearchBar = {
36 currentView: SearchView.BASIC,
48 const makeSelectedItem = (id: string, query?: string): SearchBarSelectedItem => ({ id, query: query ? query : id });
50 const makeQueryList = (recentQueries: string[], savedQueries: SearchBarAdvancedFormData[]) => {
51 const recentIds = recentQueries.map((q, idx) => makeSelectedItem(`RQ-${idx}-${q}`, q));
52 const savedIds = savedQueries.map((q, idx) => makeSelectedItem(`SQ-${idx}-${q.queryName}`, getQueryFromAdvancedData(q)));
53 return recentIds.concat(savedIds);
56 export const searchBarReducer = (state = initialState, action: SearchBarActions): SearchBar =>
57 searchBarActions.match(action, {
58 SET_CURRENT_VIEW: currentView => ({
63 OPEN_SEARCH_VIEW: () => ({ ...state, open: true }),
64 CLOSE_SEARCH_VIEW: () => ({ ...state, open: false }),
65 SET_SEARCH_RESULTS: searchResults => ({
68 selectedItem: makeSelectedItem(searchResults.length > 0
69 ? searchResults.findIndex(r => r.uuid === state.selectedItem.id) >= 0
70 ? state.selectedItem.id
75 SET_SEARCH_VALUE: searchValue => ({
79 SET_SAVED_QUERIES: savedQueries => ({ ...state, savedQueries }),
80 SET_RECENT_QUERIES: recentQueries => ({ ...state, recentQueries }),
81 UPDATE_SAVED_QUERY: searchQuery => ({ ...state, savedQueries: searchQuery }),
82 SET_SELECTED_ITEM: item => ({ ...state, selectedItem: makeSelectedItem(item) }),
84 let selectedItem = state.selectedItem;
85 if (state.currentView === SearchView.AUTOCOMPLETE) {
86 const idx = state.searchResults.findIndex(r => r.uuid === selectedItem.id);
88 selectedItem = makeSelectedItem(state.searchResults[idx - 1].uuid);
90 selectedItem = makeSelectedItem(state.searchValue);
92 } else if (state.currentView === SearchView.BASIC) {
93 const items = makeQueryList(state.recentQueries, state.savedQueries);
95 const idx = items.findIndex(i => i.id === selectedItem.id);
97 selectedItem = items[idx - 1];
106 let selectedItem = state.selectedItem;
107 if (state.currentView === SearchView.AUTOCOMPLETE) {
108 const idx = state.searchResults.findIndex(r => r.uuid === selectedItem.id);
109 if (idx >= 0 && idx < state.searchResults.length - 1) {
110 selectedItem = makeSelectedItem(state.searchResults[idx + 1].uuid);
111 } else if (idx < 0 && state.searchResults.length > 0) {
112 selectedItem = makeSelectedItem(state.searchResults[0].uuid);
114 } else if (state.currentView === SearchView.BASIC) {
115 const items = makeQueryList(state.recentQueries, state.savedQueries);
117 const idx = items.findIndex(i => i.id === selectedItem.id);
118 if (idx >= 0 && idx < items.length - 1) {
119 selectedItem = items[idx + 1];
122 if (idx < 0 && items.length > 0) {
123 selectedItem = items[0];
131 SELECT_FIRST_ITEM: () => {
132 let selectedItem = state.selectedItem;
133 if (state.currentView === SearchView.AUTOCOMPLETE) {
134 selectedItem = makeSelectedItem(state.searchValue);
135 } else if (state.currentView === SearchView.BASIC) {
136 const items = makeQueryList(state.recentQueries, state.savedQueries);
137 if (items.length > 0) {
138 selectedItem = items[0];