-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
issue-108: Add saved search feature #110
Conversation
@nikhilj13, the notes on this PR are fantastic. Can you create an answer page and copy this info there? I'd hate to lose track of this functionality. |
|
||
declare var webkitSpeechRecognition: any; // Prevent complaints about this not existing | ||
|
||
type SearchBarProps = { | ||
history: PropTypes.object.isRequired; | ||
location: PropTypes.object.isRequired; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we make the location
required this would become a breaking change. Can you refactor things a bit to make this optional?
Update: withRouter
is already included in this component, so making use of an additional prop it provides is not a breaking change. This is fine.
/** Optional, specifies the workflow that should be used for querying the index which stores saved searches */ | ||
savedSearchWorkflow?: string; | ||
/** Optional, specifies the table name assigned to the docs for saved searches, defaults to 'savedSearches' */ | ||
savedSearchTable: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indicate this is optional in flow:
savedSearchTable?: string;
/** Optional, specifies the table name assigned to the docs for saved searches, defaults to 'savedSearches' */ | ||
savedSearchTable: string; | ||
/** Specifies the zone name for the zone that stores saved searches, defaults to 'savedSearches' */ | ||
savedSearchZone: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this optional?
savedSearchZone?: string;
|
||
// populates the saved searches in the saved searches drop down | ||
populateSavedSearches() { | ||
const response = this.state.response; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer desctructuring.
const { response } = this.state;
if (response) { | ||
this.setState( | ||
{ | ||
response, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you create a class for the response in the api directory
and move the formatting you do later on into it to be used here?
@@ -54,6 +64,14 @@ type SearchBarProps = { | |||
buttonLabel: string; | |||
/** If set, this is the route to navigate to upon executing a search. By default, no navigation will occur when searching. */ | |||
route: string | null; | |||
/** If set, the save search option is displayed next to the SearchBar, false by default */ | |||
allowSavedSearch: boolean; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New props should be optional for backwards compatibility.
allowSavedSearch?: boolean;
savedSearch.title = htmlString.replace(/<[^>]+>/g, ''); | ||
savedSearch.query = doc.getFirstValue('query_s'); | ||
savedSearch.queryString = doc.getFirstValue('query_string_s'); | ||
let savedSearchTitle = savedSearch.title; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const savedSearchTitle = savedSearch.title > 15 ? `${savedSearch.title.substring(0, 15)}...` : savedSearch.title;
substring()
does not modify the original string, it returns a brand new string, so it's safe to use the original string.
</MenuItem>, | ||
); | ||
}); | ||
this.setState({ savedSearchList: menuItemList }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Storing jsx as state is generally considered bad practice. It's usually an indicator that you need to refactor your component, break out a function, or create a building block component.
https://reactjs.org/docs/thinking-in-react.html#step-3-identify-the-minimal-but-complete-representation-of-ui-state
@@ -223,6 +357,44 @@ class SearchBar extends React.Component<SearchBarDefaultProps, SearchBarProps, S | |||
} | |||
} | |||
|
|||
// saves the current search from the url and feed it to a separate index zone | |||
saveThisSearch(searcherState) { | |||
const searcher = this.context.searcher; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer destructuring:
const { searcher } = this.context;
const username = AuthUtils.getLoggedInUserId(); | ||
const loggedDateTime = new Date().toISOString(); | ||
const id = username.concat(loggedDateTime); | ||
const title = this.state.savedSearchTitle; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Place this at the top of the function somewhere above line 364
. Prefer destructuring:
const { savedSearchTitle: title } = this.state;
+ `[ "${title}" ], "query_s" : [ "${currentSearch}" ], "query_string_s" : [ "${queryString}" ], ` | ||
+ `"username_s" : [ "${username}" ], "date" : [ "${loggedDateTime}" ], "table" : [ "${savedSearchTable}" ] }, ` | ||
+ `"id" : "${id}", "zone" : "${savedSearchZone}" }`; | ||
searcher.search.updateSavedSearches(JSON.parse(jsonDoc), this.getSavedSearches); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Response parsing should be done in a class.
</MenuItem> | ||
); | ||
|
||
const saveQuery = this.props.allowSavedSearch ? ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this to out's own render function. Same with the other saved variables.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Address comments.
Save searches
Save search feature allows you to save your search (including any filters that are applied) which can later be revisited by clicking on the saved search title. This feature is disabled by default.
How to enable save search
You can turn on the save search option by passing in an additional prop to SearchBar component, this prop is called allowSavedSearch. For example:
This would show a heart icon with a drop down next to the Search Bar, which means the UI component for saved search is enabled.
Configuring a new zone to store the saved searches
Follow these steps to configure a new zone for storing the saved searches:
Zones are configured via the Index Feature, in [project-dir]\conf\features\core\Index.index.xml. It should look similar to:
Edit this file to add in a new index zone. For example, we're creating a new index zone called testZone in the example below:
How to use saved searches
After you enable and configure saved searches, you should have this component right next to the search bar:
![SavedSearch](https://user-images.githubusercontent.com/31805650/56602139-cdad5a00-65ca-11e9-9ee8-0744cc3de6cc.gif)
Saving a search
You can save searches by clicking on the first option in the drop-down menu 'SAVE SEARCH'. It will open up a modal that asks for the name for this search.
![Save a search](https://user-images.githubusercontent.com/31805650/56602446-7956aa00-65cb-11e9-975b-e5f2d1ee4ebc.gif)
Click on save search button to save the search.
Revisiting a search
You can revisit a search by clicking on the search title in the drop-down for saved search.
![Revisit a search](https://user-images.githubusercontent.com/31805650/56602470-8378a880-65cb-11e9-8e25-d04818424108.gif)
Deleting a saved search
You can also delete a saved search, there's a x next to every saved search in the drop-down. Simply click on the x to delete a saved search.
![Delete a search](https://user-images.githubusercontent.com/31805650/56602482-8a072000-65cb-11e9-9821-7852ce27dfcb.gif)