mirror of
https://github.com/Unleash/unleash.git
synced 2025-06-04 01:18:20 +02:00
Make edit strategy view
This commit is contained in:
parent
efcfcfa347
commit
398f46c561
@ -1,4 +1,4 @@
|
|||||||
import React, { PropTypes } from 'react';
|
import React, { PropTypes, Component } from 'react';
|
||||||
|
|
||||||
import { Textfield, IconButton, Menu, MenuItem, Checkbox } from 'react-mdl';
|
import { Textfield, IconButton, Menu, MenuItem, Checkbox } from 'react-mdl';
|
||||||
import { HeaderTitle, FormButtons } from '../common';
|
import { HeaderTitle, FormButtons } from '../common';
|
||||||
@ -65,15 +65,43 @@ const Parameters = ({ input = [], count = 0, updateInList }) => (
|
|||||||
/>)
|
/>)
|
||||||
}</div>);
|
}</div>);
|
||||||
|
|
||||||
const AddStrategy = ({
|
class AddStrategy extends Component {
|
||||||
|
|
||||||
|
static propTypes () {
|
||||||
|
return {
|
||||||
|
input: PropTypes.object,
|
||||||
|
setValue: PropTypes.func,
|
||||||
|
updateInList: PropTypes.func,
|
||||||
|
incValue: PropTypes.func,
|
||||||
|
clear: PropTypes.func,
|
||||||
|
onCancel: PropTypes.func,
|
||||||
|
onSubmit: PropTypes.func,
|
||||||
|
editmode: PropTypes.bool,
|
||||||
|
initCallRequired: PropTypes.bool,
|
||||||
|
init: PropTypes.func,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillMount () {
|
||||||
|
// TODO unwind this stuff
|
||||||
|
if (this.props.initCallRequired === true) {
|
||||||
|
this.props.init(this.props.input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const {
|
||||||
input,
|
input,
|
||||||
setValue,
|
setValue,
|
||||||
updateInList,
|
updateInList,
|
||||||
incValue,
|
incValue,
|
||||||
// clear,
|
|
||||||
onCancel,
|
onCancel,
|
||||||
|
editmode = false,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
}) => (
|
} = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
<form onSubmit={onSubmit(input)}>
|
<form onSubmit={onSubmit(input)}>
|
||||||
<HeaderTitle title="Create new strategy" subtitle="It is not possible to edit a strategy after it is created."/>
|
<HeaderTitle title="Create new strategy" subtitle="It is not possible to edit a strategy after it is created."/>
|
||||||
<section style={{ margin: '16px 20px' }}>
|
<section style={{ margin: '16px 20px' }}>
|
||||||
@ -81,6 +109,7 @@ const AddStrategy = ({
|
|||||||
floatingLabel
|
floatingLabel
|
||||||
name="name"
|
name="name"
|
||||||
required
|
required
|
||||||
|
disabled={editmode}
|
||||||
pattern="^[0-9a-zA-Z\.\-]+$"
|
pattern="^[0-9a-zA-Z\.\-]+$"
|
||||||
onChange={({ target }) => setValue('name', trim(target.value))}
|
onChange={({ target }) => setValue('name', trim(target.value))}
|
||||||
value={input.name}
|
value={input.name}
|
||||||
@ -109,19 +138,12 @@ const AddStrategy = ({
|
|||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<FormButtons
|
<FormButtons
|
||||||
|
submitText={editmode ? 'Update' : 'Create'}
|
||||||
onCancel={onCancel}
|
onCancel={onCancel}
|
||||||
/>
|
/>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
AddStrategy.propTypes = {
|
}
|
||||||
input: PropTypes.object,
|
|
||||||
setValue: PropTypes.func,
|
|
||||||
updateInList: PropTypes.func,
|
|
||||||
incValue: PropTypes.func,
|
|
||||||
clear: PropTypes.func,
|
|
||||||
onCancel: PropTypes.func,
|
|
||||||
onSubmit: PropTypes.func,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AddStrategy;
|
export default AddStrategy;
|
||||||
|
71
frontend/src/component/strategies/edit-container.js
Normal file
71
frontend/src/component/strategies/edit-container.js
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import { createMapper, createActions } from '../input-helpers';
|
||||||
|
import { updateStrategy } from '../../store/strategy/actions';
|
||||||
|
|
||||||
|
import AddStrategy from './add-strategy';
|
||||||
|
|
||||||
|
const ID = 'edit-strategy';
|
||||||
|
|
||||||
|
function getId (props) {
|
||||||
|
return [ID, props.strategy.name];
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: need to scope to the active strategy
|
||||||
|
// best is to emulate the "input-storage"?
|
||||||
|
const mapStateToProps = createMapper({
|
||||||
|
id: getId,
|
||||||
|
getDefault: (state, ownProps) => ownProps.strategy,
|
||||||
|
prepare: (props) => {
|
||||||
|
props.editmode = true;
|
||||||
|
return props;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const prepare = (methods, dispatch) => {
|
||||||
|
methods.onSubmit = (input) => (
|
||||||
|
(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
// clean
|
||||||
|
const parameters = input.parameters
|
||||||
|
.filter((name) => !!name)
|
||||||
|
.map(({
|
||||||
|
name,
|
||||||
|
type = 'string',
|
||||||
|
description = '',
|
||||||
|
required = false,
|
||||||
|
}) => ({
|
||||||
|
name,
|
||||||
|
type,
|
||||||
|
description,
|
||||||
|
required,
|
||||||
|
}));
|
||||||
|
|
||||||
|
updateStrategy({
|
||||||
|
name: input.name,
|
||||||
|
description: input.description,
|
||||||
|
parameters,
|
||||||
|
})(dispatch)
|
||||||
|
.then(() => methods.clear())
|
||||||
|
// somewhat quickfix / hacky to go back..
|
||||||
|
.then(() => window.history.back());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
methods.onCancel = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
methods.clear();
|
||||||
|
// somewhat quickfix / hacky to go back..
|
||||||
|
window.history.back();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return methods;
|
||||||
|
};
|
||||||
|
|
||||||
|
const actions = createActions({
|
||||||
|
id: getId,
|
||||||
|
prepare,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, actions)(AddStrategy);
|
@ -1,19 +1,8 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import { Grid, Cell, List, ListItem, ListItemContent } from 'react-mdl';
|
import { Grid, Cell, List, ListItem, ListItemContent } from 'react-mdl';
|
||||||
import { AppsLinkList, TogglesLinkList, HeaderTitle } from '../common';
|
import { AppsLinkList, TogglesLinkList } from '../common';
|
||||||
|
|
||||||
class ShowStrategyComponent extends Component {
|
class ShowStrategyComponent extends PureComponent {
|
||||||
componentDidMount () {
|
|
||||||
if (!this.props.strategy) {
|
|
||||||
this.props.fetchStrategies();
|
|
||||||
};
|
|
||||||
if (!this.props.applications || this.props.applications.length === 0) {
|
|
||||||
this.props.fetchApplications();
|
|
||||||
}
|
|
||||||
if (!this.props.toggles || this.props.toggles.length === 0) {
|
|
||||||
this.props.fetchFeatureToggles();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
renderParameters (params) {
|
renderParameters (params) {
|
||||||
if (params) {
|
if (params) {
|
||||||
@ -32,24 +21,17 @@ class ShowStrategyComponent extends Component {
|
|||||||
render () {
|
render () {
|
||||||
const {
|
const {
|
||||||
strategy,
|
strategy,
|
||||||
strategyName,
|
|
||||||
applications,
|
applications,
|
||||||
toggles,
|
toggles,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if (!strategy) {
|
|
||||||
return <div>Cannot find Strategy "{strategyName}".</div>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
name,
|
|
||||||
description,
|
|
||||||
parameters = [],
|
parameters = [],
|
||||||
} = strategy;
|
} = strategy;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<HeaderTitle title={name} subtitle={description} />
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<Cell col={12}>
|
<Cell col={12}>
|
||||||
<h6>Parameters</h6>
|
<h6>Parameters</h6>
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import { Tabs, Tab, ProgressBar } from 'react-mdl';
|
||||||
|
import ShowStrategy from './show-strategy-component';
|
||||||
|
import EditStrategy from './edit-container';
|
||||||
|
import { HeaderTitle } from '../common';
|
||||||
|
|
||||||
|
const EDIT = 1;
|
||||||
|
|
||||||
|
export default class StrategyDetails extends Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props);
|
||||||
|
this.state = { activeTab: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount () {
|
||||||
|
if (!this.props.strategy) {
|
||||||
|
this.props.fetchStrategies();
|
||||||
|
};
|
||||||
|
if (!this.props.applications || this.props.applications.length === 0) {
|
||||||
|
this.props.fetchApplications();
|
||||||
|
}
|
||||||
|
if (!this.props.toggles || this.props.toggles.length === 0) {
|
||||||
|
this.props.fetchFeatureToggles();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getTabContent (id) {
|
||||||
|
if (id === EDIT) {
|
||||||
|
return <EditStrategy strategy={this.props.strategy} />;
|
||||||
|
} else {
|
||||||
|
return (<ShowStrategy
|
||||||
|
strategy={this.props.strategy}
|
||||||
|
toggles={this.props.toggles}
|
||||||
|
applications={this.props.applications} />);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const strategy = this.props.strategy;
|
||||||
|
if (!strategy) {
|
||||||
|
return <ProgressBar indeterminate />;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tabContent = this.getTabContent(this.state.activeTab);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<HeaderTitle title={strategy.name} subtitle={strategy.description} />
|
||||||
|
<Tabs activeTab={this.state.activeTab}
|
||||||
|
onChange={(tabId) => this.setState({ activeTab: tabId })} ripple>
|
||||||
|
<Tab>Details</Tab>
|
||||||
|
<Tab>Edit</Tab>
|
||||||
|
</Tabs>
|
||||||
|
<section>
|
||||||
|
<div className="content">
|
||||||
|
{tabContent}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import ShowStrategy from './show-strategy-component';
|
import ShowStrategy from './strategy-details-component';
|
||||||
import { fetchStrategies } from '../../store/strategy/actions';
|
import { fetchStrategies } from '../../store/strategy/actions';
|
||||||
import { fetchAll } from '../../store/application/actions';
|
import { fetchAll } from '../../store/application/actions';
|
||||||
import { fetchFeatureToggles } from '../../store/feature-actions';
|
import { fetchFeatureToggles } from '../../store/feature-actions';
|
@ -17,6 +17,15 @@ function create (strategy) {
|
|||||||
}).then(throwIfNotSuccess);
|
}).then(throwIfNotSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function update (strategy) {
|
||||||
|
return fetch(`${URI}/${strategy.name}`, {
|
||||||
|
method: 'put',
|
||||||
|
headers,
|
||||||
|
body: JSON.stringify(strategy),
|
||||||
|
credentials: 'include',
|
||||||
|
}).then(throwIfNotSuccess);
|
||||||
|
}
|
||||||
|
|
||||||
function remove (strategy) {
|
function remove (strategy) {
|
||||||
return fetch(`${URI}/${strategy.name}`, {
|
return fetch(`${URI}/${strategy.name}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
@ -28,5 +37,6 @@ function remove (strategy) {
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
fetchAll,
|
fetchAll,
|
||||||
create,
|
create,
|
||||||
|
update,
|
||||||
remove,
|
remove,
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ShowStrategy from '../../component/strategies/show-strategy-container';
|
import ShowStrategy from '../../component/strategies/strategy-details-container';
|
||||||
|
|
||||||
const render = ({ params }) => <ShowStrategy strategyName={params.strategyName} />;
|
const render = ({ params }) => <ShowStrategy strategyName={params.strategyName} />;
|
||||||
|
|
||||||
|
@ -2,21 +2,30 @@ import api from '../../data/strategy-api';
|
|||||||
import { fetchApplicationsWithStrategyName } from '../../data/applications-api';
|
import { fetchApplicationsWithStrategyName } from '../../data/applications-api';
|
||||||
|
|
||||||
export const ADD_STRATEGY = 'ADD_STRATEGY';
|
export const ADD_STRATEGY = 'ADD_STRATEGY';
|
||||||
|
export const UPDATE_STRATEGY = 'UPDATE_STRATEGY';
|
||||||
export const REMOVE_STRATEGY = 'REMOVE_STRATEGY';
|
export const REMOVE_STRATEGY = 'REMOVE_STRATEGY';
|
||||||
export const REQUEST_STRATEGIES = 'REQUEST_STRATEGIES';
|
export const REQUEST_STRATEGIES = 'REQUEST_STRATEGIES';
|
||||||
export const START_CREATE_STRATEGY = 'START_CREATE_STRATEGY';
|
export const START_CREATE_STRATEGY = 'START_CREATE_STRATEGY';
|
||||||
|
export const START_UPDATE_STRATEGY = 'START_UPDATE_STRATEGY';
|
||||||
export const RECEIVE_STRATEGIES = 'RECEIVE_STRATEGIES';
|
export const RECEIVE_STRATEGIES = 'RECEIVE_STRATEGIES';
|
||||||
export const ERROR_RECEIVE_STRATEGIES = 'ERROR_RECEIVE_STRATEGIES';
|
export const ERROR_RECEIVE_STRATEGIES = 'ERROR_RECEIVE_STRATEGIES';
|
||||||
export const ERROR_CREATING_STRATEGY = 'ERROR_CREATING_STRATEGY';
|
export const ERROR_CREATING_STRATEGY = 'ERROR_CREATING_STRATEGY';
|
||||||
|
export const ERROR_UPDATING_STRATEGY = 'ERROR_UPDATING_STRATEGY';
|
||||||
|
|
||||||
const addStrategy = (strategy) => ({ type: ADD_STRATEGY, strategy });
|
const addStrategy = (strategy) => ({ type: ADD_STRATEGY, strategy });
|
||||||
const createRemoveStrategy = (strategy) => ({ type: REMOVE_STRATEGY, strategy });
|
const createRemoveStrategy = (strategy) => ({ type: REMOVE_STRATEGY, strategy });
|
||||||
|
const updatedStrategy = (strategy) => ({ type: UPDATE_STRATEGY, strategy });
|
||||||
|
|
||||||
const errorCreatingStrategy = (statusCode) => ({
|
const errorCreatingStrategy = (statusCode) => ({
|
||||||
type: ERROR_CREATING_STRATEGY,
|
type: ERROR_CREATING_STRATEGY,
|
||||||
statusCode,
|
statusCode,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const errorUpdatingStrategy = (statusCode) => ({
|
||||||
|
type: ERROR_UPDATING_STRATEGY,
|
||||||
|
statusCode,
|
||||||
|
});
|
||||||
|
|
||||||
const startRequest = () => ({ type: REQUEST_STRATEGIES });
|
const startRequest = () => ({ type: REQUEST_STRATEGIES });
|
||||||
|
|
||||||
|
|
||||||
@ -32,6 +41,8 @@ const errorReceiveStrategies = (statusCode) => ({
|
|||||||
statusCode,
|
statusCode,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const startUpdate = () => ({ type: START_UPDATE_STRATEGY });
|
||||||
|
|
||||||
export function fetchStrategies () {
|
export function fetchStrategies () {
|
||||||
return dispatch => {
|
return dispatch => {
|
||||||
dispatch(startRequest());
|
dispatch(startRequest());
|
||||||
@ -52,6 +63,16 @@ export function createStrategy (strategy) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function updateStrategy (strategy) {
|
||||||
|
return dispatch => {
|
||||||
|
dispatch(startUpdate());
|
||||||
|
|
||||||
|
return api.update(strategy)
|
||||||
|
.then(() => dispatch(updatedStrategy(strategy)))
|
||||||
|
.catch(error => dispatch(errorUpdatingStrategy(error)));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export function removeStrategy (strategy) {
|
export function removeStrategy (strategy) {
|
||||||
return dispatch => api.remove(strategy)
|
return dispatch => api.remove(strategy)
|
||||||
|
Loading…
Reference in New Issue
Block a user