Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | import React from 'react' import { Card } from 'reactstrap' import { withTranslation, WithTranslation } from 'react-i18next' import queryString from 'query-string' import Icon, { IconName } from 'components/Common/Icon' import ListView from 'components/PageList/ListView' import RecentlyViewedPageList from './RecentlyViewedPageList' import { Page } from 'client/types/crowi' import Crowi from 'client/util/Crowi' interface Props extends WithTranslation { searchedPages: { portalPages?: [] publicPages?: [] userPages?: [] } searchingKeyword: string searching: boolean searchError: Error | null focused: boolean crowi: Crowi } class SearchSuggest extends React.Component<Props> { static defaultProps = { searchedPages: {}, searchingKeyword: '', searchError: null, searching: false, focused: false, } constructor(props: Props) { super(props) this.buildSearchUrl = this.buildSearchUrl.bind(this) this.renderList = this.renderList.bind(this) } buildSearchUrl(type: string) { const q = this.props.searchingKeyword const query = queryString.stringify({ q, type }) return `/_search?${query}` } getNumberOfResults() { const { searchedPages } = this.props const groupedPages = Object.values(searchedPages) const sum = (array: any[]): number => array.reduce((p, c) => p + c, 0) return sum(groupedPages.map((r = []) => r.length)) } renderList(title: string, icon: IconName, type: string, pages?: Page[]) { const { t } = this.props return ( pages && pages.length > 0 && ( <div className="grouped-page-list" key={type}> <h6> <Icon name={icon} /> <span className="title">{title}</span> <a className="more text-muted" href={this.buildSearchUrl(type)}> {t('search.suggest.more')} <Icon name="chevronRight" /> </a> </h6> <ListView pages={pages} /> </div> ) ) } renderBody() { const { t, searching, searchError, searchedPages, searchingKeyword } = this.props const numberOfResults = this.getNumberOfResults() const { portalPages, publicPages, userPages } = searchedPages if (searchingKeyword === '') { return <RecentlyViewedPageList crowi={this.props.crowi} /> } if (searching) { return ( <div> <Icon name="loading" spin /> Searching ... </div> ) } if (searchError !== null) { return ( <div> <Icon name="alert" /> Error on searching. </div> ) } if (numberOfResults === 0) { return <div>No results for "{searchingKeyword}".</div> } return [ this.renderList(t('page_types.portal'), 'fileDocumentBoxMultipleOutline', 'portal', portalPages), this.renderList(t('page_types.public'), 'fileDocumentBoxOutline', 'public', publicPages), this.renderList(t('page_types.user'), 'account', 'user', userPages), ] } render() { const { focused } = this.props if (!focused) { return <div /> } return ( <Card body className="search-suggest" id="search-suggest"> {this.renderBody()} </Card> ) } } export default withTranslation()(SearchSuggest) |