Skip to content

Commit

Permalink
respect existing query params when opening or closing flyouyt
Browse files Browse the repository at this point in the history
  • Loading branch information
oatkiller committed Feb 20, 2020
1 parent 5d26716 commit a160717
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,47 @@
import { Store, createStore, applyMiddleware } from 'redux';
import { History } from 'history';
import { alertListReducer } from './reducer';
import { AlertListState } from '../../types';
import { AlertListState, AlertingIndexUIQueryParams } from '../../types';
import { alertMiddlewareFactory } from './middleware';
import { AppAction } from '../action';
import { coreMock } from 'src/core/public/mocks';
import { createBrowserHistory } from 'history';
import { urlFromNewPageSizeParam, uiQueryParams, urlFromNewPageIndexParam } from './selectors';
import { uiQueryParams } from './selectors';
import { urlFromQueryParams } from '../../view/alerts/url_from_query_params';

describe('alert list pagination', () => {
let store: Store<AlertListState, AppAction>;
let coreStart: ReturnType<typeof coreMock.createStart>;
let history: History<never>;
let queryParams: () => AlertingIndexUIQueryParams;
/**
* Update the history with a new `AlertingIndexUIQueryParams`
*/
let historyPush: (params: AlertingIndexUIQueryParams) => void;
beforeEach(() => {
coreStart = coreMock.createStart();
history = createBrowserHistory();

const middleware = alertMiddlewareFactory(coreStart);
store = createStore(alertListReducer, applyMiddleware(middleware));

history.listen(location => {
store.dispatch({ type: 'userChangedUrl', payload: location });
});

queryParams = () => uiQueryParams(store.getState());

historyPush = (nextQueryParams: AlertingIndexUIQueryParams): void => {
return history.push(urlFromQueryParams(nextQueryParams));
};
});
describe('when the user navigates to the alert list page', () => {
describe('when a new page size is passed', () => {
beforeEach(() => {
const urlPageSizeSelector = urlFromNewPageSizeParam(store.getState());
history.push(urlPageSizeSelector(1));
store.dispatch({ type: 'userChangedUrl', payload: history.location });
historyPush({ ...queryParams(), page_size: '1' });
});
it('should modify the url correctly', () => {
const actualPaginationQuery = uiQueryParams(store.getState());
expect(actualPaginationQuery).toMatchInlineSnapshot(`
expect(queryParams()).toMatchInlineSnapshot(`
Object {
"page_size": "1",
}
Expand All @@ -42,13 +56,10 @@ describe('alert list pagination', () => {

describe('and then a new page index is passed', () => {
beforeEach(() => {
const urlPageIndexSelector = urlFromNewPageIndexParam(store.getState());
history.push(urlPageIndexSelector(1));
store.dispatch({ type: 'userChangedUrl', payload: history.location });
historyPush({ ...queryParams(), page_index: '1' });
});
it('should modify the url in the correct order', () => {
const actualPaginationQuery = uiQueryParams(store.getState());
expect(actualPaginationQuery).toMatchInlineSnapshot(`
expect(queryParams()).toMatchInlineSnapshot(`
Object {
"page_index": "1",
"page_size": "1",
Expand All @@ -60,13 +71,10 @@ describe('alert list pagination', () => {

describe('when a new page index is passed', () => {
beforeEach(() => {
const urlPageIndexSelector = urlFromNewPageIndexParam(store.getState());
history.push(urlPageIndexSelector(1));
store.dispatch({ type: 'userChangedUrl', payload: history.location });
historyPush({ ...queryParams(), page_index: '1' });
});
it('should modify the url correctly', () => {
const actualPaginationQuery = uiQueryParams(store.getState());
expect(actualPaginationQuery).toMatchInlineSnapshot(`
expect(queryParams()).toMatchInlineSnapshot(`
Object {
"page_index": "1",
}
Expand All @@ -75,13 +83,10 @@ describe('alert list pagination', () => {

describe('and then a new page size is passed', () => {
beforeEach(() => {
const urlPageSizeSelector = urlFromNewPageSizeParam(store.getState());
history.push(urlPageSizeSelector(1));
store.dispatch({ type: 'userChangedUrl', payload: history.location });
historyPush({ ...queryParams(), page_size: '1' });
});
it('should modify the url correctly and reset index to `0`', () => {
const actualPaginationQuery = uiQueryParams(store.getState());
expect(actualPaginationQuery).toMatchInlineSnapshot(`
expect(queryParams()).toMatchInlineSnapshot(`
Object {
"page_size": "1",
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/

import qs from 'querystring';
import querystring from 'querystring';
import {
createSelector,
createStructuredSelector as createStructuredSelectorWithBadType,
Expand Down Expand Up @@ -52,7 +52,7 @@ export const uiQueryParams: (
const data: AlertingIndexUIQueryParams = {};
if (location) {
// Removes the `?` from the beginning of query string if it exists
const query = qs.parse(location.search.slice(1));
const query = querystring.parse(location.search.slice(1));

/**
* Build an AlertingIndexUIQueryParams object with keys from the query.
Expand Down Expand Up @@ -105,7 +105,7 @@ export const urlFromNewPageSizeParam: (
if (queryParams.page_index !== undefined) {
delete queryParams.page_index;
}
return '?' + qs.stringify(queryParams);
return '?' + querystring.stringify(queryParams);
};
});

Expand All @@ -118,7 +118,7 @@ export const urlFromNewPageIndexParam: (
return newPageIndex => {
const queryParams: AlertingIndexUIQueryParams = { ...paramData };
queryParams.page_index = newPageIndex.toString();
return '?' + qs.stringify(queryParams);
return '?' + querystring.stringify(queryParams);
};
});

Expand All @@ -131,7 +131,7 @@ export const urlWithSelectedAlert: (
return (alertID: string) => {
const queryParams = { ...paramData };
queryParams.selected_alert = alertID;
return '?' + qs.stringify(queryParams);
return '?' + querystring.stringify(queryParams);
};
});

Expand All @@ -143,7 +143,7 @@ export const urlWithoutSelectedAlert: (state: AlertListState) => string = create
urlPaginationData => {
const queryParams = { ...urlPaginationData };
delete queryParams.selected_alert;
return '?' + qs.stringify(queryParams);
return '?' + querystring.stringify(queryParams);
}
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
import { i18n } from '@kbn/i18n';
import { useHistory, Link } from 'react-router-dom';
import { FormattedDate } from 'react-intl';
import { urlFromQueryParams } from './url_from_query_params';
import { AlertData } from '../../../../../common/types';
import * as selectors from '../../store/alerts/selectors';
import { useAlertListSelector } from './hooks/use_alerts_selector';
Expand Down Expand Up @@ -82,28 +83,38 @@ export const AlertIndex = memo(() => {
}, []);

const { pageIndex, pageSize, total } = useAlertListSelector(selectors.alertListPagination);
const urlFromNewPageSizeParam = useAlertListSelector(selectors.urlFromNewPageSizeParam);
const urlWithSelectedAlert = useAlertListSelector(selectors.urlWithSelectedAlert);
const urlWithoutSelectedAlert = useAlertListSelector(selectors.urlWithoutSelectedAlert);
const urlFromNewPageIndexParam = useAlertListSelector(selectors.urlFromNewPageIndexParam);
const alertListData = useAlertListSelector(selectors.alertListData);
const hasSelectedAlert = useAlertListSelector(selectors.hasSelectedAlert);
const queryParams = useAlertListSelector(selectors.uiQueryParams);

const onChangeItemsPerPage = useCallback(
newPageSize => history.push(urlFromNewPageSizeParam(newPageSize)),
[history, urlFromNewPageSizeParam]
newPageSize => {
const newQueryParms = { ...queryParams };
newQueryParms.page_size = newPageSize;
const relativeURL = urlFromQueryParams(newQueryParms);
return history.push(relativeURL);
},
[history, queryParams]
);

const onChangePage = useCallback(
newPageIndex => history.push(urlFromNewPageIndexParam(newPageIndex)),
[history, urlFromNewPageIndexParam]
newPageIndex => {
return history.push(
urlFromQueryParams({
...queryParams,
page_index: newPageIndex,
})
);
},
[history, queryParams]
);

const [visibleColumns, setVisibleColumns] = useState(() => columns.map(({ id }) => id));

const handleFlyoutClose = useCallback(() => {
history.push(urlWithoutSelectedAlert);
}, [history, urlWithoutSelectedAlert]);
const { selected_alert, ...paramsWithoutSelectedAlert } = queryParams;
history.push(urlFromQueryParams(paramsWithoutSelectedAlert));
}, [history, queryParams]);

const datesForRows: Map<AlertData, Date> = useMemo(() => {
return new Map(
Expand All @@ -123,7 +134,10 @@ export const AlertIndex = memo(() => {

if (columnId === 'alert_type') {
return (
<Link data-testid="alertTypeCellLink" to={urlWithSelectedAlert('TODO')}>
<Link
data-testid="alertTypeCellLink"
to={urlFromQueryParams({ ...queryParams, selected_alert: 'TODO' })}
>
{i18n.translate(
'xpack.endpoint.application.endpoint.alerts.alertType.maliciousFileDescription',
{
Expand Down Expand Up @@ -173,7 +187,7 @@ export const AlertIndex = memo(() => {
}
return null;
};
}, [alertListData, datesForRows, pageSize, total, urlWithSelectedAlert]);
}, [alertListData, datesForRows, pageSize, queryParams, total]);

const pagination = useMemo(() => {
return {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* 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 querystring from 'querystring';
import { AlertingIndexUIQueryParams } from '../../types';

export function urlFromQueryParams(queryParams: AlertingIndexUIQueryParams): string {
const search = querystring.stringify(queryParams);
return search === '' ? '' : '?' + search;
}

0 comments on commit a160717

Please sign in to comment.