mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-20 00:08:02 +01:00
add application view
This commit is contained in:
parent
d2ea5db48c
commit
a1006e14f0
@ -1,7 +1,7 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { Layout, Drawer, Header, Navigation, Content,
|
import { Layout, Drawer, Header, Navigation, Content,
|
||||||
Footer, FooterSection, FooterDropDownSection, FooterLinkList,
|
Footer, FooterSection, FooterDropDownSection, FooterLinkList,
|
||||||
Grid, Cell
|
Grid, Cell,
|
||||||
} from 'react-mdl';
|
} from 'react-mdl';
|
||||||
import style from './styles.scss';
|
import style from './styles.scss';
|
||||||
import ErrorContainer from './error/error-container';
|
import ErrorContainer from './error/error-container';
|
||||||
@ -9,10 +9,7 @@ import ErrorContainer from './error/error-container';
|
|||||||
import UserContainer from './user/user-container';
|
import UserContainer from './user/user-container';
|
||||||
import ShowUserContainer from './user/show-user-container';
|
import ShowUserContainer from './user/show-user-container';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default class App extends Component {
|
export default class App extends Component {
|
||||||
|
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = { drawerActive: false };
|
this.state = { drawerActive: false };
|
||||||
@ -62,6 +59,7 @@ export default class App extends Component {
|
|||||||
{createListItem('/history', 'Event history')}
|
{createListItem('/history', 'Event history')}
|
||||||
{createListItem('/archive', 'Archived toggles')}
|
{createListItem('/archive', 'Archived toggles')}
|
||||||
<hr />
|
<hr />
|
||||||
|
{createListItem('/applications', 'Applications')}
|
||||||
{createListItem('/metrics', 'Client metrics')}
|
{createListItem('/metrics', 'Client metrics')}
|
||||||
{createListItem('/client-strategies', 'Client strategies')}
|
{createListItem('/client-strategies', 'Client strategies')}
|
||||||
{createListItem('/client-instances', 'Client instances')}
|
{createListItem('/client-instances', 'Client instances')}
|
||||||
@ -86,6 +84,7 @@ export default class App extends Component {
|
|||||||
</FooterDropDownSection>
|
</FooterDropDownSection>
|
||||||
<FooterDropDownSection title="Metrics">
|
<FooterDropDownSection title="Metrics">
|
||||||
<FooterLinkList>
|
<FooterLinkList>
|
||||||
|
{createListItem('/applications', 'Applications')}
|
||||||
{createListItem('/metrics', 'Client metrics')}
|
{createListItem('/metrics', 'Client metrics')}
|
||||||
{createListItem('/client-strategies', 'Client strategies')}
|
{createListItem('/client-strategies', 'Client strategies')}
|
||||||
{createListItem('/client-instances', 'Client instances')}
|
{createListItem('/client-instances', 'Client instances')}
|
||||||
|
@ -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 <div>Loading application info...</div>;
|
||||||
|
}
|
||||||
|
const {
|
||||||
|
appName,
|
||||||
|
instances,
|
||||||
|
strategies,
|
||||||
|
seenToggles,
|
||||||
|
} = this.props.application;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h5>{appName}</h5>
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<Cell col={4}>
|
||||||
|
<h6>Instances</h6>
|
||||||
|
<ol className="demo-list-item mdl-list">
|
||||||
|
{instances.map(({ instanceId }, i) => <li className="mdl-list__item" key={i}>{instanceId}</li>)}
|
||||||
|
</ol>
|
||||||
|
</Cell>
|
||||||
|
<Cell col={4}>
|
||||||
|
<h6>Strategies</h6>
|
||||||
|
<ol className="demo-list-item mdl-list">
|
||||||
|
{/*strategies.map((name, i) => <li className="mdl-list__item" key={i}>{name}</li>)*/}
|
||||||
|
</ol>
|
||||||
|
</Cell>
|
||||||
|
<Cell col={4}>
|
||||||
|
<h6>Toggles</h6>
|
||||||
|
<ol className="demo-list-item mdl-list">
|
||||||
|
{seenToggles.map((name, i) => <li className="mdl-list__item" key={i}>
|
||||||
|
<Link to={`/features/edit/${name}`}>
|
||||||
|
{name}
|
||||||
|
</Link>
|
||||||
|
</li>)}
|
||||||
|
</ol>
|
||||||
|
</Cell>
|
||||||
|
</Grid>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default ClientStrategies;
|
@ -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;
|
@ -1,20 +1,27 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
import { Link } from 'react-router';
|
||||||
|
|
||||||
class ClientStrategies extends Component {
|
class ClientStrategies extends Component {
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
this.props.fetchApplications();
|
this.props.fetchAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
if (!this.props.applications) {
|
const {
|
||||||
return null;
|
applications,
|
||||||
}
|
} = this.props;
|
||||||
const source = this.props.applications.map(item => item.appName).join(', ');
|
|
||||||
|
|
||||||
|
if (!applications) {
|
||||||
|
return <div>loading...</div>;
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{source}
|
{applications.map(item => (
|
||||||
|
<Link key={item.appName} to={`/applications/${item.appName}`}>
|
||||||
|
Link: {item.appName}
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import ApplicationList from './application-list-component';
|
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;
|
||||||
|
@ -27,6 +27,7 @@ class EditFeatureToggleWrapper extends React.Component {
|
|||||||
this.props.fetchSeenApps();
|
this.props.fetchSeenApps();
|
||||||
this.props.fetchFeatureMetrics();
|
this.props.fetchFeatureMetrics();
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
|
this.props.fetchSeenApps();
|
||||||
this.props.fetchFeatureMetrics();
|
this.props.fetchFeatureMetrics();
|
||||||
}, 5000);
|
}, 5000);
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,13 @@ function fetchAll () {
|
|||||||
.then(response => response.json());
|
.then(response => response.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function fetchApplication (appName) {
|
||||||
|
return fetch(`${URI}/${appName}`, { headers })
|
||||||
|
.then(throwIfNotSuccess)
|
||||||
|
.then(response => response.json());
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
fetchApplication,
|
||||||
fetchAll,
|
fetchAll,
|
||||||
};
|
};
|
||||||
|
@ -18,6 +18,7 @@ import HistoryPage from './page/history';
|
|||||||
import HistoryTogglePage from './page/history/toggle';
|
import HistoryTogglePage from './page/history/toggle';
|
||||||
import Archive from './page/archive';
|
import Archive from './page/archive';
|
||||||
import Applications from './page/applications';
|
import Applications from './page/applications';
|
||||||
|
import ApplicationView from './page/applications/view';
|
||||||
import ClientStrategies from './page/client-strategies';
|
import ClientStrategies from './page/client-strategies';
|
||||||
|
|
||||||
const unleashStore = createStore(
|
const unleashStore = createStore(
|
||||||
@ -41,6 +42,7 @@ ReactDOM.render(
|
|||||||
<Route pageTitle="History" path="/history/:toggleName" component={HistoryTogglePage} />
|
<Route pageTitle="History" path="/history/:toggleName" component={HistoryTogglePage} />
|
||||||
<Route pageTitle="Archive" path="/archive" component={Archive} />
|
<Route pageTitle="Archive" path="/archive" component={Archive} />
|
||||||
<Route pageTitle="Applications" path="/applications" component={Applications} />
|
<Route pageTitle="Applications" path="/applications" component={Applications} />
|
||||||
|
<Route pageTitle="Applications" path="/applications/:name" component={ApplicationView} />
|
||||||
<Route pageTitle="Client strategies" ppath="/client-strategies" component={ClientStrategies} />
|
<Route pageTitle="Client strategies" ppath="/client-strategies" component={ClientStrategies} />
|
||||||
</Route>
|
</Route>
|
||||||
</Router>
|
</Router>
|
||||||
|
6
frontend/src/page/applications/view.js
Normal file
6
frontend/src/page/applications/view.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import ApplicationEditComponent from '../../component/application/application-edit-container';
|
||||||
|
|
||||||
|
const render = ({ params }) => <ApplicationEditComponent appName={params.name} />;
|
||||||
|
|
||||||
|
export default render;
|
@ -1,20 +1,34 @@
|
|||||||
import api from '../../data/applications-api';
|
import api from '../../data/applications-api';
|
||||||
|
|
||||||
export const RECEIVE_APPLICATINS = 'RECEIVE_APPLICATINS';
|
export const RECEIVE_ALL_APPLICATIONS = 'RECEIVE_ALL_APPLICATIONS';
|
||||||
export const ERROR_RECEIVE_APPLICATINS = 'ERROR_RECEIVE_APPLICATINS';
|
export const ERROR_RECEIVE_ALL_APPLICATIONS = 'ERROR_RECEIVE_ALL_APPLICATIONS';
|
||||||
|
|
||||||
const recieveApplications = (json) => ({
|
export const RECEIVE_APPLICATION = 'RECEIVE_APPLICATION';
|
||||||
type: RECEIVE_APPLICATINS,
|
|
||||||
|
const recieveAllApplications = (json) => ({
|
||||||
|
type: RECEIVE_ALL_APPLICATIONS,
|
||||||
|
value: json,
|
||||||
|
});
|
||||||
|
|
||||||
|
const recieveApplication = (json) => ({
|
||||||
|
type: RECEIVE_APPLICATION,
|
||||||
value: json,
|
value: json,
|
||||||
});
|
});
|
||||||
|
|
||||||
const errorReceiveApplications = (statusCode) => ({
|
const errorReceiveApplications = (statusCode) => ({
|
||||||
type: ERROR_RECEIVE_APPLICATINS,
|
type: ERROR_RECEIVE_ALL_APPLICATIONS,
|
||||||
statusCode,
|
statusCode,
|
||||||
});
|
});
|
||||||
|
|
||||||
export function fetchApplications () {
|
export function fetchAll () {
|
||||||
return dispatch => api.fetchAll()
|
return dispatch => api.fetchAll()
|
||||||
.then(json => dispatch(recieveApplications(json)))
|
.then(json => dispatch(recieveAllApplications(json)))
|
||||||
.catch(error => dispatch(errorReceiveApplications(error)));
|
.catch(error => dispatch(errorReceiveApplications(error)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function fetchApplication (appName) {
|
||||||
|
return dispatch => api.fetchApplication(appName)
|
||||||
|
.then(json => dispatch(recieveApplication(json)))
|
||||||
|
.catch(error => dispatch(errorReceiveApplications(error)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
import { fromJS } from 'immutable';
|
import { fromJS, List, Map } from 'immutable';
|
||||||
import { RECEIVE_APPLICATINS } from './actions';
|
import { RECEIVE_ALL_APPLICATIONS, RECEIVE_APPLICATION } from './actions';
|
||||||
|
|
||||||
function getInitState () {
|
function getInitState () {
|
||||||
return fromJS([]);
|
return fromJS({ list: [], apps: {} });
|
||||||
}
|
}
|
||||||
|
|
||||||
const store = (state = getInitState(), action) => {
|
const store = (state = getInitState(), action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case RECEIVE_APPLICATINS:
|
case RECEIVE_APPLICATION:
|
||||||
return fromJS(action.value.applications);
|
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:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user