From c4ca5bf4b0e849e8ecc6e6607170d2fc4a4840b9 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Tue, 25 Aug 2020 17:51:50 +0200 Subject: [PATCH 1/5] use select for breakdown --- .../Breakdowns/BreakdownFilter.tsx | 62 ++++++----- .../Breakdowns/BreakdownGroup.tsx | 100 ------------------ .../RumDashboard/Charts/PageLoadDistChart.tsx | 14 +-- .../PageLoadDistribution/index.tsx | 11 +- .../app/RumDashboard/PageViewsTrend/index.tsx | 17 ++- .../lib/rum_client/get_page_view_trends.ts | 35 +++--- 6 files changed, 72 insertions(+), 167 deletions(-) delete mode 100644 x-pack/plugins/apm/public/components/app/RumDashboard/Breakdowns/BreakdownGroup.tsx diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/Breakdowns/BreakdownFilter.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/Breakdowns/BreakdownFilter.tsx index 7e5e7cdc53c55..131bdf1370f24 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/Breakdowns/BreakdownFilter.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/Breakdowns/BreakdownFilter.tsx @@ -5,64 +5,74 @@ */ import React from 'react'; -import { BreakdownGroup } from './BreakdownGroup'; -import { BreakdownItem } from '../../../../../typings/ui_filters'; +import { EuiSuperSelect } from '@elastic/eui'; import { CLIENT_GEO_COUNTRY_ISO_CODE, USER_AGENT_DEVICE, USER_AGENT_NAME, USER_AGENT_OS, } from '../../../../../common/elasticsearch_fieldnames'; +import { BreakdownItem } from '../../../../../typings/ui_filters'; interface Props { - id: string; - selectedBreakdowns: BreakdownItem[]; - onBreakdownChange: (values: BreakdownItem[]) => void; + selectedBreakdown: BreakdownItem; + onBreakdownChange: (value: BreakdownItem) => void; } export function BreakdownFilter({ - id, - selectedBreakdowns, + selectedBreakdown, onBreakdownChange, }: Props) { - const categories: BreakdownItem[] = [ + const NO_BREAKDOWN = 'noBreakdown'; + + const items: BreakdownItem[] = [ { - name: 'Browser', + name: '- No breakdown -', + fieldName: NO_BREAKDOWN, type: 'category', - count: 0, - selected: selectedBreakdowns.some(({ name }) => name === 'Browser'), + }, + { + name: 'Browser', fieldName: USER_AGENT_NAME, + type: 'category', }, { name: 'OS', - type: 'category', - count: 0, - selected: selectedBreakdowns.some(({ name }) => name === 'OS'), fieldName: USER_AGENT_OS, + type: 'category', }, { name: 'Device', - type: 'category', - count: 0, - selected: selectedBreakdowns.some(({ name }) => name === 'Device'), fieldName: USER_AGENT_DEVICE, + type: 'category', }, { name: 'Location', - type: 'category', - count: 0, - selected: selectedBreakdowns.some(({ name }) => name === 'Location'), fieldName: CLIENT_GEO_COUNTRY_ISO_CODE, + type: 'category', }, ]; + const options = items.map(({ name, fieldName }) => ({ + inputDisplay: fieldName === NO_BREAKDOWN ? name : {name}, + value: fieldName, + dropdownDisplay: name, + })); + + const onOptionChange = (value) => { + if (value === NO_BREAKDOWN) { + onBreakdownChange(null); + } + onBreakdownChange(items.find(({ fieldName }) => fieldName === value)); + }; + return ( - { - onBreakdownChange(selValues); - }} + onOptionChange(value)} /> ); } diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/Breakdowns/BreakdownGroup.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/Breakdowns/BreakdownGroup.tsx deleted file mode 100644 index d4f80667ce98b..0000000000000 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/Breakdowns/BreakdownGroup.tsx +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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 { - EuiPopover, - EuiFilterButton, - EuiFilterGroup, - EuiPopoverTitle, - EuiFilterSelectItem, -} from '@elastic/eui'; -import React, { MouseEvent, useCallback, useEffect, useState } from 'react'; -import { BreakdownItem } from '../../../../../typings/ui_filters'; -import { I18LABELS } from '../translations'; - -export interface BreakdownGroupProps { - id: string; - disabled?: boolean; - items: BreakdownItem[]; - onChange: (values: BreakdownItem[]) => void; -} - -export function BreakdownGroup({ - id, - disabled, - onChange, - items, -}: BreakdownGroupProps) { - const [isOpen, setIsOpen] = useState(false); - - const [activeItems, setActiveItems] = useState(items); - - useEffect(() => { - setActiveItems(items); - }, [items]); - - const getSelItems = () => activeItems.filter((item) => item.selected); - - const onFilterItemClick = useCallback( - (name: string) => (_event: MouseEvent) => { - setActiveItems((prevItems) => - prevItems.map((item) => ({ - ...item, - selected: name === item.name ? !item.selected : item.selected, - })) - ); - }, - [] - ); - - return ( - - 0} - numFilters={activeItems.length} - numActiveFilters={getSelItems().length} - hasActiveFilters={getSelItems().length !== 0} - iconType="arrowDown" - onClick={() => { - setIsOpen(!isOpen); - }} - size="s" - > - {I18LABELS.breakdown} - - } - closePopover={() => { - setIsOpen(false); - onChange(getSelItems()); - }} - data-cy={`breakdown-popover_${id}`} - id={id} - isOpen={isOpen} - ownFocus={true} - withTitle - zIndex={10000} - > - {I18LABELS.selectBreakdown} -
- {activeItems.map(({ name, count, selected }) => ( - 0} - > - {name} - - ))} -
-
-
- ); -} diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/Charts/PageLoadDistChart.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/Charts/PageLoadDistChart.tsx index b2b5e66d06ac6..2674134e3c5d4 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/Charts/PageLoadDistChart.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/Charts/PageLoadDistChart.tsx @@ -43,7 +43,7 @@ interface PageLoadData { interface Props { onPercentileChange: (min: number, max: number) => void; data?: PageLoadData | null; - breakdowns: BreakdownItem[]; + breakdown: BreakdownItem; percentileRange: PercentileRange; loading: boolean; } @@ -57,7 +57,7 @@ const PageLoadChart = styled(Chart)` export function PageLoadDistChart({ onPercentileChange, data, - breakdowns, + breakdown, loading, percentileRange, }: Props) { @@ -122,17 +122,17 @@ export function PageLoadDistChart({ data={data?.pageLoadDistribution ?? []} curve={CurveType.CURVE_CATMULL_ROM} /> - {breakdowns.map(({ name, type }) => ( + {breakdown && ( { setBreakdownLoading(bLoading); }} /> - ))} + )} )} diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/index.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/index.tsx index 53f2d5ae238c5..ca88dbe37ce0f 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/index.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/index.tsx @@ -34,7 +34,7 @@ export function PageLoadDistribution() { max: null, }); - const [breakdowns, setBreakdowns] = useState([]); + const [breakdown, setBreakdown] = useState(); const { data, status } = useFetcher( (callApmApi) => { @@ -94,11 +94,10 @@ export function PageLoadDistribution() { {I18LABELS.resetZoom} - + @@ -107,7 +106,7 @@ export function PageLoadDistribution() { data={data} onPercentileChange={onPercentileChange} loading={status !== 'success'} - breakdowns={breakdowns} + breakdown={breakdown} percentileRange={{ max: percentileRange.max || data?.maxDuration, min: percentileRange.min || data?.minDuration, diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/PageViewsTrend/index.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/PageViewsTrend/index.tsx index 0f43c0ddf540d..94ba5e8431e8c 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/PageViewsTrend/index.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/PageViewsTrend/index.tsx @@ -18,7 +18,7 @@ export function PageViewsTrend() { const { start, end, serviceName } = urlParams; - const [breakdowns, setBreakdowns] = useState([]); + const [breakdown, setBreakdown] = useState(); const { data, status } = useFetcher( (callApmApi) => { @@ -30,9 +30,9 @@ export function PageViewsTrend() { start, end, uiFilters: JSON.stringify(uiFilters), - ...(breakdowns.length > 0 + ...(breakdown ? { - breakdowns: JSON.stringify(breakdowns), + breakdowns: JSON.stringify(breakdown), } : {}), }, @@ -41,11 +41,11 @@ export function PageViewsTrend() { } return Promise.resolve(undefined); }, - [end, start, serviceName, uiFilters, breakdowns] + [end, start, serviceName, uiFilters, breakdown] ); - const onBreakdownChange = (values: BreakdownItem[]) => { - setBreakdowns(values); + const onBreakdownChange = (value: BreakdownItem) => { + setBreakdown(value); }; return ( @@ -56,10 +56,9 @@ export function PageViewsTrend() {

{I18LABELS.pageViews}

- + diff --git a/x-pack/plugins/apm/server/lib/rum_client/get_page_view_trends.ts b/x-pack/plugins/apm/server/lib/rum_client/get_page_view_trends.ts index 23169ddaca534..fe82212fafcec 100644 --- a/x-pack/plugins/apm/server/lib/rum_client/get_page_view_trends.ts +++ b/x-pack/plugins/apm/server/lib/rum_client/get_page_view_trends.ts @@ -24,19 +24,7 @@ export async function getPageViewTrends({ const projection = getRumOverviewProjection({ setup, }); - const breakdownAggs: AggregationInputMap = {}; - if (breakdowns) { - const breakdownList: BreakdownItem[] = JSON.parse(breakdowns); - breakdownList.forEach(({ name, type, fieldName }) => { - breakdownAggs[name] = { - terms: { - field: fieldName, - size: 9, - missing: 'Other', - }, - }; - }); - } + const breakdownItem: BreakdownItem = JSON.parse(breakdowns ?? null); const params = mergeProjection(projection, { body: { @@ -50,7 +38,17 @@ export async function getPageViewTrends({ field: '@timestamp', buckets: 50, }, - aggs: breakdownAggs, + aggs: breakdownItem + ? { + breakdown: { + terms: { + field: breakdownItem.fieldName, + size: 9, + missing: 'Other', + }, + }, + } + : undefined, }, }, }, @@ -68,19 +66,18 @@ export async function getPageViewTrends({ x: xVal, y: bCount, }; - - Object.keys(breakdownAggs).forEach((bKey) => { - const categoryBuckets = (bucket[bKey] as any).buckets; + if (breakdownItem) { + const categoryBuckets = (bucket.breakdown as any).buckets; categoryBuckets.forEach( ({ key, doc_count: docCount }: { key: string; doc_count: number }) => { if (key === 'Other') { - res[key + `(${bKey})`] = docCount; + res[key + `(${breakdownItem.name})`] = docCount; } else { res[key] = docCount; } } ); - }); + } return res; }); From e88a9ec485a7948c558c9e6252ccf0ac77c17465 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Wed, 26 Aug 2020 14:46:12 +0200 Subject: [PATCH 2/5] WIP --- .../app/RumDashboard/Breakdowns/BreakdownFilter.tsx | 8 ++++---- .../app/RumDashboard/Charts/PageLoadDistChart.tsx | 2 +- .../app/RumDashboard/PageLoadDistribution/index.tsx | 2 +- .../components/app/RumDashboard/PageViewsTrend/index.tsx | 4 ++-- .../lib/rum_client/__snapshots__/queries.test.ts.snap | 2 +- .../apm/server/lib/rum_client/get_page_view_trends.ts | 6 ++++-- x-pack/plugins/apm/typings/ui_filters.ts | 1 - 7 files changed, 13 insertions(+), 12 deletions(-) diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/Breakdowns/BreakdownFilter.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/Breakdowns/BreakdownFilter.tsx index 131bdf1370f24..c7c47709b6a6d 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/Breakdowns/BreakdownFilter.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/Breakdowns/BreakdownFilter.tsx @@ -15,8 +15,8 @@ import { import { BreakdownItem } from '../../../../../typings/ui_filters'; interface Props { - selectedBreakdown: BreakdownItem; - onBreakdownChange: (value: BreakdownItem) => void; + selectedBreakdown: BreakdownItem | null; + onBreakdownChange: (value: BreakdownItem | null) => void; } export function BreakdownFilter({ @@ -59,11 +59,11 @@ export function BreakdownFilter({ dropdownDisplay: name, })); - const onOptionChange = (value) => { + const onOptionChange = (value: string) => { if (value === NO_BREAKDOWN) { onBreakdownChange(null); } - onBreakdownChange(items.find(({ fieldName }) => fieldName === value)); + onBreakdownChange(items.find(({ fieldName }) => fieldName === value)!); }; return ( diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/Charts/PageLoadDistChart.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/Charts/PageLoadDistChart.tsx index 2674134e3c5d4..419cb307ed6ba 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/Charts/PageLoadDistChart.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/Charts/PageLoadDistChart.tsx @@ -43,7 +43,7 @@ interface PageLoadData { interface Props { onPercentileChange: (min: number, max: number) => void; data?: PageLoadData | null; - breakdown: BreakdownItem; + breakdown: BreakdownItem | null; percentileRange: PercentileRange; loading: boolean; } diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/index.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/index.tsx index ca88dbe37ce0f..3e35f15254937 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/index.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/index.tsx @@ -34,7 +34,7 @@ export function PageLoadDistribution() { max: null, }); - const [breakdown, setBreakdown] = useState(); + const [breakdown, setBreakdown] = useState(null); const { data, status } = useFetcher( (callApmApi) => { diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/PageViewsTrend/index.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/PageViewsTrend/index.tsx index 94ba5e8431e8c..97be4c3509a05 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/PageViewsTrend/index.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/PageViewsTrend/index.tsx @@ -18,7 +18,7 @@ export function PageViewsTrend() { const { start, end, serviceName } = urlParams; - const [breakdown, setBreakdown] = useState(); + const [breakdown, setBreakdown] = useState(null); const { data, status } = useFetcher( (callApmApi) => { @@ -44,7 +44,7 @@ export function PageViewsTrend() { [end, start, serviceName, uiFilters, breakdown] ); - const onBreakdownChange = (value: BreakdownItem) => { + const onBreakdownChange = (value: BreakdownItem | null) => { setBreakdown(value); }; diff --git a/x-pack/plugins/apm/server/lib/rum_client/__snapshots__/queries.test.ts.snap b/x-pack/plugins/apm/server/lib/rum_client/__snapshots__/queries.test.ts.snap index c5264373ea495..6465c584dd847 100644 --- a/x-pack/plugins/apm/server/lib/rum_client/__snapshots__/queries.test.ts.snap +++ b/x-pack/plugins/apm/server/lib/rum_client/__snapshots__/queries.test.ts.snap @@ -138,7 +138,7 @@ Object { "body": Object { "aggs": Object { "pageViews": Object { - "aggs": Object {}, + "aggs": undefined, "auto_date_histogram": Object { "buckets": 50, "field": "@timestamp", diff --git a/x-pack/plugins/apm/server/lib/rum_client/get_page_view_trends.ts b/x-pack/plugins/apm/server/lib/rum_client/get_page_view_trends.ts index fe82212fafcec..a00c78e12ad6b 100644 --- a/x-pack/plugins/apm/server/lib/rum_client/get_page_view_trends.ts +++ b/x-pack/plugins/apm/server/lib/rum_client/get_page_view_trends.ts @@ -11,7 +11,6 @@ import { SetupTimeRange, SetupUIFilters, } from '../helpers/setup_request'; -import { AggregationInputMap } from '../../../typings/elasticsearch/aggregations'; import { BreakdownItem } from '../../../typings/ui_filters'; export async function getPageViewTrends({ @@ -24,7 +23,10 @@ export async function getPageViewTrends({ const projection = getRumOverviewProjection({ setup, }); - const breakdownItem: BreakdownItem = JSON.parse(breakdowns ?? null); + let breakdownItem: BreakdownItem = null; + if (breakdowns) { + breakdownItem = JSON.parse(breakdowns); + } const params = mergeProjection(projection, { body: { diff --git a/x-pack/plugins/apm/typings/ui_filters.ts b/x-pack/plugins/apm/typings/ui_filters.ts index 2a727dda7241d..efba6919778bb 100644 --- a/x-pack/plugins/apm/typings/ui_filters.ts +++ b/x-pack/plugins/apm/typings/ui_filters.ts @@ -14,7 +14,6 @@ export type UIFilters = { export interface BreakdownItem { name: string; - count: number; type: string; fieldName: string; selected?: boolean; From ca56c72d22c835a331c654d97925a46bfd8b22ed Mon Sep 17 00:00:00 2001 From: Shahzad Date: Wed, 26 Aug 2020 14:46:35 +0200 Subject: [PATCH 3/5] WIP --- .../plugins/apm/server/lib/rum_client/get_page_view_trends.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/apm/server/lib/rum_client/get_page_view_trends.ts b/x-pack/plugins/apm/server/lib/rum_client/get_page_view_trends.ts index a00c78e12ad6b..75fab00d9be40 100644 --- a/x-pack/plugins/apm/server/lib/rum_client/get_page_view_trends.ts +++ b/x-pack/plugins/apm/server/lib/rum_client/get_page_view_trends.ts @@ -23,7 +23,7 @@ export async function getPageViewTrends({ const projection = getRumOverviewProjection({ setup, }); - let breakdownItem: BreakdownItem = null; + let breakdownItem: BreakdownItem | null = null; if (breakdowns) { breakdownItem = JSON.parse(breakdowns); } From 92482a5946017d385a57a4e32adb7edf3e76a712 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Wed, 26 Aug 2020 16:40:28 +0200 Subject: [PATCH 4/5] fix type --- .../plugins/apm/server/lib/rum_client/get_page_view_trends.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/apm/server/lib/rum_client/get_page_view_trends.ts b/x-pack/plugins/apm/server/lib/rum_client/get_page_view_trends.ts index 75fab00d9be40..114137e9fad17 100644 --- a/x-pack/plugins/apm/server/lib/rum_client/get_page_view_trends.ts +++ b/x-pack/plugins/apm/server/lib/rum_client/get_page_view_trends.ts @@ -73,7 +73,7 @@ export async function getPageViewTrends({ categoryBuckets.forEach( ({ key, doc_count: docCount }: { key: string; doc_count: number }) => { if (key === 'Other') { - res[key + `(${breakdownItem.name})`] = docCount; + res[key + `(${breakdownItem?.name})`] = docCount; } else { res[key] = docCount; } From ac5f84cb73d1b05b357c78317c893ee3f5324920 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Tue, 1 Sep 2020 18:21:57 +0200 Subject: [PATCH 5/5] PR feedback --- .../Breakdowns/BreakdownFilter.tsx | 21 ++++++++++++++----- .../app/RumDashboard/PageViewsTrend/index.tsx | 6 +----- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/Breakdowns/BreakdownFilter.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/Breakdowns/BreakdownFilter.tsx index c7c47709b6a6d..12d8efdbd27f3 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/Breakdowns/BreakdownFilter.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/Breakdowns/BreakdownFilter.tsx @@ -6,6 +6,7 @@ import React from 'react'; import { EuiSuperSelect } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; import { CLIENT_GEO_COUNTRY_ISO_CODE, USER_AGENT_DEVICE, @@ -27,27 +28,37 @@ export function BreakdownFilter({ const items: BreakdownItem[] = [ { - name: '- No breakdown -', + name: i18n.translate('xpack.apm.csm.breakDownFilter.noBreakdown', { + defaultMessage: 'No breakdown', + }), fieldName: NO_BREAKDOWN, type: 'category', }, { - name: 'Browser', + name: i18n.translate('xpack.apm.csm.breakdownFilter.browser', { + defaultMessage: 'Browser', + }), fieldName: USER_AGENT_NAME, type: 'category', }, { - name: 'OS', + name: i18n.translate('xpack.apm.csm.breakdownFilter.os', { + defaultMessage: 'OS', + }), fieldName: USER_AGENT_OS, type: 'category', }, { - name: 'Device', + name: i18n.translate('xpack.apm.csm.breakdownFilter.device', { + defaultMessage: 'Device', + }), fieldName: USER_AGENT_DEVICE, type: 'category', }, { - name: 'Location', + name: i18n.translate('xpack.apm.csm.breakdownFilter.location', { + defaultMessage: 'Location', + }), fieldName: CLIENT_GEO_COUNTRY_ISO_CODE, type: 'category', }, diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/PageViewsTrend/index.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/PageViewsTrend/index.tsx index 97be4c3509a05..a67f6dd8e3cb5 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/PageViewsTrend/index.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/PageViewsTrend/index.tsx @@ -44,10 +44,6 @@ export function PageViewsTrend() { [end, start, serviceName, uiFilters, breakdown] ); - const onBreakdownChange = (value: BreakdownItem | null) => { - setBreakdown(value); - }; - return (
@@ -59,7 +55,7 @@ export function PageViewsTrend() {