Skip to content
Open

Ht4 #46

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, ADD_COMMENT, CHANGE_DATE_RANGE, CHANGE_SELECTION} from '../constants'

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

export function addComment(text) {
return {
type: ADD_COMMENT,
payload: { text }
}
}
12 changes: 6 additions & 6 deletions src/components/article-list/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ export class ArticleList extends Component {

render() {
const { articles, openItemId, toggleItem } = this.props
console.log('---', 'rendering ArticlList')
const articleElements = articles.map(article =>
<li key = {article.id} className = "test__article-list--item">
console.log('---', 'rendering ArticlList', articles)
const articleElements = articles.map(id =>
<li key = {id} className = "test__article-list--item">
<Article
article = {article}
id = {id}
onButtonClick = {toggleItem}
isOpen = {openItemId === article.id}
isOpen = {openItemId === id}
/>
</li>
)
Expand All @@ -43,4 +43,4 @@ export default connect(state => {
return {
articles: filtratedArticles(state)
}
})(accordion(ArticleList))
})(accordion(ArticleList))
16 changes: 15 additions & 1 deletion src/components/article/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import CSSTransition from 'react-addons-css-transition-group'
import { connect } from 'react-redux'
import CommentList from '../comment-list'
import { deleteArticle } from '../../AC'
import { createArticleSelector } from '../../selectors'
import './style.css'

class Article extends PureComponent {
Expand Down Expand Up @@ -48,6 +49,10 @@ class Article extends PureComponent {
)
}

handleAdd = () => {

}

handleDelete = () => {
const { deleteArticle, article } = this.props
deleteArticle(article.id)
Expand All @@ -73,4 +78,13 @@ Article.propTypes = {
onButtonClick: PropTypes.func
}

export default connect(null, { deleteArticle })(Article)
const createMapStateToProps = () => {
const articleSelector = createArticleSelector()

return (state, ownProps) => ({
article: articleSelector(state, ownProps)
})
}


export default connect(createMapStateToProps, { deleteArticle })(Article)
37 changes: 35 additions & 2 deletions src/components/comment-list/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import React, {Component} from 'react'
import React, {Component, Fragment} from 'react'
import PropTypes from 'prop-types'
import CSSTransition from 'react-addons-css-transition-group'
import Comment from '../comment'
import toggleOpen from '../../decorators/toggleOpen'
import { addComment } from '../../AC'
import { connect } from 'react-redux'
import './style.css'

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

Expand All @@ -17,6 +20,19 @@ class CommentList extends Component {
toggleOpen: PropTypes.func
}

handleAdd = () => {
const { comment } = this.state
const { addComment } = this.props
console.log('add', comment)
addComment(comment)
this.setState({comment: ''})
}

handleChange = (event) => {
console.log('change', event.target.value)
this.setState({comment: event.target.value})
}

render() {
const {isOpen, toggleOpen} = this.props
const text = isOpen ? 'hide comments' : 'show comments'
Expand All @@ -30,6 +46,14 @@ class CommentList extends Component {
>
{this.getBody()}
</CSSTransition>

{ isOpen && <Fragment>
<textarea onChange = {this.handleChange} style={{ width: '100%'}} />
<br/>
<button onClick = {this.handleAdd}>
add comment
</button>
</Fragment> }
</div>
)
}
Expand All @@ -50,6 +74,7 @@ class CommentList extends Component {
}

getComments() {
console.log('comments', this.props.comments)
return (
<ul>
{
Expand All @@ -63,5 +88,13 @@ class CommentList extends Component {
}
}

const createMapStateToProps = (state, ownProps) => {
console.log('---', 'comnent list connect')
console.log('---', 'ownProps', ownProps)
return {
comments: ownProps.comments
}
}

export default toggleOpen(CommentList)
// export default toggleOpen(CommentList)
export default toggleOpen(connect(createMapStateToProps, { addComment })(CommentList))
2 changes: 1 addition & 1 deletion src/components/counter.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ const mapStateToProps = state => ({
count: state.counter
})

export default connect(mapStateToProps)(Counter)
export default connect(mapStateToProps)(Counter)
10 changes: 5 additions & 5 deletions src/components/filters/select.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ 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 = Object.keys(articles).map(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.

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

label: articles[id].title,
value: id
}))

return <Select
Expand All @@ -32,4 +32,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
@@ -1,6 +1,7 @@
export const INCREMENT = 'INCREMENT'

export const DELETE_ARTICLE = 'DELETE_ARTICLE'
export const ADD_COMMENT = 'ADD_COMMENT'

export const CHANGE_SELECTION = 'CHANGE_SELECTION'
export const CHANGE_DATE_RANGE = 'CHANGE_DATE_RANGE'
export const CHANGE_DATE_RANGE = 'CHANGE_DATE_RANGE'
6 changes: 3 additions & 3 deletions src/fixtures.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions src/middlewares/uuid.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export default store => next => action => {
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

let uuid

function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
uuid = s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();

action.payload.uuid = uuid;
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)
}
18 changes: 15 additions & 3 deletions src/reducer/articles.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
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

console.log('ARTICLES', articlesState)
switch (type) {
case ADD_COMMENT:
let id = Object.keys(articlesState)[0]
articlesState[id].comments.push(action.payload.uuid)
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 articlesState

case DELETE_ARTICLE:
return articlesState.filter(article => article.id !== payload.id)

default:
return articlesState
}
}
}
12 changes: 10 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 } from '../fixtures'

const defaultComments = normalizedComments.reduce((acc, comment) => ({
Expand All @@ -11,8 +11,16 @@ export default (commentsState = defaultComments, action) => {
const {type} = action

switch (type) {
case ADD_COMMENT:
let comment = {}
comment['id'] = action.payload.uuid
comment['text'] = action.payload.text
comment['user'] = 'USER1'
commentsState[action.payload.uuid] = comment
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.

И здесь не мутируй

console.log('COMMENT STATE', commentsState)
return commentsState

default:
return commentsState
}
}
}
2 changes: 1 addition & 1 deletion src/reducer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ import filters from './filters'
export default combineReducers({
counter: counterReducer,
articles, comments, filters
})
})
7 changes: 7 additions & 0 deletions src/reducer/select.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { CHANGE_SELECTED } from '../constants'

export default (selectState = null, action) => {
const { type, payload } = action

return type === CHANGE_SELECTED ? payload.selection : selectState
}
11 changes: 7 additions & 4 deletions src/selectors/index.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import { createSelector } from 'reselect'

const articleListSelector = state => state.articles
const articlesSelector = state => state.articles
const commentsSelector = state => state.comments
const filtersSelector = state => state.filters
const idSelector = (_, props) => props.id

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

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

export const createCommentSelector = () => createSelector(commentsSelector, idSelector, (comments, id) => comments[id])
export const createCommentSelector = () => createSelector(commentsSelector, idSelector, (comments, id) => comments[id])

export const createArticleSelector = () => createSelector(articlesSelector, idSelector, (articles, id) => articles[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 uuid from '../middlewares/uuid'

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

const store = createStore(reducer, enhancer)

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

export default store
export default store