1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
6 getQueryFromAdvancedData,
9 setSearchValueFromAdvancedData
10 } from '~/store/search-bar/search-bar-actions';
11 import { GroupContentsResource } from '~/services/groups-service/groups-service';
12 import { SearchBarAdvanceFormData } from '~/models/search-bar';
14 type SearchResult = GroupContentsResource;
15 export type SearchBarSelectedItem = {
23 searchResults: SearchResult[];
25 savedQueries: SearchBarAdvanceFormData[];
26 recentQueries: string[];
27 selectedItem: SearchBarSelectedItem;
30 export enum SearchView {
32 ADVANCED = 'advanced',
33 AUTOCOMPLETE = 'autocomplete'
36 const initialState: SearchBar = {
37 currentView: SearchView.BASIC,
49 const makeSelectedItem = (id: string, query?: string): SearchBarSelectedItem => ({ id, query: query ? query : id });
51 const makeQueryList = (recentQueries: string[], savedQueries: SearchBarAdvanceFormData[]) => {
52 const recentIds = recentQueries.map((q, idx) => makeSelectedItem(`RQ-${idx}-${q}`, q));
53 const savedIds = savedQueries.map((q, idx) => makeSelectedItem(`SQ-${idx}-${q.queryName}`, getQueryFromAdvancedData(q)));
54 return recentIds.concat(savedIds);
57 export const searchBarReducer = (state = initialState, action: SearchBarActions): SearchBar =>
58 searchBarActions.match(action, {
59 SET_CURRENT_VIEW: currentView => ({
64 OPEN_SEARCH_VIEW: () => ({ ...state, open: true }),
65 CLOSE_SEARCH_VIEW: () => ({ ...state, open: false }),
66 SET_SEARCH_RESULTS: searchResults => ({
69 selectedItem: makeSelectedItem(searchResults.length > 0
70 ? searchResults.findIndex(r => r.uuid === state.selectedItem.id) >= 0
71 ? state.selectedItem.id
76 SET_SEARCH_VALUE: searchValue => ({
80 SET_SAVED_QUERIES: savedQueries => ({ ...state, savedQueries }),
81 SET_RECENT_QUERIES: recentQueries => ({ ...state, recentQueries }),
82 UPDATE_SAVED_QUERY: searchQuery => ({ ...state, savedQueries: searchQuery }),
83 SET_SELECTED_ITEM: item => ({ ...state, selectedItem: makeSelectedItem(item) }),
85 let selectedItem = state.selectedItem;
86 if (state.currentView === SearchView.AUTOCOMPLETE) {
87 const idx = state.searchResults.findIndex(r => r.uuid === selectedItem.id);
89 selectedItem = makeSelectedItem(state.searchResults[idx - 1].uuid);
91 selectedItem = makeSelectedItem(state.searchValue);
93 } else if (state.currentView === SearchView.BASIC) {
94 const items = makeQueryList(state.recentQueries, state.savedQueries);
96 const idx = items.findIndex(i => i.id === selectedItem.id);
98 selectedItem = items[idx - 1];
107 let selectedItem = state.selectedItem;
108 if (state.currentView === SearchView.AUTOCOMPLETE) {
109 const idx = state.searchResults.findIndex(r => r.uuid === selectedItem.id);
110 if (idx >= 0 && idx < state.searchResults.length - 1) {
111 selectedItem = makeSelectedItem(state.searchResults[idx + 1].uuid);
112 } else if (idx < 0 && state.searchResults.length > 0) {
113 selectedItem = makeSelectedItem(state.searchResults[0].uuid);
115 } else if (state.currentView === SearchView.BASIC) {
116 const items = makeQueryList(state.recentQueries, state.savedQueries);
118 const idx = items.findIndex(i => i.id === selectedItem.id);
119 if (idx >= 0 && idx < items.length - 1) {
120 selectedItem = items[idx + 1];
123 if (idx < 0 && items.length > 0) {
124 selectedItem = items[0];
132 SELECT_FIRST_ITEM: () => {
133 let selectedItem = state.selectedItem;
134 if (state.currentView === SearchView.AUTOCOMPLETE) {
135 selectedItem = makeSelectedItem(state.searchValue);
136 } else if (state.currentView === SearchView.BASIC) {
137 const items = makeQueryList(state.recentQueries, state.savedQueries);
138 if (items.length > 0) {
139 selectedItem = items[0];