SearchPage.js 3.0 KB

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