Ivan - Add articles reducer and view article view [skip ci]

This commit is contained in:
ivan 2016-12-02 07:38:02 -03:00
parent bbe7b0c3d5
commit a193acd51a
7 changed files with 163 additions and 24 deletions

View File

@ -0,0 +1,21 @@
import API from 'lib-app/api-call';
export default {
initArticles() {
return {
type: 'INIT_ARTICLES',
payload: {}
};
},
retrieveArticles() {
return {
type: 'GET_ARTICLES',
payload: API.call({
path: '/article/get-all',
data: {}
})
};
}
};

View File

@ -1,7 +1,8 @@
import React from 'react';
import {connect} from 'react-redux';
import API from 'lib-app/api-call';
import i18n from 'lib-app/i18n';
import ArticlesActions from 'actions/articles-actions';
import TopicViewer from 'app-components/topic-viewer';
import ModalContainer from 'app-components/modal-container';
@ -14,24 +15,21 @@ import Icon from 'core-components/icon';
class ArticlesList extends React.Component {
static propTypes = {
editable: React.PropTypes.bool
editable: React.PropTypes.bool,
loading: React.PropTypes.bool,
topics: React.PropTypes.array
};
static defaultProps = {
editable: true
};
state = {
loading: true,
topics: []
};
componentDidMount() {
this.retrieveArticles();
}
render() {
return (this.state.loading) ? <Loading /> : this.renderContent();
return (this.props.loading) ? <Loading /> : this.renderContent();
}
renderContent() {
@ -46,7 +44,7 @@ class ArticlesList extends React.Component {
renderTopics() {
return (
<div className="articles-list__topics">
{this.state.topics.map((topic, index) => {
{this.props.topics.map((topic, index) => {
return (
<div key={index}>
<TopicViewer {...topic} editable={this.props.editable} onChange={this.retrieveArticles.bind(this)}/>
@ -69,18 +67,13 @@ class ArticlesList extends React.Component {
}
retrieveArticles() {
API.call({
path: '/article/get-all',
data: {}
}).then(this.onRetrieveSuccess.bind(this));
}
onRetrieveSuccess(result) {
this.setState({
loading: false,
topics: result.data
});
this.props.dispatch(ArticlesActions.retrieveArticles());
}
}
export default ArticlesList;
export default connect((store) => {
return {
topics: store.articles.topics,
loading: store.articles.loading
};
})(ArticlesList);

View File

@ -1,14 +1,80 @@
import React from 'react';
import _ from 'lodash';
import {connect} from 'react-redux';
import ArticlesActions from 'actions/articles-actions';
import SessionStore from 'lib-app/session-store';
import i18n from 'lib-app/i18n';
import DateTransformer from 'lib-core/date-transformer';
import Header from 'core-components/header';
import Loading from 'core-components/loading';
class AdminPanelViewArticle extends React.Component {
static propTypes = {
topics: React.PropTypes.array,
loading: React.PropTypes.bool
};
static defaultProps = {
topics: [],
loading: true
};
componentDidMount() {
if(SessionStore.getItem('topics')) {
this.props.dispatch(ArticlesActions.initArticles());
} else {
this.props.dispatch(ArticlesActions.retrieveArticles());
}
}
render() {
return (
<div>
/admin/panel/articles/view-article
<div className="admin-panel-view-article">
{(this.props.loading) ? <Loading /> : this.renderContent()}
</div>
);
}
renderContent() {
let article = this.findArticle();
return (article) ? this.renderArticle(article) : i18n('ARTICLE_NOT_FOUND');
}
renderArticle(article) {
return (
<div className="admin-panel-view-article__article">
<Header title={article.title}/>
<div className="admin-panel-view-article__content">
<div dangerouslySetInnerHTML={{__html: article.content}}/>
</div>
<div className="admin-panel-view-article__last-edited">
{i18n('LAST_EDITED_IN', {date: DateTransformer.transformToString(article.lastEdited)})}
</div>
</div>
);
}
findArticle() {
let article = null;
_.forEach(this.props.topics, (topic) => {
if(!article) {
article = _.find(topic.articles, {id: this.props.params.articleId * 1});
}
});
return article;
}
}
export default AdminPanelViewArticle;
export default connect((store) => {
return {
topics: store.articles.topics,
loading: store.articles.loading
};
})(AdminPanelViewArticle);

View File

@ -0,0 +1,8 @@
.admin-panel-view-article {
&__last-edited {
font-style: italic;
text-align: right;
margin-top: 20px;
}
}

View File

@ -86,6 +86,7 @@ export default {
'COLOR': 'Color',
'ADD_NEW_ARTICLE': 'Add new article',
'ADD_ARTICLE': 'Add article',
'LAST_EDITED_IN': 'Last edited in {date}',
//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.',

View File

@ -4,12 +4,14 @@ import { routerReducer } from 'react-router-redux';
import sessionReducer from 'reducers/session-reducer';
import configReducer from 'reducers/config-reducer';
import modalReducer from 'reducers/modal-reducer';
import articlesReducer from 'reducers/articles-reducer';
import adminDataReducer from 'reducers/admin-data-reducer';
export default combineReducers({
session: sessionReducer,
config: configReducer,
modal: modalReducer,
articles: articlesReducer,
adminData: adminDataReducer,
routing: routerReducer
});

View File

@ -0,0 +1,48 @@
import _ from 'lodash';
import Reducer from 'reducers/reducer';
import SessionStore from 'lib-app/session-store';
class ArticlesReducer extends Reducer {
getInitialState() {
return {
retrieved: false,
loading: true,
topics: []
};
}
getTypeHandlers() {
return {
'GET_ARTICLES_FULFILLED': this.onArticlesRetrieved,
'INIT_ARTICLES': this.onInitArticles
};
}
onArticlesRetrieved(state, payload) {
SessionStore.setItem('topics', JSON.stringify(payload.data));
return _.extend({}, state, {
retrieved: true,
loading: false,
topics: payload.data
});
}
onInitArticles(state) {
let topics = SessionStore.getItem('topics');
if(topics) {
topics = JSON.parse(topics);
}
return _.extend({}, state, {
retrieved: !!topics,
loading: false,
topics: topics
});
}
}
export default ArticlesReducer.getInstance();