diff --git a/x-pack/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.container.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.container.js
index 26a312692e5ef..3f8c8331f4909 100644
--- a/x-pack/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.container.js
+++ b/x-pack/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.container.js
@@ -7,8 +7,13 @@
import { connect } from 'react-redux';
import { SECTIONS } from '../../constants';
-import { getApiStatus, getApiError, getSelectedAutoFollowPattern } from '../../store/selectors';
-import { getAutoFollowPattern, saveAutoFollowPattern, clearApiError } from '../../store/actions';
+import {
+ getApiStatus,
+ getApiError,
+ getSelectedAutoFollowPatternId,
+ getSelectedAutoFollowPattern,
+} from '../../store/selectors';
+import { getAutoFollowPattern, saveAutoFollowPattern, selectEditAutoFollowPattern, clearApiError } from '../../store/actions';
import { AutoFollowPatternEdit as AutoFollowPatternEditView } from './auto_follow_pattern_edit';
const scope = SECTIONS.AUTO_FOLLOW_PATTERN;
@@ -16,11 +21,13 @@ const scope = SECTIONS.AUTO_FOLLOW_PATTERN;
const mapStateToProps = (state) => ({
apiStatus: getApiStatus(scope)(state),
apiError: getApiError(scope)(state),
- autoFollowPattern: getSelectedAutoFollowPattern(state),
+ autoFollowPatternId: getSelectedAutoFollowPatternId('edit')(state),
+ autoFollowPattern: getSelectedAutoFollowPattern('edit')(state),
});
const mapDispatchToProps = dispatch => ({
getAutoFollowPattern: (id) => dispatch(getAutoFollowPattern(id)),
+ selectAutoFollowPattern: (id) => dispatch(selectEditAutoFollowPattern(id)),
saveAutoFollowPattern: (id, autoFollowPattern) => dispatch(saveAutoFollowPattern(id, autoFollowPattern, true)),
clearApiError: () => dispatch(clearApiError(scope)),
});
diff --git a/x-pack/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.js
index 46a802e9c228f..2e7f1cf89909e 100644
--- a/x-pack/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.js
+++ b/x-pack/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.js
@@ -37,22 +37,40 @@ export const AutoFollowPatternEdit = injectI18n(
class extends PureComponent {
static propTypes = {
getAutoFollowPattern: PropTypes.func.isRequired,
+ selectAutoFollowPattern: PropTypes.func.isRequired,
saveAutoFollowPattern: PropTypes.func.isRequired,
clearApiError: PropTypes.func.isRequired,
apiError: PropTypes.object,
apiStatus: PropTypes.string.isRequired,
+ autoFollowPattern: PropTypes.object,
+ autoFollowPatternId: PropTypes.string,
}
- componentDidMount() {
- const { autoFollowPattern, match: { params: { id } } } = this.props;
- if (!autoFollowPattern) {
- const decodedId = decodeURIComponent(id);
- this.props.getAutoFollowPattern(decodedId);
+ static getDerivedStateFromProps({ autoFollowPatternId }, { lastAutoFollowPatternId }) {
+ if (lastAutoFollowPatternId !== autoFollowPatternId) {
+ return { lastAutoFollowPatternId: autoFollowPatternId };
}
+ }
+
+ state = { lastAutoFollowPatternId: undefined }
+
+ componentDidMount() {
+ const { match: { params: { id } }, selectAutoFollowPattern } = this.props;
+ const decodedId = decodeURIComponent(id);
+
+ selectAutoFollowPattern(decodedId);
chrome.breadcrumbs.set([ MANAGEMENT_BREADCRUMB, listBreadcrumb, editBreadcrumb ]);
}
+ componentDidUpdate(prevProps, prevState) {
+ const { autoFollowPattern, getAutoFollowPattern } = this.props;
+ if (!autoFollowPattern && prevState.lastAutoFollowPatternId !== this.state.lastAutoFollowPatternId) {
+ // Fetch the auto-follow pattern on the server
+ getAutoFollowPattern(this.state.lastAutoFollowPatternId);
+ }
+ }
+
componentWillUnmount() {
this.props.clearApiError();
}
diff --git a/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.container.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.container.js
index efed7e2593c97..7e1b650f521d8 100644
--- a/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.container.js
+++ b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.container.js
@@ -9,15 +9,14 @@ import { connect } from 'react-redux';
import { SECTIONS } from '../../../constants';
import {
getListAutoFollowPatterns,
+ getSelectedAutoFollowPatternId,
getApiStatus,
getApiError,
isApiAuthorized,
- isAutoFollowPatternDetailPanelOpen as isDetailPanelOpen,
} from '../../../store/selectors';
import {
loadAutoFollowPatterns,
- openAutoFollowPatternDetailPanel as openDetailPanel,
- closeAutoFollowPatternDetailPanel as closeDetailPanel,
+ selectDetailAutoFollowPattern,
} from '../../../store/actions';
import { AutoFollowPatternList as AutoFollowPatternListView } from './auto_follow_pattern_list';
@@ -25,20 +24,15 @@ const scope = SECTIONS.AUTO_FOLLOW_PATTERN;
const mapStateToProps = (state) => ({
autoFollowPatterns: getListAutoFollowPatterns(state),
+ autoFollowPatternId: getSelectedAutoFollowPatternId('detail')(state),
apiStatus: getApiStatus(scope)(state),
apiError: getApiError(scope)(state),
isAuthorized: isApiAuthorized(scope)(state),
- isDetailPanelOpen: isDetailPanelOpen(state),
});
const mapDispatchToProps = dispatch => ({
loadAutoFollowPatterns: (inBackground) => dispatch(loadAutoFollowPatterns(inBackground)),
- openDetailPanel: (name) => {
- dispatch(openDetailPanel(name));
- },
- closeDetailPanel: () => {
- dispatch(closeDetailPanel());
- },
+ selectAutoFollowPattern: (id) => dispatch(selectDetailAutoFollowPattern(id)),
});
export const AutoFollowPatternList = connect(
diff --git a/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.js
index 34768f655be69..0bc8231c5cbc5 100644
--- a/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.js
+++ b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.js
@@ -17,49 +17,71 @@ import { AutoFollowPatternTable, DetailPanel } from './components';
const REFRESH_RATE_MS = 30000;
+const getQueryParamPattern = ({ location: { search } }) => {
+ const { pattern } = extractQueryParams(search);
+ return pattern ? decodeURIComponent(pattern) : null;
+};
+
export const AutoFollowPatternList = injectI18n(
class extends PureComponent {
static propTypes = {
loadAutoFollowPatterns: PropTypes.func,
+ selectAutoFollowPattern: PropTypes.func,
autoFollowPatterns: PropTypes.array,
apiStatus: PropTypes.string,
apiError: PropTypes.object,
- openDetailPanel: PropTypes.func.isRequired,
- closeDetailPanel: PropTypes.func.isRequired,
- isDetailPanelOpen: PropTypes.bool,
}
+ static getDerivedStateFromProps({ autoFollowPatternId }, { lastAutoFollowPatternId }) {
+ if (autoFollowPatternId !== lastAutoFollowPatternId) {
+ return {
+ lastAutoFollowPatternId: autoFollowPatternId,
+ isDetailPanelOpen: !!autoFollowPatternId,
+ };
+ }
+ return null;
+ }
+
+ state = {
+ lastAutoFollowPatternId: null,
+ isDetailPanelOpen: false,
+ };
+
componentDidMount() {
- this.props.loadAutoFollowPatterns();
+ const { loadAutoFollowPatterns, selectAutoFollowPattern, history } = this.props;
+
+ loadAutoFollowPatterns();
+
+ // Select the pattern in the URL query params
+ selectAutoFollowPattern(getQueryParamPattern(history));
// Interval to load auto-follow patterns in the background passing "true" to the fetch method
- this.interval = setInterval(() => this.props.loadAutoFollowPatterns(true), REFRESH_RATE_MS);
+ this.interval = setInterval(() => loadAutoFollowPatterns(true), REFRESH_RATE_MS);
}
- componentWillUnmount() {
- clearInterval(this.interval);
+ componentDidUpdate(prevProps, prevState) {
+ const { history } = this.props;
+ const { lastAutoFollowPatternId } = this.state;
+
+ /**
+ * Each time our state is updated (through getDerivedStateFromProps())
+ * we persist the auto-follow pattern id to query params for deep linking
+ */
+ if (lastAutoFollowPatternId !== prevState.lastAutoFollowPatternId) {
+ if(!lastAutoFollowPatternId) {
+ history.replace({
+ search: '',
+ });
+ } else {
+ history.replace({
+ search: `?pattern=${encodeURIComponent(lastAutoFollowPatternId)}`,
+ });
+ }
+ }
}
- componentDidUpdate() {
- const {
- openDetailPanel,
- closeDetailPanel,
- isDetailPanelOpen,
- history: {
- location: {
- search,
- },
- },
- } = this.props;
-
- const { pattern: patternName } = extractQueryParams(search);
-
- // Show deeplinked auto follow pattern whenever patterns get loaded or the URL changes.
- if (patternName != null) {
- openDetailPanel(patternName);
- } else if (isDetailPanelOpen) {
- closeDetailPanel();
- }
+ componentWillUnmount() {
+ clearInterval(this.interval);
}
renderEmpty() {
@@ -102,7 +124,13 @@ export const AutoFollowPatternList = injectI18n(
}
renderList() {
- const { autoFollowPatterns, apiStatus } = this.props;
+ const {
+ selectAutoFollowPattern,
+ autoFollowPatterns,
+ apiStatus,
+ } = this.props;
+
+ const { isDetailPanelOpen } = this.state;
if (apiStatus === API_STATUS.LOADING) {
return (
@@ -118,7 +146,7 @@ export const AutoFollowPatternList = injectI18n(
return (
-
+ {isDetailPanelOpen && selectAutoFollowPattern(null)} />}
);
}
diff --git a/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/auto_follow_pattern_table.container.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/auto_follow_pattern_table.container.js
index f631533f68385..d80bf65bd0013 100644
--- a/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/auto_follow_pattern_table.container.js
+++ b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/auto_follow_pattern_table.container.js
@@ -7,10 +7,7 @@
import { connect } from 'react-redux';
import { SECTIONS } from '../../../../../constants';
-import {
- editAutoFollowPattern,
- openAutoFollowPatternDetailPanel as openDetailPanel,
-} from '../../../../../store/actions';
+import { selectDetailAutoFollowPattern } from '../../../../../store/actions';
import { getApiStatus } from '../../../../../store/selectors';
import { AutoFollowPatternTable as AutoFollowPatternTableComponent } from './auto_follow_pattern_table';
@@ -21,10 +18,7 @@ const mapStateToProps = (state) => ({
});
const mapDispatchToProps = (dispatch) => ({
- editAutoFollowPattern: (name) => dispatch(editAutoFollowPattern(name)),
- openDetailPanel: (name) => {
- dispatch(openDetailPanel(name));
- },
+ selectAutoFollowPattern: (name) => dispatch(selectDetailAutoFollowPattern(name)),
});
export const AutoFollowPatternTable = connect(
diff --git a/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/auto_follow_pattern_table.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/auto_follow_pattern_table.js
index fa42a80b4ecd4..1a9966896db5c 100644
--- a/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/auto_follow_pattern_table.js
+++ b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/auto_follow_pattern_table.js
@@ -25,7 +25,7 @@ export const AutoFollowPatternTable = injectI18n(
class extends PureComponent {
static propTypes = {
autoFollowPatterns: PropTypes.array,
- openDetailPanel: PropTypes.func.isRequired,
+ selectAutoFollowPattern: PropTypes.func.isRequired,
}
state = {
@@ -61,7 +61,7 @@ export const AutoFollowPatternTable = injectI18n(
};
getTableColumns() {
- const { intl, editAutoFollowPattern, openDetailPanel } = this.props;
+ const { intl, selectAutoFollowPattern } = this.props;
return [{
field: 'name',
@@ -73,7 +73,7 @@ export const AutoFollowPatternTable = injectI18n(
truncateText: false,
render: (name) => {
return (
- openDetailPanel(name)}>
+ selectAutoFollowPattern(name)}>
{name}
);
@@ -142,20 +142,25 @@ export const AutoFollowPatternTable = injectI18n(
},
},
{
- name: intl.formatMessage({
- id: 'xpack.crossClusterReplication.editIndexPattern.fields.table.actionEditLabel',
- defaultMessage: 'Edit',
- }),
- description: intl.formatMessage({
- id: 'xpack.crossClusterReplication.editIndexPattern.fields.table.actionEditDescription',
- defaultMessage: 'Edit',
- }),
- icon: 'pencil',
- onClick: ({ name }) => {
- editAutoFollowPattern(name);
- routing.navigate(encodeURI(`/auto_follow_patterns/edit/${encodeURIComponent(name)}`));
+ render: ({ name }) => {
+ const label = i18n.translate('xpack.crossClusterReplication.autoFollowPatternList.table.actionEditDescription', {
+ defaultMessage: 'Edit auto-follow pattern',
+ });
+
+ return (
+
+
+
+ );
},
- type: 'icon',
},
],
width: '100px',
diff --git a/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.container.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.container.js
index 3f8183eb5158e..6446800388729 100644
--- a/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.container.js
+++ b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.container.js
@@ -7,45 +7,17 @@
import { connect } from 'react-redux';
import { DetailPanel as DetailPanelView } from './detail_panel';
-import {
- getDetailPanelAutoFollowPattern,
- getDetailPanelAutoFollowPatternName,
- getApiStatus,
- isAutoFollowPatternDetailPanelOpen as isDetailPanelOpen,
-} from '../../../../../store/selectors';
-
-import {
- closeAutoFollowPatternDetailPanel as closeDetailPanel,
- editAutoFollowPattern,
-} from '../../../../../store/actions';
-
-import {
- SECTIONS
-} from '../../../../../constants';
+import { getSelectedAutoFollowPattern, getSelectedAutoFollowPatternId, getApiStatus, } from '../../../../../store/selectors';
+import { SECTIONS } from '../../../../../constants';
const scope = SECTIONS.AUTO_FOLLOW_PATTERN;
-const mapStateToProps = (state) => {
- return {
- isDetailPanelOpen: isDetailPanelOpen(state),
- autoFollowPattern: getDetailPanelAutoFollowPattern(state),
- autoFollowPatternName: getDetailPanelAutoFollowPatternName(state),
- apiStatus: getApiStatus(scope)(state),
- };
-};
-
-const mapDispatchToProps = (dispatch) => {
- return {
- closeDetailPanel: () => {
- dispatch(closeDetailPanel());
- },
- editAutoFollowPattern: (name) => {
- dispatch(editAutoFollowPattern(name));
- }
- };
-};
+const mapStateToProps = (state) => ({
+ autoFollowPatternId: getSelectedAutoFollowPatternId('detail')(state),
+ autoFollowPattern: getSelectedAutoFollowPattern('detail')(state),
+ apiStatus: getApiStatus(scope)(state),
+});
export const DetailPanel = connect(
mapStateToProps,
- mapDispatchToProps
)(DetailPanelView);
diff --git a/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.js
index c2c239960743d..0be3de11d6f9e 100644
--- a/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.js
+++ b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.js
@@ -41,12 +41,10 @@ import routing from '../../../../../services/routing';
export class DetailPanelUi extends Component {
static propTypes = {
- isDetailPanelOpen: PropTypes.bool.isRequired,
apiStatus: PropTypes.string,
+ autoFollowPatternId: PropTypes.string,
autoFollowPattern: PropTypes.object,
- autoFollowPatternName: PropTypes.string,
closeDetailPanel: PropTypes.func.isRequired,
- editAutoFollowPattern: PropTypes.func.isRequired,
}
renderAutoFollowPattern() {
@@ -192,7 +190,7 @@ export class DetailPanelUi extends Component {
autoFollowPattern,
} = this.props;
- if(apiStatus === API_STATUS.LOADING) {
+ if (apiStatus === API_STATUS.LOADING) {
return (
@@ -277,56 +269,49 @@ export class DetailPanelUi extends Component {
-
-
-
-
- {(deleteAutoFollowPattern) => (
- deleteAutoFollowPattern(autoFollowPatternName)}
- >
-
-
- )}
-
-
-
-
- {
- editAutoFollowPattern(autoFollowPatternName);
- routing.navigate(encodeURI(`/auto_follow_patterns/edit/${encodeURIComponent(autoFollowPatternName)}`));
- }}
- >
-
-
-
-
-
+ {autoFollowPattern && (
+
+
+
+
+ {(deleteAutoFollowPattern) => (
+ deleteAutoFollowPattern(autoFollowPattern.name)}
+ >
+
+
+ )}
+
+
+
+
+ {
+ routing.navigate(encodeURI(`/auto_follow_patterns/edit/${encodeURIComponent(autoFollowPattern.name)}`));
+ }}
+ >
+
+
+
+
+
+ )}
);
}
render() {
- const {
- isDetailPanelOpen,
- closeDetailPanel,
- autoFollowPatternName,
- } = this.props;
-
- if (!isDetailPanelOpen) {
- return null;
- }
+ const { autoFollowPatternId, closeDetailPanel } = this.props;
return (
+
- {autoFollowPatternName}
+ {autoFollowPatternId}
{this.renderContent()}
-
{this.renderFooter()}
);
diff --git a/x-pack/plugins/cross_cluster_replication/public/app/services/routing.js b/x-pack/plugins/cross_cluster_replication/public/app/services/routing.js
index 988201fd240f7..fd24a8932f532 100644
--- a/x-pack/plugins/cross_cluster_replication/public/app/services/routing.js
+++ b/x-pack/plugins/cross_cluster_replication/public/app/services/routing.js
@@ -80,6 +80,10 @@ class Routing {
});
}
+ getAutoFollowPatternPath = (name, section = '/edit') => {
+ return encodeURI(`#${BASE_PATH}/auto_follow_patterns${section}/${encodeURIComponent(name)}`);
+ };
+
get reactRouter() {
return this._reactRouter;
}
diff --git a/x-pack/plugins/cross_cluster_replication/public/app/store/action_types.js b/x-pack/plugins/cross_cluster_replication/public/app/store/action_types.js
index dd618161aefce..c018e7b44ebcc 100644
--- a/x-pack/plugins/cross_cluster_replication/public/app/store/action_types.js
+++ b/x-pack/plugins/cross_cluster_replication/public/app/store/action_types.js
@@ -11,10 +11,10 @@ export const API_REQUEST_END = 'API_REQUEST_END';
export const API_ERROR_SET = 'API_ERROR_SET';
// Auto Follow Pattern
-export const AUTO_FOLLOW_PATTERN_EDIT = 'AUTO_FOLLOW_PATTERN_EDIT';
+export const AUTO_FOLLOW_PATTERN_SELECT_DETAIL = 'AUTO_FOLLOW_PATTERN_SELECT_DETAIL';
+export const AUTO_FOLLOW_PATTERN_SELECT_EDIT = 'AUTO_FOLLOW_PATTERN_SELECT_EDIT';
export const AUTO_FOLLOW_PATTERN_LOAD = 'AUTO_FOLLOW_PATTERN_LOAD';
export const AUTO_FOLLOW_PATTERN_GET = 'AUTO_FOLLOW_PATTERN_GET';
export const AUTO_FOLLOW_PATTERN_CREATE = 'AUTO_FOLLOW_PATTERN_CREATE';
export const AUTO_FOLLOW_PATTERN_UPDATE = 'AUTO_FOLLOW_PATTERN_UPDATE';
export const AUTO_FOLLOW_PATTERN_DELETE = 'AUTO_FOLLOW_PATTERN_DELETE';
-export const AUTO_FOLLOW_PATTERN_DETAIL_PANEL = 'AUTO_FOLLOW_PATTERN_DETAIL_PANEL';
diff --git a/x-pack/plugins/cross_cluster_replication/public/app/store/actions/api.js b/x-pack/plugins/cross_cluster_replication/public/app/store/actions/api.js
index 7b5fa621dddea..0bc4be5c7be04 100644
--- a/x-pack/plugins/cross_cluster_replication/public/app/store/actions/api.js
+++ b/x-pack/plugins/cross_cluster_replication/public/app/store/actions/api.js
@@ -7,15 +7,6 @@
import * as t from '../action_types';
import { API_STATUS } from '../../constants';
-export const sendApiRequest = ({
- label,
- scope,
- status,
- handler,
- onSuccess = () => undefined,
- onError = () => undefined,
-}) => ({ type: t.API, payload: { label, scope, status, handler, onSuccess, onError } });
-
export const apiRequestStart = ({ label, scope, status = API_STATUS.LOADING }) => ({
type: t.API_REQUEST_START,
payload: { label, scope, status },
@@ -29,3 +20,32 @@ export const setApiError = ({ error, scope }) => ({
});
export const clearApiError = scope => ({ type: t.API_ERROR_SET, payload: { error: null, scope } });
+
+export const sendApiRequest = ({
+ label,
+ scope,
+ status,
+ handler,
+ onSuccess = () => undefined,
+ onError = () => undefined,
+}) => async (dispatch, getState) => {
+
+ dispatch(clearApiError(scope));
+ dispatch(apiRequestStart({ label, scope, status }));
+
+ try {
+ const response = await handler(dispatch);
+
+ dispatch(apiRequestEnd({ label, scope }));
+ dispatch({ type: `${label}_SUCCESS`, payload: response });
+
+ onSuccess(response, dispatch, getState);
+
+ } catch (error) {
+ dispatch(apiRequestEnd({ label, scope }));
+ dispatch(setApiError({ error, scope }));
+ dispatch({ type: `${label}_FAILURE`, payload: error });
+
+ onError(error, dispatch, getState);
+ }
+};
diff --git a/x-pack/plugins/cross_cluster_replication/public/app/store/actions/auto_follow_pattern.js b/x-pack/plugins/cross_cluster_replication/public/app/store/actions/auto_follow_pattern.js
index e02085ceb0290..b041be4e4bea5 100644
--- a/x-pack/plugins/cross_cluster_replication/public/app/store/actions/auto_follow_pattern.js
+++ b/x-pack/plugins/cross_cluster_replication/public/app/store/actions/auto_follow_pattern.js
@@ -16,25 +16,18 @@ import {
import routing from '../../services/routing';
import * as t from '../action_types';
import { sendApiRequest } from './api';
-import { getDetailPanelAutoFollowPatternName } from '../selectors';
+import { getSelectedAutoFollowPatternId } from '../selectors';
const { AUTO_FOLLOW_PATTERN: scope } = SECTIONS;
-export const editAutoFollowPattern = (name) => ({
- type: t.AUTO_FOLLOW_PATTERN_EDIT,
- payload: name
+export const selectDetailAutoFollowPattern = (id) => ({
+ type: t.AUTO_FOLLOW_PATTERN_SELECT_DETAIL,
+ payload: id
});
-export const openAutoFollowPatternDetailPanel = (name) => {
- return {
- type: t.AUTO_FOLLOW_PATTERN_DETAIL_PANEL,
- payload: name
- };
-};
-
-export const closeAutoFollowPatternDetailPanel = () => ({
- type: t.AUTO_FOLLOW_PATTERN_DETAIL_PANEL,
- payload: null
+export const selectEditAutoFollowPattern = (id) => ({
+ type: t.AUTO_FOLLOW_PATTERN_SELECT_EDIT,
+ payload: id
});
export const loadAutoFollowPatterns = (isUpdating = false) =>
@@ -42,21 +35,17 @@ export const loadAutoFollowPatterns = (isUpdating = false) =>
label: t.AUTO_FOLLOW_PATTERN_LOAD,
scope,
status: isUpdating ? API_STATUS.UPDATING : API_STATUS.LOADING,
- handler: async () => {
- return await loadAutoFollowPatternsRequest();
- },
+ handler: async () => (
+ await loadAutoFollowPatternsRequest()
+ ),
});
export const getAutoFollowPattern = (id) =>
sendApiRequest({
label: t.AUTO_FOLLOW_PATTERN_GET,
scope,
- handler: async (dispatch) => (
- getAutoFollowPatternRequest(id)
- .then((response) => {
- dispatch(editAutoFollowPattern(id));
- return response;
- })
+ handler: async () => (
+ await getAutoFollowPatternRequest(id)
)
});
@@ -132,12 +121,12 @@ export const deleteAutoFollowPattern = (id) => (
});
toastNotifications.addSuccess(successMessage);
- }
- // If we've just deleted a pattern we were looking at, we need to close the panel.
- const detailPanelAutoFollowPatternName = getDetailPanelAutoFollowPatternName(getState());
- if (detailPanelAutoFollowPatternName && response.itemsDeleted.includes(detailPanelAutoFollowPatternName)) {
- dispatch(closeAutoFollowPatternDetailPanel());
+ // If we've just deleted a pattern we were looking at, we need to close the panel.
+ const autoFollowPatternId = getSelectedAutoFollowPatternId('detail')(getState());
+ if (response.itemsDeleted.includes(autoFollowPatternId)) {
+ dispatch(selectDetailAutoFollowPattern(null));
+ }
}
}
})
diff --git a/x-pack/plugins/cross_cluster_replication/public/app/store/middleware/api.js b/x-pack/plugins/cross_cluster_replication/public/app/store/middleware/api.js
deleted file mode 100644
index 234aa24c07748..0000000000000
--- a/x-pack/plugins/cross_cluster_replication/public/app/store/middleware/api.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import * as t from '../action_types';
-import { apiRequestStart, apiRequestEnd, setApiError, clearApiError } from '../actions/api';
-
-export const apiMiddleware = ({ dispatch, getState }) => next => async (action) => {
- next(action);
-
- if (action.type !== t.API) {
- return;
- }
-
- const { label, scope, status, handler, onSuccess, onError } = action.payload;
-
- dispatch(clearApiError(scope));
- dispatch(apiRequestStart({ label, scope, status }));
-
- try {
- const response = await handler(dispatch);
-
- dispatch(apiRequestEnd({ label, scope }));
- dispatch({ type: `${label}_SUCCESS`, payload: response });
-
- onSuccess(response, dispatch, getState);
-
- } catch (error) {
- dispatch(apiRequestEnd({ label, scope }));
- dispatch(setApiError({ error, scope }));
- dispatch({ type: `${label}_FAILURE`, payload: error });
-
- onError(error, dispatch, getState);
- }
-};
diff --git a/x-pack/plugins/cross_cluster_replication/public/app/store/middleware/auto_follow_pattern.js b/x-pack/plugins/cross_cluster_replication/public/app/store/middleware/auto_follow_pattern.js
deleted file mode 100644
index 214f4768be7a7..0000000000000
--- a/x-pack/plugins/cross_cluster_replication/public/app/store/middleware/auto_follow_pattern.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import routing from '../../services/routing';
-import * as t from '../action_types';
-import { extractQueryParams } from '../../services/query_params';
-
-export const autoFollowPatternMiddleware = () => next => action => {
- const { type, payload: name } = action;
- const { history } = routing.reactRouter;
- const search = history.location.search;
- const { pattern: patternName } = extractQueryParams(search);
-
- switch (type) {
- case t.AUTO_FOLLOW_PATTERN_DETAIL_PANEL:
- if (!routing.userHasLeftApp) {
- // Persist state to query params by removing deep link.
- if(!name) {
- history.replace({
- search: '',
- });
- }
- // Allow the user to share a deep link to this job.
- else if (patternName !== name) {
- history.replace({
- search: `?pattern=${encodeURIComponent(name)}`,
- });
- }
- }
-
- break;
- }
-
- return next(action);
-};
diff --git a/x-pack/plugins/cross_cluster_replication/public/app/store/middleware/index.js b/x-pack/plugins/cross_cluster_replication/public/app/store/middleware/index.js
deleted file mode 100644
index 5097ec64e8284..0000000000000
--- a/x-pack/plugins/cross_cluster_replication/public/app/store/middleware/index.js
+++ /dev/null
@@ -1,8 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-export { apiMiddleware } from './api';
-export { autoFollowPatternMiddleware } from './auto_follow_pattern';
diff --git a/x-pack/plugins/cross_cluster_replication/public/app/store/reducers/auto_follow_pattern.js b/x-pack/plugins/cross_cluster_replication/public/app/store/reducers/auto_follow_pattern.js
index 398f949db9425..2170bc539d033 100644
--- a/x-pack/plugins/cross_cluster_replication/public/app/store/reducers/auto_follow_pattern.js
+++ b/x-pack/plugins/cross_cluster_replication/public/app/store/reducers/auto_follow_pattern.js
@@ -10,8 +10,8 @@ import { getPrefixSuffixFromFollowPattern } from '../../services/auto_follow_pat
const initialState = {
byId: {},
- selectedId: null,
- detailPanelId: null,
+ selectedDetailId: null,
+ selectedEditId: null,
};
const success = action => `${action}_SUCCESS`;
@@ -31,11 +31,11 @@ export const reducer = (state = initialState, action) => {
case success(t.AUTO_FOLLOW_PATTERN_GET): {
return { ...state, byId: { ...state.byId, [action.payload.name]: parseAutoFollowPattern(action.payload) } };
}
- case t.AUTO_FOLLOW_PATTERN_EDIT: {
- return { ...state, selectedId: action.payload };
+ case t.AUTO_FOLLOW_PATTERN_SELECT_DETAIL: {
+ return { ...state, selectedDetailId: action.payload };
}
- case t.AUTO_FOLLOW_PATTERN_DETAIL_PANEL: {
- return { ...state, detailPanelId: action.payload };
+ case t.AUTO_FOLLOW_PATTERN_SELECT_EDIT: {
+ return { ...state, selectedEditId: action.payload };
}
case success(t.AUTO_FOLLOW_PATTERN_DELETE): {
const byId = { ...state.byId };
diff --git a/x-pack/plugins/cross_cluster_replication/public/app/store/selectors/index.js b/x-pack/plugins/cross_cluster_replication/public/app/store/selectors/index.js
index bf680fb157879..52e638cc0c513 100644
--- a/x-pack/plugins/cross_cluster_replication/public/app/store/selectors/index.js
+++ b/x-pack/plugins/cross_cluster_replication/public/app/store/selectors/index.js
@@ -21,21 +21,15 @@ export const isApiAuthorized = (scope) => createSelector(getApiError(scope), (er
// Auto-follow pattern
export const getAutoFollowPatternState = (state) => state.autoFollowPattern;
export const getAutoFollowPatterns = createSelector(getAutoFollowPatternState, (autoFollowPatternsState) => autoFollowPatternsState.byId);
-export const getDetailPanelAutoFollowPatternName = createSelector(getAutoFollowPatternState,
- (autoFollowPatternsState) => autoFollowPatternsState.detailPanelId);
-export const getSelectedAutoFollowPattern = createSelector(getAutoFollowPatternState, (autoFollowPatternsState) => {
- if(!autoFollowPatternsState.selectedId) {
- return null;
- }
- return autoFollowPatternsState.byId[autoFollowPatternsState.selectedId];
-});
-export const isAutoFollowPatternDetailPanelOpen = createSelector(getAutoFollowPatternState, (autoFollowPatternsState) => {
- return !!autoFollowPatternsState.detailPanelId;
-});
-export const getDetailPanelAutoFollowPattern = createSelector(getAutoFollowPatternState, (autoFollowPatternsState) => {
- if(!autoFollowPatternsState.detailPanelId) {
+export const getSelectedAutoFollowPatternId = (view = 'detail') => createSelector(getAutoFollowPatternState, (autoFollowPatternsState) => (
+ view === 'detail' ? autoFollowPatternsState.selectedDetailId : autoFollowPatternsState.selectedEditId
+));
+export const getSelectedAutoFollowPattern = (view = 'detail') => createSelector(getAutoFollowPatternState, (autoFollowPatternsState) => {
+ const propId = view === 'detail' ? 'selectedDetailId' : 'selectedEditId';
+
+ if(!autoFollowPatternsState[propId]) {
return null;
}
- return autoFollowPatternsState.byId[autoFollowPatternsState.detailPanelId];
+ return autoFollowPatternsState.byId[autoFollowPatternsState[propId]];
});
export const getListAutoFollowPatterns = createSelector(getAutoFollowPatterns, (autoFollowPatterns) => objectToArray(autoFollowPatterns));
diff --git a/x-pack/plugins/cross_cluster_replication/public/app/store/store.js b/x-pack/plugins/cross_cluster_replication/public/app/store/store.js
index 6d2a700deab41..b6674d89f6278 100644
--- a/x-pack/plugins/cross_cluster_replication/public/app/store/store.js
+++ b/x-pack/plugins/cross_cluster_replication/public/app/store/store.js
@@ -5,12 +5,12 @@
*/
import { applyMiddleware, compose, createStore } from 'redux';
+import thunk from 'redux-thunk';
-import { apiMiddleware, autoFollowPatternMiddleware } from './middleware';
import { ccr } from './reducers';
function createCrossClusterReplicationStore(initialState = {}) {
- const enhancers = [applyMiddleware(apiMiddleware, autoFollowPatternMiddleware)];
+ const enhancers = [applyMiddleware(thunk)];
if (window.__REDUX_DEVTOOLS_EXTENSION__) {
enhancers.push(window.__REDUX_DEVTOOLS_EXTENSION__());
diff --git a/x-pack/plugins/remote_clusters/public/sections/remote_cluster_list/detail_panel/detail_panel.js b/x-pack/plugins/remote_clusters/public/sections/remote_cluster_list/detail_panel/detail_panel.js
index b90ad0148709f..130e92aba0332 100644
--- a/x-pack/plugins/remote_clusters/public/sections/remote_cluster_list/detail_panel/detail_panel.js
+++ b/x-pack/plugins/remote_clusters/public/sections/remote_cluster_list/detail_panel/detail_panel.js
@@ -287,11 +287,6 @@ export const DetailPanel = injectI18n(
closeDetailPanel,
} = this.props;
- // Remote clusters configured by a node's elasticsearch.yml file can't be edited or removed.
- if (!cluster || cluster.isConfiguredByNode) {
- return null;
- }
-
return (
@@ -308,38 +303,40 @@ export const DetailPanel = injectI18n(
-
-
-
-
- {(removeCluster) => (
-
-
-
- )}
-
-
-
-
-
-
-
-
-
-
+ {cluster && !cluster.isConfiguredByNode && (
+
+
+
+
+ {(removeCluster) => (
+
+
+
+ )}
+
+
+
+
+
+
+
+
+
+
+ )}
);