diff --git a/frontend/src/component/app.jsx b/frontend/src/component/app.jsx
index 6687523056..da7081e7c9 100644
--- a/frontend/src/component/app.jsx
+++ b/frontend/src/component/app.jsx
@@ -1,7 +1,7 @@
import React, { Component } from 'react';
import { Layout, Drawer, Header, Navigation, Content,
Footer, FooterSection, FooterDropDownSection, FooterLinkList,
- Grid, Cell
+ Grid, Cell,
} from 'react-mdl';
import style from './styles.scss';
import ErrorContainer from './error/error-container';
@@ -9,10 +9,7 @@ import ErrorContainer from './error/error-container';
import UserContainer from './user/user-container';
import ShowUserContainer from './user/show-user-container';
-
-
export default class App extends Component {
-
constructor (props) {
super(props);
this.state = { drawerActive: false };
@@ -40,7 +37,7 @@ export default class App extends Component {
render () {
const createListItem = (path, caption) =>
{caption}
;
@@ -62,6 +59,7 @@ export default class App extends Component {
{createListItem('/history', 'Event history')}
{createListItem('/archive', 'Archived toggles')}
+ {createListItem('/applications', 'Applications')}
{createListItem('/metrics', 'Client metrics')}
{createListItem('/client-strategies', 'Client strategies')}
{createListItem('/client-instances', 'Client instances')}
@@ -86,6 +84,7 @@ export default class App extends Component {
+ {createListItem('/applications', 'Applications')}
{createListItem('/metrics', 'Client metrics')}
{createListItem('/client-strategies', 'Client strategies')}
{createListItem('/client-instances', 'Client instances')}
diff --git a/frontend/src/component/application/application-edit-component.js b/frontend/src/component/application/application-edit-component.js
new file mode 100644
index 0000000000..fa679fe2f2
--- /dev/null
+++ b/frontend/src/component/application/application-edit-component.js
@@ -0,0 +1,57 @@
+import React, { Component } from 'react';
+
+import { Link } from 'react-router';
+import { Grid, Cell } from 'react-mdl';
+
+class ClientStrategies extends Component {
+
+ componentDidMount () {
+ this.props.fetchApplication(this.props.appName);
+ }
+
+ render () {
+ if (!this.props.application) {
+ return Loading application info...
;
+ }
+ const {
+ appName,
+ instances,
+ strategies,
+ seenToggles,
+ } = this.props.application;
+
+ return (
+
+
{appName}
+
+
+
+ Instances
+
+ {instances.map(({ instanceId }, i) => - {instanceId}
)}
+
+ |
+
+ Strategies
+
+ {/*strategies.map((name, i) => - {name}
)*/}
+
+ |
+
+ Toggles
+
+ {seenToggles.map((name, i) => -
+
+ {name}
+
+
)}
+
+ |
+
+
+ );
+ }
+}
+
+
+export default ClientStrategies;
diff --git a/frontend/src/component/application/application-edit-container.js b/frontend/src/component/application/application-edit-container.js
new file mode 100644
index 0000000000..fa76680372
--- /dev/null
+++ b/frontend/src/component/application/application-edit-container.js
@@ -0,0 +1,17 @@
+import { connect } from 'react-redux';
+import ApplicationEdit from './application-edit-component';
+import { fetchApplication } from '../../store/application/actions';
+
+const mapStateToProps = (state, props) => {
+ let application = state.applications.getIn(['apps', props.appName]);
+ if (application) {
+ application = application.toJS();
+ }
+ return {
+ application,
+ };
+};
+
+const Constainer = connect(mapStateToProps, { fetchApplication })(ApplicationEdit);
+
+export default Constainer;
diff --git a/frontend/src/component/application/application-list-component.js b/frontend/src/component/application/application-list-component.js
index 796183b17c..ccf44e7a48 100644
--- a/frontend/src/component/application/application-list-component.js
+++ b/frontend/src/component/application/application-list-component.js
@@ -1,20 +1,27 @@
import React, { Component } from 'react';
+import { Link } from 'react-router';
class ClientStrategies extends Component {
componentDidMount () {
- this.props.fetchApplications();
+ this.props.fetchAll();
}
render () {
- if (!this.props.applications) {
- return null;
- }
- const source = this.props.applications.map(item => item.appName).join(', ');
+ const {
+ applications,
+ } = this.props;
+ if (!applications) {
+ return loading...
;
+ }
return (
- {source}
+ {applications.map(item => (
+
+ Link: {item.appName}
+
+ ))}
);
}
diff --git a/frontend/src/component/application/application-list-container.js b/frontend/src/component/application/application-list-container.js
index 9d0322ef94..519527955d 100644
--- a/frontend/src/component/application/application-list-container.js
+++ b/frontend/src/component/application/application-list-container.js
@@ -1,9 +1,9 @@
import { connect } from 'react-redux';
import ApplicationList from './application-list-component';
-import { fetchApplications } from '../../store/application/actions';
+import { fetchAll } from '../../store/application/actions';
-const mapStateToProps = (state) => ({ applications: state.applications.toJS() });
+const mapStateToProps = (state) => ({ applications: state.applications.get('list').toJS() });
-const StrategiesContainer = connect(mapStateToProps, { fetchApplications })(ApplicationList);
+const Container = connect(mapStateToProps, { fetchAll })(ApplicationList);
-export default StrategiesContainer;
+export default Container;
diff --git a/frontend/src/component/feature/view-edit-container.jsx b/frontend/src/component/feature/view-edit-container.jsx
index b2bdd7067a..7acadef46a 100644
--- a/frontend/src/component/feature/view-edit-container.jsx
+++ b/frontend/src/component/feature/view-edit-container.jsx
@@ -27,6 +27,7 @@ class EditFeatureToggleWrapper extends React.Component {
this.props.fetchSeenApps();
this.props.fetchFeatureMetrics();
setInterval(() => {
+ this.props.fetchSeenApps();
this.props.fetchFeatureMetrics();
}, 5000);
}
diff --git a/frontend/src/data/applications-api.js b/frontend/src/data/applications-api.js
index c79ae79156..21a6487c1e 100644
--- a/frontend/src/data/applications-api.js
+++ b/frontend/src/data/applications-api.js
@@ -8,6 +8,13 @@ function fetchAll () {
.then(response => response.json());
}
+function fetchApplication (appName) {
+ return fetch(`${URI}/${appName}`, { headers })
+ .then(throwIfNotSuccess)
+ .then(response => response.json());
+}
+
module.exports = {
+ fetchApplication,
fetchAll,
};
diff --git a/frontend/src/index.jsx b/frontend/src/index.jsx
index 94ff41fff6..905c9c3dfd 100644
--- a/frontend/src/index.jsx
+++ b/frontend/src/index.jsx
@@ -18,6 +18,7 @@ import HistoryPage from './page/history';
import HistoryTogglePage from './page/history/toggle';
import Archive from './page/archive';
import Applications from './page/applications';
+import ApplicationView from './page/applications/view';
import ClientStrategies from './page/client-strategies';
const unleashStore = createStore(
@@ -41,6 +42,7 @@ ReactDOM.render(
+
diff --git a/frontend/src/page/applications/view.js b/frontend/src/page/applications/view.js
new file mode 100644
index 0000000000..e4bc3b2405
--- /dev/null
+++ b/frontend/src/page/applications/view.js
@@ -0,0 +1,6 @@
+import React from 'react';
+import ApplicationEditComponent from '../../component/application/application-edit-container';
+
+const render = ({ params }) => ;
+
+export default render;
diff --git a/frontend/src/store/application/actions.js b/frontend/src/store/application/actions.js
index faeec7fb01..311c5d6b10 100644
--- a/frontend/src/store/application/actions.js
+++ b/frontend/src/store/application/actions.js
@@ -1,20 +1,34 @@
import api from '../../data/applications-api';
-export const RECEIVE_APPLICATINS = 'RECEIVE_APPLICATINS';
-export const ERROR_RECEIVE_APPLICATINS = 'ERROR_RECEIVE_APPLICATINS';
+export const RECEIVE_ALL_APPLICATIONS = 'RECEIVE_ALL_APPLICATIONS';
+export const ERROR_RECEIVE_ALL_APPLICATIONS = 'ERROR_RECEIVE_ALL_APPLICATIONS';
-const recieveApplications = (json) => ({
- type: RECEIVE_APPLICATINS,
+export const RECEIVE_APPLICATION = 'RECEIVE_APPLICATION';
+
+const recieveAllApplications = (json) => ({
+ type: RECEIVE_ALL_APPLICATIONS,
+ value: json,
+});
+
+const recieveApplication = (json) => ({
+ type: RECEIVE_APPLICATION,
value: json,
});
const errorReceiveApplications = (statusCode) => ({
- type: ERROR_RECEIVE_APPLICATINS,
+ type: ERROR_RECEIVE_ALL_APPLICATIONS,
statusCode,
});
-export function fetchApplications () {
+export function fetchAll () {
return dispatch => api.fetchAll()
- .then(json => dispatch(recieveApplications(json)))
+ .then(json => dispatch(recieveAllApplications(json)))
.catch(error => dispatch(errorReceiveApplications(error)));
}
+
+export function fetchApplication (appName) {
+ return dispatch => api.fetchApplication(appName)
+ .then(json => dispatch(recieveApplication(json)))
+ .catch(error => dispatch(errorReceiveApplications(error)));
+}
+
diff --git a/frontend/src/store/application/index.js b/frontend/src/store/application/index.js
index 7036f73ec8..b2daa39146 100644
--- a/frontend/src/store/application/index.js
+++ b/frontend/src/store/application/index.js
@@ -1,14 +1,16 @@
-import { fromJS } from 'immutable';
-import { RECEIVE_APPLICATINS } from './actions';
+import { fromJS, List, Map } from 'immutable';
+import { RECEIVE_ALL_APPLICATIONS, RECEIVE_APPLICATION } from './actions';
function getInitState () {
- return fromJS([]);
+ return fromJS({ list: [], apps: {} });
}
const store = (state = getInitState(), action) => {
switch (action.type) {
- case RECEIVE_APPLICATINS:
- return fromJS(action.value.applications);
+ case RECEIVE_APPLICATION:
+ return state.setIn(['apps', action.value.appName], new Map(action.value));
+ case RECEIVE_ALL_APPLICATIONS:
+ return state.set('list', new List(action.value.applications));
default:
return state;
}