mirror of
https://github.com/Unleash/unleash.git
synced 2025-08-04 13:48:56 +02:00
applications
This commit is contained in:
parent
4c343adb34
commit
946f9af733
@ -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>
|
||||||
|
@ -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;
|
||||||
|
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
@ -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)))
|
||||||
|
Loading…
Reference in New Issue
Block a user