Skip to content
Open

ht4 #48

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/AC/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {INCREMENT, DELETE_ARTICLE, CHANGE_DATE_RANGE, CHANGE_SELECTION} from '../constants'
import {INCREMENT, DELETE_ARTICLE, CHANGE_DATE_RANGE, CHANGE_SELECTION, ADD_COMMENT} from '../constants'

export function increment() {
return {
Expand Down Expand Up @@ -26,3 +26,10 @@ export function changeSelection(selected) {
payload: { selected }
}
}

export function addComment(comment, user, articleId) {
return {
type: ADD_COMMENT,
payload: { comment, user, articleId }
}
}
12 changes: 10 additions & 2 deletions src/components/article/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import CSSTransition from 'react-addons-css-transition-group'
import { connect } from 'react-redux'
import CommentList from '../comment-list'
import { deleteArticle } from '../../AC'
import { articleListSelector } from '../../selectors'

import './style.css'

class Article extends PureComponent {
Expand Down Expand Up @@ -58,7 +60,7 @@ function getBody(article) {
return (
<section className = "test__article--body">
{article.text}
<CommentList comments={article.comments}/>
<CommentList comments={article.comments} articleId={article.id} />
</section>
)
}
Expand All @@ -73,4 +75,10 @@ Article.propTypes = {
onButtonClick: PropTypes.func
}

export default connect(null, { deleteArticle })(Article)
export default connect(/*state => {
console.log('---', 'article connect')
console.log(this.props)
return {
article: articleListSelector(state)
}
}*/null, { deleteArticle })(Article)
15 changes: 13 additions & 2 deletions src/components/comment-list/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import PropTypes from 'prop-types'
import CSSTransition from 'react-addons-css-transition-group'
import Comment from '../comment'
import toggleOpen from '../../decorators/toggleOpen'
import { connect } from 'react-redux'
import { addComment } from '../../AC'
import './style.css'

class CommentList extends Component {
static defaultProps = {
comments: []
}

addComment
static propTypes = {
comments: PropTypes.array.isRequired,
//from toggleOpen decorator
Expand Down Expand Up @@ -51,6 +53,7 @@ class CommentList extends Component {

getComments() {
return (
<div>
<ul>
{
this.props.comments.map(id =>
Expand All @@ -59,9 +62,17 @@ class CommentList extends Component {
</li>)
}
</ul>
<button onClick = {this.handleAdd}>
add comment
</button>
</div>
)
}
handleAdd = () => {
const { addComment, comment, user, articleId } = this.props
addComment('comment', 'user', articleId)
}
}


export default toggleOpen(CommentList)
export default connect(null, { addComment })(toggleOpen(CommentList))
16 changes: 9 additions & 7 deletions src/components/filters/select.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,20 @@ import 'react-select/dist/react-select.css'

class SelectFilter extends Component {
static propTypes = {
articles: PropTypes.array.isRequired
articles: PropTypes.object.isRequired
};

handleChange = selected => this.props.changeSelection(selected.map(option => option.value))

render() {
const { articles, selected } = this.props
const options = articles.map(article => ({
label: article.title,
value: article.id
}))

const options = [];
for(var id in articles) {
options.push({
label: articles[id].title,
value: id
})
}
return <Select
options={options}
value={selected}
Expand All @@ -32,4 +34,4 @@ class SelectFilter extends Component {
export default connect(state => ({
selected: state.filters.selected,
articles: state.articles
}), { changeSelection })(SelectFilter)
}), { changeSelection })(SelectFilter)
3 changes: 2 additions & 1 deletion src/constants/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export const INCREMENT = 'INCREMENT'
export const DELETE_ARTICLE = 'DELETE_ARTICLE'

export const CHANGE_SELECTION = 'CHANGE_SELECTION'
export const CHANGE_DATE_RANGE = 'CHANGE_DATE_RANGE'
export const CHANGE_DATE_RANGE = 'CHANGE_DATE_RANGE'
export const ADD_COMMENT = 'ADD_COMMENT'
4 changes: 4 additions & 0 deletions src/middlewares/generateId.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export default store => next => action => {
if (action.type === 'ADD_COMMENT') action.payload.id = Math.random().toString(36).substring(7);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

через мидлвары будет проходить каждый экшин, они должны быть максимально общими, завязывать на конкретные экшины - не лучшее решение

  • лучше не мутировать payload, мало-ли что там станут передавать

next(action);
}
21 changes: 17 additions & 4 deletions src/reducer/articles.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
import { normalizedArticles as defaultArticles } from '../fixtures'
import { DELETE_ARTICLE } from '../constants'
import { normalizedArticles } from '../fixtures'
import { DELETE_ARTICLE, ADD_COMMENT } from '../constants'

const defaultArticles = normalizedArticles.reduce((acc, article) => ({
...acc,
[article.id]: article
})
, {})

export default (articlesState = defaultArticles, action) => {
const { type, payload } = action
let articlesStateObj;

switch (type) {
case ADD_COMMENT:
articlesStateObj = articlesState
articlesStateObj[payload.articleId].comments.push(payload.id)
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не мутируй стейт!

return articlesStateObj
case DELETE_ARTICLE:
return articlesState.filter(article => article.id !== payload.id)
articlesStateObj = articlesState
delete articlesStateObj[payload.id]
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

и тут не мутируй

return articlesStateObj

default:
return articlesState
}
}
}
15 changes: 13 additions & 2 deletions src/reducer/comments.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {} from '../constants'
import { normalizedComments } from '../fixtures'
import { ADD_COMMENT } from '../constants'

const defaultComments = normalizedComments.reduce((acc, comment) => ({
...acc,
Expand All @@ -8,11 +9,21 @@ const defaultComments = normalizedComments.reduce((acc, comment) => ({
, {})

export default (commentsState = defaultComments, action) => {
const {type} = action
const {type, payload} = action
let newCommentsState={};

switch (type) {

case ADD_COMMENT:
debugger;
newCommentsState = commentsState
newCommentsState[payload.id] = {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

и тут

id: payload.id,
user: payload.user,
text: payload.comment
}
return newCommentsState
default:
return commentsState
}
}
}
18 changes: 11 additions & 7 deletions src/selectors/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@ const idSelector = (_, props) => props.id
export const filtratedArticles = createSelector(articleListSelector, filtersSelector, (articles, filters) => {
const {selected, dateRange: {from, to}} = filters
console.log('---', 'recomputing filtration')

return articles.filter(article => {
const published = Date.parse(article.date)
return (!selected.length || selected.includes(article.id)) &&
(!from || !to || (published > from && published < to))
})
let filtratedArticlesArray = []
debugger;
for (const id in articles){
const published = Date.parse(articles[id].date)
if ((!selected.length || selected.includes(id)) &&
(!from || !to || (published > from && published < to))) {
filtratedArticlesArray.push(articles[id])
}
}
return filtratedArticlesArray
})

export const createCommentSelector = () => createSelector(commentsSelector, idSelector, (comments, id) => comments[id])
export const createCommentSelector = () => createSelector(commentsSelector, idSelector, (comments, id) => comments[id])
5 changes: 3 additions & 2 deletions src/store/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { createStore, applyMiddleware } from 'redux'
import reducer from '../reducer'
import logger from '../middlewares/logger'
import generateId from '../middlewares/generateId'

const enhancer = applyMiddleware(logger)
const enhancer = applyMiddleware(logger, generateId)

const store = createStore(reducer, enhancer)

//dev only, no need in prod
window.store = store

export default store
export default store