feat(Flash): Add initial redux logic

This commit is contained in:
Berkeley Martinez
2018-01-04 16:24:03 -08:00
parent 9e9e39b8b0
commit f452a8dbce
3 changed files with 77 additions and 4 deletions

View File

@ -1,15 +1,28 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types';
import { CloseButton } from 'react-bootstrap'; import { CloseButton } from 'react-bootstrap';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import ns from './ns.json'; import ns from './ns.json';
import { alertTypes, latestMessageSelector } from './redux';
const propTypes = {}; const propTypes = {
export default function Flash() { alertType: PropTypes.oneOf(Object.keys(alertTypes)),
message: PropTypes.string
};
const mapStateToProps = latestMessageSelector;
const mapDispatchToProps = null;
export function Flash({ alertType, message }) {
if (!message) {
return null;
}
return ( return (
<div className={`${ns}-container bg-info`}> <div className={`${ns}-container bg-${alertType}`}>
<div className={`${ns}-content`}> <div className={`${ns}-content`}>
<div> <div>
Content { message }
</div> </div>
<CloseButton /> <CloseButton />
</div> </div>
@ -19,3 +32,8 @@ export default function Flash() {
Flash.displayName = 'Flash'; Flash.displayName = 'Flash';
Flash.propTypes = propTypes; Flash.propTypes = propTypes;
export default connect(
mapStateToProps,
mapDispatchToProps
)(Flash);

View File

@ -1 +1,54 @@
import { composeReducers } from 'berkeleys-redux-utils';
import _ from 'lodash/fp';
import ns from '../ns.json';
export const alertTypes = _.keyBy(_.identity)([
'success',
'info',
'warning',
'danger'
]);
export const getFlashAction = _.flow(
_.property('meta'),
_.property('flash')
);
export const isFlashAction = _.flow(
getFlashAction,
Boolean
);
const defaultState = {
stack: [{ alertType: 'danger', message: 'foo bar' }]
};
const getNS = _.property(ns);
export const latestMessageSelector = _.flow(
getNS,
_.property('stack'),
_.head,
_.defaultTo(_.stubObject)
);
export default composeReducers(
ns,
function metaReducer(state = defaultState, action) {
if (isFlashAction(action)) {
const { payload: { alertType, message } } = getFlashAction(action);
return {
...state,
stack: [
...state.stack,
{
alertType: alertTypes[alertType] || 'info',
message: _.escape(message)
}
]
};
}
return state;
}
);

View File

@ -8,6 +8,7 @@ import nav from './Nav/redux';
import routes from './routes/redux'; import routes from './routes/redux';
import toasts from './Toasts/redux'; import toasts from './Toasts/redux';
import files from './files'; import files from './files';
import flash from './Flash/redux';
// not ideal but should go away once we move to react-redux-form // not ideal but should go away once we move to react-redux-form
import { projectNormalizer } from './routes/Challenges/redux'; import { projectNormalizer } from './routes/Challenges/redux';
@ -22,5 +23,6 @@ export default combineReducers(
routes, routes,
toasts, toasts,
files, files,
flash,
_formReducer _formReducer
); );