Skip to content
Open

HT5 #77

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({id, user, text, targetArticle}) {
return {
type: ADD_COMMENT,
payload: { id, user, text, targetArticle }
}
}
14 changes: 11 additions & 3 deletions src/components/Article/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import CSSTransition from 'react-addons-css-transition-group'
import {connect} from 'react-redux'
import CommentList from '../CommentList'
import {deleteArticle} from '../../AC'
import {createArticleSelector} from '../../selectors'
import './style.css'

class Article extends PureComponent {
Expand Down Expand Up @@ -33,7 +34,7 @@ class Article extends PureComponent {
const body = isOpen && (
<div>
<section>{article.text}</section>
<CommentList comments = {article.comments} ref = {this.setCommentsRef} key = {this.state.count}/>
<CommentList targetArticle = {article.id} comments = {article.comments} ref = {this.setCommentsRef} key = {this.state.count}/>
</div>
)
return (
Expand Down Expand Up @@ -85,5 +86,12 @@ class Article extends PureComponent {

}


export default connect(null, { deleteArticle })(Article)
const createMapStateToProps = () => {
const articleSelector = createArticleSelector()
return (state, ownProps) => {
return {
article: articleSelector(state, ownProps)
}
}
}
export default connect(createMapStateToProps, { deleteArticle })(Article)
8 changes: 4 additions & 4 deletions src/components/ArticleList.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ class ArticleList extends Accordion {
console.log('---', 'rerendering article list')
const {articles} = this.props
if (!articles.length) return <h3>No Articles</h3>
const articleElements = articles.map((article) => <li key={article.id}>
<Article article={article}
isOpen={article.id === this.state.openItemId}
toggleOpen={this.toggleOpenItemMemoized(article.id)}
const articleElements = articles.map(({id}) => <li key={id}>
<Article id={id}
Copy link
Owner

Choose a reason for hiding this comment

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

Не понял зачем это

isOpen={id === this.state.openItemId}
toggleOpen={this.toggleOpenItemMemoized(id)}
/>
</li>)
return (
Expand Down
13 changes: 12 additions & 1 deletion src/components/CommentForm/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import React, { Component } from 'react'
import {connect} from 'react-redux'
import {addComment} from '../../AC'

import './style.css'

class CommentForm extends Component {
Expand Down Expand Up @@ -26,6 +29,14 @@ class CommentForm extends Component {

handleSubmit = ev => {
ev.preventDefault()

const {addComment} = this.props;
addComment({
user: this.state.user,
text: this.state.text,
targetArticle: this.props.targetArticle
});

this.setState({
user: '',
text: ''
Expand Down Expand Up @@ -58,4 +69,4 @@ const limits = {
}
}

export default CommentForm
export default connect(null, { addComment })(CommentForm)
8 changes: 6 additions & 2 deletions src/components/CommentList.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ class CommentList extends Component {
//from toggleOpen decorator
isOpen: PropTypes.bool,
toggleOpen: PropTypes.func
}
};

static defaultProps = {
comments: []
};

render() {
const {isOpen, toggleOpen} = this.props
Expand All @@ -36,7 +40,7 @@ class CommentList extends Component {
return (
<div>
{body}
<CommentForm />
<CommentForm targetArticle = {this.props.targetArticle}/>
</div>
)
}
Expand Down
10 changes: 6 additions & 4 deletions src/components/Filters/Select.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,18 @@ 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
// console.log(articles)

const options = Object.values(articles).map(({title, id}) => ({
Copy link
Owner

Choose a reason for hiding this comment

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

Лучше селектор, который достанет из в виде массива

label: title,
value: id
}))

return <Select
Expand Down
4 changes: 3 additions & 1 deletion src/constants/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ 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'
11 changes: 11 additions & 0 deletions src/middlewares/randomizer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {ADD_COMMENT} from '../constants'

const generateRandomId = (num = 10, str = '') => num ? generateRandomId(num - 1, str += String.fromCharCode(Math.round(Math.random() * 25) + 65)) : str;
// можно добавить проверку на id, чтобы не было повторений, но это потом

export default store => next => action => {
if (action.type === ADD_COMMENT) {
Copy link
Owner

Choose a reason for hiding this comment

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

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

action.payload.id = generateRandomId();
Copy link
Owner

Choose a reason for hiding this comment

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

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

}
next(action)
}
28 changes: 23 additions & 5 deletions src/reducer/articles.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,31 @@
import { DELETE_ARTICLE } from '../constants'
import { DELETE_ARTICLE, ADD_COMMENT } from '../constants'
import {normalizedArticles as defaultArticles} from '../fixtures'

export default (articlesState = defaultArticles, action) => {
const { type, payload } = action
const articlesMap = defaultArticles.reduce((acc, article) => (
article.comments = article.comments || [],
{...acc, [article.id]: article}
), {});

export default (articlesState = articlesMap, action) => {
const { type, payload } = action;

switch (type) {
case DELETE_ARTICLE:
return articlesState.filter(article => article.id !== payload.id)
const newState = {...articlesState};
delete newState[payload.id];
return newState;

case ADD_COMMENT:
const targetArticle = {...articlesState[payload.targetArticle]};
targetArticle.comments = [...targetArticle.comments, payload.id];
Copy link
Owner

Choose a reason for hiding this comment

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

comments может быть undefined


return {
...articlesState,
[payload.targetArticle]: targetArticle
}

}

return articlesState
}
}

14 changes: 12 additions & 2 deletions src/reducer/comments.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { } from '../constants'
import { ADD_COMMENT } from '../constants'
import {normalizedComments as defaultComments} from '../fixtures'

const commentsMap = defaultComments.reduce((acc, comment) => ({
Expand All @@ -7,10 +7,20 @@ const commentsMap = defaultComments.reduce((acc, comment) => ({
}), {})

export default (state = commentsMap, action) => {
const { type } = action
const { type, payload } = action

switch (type) {

case ADD_COMMENT:
return {
...state,
[payload.id] : {
id: payload.id,
user: payload.user,
text: payload.text
}
}

}

return state
Expand Down
10 changes: 8 additions & 2 deletions src/selectors/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,19 @@ export const createCommentSelector = () => createSelector(commentsSelector, idSe
return comments[id]
})

export const createArticleSelector = () => createSelector(articlesSelector, idSelector, (articles, id) => {
console.log('---', 'searching for article', id)
return articles[id]
})

export const filtratedArticlesSelector = createSelector(articlesSelector, filtersSelector, (articles, filters) => {
console.log('---', 'computing filters')
const {selected, dateRange: {from, to}} = filters

return articles.filter(article => {
return Object.values(articles).filter(article => {
const published = Date.parse(article.date)
return (!selected.length || selected.includes(article.id)) &&
(!from || !to || (published > from && published < to))
})
})
})

3 changes: 2 additions & 1 deletion src/store/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {createStore, applyMiddleware, compose} from 'redux'
import rootReducer from '../reducer'
import logger from '../middlewares/logger'
import randomizer from '../middlewares/randomizer'

const composeEnhancers =
typeof window === 'object' &&
Expand All @@ -10,7 +11,7 @@ const composeEnhancers =
}) : compose

const enhancer = composeEnhancers(
applyMiddleware(logger)
applyMiddleware(logger, randomizer)
Copy link
Owner

Choose a reason for hiding this comment

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

лучше логгер в конце ставить

)
const store = createStore(rootReducer, enhancer)

Expand Down