Ivan - Add search article list [skip ci]
This commit is contained in:
parent
c774df46f4
commit
b4b94a883e
|
@ -18,15 +18,19 @@ class ArticlesList extends React.Component {
|
|||
editable: React.PropTypes.bool,
|
||||
articlePath: React.PropTypes.string,
|
||||
loading: React.PropTypes.bool,
|
||||
topics: React.PropTypes.array
|
||||
topics: React.PropTypes.array,
|
||||
retrieveOnMount: React.PropTypes.bool
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
editable: true
|
||||
editable: true,
|
||||
retrieveOnMount: true
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.retrieveArticles();
|
||||
if(this.props.retrieveOnMount) {
|
||||
this.retrieveArticles();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import React from 'react';
|
||||
import _ from 'react';
|
||||
|
||||
import i18n from 'lib-app/i18n';
|
||||
import API from 'lib-app/api-call';
|
||||
|
@ -79,7 +80,7 @@ class AdminPanelBanUsers extends React.Component {
|
|||
|
||||
onSearch(query) {
|
||||
this.setState({
|
||||
filteredEmails: SearchBox.searchQueryInList(this.state.emails, query)
|
||||
filteredEmails: SearchBox.searchQueryInList(this.state.emails, query, _.startsWith, _.includes)
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,109 @@
|
|||
import React from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import _ from 'lodash';
|
||||
import {Link} from 'react-router';
|
||||
|
||||
import i18n from 'lib-app/i18n';
|
||||
import ArticlesList from 'app-components/articles-list';
|
||||
import ArticlesActions from 'actions/articles-actions';
|
||||
|
||||
import Header from 'core-components/header';
|
||||
import SearchBox from 'core-components/search-box';
|
||||
|
||||
class DashboardListArticlesPage extends React.Component {
|
||||
|
||||
state = {
|
||||
results: [],
|
||||
showSearchResults: false
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.props.dispatch(ArticlesActions.retrieveArticles());
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<div classnames="dashboard-list-articles-page">
|
||||
<Header title={i18n('LIST_ARTICLES')} description={i18n('LIST_ARTICLES_DESCRIPTION')}/>
|
||||
<ArticlesList editable={false} articlePath="/dashboard/article/"/>
|
||||
<SearchBox className="dashboard-list-articles-page__search-box" onSearch={this.onSearch.bind(this)} searchOnType />
|
||||
{(!this.state.showSearchResults) ? this.renderArticleList() : this.renderSearchResults()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderArticleList() {
|
||||
return (
|
||||
<ArticlesList editable={false} articlePath="/dashboard/article/" retrieveOnMount={false}/>
|
||||
);
|
||||
}
|
||||
|
||||
renderSearchResults() {
|
||||
return (
|
||||
<div className="dashboard-list-articles-page__search-results">
|
||||
{(_.isEmpty(this.state.results)) ? i18n('NO_RESULTS') : this.state.results.map(this.renderSearchResultsItem.bind(this))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderSearchResultsItem(item) {
|
||||
let content = this.stripHTML(item.content);
|
||||
content = content.substring(0, 100);
|
||||
content += '...';
|
||||
|
||||
return (
|
||||
<div className="dashboard-list-articles-page__search-result">
|
||||
<div className="dashboard-list-articles-page__search-result-title">
|
||||
<Link to={'/dashboard/article/' + item.id}>{item.title}</Link>
|
||||
</div>
|
||||
<div className="dashboard-list-articles-page__search-result-description">{content}</div>
|
||||
<div className="dashboard-list-articles-page__search-result-topic">{item.topic}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
onSearch(query) {
|
||||
this.setState({
|
||||
results: SearchBox.searchQueryInList(this.getArticles(), query, this.isQueryInTitle.bind(this), this.isQueryInContent.bind(this)),
|
||||
showSearchResults: query.length
|
||||
});
|
||||
}
|
||||
|
||||
getArticles() {
|
||||
let articles = [];
|
||||
|
||||
_.forEach(this.props.topics, (topic) => {
|
||||
_.forEach(topic.articles, (article) => {
|
||||
articles.push({
|
||||
id: article.id,
|
||||
title: article.title,
|
||||
content: article.content,
|
||||
topic: topic.name
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return articles;
|
||||
}
|
||||
|
||||
isQueryInTitle(article, query) {
|
||||
return _.includes(article.title.toLowerCase(), query.toLowerCase());
|
||||
}
|
||||
|
||||
isQueryInContent(article, query) {
|
||||
return _.includes(article.content.toLowerCase(), query.toLowerCase());
|
||||
}
|
||||
|
||||
stripHTML(html){
|
||||
let tmp = document.createElement('DIV');
|
||||
tmp.innerHTML = html;
|
||||
return tmp.textContent || tmp.innerText || "";
|
||||
}
|
||||
}
|
||||
|
||||
export default DashboardListArticlesPage;
|
||||
|
||||
export default connect((store) => {
|
||||
return {
|
||||
topics: store.articles.topics,
|
||||
loading: store.articles.loading
|
||||
};
|
||||
})(DashboardListArticlesPage);
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
@import "../../../../scss/vars";
|
||||
|
||||
.dashboard-list-articles-page {
|
||||
|
||||
&__search-results {
|
||||
|
||||
}
|
||||
|
||||
&__search-box {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
&__search-result {
|
||||
margin-bottom: 20px;
|
||||
text-align: left;
|
||||
|
||||
&-title {
|
||||
|
||||
}
|
||||
|
||||
&-description {
|
||||
font-size: $font-size--xs;
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
&-topic {
|
||||
color: $grey;
|
||||
font-size: $font-size--sm;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import _ from 'lodash';
|
||||
|
||||
import Input from 'core-components/input';
|
||||
import Icon from 'core-components/icon';
|
||||
|
@ -8,12 +7,12 @@ import keyCode from 'keycode';
|
|||
|
||||
class SearchBox extends React.Component {
|
||||
|
||||
static searchQueryInList(list, query) {
|
||||
static searchQueryInList(list, query, startsWith, includes) {
|
||||
let match = [];
|
||||
let rest = [];
|
||||
|
||||
list.forEach(function (item) {
|
||||
if(_.startsWith(item, query)) {
|
||||
if(startsWith(item, query)) {
|
||||
match.push(item);
|
||||
} else {
|
||||
rest.push(item);
|
||||
|
@ -21,7 +20,7 @@ class SearchBox extends React.Component {
|
|||
});
|
||||
|
||||
rest.forEach(function (item) {
|
||||
if(_.includes(item, query)) {
|
||||
if(includes(item, query)) {
|
||||
match.push(item);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -92,6 +92,7 @@ export default {
|
|||
'ADD_ARTICLE': 'Add article',
|
||||
'LAST_EDITED_IN': 'Last edited in {date}',
|
||||
'EDIT': 'Edit',
|
||||
'NO_RESULTS': 'No results',
|
||||
|
||||
//VIEW DESCRIPTIONS
|
||||
'CREATE_TICKET_DESCRIPTION': 'This is a form for creating tickets. Fill the form and send us your issues/doubts/suggestions. Our support system will answer it as soon as possible.',
|
||||
|
|
Loading…
Reference in New Issue