mirror of
https://github.com/Unleash/unleash.git
synced 2024-12-22 19:07:54 +01:00
moved remove feature button from list to view
This commit is contained in:
parent
b93b27993e
commit
5cfc5b0861
@ -2,4 +2,14 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.divider {
|
||||||
|
border-color: #e1e1e1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 960px) {
|
||||||
|
.hideLt960 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -9,6 +9,8 @@ const {
|
|||||||
} = require('react-mdl');
|
} = require('react-mdl');
|
||||||
const { Link } = require('react-router');
|
const { Link } = require('react-router');
|
||||||
|
|
||||||
|
export { styles };
|
||||||
|
|
||||||
export const shorten = (str, len = 50) => (str && str.length > len ? `${str.substring(0, len)}...` : str);
|
export const shorten = (str, len = 50) => (str && str.length > len ? `${str.substring(0, len)}...` : str);
|
||||||
|
|
||||||
export const AppsLinkList = ({ apps }) => (
|
export const AppsLinkList = ({ apps }) => (
|
||||||
@ -52,10 +54,10 @@ export const FormButtons = ({ submitText = 'Create', onCancel }) => (
|
|||||||
|
|
||||||
export const SwitchWithLabel = ({ onChange, children, checked }) => (
|
export const SwitchWithLabel = ({ onChange, children, checked }) => (
|
||||||
<span>
|
<span>
|
||||||
<span style={{ cursor: 'pointer', display: 'inline-block', width: '45px' }}>
|
<span style={{ cursor: 'pointer', display: 'inline-block', width: '52px' }}>
|
||||||
<Switch onChange={onChange} checked={checked} />
|
<Switch onChange={onChange} checked={checked} />
|
||||||
</span>
|
</span>
|
||||||
<span>{children}</span>
|
<span style={{ fontSize: '16px', lineHeight: '24px' }}>{children}</span>
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
import React, { PropTypes } from 'react';
|
import React, { PropTypes } from 'react';
|
||||||
import { Link } from 'react-router';
|
import { Link } from 'react-router';
|
||||||
import { Switch, Icon, IconButton } from 'react-mdl';
|
import { Chip, Switch, Icon } from 'react-mdl';
|
||||||
import Progress from './progress';
|
import Progress from './progress';
|
||||||
import { shorten, calc } from '../common';
|
import { shorten, calc, styles as commonStyles } from '../common';
|
||||||
|
|
||||||
import style from './feature.scss';
|
import styles from './feature.scss';
|
||||||
|
|
||||||
const Feature = ({
|
const Feature = ({
|
||||||
feature,
|
feature,
|
||||||
onFeatureClick,
|
onFeatureClick,
|
||||||
onFeatureRemove,
|
|
||||||
settings,
|
settings,
|
||||||
metricsLastHour = { yes: 0, no: 0, isFallback: true },
|
metricsLastHour = { yes: 0, no: 0, isFallback: true },
|
||||||
metricsLastMinute = { yes: 0, no: 0, isFallback: true },
|
metricsLastMinute = { yes: 0, no: 0, isFallback: true },
|
||||||
@ -24,44 +23,34 @@ const Feature = ({
|
|||||||
calc(metricsLastMinute.yes, metricsLastMinute.yes + metricsLastMinute.no, 0)
|
calc(metricsLastMinute.yes, metricsLastMinute.yes + metricsLastMinute.no, 0)
|
||||||
);
|
);
|
||||||
|
|
||||||
const removeToggle = () => {
|
|
||||||
if (window.confirm('Are you sure you want to remove this toggle?')) { // eslint-disable-line no-alert
|
|
||||||
onFeatureRemove(name);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li key={name} className="mdl-list__item mdl-list__item--two-line">
|
<li key={name} className="mdl-list__item mdl-list__item--two-line">
|
||||||
<span className="mdl-list__item-secondary-action">
|
<span className={styles.iconListItemProgress}>
|
||||||
<div style={{ width: '40px', textAlign: 'center', marginRight: '5px' }}>
|
<div style={{ width: '40px', textAlign: 'center' }}>
|
||||||
{
|
{
|
||||||
isStale ?
|
isStale ?
|
||||||
<Icon
|
<Icon
|
||||||
style={{ width: '25px', marginTop: '4px', fontSize: '25px', color: '#ccc' }}
|
style={{ width: '25px', marginTop: '4px', fontSize: '25px', color: '#ccc' }}
|
||||||
name="report problem" title="No metrics avaiable" /> :
|
name="report problem" title="No metrics available" /> :
|
||||||
<div>
|
<div>
|
||||||
<Progress strokeWidth={15} percentage={percent} width="50" />
|
<Progress strokeWidth={15} percentage={percent} width="50" />
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
<span className="mdl-list__item-secondary-action" style={{ width: '45px' }} title={`Toggle ${name}`}>
|
<span className={styles.iconListItemToggle}>
|
||||||
<Switch title="test" key="left-actions" onChange={() => onFeatureClick(feature)} checked={enabled} />
|
<Switch title={`Toggle ${name}`} key="left-actions" onChange={() => onFeatureClick(feature)} checked={enabled} />
|
||||||
</span>
|
</span>
|
||||||
<span className="mdl-list__item-primary-content">
|
<span className={['mdl-list__item-primary-content', commonStyles.truncate].join(' ')}>
|
||||||
<Link to={`/features/view/${name}`} className={style.link} style={{ display: 'inline-block', width: '100%' }}>
|
<Link to={`/features/view/${name}`} className={[styles.link, commonStyles.truncate].join(' ')}>
|
||||||
{shorten(name, 75)} <small className={[style.hideLt960, 'mdl-list__item-sub-title'].join(' ')}>
|
{shorten(name, 75)}
|
||||||
{shorten(description, 75) || ''}</small>
|
<span className={['mdl-list__item-sub-title', commonStyles.truncate].join(' ')}>{shorten(description, 75) || ''}</span>
|
||||||
</Link>
|
</Link>
|
||||||
</span>
|
</span>
|
||||||
|
<span className={commonStyles.hideLt960}>
|
||||||
<span className="mdl-list__item-secondary-action">
|
{strategies && strategies.map((s, i) => <Chip className={styles.iconListItemChip} key={i}>
|
||||||
{strategies && strategies.map((s, i) => <span className={[style.iconListItemChip, style.hideLt960].join(' ')} key={i}>
|
|
||||||
{s.name}
|
{s.name}
|
||||||
</span>)}
|
</Chip>)}
|
||||||
</span>
|
|
||||||
<span className="mdl-list__item-secondary-action">
|
|
||||||
<IconButton name="delete" onClick={removeToggle} className={style.iconListItem} />
|
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
@ -70,7 +59,6 @@ const Feature = ({
|
|||||||
Feature.propTypes = {
|
Feature.propTypes = {
|
||||||
feature: PropTypes.object,
|
feature: PropTypes.object,
|
||||||
onFeatureClick: PropTypes.func,
|
onFeatureClick: PropTypes.func,
|
||||||
onFeatureRemove: PropTypes.func,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Feature;
|
export default Feature;
|
||||||
|
@ -14,30 +14,26 @@
|
|||||||
.link {
|
.link {
|
||||||
color: #212121;
|
color: #212121;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
font-weight: normal;
|
||||||
|
display: block;
|
||||||
.link small {
|
|
||||||
color: #aaa;
|
|
||||||
font-weight: 100;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.link:hover {
|
.link:hover {
|
||||||
color: #000;
|
color: #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.iconListItem {
|
.iconListItemProgress {
|
||||||
color: #bbb !important;
|
float: left;
|
||||||
|
margin-right: 16px;
|
||||||
}
|
}
|
||||||
.iconListItem *:hover {
|
|
||||||
color: #333;
|
.iconListItemToggle {
|
||||||
|
float: left;
|
||||||
|
margin-right: 16px;
|
||||||
|
width: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.iconListItemChip {
|
.iconListItemChip {
|
||||||
font-size: 10px;
|
|
||||||
line-height: 12px;
|
|
||||||
background-color: #e0e0e0;
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 5px 8px 4px 8px;
|
|
||||||
margin-left: 5px !important;
|
margin-left: 5px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,9 +54,3 @@
|
|||||||
.topListItem2 {
|
.topListItem2 {
|
||||||
flex: 2;
|
flex: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 960px) {
|
|
||||||
.hideLt960 {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -10,7 +10,6 @@ export default class FeatureListComponent extends React.PureComponent {
|
|||||||
static propTypes () {
|
static propTypes () {
|
||||||
return {
|
return {
|
||||||
onFeatureClick: PropTypes.func.isRequired,
|
onFeatureClick: PropTypes.func.isRequired,
|
||||||
onFeatureRemove: PropTypes.func.isRequired,
|
|
||||||
features: PropTypes.array.isRequired,
|
features: PropTypes.array.isRequired,
|
||||||
featureMetrics: PropTypes.object.isRequired,
|
featureMetrics: PropTypes.object.isRequired,
|
||||||
fetchFeatureToggles: PropTypes.func.isRequired,
|
fetchFeatureToggles: PropTypes.func.isRequired,
|
||||||
@ -47,7 +46,7 @@ export default class FeatureListComponent extends React.PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { features, onFeatureClick, onFeatureRemove, featureMetrics, settings } = this.props;
|
const { features, onFeatureClick, featureMetrics, settings } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@ -104,8 +103,7 @@ export default class FeatureListComponent extends React.PureComponent {
|
|||||||
metricsLastHour={featureMetrics.lastHour[feature.name]}
|
metricsLastHour={featureMetrics.lastHour[feature.name]}
|
||||||
metricsLastMinute={featureMetrics.lastMinute[feature.name]}
|
metricsLastMinute={featureMetrics.lastMinute[feature.name]}
|
||||||
feature={feature}
|
feature={feature}
|
||||||
onFeatureClick={onFeatureClick}
|
onFeatureClick={onFeatureClick}/>
|
||||||
onFeatureRemove={onFeatureRemove}/>
|
|
||||||
)}
|
)}
|
||||||
</ul>
|
</ul>
|
||||||
<hr />
|
<hr />
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { toggleFeature, fetchFeatureToggles, removeFeatureToggle } from '../../store/feature-actions';
|
import { toggleFeature, fetchFeatureToggles } from '../../store/feature-actions';
|
||||||
import { fetchFeatureMetrics } from '../../store/feature-metrics-actions';
|
import { fetchFeatureMetrics } from '../../store/feature-metrics-actions';
|
||||||
import { updateSettingForGroup } from '../../store/settings/actions';
|
import { updateSettingForGroup } from '../../store/settings/actions';
|
||||||
|
|
||||||
@ -71,7 +71,6 @@ const mapStateToProps = (state) => {
|
|||||||
|
|
||||||
const mapDispatchToProps = {
|
const mapDispatchToProps = {
|
||||||
onFeatureClick: toggleFeature,
|
onFeatureClick: toggleFeature,
|
||||||
onFeatureRemove: removeFeatureToggle,
|
|
||||||
fetchFeatureToggles,
|
fetchFeatureToggles,
|
||||||
fetchFeatureMetrics,
|
fetchFeatureMetrics,
|
||||||
updateSetting: updateSettingForGroup('feature'),
|
updateSetting: updateSettingForGroup('feature'),
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import React, { PropTypes } from 'react';
|
import React, { PropTypes } from 'react';
|
||||||
import { Grid, Cell, Icon, Chip, ChipContact } from 'react-mdl';
|
import { Grid, Cell, Icon, Chip, ChipContact, IconButton } from 'react-mdl';
|
||||||
import Progress from './progress';
|
import Progress from './progress';
|
||||||
import { Link } from 'react-router';
|
import { Link, hashHistory } from 'react-router';
|
||||||
import { AppsLinkList, SwitchWithLabel, calc } from '../common';
|
import { AppsLinkList, SwitchWithLabel, calc, styles as commonStyles } from '../common';
|
||||||
import styles from './metrics.scss';
|
import styles from './metrics.scss';
|
||||||
|
|
||||||
const StrategyChipItem = ({ strategy }) => (
|
const StrategyChipItem = ({ strategy }) => (
|
||||||
@ -29,6 +29,7 @@ export default class MetricComponent extends React.Component {
|
|||||||
toggleFeature: PropTypes.func.isRequired,
|
toggleFeature: PropTypes.func.isRequired,
|
||||||
fetchSeenApps: PropTypes.func.isRequired,
|
fetchSeenApps: PropTypes.func.isRequired,
|
||||||
fetchFeatureMetrics: PropTypes.func.isRequired,
|
fetchFeatureMetrics: PropTypes.func.isRequired,
|
||||||
|
removeFeatureToggle: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +46,7 @@ export default class MetricComponent extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { metrics = {}, featureToggle, toggleFeature } = this.props;
|
const { metrics = {}, featureToggle, toggleFeature, removeFeatureToggle } = this.props;
|
||||||
const {
|
const {
|
||||||
lastHour = { yes: 0, no: 0, isFallback: true },
|
lastHour = { yes: 0, no: 0, isFallback: true },
|
||||||
lastMinute = { yes: 0, no: 0, isFallback: true },
|
lastMinute = { yes: 0, no: 0, isFallback: true },
|
||||||
@ -55,13 +56,24 @@ export default class MetricComponent extends React.Component {
|
|||||||
const lastHourPercent = 1 * calc(lastHour.yes, lastHour.yes + lastHour.no, 0);
|
const lastHourPercent = 1 * calc(lastHour.yes, lastHour.yes + lastHour.no, 0);
|
||||||
const lastMinutePercent = 1 * calc(lastMinute.yes, lastMinute.yes + lastMinute.no, 0);
|
const lastMinutePercent = 1 * calc(lastMinute.yes, lastMinute.yes + lastMinute.no, 0);
|
||||||
|
|
||||||
|
|
||||||
|
const removeToggle = () => {
|
||||||
|
if (window.confirm('Are you sure you want to remove this toggle?')) { // eslint-disable-line no-alert
|
||||||
|
removeFeatureToggle(featureToggle.name);
|
||||||
|
hashHistory.push('/features');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (<div>
|
return (<div>
|
||||||
<div style={{ paddingTop: '4px' }}>
|
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||||
<SwitchWithLabel
|
<span className={commonStyles.truncate} style={{ paddingTop: '4px' }}>
|
||||||
checked={featureToggle.enabled}
|
<SwitchWithLabel
|
||||||
onChange={() => toggleFeature(featureToggle)}>Toggle {featureToggle.name}</SwitchWithLabel>
|
checked={featureToggle.enabled}
|
||||||
|
onChange={() => toggleFeature(featureToggle)}>Toggle {featureToggle.name}</SwitchWithLabel>
|
||||||
|
</span>
|
||||||
|
<IconButton name="delete" onClick={removeToggle} className="mdl-color-text--grey-600"/>
|
||||||
</div>
|
</div>
|
||||||
<hr style={{ borderColor: '#e0e0e0' }} />
|
<hr className={commonStyles.divider}/>
|
||||||
<Grid style={{ textAlign: 'center' }}>
|
<Grid style={{ textAlign: 'center' }}>
|
||||||
<Cell tablet={4} col={3} phone={12}>
|
<Cell tablet={4} col={3} phone={12}>
|
||||||
{
|
{
|
||||||
@ -95,7 +107,7 @@ export default class MetricComponent extends React.Component {
|
|||||||
<AppsLinkList apps={seenApps} />
|
<AppsLinkList apps={seenApps} />
|
||||||
</Cell>
|
</Cell>
|
||||||
</Grid>
|
</Grid>
|
||||||
<hr style={{ borderColor: '#e0e0e0' }} />
|
<hr className={commonStyles.divider}/>
|
||||||
<StrategiesList strategies={featureToggle.strategies}/>
|
<StrategiesList strategies={featureToggle.strategies}/>
|
||||||
</div>);
|
</div>);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { fetchFeatureMetrics, fetchSeenApps } from '../../store/feature-metrics-actions';
|
import { fetchFeatureMetrics, fetchSeenApps } from '../../store/feature-metrics-actions';
|
||||||
import { toggleFeature } from '../../store/feature-actions';
|
import { toggleFeature, removeFeatureToggle } from '../../store/feature-actions';
|
||||||
|
|
||||||
import MatricComponent from './metric-component';
|
import MatricComponent from './metric-component';
|
||||||
|
|
||||||
@ -28,4 +28,5 @@ export default connect((state, props) => ({
|
|||||||
fetchFeatureMetrics,
|
fetchFeatureMetrics,
|
||||||
toggleFeature,
|
toggleFeature,
|
||||||
fetchSeenApps,
|
fetchSeenApps,
|
||||||
|
removeFeatureToggle,
|
||||||
})(MatricComponent);
|
})(MatricComponent);
|
||||||
|
Loading…
Reference in New Issue
Block a user