Skip to content
Open

Ht3 #19

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
50 changes: 50 additions & 0 deletions src/components/people/PeopleList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React, {Component} from 'react'
import {connect} from 'react-redux'
import {moduleName, peopleListSelector, fetchPeople} from '../../ducks/people'
import {List} from 'react-virtualized'
import 'react-virtualized/styles.css'

class PeopleList extends Component {

constructor(props) {
super(props)
}

componentDidMount(){
this.props.fetchPeople()
}

render() {

const {people} = this.props
console.log(people)

return <div><List
width={300}
height={500}
rowCount={people.length}
rowHeight={20}
rowRenderer={this.rowRenderer(people)}
/></div>
}

rowRenderer = people => ({key, index, isScrolling, isVisible, style}) => {
return (
<div
key={key}
style={style}
className="test--people-list__row"
>
{people[index].firstName }
&nbsp;
{people[index].lastName }
&nbsp;
{people[index].email }
</div>
)
}
}

export default connect(state => ({
people: peopleListSelector(state)
}), {fetchPeople})(PeopleList)
23 changes: 23 additions & 0 deletions src/components/people/PeopleList.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react'
import {shallow, mount} from 'enzyme'
import {PeopleList} from './PeopleList'
import {PersonRecord} from '../../ducks/people'

const testPeople = [{
firstName: 'Alex',
lastName : 'Ivanov',
email: 'iva@gmail.com'
},{
firstName: 'Masha',
lastName : 'Popova',
email: 'mash@gmail.com'
}].map(event => new PersonRecord({...event, uid: Math.random().toString()}))

it('should render people list', () => {
const container = shallow(<PeopleList people = {testPeople}/>)

const rows = container.find('.test--people-list__row')

expect(rows.length).toEqual(testPeople.length)
})

2 changes: 2 additions & 0 deletions src/components/routes/PersonPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { Component } from 'react'
import {connect} from 'react-redux'
import {addPerson} from '../../ducks/people'
import NewPersonForm from '../people/NewPersonForm'
import PeopleList from '../people/PeopleList'

class PersonPage extends Component {
static propTypes = {
Expand All @@ -13,6 +14,7 @@ class PersonPage extends Component {
<div>
<h2>Add new person</h2>
<NewPersonForm onSubmit={this.props.addPerson}/>
<PeopleList />
</div>
)
}
Expand Down
16 changes: 8 additions & 8 deletions src/config.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import firebase from 'firebase'

export const appName = "advreact-21-08"
export const appName = "advanced-react-varenik163"
export const firebaseConfig = {
apiKey: "AIzaSyDjA6CeIHuni5lNm4ML1b-TSxJltsYUO8g",
authDomain: `${appName}.firebaseapp.com`,
databaseURL: `https://${appName}.firebaseio.com`,
projectId: appName,
storageBucket: `${appName}.appspot.com`,
messagingSenderId: "789814589283"
}
apiKey: "AIzaSyDVBpwgGnjIYZu7iKWsPUiUPVvVc92XC2w",
authDomain: "advanced-react-varenik163.firebaseapp.com",
databaseURL: "https://advanced-react-varenik163.firebaseio.com",
projectId: "advanced-react-varenik163",
storageBucket: "advanced-react-varenik163.appspot.com",
messagingSenderId: "860869576887"
};

firebase.initializeApp(firebaseConfig)
64 changes: 58 additions & 6 deletions src/ducks/people.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import {appName} from '../config'
import {Record, List} from 'immutable'
import {put, call, takeEvery} from 'redux-saga/effects'
import {generateId} from './utils'
import {put, call, all, take, takeEvery} from 'redux-saga/effects'
import {generateId, fbPeopleDatatoEntities} from './utils'
import {reset} from 'redux-form'
import {addPersonToFB} from '../mocks/index'
import {createSelector} from 'reselect'
import {entitiesSelector} from "../redux/entitiesSelector"
import firebase from 'firebase'


const ReducerState = Record({
entities: new List([])
entities: new List([]),
loading: false,
loaded: false
})

const PersonRecord = Record({
export const PersonRecord = Record({
id: null,
firstName: null,
lastName: null,
Expand All @@ -19,36 +26,78 @@ export const moduleName = 'people'
const prefix = `${appName}/${moduleName}`
export const ADD_PERSON_REQUEST = `${prefix}/ADD_PERSON_REQUEST`
export const ADD_PERSON = `${prefix}/ADD_PERSON`

export const FETCH_PEOPLE_REQUEST = `${prefix}/FETCH_PEOPLE_REQUEST`
export const FETCH_PEOPLE_SUCCESS = `${prefix}/FETCH_PEOPLE_SUCCESS`

export default function reducer(state = new ReducerState(), action) {
const {type, payload} = action

switch (type) {
case FETCH_PEOPLE_REQUEST: return state
.set('loading', true)

case ADD_PERSON:
return state.update('entities', entities => entities.push(new PersonRecord(payload)))

case FETCH_PEOPLE_SUCCESS:
console.log(payload)
return state
.set('loading', false)
.set('loaded', true)
.set('entities', fbPeopleDatatoEntities(payload, PersonRecord))

default:
return state
}
}



export const peopleListSelector = createSelector(entitiesSelector(moduleName), entities => (
entities.valueSeq().toArray()
))

export function addPerson(person) {
return {
type: ADD_PERSON_REQUEST,
payload: person
}
}

export function fetchPeople() {
return {
type: FETCH_PEOPLE_REQUEST
}
}

export const addPersonSaga = function * (action) {

const id = yield call(generateId)

addPersonToFB(action.payload)

yield put({
type: ADD_PERSON,
payload: {...action.payload, id}
})

yield put(reset('person'))

}

export const fetchPeopleSaga = function * () {
while (true) {
yield take(FETCH_PEOPLE_REQUEST)

const ref = firebase.database().ref('people')

const data = yield call([ref, ref.once], 'value')

yield put({
type: FETCH_PEOPLE_SUCCESS,
payload: data.val()
})
}
}

/*
Expand All @@ -65,5 +114,8 @@ export function addPerson(person) {
*/

export const saga = function * () {
yield takeEvery(ADD_PERSON_REQUEST, addPersonSaga)
yield takeEvery(ADD_PERSON_REQUEST, addPersonSaga)//не понял, как их объединить?
yield all([
fetchPeopleSaga()
])
}
6 changes: 6 additions & 0 deletions src/ducks/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,10 @@ export function fbDatatoEntities(data, RecordModel = Map) {
return (new OrderedMap(data)).mapEntries(([uid, value]) => (
[uid, (new RecordModel(value)).set('uid', uid)]
))
}

export function fbPeopleDatatoEntities(data, RecordModel = Map) {
return Map(data).mapEntries(([uid, value]) => (
[uid, (new RecordModel(value)).set('id', uid)]
)).toList()
}
5 changes: 5 additions & 0 deletions src/mocks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,9 @@ window.runMigration = function() {
firebase.database().ref('/events').once('value', data => {
if (!data.val()) saveEventsToFB()
})
}

export function addPersonToFB(person) {
const peopleRef = firebase.database().ref('/people')
peopleRef.push(person)
}
6 changes: 6 additions & 0 deletions src/redux/entitiesSelector.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import {createSelector} from 'reselect'

export function entitiesSelector(moduleName) {
const stateSelector = state => state[moduleName]
return createSelector(stateSelector, state => state.entities)
}