feat(Flash): Add initial redux logic
This commit is contained in:
@ -1,15 +1,28 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { CloseButton } from 'react-bootstrap';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
|
||||
import ns from './ns.json';
|
||||
import { alertTypes, latestMessageSelector } from './redux';
|
||||
|
||||
const propTypes = {};
|
||||
export default function Flash() {
|
||||
const propTypes = {
|
||||
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 (
|
||||
<div className={`${ns}-container bg-info`}>
|
||||
<div className={`${ns}-container bg-${alertType}`}>
|
||||
<div className={`${ns}-content`}>
|
||||
<div>
|
||||
Content
|
||||
{ message }
|
||||
</div>
|
||||
<CloseButton />
|
||||
</div>
|
||||
@ -19,3 +32,8 @@ export default function Flash() {
|
||||
|
||||
Flash.displayName = 'Flash';
|
||||
Flash.propTypes = propTypes;
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Flash);
|
||||
|
@ -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;
|
||||
}
|
||||
);
|
||||
|
@ -8,6 +8,7 @@ import nav from './Nav/redux';
|
||||
import routes from './routes/redux';
|
||||
import toasts from './Toasts/redux';
|
||||
import files from './files';
|
||||
import flash from './Flash/redux';
|
||||
// not ideal but should go away once we move to react-redux-form
|
||||
import { projectNormalizer } from './routes/Challenges/redux';
|
||||
|
||||
@ -22,5 +23,6 @@ export default combineReducers(
|
||||
routes,
|
||||
toasts,
|
||||
files,
|
||||
flash,
|
||||
_formReducer
|
||||
);
|
||||
|
Reference in New Issue
Block a user