SearchPage.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. // This is the root component for #search-page
  2. import React from 'react';
  3. import PropTypes from 'prop-types';
  4. import { translate } from 'react-i18next';
  5. import SearchPageForm from './SearchPage/SearchPageForm';
  6. import SearchResult from './SearchPage/SearchResult';
  7. class SearchPage extends React.Component {
  8. constructor(props) {
  9. super(props);
  10. this.state = {
  11. searchingKeyword: this.props.query.q || '',
  12. searchedKeyword: '',
  13. searchedPages: [],
  14. searchResultMeta: {},
  15. };
  16. this.search = this.search.bind(this);
  17. this.changeURL = this.changeURL.bind(this);
  18. }
  19. componentDidMount() {
  20. const keyword = this.state.searchingKeyword;
  21. if (keyword !== '') {
  22. this.search({ keyword });
  23. }
  24. }
  25. static getQueryByLocation(location) {
  26. const search = location.search || '';
  27. const query = {};
  28. search.replace(/^\?/, '').split('&').forEach((element) => {
  29. const queryParts = element.split('=');
  30. query[queryParts[0]] = decodeURIComponent(queryParts[1]).replace(/\+/g, ' ');
  31. });
  32. return query;
  33. }
  34. changeURL(keyword, refreshHash) {
  35. let hash = window.location.hash || '';
  36. // TODO 整理する
  37. if (refreshHash || this.state.searchedKeyword !== '') {
  38. hash = '';
  39. }
  40. if (window.history && window.history.pushState) {
  41. window.history.pushState('', `Search - ${keyword}`, `/_search?q=${keyword}${hash}`);
  42. }
  43. }
  44. search(data) {
  45. const keyword = data.keyword;
  46. if (keyword === '') {
  47. this.setState({
  48. searchingKeyword: '',
  49. searchedPages: [],
  50. searchResultMeta: {},
  51. });
  52. return true;
  53. }
  54. this.setState({
  55. searchingKeyword: keyword,
  56. });
  57. this.props.crowi.apiGet('/search', { q: keyword })
  58. .then((res) => {
  59. this.changeURL(keyword);
  60. this.setState({
  61. searchedKeyword: keyword,
  62. searchedPages: res.data,
  63. searchResultMeta: res.meta,
  64. });
  65. })
  66. .catch((err) => {
  67. // TODO error
  68. // this.setState({
  69. // });
  70. });
  71. }
  72. render() {
  73. return (
  74. <div>
  75. <div className="search-page-input">
  76. <SearchPageForm
  77. t={this.props.t}
  78. crowi={this.props.crowi}
  79. onSearchFormChanged={this.search}
  80. keyword={this.state.searchingKeyword}
  81. />
  82. </div>
  83. <SearchResult
  84. crowi={this.props.crowi}
  85. crowiRenderer={this.props.crowiRenderer}
  86. pages={this.state.searchedPages}
  87. searchingKeyword={this.state.searchingKeyword}
  88. searchResultMeta={this.state.searchResultMeta}
  89. />
  90. </div>
  91. );
  92. }
  93. }
  94. SearchPage.propTypes = {
  95. t: PropTypes.func.isRequired, // i18next
  96. crowi: PropTypes.object.isRequired,
  97. crowiRenderer: PropTypes.object.isRequired,
  98. query: PropTypes.object,
  99. };
  100. SearchPage.defaultProps = {
  101. // pollInterval: 1000,
  102. query: SearchPage.getQueryByLocation(window.location || {}),
  103. };
  104. export default translate()(SearchPage);