diff --git a/src/ac/index.js b/src/ac/index.js
index edf08ca..151396b 100644
--- a/src/ac/index.js
+++ b/src/ac/index.js
@@ -6,6 +6,7 @@ import {
ADD_COMMENT,
LOAD_ALL_ARTICLES,
LOAD_ARTICLE,
+ LOAD_ALL_COMMENTS,
START,
SUCCESS,
FAIL
@@ -46,6 +47,13 @@ export function addComment(comment, articleId) {
}
}
+export function loadAllComments(articleId) {
+ return {
+ type: LOAD_ALL_COMMENTS,
+ callAPI: `/api/comment?article=${articleId}`
+ }
+}
+
export function loadAllArticles() {
return {
type: LOAD_ALL_ARTICLES,
diff --git a/src/components/comment-list/index.js b/src/components/comment-list/index.js
index 30f2342..205c82f 100644
--- a/src/components/comment-list/index.js
+++ b/src/components/comment-list/index.js
@@ -1,10 +1,14 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
+import { connect } from 'react-redux'
import CSSTransition from 'react-addons-css-transition-group'
import Comment from '../comment'
import CommentForm from '../comment-form'
import toggleOpen from '../../decorators/toggleOpen'
import './style.css'
+import { commentsLoadingSelector, commentsSelector } from '../../selectors'
+import { loadAllComments } from '../../ac'
+import Loader from '../common/loader'
class CommentList extends Component {
static propTypes = {
@@ -40,8 +44,11 @@ class CommentList extends Component {
}
getBody() {
+ if (this.props.loading) return
+
const {
- article: { id, comments = [] },
+ article: { id },
+ comments = [],
isOpen
} = this.props
if (!isOpen) return null
@@ -61,14 +68,30 @@ class CommentList extends Component {
get comments() {
return (
- {this.props.article.comments.map((id) => (
- -
-
+ {this.props.comments.map((comment) => (
+
-
+
))}
)
}
+
+ componentDidUpdate(oldProps) {
+ const { isOpen, fetchData, comments = [], article } = this.props
+ if (!oldProps.isOpen && isOpen && !comments.length && fetchData)
+ fetchData(article.id)
+ }
+}
+
+const createMapStateToProps = () => {
+ return (state, ownProps) => ({
+ comments: commentsSelector(state, ownProps),
+ loading: commentsLoadingSelector(state)
+ })
}
-export default toggleOpen(CommentList)
+export default connect(
+ createMapStateToProps(),
+ { fetchData: loadAllComments }
+)(toggleOpen(CommentList))
diff --git a/src/constants/index.js b/src/constants/index.js
index 6266326..c1e13ce 100644
--- a/src/constants/index.js
+++ b/src/constants/index.js
@@ -8,6 +8,7 @@ export const CHANGE_SELECTION = 'CHANGE_SELECTION'
export const CHANGE_DATE_RANGE = 'CHANGE_DATE_RANGE'
export const ADD_COMMENT = 'ADD_COMMENT'
+export const LOAD_ALL_COMMENTS = 'LOAD_ALL_COMMENTS'
export const START = '_START'
export const SUCCESS = '_SUCCESS'
diff --git a/src/reducer/comments.js b/src/reducer/comments.js
index b88e10b..21f2d9b 100644
--- a/src/reducer/comments.js
+++ b/src/reducer/comments.js
@@ -1,19 +1,40 @@
-import { ADD_COMMENT } from '../constants'
-import { normalizedComments } from '../fixtures'
+import { ADD_COMMENT, LOAD_ALL_COMMENTS, START, SUCCESS } from '../constants'
+import { Record } from 'immutable'
import { arrToMap } from './utils'
-export default (state = arrToMap(normalizedComments), action) => {
- const { type, payload, randomId } = action
+const CommentRecord = Record({
+ id: null,
+ user: null,
+ text: null
+})
+
+const ReducerRecord = Record({
+ entities: arrToMap([], CommentRecord),
+ loading: false,
+ error: null
+})
+
+export default (state = new ReducerRecord(), action) => {
+ const { type, payload, randomId, response } = action
switch (type) {
case ADD_COMMENT:
- return {
- ...state,
- [randomId]: {
- ...payload.comment,
- id: randomId
- }
- }
+ return state.setIn(
+ ['entities', randomId],
+ new CommentRecord({
+ id: randomId,
+ user: payload.comment.user,
+ text: payload.comment.text
+ })
+ )
+
+ case LOAD_ALL_COMMENTS + START:
+ return state.set('loading', true)
+
+ case LOAD_ALL_COMMENTS + SUCCESS:
+ return state
+ .set('entities', arrToMap(response, CommentRecord))
+ .set('loading', false)
default:
return state
diff --git a/src/selectors/index.js b/src/selectors/index.js
index 8e5b7d0..4439254 100644
--- a/src/selectors/index.js
+++ b/src/selectors/index.js
@@ -8,7 +8,19 @@ export const articleListSelector = createSelector(
articlesMapSelector,
(articlesMap) => articlesMap.valueSeq().toArray()
)
-export const commentsSelector = (state) => state.comments
+export const commentsLoadingSelector = (state) => state.comments.loading
+export const commentsMapSelector = (state, props) => {
+ const commentsIdsList = props.article && props.article.get('comments')
+ return commentsIdsList
+ ? state.comments.entities.filter((comment) =>
+ commentsIdsList.includes(comment.id)
+ )
+ : state.comments.entities
+}
+export const commentsSelector = createSelector(
+ commentsMapSelector,
+ (commentsMap) => commentsMap.valueSeq().toArray()
+)
export const idSelector = (_, props) => props.id
export const filtratedArticlesSelector = createSelector(
@@ -31,6 +43,6 @@ export const filtratedArticlesSelector = createSelector(
)
export const createCommentSelector = () =>
- createSelector(commentsSelector, idSelector, (comments, id) => {
- return comments[id]
+ createSelector(commentsMapSelector, idSelector, (commentsMap, id) => {
+ return commentsMap.get(id)
})