Merge branch '19687-log-scrolling-safari'. Closes #19687
[arvados-workbench2.git] / src / store / search-bar / search-bar-reducer.ts
index fd417d374a9853f958b14315f5b7d9a2f32c7d97..5e16c9a0855b24f89014e55551f144e455970476 100644 (file)
@@ -2,19 +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: SearchResult[];
     searchValue: string;
-    savedQueries: SearchBarAdvanceFormData[];
-    selectedItem: string;
+    savedQueries: SearchBarAdvancedFormData[];
+    recentQueries: string[];
+    selectedItem: SearchBarSelectedItem;
 }
 
 export enum SearchView {
@@ -29,7 +38,19 @@ const initialState: SearchBar = {
     searchResults: [],
     searchValue: '',
     savedQueries: [],
-    selectedItem: ''
+    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 =>
@@ -44,30 +65,36 @@ export const searchBarReducer = (state = initialState, action: SearchBarActions)
         SET_SEARCH_RESULTS: searchResults => ({
             ...state,
             searchResults,
-            selectedItem: searchResults.length > 0
-                ? searchResults.findIndex(r => r.uuid === state.selectedItem) >= 0
-                    ? state.selectedItem
+            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,
-            selectedItem: state.searchValue === state.selectedItem
-                ? searchValue
-                : state.selectedItem
+            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: item }),
+        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);
+                const idx = state.searchResults.findIndex(r => r.uuid === selectedItem.id);
                 if (idx > 0) {
-                    selectedItem = state.searchResults[idx - 1].uuid;
+                    selectedItem = makeSelectedItem(state.searchResults[idx - 1].uuid);
                 } else {
-                    selectedItem = state.searchValue;
+                    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 {
@@ -78,11 +105,37 @@ export const searchBarReducer = (state = initialState, action: SearchBarActions)
         MOVE_DOWN: () => {
             let selectedItem = state.selectedItem;
             if (state.currentView === SearchView.AUTOCOMPLETE) {
-                const idx = state.searchResults.findIndex(r => r.uuid === selectedItem);
+                const idx = state.searchResults.findIndex(r => r.uuid === selectedItem.id);
                 if (idx >= 0 && idx < state.searchResults.length - 1) {
-                    selectedItem = state.searchResults[idx + 1].uuid;
+                    selectedItem = makeSelectedItem(state.searchResults[idx + 1].uuid);
                 } else if (idx < 0 && state.searchResults.length > 0) {
-                    selectedItem = state.searchResults[0].uuid;
+                    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 {