Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use store accessor library for getter functions that refresh stale state #10

Open
wants to merge 1 commit into
base: routed-email-app
Choose a base branch
from
Open
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
5 changes: 2 additions & 3 deletions components/EmailPreview.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import React, { Component } from 'react'
import { connect } from 'react-redux'

import storeAccessor from '../utils/storeAccessor'
class EmailPreview extends Component {

render() {
console.log("Rendering email preview");
const { email } = this.props;
Expand All @@ -25,7 +24,7 @@ class EmailPreview extends Component {

const mapStateToProps = function(state, existingProps) {
return {
email: state.emailApp.emails.emails.find((email) => email.id == existingProps.params.emailId)
email: storeAccessor.emailApp.emails().emails.find((email) => email.id == existingProps.params.emailId)
}
}

Expand Down
21 changes: 13 additions & 8 deletions components/Emails.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import React, { Component, PropTypes } from 'react'
import { connect } from 'react-redux'

import storeAccessor from '../utils/storeAccessor'
import MoveEmail from './MoveEmail'

class Emails extends Component {

render() {
const { emails, fetchedAt } = this.props;
return (
Expand All @@ -27,9 +26,9 @@ class Emails extends Component {
<tr key={email.id}>
<td>{email.subject}</td>
<td>{email.sender}</td>
<td>{email.folderName}</td>
<td>{email.folder ? email.folder.name : 'Missing...'}</td>
<td><button onClick={() => this.props.removeEmail(email.id)}>Delete</button></td>
<td><MoveEmail emailId={email.id}/></td>
<td><MoveEmail email={email}/></td>
</tr>
)
})
Expand All @@ -42,11 +41,17 @@ class Emails extends Component {
}

const mapStateToProps = function(state) {
const emailState = storeAccessor.emailApp.emails();
let folders = storeAccessor.emailApp.folders().folders;
let emails = emailState.emails;
if(emails && folders) {
emails = emails.map((email) => {
return Object.assign({}, email, { folder: folders.find((folder) => folder.id === email.folderId) });
});
}
return {
emails: state.emailApp.emails.emails.map((email) => {
return Object.assign({}, email, { folderName: state.emailApp.folders.folders.find((folder) => folder.id === email.folderId).name });
}),
fetchedAt: state.emailApp.emails.fetchedAt
emails: emails,
fetchedAt: emailState.fetchedAt
}
}

Expand Down
75 changes: 40 additions & 35 deletions components/Folder.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,52 +4,57 @@ import { Link } from 'react-router'
import emailApp from '../emailApp'
import * as actions from '../actions'
import MoveEmail from './MoveEmail'

import storeAccessor from '../utils/storeAccessor'

class Folder extends Component {

render() {
const { emails, folder, fetchedAt } = this.props;
return (
<div>
<h1>{folder.name} (fetched at {fetchedAt}</h1><button onClick={this.props.fetchEmails}>Fetch</button>
<table>
<thead>
<tr>
<th>Subject</th>
<th>Sender</th>
<th>Delete</th>
<th>Move</th>
<th>Open</th>
</tr>
</thead>
<tbody>
{
emails.map((email) => {
return (
<tr key={email.id}>
<td><Link to={'/folder/' + folder.id + '/email/' + email.id}>{email.subject}</Link></td>
<td>{email.sender}</td>
<td><button onClick={() => this.props.removeEmail(email.id)}>Delete</button></td>
<td><MoveEmail emailId={email.id}/></td>
<td><button onClick={() => this.props.openEmail(email.id)}>Open</button></td>
</tr>
)
})
}
</tbody>
</table>
{this.props.children}
</div>
folder !== undefined && emails !== undefined ? (
<div>
<h1>{folder.name} (fetched at {fetchedAt})</h1><button onClick={this.props.fetchEmails}>Fetch</button>
<table>
<thead>
<tr>
<th>Subject</th>
<th>Sender</th>
<th>Delete</th>
<th>Move</th>
<th>Open</th>
</tr>
</thead>
<tbody>
{
emails.map((email) => {
return (
<tr key={email.id}>
<td><Link to={'/folder/' + folder.id + '/email/' + email.id}>{email.subject}</Link></td>
<td>{email.sender}</td>
<td><button onClick={() => this.props.removeEmail(email.id)}>Delete</button></td>
<td><MoveEmail email={email}/></td>
<td><button onClick={() => this.props.openEmail(email.id)}>Open</button></td>
</tr>
)
})
}
</tbody>
</table>
{this.props.children}
</div>
) : <p>Loading...</p>
)
}
}

const mapStateToProps = function(state, existingProps) {
const foldersState = storeAccessor.emailApp.folders();
const emailsState = storeAccessor.emailApp.emails();
const folder = foldersState.folders ? foldersState.folders.find((folder) => folder.id === existingProps.params.folderId) : undefined;
const emails = emailsState.emails ? emailsState.emails.filter((email) => email.folderId === existingProps.params.folderId) : undefined;
return {
folder: state.emailApp.folders.folders.find((folder) => folder.id === existingProps.params.folderId),
emails: state.emailApp.emails.emails.filter((email) => email.folderId === existingProps.params.folderId),
fetchedAt: state.emailApp.emails.fetchedAt
folder: folder,
emails: emails,
fetchedAt: emailsState.fetchedAt
}
}

Expand Down
23 changes: 13 additions & 10 deletions components/Folders.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,30 @@ import { connect } from 'react-redux'

import AddFolder from './AddFolder'
import emailApp from '../emailApp'
import storeAccessor from '../utils/storeAccessor'

class Folders extends Component {

render() {
const { folders } = this.props;
return (
<div>
<h1>Folders</h1>
<ul>
{ folders.map((folder) => <li key={folder.id}>{folder.name} - <button onClick={() => this.props.removeFolder(folder.id)}>Delete</button></li>) }
</ul>
<AddFolder/>
</div>
folders ? (
<div>
<h1>Folders</h1>
<ul>
{ folders.map((folder) => <li key={folder.id}>{folder.name} - <button onClick={() => this.props.removeFolder(folder.id)}>Delete</button></li>) }
</ul>
<AddFolder/>
</div>
) : <p>Loading...</p>
)
}
}

const mapStateToProps = function(state) {
const foldersState = storeAccessor.emailApp.folders();
return {
folders: state.emailApp.folders.folders,
fetchedAt: state.emailApp.folders.fetchedAt
folders: foldersState.folders,
fetchedAt: foldersState.fetchedAt
}
}

Expand Down
15 changes: 9 additions & 6 deletions components/MoveEmail.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { Component, PropTypes } from 'react'
import { connect } from 'react-redux'

import storeAccessor from '../utils/storeAccessor'
import emailApp from '../emailApp'

class MoveEmail extends Component {
Expand All @@ -25,7 +25,11 @@ class MoveEmail extends Component {
return (
<form onSubmit={(e) => this.submit(e)}>
<select onChange={(e) => this.updateSelectedFolder(e.target.value)} value={this.state.selectedFolderId}>
{ folders.map((folder) => <option key={folder.id} value={folder.id}>{folder.name}</option> )}
{
folders ? (
folders.map((folder) => <option key={folder.id} value={folder.id}>{folder.name}</option> )
) : null
}
</select>
<button type="submit">Move</button>
</form>
Expand All @@ -34,16 +38,15 @@ class MoveEmail extends Component {
}

const mapStateToProps = function(state, existingProps) {
const email = state.emailApp.emails.emails.find((email) => email.id === existingProps.emailId);
const foldersState = storeAccessor.emailApp.folders();
return {
email: email,
folders: state.emailApp.folders.folders
folders: foldersState.folders
}
}

const mapDispatchToProps = function(dispatch, existingProps) {
return {
moveToFolder: (folderId) => dispatch(emailApp.actions.email.moveEmailToFolder(existingProps.emailId, folderId))
moveToFolder: (folderId) => dispatch(emailApp.actions.email.moveEmailToFolder(existingProps.email.id, folderId))
}
}

Expand Down
4 changes: 3 additions & 1 deletion components/OpenEmail.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React, { Component } from 'react'
import { connect } from 'react-redux'

import storeAccessor from '../utils/storeAccessor';

class OpenEmail extends Component {

render() {
Expand All @@ -16,7 +18,7 @@ class OpenEmail extends Component {

const mapStateToProps = function(state, existingProps) {
return {
email: state.emailApp.emails.emails.find((email) => email.id === existingProps.openEmail.emailId)
email: storeAccessor.emailApp.emails().emails.find((email) => email.id === existingProps.openEmail.emailId)
}
}

Expand Down
19 changes: 13 additions & 6 deletions containers/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import Folders from '../components/Folders'
import OpenEmails from '../components/OpenEmails.js';
import { Link } from 'react-router'

import emailApp from '../emailApp';

import storeAccessor from '../utils/storeAccessor';


class App extends Component {
render() {
Expand All @@ -17,11 +21,13 @@ class App extends Component {
<Link to="/folders">Folders</Link>
<ul>
{
folders.map((folder) => {
return (
<li key={folder.id}><Link to={'/folder/' + folder.id}>{folder.name}</Link></li>
)
})
folders ? (
folders.map((folder) => {
return (
<li key={folder.id}><Link to={'/folder/' + folder.id}>{folder.name}</Link></li>
)
})
) : <li>Loading Folders...</li>
}
</ul>
</li>
Expand All @@ -37,10 +43,11 @@ class App extends Component {
{this.props.children}
</div>
<OpenEmails/>

</div>
)
}
}

// Wrap the component to inject dispatch and state into it
export default connect((state) => { return { folders: state.emailApp.folders.folders } })(App)
export default connect((state) => { return { folders: storeAccessor.emailApp.folders().folders } })(App)
16 changes: 13 additions & 3 deletions emailApp/actions/emailActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,18 @@ import { api } from '../api'
window.api = api;

export const FETCHED_EMAILS = 'FETCHED_EMAILS'
export const REMOVED_EMAIL = 'REMOVED_EMAIL'
export const MOVED_EMAIL_TO_FOLDER = 'MOVED_EMAIL_TO_FOLDER'

// State actions
const removedEmail = function(emailId) {
return { type: REMOVED_EMAIL, emailId: emailId };
}

const movedEmailToFolder = function(emailId, folderId) {
return { type: MOVED_EMAIL_TO_FOLDER, emailId: emailId, folderId: folderId };
}

// State action
const fetchedEmails = function(emails, fetchedAt) {
return { type: FETCHED_EMAILS, emails: emails, fetchedAt: fetchedAt };
}
Expand All @@ -20,13 +30,13 @@ export function fetchEmails() {
export function removeEmail(emailId) {
return (dispatch) => {
api.removeEmail(emailId);
dispatch(fetchEmails());
dispatch(removedEmail(emailId));
}
}

export function moveEmailToFolder(emailId, folderId) {
return (dispatch) => {
api.moveEmailToFolder(emailId, folderId);
dispatch(fetchEmails());
dispatch(movedEmailToFolder(emailId, folderId));
}
}
17 changes: 13 additions & 4 deletions emailApp/actions/folderActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,21 @@ import { api } from '../api'
import * as emailActions from './emailActions'

export const FETCHED_FOLDERS = 'FETCHED_FOLDERS'
export const ADDED_FOLDER = 'ADDED_FOLDER'
export const REMOVED_FOLDER = 'REMOVED_FOLDER'

const fetchedFolders = function(folders, fetchedAt) {
return { type: FETCHED_FOLDERS, folders: folders, fetchedAt: fetchedAt };
}

const removedFolder = function(folderId) {
return { type: REMOVED_FOLDER, folderId: folderId };
}

const addedFolder = function() {
return { type: ADDED_FOLDER };
}

// Public application API for consumption by GUI

export const fetchFolders = function() {
Expand All @@ -19,15 +29,14 @@ export const fetchFolders = function() {

export const addFolder = function(name) {
return (dispatch) => {
api.addFolder(name)
dispatch(fetchFolders());
api.addFolder(name);
dispatch(addedFolder());
}
}

export const removeFolder = function(folderId) {
return (dispatch) => {
api.removeFolder(folderId);
dispatch(emailActions.fetchEmails());
dispatch(fetchFolders());
dispatch(removedFolder(folderId));
}
}
Loading