mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
* observability - exploratory view - limit breakdown to one series * adjust content Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
587f66a604
commit
d4f8b4b42e
4 changed files with 112 additions and 13 deletions
|
@ -6,15 +6,17 @@
|
|||
*/
|
||||
|
||||
import React, { useEffect } from 'react';
|
||||
import { act, renderHook } from '@testing-library/react-hooks';
|
||||
import { Route, Router } from 'react-router-dom';
|
||||
import { render } from '@testing-library/react';
|
||||
import { UrlStorageContextProvider, useSeriesStorage } from './use_series_storage';
|
||||
import { getHistoryFromUrl } from '../rtl_helpers';
|
||||
import type { AppDataType } from '../types';
|
||||
|
||||
const mockSingleSeries = [
|
||||
{
|
||||
name: 'performance-distribution',
|
||||
dataType: 'ux',
|
||||
dataType: 'ux' as AppDataType,
|
||||
breakdown: 'user_agent.name',
|
||||
time: { from: 'now-15m', to: 'now' },
|
||||
},
|
||||
|
@ -23,13 +25,13 @@ const mockSingleSeries = [
|
|||
const mockMultipleSeries = [
|
||||
{
|
||||
name: 'performance-distribution',
|
||||
dataType: 'ux',
|
||||
dataType: 'ux' as AppDataType,
|
||||
breakdown: 'user_agent.name',
|
||||
time: { from: 'now-15m', to: 'now' },
|
||||
},
|
||||
{
|
||||
name: 'kpi-over-time',
|
||||
dataType: 'synthetics',
|
||||
dataType: 'synthetics' as AppDataType,
|
||||
breakdown: 'user_agent.name',
|
||||
time: { from: 'now-15m', to: 'now' },
|
||||
},
|
||||
|
@ -92,7 +94,7 @@ describe('userSeriesStorage', function () {
|
|||
);
|
||||
});
|
||||
|
||||
it('should return expected result when there are multiple series series', function () {
|
||||
it('should return expected result when there are multiple series', function () {
|
||||
const setData = setupTestComponent(mockMultipleSeries);
|
||||
|
||||
expect(setData).toHaveBeenCalledTimes(2);
|
||||
|
@ -133,4 +135,41 @@ describe('userSeriesStorage', function () {
|
|||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('ensures that only one series has a breakdown', () => {
|
||||
function wrapper({ children }: { children: React.ReactElement }) {
|
||||
return (
|
||||
<UrlStorageContextProvider
|
||||
storage={{
|
||||
get: jest
|
||||
.fn()
|
||||
.mockImplementation((key: string) => (key === 'sr' ? mockMultipleSeries : null)),
|
||||
set: jest.fn(),
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</UrlStorageContextProvider>
|
||||
);
|
||||
}
|
||||
const { result } = renderHook(() => useSeriesStorage(), { wrapper });
|
||||
|
||||
act(() => {
|
||||
result.current.setSeries(1, mockMultipleSeries[1]);
|
||||
});
|
||||
|
||||
expect(result.current.allSeries).toEqual([
|
||||
{
|
||||
name: 'performance-distribution',
|
||||
dataType: 'ux',
|
||||
breakdown: 'user_agent.name',
|
||||
time: { from: 'now-15m', to: 'now' },
|
||||
},
|
||||
{
|
||||
name: 'kpi-over-time',
|
||||
dataType: 'synthetics',
|
||||
breakdown: undefined,
|
||||
time: { from: 'now-15m', to: 'now' },
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -71,9 +71,16 @@ export function UrlStorageContextProvider({
|
|||
|
||||
const setSeries = useCallback((seriesIndex: number, newValue: SeriesUrl) => {
|
||||
setAllSeries((prevAllSeries) => {
|
||||
const seriesWithCurrentBreakdown = prevAllSeries.findIndex((series) => series.breakdown);
|
||||
const newStateRest = prevAllSeries.map((series, index) => {
|
||||
if (index === seriesIndex) {
|
||||
return newValue;
|
||||
return {
|
||||
...newValue,
|
||||
breakdown:
|
||||
seriesWithCurrentBreakdown === seriesIndex || seriesWithCurrentBreakdown === -1
|
||||
? newValue.breakdown
|
||||
: undefined,
|
||||
};
|
||||
}
|
||||
return series;
|
||||
});
|
||||
|
|
|
@ -55,4 +55,24 @@ describe('Breakdowns', function () {
|
|||
});
|
||||
expect(setSeries).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should disable breakdowns when a different series has a breakdown', function () {
|
||||
const initSeries = {
|
||||
data: [mockUxSeries, { ...mockUxSeries, breakdown: undefined }],
|
||||
breakdown: USER_AGENT_OS,
|
||||
};
|
||||
|
||||
render(
|
||||
<Breakdowns
|
||||
seriesId={1}
|
||||
seriesConfig={dataViewSeries}
|
||||
series={{ ...mockUxSeries, breakdown: undefined }}
|
||||
/>,
|
||||
{ initSeries }
|
||||
);
|
||||
|
||||
const button = screen.getByText('No breakdown');
|
||||
|
||||
expect(button).toHaveAttribute('disabled');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { EuiSuperSelect } from '@elastic/eui';
|
||||
import styled from 'styled-components';
|
||||
import { EuiSuperSelect, EuiToolTip } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { useSeriesStorage } from '../../hooks/use_series_storage';
|
||||
import { LABEL_FIELDS_BREAKDOWN, USE_BREAK_DOWN_COLUMN } from '../../configurations/constants';
|
||||
|
@ -19,7 +20,14 @@ interface Props {
|
|||
}
|
||||
|
||||
export function Breakdowns({ seriesConfig, seriesId, series }: Props) {
|
||||
const { setSeries } = useSeriesStorage();
|
||||
const { setSeries, allSeries } = useSeriesStorage();
|
||||
|
||||
const indexOfSeriesWithBreakdown = allSeries.findIndex((seriesT) => {
|
||||
return Boolean(seriesT.breakdown);
|
||||
});
|
||||
const currentSeriesHasBreakdown = indexOfSeriesWithBreakdown === seriesId;
|
||||
const anySeriesHasBreakdown = indexOfSeriesWithBreakdown !== -1;
|
||||
const differentSeriesHasBreakdown = anySeriesHasBreakdown && !currentSeriesHasBreakdown;
|
||||
|
||||
const selectedBreakdown = series.breakdown;
|
||||
const NO_BREAKDOWN = 'no_breakdown';
|
||||
|
@ -69,13 +77,28 @@ export function Breakdowns({ seriesConfig, seriesId, series }: Props) {
|
|||
valueOfSelected = LABEL_FIELDS_BREAKDOWN;
|
||||
}
|
||||
|
||||
function Select() {
|
||||
return (
|
||||
<EuiSuperSelect
|
||||
options={options}
|
||||
valueOfSelected={valueOfSelected}
|
||||
onChange={(value) => onOptionChange(value)}
|
||||
data-test-subj={'seriesBreakdown'}
|
||||
disabled={differentSeriesHasBreakdown}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<EuiSuperSelect
|
||||
options={options}
|
||||
valueOfSelected={valueOfSelected}
|
||||
onChange={(value) => onOptionChange(value)}
|
||||
data-test-subj={'seriesBreakdown'}
|
||||
/>
|
||||
<Wrapper>
|
||||
{differentSeriesHasBreakdown ? (
|
||||
<EuiToolTip content={BREAKDOWN_WARNING} position="top">
|
||||
<Select />
|
||||
</EuiToolTip>
|
||||
) : (
|
||||
<Select />
|
||||
)}
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -85,3 +108,13 @@ export const NO_BREAK_DOWN_LABEL = i18n.translate(
|
|||
defaultMessage: 'No breakdown',
|
||||
}
|
||||
);
|
||||
|
||||
export const BREAKDOWN_WARNING = i18n.translate('xpack.observability.exp.breakDownFilter.warning', {
|
||||
defaultMessage: 'Breakdowns can be applied to only one series at a time.',
|
||||
});
|
||||
|
||||
const Wrapper = styled.span`
|
||||
.euiToolTipAnchor {
|
||||
width: 100%;
|
||||
}
|
||||
`;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue