Force sources to reload after deletion

Deleting a source invalidates the state held by the client because of
automatic re-assignment of the default source by the backend. Without
duplicating backend logic, it is impossible for the frontend to discover
the new source without reloading sources.

The ManageSources page now uses an async-action creator which deletes
the requested source and reloads all sources. The source action creators
have also been refactored to use implicit returns like other action
creators.
pull/1074/head
Tim Raymond 2017-03-27 12:00:13 -04:00
parent b0d87c1ce1
commit 04bf3caf39
2 changed files with 58 additions and 53 deletions

View File

@ -1,35 +1,37 @@
export function loadSources(sources) {
return {
type: 'LOAD_SOURCES',
payload: {
sources,
},
};
}
import {deleteSource, getSources} from 'src/shared/apis'
export function updateSource(source) {
return {
type: 'SOURCE_UPDATED',
payload: {
source,
},
};
}
export const loadSources = (sources) => ({
type: 'LOAD_SOURCES',
payload: {
sources,
},
})
export function removeSource(source) {
return {
type: 'SOURCE_REMOVED',
payload: {
source,
},
};
}
export const updateSource = (source) => ({
type: 'SOURCE_UPDATED',
payload: {
source,
},
})
export function addSource(source) {
return {
type: 'SOURCE_ADDED',
payload: {
source,
},
};
export const removeSource = (source) => ({
type: 'SOURCE_REMOVED',
payload: {
source,
},
})
export const addSource = (source) => ({
type: 'SOURCE_ADDED',
payload: {
source,
},
})
// Async action creators
export const removeAndLoadSources = (source) => async (dispatch) => {
await deleteSource(source)
const sources = await getSources()
dispatch(loadSources(sources.data.sources))
}

View File

@ -1,29 +1,33 @@
import React, {PropTypes} from 'react';
import {withRouter, Link} from 'react-router';
import {getKapacitor, deleteSource} from 'shared/apis';
import {
loadSources as loadSourcesAction,
removeSource as removeSourceAction,
} from 'src/shared/actions/sources';
import {getKapacitor} from 'shared/apis';
import {removeAndLoadSources} from 'src/shared/actions/sources';
import {connect} from 'react-redux';
const {
array,
func,
shape,
string,
} = PropTypes
export const ManageSources = React.createClass({
propTypes: {
location: PropTypes.shape({
pathname: PropTypes.string.isRequired,
location: shape({
pathname: string.isRequired,
}).isRequired,
source: PropTypes.shape({
id: PropTypes.string.isRequired,
links: PropTypes.shape({
proxy: PropTypes.string.isRequired,
self: PropTypes.string.isRequired,
source: shape({
id: string.isRequired,
links: shape({
proxy: string.isRequired,
self: string.isRequired,
}),
}),
sources: PropTypes.array,
addFlashMessage: PropTypes.func,
loadSourcesAction: PropTypes.func.isRequired,
removeSourceAction: PropTypes.func.isRequired,
sources: array,
addFlashMessage: func,
removeAndLoadSources: func,
},
getInitialState() {
return {
kapacitors: {},
@ -47,12 +51,11 @@ export const ManageSources = React.createClass({
handleDeleteSource(source) {
const {addFlashMessage} = this.props;
deleteSource(source).then(() => {
this.props.removeSourceAction(source);
addFlashMessage({type: 'success', text: 'Source removed from Chronograf'});
}).catch(() => {
try {
this.props.removeAndLoadSources(source)
} catch (e) {
addFlashMessage({type: 'error', text: 'Could not remove source from Chronograf'});
});
}
},
render() {
@ -130,4 +133,4 @@ function mapStateToProps(state) {
};
}
export default connect(mapStateToProps, {loadSourcesAction, removeSourceAction})(withRouter(ManageSources));
export default connect(mapStateToProps, {removeAndLoadSources})(withRouter(ManageSources));