basic-view-recent-queries
authorPawel Kowalczyk <pawel.kowalczyk@contractors.roche.com>
Tue, 9 Oct 2018 09:35:24 +0000 (11:35 +0200)
committerPawel Kowalczyk <pawel.kowalczyk@contractors.roche.com>
Tue, 9 Oct 2018 09:35:24 +0000 (11:35 +0200)
Feature #14313

Arvados-DCO-1.1-Signed-off-by: Pawel Kowalczyk <pawel.kowalczyk@contractors.roche.com>

src/services/search-service/search-service.ts [new file with mode: 0644]
src/services/services.ts
src/store/search-bar/search-bar-actions.ts
src/views-components/search-bar/search-bar-basic-view.tsx
src/views-components/search-bar/search-bar-view.tsx
src/views-components/search-bar/search-bar.tsx

diff --git a/src/services/search-service/search-service.ts b/src/services/search-service/search-service.ts
new file mode 100644 (file)
index 0000000..1fc61dd
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+export class SearchQueriesService {
+    private recentQueries: string[] = this.getRecentQueries();
+
+    saveRecentQuery(query: string) {
+        if (this.recentQueries.length >= 5) {
+            this.recentQueries.shift();
+            this.recentQueries.push(query);
+        } else {
+            this.recentQueries.push(query);
+        }
+        localStorage.setItem('recentQueries', JSON.stringify(this.recentQueries));
+    }
+
+    getRecentQueries() {
+        return JSON.parse(localStorage.getItem('recentQueries') || '[]') as string[];
+    }
+}
\ No newline at end of file
index d39a68b91c20df7d4ce896ae62f826d74bd53249..205d16c806e7abf3edd184b7de30c4ba1d66f68b 100644 (file)
@@ -22,6 +22,7 @@ import { ContainerService } from './container-service/container-service';
 import { LogService } from './log-service/log-service';
 import { ApiActions } from "~/services/api/api-actions";
 import { WorkflowService } from "~/services/workflow-service/workflow-service";
+import { SearchQueriesService } from '~/services/search-service/search-service';
 
 export type ServiceRepository = ReturnType<typeof createServices>;
 
@@ -48,6 +49,7 @@ export const createServices = (config: Config, actions: ApiActions) => {
     const collectionFilesService = new CollectionFilesService(collectionService);
     const favoriteService = new FavoriteService(linkService, groupsService);
     const tagService = new TagService(linkService);
+    const searchQueriesService = new SearchQueriesService();
 
     return {
         ancestorsService,
@@ -63,6 +65,7 @@ export const createServices = (config: Config, actions: ApiActions) => {
         linkService,
         logService,
         projectService,
+        searchQueriesService,
         tagService,
         userService,
         webdavClient,
index 1e1810e767b07b17d0e7d95ab1d142e8e307733e..3d6d3fdc7348d849cc2db158f2713103079e693b 100644 (file)
@@ -3,6 +3,9 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import { unionize, ofType, UnionOf } from "~/common/unionize";
+import { Dispatch } from 'redux';
+import { RootState } from '~/store/store';
+import { ServiceRepository } from '~/services/services';
 
 export const searchBarActions = unionize({
     SET_CURRENT_VIEW: ofType<string>(),
@@ -12,4 +15,15 @@ export const searchBarActions = unionize({
 
 export type SearchBarActions = UnionOf<typeof searchBarActions>;
 
-export const goToView = (currentView: string) => searchBarActions.SET_CURRENT_VIEW(currentView);
\ No newline at end of file
+export const goToView = (currentView: string) => searchBarActions.SET_CURRENT_VIEW(currentView);
+
+export const saveRecentQuery = (query: string) =>
+    (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
+        services.searchQueriesService.saveRecentQuery(query);
+    };
+
+export const loadRecentQueries = () =>
+    (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
+        const recentSearchQueries = services.searchQueriesService.getRecentQueries();
+        return recentSearchQueries || [];
+    };
\ No newline at end of file
index 7e25214e582ff3662793bac4661c721675817d83..43fb40fcd2858a19da82c1a9bb719dd63e6359c0 100644 (file)
@@ -35,10 +35,11 @@ const styles: StyleRulesCallback<CssRules> = theme => {
 
 interface SearchBarBasicViewProps {
     setView: (currentView: string) => void;
+    recentQueries: () => string[];
 }
 
 export const SearchBarBasicView = withStyles(styles)(
-    ({ classes, setView }: SearchBarBasicViewProps & WithStyles<CssRules>) =>
+    ({ classes, setView, recentQueries }: SearchBarBasicViewProps & WithStyles<CssRules>) =>
         <Paper className={classes.searchView}>
             <div className={classes.searchQueryList}>Saved search queries</div>
             <List component="nav" className={classes.list}>
@@ -47,8 +48,7 @@ export const SearchBarBasicView = withStyles(styles)(
             </List>
             <div className={classes.searchQueryList}>Recent search queries</div>
             <List component="nav" className={classes.list}>
-                <RenderRecentQueries text="cos" />
-                <RenderRecentQueries text="testtest" />
+                {recentQueries().map((query, index) => <RenderRecentQueries key={query + index} text={query} />)}
             </List>
             <div className={classes.advanced} onClick={() => setView(SearchView.ADVANCED)}>Advanced search</div>
         </Paper>
index acd7ca2f3461a328f1109de5f580d80f4dd0b1bb..7f9a14ad99b5b094ed242ac9ed6f35701ea1c110 100644 (file)
@@ -52,6 +52,8 @@ interface SearchBarActionProps {
     onSetView: (currentView: string) => void;
     openView: () => void;
     closeView: () => void;
+    saveQuery: (query: string) => void;
+    loadQueries: () => string[];
 }
 
 type SearchBarProps = SearchBarDataProps & SearchBarActionProps & WithStyles<CssRules>;
@@ -139,21 +141,23 @@ export const SearchBarView = withStyles(styles)(
         getView = (currentView: string) => {
             switch (currentView) {
                 case SearchView.BASIC:
-                    return <SearchBarBasicView setView={this.props.onSetView} />;
+                    return <SearchBarBasicView setView={this.props.onSetView} recentQueries={this.props.loadQueries}/>;
                 case SearchView.ADVANCED:
                     return <SearchBarAdvancedView setView={this.props.onSetView} />;
                 case SearchView.AUTOCOMPLETE:
                     return <SearchBarAutocompleteView />;
                 default:
-                    return <SearchBarBasicView setView={this.props.onSetView} />;
+                    return <SearchBarBasicView setView={this.props.onSetView} recentQueries={this.props.loadQueries}/>;
             }
         }
 
         handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
-            event.preventDefault();
-            clearTimeout(this.timeout);
-            this.props.onSearch(this.state.value);
-        }
+                event.preventDefault();
+                clearTimeout(this.timeout);
+                this.props.saveQuery(this.state.value);
+                this.props.onSearch(this.state.value);
+                this.props.loadQueries();
+            }
 
         handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
             clearTimeout(this.timeout);
index affd5e4c69b16dc488b0f18a98430fdda405a723..e9ebc7c73503d6aad46ecd21e32d1aac442da65a 100644 (file)
@@ -7,6 +7,7 @@ import { RootState } from '~/store/store';
 import { Dispatch } from 'redux';
 import { goToView, searchBarActions } from '~/store/search-bar/search-bar-actions';
 import { SearchBarView } from '~/views-components/search-bar/search-bar-view';
+import { saveRecentQuery, loadRecentQueries } from '~/store/search-bar/search-bar-actions';
 
 const mapStateToProps = ({ searchBar }: RootState) => {
     return {
@@ -18,7 +19,9 @@ const mapStateToProps = ({ searchBar }: RootState) => {
 const mapDispatchToProps = (dispatch: Dispatch) => ({
     onSetView: (currentView: string) => dispatch(goToView(currentView)),
     openView: () => dispatch<any>(searchBarActions.OPEN_SEARCH_VIEW()),
-    closeView: () => dispatch<any>(searchBarActions.CLOSE_SEARCH_VIEW())
+    closeView: () => dispatch<any>(searchBarActions.CLOSE_SEARCH_VIEW()),
+    saveQuery: (query: string) => dispatch<any>(saveRecentQuery(query)),
+    loadQueries: () => dispatch<any>(loadRecentQueries())
 });
 
 export const SearchBar = connect(mapStateToProps, mapDispatchToProps)(SearchBarView);
\ No newline at end of file