1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-02-09 00:18:00 +01:00

Split feature toggle view in smaller components

This commit is contained in:
ivaosthu 2016-12-19 19:55:44 +01:00
parent b42742e992
commit d63e05abc0
3 changed files with 157 additions and 159 deletions

View File

@ -0,0 +1,66 @@
import React, { PropTypes } from 'react';
import { Grid, Cell, Icon } from 'react-mdl';
import Progress from './progress';
import { AppsLinkList, SwitchWithLabel, calc } from '../common';
const MetricComponent = ({ metrics, featureToggle, toggleFeature }) => {
const {
lastHour = { yes: 0, no: 0, isFallback: true },
lastMinute = { yes: 0, no: 0, isFallback: true },
seenApps = [],
} = metrics;
const lastHourPercent = 1 * calc(lastHour.yes, lastHour.yes + lastHour.no, 0);
const lastMinutePercent = 1 * calc(lastMinute.yes, lastMinute.yes + lastMinute.no, 0);
return (<div>
<SwitchWithLabel
checked={featureToggle.enabled}
onChange={() => toggleFeature(featureToggle)}>Toggle {featureToggle.name}</SwitchWithLabel>
<hr />
<Grid style={{ textAlign: 'center' }}>
<Cell tablet={4} col={3} phone={12}>
{
lastMinute.isFallback ?
<Icon style={{ width: '100px', height: '100px', fontSize: '100px', color: '#ccc' }}
name="report problem" title="No metrics avaiable" /> :
<div>
<Progress animatePercentageText strokeWidth={10} percentage={lastMinutePercent} width="50" />
</div>
}
<p><strong>Last minute</strong><br /> Yes {lastMinute.yes}, No: {lastMinute.no}</p>
</Cell>
<Cell col={3} tablet={4} phone={12}>
{
lastHour.isFallback ?
<Icon style={{ width: '100px', height: '100px', fontSize: '100px', color: '#ccc' }}
name="report problem" title="No metrics avaiable" /> :
<div>
<Progress strokeWidth={10} percentage={lastHourPercent} width="50" />
</div>
}
<p><strong>Last hour</strong><br /> Yes {lastHour.yes}, No: {lastHour.no}</p>
</Cell>
<Cell col={6} tablet={12}>
{seenApps.length > 0 ?
(<div><strong>Seen in applications:</strong></div>) :
<div>
<Icon style={{ width: '100px', height: '100px', fontSize: '100px', color: '#ccc' }}
name="report problem" title="Not used in a app in the last hour" />
<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>
}
<AppsLinkList apps={seenApps} />
</Cell>
</Grid>
</div>);
};
MetricComponent.propTypes = {
metrics: PropTypes.object,
featureToggle: PropTypes.object,
toggleFeature: PropTypes.object,
};
export default MetricComponent;

View File

@ -0,0 +1,88 @@
import React, { PropTypes } from 'react';
import { Tabs, Tab, ProgressBar, List, ListItem, ListItemContent } from 'react-mdl';
import { Link } from 'react-router';
import HistoryComponent from '../history/history-list-toggle-container';
import MetricComponent from './metric-component';
import EditFeatureToggle from './form-edit-container.jsx';
import { getIcon } from '../common';
export default class ViewFeatureToggleComponent extends React.Component {
constructor (props) {
super(props);
this.state = { activeTab: 0 };
}
static propTypes () {
return {
featureToggleName: PropTypes.string.isRequired,
features: PropTypes.array.isRequired,
fetchFeatureToggles: PropTypes.array.isRequired,
};
}
componentWillMount () {
if (this.props.features.length === 0) {
this.props.fetchFeatureToggles();
}
this.props.fetchSeenApps();
this.props.fetchFeatureMetrics();
this.timer = setInterval(() => {
this.props.fetchFeatureMetrics();
}, 5000);
}
componentWillUnmount () {
clearInterval(this.timer);
}
render () {
const {
toggleFeature,
features,
featureToggleName,
metrics = {},
} = this.props;
const featureToggle = features.find(toggle => toggle.name === featureToggleName);
if (!featureToggle) {
if (features.length === 0 ) {
return <ProgressBar indeterminate />;
}
return <span>Could not find the toggle "{this.props.featureToggleName}"</span>;
}
let tabContent;
if (this.state.activeTab === 0) {
tabContent = <MetricComponent metrics={metrics} toggleFeature={toggleFeature} featureToggle={featureToggle} />;
} else if (this.state.activeTab === 1) {
tabContent = <EditFeatureToggle featureToggle={featureToggle} />;
} else {
tabContent = <HistoryComponent toggleName={featureToggleName} />;
}
return (
<div>
<h4>{featureToggle.name} <small>{featureToggle.enabled ? 'is enabled' : 'is disabled'}</small>
<small style={{ float: 'right', lineHeight: '38px' }}>
Created {(new Date(featureToggle.createdAt)).toLocaleString('nb-NO')}
</small>
</h4>
<div>{featureToggle.description}</div>
<Tabs activeTab={this.state.activeTab}
onChange={(tabId) => this.setState({ activeTab: tabId })}
ripple
style={{ marginBottom: '10px' }}>
<Tab>Metrics</Tab>
<Tab>Edit</Tab>
<Tab>History</Tab>
</Tabs>
{tabContent}
</div>
);
}
}

View File

@ -1,167 +1,11 @@
import React, { PropTypes } from 'react';
import { Tabs, Tab, Grid, Cell, Icon, ProgressBar, List, ListItem, ListItemContent } from 'react-mdl';
import { Link } from 'react-router';
import Progress from './progress';
import { connect } from 'react-redux';
import EditFeatureToggle from './form-edit-container.jsx';
import { fetchFeatureToggles, toggleFeature } from '../../store/feature-actions';
import { fetchFeatureMetrics, fetchSeenApps } from '../../store/feature-metrics-actions';
import { fetchHistoryForToggle } from '../../store/history-actions';
import { AppsLinkList, SwitchWithLabel, getIcon, calc } from '../common';
const MetricTab = ({ metrics, featureToggle, toggleFeature }) => {
const {
lastHour = { yes: 0, no: 0, isFallback: true },
lastMinute = { yes: 0, no: 0, isFallback: true },
seenApps = [],
} = metrics;
const lastHourPercent = 1 * calc(lastHour.yes, lastHour.yes + lastHour.no, 0);
const lastMinutePercent = 1 * calc(lastMinute.yes, lastMinute.yes + lastMinute.no, 0);
return (<div>
<SwitchWithLabel
checked={featureToggle.enabled}
onChange={() => toggleFeature(featureToggle)}>Toggle {featureToggle.name}</SwitchWithLabel>
<hr />
<Grid style={{ textAlign: 'center' }}>
<Cell tablet={4} col={3} phone={12}>
{
lastMinute.isFallback ?
<Icon style={{ width: '100px', height: '100px', fontSize: '100px', color: '#ccc' }}
name="report problem" title="No metrics avaiable" /> :
<div>
<Progress animatePercentageText strokeWidth={10} percentage={lastMinutePercent} width="50" />
</div>
}
<p><strong>Last minute</strong><br /> Yes {lastMinute.yes}, No: {lastMinute.no}</p>
</Cell>
<Cell col={3} tablet={4} phone={12}>
{
lastHour.isFallback ?
<Icon style={{ width: '100px', height: '100px', fontSize: '100px', color: '#ccc' }}
name="report problem" title="No metrics avaiable" /> :
<div>
<Progress strokeWidth={10} percentage={lastHourPercent} width="50" />
</div>
}
<p><strong>Last hour</strong><br /> Yes {lastHour.yes}, No: {lastHour.no}</p>
</Cell>
<Cell col={6} tablet={12}>
{seenApps.length > 0 ?
(<div><strong>Seen in applications:</strong></div>) :
<div>
<Icon style={{ width: '100px', height: '100px', fontSize: '100px', color: '#ccc' }}
name="report problem" title="Not used in a app in the last hour" />
<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>
}
<AppsLinkList apps={seenApps} />
</Cell>
</Grid>
</div>);
};
class EditFeatureToggleWrapper extends React.Component {
constructor (props) {
super(props);
this.state = { activeTab: 0 };
}
static propTypes () {
return {
featureToggleName: PropTypes.string.isRequired,
features: PropTypes.array.isRequired,
fetchFeatureToggles: PropTypes.array.isRequired,
};
}
componentWillMount () {
if (this.props.features.length === 0) {
this.props.fetchFeatureToggles();
}
this.props.fetchSeenApps();
this.props.fetchHistoryForToggle(this.props.featureToggleName);
this.props.fetchFeatureMetrics();
this.timer = setInterval(() => {
this.props.fetchFeatureMetrics();
}, 5000);
}
componentWillUnmount () {
clearInterval(this.timer);
}
render () {
const {
history,
toggleFeature,
features,
featureToggleName,
metrics = {},
} = this.props;
const featureToggle = features.find(toggle => toggle.name === featureToggleName);
if (!featureToggle) {
if (features.length === 0 ) {
return <ProgressBar indeterminate />;
}
return <span>Could not find the toggle "{this.props.featureToggleName}"</span>;
}
let tabContent;
if (this.state.activeTab === 0) {
tabContent = <MetricTab metrics={metrics} toggleFeature={toggleFeature} featureToggle={featureToggle} />;
} else if (this.state.activeTab === 1) {
tabContent = <EditFeatureToggle featureToggle={featureToggle} />;
} else {
tabContent = (
<div>
<List style={{ textAlign: 'left' }}>
{history.map(({ createdAt, type, createdBy }, i) =>
<ListItem twoLine key={i}>
<ListItemContent title={type} avatar={getIcon(type)} subtitle={createdAt}>
{type} <small>{createdBy}</small>
</ListItemContent>
</ListItem>)}
</List>
<Link to={`/history/${featureToggleName}`}>
See all events.
</Link>
</div>
);
}
return (
<div>
<h4>{featureToggle.name} <small>{featureToggle.enabled ? 'is enabled' : 'is disabled'}</small>
<small style={{ float: 'right', lineHeight: '38px' }}>
Created {(new Date(featureToggle.createdAt)).toLocaleString('nb-NO')}
</small>
</h4>
<div>{featureToggle.description}</div>
<Tabs activeTab={this.state.activeTab}
onChange={(tabId) => this.setState({ activeTab: tabId })}
ripple
style={{ marginBottom: '10px' }}>
<Tab>Metrics</Tab>
<Tab>Edit</Tab>
<Tab>History</Tab>
</Tabs>
{tabContent}
</div>
);
}
}
import ViewToggleComponent from './view-component';
function getMetricsForToggle (state, toggleName) {
if (!toggleName) {
@ -210,4 +54,4 @@ export default connect((state, props) => ({
toggleFeature,
fetchSeenApps,
fetchHistoryForToggle,
})(EditFeatureToggleWrapper);
})(ViewToggleComponent);