-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Finish UI portion of ServiceDetail page #214
Changes from 3 commits
717bc2f
c3da152
2acfe4c
2d26254
dd99f39
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
import { buildApiAction, buildJsonApiAction } from './base'; | ||
|
||
const buildRequestId = (serviceId) => `${serviceId}-${Date.now()}`; | ||
|
||
export const FetchBaragonServices = buildApiAction( | ||
'FETCH_BARAGON_SERVICES', | ||
{url: '/state'} | ||
|
@@ -17,8 +19,8 @@ export const FetchService = buildApiAction( | |
export const DeleteService = buildJsonApiAction( | ||
'DELETE_SERVICE', | ||
'DELETE', | ||
(serviceId) => ({ | ||
url: `/state/${serviceId}`, | ||
(serviceId, noValidate = false, noReload = false) => ({ | ||
url: `/state/${serviceId}?noValidate=${noValidate}&noReload=${noReload}`, | ||
}) | ||
); | ||
|
||
|
@@ -29,3 +31,20 @@ export const ReloadService = buildJsonApiAction( | |
url: `/state/${serviceId}/reload`, | ||
}) | ||
); | ||
|
||
export const RemoveUpstreams = buildJsonApiAction( | ||
'REMOVE_UPSTREAMS', | ||
'POST', | ||
(loadBalancerService, upstreams, noValidate, noReload) => ({ | ||
url: '/request', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there are several different actions that might submit a request. Maybe it makes sense to use the Feel free to disagree, just trying to think how to best organize what might be very similar calls from different places. |
||
body: { | ||
loadBalancerService, | ||
noValidate, | ||
noReload, | ||
loadBalancerRequestId: buildRequestId(loadBalancerService.serviceId), | ||
addUpstreams: [], | ||
removeUpstreams: upstreams, | ||
}, | ||
}), | ||
(serviceId) => serviceId, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would make more sense to have this keyed on the requestId. When fetching results for the request we are going to have to look it up by that id, not the serviceId |
||
); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import React, { Component, PropTypes } from 'react'; | ||
|
||
import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger'; | ||
import ToolTip from 'react-bootstrap/lib/Tooltip'; | ||
import { Glyphicon } from 'react-bootstrap'; | ||
|
||
import { getClickComponent } from '../modal/ModalWrapper'; | ||
|
||
import RemoveUpstreamModal from './RemoveUpstreamModal'; | ||
|
||
const removeTooltip = ( | ||
<ToolTip id="removeAll"> | ||
Remove this upstream from the service | ||
</ToolTip> | ||
); | ||
|
||
export default class RemoveUpstreamButton extends Component { | ||
static propTypes = { | ||
loadBalancerService: PropTypes.object, | ||
upstream: PropTypes.shape({ | ||
group: PropTypes.string, | ||
rackId: PropTypes.string, | ||
requestId: PropTypes.string.isRequired, | ||
upstream: PropTypes.string.isRequired, | ||
}), | ||
children: PropTypes.node, | ||
afterRemoveUpstream: PropTypes.func, | ||
}; | ||
|
||
static defaultProps = { | ||
children: ( | ||
<OverlayTrigger placement="top" id="view-delete-overlay" overlay={removeTooltip}> | ||
<Glyphicon glyph="remove" className="inactive" /> | ||
</OverlayTrigger> | ||
) | ||
}; | ||
|
||
render() { | ||
return ( | ||
<span> | ||
{getClickComponent(this)} | ||
<RemoveUpstreamModal | ||
ref="modal" | ||
loadBalancerService={this.props.loadBalancerService} | ||
upstream={this.props.upstream} | ||
then={this.props.afterRemoveUpstream} | ||
/> | ||
</span> | ||
); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import React, { Component, PropTypes } from 'react'; | ||
import { connect } from 'react-redux'; | ||
|
||
import { RemoveUpstreams } from '../../../actions/api/services'; | ||
|
||
import FormModal from '../modal/FormModal'; | ||
|
||
class RemoveUpstreamModal extends Component { | ||
static propTypes = { | ||
loadBalancerService: PropTypes.object.isRequired, | ||
upstream: PropTypes.object.isRequired, | ||
removeUpstream: PropTypes.func.isRequired, | ||
then: PropTypes.func, | ||
}; | ||
|
||
show() { | ||
this.refs.removeUpstreamModal.show(); | ||
} | ||
|
||
render() { | ||
return ( | ||
<FormModal | ||
name="Remove all Upstreams" | ||
ref="removeUpstreamModal" | ||
action="Remove" | ||
onConfirm={this.props.removeUpstream} | ||
buttonStyle="warning" | ||
formElements={[ | ||
{ | ||
name: 'noValidate', | ||
type: FormModal.INPUT_TYPES.BOOLEAN, | ||
label: 'Validate new configuration after applying changes', | ||
}, | ||
{ | ||
name: 'noReload', | ||
type: FormModal.INPUT_TYPES.BOOLEAN, | ||
label: 'Reload configuration after applying changes', | ||
}, | ||
]}> | ||
<p>Are you sure you want to remove this upstream?</p> | ||
<pre>{this.props.upstream.upstream}</pre> | ||
<p> | ||
This will post a new request to remove this upstream from the nginx | ||
config. It will not alter any other upstreams or options. | ||
</p> | ||
</FormModal> | ||
); | ||
} | ||
} | ||
|
||
const mapDispatchToProps = (dispatch, ownProps) => ({ | ||
removeUpstream: (data) => dispatch(RemoveUpstreams | ||
.trigger(ownProps.loadBalancerService, [ownProps.upstream], data.noValidate, data.noReload)) | ||
.then(response => (ownProps.then && ownProps.then(response))) | ||
}); | ||
|
||
export default connect( | ||
null, | ||
mapDispatchToProps, | ||
null, | ||
{ withRef: true } | ||
)(RemoveUpstreamModal); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import React, { PropTypes } from 'react'; | ||
|
||
import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger'; | ||
import ToolTip from 'react-bootstrap/lib/Tooltip'; | ||
|
||
import { getClickComponent } from '../modal/ModalWrapper'; | ||
|
||
import RemoveUpstreamsModal from './RemoveUpstreamsModal'; | ||
|
||
const removeTooltip = ( | ||
<ToolTip id="removeAll"> | ||
Remove all upstreams from this service | ||
</ToolTip> | ||
); | ||
|
||
export default class RemoveUpstreamsButton extends React.Component { | ||
static propTypes = { | ||
loadBalancerService: PropTypes.object, | ||
upstreams: PropTypes.arrayOf(PropTypes.shape({ | ||
group: PropTypes.string, | ||
rackId: PropTypes.string, | ||
requestId: PropTypes.string.isRequired, | ||
upstream: PropTypes.string.isRequired, | ||
})), | ||
children: PropTypes.node, | ||
afterRemoveUpstreams: PropTypes.func, | ||
}; | ||
|
||
static defaultProps = { | ||
children: ( | ||
<OverlayTrigger placement="top" id="view-delete-overlay" overlay={removeTooltip}> | ||
<span> | ||
<a className="btn btn-warning">Remove Upstreams</a> | ||
</span> | ||
</OverlayTrigger> | ||
) | ||
}; | ||
|
||
render() { | ||
return ( | ||
<span> | ||
{getClickComponent(this)} | ||
<RemoveUpstreamsModal | ||
ref="modal" | ||
loadBalancerService={this.props.loadBalancerService} | ||
upstreams={this.props.upstreams} | ||
then={this.props.afterRemoveUpstreams} | ||
/> | ||
</span> | ||
); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import React, { Component, PropTypes } from 'react'; | ||
import { connect } from 'react-redux'; | ||
|
||
import { RemoveUpstreams } from '../../../actions/api/services'; | ||
|
||
import FormModal from '../modal/FormModal'; | ||
|
||
class RemoveUpstreamsModal extends Component { | ||
static propTypes = { | ||
loadBalancerService: PropTypes.object.isRequired, | ||
upstreams: PropTypes.array.isRequired, | ||
removeUpstreams: PropTypes.func.isRequired, | ||
then: PropTypes.func, | ||
}; | ||
|
||
show() { | ||
this.refs.removeUpstreamsModal.show(); | ||
} | ||
|
||
render() { | ||
return ( | ||
<FormModal | ||
name="Remove all Upstreams" | ||
ref="removeUpstreamsModal" | ||
action="Remove" | ||
onConfirm={this.props.removeUpstreams} | ||
buttonStyle="warning" | ||
formElements={[ | ||
{ | ||
name: 'noValidate', | ||
type: FormModal.INPUT_TYPES.BOOLEAN, | ||
label: 'Validate new configuration after applying changes', | ||
}, | ||
{ | ||
name: 'noReload', | ||
type: FormModal.INPUT_TYPES.BOOLEAN, | ||
label: 'Reload configuration after applying changes', | ||
}, | ||
]}> | ||
<p>Are you sure you want to remove all upstreams for this service?</p> | ||
<pre>{this.props.loadBalancerService.serviceId}</pre> | ||
<p> | ||
This will post a new request to remove all the current upstreams | ||
for a service. This will effectively 'undo' the request by creating | ||
empty config files. | ||
</p> | ||
</FormModal> | ||
); | ||
} | ||
} | ||
|
||
const mapDispatchToProps = (dispatch, ownProps) => ({ | ||
removeUpstreams: (data) => dispatch(RemoveUpstreams | ||
.trigger(ownProps.loadBalancerService, ownProps.upstreams, data.noValidate, data.noReload)) | ||
.then(response => (ownProps.then && ownProps.then(response))) | ||
}); | ||
|
||
export default connect( | ||
null, | ||
mapDispatchToProps, | ||
null, | ||
{ withRef: true } | ||
)(RemoveUpstreamsModal); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should make sure to add this action to the reducers as well, the returned output will be more easily accessible