1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-08-04 13:48:56 +02:00

applications

This commit is contained in:
sveisvei 2016-12-09 14:02:36 +01:00
parent 4c343adb34
commit 946f9af733
6 changed files with 131 additions and 47 deletions

View File

@ -1,10 +1,31 @@
import React, { PureComponent } from 'react'; /* eslint react/no-multi-comp:off */
import React, { Component, PureComponent } from 'react';
import { Link } from 'react-router'; import { Link } from 'react-router';
import { Grid, Cell } from 'react-mdl'; import { Grid, Cell, List, ListItem, ListItemContent, Textfield, Icon } from 'react-mdl';
class StatefulTextfield extends Component {
constructor (props) {
super(props);
this.state = { value: props.value };
this.setValue = function setValue (e) {
this.setState({ value: e.target.value });
}.bind(this);
}
render () {
return (<Textfield label={this.props.label}
floatingLabel
rows={this.props.rows}
value={this.state.value}
onChange={this.setValue}
onBlur={this.props.onBlur} />
);
}
}
class ClientStrategies extends PureComponent { class ClientStrategies extends PureComponent {
componentDidMount () { componentDidMount () {
this.props.fetchApplication(this.props.appName); this.props.fetchApplication(this.props.appName);
} }
@ -13,44 +34,76 @@ class ClientStrategies extends PureComponent {
if (!this.props.application) { if (!this.props.application) {
return <div>Loading application info...</div>; return <div>Loading application info...</div>;
} }
const {
application,
storeApplicationMetaData,
} = this.props;
const { const {
appName, appName,
instances, instances,
strategies, strategies,
seenToggles, seenToggles,
} = this.props.application; data = {},
} = application;
return ( return (
<div> <div>
<h5>{appName}</h5> <h5><Icon name={data.icon || 'apps'} /> {appName}</h5>
{data.description && <p>{data.description} </p>}
<Grid> <Grid>
<Cell col={4}> <Cell col={3}>
<h6>Instances</h6> <h6> Toggles</h6>
<ol className="demo-list-item mdl-list"> <hr />
{instances.map(({ instanceId }, i) => <li className="mdl-list__item" key={i}>{instanceId}</li>)} <List>
</ol> {seenToggles.map((name, i) =>
</Cell> <ListItem key={i}>
<Cell col={4}> <ListItemContent icon="check box">
<h6>Implemented strategies</h6> <Link to={`/features/edit/${name}`}>
<ol className="demo-list-item mdl-list">
{strategies.map((name, i) => (
<li className="mdl-list__item" key={`${name}-${i}`}>
<Link to={`/strategies/view/${name}`}>
{name} {name}
</Link> </Link>
</li> </ListItemContent>
))} </ListItem>)}
</ol> </List>
</Cell> </Cell>
<Cell col={4}> <Cell col={3}>
<h6>Toggles</h6> <h6>Implemented strategies</h6>
<ol className="demo-list-item mdl-list"> <hr />
{seenToggles.map((name, i) => <li className="mdl-list__item" key={i}> <List>
<Link to={`/features/edit/${name}`}> {strategies.map((name, i) => (
{name} <ListItem key={`${name}-${i}`}>
</Link> <ListItemContent icon="toc">
</li>)} <Link to={`/strategies/view/${name}`}>
</ol> {name}
</Link>
</ListItemContent>
</ListItem>
))}
</List>
</Cell>
<Cell col={6}>
<h6>{instances.length} Instances connected</h6>
<hr />
<List>
{instances.map(({ instanceId, clientIp, lastSeen }, i) => (
<ListItem key={i} twoLine>
<ListItemContent icon="timeline" subtitle={<span>{clientIp} last seen at <small>{new Date(lastSeen).toLocaleString('nb-NO')}</small></span>}>
{instanceId}
</ListItemContent>
</ListItem>
))}
</List>
</Cell>
<Cell col={12}>
<h5>Edit app meta data</h5>
</Cell>
<Cell col={6}>
<StatefulTextfield value={data.url} label="URL" onBlur={(e) => storeApplicationMetaData(appName, 'url', e.target.value)} /><br />
<StatefulTextfield value={data.description} label="Description" rows={5} onBlur={(e) => storeApplicationMetaData(appName, 'description', e.target.value)} />
</Cell>
<Cell col={6}>
<StatefulTextfield value={data.icon} label="Select icon" onBlur={(e) => storeApplicationMetaData(appName, 'icon', e.target.value)} />
<StatefulTextfield value={data.color} label="Select color" onBlur={(e) => storeApplicationMetaData(appName, 'color', e.target.value)} />
</Cell> </Cell>
</Grid> </Grid>
</div> </div>

View File

@ -1,6 +1,6 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import ApplicationEdit from './application-edit-component'; import ApplicationEdit from './application-edit-component';
import { fetchApplication } from '../../store/application/actions'; import { fetchApplication, storeApplicationMetaData } from '../../store/application/actions';
const mapStateToProps = (state, props) => { const mapStateToProps = (state, props) => {
let application = state.applications.getIn(['apps', props.appName]); let application = state.applications.getIn(['apps', props.appName]);
@ -12,6 +12,9 @@ const mapStateToProps = (state, props) => {
}; };
}; };
const Constainer = connect(mapStateToProps, { fetchApplication })(ApplicationEdit); const Constainer = connect(mapStateToProps, {
fetchApplication,
storeApplicationMetaData,
})(ApplicationEdit);
export default Constainer; export default Constainer;

View File

@ -1,4 +1,5 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { List, ListItem, ListItemContent } from 'react-mdl';
import { Link } from 'react-router'; import { Link } from 'react-router';
class ClientStrategies extends Component { class ClientStrategies extends Component {
@ -17,15 +18,19 @@ class ClientStrategies extends Component {
} }
return ( return (
<div> <div>
<ul> <h5>Applications</h5>
{applications.map(item => ( <hr />
<li> <List>
<Link key={item.appName} to={`/applications/${item.appName}`}> {applications.map(({ appName, data = {} }) => (
Link: {item.appName} <ListItem key={appName} twoLine>
</Link> <ListItemContent avatar={data.icon || 'apps'} subtitle={data.description}>
</li> <Link to={`/applications/${appName}`}>
{appName}
</Link>
</ListItemContent>
</ListItem>
))} ))}
</ul> </List>
</div> </div>
); );
} }

View File

@ -105,12 +105,17 @@ class EditFeatureToggleWrapper extends React.Component {
<div><small><strong>Not used in a app in the last hour.</strong> This might be due to your client implementation is not reporting usage.</small></div> <div><small><strong>Not used in a app in the last hour.</strong> This might be due to your client implementation is not reporting usage.</small></div>
</div> </div>
} }
{seenApps.length > 0 && seenApps.map((appName) => ( <List style={{ textAlign: 'left' }}>
<Link key={appName} to={`/applications/${appName}`}> {seenApps.length > 0 && seenApps.map(({ appName, data = {} }) => (
{appName} <ListItem twoLine>
</Link> <ListItemContent avatar={data.icon || 'apps'} subtitle={data.description || '-'}>
<Link key={appName} to={`/applications/${appName}`}>
{appName}
</Link>
</ListItemContent>
</ListItem>
))} ))}
<p>add instances count?</p> </List>
</Cell> </Cell>
<Cell col={3}> <Cell col={3}>
<div><strong>History</strong></div> <div><strong>History</strong></div>

View File

@ -20,8 +20,20 @@ function fetchApplicationsWithStrategyName (strategyName) {
.then(response => response.json()); .then(response => response.json());
} }
function storeApplicationMetaData (appName, key, value) {
const data = {};
data[key] = value;
return fetch(`${URI}/${appName}`, {
method: 'POST',
headers,
body: JSON.stringify(data),
credentials: 'include',
}).then(throwIfNotSuccess);
}
module.exports = { module.exports = {
fetchApplication, fetchApplication,
fetchAll, fetchAll,
fetchApplicationsWithStrategyName, fetchApplicationsWithStrategyName,
storeApplicationMetaData,
}; };

View File

@ -2,6 +2,7 @@ import api from '../../data/applications-api';
export const RECEIVE_ALL_APPLICATIONS = 'RECEIVE_ALL_APPLICATIONS'; export const RECEIVE_ALL_APPLICATIONS = 'RECEIVE_ALL_APPLICATIONS';
export const ERROR_RECEIVE_ALL_APPLICATIONS = 'ERROR_RECEIVE_ALL_APPLICATIONS'; export const ERROR_RECEIVE_ALL_APPLICATIONS = 'ERROR_RECEIVE_ALL_APPLICATIONS';
export const ERROR_UPDATING_APPLICATION_DATA = 'ERROR_UPDATING_APPLICATION_DATA';
export const RECEIVE_APPLICATION = 'RECEIVE_APPLICATION'; export const RECEIVE_APPLICATION = 'RECEIVE_APPLICATION';
@ -15,8 +16,8 @@ const recieveApplication = (json) => ({
value: json, value: json,
}); });
const errorReceiveApplications = (statusCode) => ({ const errorReceiveApplications = (statusCode, type = ERROR_RECEIVE_ALL_APPLICATIONS) => ({
type: ERROR_RECEIVE_ALL_APPLICATIONS, type,
statusCode, statusCode,
}); });
@ -26,6 +27,11 @@ export function fetchAll () {
.catch(error => dispatch(errorReceiveApplications(error))); .catch(error => dispatch(errorReceiveApplications(error)));
} }
export function storeApplicationMetaData (appName, key, value) {
return dispatch => api.storeApplicationMetaData(appName, key, value)
.catch(error => dispatch(errorReceiveApplications(error, ERROR_UPDATING_APPLICATION_DATA)));
}
export function fetchApplication (appName) { export function fetchApplication (appName) {
return dispatch => api.fetchApplication(appName) return dispatch => api.fetchApplication(appName)
.then(json => dispatch(recieveApplication(json))) .then(json => dispatch(recieveApplication(json)))