diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/index.tsx b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/index.tsx index 889b6950470fb..d56e8f784a094 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/index.tsx +++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/index.tsx @@ -10,9 +10,9 @@ import React, { Component } from 'react'; import { StickyContainer } from 'react-sticky'; import styled from 'styled-components'; import { + APMQueryParams, fromQuery, history, - QueryParams, toQuery } from 'x-pack/plugins/apm/public/components/shared/Links/url_helpers'; import { IUrlParams } from '../../../../../../store/urlParams'; @@ -150,7 +150,7 @@ export class Waterfall extends Component { ); } - private setQueryParams(params: QueryParams) { + private setQueryParams(params: APMQueryParams) { const { location } = this.props; history.replace({ ...location, diff --git a/x-pack/plugins/apm/public/components/shared/FilterBar/DatePicker.tsx b/x-pack/plugins/apm/public/components/shared/FilterBar/DatePicker.tsx index 97f2ea13d3337..14c63c60cf736 100644 --- a/x-pack/plugins/apm/public/components/shared/FilterBar/DatePicker.tsx +++ b/x-pack/plugins/apm/public/components/shared/FilterBar/DatePicker.tsx @@ -6,7 +6,6 @@ import datemath from '@elastic/datemath'; import { EuiSuperDatePicker, EuiSuperDatePickerProps } from '@elastic/eui'; -import { memoize } from 'lodash'; import React from 'react'; import { connect } from 'react-redux'; import { RouteComponentProps, withRouter } from 'react-router-dom'; @@ -21,36 +20,20 @@ interface Props extends RouteComponentProps { dispatchUpdateTimePicker: typeof updateTimePicker; } -interface DatePickerParams { - rangeFrom: string; - rangeTo: string; - refreshPaused: boolean; - refreshInterval: number; -} - -const APM_DEFAULT_TIME_OPTIONS: DatePickerParams = { - rangeFrom: 'now-24h', - rangeTo: 'now', - refreshPaused: true, - refreshInterval: 0 -}; - class DatePickerComponent extends React.Component { public refreshTimeoutId = 0; - public getParamsFromSearch = memoize((search: string) => { - const query = toQuery(search); - if ('refreshPaused' in query) { - query.refreshPaused = toBoolean(query.refreshPaused); - } - if ('refreshInterval' in query) { - query.refreshInterval = toNumber(query.refreshInterval as string); - } + public getParamsFromSearch = (search: string) => { + const { rangeFrom, rangeTo, refreshPaused, refreshInterval } = toQuery( + search + ); return { - ...APM_DEFAULT_TIME_OPTIONS, - ...query - } as DatePickerParams; - }); + rangeFrom: rangeFrom || 'now-24h', + rangeTo: rangeTo || 'now', + refreshPaused: toBoolean(refreshPaused), + refreshInterval: toNumber(refreshInterval) || 0 + }; + }; public componentDidMount() { this.dispatchTimeRangeUpdate(); diff --git a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverLink.tsx b/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverLink.tsx index 2a86655c88607..5b89f29f34f67 100644 --- a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverLink.tsx +++ b/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverLink.tsx @@ -6,11 +6,11 @@ import React from 'react'; import { KibanaLink } from '../KibanaLink'; -import { QueryParamsDecoded } from '../url_helpers'; +import { APMQueryParams, RisonDecoded } from '../url_helpers'; import { QueryWithIndexPattern } from './QueryWithIndexPattern'; interface Props { - query: QueryParamsDecoded; + query: APMQueryParams | RisonDecoded; children: React.ReactNode; } diff --git a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/QueryWithIndexPattern.tsx b/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/QueryWithIndexPattern.tsx index f184e5df82242..64bcc8cf43ba7 100644 --- a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/QueryWithIndexPattern.tsx +++ b/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/QueryWithIndexPattern.tsx @@ -9,10 +9,12 @@ import { getAPMIndexPattern, ISavedObject } from 'x-pack/plugins/apm/public/services/rest/savedObjects'; -import { QueryParamsDecoded } from '../url_helpers'; +import { APMQueryParams, RisonDecoded } from '../url_helpers'; + +type Query = APMQueryParams & RisonDecoded; export function getQueryWithIndexPattern( - query: QueryParamsDecoded, + query: Query, indexPattern?: ISavedObject ) { if ((query._a && query._a.index) || !indexPattern) { @@ -20,7 +22,6 @@ export function getQueryWithIndexPattern( } const id = indexPattern && indexPattern.id; - return { ...query, _a: { @@ -31,8 +32,8 @@ export function getQueryWithIndexPattern( } interface Props { - query: QueryParamsDecoded; - children: (query: QueryParamsDecoded) => ReactElement; + query: Query; + children: (query: Query) => ReactElement; } interface State { diff --git a/x-pack/plugins/apm/public/components/shared/Links/url_helpers.ts b/x-pack/plugins/apm/public/components/shared/Links/url_helpers.ts index 6ff3263545812..ee7bc8d86c19d 100644 --- a/x-pack/plugins/apm/public/components/shared/Links/url_helpers.ts +++ b/x-pack/plugins/apm/public/components/shared/Links/url_helpers.ts @@ -13,16 +13,19 @@ import chrome from 'ui/chrome'; import url from 'url'; import { StringMap } from 'x-pack/plugins/apm/typings/common'; -export function toQuery(search?: string): QueryParams { +export function toQuery(search?: string): APMQueryParamsRaw & RisonEncoded { return search ? qs.parse(search.slice(1)) : {}; } -export function fromQuery(query: QueryParams) { +export function fromQuery(query: APMQueryParams & RisonEncoded) { const encodedQuery = encodeQuery(query, ['_g', '_a']); return stringifyWithoutEncoding(encodedQuery); } -export function encodeQuery(query: QueryParams, exclude: string[] = []) { +export function encodeQuery( + query: APMQueryParams & RisonEncoded, + exclude: string[] = [] +) { return mapValues(query, (value, key) => { if (exclude.includes(key as string)) { return encodeURI(value); @@ -31,7 +34,7 @@ export function encodeQuery(query: QueryParams, exclude: string[] = []) { }); } -function stringifyWithoutEncoding(query: QueryParams) { +function stringifyWithoutEncoding(query: APMQueryParams & RisonEncoded) { return qs.stringify(query, undefined, undefined, { encodeURIComponent: (v: string) => v }); @@ -94,7 +97,7 @@ export interface KibanaHrefArgs { location: Location; pathname?: string; hash?: string; - query?: QueryParamsDecoded; + query?: APMQueryParams & RisonDecoded; } export function getKibanaHref({ @@ -116,7 +119,7 @@ export function getKibanaHref({ return href; } -interface APMQueryParams { +interface APMQueryParamsRaw { transactionId?: string; traceId?: string; detailTab?: string; @@ -129,6 +132,23 @@ interface APMQueryParams { kuery?: string; rangeFrom?: string; rangeTo?: string; + refreshPaused?: string; + refreshInterval?: string; +} + +export interface APMQueryParams { + transactionId?: string; + traceId?: string; + detailTab?: string; + flyoutDetailTab?: string; + waterfallItemId?: string; + spanId?: string; + page?: string | number; + sortDirection?: string; + sortField?: string; + kuery?: string; + rangeFrom?: string; + rangeTo?: string; refreshPaused?: string | boolean; refreshInterval?: string | number; } @@ -138,14 +158,11 @@ interface RisonEncoded { _a?: string; } -interface RisonDecoded { +export interface RisonDecoded { _g?: StringMap; _a?: StringMap; } -export type QueryParams = APMQueryParams & RisonEncoded; -export type QueryParamsDecoded = APMQueryParams & RisonDecoded; - // This is downright horrible 😭 💔 // Angular decodes encoded url tokens like "%2F" to "/" which causes the route to change. // It was supposedly fixed in https://github.com/angular/angular.js/commit/1b779028fdd339febaa1fff5f3bd4cfcda46cc09 but still seeing the issue diff --git a/x-pack/plugins/apm/public/store/urlParams.ts b/x-pack/plugins/apm/public/store/urlParams.ts index 04837c970a35c..0d08577c1dc0f 100644 --- a/x-pack/plugins/apm/public/store/urlParams.ts +++ b/x-pack/plugins/apm/public/store/urlParams.ts @@ -65,7 +65,7 @@ export function urlParamsReducer(state = {}, action: AnyAction) { detailTab: toString(detailTab), flyoutDetailTab: toString(flyoutDetailTab), spanId: toNumber(spanId), - kuery: legacyDecodeURIComponent(kuery as string | undefined), + kuery: legacyDecodeURIComponent(kuery), // path params processorEvent, @@ -84,8 +84,8 @@ export function urlParamsReducer(state = {}, action: AnyAction) { } } -export function toNumber(value?: string | string[]) { - if (value !== undefined && !Array.isArray(value)) { +export function toNumber(value?: string) { + if (value !== undefined) { return parseInt(value, 10); } } @@ -102,13 +102,8 @@ function toString(str?: string | string[]) { return str; } -export function toBoolean(value?: string | boolean) { - if (value === 'true' || value === true) { - return true; - } - if (value === 'false' || value === false) { - return false; - } +export function toBoolean(value?: string) { + return value === 'true'; } function getPathAsArray(pathname: string) {