[ARVADOS-WORKBENCH2] created: 1.2.0-747-g4ad549e

Git user git at public.curoverse.com
Mon Oct 29 19:11:37 EDT 2018


        at  4ad549e2cebe285c9a854e466f3e0ddac10b808d (commit)


commit 4ad549e2cebe285c9a854e466f3e0ddac10b808d
Author: Daniel Kos <daniel.kos at contractors.roche.com>
Date:   Tue Oct 30 00:11:28 2018 +0100

    Add arrow navigation in autocomplete view
    
    Feature #14364
    
    Arvados-DCO-1.1-Signed-off-by: Daniel Kos <daniel.kos at contractors.roche.com>

diff --git a/src/common/codes.ts b/src/common/codes.ts
new file mode 100644
index 0000000..6342a29
--- /dev/null
+++ b/src/common/codes.ts
@@ -0,0 +1,8 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+export const KEY_CODE_UP = 38;
+export const KEY_CODE_DOWN = 40;
+export const KEY_CODE_ESC = 27;
+export const KEY_ENTER = 13;
diff --git a/src/services/search-service/search-service.ts b/src/services/search-service/search-service.ts
index 5817275..bcc42bd 100644
--- a/src/services/search-service/search-service.ts
+++ b/src/services/search-service/search-service.ts
@@ -11,10 +11,8 @@ export class SearchService {
     saveRecentQuery(query: string) {
         if (this.recentQueries.length >= MAX_NUMBER_OF_RECENT_QUERIES) {
             this.recentQueries.shift();
-            this.recentQueries.push(query);
-        } else {
-            this.recentQueries.push(query);
         }
+        this.recentQueries.push(query);
         localStorage.setItem('recentQueries', JSON.stringify(this.recentQueries));
     }
 
@@ -43,4 +41,4 @@ export class SearchService {
     }
 }
 
-const MAX_NUMBER_OF_RECENT_QUERIES = 5;
\ No newline at end of file
+const MAX_NUMBER_OF_RECENT_QUERIES = 5;
diff --git a/src/store/search-bar/search-bar-actions.ts b/src/store/search-bar/search-bar-actions.ts
index 653a8f5..f953a57 100644
--- a/src/store/search-bar/search-bar-actions.ts
+++ b/src/store/search-bar/search-bar-actions.ts
@@ -26,7 +26,10 @@ export const searchBarActions = unionize({
     SET_SEARCH_RESULTS: ofType<GroupContentsResource[]>(),
     SET_SEARCH_VALUE: ofType<string>(),
     SET_SAVED_QUERIES: ofType<SearchBarAdvanceFormData[]>(),
-    UPDATE_SAVED_QUERY: ofType<SearchBarAdvanceFormData[]>()
+    UPDATE_SAVED_QUERY: ofType<SearchBarAdvanceFormData[]>(),
+    SET_SELECTED_ITEM: ofType<string>(),
+    MOVE_UP: ofType<{}>(),
+    MOVE_DOWN: ofType<{}>()
 });
 
 export type SearchBarActions = UnionOf<typeof searchBarActions>;
@@ -51,23 +54,22 @@ export const loadRecentQueries = () =>
     };
 
 export const searchData = (searchValue: string) =>
-    async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+    async (dispatch: Dispatch, getState: () => RootState) => {
         const currentView = getState().searchBar.currentView;
         dispatch(searchBarActions.SET_SEARCH_VALUE(searchValue));
-        dispatch(searchBarActions.SET_SEARCH_RESULTS([]));
-        dispatch<any>(searchGroups(searchValue));
-        if (currentView === SearchView.BASIC) {
-            dispatch(searchBarActions.CLOSE_SEARCH_VIEW());
-            dispatch(navigateToSearchResults);
+        // dispatch(searchBarActions.SET_SEARCH_RESULTS([]));
+        if (searchValue.length > 0) {
+            dispatch<any>(searchGroups(searchValue));
+            if (currentView === SearchView.BASIC) {
+                dispatch(searchBarActions.CLOSE_SEARCH_VIEW());
+                dispatch(navigateToSearchResults);
+            }
         }
-
     };
 
 export const searchAdvanceData = (data: SearchBarAdvanceFormData) =>
-    async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
-        const searchValue = getState().searchBar.searchValue;
+    async (dispatch: Dispatch) => {
         dispatch<any>(saveQuery(data));
-        dispatch<any>(searchGroups(searchValue, 100, data.type));
         dispatch(searchBarActions.SET_CURRENT_VIEW(SearchView.BASIC));
         dispatch(searchBarActions.CLOSE_SEARCH_VIEW());
         dispatch(navigateToSearchResults);
@@ -82,11 +84,11 @@ const saveQuery = (data: SearchBarAdvanceFormData) =>
             if (filteredQuery) {
                 services.searchService.editSavedQueries(data);
                 dispatch(searchBarActions.UPDATE_SAVED_QUERY(savedSearchQueries));
-                dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Query has been sucessfully updated', hideDuration: 2000, kind: SnackbarKind.SUCCESS }));
+                dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Query has been successfully updated', hideDuration: 2000, kind: SnackbarKind.SUCCESS }));
             } else {
                 services.searchService.saveQuery(data);
                 dispatch(searchBarActions.SET_SAVED_QUERIES(savedSearchQueries));
-                dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Query has been sucessfully saved', hideDuration: 2000, kind: SnackbarKind.SUCCESS }));
+                dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Query has been successfully saved', hideDuration: 2000, kind: SnackbarKind.SUCCESS }));
             }
         }
     };
@@ -100,7 +102,7 @@ export const deleteSavedQuery = (id: number) =>
     };
 
 export const editSavedQuery = (data: SearchBarAdvanceFormData) =>
-    (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
+    (dispatch: Dispatch<any>) => {
         dispatch(searchBarActions.SET_CURRENT_VIEW(SearchView.ADVANCED));
         dispatch(searchBarActions.SET_SEARCH_VALUE(data.searchQuery));
         dispatch<any>(initialize(SEARCH_BAR_ADVANCE_FORM_NAME, data));
@@ -114,7 +116,7 @@ export const openSearchView = () =>
     };
 
 export const closeSearchView = () =>
-    (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
+    (dispatch: Dispatch<any>, getState: () => RootState) => {
         const isOpen = getState().searchBar.open;
         if (isOpen) {
             dispatch(searchBarActions.CLOSE_SEARCH_VIEW());
@@ -122,20 +124,20 @@ export const closeSearchView = () =>
         }
     };
 
-export const closeAdvanceView = () => 
-    (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
+export const closeAdvanceView = () =>
+    (dispatch: Dispatch<any>) => {
         dispatch(searchBarActions.SET_SEARCH_VALUE(''));
         dispatch(searchBarActions.SET_CURRENT_VIEW(SearchView.BASIC));
     };
 
 export const navigateToItem = (uuid: string) =>
-    (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
+    (dispatch: Dispatch<any>) => {
         dispatch(searchBarActions.CLOSE_SEARCH_VIEW());
         dispatch(navigateTo(uuid));
     };
 
-export const changeData = (searchValue: string) => 
-    (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+export const changeData = (searchValue: string) =>
+    (dispatch: Dispatch, getState: () => RootState) => {
         dispatch(searchBarActions.SET_SEARCH_VALUE(searchValue));
         const currentView = getState().searchBar.currentView;
         const searchValuePresent = searchValue.length > 0;
@@ -153,35 +155,29 @@ export const changeData = (searchValue: string) =>
     };
 
 export const submitData = (event: React.FormEvent<HTMLFormElement>) =>
-    (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+    (dispatch: Dispatch, getState: () => RootState) => {
         event.preventDefault();
         const searchValue = getState().searchBar.searchValue;
         dispatch<any>(saveRecentQuery(searchValue));
-        dispatch<any>(searchDataOnEnter(searchValue));
         dispatch<any>(loadRecentQueries());
-    };
-
-const searchDataOnEnter = (searchValue: string) =>
-    (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
         dispatch(searchBarActions.CLOSE_SEARCH_VIEW());
         dispatch(searchBarActions.SET_SEARCH_VALUE(searchValue));
         dispatch(searchBarActions.SET_SEARCH_RESULTS([]));
-        dispatch<any>(searchGroups(searchValue, 100));
         dispatch(navigateToSearchResults);
     };
 
 const debounceStartSearch = debounce((dispatch: Dispatch) => dispatch<any>(startSearch()), DEFAULT_SEARCH_DEBOUNCE);
 
-const startSearch = () => 
-    (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+const startSearch = () =>
+    (dispatch: Dispatch, getState: () => RootState) => {
         const searchValue = getState().searchBar.searchValue;
         dispatch<any>(searchData(searchValue));
     };
 
-const searchGroups = (searchValue: string, limit = 5, resourceKind?: ResourceKind) => 
+const searchGroups = (searchValue: string, limit = 5, resourceKind?: ResourceKind) =>
     async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
         const currentView = getState().searchBar.currentView;
-        
+
         if (searchValue || currentView === SearchView.ADVANCED) {
             const filters = getFilters('name', searchValue, resourceKind);
             const { items } = await services.groupsService.contents('', {
@@ -208,16 +204,26 @@ const buildUuidFilter = (type?: ResourceKind): ResourceKind[] => {
 };
 
 export const initAdvanceFormProjectsTree = () =>
-    (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+    (dispatch: Dispatch) => {
         dispatch<any>(initUserProject(SEARCH_BAR_ADVANCE_FORM_PICKER_ID));
     };
 
 export const changeAdvanceFormProperty = (property: string, value: PropertyValues[] | string = '') =>
-    (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+    (dispatch: Dispatch) => {
         dispatch(change(SEARCH_BAR_ADVANCE_FORM_NAME, property, value));
     };
 
 export const updateAdvanceFormProperties = (propertyValues: PropertyValues) =>
-    (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+    (dispatch: Dispatch) => {
         dispatch(arrayPush(SEARCH_BAR_ADVANCE_FORM_NAME, 'properties', propertyValues));
-    };
\ No newline at end of file
+    };
+
+export const moveUp = () =>
+    (dispatch: Dispatch) => {
+        dispatch(searchBarActions.MOVE_UP());
+    };
+
+export const moveDown = () =>
+    (dispatch: Dispatch) => {
+        dispatch(searchBarActions.MOVE_DOWN());
+    };
diff --git a/src/store/search-bar/search-bar-reducer.ts b/src/store/search-bar/search-bar-reducer.ts
index 781246a..fd417d3 100644
--- a/src/store/search-bar/search-bar-reducer.ts
+++ b/src/store/search-bar/search-bar-reducer.ts
@@ -6,12 +6,15 @@ import { searchBarActions, SearchBarActions } from '~/store/search-bar/search-ba
 import { GroupContentsResource } from '~/services/groups-service/groups-service';
 import { SearchBarAdvanceFormData } from '~/models/search-bar';
 
+type SearchResult = GroupContentsResource;
+
 interface SearchBar {
     currentView: string;
     open: boolean;
-    searchResults: GroupContentsResource[];
+    searchResults: SearchResult[];
     searchValue: string;
     savedQueries: SearchBarAdvanceFormData[];
+    selectedItem: string;
 }
 
 export enum SearchView {
@@ -25,17 +28,67 @@ const initialState: SearchBar = {
     open: false,
     searchResults: [],
     searchValue: '',
-    savedQueries: []
+    savedQueries: [],
+    selectedItem: ''
 };
 
 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: searchResults.length > 0
+                ? searchResults.findIndex(r => r.uuid === state.selectedItem) >= 0
+                    ? state.selectedItem
+                    : state.searchValue
+                : state.searchValue
+        }),
+        SET_SEARCH_VALUE: searchValue => ({
+            ...state,
+            searchValue,
+            selectedItem: state.searchValue === state.selectedItem
+                ? searchValue
+                : state.selectedItem
+        }),
         SET_SAVED_QUERIES: savedQueries => ({ ...state, savedQueries }),
         UPDATE_SAVED_QUERY: searchQuery => ({ ...state, savedQueries: searchQuery }),
+        SET_SELECTED_ITEM: item => ({ ...state, selectedItem: item }),
+        MOVE_UP: () => {
+            let selectedItem = state.selectedItem;
+            if (state.currentView === SearchView.AUTOCOMPLETE) {
+                const idx = state.searchResults.findIndex(r => r.uuid === selectedItem);
+                if (idx > 0) {
+                    selectedItem = state.searchResults[idx - 1].uuid;
+                } else {
+                    selectedItem = state.searchValue;
+                }
+            }
+            return {
+                ...state,
+                selectedItem
+            };
+        },
+        MOVE_DOWN: () => {
+            let selectedItem = state.selectedItem;
+            if (state.currentView === SearchView.AUTOCOMPLETE) {
+                const idx = state.searchResults.findIndex(r => r.uuid === selectedItem);
+                if (idx >= 0 && idx < state.searchResults.length - 1) {
+                    selectedItem = state.searchResults[idx + 1].uuid;
+                } else if (idx < 0 && state.searchResults.length > 0) {
+                    selectedItem = state.searchResults[0].uuid;
+                }
+            }
+            return {
+                ...state,
+                selectedItem
+            };
+        },
         default: () => state
-    });
\ No newline at end of file
+    });
diff --git a/src/store/search-results-panel/search-results-middleware-service.ts b/src/store/search-results-panel/search-results-middleware-service.ts
index 5ccb61b..3806765 100644
--- a/src/store/search-results-panel/search-results-middleware-service.ts
+++ b/src/store/search-results-panel/search-results-middleware-service.ts
@@ -28,7 +28,7 @@ export class SearchResultsMiddlewareService extends DataExplorerMiddlewareServic
         const dataExplorer = getDataExplorer(state.dataExplorer, this.getId());
         const searchValue = state.searchBar.searchValue;
         try {
-            const response = await this.services.groupsService.contents(userUuid, getParams(dataExplorer, searchValue));
+            const response = await this.services.groupsService.contents('', getParams(dataExplorer, searchValue));
             api.dispatch(updateResources(response.items));
             api.dispatch(setItems(response));
         } catch {
@@ -72,4 +72,4 @@ const couldNotFetchWorkflows = () =>
     snackbarActions.OPEN_SNACKBAR({
         message: 'Could not fetch workflows.',
         kind: SnackbarKind.ERROR
-    });
\ No newline at end of file
+    });
diff --git a/src/views-components/search-bar/search-bar-autocomplete-view.tsx b/src/views-components/search-bar/search-bar-autocomplete-view.tsx
index 69fa459..02ff4c7 100644
--- a/src/views-components/search-bar/search-bar-autocomplete-view.tsx
+++ b/src/views-components/search-bar/search-bar-autocomplete-view.tsx
@@ -21,13 +21,14 @@ const styles: StyleRulesCallback<CssRules> = theme => {
             paddingLeft: theme.spacing.unit,
             paddingRight: theme.spacing.unit * 2,
         },
-        
+
     };
 };
 
 export interface SearchBarAutocompleteViewDataProps {
-    searchResults?: GroupContentsResource[];
+    searchResults: GroupContentsResource[];
     searchValue?: string;
+    selectedItem: string;
 }
 
 export interface SearchBarAutocompleteViewActionProps {
@@ -37,18 +38,23 @@ export interface SearchBarAutocompleteViewActionProps {
 type SearchBarAutocompleteViewProps = SearchBarAutocompleteViewDataProps & SearchBarAutocompleteViewActionProps & WithStyles<CssRules>;
 
 export const SearchBarAutocompleteView = withStyles(styles)(
-    ({ classes, searchResults, searchValue, navigateTo }: SearchBarAutocompleteViewProps) =>
-        <Paper className={classes.searchView}>
-            {searchResults && <List component="nav" className={classes.list}>
+    ({ classes, searchResults, searchValue, navigateTo, selectedItem }: SearchBarAutocompleteViewProps) => {
+        console.log(searchValue, selectedItem);
+        return <Paper className={classes.searchView}>
+            <List component="nav" className={classes.list}>
+                <ListItem button className={classes.listItem} selected={!selectedItem || searchValue === selectedItem}>
+                    <ListItemText secondary={searchValue}/>
+                </ListItem>
                 {searchResults.map((item: GroupContentsResource) =>
-                    <ListItem button key={item.uuid} className={classes.listItem}>
-                        <ListItemText secondary={getFormattedText(item.name, searchValue)} onClick={() => navigateTo(item.uuid)} />
+                    <ListItem button key={item.uuid} className={classes.listItem} selected={item.uuid === selectedItem}>
+                        <ListItemText secondary={getFormattedText(item.name, searchValue)}
+                                      onClick={() => navigateTo(item.uuid)}/>
                     </ListItem>
                 )}
-            </List>}
-        </Paper>
-);
+            </List>
+        </Paper>;
+    });
 
 const getFormattedText = (textToHighlight: string, searchString = '') => {
     return <Highlighter searchWords={[searchString]} autoEscape={true} textToHighlight={textToHighlight} />;
-};
\ No newline at end of file
+};
diff --git a/src/views-components/search-bar/search-bar-view.tsx b/src/views-components/search-bar/search-bar-view.tsx
index b3ec7ab..80c3c71 100644
--- a/src/views-components/search-bar/search-bar-view.tsx
+++ b/src/views-components/search-bar/search-bar-view.tsx
@@ -31,6 +31,7 @@ import {
     SearchBarAdvancedViewDataProps,
     SearchBarAdvancedViewActionProps
 } from '~/views-components/search-bar/search-bar-advanced-view';
+import { KEY_CODE_DOWN, KEY_CODE_ESC, KEY_CODE_UP, KEY_ENTER } from "~/common/codes";
 
 type CssRules = 'container' | 'containerSearchViewOpened' | 'input' | 'view';
 
@@ -82,25 +83,47 @@ interface SearchBarViewActionProps {
     closeView: () => void;
     openSearchView: () => void;
     loadRecentQueries: () => string[];
+    moveUp: () => void;
+    moveDown: () => void;
 }
 
 type SearchBarViewProps = SearchBarDataProps & SearchBarActionProps & WithStyles<CssRules>;
 
 export const SearchBarView = withStyles(styles)(
     (props : SearchBarViewProps) => {
-        const { classes, isPopoverOpen, closeView, searchValue, openSearchView, onChange, onSubmit } = props;
+        const { classes, isPopoverOpen } = props;
         return (
-            <ClickAwayListener onClickAway={closeView}>
+            <ClickAwayListener onClickAway={props.closeView}>
                 <Paper className={isPopoverOpen ? classes.containerSearchViewOpened : classes.container} >
-                    <form onSubmit={onSubmit}>
+                    <form onSubmit={props.onSubmit}>
                         <Input
                             className={classes.input}
-                            onChange={onChange}
+                            onChange={props.onChange}
                             placeholder="Search"
-                            value={searchValue}
+                            value={props.searchValue}
                             fullWidth={true}
                             disableUnderline={true}
-                            onClick={openSearchView}
+                            onClick={props.openSearchView}
+                            onKeyDown={e => {
+                                if (e.keyCode === KEY_CODE_DOWN) {
+                                    e.preventDefault();
+                                    if (!isPopoverOpen) {
+                                        props.openSearchView();
+                                    } else {
+                                        props.moveDown();
+                                    }
+                                } else if (e.keyCode === KEY_CODE_UP) {
+                                    e.preventDefault();
+                                    props.moveUp();
+                                } else if (e.keyCode === KEY_CODE_ESC) {
+                                    props.closeView();
+                                } else if (e.keyCode === KEY_ENTER) {
+                                    if (props.selectedItem !== props.searchValue) {
+                                        e.preventDefault();
+                                        props.navigateTo(props.selectedItem);
+                                    }
+                                }
+                            }}
                             endAdornment={
                                 <InputAdornment position="end">
                                     <Tooltip title='Search'>
@@ -121,25 +144,24 @@ export const SearchBarView = withStyles(styles)(
 );
 
 const getView = (props: SearchBarViewProps) => {
-    const { onSetView, closeAdvanceView, loadRecentQueries, savedQueries, deleteSavedQuery, searchValue,
-        searchResults, onSearch, navigateTo, editSavedQuery, tags, currentView } = props;
-    switch (currentView) {
+    switch (props.currentView) {
         case SearchView.AUTOCOMPLETE:
             return <SearchBarAutocompleteView
-                navigateTo={navigateTo}
-                searchResults={searchResults}
-                searchValue={searchValue} />;
+                navigateTo={props.navigateTo}
+                searchResults={props.searchResults}
+                searchValue={props.searchValue}
+                selectedItem={props.selectedItem} />;
         case SearchView.ADVANCED:
             return <SearchBarAdvancedView
-                closeAdvanceView={closeAdvanceView}
-                tags={tags} />;
+                closeAdvanceView={props.closeAdvanceView}
+                tags={props.tags} />;
         default:
             return <SearchBarBasicView
-                onSetView={onSetView}
-                onSearch={onSearch}
-                loadRecentQueries={loadRecentQueries}
-                savedQueries={savedQueries}
-                deleteSavedQuery={deleteSavedQuery}
-                editSavedQuery={editSavedQuery} />;
+                onSetView={props.onSetView}
+                onSearch={props.onSearch}
+                loadRecentQueries={props.loadRecentQueries}
+                savedQueries={props.savedQueries}
+                deleteSavedQuery={props.deleteSavedQuery}
+                editSavedQuery={props.editSavedQuery} />;
     }
 };
diff --git a/src/views-components/search-bar/search-bar.tsx b/src/views-components/search-bar/search-bar.tsx
index 68ffecf..e60b214 100644
--- a/src/views-components/search-bar/search-bar.tsx
+++ b/src/views-components/search-bar/search-bar.tsx
@@ -16,7 +16,7 @@ import {
     navigateToItem,
     editSavedQuery,
     changeData,
-    submitData
+    submitData, moveUp, moveDown
 } from '~/store/search-bar/search-bar-actions';
 import { SearchBarView, SearchBarActionProps, SearchBarDataProps } from '~/views-components/search-bar/search-bar-view';
 import { SearchBarAdvanceFormData } from '~/models/search-bar';
@@ -27,6 +27,7 @@ const mapStateToProps = ({ searchBar, form }: RootState): SearchBarDataProps =>
         currentView: searchBar.currentView,
         isPopoverOpen: searchBar.open,
         searchResults: searchBar.searchResults,
+        selectedItem: searchBar.selectedItem,
         savedQueries: searchBar.savedQueries,
         tags: form.searchBarAdvanceFormName
     };
@@ -43,7 +44,9 @@ const mapDispatchToProps = (dispatch: Dispatch): SearchBarActionProps => ({
     deleteSavedQuery: (id: number) => dispatch<any>(deleteSavedQuery(id)),
     openSearchView: () => dispatch<any>(openSearchView()),
     navigateTo: (uuid: string) => dispatch<any>(navigateToItem(uuid)),
-    editSavedQuery: (data: SearchBarAdvanceFormData) => dispatch<any>(editSavedQuery(data))
+    editSavedQuery: (data: SearchBarAdvanceFormData) => dispatch<any>(editSavedQuery(data)),
+    moveUp: () => dispatch<any>(moveUp()),
+    moveDown: () => dispatch<any>(moveDown())
 });
 
-export const SearchBar = connect(mapStateToProps, mapDispatchToProps)(SearchBarView);
\ No newline at end of file
+export const SearchBar = connect(mapStateToProps, mapDispatchToProps)(SearchBarView);

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list