@atlaskit/global-search
Version:
A cross-product search component (batteries included)
196 lines (173 loc) • 6.16 kB
JavaScript
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import React from 'react';
import PreQueryState from './PreQueryState';
import { isEmpty } from '../SearchResultsUtil';
import { PostQueryAnalyticsComponent } from './ScreenAnalyticsHelper';
import ResultGroupsComponent, { ResultGroupType } from './ResultGroupsComponent';
import SearchError from '../SearchError';
import deepEqual from 'deep-equal';
export let SearchResultsState;
(function (SearchResultsState) {
SearchResultsState[SearchResultsState["PreQueryLoading"] = 0] = "PreQueryLoading";
SearchResultsState[SearchResultsState["PreQueryResults"] = 1] = "PreQueryResults";
SearchResultsState[SearchResultsState["PreQueryNoResults"] = 2] = "PreQueryNoResults";
SearchResultsState[SearchResultsState["PostQueryResults"] = 3] = "PostQueryResults";
SearchResultsState[SearchResultsState["PostQueryNoResults"] = 4] = "PostQueryNoResults";
SearchResultsState[SearchResultsState["IntermediateResults"] = 5] = "IntermediateResults";
SearchResultsState[SearchResultsState["IntermediateNoResults"] = 6] = "IntermediateNoResults";
})(SearchResultsState || (SearchResultsState = {}));
export const getSearchResultState = ({
isPreQuery,
isLoading,
hasResults
}) => {
if (isPreQuery) {
// Pre query
if (isLoading) {
return SearchResultsState.PreQueryLoading;
}
if (!hasResults) {
return SearchResultsState.PreQueryNoResults;
}
return SearchResultsState.PreQueryResults;
} else if (isLoading) {
// Intermediate
if (!hasResults) {
return SearchResultsState.IntermediateNoResults;
}
return SearchResultsState.IntermediateResults;
} else {
// Post query
if (!hasResults) {
return SearchResultsState.PostQueryNoResults;
}
return SearchResultsState.PostQueryResults;
}
};
export default class SearchResults extends React.Component {
shouldComponentUpdate(nextProps) {
return !deepEqual(nextProps, this.props);
}
hasNoResult() {
const {
isPreQuery,
isLoading,
keepPreQueryState,
getPreQueryGroups,
getPostQueryGroups
} = this.props;
const results = isPreQuery || isLoading && keepPreQueryState ? getPreQueryGroups() : getPostQueryGroups();
return results.map(({
items
}) => items).every(isEmpty);
}
renderNoResult() {
const {
renderNoResult,
postQueryScreenCounter,
searchSessionId,
referralContextIdentifiers
} = this.props;
return /*#__PURE__*/React.createElement(React.Fragment, null, renderNoResult(), /*#__PURE__*/React.createElement(PostQueryAnalyticsComponent, {
screenCounter: postQueryScreenCounter,
searchSessionId: searchSessionId,
referralContextIdentifiers: referralContextIdentifiers,
key: "post-query-analytics"
}));
}
renderPreQueryState() {
const {
searchSessionId,
preQueryScreenCounter,
renderNoRecentActivity,
referralContextIdentifiers,
renderBeforePreQueryState,
renderAdvancedSearchGroup,
getPreQueryGroups
} = this.props;
return /*#__PURE__*/React.createElement(React.Fragment, null, renderBeforePreQueryState && renderBeforePreQueryState(), /*#__PURE__*/React.createElement(PreQueryState, {
resultsGroups: getPreQueryGroups(),
renderNoRecentActivity: renderNoRecentActivity,
searchSessionId: searchSessionId,
screenCounter: preQueryScreenCounter,
referralContextIdentifiers: referralContextIdentifiers,
renderAdvancedSearchGroup: renderAdvancedSearchGroup
}));
}
renderSearchResultsState() {
const {
searchSessionId,
referralContextIdentifiers,
renderAdvancedSearchGroup,
getPostQueryGroups,
postQueryScreenCounter,
searchMore,
onSearchMoreAdvancedSearchClicked,
query,
getFilterComponent,
isLoading,
currentFilters,
onFilterChanged
} = this.props;
const resultGroups = getPostQueryGroups();
const topGroup = resultGroups.length > 0 ? resultGroups[0] : null;
return /*#__PURE__*/React.createElement(React.Fragment, null, topGroup && getFilterComponent({
latestSearchQuery: query,
searchResultsTotalSize: topGroup.totalSize,
isLoading,
searchSessionId,
currentFilters,
onFilterChanged
}), /*#__PURE__*/React.createElement(ResultGroupsComponent, {
query: query,
type: ResultGroupType.PostQuery,
renderAdvancedSearch: renderAdvancedSearchGroup,
resultsGroups: resultGroups,
searchSessionId: searchSessionId,
screenCounter: postQueryScreenCounter,
referralContextIdentifiers: referralContextIdentifiers,
onShowMoreClicked: searchMore || (() => {}),
onSearchMoreAdvancedSearchClicked: onSearchMoreAdvancedSearchClicked
}));
}
render() {
const {
isPreQuery,
isError,
isLoading,
retrySearch,
keepPreQueryState
} = this.props;
if (isError) {
return /*#__PURE__*/React.createElement(SearchError, {
onRetryClick: retrySearch
});
}
const searchResultState = getSearchResultState({
isPreQuery,
isLoading,
hasResults: !this.hasNoResult()
});
switch (searchResultState) {
case SearchResultsState.PreQueryLoading:
return null;
case SearchResultsState.PreQueryNoResults:
return this.renderPreQueryState();
case SearchResultsState.PreQueryResults:
return this.renderPreQueryState();
case SearchResultsState.IntermediateNoResults:
return keepPreQueryState ? this.renderPreQueryState() : null;
case SearchResultsState.IntermediateResults:
return keepPreQueryState ? this.renderPreQueryState() : this.renderSearchResultsState();
case SearchResultsState.PostQueryNoResults:
return this.renderNoResult();
case SearchResultsState.PostQueryResults:
return this.renderSearchResultsState();
default:
throw new Error('unhandled state');
}
}
}
_defineProperty(SearchResults, "defaultProps", {
getFilterComponent: () => null
});