From da3ae51b7b3b63561a9e1c47c965f45a08225d34 Mon Sep 17 00:00:00 2001 From: Pawel Kowalczyk Date: Tue, 9 Oct 2018 11:35:24 +0200 Subject: [PATCH] basic-view-recent-queries Feature #14313 Arvados-DCO-1.1-Signed-off-by: Pawel Kowalczyk --- src/services/search-service/search-service.ts | 21 +++++++++++++++++++ src/services/services.ts | 3 +++ src/store/search-bar/search-bar-actions.ts | 16 +++++++++++++- .../search-bar/search-bar-basic-view.tsx | 6 +++--- .../search-bar/search-bar-view.tsx | 16 ++++++++------ .../search-bar/search-bar.tsx | 5 ++++- 6 files changed, 56 insertions(+), 11 deletions(-) create mode 100644 src/services/search-service/search-service.ts diff --git a/src/services/search-service/search-service.ts b/src/services/search-service/search-service.ts new file mode 100644 index 00000000..1fc61dd2 --- /dev/null +++ b/src/services/search-service/search-service.ts @@ -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 diff --git a/src/services/services.ts b/src/services/services.ts index d39a68b9..205d16c8 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -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; @@ -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, diff --git a/src/store/search-bar/search-bar-actions.ts b/src/store/search-bar/search-bar-actions.ts index 1e1810e7..3d6d3fdc 100644 --- a/src/store/search-bar/search-bar-actions.ts +++ b/src/store/search-bar/search-bar-actions.ts @@ -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(), @@ -12,4 +15,15 @@ export const searchBarActions = unionize({ export type SearchBarActions = UnionOf; -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, getState: () => RootState, services: ServiceRepository) => { + services.searchQueriesService.saveRecentQuery(query); + }; + +export const loadRecentQueries = () => + (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { + const recentSearchQueries = services.searchQueriesService.getRecentQueries(); + return recentSearchQueries || []; + }; \ No newline at end of file diff --git a/src/views-components/search-bar/search-bar-basic-view.tsx b/src/views-components/search-bar/search-bar-basic-view.tsx index 7e25214e..43fb40fc 100644 --- a/src/views-components/search-bar/search-bar-basic-view.tsx +++ b/src/views-components/search-bar/search-bar-basic-view.tsx @@ -35,10 +35,11 @@ const styles: StyleRulesCallback = theme => { interface SearchBarBasicViewProps { setView: (currentView: string) => void; + recentQueries: () => string[]; } export const SearchBarBasicView = withStyles(styles)( - ({ classes, setView }: SearchBarBasicViewProps & WithStyles) => + ({ classes, setView, recentQueries }: SearchBarBasicViewProps & WithStyles) =>
Saved search queries
@@ -47,8 +48,7 @@ export const SearchBarBasicView = withStyles(styles)(
Recent search queries
- - + {recentQueries().map((query, index) => )}
setView(SearchView.ADVANCED)}>Advanced search
diff --git a/src/views-components/search-bar/search-bar-view.tsx b/src/views-components/search-bar/search-bar-view.tsx index acd7ca2f..7f9a14ad 100644 --- a/src/views-components/search-bar/search-bar-view.tsx +++ b/src/views-components/search-bar/search-bar-view.tsx @@ -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; @@ -139,21 +141,23 @@ export const SearchBarView = withStyles(styles)( getView = (currentView: string) => { switch (currentView) { case SearchView.BASIC: - return ; + return ; case SearchView.ADVANCED: return ; case SearchView.AUTOCOMPLETE: return ; default: - return ; + return ; } } handleSubmit = (event: React.FormEvent) => { - 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) => { clearTimeout(this.timeout); diff --git a/src/views-components/search-bar/search-bar.tsx b/src/views-components/search-bar/search-bar.tsx index affd5e4c..e9ebc7c7 100644 --- a/src/views-components/search-bar/search-bar.tsx +++ b/src/views-components/search-bar/search-bar.tsx @@ -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(searchBarActions.OPEN_SEARCH_VIEW()), - closeView: () => dispatch(searchBarActions.CLOSE_SEARCH_VIEW()) + closeView: () => dispatch(searchBarActions.CLOSE_SEARCH_VIEW()), + saveQuery: (query: string) => dispatch(saveRecentQuery(query)), + loadQueries: () => dispatch(loadRecentQueries()) }); export const SearchBar = connect(mapStateToProps, mapDispatchToProps)(SearchBarView); \ No newline at end of file -- 2.30.2