Better data management for atlases

This commit is contained in:
Jori Lallo
2016-05-18 01:13:52 -07:00
parent 582b937961
commit 6b3e56a4cf
6 changed files with 63 additions and 34 deletions

View File

@@ -83,6 +83,7 @@
"node-sass": "^3.4.2",
"nodemon": "^1.9.1",
"normalize.css": "^3.0.3",
"normalizr": "^2.0.1",
"react": "^0.14.7",
"react-codemirror": "^0.2.5",
"react-dropzone": "^3.3.2",

View File

@@ -1,12 +1,15 @@
import makeActionCreator from '../utils/actions';
import { client } from 'utils/ApiClient';
import { normalize, Schema, arrayOf } from 'normalizr';
const atlas = new Schema('atlases');
export const FETCH_ATLASES_PENDING = 'FETCH_ATLASES_PENDING';
export const FETCH_ATLASES_SUCCESS = 'FETCH_ATLASES_SUCCESS';
export const FETCH_ATLASES_FAILURE = 'FETCH_ATLASES_FAILURE';
const fetchAtlasesPending = makeActionCreator(FETCH_ATLASES_PENDING);
const fetchAtlasesSuccess = makeActionCreator(FETCH_ATLASES_SUCCESS, 'items', 'pagination');
const fetchAtlasesSuccess = makeActionCreator(FETCH_ATLASES_SUCCESS, 'data', 'pagination');
const fetchAtlasesFailure = makeActionCreator(FETCH_ATLASES_FAILURE, 'error');
export function fetchAtlasesAsync(teamId) {
@@ -17,7 +20,9 @@ export function fetchAtlasesAsync(teamId) {
teamId: teamId,
})
.then(data => {
dispatch(fetchAtlasesSuccess(data.data, data.pagination));
const response = normalize(data.data, arrayOf(atlas));
dispatch(fetchAtlasesSuccess(response, data.pagination));
})
.catch((err) => {
dispatch(fetchAtlasesFailure(err));
@@ -43,7 +48,9 @@ export function fetchAtlasAsync(atlasId) {
id: atlasId,
})
.then(data => {
dispatch(fetchAtlasSuccess(data.data,));
const response = normalize(data.data, atlas);
dispatch(fetchAtlasSuccess(response));
})
.catch((err) => {
dispatch(fetchAtlasFailure(err));

View File

@@ -11,10 +11,12 @@ class AtlasPreview extends React.Component {
}
render() {
const data = this.props.data;
return (
<div className={ styles.container }>
<h2><Link to={ `/atlas/${this.props.data.id}` } className={ styles.atlasLink }>{ this.props.data.name }</Link></h2>
<div>No documents. Why not <Link to='/new-document'>create one</Link>?</div>
<h2><Link to={ `/atlas/${data.id}` } className={ styles.atlasLink }>{ data.name }</Link></h2>
<div>No documents. Why not <Link to={ `/atlas/${data.id}/new` }>create one</Link>?</div>
</div>
);
}

View File

@@ -2,10 +2,13 @@ import {
FETCH_ATLASES_PENDING,
FETCH_ATLASES_SUCCESS,
FETCH_ATLASES_FAILURE,
FETCH_ATLAS_PENDING,
FETCH_ATLAS_SUCCESS,
FETCH_ATLAS_FAILURE,
} from 'actions/AtlasActions';
const initialState = {
items: [],
pagination: null,
isLoading: false,
}
@@ -21,7 +24,7 @@ const atlases = (state = initialState, action) => {
case FETCH_ATLASES_SUCCESS: {
return {
...state,
items: action.items,
...action.data,
pagination: action.pagination,
isLoading: false,
};
@@ -33,6 +36,28 @@ const atlases = (state = initialState, action) => {
error: action.error,
};
}
case FETCH_ATLAS_PENDING: {
return {
...state,
isLoading: true,
};
}
case FETCH_ATLAS_SUCCESS: {
return {
...state,
...action.data,
isLoading: false,
};
}
case FETCH_ATLAS_FAILURE: {
return {
...state,
isLoading: false,
error: action.error,
};
}
default:
return state;
}

View File

@@ -16,50 +16,41 @@ import styles from './Atlas.scss';
class Atlas extends React.Component {
static propTypes = {
isLoading: React.PropTypes.bool,
atlas: React.PropTypes.object,
}
state = {
isLoading: true,
data: null,
}
componentDidMount = () => {
const { id } = this.props.params;
// this.props.fetchAtlasAsync(id);
// Temp before breaking out redux store
client.post('/atlases.info', {
id: id,
})
.then(data => {
this.setState({
isLoading: false,
data: data.data
});
})
this.props.fetchAtlasAsync(id);
}
render() {
const data = this.state.data;
const atlas = this.props.atlas;
let actions;
let title;
if (this.props.isLoading === false) {
actions = <Link to={ `/atlas/${atlas.id}/new` }>New document</Link>;
title = <Title>{ atlas.name }</Title>;
}
return (
<Layout
actions={(
<Link to={ `/atlas/${data.id}/new` }>New document</Link>
)}
title={ <Title>{ data.name }</Title> }
actions={ actions }
title={ title }
>
<CenteredContent>
{ this.state.isLoading ? (
{ this.props.isLoading ? (
<AtlasPreviewLoading />
) : (
<div className={ styles.container }>
<div className={ styles.atlasDetails }>
<h2>{ data.name }</h2>
<h2>{ atlas.name }</h2>
<blockquote>
{ data.description }
{ atlas.description }
</blockquote>
</div>
@@ -72,9 +63,12 @@ class Atlas extends React.Component {
}
}
const mapStateToProps = (state) => {
const mapStateToProps = (state, currentProps) => {
const id = currentProps.params.id;
return {
isLoading: state.atlases.isLoading,
atlas: state.atlases.entities ? state.atlases.entities.atlases[id] : null, // reselect
}
};

View File

@@ -37,7 +37,7 @@ const mapStateToProps = (state) => {
return {
teamId: state.team ? state.team.id : null,
isLoading: state.atlases.isLoading,
items: state.atlases.items,
items: Array.isArray(state.atlases.result) ? state.atlases.result.map((id) => state.atlases.entities.atlases[id]) : [], // reselect
}
};