added redux with a small example store

This commit is contained in:
ivaosthu
2016-09-16 21:36:35 +02:00
committed by Ivar Conradi Østhus
parent 0b07d10c97
commit 59ee635ede
17 changed files with 244 additions and 22 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+4 -1
View File
@@ -34,8 +34,10 @@
"react": "^15.3.1",
"react-addons-css-transition-group": "^15.3.1",
"react-dom": "^15.3.1",
"react-redux": "^4.4.5",
"react-router": "^2.8.0",
"react-toolbox": "^1.2.1"
"react-toolbox": "^1.2.1",
"redux": "^3.6.0"
},
"devDependencies": {
"babel-core": "^6.14.0",
@@ -49,6 +51,7 @@
"extract-text-webpack-plugin": "^1.0.1",
"node-sass": "~3.7.0",
"postcss-loader": "^0.13.0",
"redux-devtools": "^3.3.1",
"sass-loader": "^4.0.2",
"style-loader": "^0.13.1",
"toolbox-loader": "0.0.3",
@@ -6,9 +6,9 @@ export default class UnleashNav extends Component {
render () {
return (
<List selectable ripple>
<Link to="/features"><ListItem selectable className="active" caption="Feature Toggles" /></Link>
<Link to="/"><ListItem selectable className="active" caption="Feature Toggles" /></Link>
<Link to="/strategies"><ListItem selectable caption="Strategies" /></Link>
<Link to="/log"><ListItem selectable caption="Log" /></Link>
<Link to="/logs"><ListItem selectable caption="Log" /></Link>
<Link to="/archive"><ListItem selectable caption="Archive" /></Link>
<ListDivider />
<ListSubHeader Resources/>
@@ -0,0 +1,11 @@
let nextFeatureId = 0;
export const addFeatureToggle = (featureName) => ({
type: 'ADD_FEATURE_TOGGLE',
id: nextFeatureId++,
featureName,
});
export const toggleFeature = (id) => ({
type: 'TOGGLE_FEATURE_TOGGLE',
id,
});
@@ -0,0 +1,31 @@
import React from 'react';
import { connect } from 'react-redux';
import { addFeatureToggle } from '../../action';
let AddFeatureToggle = ({ dispatch }) => {
let input;
return (
<div>
<form onSubmit={e => {
e.preventDefault();
if (!input.value.trim()) {
return;
}
dispatch(addFeatureToggle(input.value));
input.value = '';
}}>
<input ref={node => {
input = node;
}} />
<button type="submit">
Add Feature Toggle.
</button>
</form>
</div>
);
};
AddFeatureToggle = connect()(AddFeatureToggle);
export default AddFeatureToggle;
@@ -0,0 +1,16 @@
import React, { PropTypes } from 'react';
const Feature = ({ onClick, featureName, enabled }) => (
<li>
{featureName} is {enabled ? 'enabled ' : 'disabled '}
<a onClick={onClick} href="#">toggle</a>
</li>
);
Feature.propTypes = {
onClick: PropTypes.func.isRequired,
enabled: PropTypes.bool.isRequired,
featureName: PropTypes.string.isRequired,
};
export default Feature;
@@ -0,0 +1,21 @@
import React, { PropTypes } from 'react';
import Feature from './Feature';
const FeatureList = ({ features, onFeatureClick }) => (
<ul>
{features.map(featureToggle =>
<Feature
key={featureToggle.id}
{...featureToggle}
onClick={() => onFeatureClick(featureToggle.id)}
/>
)}
</ul>
);
FeatureList.propTypes = {
onFeatureClick: PropTypes.func.isRequired,
features: PropTypes.array.isRequired,
};
export default FeatureList;
@@ -0,0 +1,21 @@
import { connect } from 'react-redux';
import { toggleFeature } from '../../action';
import FeatureList from './FeatureList';
const mapStateToProps = (state) => ({
features: state.features,
});
const mapDispatchToProps = (dispatch) => ({
onFeatureClick: (id) => {
dispatch(toggleFeature(id));
},
});
const FeatureListContainer = connect(
mapStateToProps,
mapDispatchToProps
)(FeatureList);
export default FeatureListContainer;
+24 -14
View File
@@ -1,17 +1,27 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, hashHistory } from 'react-router';
import App from './App';
import Features from './Features';
import Strategies from './Strategies';
import { Router, Route, IndexRoute, hashHistory } from 'react-router';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
ReactDOM.render((
<Router history={hashHistory}>
<Route path="/" component={App}>
<Route path="/features" component={Features} />
<Route path="/strategies" component={Strategies} />
<Route path="/log" component={Strategies} />
<Route path="/archive" component={Strategies} />
</Route>
</Router>
), document.getElementById('app'));
import store from './store';
import App from './App';
import Features from './page/features';
import Strategies from './page/strategies';
import Logs from './page/logs';
import Archive from './page/archive';
const unleashStore = createStore(store);
ReactDOM.render(
<Provider store={unleashStore}>
<Router history={hashHistory}>
<Route path="/" component={App}>
<IndexRoute component={Features} />
<Route path="/strategies" component={Strategies} />
<Route path="/logs" component={Logs} />
<Route path="/archive" component={Archive} />
</Route>
</Router>
</Provider>, document.getElementById('app'));
@@ -2,11 +2,11 @@ import React, { Component } from 'react';
import { Card, CardTitle, CardText } from 'react-toolbox';
export default class Features extends Component {
export default class Archive extends Component {
render () {
return (
<Card>
<CardTitle>Feture toggles</CardTitle>
<CardTitle>Archived Feture Toggles</CardTitle>
<CardText>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam pharetra finibus
@@ -0,0 +1,17 @@
import React, { Component } from 'react';
import FeatureListContainer from '../../component/feature/FeatureListContainer';
import AddFeatureToggle from '../../component/feature/AddFeatureToggle';
export default class Features extends Component {
render () {
return (
<div>
<h1>Feature Toggles</h1>
<AddFeatureToggle />
<FeatureListContainer />
</div>
);
}
};
@@ -1,12 +1,11 @@
import React, { Component } from 'react';
export default class Strategies extends Component {
render () {
return (
<p>
<div>
<h1>Strategies</h1>
</p>
</div>
);
}
};
@@ -0,0 +1,39 @@
const feature = (state = {}, action) => {
switch (action.type) {
case 'ADD_FEATURE_TOGGLE':
return {
id: action.id,
featureName: action.featureName,
enabled: false,
};
case 'TOGGLE_FEATURE_TOGGLE':
if (state.id !== action.id) {
return state;
}
return Object.assign({}, state, {
enabled: !state.enabled,
});
default:
return state;
}
};
const features = (state = [{ id: 1, featureName: 'test', enabled: true }], action) => {
switch (action.type) {
case 'ADD_FEATURE_TOGGLE':
return [
...state,
feature(undefined, action),
];
case 'TOGGLE_FEATURE_TOGGLE':
return state.map(t =>
feature(t, action)
);
default:
return state;
}
};
export default features;
@@ -0,0 +1,8 @@
import { combineReducers } from 'redux';
import features from './features';
const unleashStore = combineReducers({
features,
});
export default unleashStore;