diff --git a/x-pack/plugins/remote_clusters/__jest__/client_integration/helpers/remote_clusters_list.helpers.js b/x-pack/plugins/remote_clusters/__jest__/client_integration/helpers/remote_clusters_list.helpers.js
index dc9b22b40542a..1d5bc52038ffc 100644
--- a/x-pack/plugins/remote_clusters/__jest__/client_integration/helpers/remote_clusters_list.helpers.js
+++ b/x-pack/plugins/remote_clusters/__jest__/client_integration/helpers/remote_clusters_list.helpers.js
@@ -69,6 +69,10 @@ export const setup = props => {
remoteClusterLink.simulate('click');
};
+ const clickPaginationNextButton = () => {
+ testBed.find('remoteClusterListTable.pagination-button-next').simulate('click');
+ };
+
return {
...testBed,
actions: {
@@ -77,6 +81,7 @@ export const setup = props => {
clickRowActionButtonAt,
clickConfirmModalDeleteRemoteCluster,
clickRemoteClusterAt,
+ clickPaginationNextButton,
},
};
};
diff --git a/x-pack/plugins/remote_clusters/__jest__/client_integration/remote_clusters_list.test.js b/x-pack/plugins/remote_clusters/__jest__/client_integration/remote_clusters_list.test.js
index bc73387831c9d..e72ea815aad83 100644
--- a/x-pack/plugins/remote_clusters/__jest__/client_integration/remote_clusters_list.test.js
+++ b/x-pack/plugins/remote_clusters/__jest__/client_integration/remote_clusters_list.test.js
@@ -69,6 +69,52 @@ describe('', () => {
});
});
+ describe('when there are multiple pages of remote clusters', () => {
+ let table;
+ let actions;
+ let waitFor;
+ let form;
+ let component;
+
+ const remoteClusters = [
+ {
+ name: 'unique',
+ seeds: [],
+ },
+ ];
+
+ for (let i = 0; i < 29; i++) {
+ remoteClusters.push({
+ name: `name${i}`,
+ seeds: [],
+ });
+ }
+
+ beforeEach(async () => {
+ httpRequestsMockHelpers.setLoadRemoteClustersResponse(remoteClusters);
+
+ await act(async () => {
+ ({ component, table, actions, waitFor, form } = setup());
+ await waitFor('remoteClusterListTable');
+ });
+ });
+
+ test('pagination works', () => {
+ actions.clickPaginationNextButton();
+ const { tableCellsValues } = table.getMetaData('remoteClusterListTable');
+
+ // Pagination defaults to 20 remote clusters per page. We loaded 30 remote clusters,
+ // so the second page should have 10.
+ expect(tableCellsValues.length).toBe(10);
+ });
+
+ test('search works', () => {
+ form.setInputValue(component.find('input[type="search"]'), 'unique');
+ const { tableCellsValues } = table.getMetaData('remoteClusterListTable');
+ expect(tableCellsValues.length).toBe(1);
+ });
+ });
+
describe('when there are remote clusters', () => {
let find;
let exists;
diff --git a/x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/remote_cluster_table/remote_cluster_table.js b/x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/remote_cluster_table/remote_cluster_table.js
index 73f32fe8bca5b..11e3eb0a0c8e4 100644
--- a/x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/remote_cluster_table/remote_cluster_table.js
+++ b/x-pack/plugins/remote_clusters/public/application/sections/remote_cluster_list/remote_cluster_table/remote_cluster_table.js
@@ -25,6 +25,24 @@ import { PROXY_MODE } from '../../../../../common/constants';
import { getRouterLinkProps, trackUiMetric, METRIC_TYPE } from '../../../services';
import { ConnectionStatus, RemoveClusterButtonProvider } from '../components';
+const getFilteredClusters = (clusters, queryText) => {
+ if (queryText) {
+ const normalizedSearchText = queryText.toLowerCase();
+
+ return clusters.filter(cluster => {
+ const { name, seeds } = cluster;
+ const normalizedName = name.toLowerCase();
+ if (normalizedName.toLowerCase().includes(normalizedSearchText)) {
+ return true;
+ }
+
+ return seeds.some(seed => seed.includes(normalizedSearchText));
+ });
+ } else {
+ return clusters;
+ }
+};
+
export class RemoteClusterTable extends Component {
static propTypes = {
clusters: PropTypes.array,
@@ -35,46 +53,47 @@ export class RemoteClusterTable extends Component {
clusters: [],
};
+ static getDerivedStateFromProps(props, state) {
+ const { clusters } = props;
+ const { prevClusters, queryText } = state;
+
+ // If a remote cluster gets deleted, we need to recreate the cached filtered clusters.
+ if (prevClusters !== clusters) {
+ return {
+ prevClusters: clusters,
+ filteredClusters: getFilteredClusters(clusters, queryText),
+ };
+ }
+
+ return null;
+ }
+
constructor(props) {
super(props);
this.state = {
- queryText: undefined,
+ prevClusters: props.clusters,
selectedItems: [],
+ filteredClusters: props.clusters,
+ queryText: '',
};
}
onSearch = ({ query }) => {
+ const { clusters } = this.props;
const { text } = query;
- const normalizedSearchText = text.toLowerCase();
+
+ // We cache the filtered indices instead of calculating them inside render() because
+ // of https://github.com/elastic/eui/issues/3445.
this.setState({
- queryText: normalizedSearchText,
+ queryText: text,
+ filteredClusters: getFilteredClusters(clusters, text),
});
};
- getFilteredClusters = () => {
- const { clusters } = this.props;
- const { queryText } = this.state;
-
- if (queryText) {
- return clusters.filter(cluster => {
- const { name, seeds } = cluster;
- const normalizedName = name.toLowerCase();
- if (normalizedName.toLowerCase().includes(queryText)) {
- return true;
- }
-
- return seeds.some(seed => seed.includes(queryText));
- });
- } else {
- return clusters.slice(0);
- }
- };
-
render() {
const { openDetailPanel } = this.props;
-
- const { selectedItems } = this.state;
+ const { selectedItems, filteredClusters } = this.state;
const columns = [
{
@@ -327,8 +346,6 @@ export class RemoteClusterTable extends Component {
selectable: ({ isConfiguredByNode }) => !isConfiguredByNode,
};
- const filteredClusters = this.getFilteredClusters();
-
return (