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

minor feature cleanup

This commit is contained in:
sveisvei 2016-10-24 18:48:24 +02:00
parent 90c9682634
commit 993785f264
11 changed files with 166 additions and 176 deletions

View File

@ -3,47 +3,47 @@ import { Input, Switch, Button } from 'react-toolbox';
import AddFeatureToggleStrategy from './AddFeatureToggleStrategy'; import AddFeatureToggleStrategy from './AddFeatureToggleStrategy';
import ConfiguredStrategies from './ConfiguredStrategies'; import ConfiguredStrategies from './ConfiguredStrategies';
class AddFeatureToggleUI extends React.Component { const AddFeatureToggleUI = ({
static propTypes () { strategies,
return { featureToggle,
strategies: PropTypes.array.required, updateField,
featureToggle: PropTypes.object, addStrategy,
updateField: PropTypes.func.required, removeStrategy,
addStrategy: PropTypes.func.required, onSubmit,
removeStrategy: PropTypes.func.required, onCancel,
onSubmit: PropTypes.func.required, editmode,
onCancel: PropTypes.func.required, }) => {
editmode: PropTypes.bool, const {
}; name, // eslint-disable-line
} description,
enabled,
render () { } = featureToggle;
const configuredStrategies = this.props.featureToggle.strategies; const configuredStrategies = featureToggle.strategies;
return ( return (
<form onSubmit={this.props.onSubmit}> <form onSubmit={onSubmit}>
<section> <section>
<Input <Input
type="text" type="text"
label="Name" label="Name"
name="name" name="name"
disabled={this.props.editmode} disabled={editmode}
required required
value={this.props.featureToggle.name} value={name}
onChange={this.props.updateField.bind(this, 'name')} /> onChange={updateField.bind(this, 'name')} />
<Input <Input
type="text" type="text"
multiline label="Description" multiline label="Description"
required required
value={this.props.featureToggle.description} value={description}
onChange={this.props.updateField.bind(this, 'description')} /> onChange={updateField.bind(this, 'description')} />
<br /> <br />
<Switch <Switch
checked={this.props.featureToggle.enabled} checked={enabled}
label="Enabled" label="Enabled"
onChange={this.props.updateField.bind(this, 'enabled')} /> onChange={updateField.bind(this, 'enabled')} />
<br /> <br />
</section> </section>
@ -52,23 +52,32 @@ class AddFeatureToggleUI extends React.Component {
<strong>Activation strategies</strong> <strong>Activation strategies</strong>
<ConfiguredStrategies <ConfiguredStrategies
configuredStrategies={configuredStrategies} configuredStrategies={configuredStrategies}
removeStrategy={this.props.removeStrategy} /> removeStrategy={removeStrategy} />
</section> </section>
<section> <section>
<AddFeatureToggleStrategy <AddFeatureToggleStrategy strategies={strategies} addStrategy={addStrategy} />
strategies={this.props.strategies}
addStrategy={this.props.addStrategy} />
</section> </section>
<br /> <br />
<Button type="submit" raised primary label={this.props.editmode ? 'Update' : 'Create'} /> <Button type="submit" raised primary label={editmode ? 'Update' : 'Create'} />
<Button type="cancel" raised label="Cancel" onClick={this.props.onCancel} /> &nbsp;
<Button type="cancel" raised label="Cancel" onClick={onCancel} />
</form> </form>
); );
} };
}
AddFeatureToggleUI.propTypes = {
strategies: PropTypes.array.required,
featureToggle: PropTypes.object,
updateField: PropTypes.func.required,
addStrategy: PropTypes.func.required,
removeStrategy: PropTypes.func.required,
onSubmit: PropTypes.func.required,
onCancel: PropTypes.func.required,
editmode: PropTypes.bool,
};
export default AddFeatureToggleUI; export default AddFeatureToggleUI;

View File

@ -2,9 +2,11 @@ import React, { PropTypes } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { editFeatureToggle } from '../../store/feature-actions'; import { editFeatureToggle } from '../../store/feature-actions';
import AddFeatureToggleUI from './AddFeatureToggleUI'; import AddFeatureToggleUI from './AddFeatureToggleUI';
import { fetchStrategies } from '../../store/strategy-actions';
const mapStateToProps = (state, ownProps) => ({ const mapStateToProps = (state, ownProps) => ({
strategies: state.strategies.toJS(), strategies: state.strategies.get('list').toArray(),
featureToggle: state.features.toJS().find(toggle => toggle.name === ownProps.featureToggleName) || {}, featureToggle: state.features.toJS().find(toggle => toggle.name === ownProps.featureToggleName) || {},
}); });
@ -28,6 +30,11 @@ class EditFeatureToggle extends React.Component {
}; };
} }
componentDidMount () {
// todo fetch feature if missing? (reload of page does not fetch data from url)
this.props.fetchStrategies();
}
static contextTypes = { static contextTypes = {
router: React.PropTypes.object, router: React.PropTypes.object,
} }
@ -62,7 +69,6 @@ class EditFeatureToggle extends React.Component {
render () { render () {
return ( return (
<div>
<AddFeatureToggleUI <AddFeatureToggleUI
editmode="true" editmode="true"
strategies={this.props.strategies} strategies={this.props.strategies}
@ -73,9 +79,8 @@ class EditFeatureToggle extends React.Component {
onSubmit={this.onSubmit} onSubmit={this.onSubmit}
onCancel={this.onCancel} onCancel={this.onCancel}
/> />
</div>
); );
} }
} }
export default connect(mapStateToProps)(EditFeatureToggle); export default connect(mapStateToProps, { fetchStrategies })(EditFeatureToggle);

View File

@ -1,33 +1,43 @@
/* eslint no-shadow: ["error", { "allow": ["name"] }]*/
import React, { PropTypes } from 'react'; import React, { PropTypes } from 'react';
import { Switch, FontIcon } from 'react-toolbox';
import { Link } from 'react-router';
const Feature = ({ onClick, name, enabled, strategies, onFeatureRemove }) => ( import { Link } from 'react-router';
<tr> import FontIcon from 'react-toolbox/lib/font_icon';
<td style={{ paddingTop: '1.5rem' }}><Switch onChange={onClick} checked={enabled} /></td> import Switch from 'react-toolbox/lib/switch';
<td> import { ListItem } from 'react-toolbox/lib/list';
import style from './feature.scss';
const Feature = ({ feature, onFeatureClick, onFeatureRemove }) => {
const { name, description, enabled, strategies } = feature; // eslint-disable-line no-shadow
const actions = [
strategies.map(s => s.name).join(', '),
<Link to={`/features/edit/${name}`} title={`Edit ${name}`}> <Link to={`/features/edit/${name}`} title={`Edit ${name}`}>
<FontIcon value="edit" className={style.action} />
</Link>,
<FontIcon className={style.action} value="delete" onClick={() => onFeatureRemove(name)} />,
];
const leftActions = [
<Switch onChange={() => onFeatureClick(feature)} checked={enabled} />,
];
return (
<ListItem
leftActions={leftActions}
rightActions={actions}
caption={<Link to={`/features/edit/${name}`} title={`Edit ${name}`} className={style.link}>
{name} {name}
</Link> </Link>}
</td> legend={(description && description.substring(0, 100)) || '-'}
<td>{strategies.map(s => s.name).join(', ')}</td> />
<td style={{ textAlign: 'right' }}> );
<Link to={`/features/edit/${name}`} title={`Edit ${name}`}> };
<FontIcon value="edit" />
</Link>
<FontIcon style={{ cursor: 'pointer' }} value="delete" onClick={onFeatureRemove} />
</td>
</tr>
);
Feature.propTypes = { Feature.propTypes = {
onClick: PropTypes.func.isRequired, feature: PropTypes.object,
onFeatureRemove: PropTypes.func.isRequired, onFeatureClick: PropTypes.func,
enabled: PropTypes.bool.isRequired, onFeatureRemove: PropTypes.func,
strategies: PropTypes.array.isRequired,
name: PropTypes.string.isRequired,
}; };
export default Feature; export default Feature;

View File

@ -1,11 +1,8 @@
import React, { PropTypes } from 'react'; import React, { PropTypes } from 'react';
import Feature from './Feature'; import Feature from './Feature';
import style from './table.scss'; import { List, ListItem, ListSubHeader, ListDivider } from 'react-toolbox/lib/list';
export default class FeatureList extends React.Component { export default class FeatureList extends React.Component {
constructor () {
super();
}
static propTypes () { static propTypes () {
return { return {
@ -16,35 +13,28 @@ export default class FeatureList extends React.Component {
}; };
} }
static contextTypes = {
router: React.PropTypes.object,
}
componentDidMount () { componentDidMount () {
this.props.fetchFeatureToggles(); this.props.fetchFeatureToggles();
} }
render () { render () {
const onFeatureClick = this.props.onFeatureClick; const { features, onFeatureClick, onFeatureRemove } = this.props;
const onFeatureRemove = this.props.onFeatureRemove;
const features = this.props.features.map(featureToggle =>
<Feature key={featureToggle.name}
{...featureToggle}
onClick={() => onFeatureClick(featureToggle)}
onFeatureRemove={() => onFeatureRemove(featureToggle.name)}
/>
);
return ( return (
<table className={style.ztable}> <List>
<thead> <ListSubHeader caption="Feature toggles" />
<tr> {features.map(feature =>
<th width="80">Enabled</th> <Feature feature={feature} onFeatureClick={onFeatureClick} onFeatureRemove={onFeatureRemove}/>
<th>Feature Toggle</th> )}
<th>Strategies</th> <ListDivider />
<th width="100" style={{ textAlign: 'right' }}>Actions</th> <ListItem
</tr> onClick={() => this.context.router.push('/features/create')}
</thead> caption="Add" legend="new feature toggle" leftIcon="add" />
<tbody> </List>
{features}
</tbody>
</table>
); );
} }
} }

View File

@ -4,7 +4,6 @@ import FeatureList from './FeatureList';
const mapStateToProps = (state) => ({ const mapStateToProps = (state) => ({
features: state.features.toJS(), features: state.features.toJS(),
strategies: state.strategies.toJS(),
}); });
const mapDispatchToProps = { const mapDispatchToProps = {

View File

@ -0,0 +1,8 @@
.link {
color: #212121;
}
.action {
color: #aaa !important;
cursor: pointer;
}

View File

@ -1,12 +0,0 @@
.ztable tbody tr:nth-child(odd) {
background-color: #efefef;
}
.ztable {
margin: 10px;
border-collapse: separate;
border-spacing: 0;
}
.ztable td, th {
padding: 4px 10px;
}

View File

@ -1,13 +1,11 @@
import React, { Component } from 'react'; import React from 'react';
import AddFeatureToggle from '../../component/feature/AddFeatureToggle'; import AddFeatureToggle from '../../component/feature/AddFeatureToggle';
export default class Features extends Component { const render = () => (
render () {
return (
<div> <div>
<h1>Create Feature Toggle</h1> <h3>Create feature toggle</h3>
<AddFeatureToggle /> <AddFeatureToggle />
</div> </div>
); );
}
}; export default render;

View File

@ -8,14 +8,10 @@ export default class Features extends Component {
}; };
} }
static contextTypes = {
router: React.PropTypes.object,
}
render () { render () {
return ( return (
<div> <div>
<h1>Edit Feature Toggle</h1> <h3>Edit feature toggle</h3>
<EditFeatureToggle featureToggleName={this.props.params.name} /> <EditFeatureToggle featureToggleName={this.props.params.name} />
</div> </div>
); );

View File

@ -1,21 +1,8 @@
import React, { Component } from 'react'; import React from 'react';
import FeatureListContainer from '../../component/feature/FeatureListContainer'; import FeatureListContainer from '../../component/feature/FeatureListContainer';
import { Button } from 'react-toolbox';
const render = () => (<FeatureListContainer />);
export default render;
export default class Features extends Component {
static contextTypes = {
router: React.PropTypes.object,
}
render () {
const createHref = this.context.router.createHref('/features/create');
return (
<div>
<h1>Feature Toggles</h1>
<Button href={createHref} icon="add" raised primary label="New Feature Toggle"/>
<FeatureListContainer />
</div>
);
}
};

View File

@ -4,7 +4,7 @@ export default class EventHisotry extends Component {
render () { render () {
return ( return (
<div> <div>
<h1>Event history</h1> <h2>Event history</h2>
</div> </div>
); );
} }