Sotaro KARASAWA 9 лет назад
Родитель
Сommit
54a4d63f69

+ 4 - 0
lib/util/search.js

@@ -26,6 +26,10 @@ function SearchClient(crowi, esUri) {
   this.mappingFile = crowi.resourceDir + 'search/mappings.json';
 }
 
+SearchClient.prototype.checkESVersion = function() {
+  // TODO
+};
+
 SearchClient.prototype.registerUpdateEvent = function() {
   var pageEvent = this.crowi.event('page');
   pageEvent.on('create', this.syncPageCreated.bind(this))

+ 5 - 0
resource/css/_page_list.scss

@@ -29,6 +29,11 @@
       list-style: none;
       line-height: 1.8em;
 
+      .page-list-option {
+        float: right;
+        margin-left: 4px;
+      }
+
       .picture {
         width: 16px;
         height: 16px;

+ 6 - 2
resource/css/_search.scss

@@ -49,14 +49,18 @@
     nav {
       &.affix {
         top: 8px;
-        width: 25%;
+        width: 33.33333%;
         padding-right: 30px;
+        padding-bottom: 50px;
+        height: 100%;
+        overflow-y: scroll;
       }
       .nav {
 
         > li {
-          padding: 0px 8px;
+          padding: 0px 11px 0 8px;
           &.active {
+            padding: 0px 8px;
             border-right: solid 3px #666;
             background: #f0f0f0;
           }

+ 1 - 2
resource/js/components/Header/SearchBox.js

@@ -47,8 +47,7 @@ export default class SearchBox extends React.Component {
         });
       }
       // TODO error
-    })
-    .catch((res) => {
+    }).catch((res) => {
       // TODO error
       this.setState({
         searchError: res,

+ 1 - 0
resource/js/components/Header/SearchForm.js

@@ -46,6 +46,7 @@ export default class SearchForm extends React.Component {
         className="search-form form-group input-group search-top-input-group"
       >
         <input
+          autocomplete="off"
           type="text"
           className="search-top-input form-control"
           placeholder="Search ..."

+ 27 - 0
resource/js/components/Page/PageBody.js

@@ -0,0 +1,27 @@
+import React from 'react';
+
+export default class PageBody extends React.Component {
+  render() {
+    let body = this.props.pageBody;
+    if (body === '') {
+      body = this.props.page.revision.body;
+    }
+
+    return (
+      <div>
+        {body}
+      </div>
+    );
+  }
+}
+
+PageBody.propTypes = {
+  page: React.PropTypes.object.isRequired,
+  pageBody: React.PropTypes.string,
+};
+
+PageBody.defaultProps = {
+  page: {},
+  pageBody: '',
+};
+

+ 2 - 13
resource/js/components/PageList/ListView.js

@@ -1,23 +1,12 @@
 import React from 'react';
 
-import UserPicture from '../User/UserPicture';
-import PageListMeta from './PageListMeta';
-import PagePath from './PagePath';
+import Page from './Page';
 
 export default class ListView extends React.Component {
 
   render() {
     const listView = this.props.pages.map((page) => {
-
-      return (
-        <li className="page-list-li" key={page._id}>
-          <UserPicture user={page.revision.author} />
-          <a className="page-list-link" href={page.path}>
-            <PagePath page={page} />
-          </a>
-          <PageListMeta page={page} />
-        </li>
-      );
+      return <Page page={page} />;
     });
 
     return (

+ 38 - 0
resource/js/components/PageList/Page.js

@@ -0,0 +1,38 @@
+import React from 'react';
+
+import UserPicture from '../User/UserPicture';
+import PageListMeta from './PageListMeta';
+import PagePath from './PagePath';
+
+export default class Page extends React.Component {
+
+  render() {
+    const page = this.props.page;
+    let link = this.props.linkTo;
+    if (link === '') {
+      link = page.path;
+    }
+
+    return (
+      <li className="page-list-li">
+        {this.props.children}
+        <UserPicture user={page.revision.author} />
+        <a className="page-list-link" href={link}>
+          <PagePath page={page} />
+        </a>
+        <PageListMeta page={page} />
+      </li>
+    );
+  }
+}
+
+Page.propTypes = {
+  page: React.PropTypes.object.isRequired,
+  linkTo: React.PropTypes.string,
+};
+
+Page.defaultProps = {
+  page: {},
+  linkTo: '',
+};
+

+ 4 - 2
resource/js/components/Search/SearchPage.js

@@ -37,7 +37,6 @@ export default class SearchPage extends React.Component {
       query[queryParts[0]] = decodeURIComponent(queryParts[1]).replace(/\+/g, ' ');
     });
 
-    console.log(query);
     return query;
   }
 
@@ -83,7 +82,10 @@ export default class SearchPage extends React.Component {
           </header>
         </div>
 
-        <SearchResult pages={this.state.searchedPages} />
+        <SearchResult
+          pages={this.state.searchedPages}
+          searchingKeyword={this.state.searchingKeyword}
+          />
       </div>
     );
   }

+ 24 - 4
resource/js/components/Search/SearchResult.js

@@ -1,19 +1,39 @@
 import React from 'react';
 
+import Page from '../PageList/Page';
+import SearchResultList from './SearchResultList';
+
 // Search.SearchResult
 export default class SearchResult extends React.Component {
 
   render() {
 
+    const listView = this.props.pages.map((page) => {
+      const pageId = "#" + page._id;
+      return (
+        <Page page={page} linkTo={pageId}>
+          <div className="page-list-option">
+            <a href={page.path}><i className="fa fa-arrow-circle-right" /></a>
+          </div>
+        </Page>
+      );
+    });
 
     return (
       <div className="content-main" id="content-main">
         <div className="search-result row" id="search-result">
-          <div className="col-md-3 page-list search-result-list" id="search-result-list">
-          row
+          <div className="col-md-4 page-list search-result-list" id="search-result-list">
+            <nav data-spy="affix"  data-offset-top="120">
+              <ul className="page-list-ul nav">
+                {listView}
+              </ul>
+            </nav>
           </div>
-          <div className="col-md-9 search-result-content" id="search-result-content">
-          content
+          <div className="col-md-8 search-result-content" id="search-result-content">
+            <SearchResultList
+              pages={this.props.pages}
+              searchingKeyword={this.props.searchingKeyword}
+              />
           </div>
         </div>
       </div>

+ 60 - 0
resource/js/components/Search/SearchResultList.js

@@ -0,0 +1,60 @@
+import React from 'react';
+
+import PageBody from '../Page/PageBody.js';
+
+export default class SearchResultList extends React.Component {
+
+  constructor(props) {
+    super(props);
+
+    this.getHighlightBody = this.getHighlightBody.bind(this);
+  }
+
+  getHighlightBody(body) {
+    console.log('getHighlightBody', this.props.searchingKeyword);
+    console.log('getHighlightBody', this.props.searchingKeyword.split(' '));
+    this.props.searchingKeyword.split(' ').forEach((keyword) => {
+      console.log(keyword);
+      const keywordExp = new RegExp('(' + keyword + ')', 'g');
+      console.log(keywordExp);
+      console.log(body.repalce(keywordExp, 'hoge hoge'));
+      //body = body.repalce(keywordExp, '<span style="highlighted">$1</span>');
+    });
+
+    //console.log(this.props.searchingKeyword, body);
+    return body;
+  }
+
+  render() {
+    const resultList = this.props.pages.map((page) => {
+      const pageBody = this.getHighlightBody(page.revision.body);
+      //console.log('resultList.page.path', page.path);
+      //console.log('resultList.pageBody', pageBody);
+      return (
+        <div id={page._id}>
+          <h2>{page.path}</h2>
+          <div>
+            <PageBody page={page} pageBody={pageBody} />
+          </div>
+        </div>
+      );
+    });
+
+    return (
+      <div>
+      {resultList}
+      </div>
+    );
+  }
+}
+
+SearchResultList.propTypes = {
+  pages: React.PropTypes.array.isRequired,
+  searchingKeyword: React.PropTypes.string.isRequired,
+};
+
+SearchResultList.defaultProps = {
+  pages: [],
+  searchingKeyword: '',
+};
+