Skip to content

Commit

Permalink
Fix broken pagination in CCR Auto-follow patterns table.
Browse files Browse the repository at this point in the history
  • Loading branch information
cjcenizal committed May 9, 2020
1 parent c3048f8 commit 4dbdd12
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,48 @@ describe('<AutoFollowPatternList />', () => {
});
});

describe('when there are multiple pages of auto-follow patterns', () => {
let component;
let table;
let actions;
let form;

const autoFollowPatterns = [
getAutoFollowPatternMock({ name: 'unique', followPattern: '{{leader_index}}' }),
];

for (let i = 0; i < 29; i++) {
autoFollowPatterns.push(
getAutoFollowPatternMock({ name: `${i}`, followPattern: '{{leader_index}}' })
);
}

beforeEach(async () => {
httpRequestsMockHelpers.setLoadAutoFollowPatternsResponse({ patterns: autoFollowPatterns });

// Mount the component
({ component, table, actions, form } = setup());

await nextTick(); // Make sure that the http request is fulfilled
component.update();
});

test('pagination works', () => {
actions.clickPaginationNextButton();
const { tableCellsValues } = table.getMetaData('autoFollowPatternListTable');

// Pagination defaults to 20 auto-follow patterns per page. We loaded 30 auto-follow patterns,
// 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('autoFollowPatternListTable');
expect(tableCellsValues.length).toBe(1);
});
});

describe('when there are auto-follow patterns', () => {
let find;
let exists;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ export const setup = props => {
autoFollowPatternLink.simulate('click');
};

const clickPaginationNextButton = () => {
testBed.find('autoFollowPatternListTable.pagination-button-next').simulate('click');
};

return {
...testBed,
actions: {
Expand All @@ -94,6 +98,7 @@ export const setup = props => {
clickAutoFollowPatternAt,
getPatternsActionMenuItemText,
clickPatternsActionMenuItem,
clickPaginationNextButton,
},
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,30 @@ import {
import { routing } from '../../../../../services/routing';
import { trackUiMetric } from '../../../../../services/track_ui_metric';

const getFilteredPatterns = (autoFollowPatterns, queryText) => {
if (queryText) {
const normalizedSearchText = queryText.toLowerCase();

return autoFollowPatterns.filter(autoFollowPattern => {
const {
name,
remoteCluster,
followIndexPatternPrefix,
followIndexPatternSuffix,
} = autoFollowPattern;

const inName = name.toLowerCase().includes(normalizedSearchText);
const inRemoteCluster = remoteCluster.toLowerCase().includes(normalizedSearchText);
const inPrefix = followIndexPatternPrefix.toLowerCase().includes(normalizedSearchText);
const inSuffix = followIndexPatternSuffix.toLowerCase().includes(normalizedSearchText);

return inName || inRemoteCluster || inPrefix || inSuffix;
});
}

return autoFollowPatterns;
};

export class AutoFollowPatternTable extends PureComponent {
static propTypes = {
autoFollowPatterns: PropTypes.array,
Expand All @@ -31,41 +55,42 @@ export class AutoFollowPatternTable extends PureComponent {
resumeAutoFollowPattern: PropTypes.func.isRequired,
};

state = {
selectedItems: [],
};
static getDerivedStateFromProps(props, state) {
const { autoFollowPatterns } = props;
const { prevAutoFollowPatterns, queryText } = state;

onSearch = ({ query }) => {
const { text } = query;
const normalizedSearchText = text.toLowerCase();
this.setState({
queryText: normalizedSearchText,
});
};
// If an auto-follow pattern gets deleted, we need to recreate the cached filtered auto-follow patterns.
if (prevAutoFollowPatterns !== autoFollowPatterns) {
return {
prevAutoFollowPatterns: autoFollowPatterns,
filteredAutoFollowPatterns: getFilteredPatterns(autoFollowPatterns, queryText),
};
}

getFilteredPatterns = () => {
const { autoFollowPatterns } = this.props;
const { queryText } = this.state;
return null;
}

if (queryText) {
return autoFollowPatterns.filter(autoFollowPattern => {
const {
name,
remoteCluster,
followIndexPatternPrefix,
followIndexPatternSuffix,
} = autoFollowPattern;
constructor(props) {
super(props);

const inName = name.toLowerCase().includes(queryText);
const inRemoteCluster = remoteCluster.toLowerCase().includes(queryText);
const inPrefix = followIndexPatternPrefix.toLowerCase().includes(queryText);
const inSuffix = followIndexPatternSuffix.toLowerCase().includes(queryText);
this.state = {
prevAutoFollowPatterns: props.autoFollowPatterns,
selectedItems: [],
filteredAutoFollowPatterns: props.autoFollowPatterns,
queryText: '',
};
}

return inName || inRemoteCluster || inPrefix || inSuffix;
});
}
onSearch = ({ query }) => {
const { autoFollowPatterns } = this.props;
const { text } = query;

return autoFollowPatterns.slice(0);
// We cache the filtered indices instead of calculating them inside render() because
// of https://github.com/elastic/eui/issues/3445.
this.setState({
queryText: text,
filteredAutoFollowPatterns: getFilteredPatterns(autoFollowPatterns, text),
});
};

getTableColumns() {
Expand Down Expand Up @@ -144,7 +169,7 @@ export class AutoFollowPatternTable extends PureComponent {
defaultMessage: 'Leader patterns',
}
),
render: leaderPatterns => leaderPatterns.join(', '),
render: leaderIndexPatterns => leaderIndexPatterns.join(', '),
},
{
field: 'followIndexPatternPrefix',
Expand Down Expand Up @@ -278,7 +303,7 @@ export class AutoFollowPatternTable extends PureComponent {
};

render() {
const { selectedItems } = this.state;
const { selectedItems, filteredAutoFollowPatterns } = this.state;

const sorting = {
sort: {
Expand All @@ -297,13 +322,13 @@ export class AutoFollowPatternTable extends PureComponent {
this.setState({ selectedItems: selectedItems.map(({ name }) => name) }),
};

const items = this.getFilteredPatterns();

const search = {
toolsLeft: selectedItems.length ? (
<AutoFollowPatternActionMenu
arrowDirection="down"
patterns={this.state.selectedItems.map(name => items.find(item => item.name === name))}
patterns={this.state.selectedItems.map(name =>
filteredAutoFollowPatterns.find(item => item.name === name)
)}
/>
) : (
undefined
Expand All @@ -317,7 +342,7 @@ export class AutoFollowPatternTable extends PureComponent {
return (
<Fragment>
<EuiInMemoryTable
items={items}
items={filteredAutoFollowPatterns}
itemId="name"
columns={this.getTableColumns()}
search={search}
Expand Down

0 comments on commit 4dbdd12

Please sign in to comment.