From edbd9c10c0b3623c2164d8f34d361ee7ed43679e Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Fri, 8 May 2020 13:28:27 -0700 Subject: [PATCH] Fix broken pagination in Remote Clusters table. --- .../helpers/remote_clusters_list.helpers.js | 5 ++ .../remote_clusters_list.test.js | 46 +++++++++++++ .../remote_cluster_table.js | 69 ++++++++++++------- 3 files changed, 94 insertions(+), 26 deletions(-) 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 (