Ivan - Add articles reducer and view article view [skip ci]
This commit is contained in:
parent
bbe7b0c3d5
commit
a193acd51a
|
@ -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: {}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
|
@ -1,7 +1,8 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import {connect} from 'react-redux';
|
||||||
|
|
||||||
import API from 'lib-app/api-call';
|
|
||||||
import i18n from 'lib-app/i18n';
|
import i18n from 'lib-app/i18n';
|
||||||
|
import ArticlesActions from 'actions/articles-actions';
|
||||||
|
|
||||||
import TopicViewer from 'app-components/topic-viewer';
|
import TopicViewer from 'app-components/topic-viewer';
|
||||||
import ModalContainer from 'app-components/modal-container';
|
import ModalContainer from 'app-components/modal-container';
|
||||||
|
@ -14,24 +15,21 @@ import Icon from 'core-components/icon';
|
||||||
class ArticlesList extends React.Component {
|
class ArticlesList extends React.Component {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
editable: React.PropTypes.bool
|
editable: React.PropTypes.bool,
|
||||||
|
loading: React.PropTypes.bool,
|
||||||
|
topics: React.PropTypes.array
|
||||||
};
|
};
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
editable: true
|
editable: true
|
||||||
};
|
};
|
||||||
|
|
||||||
state = {
|
|
||||||
loading: true,
|
|
||||||
topics: []
|
|
||||||
};
|
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.retrieveArticles();
|
this.retrieveArticles();
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (this.state.loading) ? <Loading /> : this.renderContent();
|
return (this.props.loading) ? <Loading /> : this.renderContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
renderContent() {
|
renderContent() {
|
||||||
|
@ -46,7 +44,7 @@ class ArticlesList extends React.Component {
|
||||||
renderTopics() {
|
renderTopics() {
|
||||||
return (
|
return (
|
||||||
<div className="articles-list__topics">
|
<div className="articles-list__topics">
|
||||||
{this.state.topics.map((topic, index) => {
|
{this.props.topics.map((topic, index) => {
|
||||||
return (
|
return (
|
||||||
<div key={index}>
|
<div key={index}>
|
||||||
<TopicViewer {...topic} editable={this.props.editable} onChange={this.retrieveArticles.bind(this)}/>
|
<TopicViewer {...topic} editable={this.props.editable} onChange={this.retrieveArticles.bind(this)}/>
|
||||||
|
@ -69,18 +67,13 @@ class ArticlesList extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
retrieveArticles() {
|
retrieveArticles() {
|
||||||
API.call({
|
this.props.dispatch(ArticlesActions.retrieveArticles());
|
||||||
path: '/article/get-all',
|
|
||||||
data: {}
|
|
||||||
}).then(this.onRetrieveSuccess.bind(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
onRetrieveSuccess(result) {
|
|
||||||
this.setState({
|
|
||||||
loading: false,
|
|
||||||
topics: result.data
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ArticlesList;
|
export default connect((store) => {
|
||||||
|
return {
|
||||||
|
topics: store.articles.topics,
|
||||||
|
loading: store.articles.loading
|
||||||
|
};
|
||||||
|
})(ArticlesList);
|
||||||
|
|
|
@ -1,14 +1,80 @@
|
||||||
import React from 'react';
|
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 {
|
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() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="admin-panel-view-article">
|
||||||
/admin/panel/articles/view-article
|
{(this.props.loading) ? <Loading /> : this.renderContent()}
|
||||||
</div>
|
</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);
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
.admin-panel-view-article {
|
||||||
|
|
||||||
|
&__last-edited {
|
||||||
|
font-style: italic;
|
||||||
|
text-align: right;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
}
|
|
@ -86,6 +86,7 @@ export default {
|
||||||
'COLOR': 'Color',
|
'COLOR': 'Color',
|
||||||
'ADD_NEW_ARTICLE': 'Add new article',
|
'ADD_NEW_ARTICLE': 'Add new article',
|
||||||
'ADD_ARTICLE': 'Add article',
|
'ADD_ARTICLE': 'Add article',
|
||||||
|
'LAST_EDITED_IN': 'Last edited in {date}',
|
||||||
|
|
||||||
//VIEW DESCRIPTIONS
|
//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.',
|
'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.',
|
||||||
|
|
|
@ -4,12 +4,14 @@ import { routerReducer } from 'react-router-redux';
|
||||||
import sessionReducer from 'reducers/session-reducer';
|
import sessionReducer from 'reducers/session-reducer';
|
||||||
import configReducer from 'reducers/config-reducer';
|
import configReducer from 'reducers/config-reducer';
|
||||||
import modalReducer from 'reducers/modal-reducer';
|
import modalReducer from 'reducers/modal-reducer';
|
||||||
|
import articlesReducer from 'reducers/articles-reducer';
|
||||||
import adminDataReducer from 'reducers/admin-data-reducer';
|
import adminDataReducer from 'reducers/admin-data-reducer';
|
||||||
|
|
||||||
export default combineReducers({
|
export default combineReducers({
|
||||||
session: sessionReducer,
|
session: sessionReducer,
|
||||||
config: configReducer,
|
config: configReducer,
|
||||||
modal: modalReducer,
|
modal: modalReducer,
|
||||||
|
articles: articlesReducer,
|
||||||
adminData: adminDataReducer,
|
adminData: adminDataReducer,
|
||||||
routing: routerReducer
|
routing: routerReducer
|
||||||
});
|
});
|
|
@ -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();
|
Loading…
Reference in New Issue