diff --git a/package.json b/package.json index 34ccfa1c7b..ab8b89bec0 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "nconf": "0.7.1", "pg": "4.3.0", "react": "^0.13.1", + "react-router": "^0.13.2", "reflux": "^0.2.5", "reqwest": "^1.1.4", "webpack": "1.7.3", diff --git a/public/js/UnleashApp.jsx b/public/js/UnleashApp.jsx index fb804ed8a9..724bcbdd2f 100644 --- a/public/js/UnleashApp.jsx +++ b/public/js/UnleashApp.jsx @@ -1,52 +1,91 @@ var React = require('react'); -var TabView = require('./components/TabView'); +var Router = require('react-router'); var Menu = require('./components/Menu'); -var UserStore = require('./stores/UserStore'); var ErrorMessages = require('./components/ErrorMessages'); var initalizer = require('./stores/initalizer'); -var LogEntriesComponent = React.createFactory(require('./components/log/LogEntriesComponent')); -var FeatureTogglesComponent = React.createFactory(require('./components/feature/FeatureTogglesComponent')); -var StrategiesComponent = React.createFactory(require('./components/strategy/StrategiesComponent')); -var ArchiveFeatureComponent = React.createFactory(require('./components/feature/ArchiveFeatureComponent')); - -UserStore.init(); - -var tabPanes = [ -{ - name: 'Feature Toggles', - slug: 'feature-toggles', - content: FeatureTogglesComponent -}, -{ - name: 'Strategies', - slug: 'strategies', - content: StrategiesComponent -}, -{ - name: "Log", - slug: 'log', - content: LogEntriesComponent -}, -{ - name: "Archive", - slug: 'archive', - content: ArchiveFeatureComponent -} -]; - +var FeatureToggleStore = require('./stores/FeatureToggleStore'); +var StrategyStore = require('./stores/StrategyStore'); +var ArchiveStore = require('./stores/ArchivedToggleStore'); +var Link = Router.Link; +var RouteHandler = Router.RouteHandler; var UnleashApp = React.createClass({ + contextTypes: { + router: React.PropTypes.func + }, + + getInitialState: function() { + return { + features: FeatureToggleStore.getFeatureToggles(), + strategies: StrategyStore.getStrategies(), + archivedFeatures: ArchiveStore.getArchivedToggles() + }; + }, + + onFeatureToggleChange: function() { + this.setState({ + features: FeatureToggleStore.getFeatureToggles() + }); + }, + + onStrategiesChange: function() { + this.setState({ + strategies: StrategyStore.getStrategies() + }); + }, + + onArchiveChange: function() { + this.setState({ + archivedFeatures: ArchiveStore.getArchivedToggles() + }); + }, + + componentDidMount: function() { + this.unsubscribeFS = FeatureToggleStore.listen(this.onFeatureToggleChange); + this.unsubscribeSS = StrategyStore.listen(this.onStrategiesChange); + this.unsubscribeAS = ArchiveStore.listen(this.onArchiveChange); + }, + componentWillUnmount: function() { + this.unsubscribeFS(); + this.unsubscribeSS(); + this.unsubscribeAS(); + }, + componentWillMount: function() { initalizer(30); }, + + renderLink: function(id, label) { + return ( + + {label} + + ); + }, + render: function () { return (
- + + {this.renderLink("features", "Toggles")} + {this.renderLink("strategies", "Strategies")} + {this.renderLink("log", "Log")} + {this.renderLink("archive", "Archive")} +
- +
+
+
+ +
+
+
@@ -54,4 +93,5 @@ var UnleashApp = React.createClass({ } }); + module.exports = UnleashApp; diff --git a/public/js/__tests__/components/feature/ArchiveFeatureComponent-test.js b/public/js/__tests__/components/feature/ArchiveFeatureComponent-test.js index a219abd55c..7a874aec6d 100644 --- a/public/js/__tests__/components/feature/ArchiveFeatureComponent-test.js +++ b/public/js/__tests__/components/feature/ArchiveFeatureComponent-test.js @@ -16,13 +16,8 @@ describe("FeatureForm", function () { { name: "featureY" } ]; - Server.getArchivedFeatures.mockImplementation(function(cb) { - cb(null, archivedToggles); - }); - - FeatureToggleStore.initStore(archivedToggles); - - Component = TestUtils.renderIntoDocument(); + Component = TestUtils.renderIntoDocument( + ); }); afterEach(function() { diff --git a/public/js/app.jsx b/public/js/app.jsx index 4cf42046b0..948026dd48 100644 --- a/public/js/app.jsx +++ b/public/js/app.jsx @@ -1,3 +1,10 @@ -var React = require('react'); -var UnleashApp = require('./UnleashApp'); -React.render(, document.getElementById('content')); +var React = require('react'); +var Router = require('react-router'); +var UserStore = require('./stores/UserStore'); +var routes = require('./routes'); + +UserStore.init(); + +Router.run(routes, function (Handler) { + React.render(, document.getElementById('content')); +}); diff --git a/public/js/components/Menu.jsx b/public/js/components/Menu.jsx index 49442f3f05..d00572f313 100644 --- a/public/js/components/Menu.jsx +++ b/public/js/components/Menu.jsx @@ -10,7 +10,7 @@ var Menu = React.createClass({
- + - - {tabPane.name} - - - ); - }.bind(this)); - - return ( -
-
    - {tabNodes} -
-
-
-
-
-
- {new this.state.activeTab.content()} -
-
-
-
-
-
- ); - } -}); - -module.exports = TabView; diff --git a/public/js/components/feature/ArchiveFeatureComponent.jsx b/public/js/components/feature/ArchiveFeatureComponent.jsx index 3730d0d0cb..5f6cb200d4 100644 --- a/public/js/components/feature/ArchiveFeatureComponent.jsx +++ b/public/js/components/feature/ArchiveFeatureComponent.jsx @@ -1,27 +1,7 @@ var React = require("react"); var FeatureActions = require('../../stores/FeatureToggleActions'); -var FeatureToggleStore = require('../../stores/ArchivedToggleStore'); var ArchiveFeatureComponent = React.createClass({ - getInitialState: function() { - return { - archivedFeatures: FeatureToggleStore.getArchivedToggles() - }; - }, - - onStoreChange: function() { - this.setState({ - archivedFeatures: FeatureToggleStore.getArchivedToggles() - }); - }, - - componentDidMount: function() { - this.unsubscribe = FeatureToggleStore.listen(this.onStoreChange); - }, - - componentWillUnmount: function() { - this.unsubscribe(); - }, onRevive: function(item) { FeatureActions.revive.triggerPromise(item); @@ -30,7 +10,8 @@ var ArchiveFeatureComponent = React.createClass({ render: function () { return (
-

Archived feature toggles

+

Archived Feature Toggles

+
@@ -39,7 +20,7 @@ var ArchiveFeatureComponent = React.createClass({ - {this.state.archivedFeatures.map(this.renderArchivedItem)} + {this.props.archivedFeatures.map(this.renderArchivedItem)}
diff --git a/public/js/components/feature/FeatureTogglesComponent.jsx b/public/js/components/feature/FeatureTogglesComponent.jsx index 683d362d3a..85bdbeba0f 100644 --- a/public/js/components/feature/FeatureTogglesComponent.jsx +++ b/public/js/components/feature/FeatureTogglesComponent.jsx @@ -3,29 +3,14 @@ var FeatureList = require('./FeatureList'); var FeatureForm = require('./FeatureForm'); var FeatureActions = require('../../stores/FeatureToggleActions'); var ErrorActions = require('../../stores/ErrorActions'); -var FeatureToggleStore = require('../../stores/FeatureToggleStore'); -var StrategyStore = require('../../stores/StrategyStore'); var FeatureTogglesComponent = React.createClass({ getInitialState: function() { return { - features: FeatureToggleStore.getFeatureToggles(), createView: false }; }, - onFeatureToggleChange: function() { - this.setState({ - features: FeatureToggleStore.getFeatureToggles() - }); - }, - componentDidMount: function() { - this.unsubscribe = FeatureToggleStore.listen(this.onFeatureToggleChange); - }, - componentWillUnmount: function() { - this.unsubscribe(); - }, - updateFeature: function (feature) { FeatureActions.update.triggerPromise(feature); }, @@ -52,16 +37,18 @@ var FeatureTogglesComponent = React.createClass({ return (
+

Feature Toggles

+ {this.state.createView ? this.renderCreateView() : this.renderCreateButton()} + strategies={this.props.strategies} />
); }, @@ -70,7 +57,7 @@ var FeatureTogglesComponent = React.createClass({ return ; + strategies={this.props.strategies} />; }, renderCreateButton: function() { diff --git a/public/js/components/log/LogEntriesComponent.jsx b/public/js/components/log/LogEntriesComponent.jsx index 71d5992e53..72ff98ccee 100644 --- a/public/js/components/log/LogEntriesComponent.jsx +++ b/public/js/components/log/LogEntriesComponent.jsx @@ -24,6 +24,7 @@ var LogEntriesComponent = React.createClass({ render: function() { return (
+

Log


diff --git a/public/js/components/strategy/StrategiesComponent.jsx b/public/js/components/strategy/StrategiesComponent.jsx index e913f6c03b..866d1fcf7c 100644 --- a/public/js/components/strategy/StrategiesComponent.jsx +++ b/public/js/components/strategy/StrategiesComponent.jsx @@ -1,29 +1,15 @@ var React = require('react'); var StrategyList = require('./StrategyList'); var StrategyForm = require('./StrategyForm'); -var StrategyStore = require('../../stores/StrategyStore'); var StrategyActions = require('../../stores/StrategyActions'); var StrategiesComponent = React.createClass({ getInitialState: function() { return { - createView: false, - strategies: StrategyStore.getStrategies() + createView: false }; }, - onStoreChange: function() { - this.setState({ - strategies: StrategyStore.getStrategies() - }); - }, - componentDidMount: function() { - this.unsubscribe = StrategyStore.listen(this.onStoreChange); - }, - componentWillUnmount: function() { - this.unsubscribe(); - }, - onNewStrategy: function() { this.setState({createView: true}); }, @@ -44,11 +30,12 @@ var StrategiesComponent = React.createClass({ render: function() { return (
+

Activation Strategies

{this.state.createView ? this.renderCreateView() : this.renderCreateButton()}
); diff --git a/public/js/routes.jsx b/public/js/routes.jsx new file mode 100644 index 0000000000..7b0d3fd2d8 --- /dev/null +++ b/public/js/routes.jsx @@ -0,0 +1,20 @@ +var React = require('react'); +var Router = require('react-router'); +var UnleashApp = require('./UnleashApp'); +var LogEntriesComponent = require('./components/log/LogEntriesComponent'); +var FeatureTogglesComponent = require('./components/feature/FeatureTogglesComponent'); +var StrategiesComponent = require('./components/strategy/StrategiesComponent'); +var ArchiveFeatureComponent = require('./components/feature/ArchiveFeatureComponent'); +var DefaultRoute = Router.DefaultRoute; +var Route = Router.Route; + +var routes = ( + + + + + + +); + +module.exports = routes;