|
|
@@ -28,20 +28,25 @@ class SearchPage extends React.Component {
|
|
|
this.state = {
|
|
|
searchingKeyword: decodeURI(this.props.query.q) || '',
|
|
|
searchedKeyword: '',
|
|
|
- searchedPages: [],
|
|
|
+ searchResults: [],
|
|
|
searchResultMeta: {},
|
|
|
- selectedPage: null,
|
|
|
+ focusedSearchResultData: null,
|
|
|
selectedPages: new Set(),
|
|
|
+ searchResultCount: 0,
|
|
|
+ activePage: 1,
|
|
|
+ pagingLimit: 10, // change to an appropriate limit number
|
|
|
excludeUsersHome: true,
|
|
|
excludeTrash: true,
|
|
|
};
|
|
|
|
|
|
this.changeURL = this.changeURL.bind(this);
|
|
|
this.search = this.search.bind(this);
|
|
|
+ this.searchHandler = this.searchHandler.bind(this);
|
|
|
this.selectPage = this.selectPage.bind(this);
|
|
|
this.toggleCheckBox = this.toggleCheckBox.bind(this);
|
|
|
this.onExcludeUsersHome = this.onExcludeUsersHome.bind(this);
|
|
|
this.onExcludeTrash = this.onExcludeTrash.bind(this);
|
|
|
+ this.onPagingNumberChanged = this.onPagingNumberChanged.bind(this);
|
|
|
}
|
|
|
|
|
|
componentDidMount() {
|
|
|
@@ -96,13 +101,34 @@ class SearchPage extends React.Component {
|
|
|
return query;
|
|
|
}
|
|
|
|
|
|
- search(data) {
|
|
|
+ /**
|
|
|
+ * this method is called when user changes paging number
|
|
|
+ */
|
|
|
+ async onPagingNumberChanged(activePage) {
|
|
|
+ // this.setState does not change the state immediately and following calls of this.search outside of this.setState will have old activePage state.
|
|
|
+ // To prevent above, pass this.search as a callback function to make sure this.search will have the latest activePage state.
|
|
|
+ this.setState({ activePage }, () => this.search({ keyword: this.state.searchedKeyword }));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * this method is called when user searches by pressing Enter or using searchbox
|
|
|
+ */
|
|
|
+ async searchHandler(data) {
|
|
|
+ // this.setState does not change the state immediately and following calls of this.search outside of this.setState will have old activePage state.
|
|
|
+ // To prevent above, pass this.search as a callback function to make sure this.search will have the latest activePage state.
|
|
|
+ this.setState({ activePage: 1 }, () => this.search(data));
|
|
|
+ }
|
|
|
+
|
|
|
+ async search(data) {
|
|
|
const keyword = data.keyword;
|
|
|
if (keyword === '') {
|
|
|
this.setState({
|
|
|
searchingKeyword: '',
|
|
|
- searchedPages: [],
|
|
|
+ searchedKeyword: '',
|
|
|
+ searchResults: [],
|
|
|
searchResultMeta: {},
|
|
|
+ searchResultCount: 0,
|
|
|
+ activePage: 1,
|
|
|
});
|
|
|
|
|
|
return true;
|
|
|
@@ -111,37 +137,48 @@ class SearchPage extends React.Component {
|
|
|
this.setState({
|
|
|
searchingKeyword: keyword,
|
|
|
});
|
|
|
- this.props.appContainer.apiGet('/search', { q: this.createSearchQuery(keyword) })
|
|
|
- .then((res) => {
|
|
|
- this.changeURL(keyword);
|
|
|
- if (res.data.length > 0) {
|
|
|
- this.setState({
|
|
|
- searchedKeyword: keyword,
|
|
|
- searchedPages: res.data,
|
|
|
- searchResultMeta: res.meta,
|
|
|
- selectedPage: res.data[0],
|
|
|
- });
|
|
|
- }
|
|
|
- else {
|
|
|
- this.setState({
|
|
|
- searchedKeyword: keyword,
|
|
|
- searchedPages: [],
|
|
|
- searchResultMeta: {},
|
|
|
- selectedPage: null,
|
|
|
- });
|
|
|
- }
|
|
|
- })
|
|
|
- .catch((err) => {
|
|
|
- toastError(err);
|
|
|
+ const pagingLimit = this.state.pagingLimit;
|
|
|
+ const offset = (this.state.activePage * pagingLimit) - pagingLimit;
|
|
|
+ try {
|
|
|
+ const res = await this.props.appContainer.apiGet('/search', {
|
|
|
+ q: this.createSearchQuery(keyword),
|
|
|
+ limit: pagingLimit,
|
|
|
+ offset,
|
|
|
});
|
|
|
+ this.changeURL(keyword);
|
|
|
+ if (res.data.length > 0) {
|
|
|
+ this.setState({
|
|
|
+ searchedKeyword: keyword,
|
|
|
+ searchResults: res.data,
|
|
|
+ searchResultMeta: res.meta,
|
|
|
+ searchResultCount: res.meta.total,
|
|
|
+ focusedSearchResultData: res.data[0],
|
|
|
+ // reset active page if keyword changes, otherwise set the current state
|
|
|
+ activePage: this.state.searchedKeyword === keyword ? this.state.activePage : 1,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ this.setState({
|
|
|
+ searchedKeyword: keyword,
|
|
|
+ searchResults: [],
|
|
|
+ searchResultMeta: {},
|
|
|
+ searchResultCount: 0,
|
|
|
+ focusedSearchResultData: {},
|
|
|
+ activePage: 1,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (err) {
|
|
|
+ toastError(err);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
selectPage= (pageId) => {
|
|
|
- const index = this.state.searchedPages.findIndex((page) => {
|
|
|
- return page._id === pageId;
|
|
|
+ const index = this.state.searchResults.findIndex(({ pageData }) => {
|
|
|
+ return pageData._id === pageId;
|
|
|
});
|
|
|
this.setState({
|
|
|
- selectedPage: this.state.searchedPages[index],
|
|
|
+ focusedSearchResultData: this.state.searchResults[index],
|
|
|
});
|
|
|
}
|
|
|
|
|
|
@@ -159,7 +196,7 @@ class SearchPage extends React.Component {
|
|
|
<SearchResultContent
|
|
|
appContainer={this.props.appContainer}
|
|
|
searchingKeyword={this.state.searchingKeyword}
|
|
|
- selectedPage={this.state.selectedPage}
|
|
|
+ focusedSearchResultData={this.state.focusedSearchResultData}
|
|
|
>
|
|
|
</SearchResultContent>
|
|
|
);
|
|
|
@@ -168,14 +205,16 @@ class SearchPage extends React.Component {
|
|
|
renderSearchResultList = () => {
|
|
|
return (
|
|
|
<SearchResultList
|
|
|
- pages={this.state.searchedPages}
|
|
|
- deletionMode={false}
|
|
|
- selectedPage={this.state.selectedPage}
|
|
|
- selectedPages={this.state.selectedPages}
|
|
|
+ pages={this.state.searchResults || []}
|
|
|
+ focusedSearchResultData={this.state.focusedSearchResultData}
|
|
|
+ selectedPages={this.state.selectedPages || []}
|
|
|
+ searchResultCount={this.state.searchResultCount}
|
|
|
+ activePage={this.state.activePage}
|
|
|
+ pagingLimit={this.state.pagingLimit}
|
|
|
onClickInvoked={this.selectPage}
|
|
|
onChangedInvoked={this.toggleCheckBox}
|
|
|
- >
|
|
|
- </SearchResultList>
|
|
|
+ onPagingNumberChanged={this.onPagingNumberChanged}
|
|
|
+ />
|
|
|
);
|
|
|
}
|
|
|
|
|
|
@@ -184,7 +223,7 @@ class SearchPage extends React.Component {
|
|
|
<SearchControl
|
|
|
searchingKeyword={this.state.searchingKeyword}
|
|
|
appContainer={this.props.appContainer}
|
|
|
- onSearchInvoked={this.search}
|
|
|
+ onSearchInvoked={this.searchHandler}
|
|
|
onExcludeUsersHome={this.onExcludeUsersHome}
|
|
|
onExcludeTrash={this.onExcludeTrash}
|
|
|
>
|