Bug 1717212 - Compare View query string parameters are not updated (#7189)

* The filter text from the Perfherder Compare View Page is now updated in URL as query params.
This commit is contained in:
beatrice-acasandrei 2021-07-07 03:23:18 +03:00 коммит произвёл GitHub
Родитель 7ef59ec1c6
Коммит 550d535480
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 142 добавлений и 9 удалений

Просмотреть файл

@ -118,6 +118,7 @@ const results = new Map([['a11yr pgo e10s stylo', result]]);
jest.mock('../../../../ui/models/job');
const mockHandlePermalinkClick = jest.fn();
const mockUpdateParams = jest.fn();
const regexComptableHeaderId = /table-header-\d+/;
const regexComptableRowId = /table-row-\d+/;
@ -140,6 +141,14 @@ const compareTableControlsNode = (
isBaseAggregate={isBaseAggregate}
onPermalinkClick={mockHandlePermalinkClick}
projects={projects}
validated={{
updateParams: mockUpdateParams,
showOnlyImportant: '0',
showOnlyComparable: '0',
showOnlyConfident: '0',
showOnlyNoise: '0',
filter: null,
}}
/>
);
};
@ -204,6 +213,81 @@ test('toggle buttons should filter results by selected filter', async () => {
expect(result2).toBeInTheDocument();
});
test('toggle all buttons should update the URL params', async () => {
const { getByText } = compareTableControls();
const showImportant = await waitFor(() =>
getByText(filterText.showImportant),
);
fireEvent.click(showImportant);
expect(mockUpdateParams).toHaveBeenLastCalledWith({ showOnlyImportant: 1 }, [
'filter',
'showOnlyComparable',
'showOnlyConfident',
'showOnlyNoise',
]);
const hideUncertain = await waitFor(() =>
getByText(filterText.hideUncertain),
);
fireEvent.click(hideUncertain);
expect(mockUpdateParams).toHaveBeenLastCalledWith(
{
showOnlyImportant: 1,
showOnlyConfident: 1,
},
['filter', 'showOnlyComparable', 'showOnlyNoise'],
);
const showNoise = await waitFor(() => getByText(filterText.showNoise));
fireEvent.click(showNoise);
expect(mockUpdateParams).toHaveBeenLastCalledWith(
{
showOnlyImportant: 1,
showOnlyConfident: 1,
showOnlyNoise: 1,
},
['filter', 'showOnlyComparable'],
);
const hideUncomparable = await waitFor(() =>
getByText(filterText.hideUncomparable),
);
fireEvent.click(hideUncomparable);
expect(mockUpdateParams).toHaveBeenLastCalledWith(
{
showOnlyImportant: 1,
showOnlyConfident: 1,
showOnlyNoise: 1,
showOnlyComparable: 1,
},
['filter'],
);
});
test('filters that are not enabled are removed from URL params', async () => {
const { getByText } = compareTableControls();
const showImportant = await waitFor(() =>
getByText(filterText.showImportant),
);
fireEvent.click(showImportant);
expect(mockUpdateParams).toHaveBeenLastCalledWith({ showOnlyImportant: 1 }, [
'filter',
'showOnlyComparable',
'showOnlyConfident',
'showOnlyNoise',
]);
fireEvent.click(showImportant);
expect(mockUpdateParams).toHaveBeenLastCalledWith({}, [
'filter',
'showOnlyComparable',
'showOnlyImportant',
'showOnlyConfident',
'showOnlyNoise',
]);
});
test('text input filter results should differ when filter button(s) are selected', async () => {
const {
getByText,

Просмотреть файл

@ -47,13 +47,17 @@ const withValidation = ({ requiredParams }, verifyRevisions = true) => (
}
}
updateParams = (params) => {
updateParams = (params, paramsToBeRemoved = []) => {
const { history, location } = this.props;
const newParams = {
...parseQueryParams(location.search),
...params,
};
if (paramsToBeRemoved.length !== 0)
paramsToBeRemoved.forEach((param) => {
delete newParams[param];
});
const queryString = createQueryParams(newParams);
history.push({ search: queryString });
};
@ -171,9 +175,11 @@ const withValidation = ({ requiredParams }, verifyRevisions = true) => (
render() {
const updateParams = { updateParams: this.updateParams };
const removeParams = { removeParams: this.removeParams };
const validatedProps = {
...this.state,
...updateParams,
...removeParams,
};
const { validationComplete, errorMessages } = this.state;

Просмотреть файл

@ -192,6 +192,7 @@ export default class AlertsViewControls extends React.Component {
</Container>
)}
<FilterControls
filteredTextValue={filterText}
dropdownOptions={isListMode ? alertDropdowns : []}
filterOptions={alertCheckboxes}
updateFilter={this.updateFilter}

Просмотреть файл

@ -24,7 +24,7 @@ export default class CompareTableControls extends React.Component {
hideUncertain: convertParams(this.validated, 'showOnlyConfident'),
showNoise: convertParams(this.validated, 'showOnlyNoise'),
results: new Map(),
filterText: '',
filteredText: this.getDefaultFilterText(this.validated),
showRetriggerModal: false,
currentRetriggerRow: {},
};
@ -41,8 +41,15 @@ export default class CompareTableControls extends React.Component {
}
}
getDefaultFilterText = (validated) => {
const { filter } = validated;
return filter === undefined || filter === null ? '' : filter;
};
updateFilterText = (filterText) => {
this.setState({ filterText }, () => this.updateFilteredResults());
this.setState({ filteredText: filterText }, () =>
this.updateFilteredResults(),
);
};
updateFilter = (filter) => {
@ -54,7 +61,7 @@ export default class CompareTableControls extends React.Component {
filterResult = (testName, result) => {
const {
filterText,
filteredText,
showImportant,
hideUncertain,
showNoise,
@ -67,18 +74,18 @@ export default class CompareTableControls extends React.Component {
(!hideUncertain || result.isConfident) &&
(!showNoise || result.isNoiseMetric);
if (!filterText) return matchesFilters;
if (!filteredText) return matchesFilters;
const textToSearch = `${testName} ${result.name}`;
// searching with filter input and one or more metricFilter buttons on
// will produce different results compared to when all filters are off
return containsText(textToSearch, filterText) && matchesFilters;
return containsText(textToSearch, filteredText) && matchesFilters;
};
updateFilteredResults = () => {
const {
filterText,
filteredText,
hideUncomparable,
showImportant,
hideUncertain,
@ -87,8 +94,9 @@ export default class CompareTableControls extends React.Component {
const { compareResults } = this.props;
this.updateUrlParams();
if (
!filterText &&
!filteredText &&
!hideUncomparable &&
!showImportant &&
!hideUncertain &&
@ -133,6 +141,36 @@ export default class CompareTableControls extends React.Component {
this.toggleRetriggerModal();
};
updateUrlParams = () => {
const { updateParams } = this.props.validated;
const {
filteredText,
hideUncomparable,
showImportant,
hideUncertain,
showNoise,
} = this.state;
const compareURLParams = {};
const paramsToRemove = [];
if (filteredText !== '') compareURLParams.filter = filteredText;
else paramsToRemove.push('filter');
if (hideUncomparable) compareURLParams.showOnlyComparable = 1;
else paramsToRemove.push('showOnlyComparable');
if (showImportant) compareURLParams.showOnlyImportant = 1;
else paramsToRemove.push('showOnlyImportant');
if (hideUncertain) compareURLParams.showOnlyConfident = 1;
else paramsToRemove.push('showOnlyConfident');
if (showNoise) compareURLParams.showOnlyNoise = 1;
else paramsToRemove.push('showOnlyNoise');
updateParams(compareURLParams, paramsToRemove);
};
onModalOpen = (rowResults) => {
this.setState({ currentRetriggerRow: rowResults });
this.toggleRetriggerModal();
@ -160,6 +198,7 @@ export default class CompareTableControls extends React.Component {
results,
showRetriggerModal,
currentRetriggerRow,
filteredText,
} = this.state;
const compareFilters = [
@ -200,6 +239,7 @@ export default class CompareTableControls extends React.Component {
isBaseAggregate={isBaseAggregate}
/>
<FilterControls
filteredTextValue={filteredText}
filterOptions={compareFilters}
updateFilter={this.updateFilter}
updateFilterText={this.updateFilterText}

Просмотреть файл

@ -49,6 +49,7 @@ const FilterControls = ({
updateFilter,
updateOnEnter,
dropdownCol,
filteredTextValue,
}) => {
const createButton = (filter) => (
<Button
@ -75,6 +76,7 @@ const FilterControls = ({
<Col className="col-2 py-2 pl-0 pr-2">
<InputFilter
filteredTextValue={filteredTextValue}
updateFilterText={updateFilterText}
updateOnEnter={updateOnEnter}
/>

Просмотреть файл

@ -10,7 +10,7 @@ export default class InputFilter extends React.Component {
constructor(props) {
super(props);
this.state = {
input: '',
input: props.filteredTextValue,
};
}