[Exploratory View] Refactor series storage (#100571)
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
45ae6cc39b
commit
f367deca48
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
import rison, { RisonValue } from 'rison-node';
|
||||
import type { AllSeries, AllShortSeries } from '../hooks/use_url_storage';
|
||||
import type { AllSeries, AllShortSeries } from '../hooks/use_series_storage';
|
||||
import type { SeriesUrl } from '../types';
|
||||
import { IIndexPattern } from '../../../../../../../../src/plugins/data/common/index_patterns';
|
||||
import { esFilters } from '../../../../../../../../src/plugins/data/public';
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import React from 'react';
|
||||
import { screen, waitFor } from '@testing-library/dom';
|
||||
import { render, mockUrlStorage, mockCore, mockAppIndexPattern } from './rtl_helpers';
|
||||
import { render, mockCore, mockAppIndexPattern } from './rtl_helpers';
|
||||
import { ExploratoryView } from './exploratory_view';
|
||||
import { getStubIndexPattern } from '../../../../../../../src/plugins/data/public/test_utils';
|
||||
import * as obsvInd from './utils/observability_index_patterns';
|
||||
|
@ -41,26 +41,26 @@ describe('ExploratoryView', () => {
|
|||
it('renders exploratory view', async () => {
|
||||
render(<ExploratoryView />);
|
||||
|
||||
await waitFor(() => {
|
||||
screen.getByText(/open in lens/i);
|
||||
screen.getByRole('heading', { name: /analyze data/i });
|
||||
});
|
||||
expect(await screen.findByText(/open in lens/i)).toBeInTheDocument();
|
||||
expect(
|
||||
await screen.findByRole('heading', { name: /Performance Distribution/i })
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders lens component when there is series', async () => {
|
||||
mockUrlStorage({
|
||||
const initSeries = {
|
||||
data: {
|
||||
'ux-series': {
|
||||
dataType: 'ux',
|
||||
reportType: 'pld',
|
||||
breakdown: 'user_agent.name',
|
||||
dataType: 'ux' as const,
|
||||
reportType: 'pld' as const,
|
||||
breakdown: 'user_agent .name',
|
||||
reportDefinitions: { 'service.name': ['elastic-co'] },
|
||||
time: { from: 'now-15m', to: 'now' },
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
render(<ExploratoryView />);
|
||||
render(<ExploratoryView />, { initSeries });
|
||||
|
||||
expect(await screen.findByText(/open in lens/i)).toBeInTheDocument();
|
||||
expect(await screen.findByText('Performance Distribution')).toBeInTheDocument();
|
||||
|
|
|
@ -11,7 +11,7 @@ import styled from 'styled-components';
|
|||
import { useKibana } from '../../../../../../../src/plugins/kibana_react/public';
|
||||
import { ObservabilityPublicPluginsStart } from '../../../plugin';
|
||||
import { ExploratoryViewHeader } from './header/header';
|
||||
import { useUrlStorage } from './hooks/use_url_storage';
|
||||
import { useSeriesStorage } from './hooks/use_series_storage';
|
||||
import { useLensAttributes } from './hooks/use_lens_attributes';
|
||||
import { EmptyView } from './components/empty_view';
|
||||
import { TypedLensByValueInput } from '../../../../../lens/public';
|
||||
|
@ -19,7 +19,11 @@ import { useAppIndexPatternContext } from './hooks/use_app_index_pattern';
|
|||
import { ReportToDataTypeMap } from './configurations/constants';
|
||||
import { SeriesBuilder } from './series_builder/series_builder';
|
||||
|
||||
export function ExploratoryView() {
|
||||
export function ExploratoryView({
|
||||
saveAttributes,
|
||||
}: {
|
||||
saveAttributes?: (attr: TypedLensByValueInput['attributes'] | null) => void;
|
||||
}) {
|
||||
const {
|
||||
services: { lens, notifications },
|
||||
} = useKibana<ObservabilityPublicPluginsStart>();
|
||||
|
@ -28,6 +32,7 @@ export function ExploratoryView() {
|
|||
const wrapperRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const [height, setHeight] = useState<string>('100vh');
|
||||
const [seriesId, setSeriesId] = useState<string>('');
|
||||
|
||||
const [lensAttributes, setLensAttributes] = useState<TypedLensByValueInput['attributes'] | null>(
|
||||
null
|
||||
|
@ -37,7 +42,11 @@ export function ExploratoryView() {
|
|||
|
||||
const LensComponent = lens?.EmbeddableComponent;
|
||||
|
||||
const { firstSeriesId: seriesId, firstSeries: series, setSeries } = useUrlStorage();
|
||||
const { firstSeriesId, firstSeries: series, setSeries, allSeries } = useSeriesStorage();
|
||||
|
||||
useEffect(() => {
|
||||
setSeriesId(firstSeriesId);
|
||||
}, [allSeries, firstSeriesId]);
|
||||
|
||||
const lensAttributesT = useLensAttributes({
|
||||
seriesId,
|
||||
|
@ -59,6 +68,10 @@ export function ExploratoryView() {
|
|||
|
||||
useEffect(() => {
|
||||
setLensAttributes(lensAttributesT);
|
||||
if (saveAttributes) {
|
||||
saveAttributes(lensAttributesT);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [JSON.stringify(lensAttributesT ?? {}), series?.reportType, series?.time?.from]);
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { mockUrlStorage, render } from '../rtl_helpers';
|
||||
import { render } from '../rtl_helpers';
|
||||
import { ExploratoryViewHeader } from './header';
|
||||
import { fireEvent } from '@testing-library/dom';
|
||||
|
||||
|
@ -22,22 +22,23 @@ describe('ExploratoryViewHeader', function () {
|
|||
});
|
||||
|
||||
it('should be able to click open in lens', function () {
|
||||
mockUrlStorage({
|
||||
const initSeries = {
|
||||
data: {
|
||||
'uptime-pings-histogram': {
|
||||
dataType: 'synthetics',
|
||||
reportType: 'upp',
|
||||
dataType: 'synthetics' as const,
|
||||
reportType: 'upp' as const,
|
||||
breakdown: 'monitor.status',
|
||||
time: { from: 'now-15m', to: 'now' },
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const { getByText, core } = render(
|
||||
<ExploratoryViewHeader
|
||||
seriesId={'dummy-series'}
|
||||
lensAttributes={{ title: 'Performance distribution' } as any}
|
||||
/>
|
||||
/>,
|
||||
{ initSeries }
|
||||
);
|
||||
fireEvent.click(getByText('Open in Lens'));
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ import { TypedLensByValueInput } from '../../../../../../lens/public';
|
|||
import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public';
|
||||
import { ObservabilityPublicPluginsStart } from '../../../../plugin';
|
||||
import { DataViewLabels } from '../configurations/constants';
|
||||
import { useUrlStorage } from '../hooks/use_url_storage';
|
||||
import { useSeriesStorage } from '../hooks/use_series_storage';
|
||||
|
||||
interface Props {
|
||||
seriesId: string;
|
||||
|
@ -24,7 +24,9 @@ export function ExploratoryViewHeader({ seriesId, lensAttributes }: Props) {
|
|||
services: { lens },
|
||||
} = useKibana<ObservabilityPublicPluginsStart>();
|
||||
|
||||
const { series } = useUrlStorage(seriesId);
|
||||
const { getSeries } = useSeriesStorage();
|
||||
|
||||
const series = getSeries(seriesId);
|
||||
|
||||
return (
|
||||
<EuiFlexGroup justifyContent="spaceBetween" alignItems="center">
|
||||
|
|
|
@ -9,7 +9,7 @@ import { useMemo } from 'react';
|
|||
import { isEmpty } from 'lodash';
|
||||
import { TypedLensByValueInput } from '../../../../../../lens/public';
|
||||
import { LensAttributes } from '../configurations/lens_attributes';
|
||||
import { useUrlStorage } from './use_url_storage';
|
||||
import { useSeriesStorage } from './use_series_storage';
|
||||
import { getDefaultConfigs } from '../configurations/default_configs';
|
||||
|
||||
import { DataSeries, SeriesUrl, UrlFilter } from '../types';
|
||||
|
@ -40,8 +40,8 @@ export const getFiltersFromDefs = (
|
|||
export const useLensAttributes = ({
|
||||
seriesId,
|
||||
}: Props): TypedLensByValueInput['attributes'] | null => {
|
||||
const { series } = useUrlStorage(seriesId);
|
||||
|
||||
const { getSeries } = useSeriesStorage();
|
||||
const series = getSeries(seriesId);
|
||||
const { breakdown, seriesType, operationType, reportType, reportDefinitions = {} } = series ?? {};
|
||||
|
||||
const { indexPattern } = useAppIndexPatternContext();
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { useUrlStorage } from './use_url_storage';
|
||||
import { useSeriesStorage } from './use_series_storage';
|
||||
import { UrlFilter } from '../types';
|
||||
|
||||
export interface UpdateFilter {
|
||||
|
@ -15,7 +15,9 @@ export interface UpdateFilter {
|
|||
}
|
||||
|
||||
export const useSeriesFilters = ({ seriesId }: { seriesId: string }) => {
|
||||
const { series, setSeries } = useUrlStorage(seriesId);
|
||||
const { getSeries, setSeries } = useSeriesStorage();
|
||||
|
||||
const series = getSeries(seriesId);
|
||||
|
||||
const filters = series.filters ?? [];
|
||||
|
||||
|
|
|
@ -5,8 +5,11 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { createContext, useContext, Context } from 'react';
|
||||
import { IKbnUrlStateStorage } from '../../../../../../../../src/plugins/kibana_utils/public';
|
||||
import React, { createContext, useContext, useState, useEffect, useCallback } from 'react';
|
||||
import {
|
||||
IKbnUrlStateStorage,
|
||||
ISessionStorageStateStorage,
|
||||
} from '../../../../../../../../src/plugins/kibana_utils/public';
|
||||
import type {
|
||||
AppDataType,
|
||||
ReportViewTypeId,
|
||||
|
@ -18,17 +21,81 @@ import { convertToShortUrl } from '../configurations/utils';
|
|||
import { OperationType, SeriesType } from '../../../../../../lens/public';
|
||||
import { URL_KEYS } from '../configurations/constants/url_constants';
|
||||
|
||||
export const UrlStorageContext = createContext<IKbnUrlStateStorage | null>(null);
|
||||
export interface SeriesContextValue {
|
||||
firstSeries: SeriesUrl;
|
||||
firstSeriesId: string;
|
||||
allSeriesIds: string[];
|
||||
allSeries: AllSeries;
|
||||
setSeries: (seriesIdN: string, newValue: SeriesUrl) => void;
|
||||
getSeries: (seriesId: string) => SeriesUrl;
|
||||
removeSeries: (seriesId: string) => void;
|
||||
}
|
||||
export const UrlStorageContext = createContext<SeriesContextValue>({} as SeriesContextValue);
|
||||
|
||||
interface ProviderProps {
|
||||
storage: IKbnUrlStateStorage;
|
||||
storage: IKbnUrlStateStorage | ISessionStorageStateStorage;
|
||||
}
|
||||
|
||||
export function UrlStorageContextProvider({
|
||||
children,
|
||||
storage,
|
||||
}: ProviderProps & { children: JSX.Element }) {
|
||||
return <UrlStorageContext.Provider value={storage}>{children}</UrlStorageContext.Provider>;
|
||||
const allSeriesKey = 'sr';
|
||||
|
||||
const [allShortSeries, setAllShortSeries] = useState<AllShortSeries>(
|
||||
() => storage.get(allSeriesKey) ?? {}
|
||||
);
|
||||
const [allSeries, setAllSeries] = useState<AllSeries>({});
|
||||
const [firstSeriesId, setFirstSeriesId] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
const allSeriesIds = Object.keys(allShortSeries);
|
||||
const allSeriesN: AllSeries = {};
|
||||
allSeriesIds.forEach((seriesKey) => {
|
||||
allSeriesN[seriesKey] = convertFromShortUrl(allShortSeries[seriesKey]);
|
||||
});
|
||||
|
||||
setAllSeries(allSeriesN);
|
||||
setFirstSeriesId(allSeriesIds?.[0]);
|
||||
(storage as IKbnUrlStateStorage).set(allSeriesKey, allShortSeries);
|
||||
}, [allShortSeries, storage]);
|
||||
|
||||
const setSeries = (seriesIdN: string, newValue: SeriesUrl) => {
|
||||
setAllShortSeries((prevState) => {
|
||||
prevState[seriesIdN] = convertToShortUrl(newValue);
|
||||
return { ...prevState };
|
||||
});
|
||||
};
|
||||
|
||||
const removeSeries = (seriesIdN: string) => {
|
||||
delete allShortSeries[seriesIdN];
|
||||
delete allSeries[seriesIdN];
|
||||
};
|
||||
|
||||
const allSeriesIds = Object.keys(allShortSeries);
|
||||
|
||||
const getSeries = useCallback(
|
||||
(seriesId?: string) => {
|
||||
return seriesId ? allSeries?.[seriesId] ?? {} : ({} as SeriesUrl);
|
||||
},
|
||||
[allSeries]
|
||||
);
|
||||
|
||||
const value = {
|
||||
storage,
|
||||
getSeries,
|
||||
setSeries,
|
||||
removeSeries,
|
||||
firstSeriesId,
|
||||
allSeries,
|
||||
allSeriesIds,
|
||||
firstSeries: allSeries?.[firstSeriesId],
|
||||
};
|
||||
return <UrlStorageContext.Provider value={value}>{children}</UrlStorageContext.Provider>;
|
||||
}
|
||||
|
||||
export function useSeriesStorage() {
|
||||
return useContext(UrlStorageContext);
|
||||
}
|
||||
|
||||
function convertFromShortUrl(newValue: ShortUrlSeries): SeriesUrl {
|
||||
|
@ -64,47 +131,3 @@ export type AllShortSeries = Record<string, ShortUrlSeries>;
|
|||
export type AllSeries = Record<string, SeriesUrl>;
|
||||
|
||||
export const NEW_SERIES_KEY = 'new-series-key';
|
||||
|
||||
export function useUrlStorage(seriesId?: string) {
|
||||
const allSeriesKey = 'sr';
|
||||
const storage = useContext((UrlStorageContext as unknown) as Context<IKbnUrlStateStorage>);
|
||||
let series: SeriesUrl = {} as SeriesUrl;
|
||||
const allShortSeries = storage.get<AllShortSeries>(allSeriesKey) ?? {};
|
||||
|
||||
const allSeriesIds = Object.keys(allShortSeries);
|
||||
|
||||
const allSeries: AllSeries = {};
|
||||
|
||||
allSeriesIds.forEach((seriesKey) => {
|
||||
allSeries[seriesKey] = convertFromShortUrl(allShortSeries[seriesKey]);
|
||||
});
|
||||
|
||||
if (seriesId) {
|
||||
series = allSeries?.[seriesId] ?? ({} as SeriesUrl);
|
||||
}
|
||||
|
||||
const setSeries = async (seriesIdN: string, newValue: SeriesUrl) => {
|
||||
allShortSeries[seriesIdN] = convertToShortUrl(newValue);
|
||||
allSeries[seriesIdN] = newValue;
|
||||
return storage.set(allSeriesKey, allShortSeries);
|
||||
};
|
||||
|
||||
const removeSeries = (seriesIdN: string) => {
|
||||
delete allShortSeries[seriesIdN];
|
||||
delete allSeries[seriesIdN];
|
||||
storage.set(allSeriesKey, allShortSeries);
|
||||
};
|
||||
|
||||
const firstSeriesId = allSeriesIds?.[0];
|
||||
|
||||
return {
|
||||
storage,
|
||||
setSeries,
|
||||
removeSeries,
|
||||
series,
|
||||
firstSeriesId,
|
||||
allSeries,
|
||||
allSeriesIds,
|
||||
firstSeries: allSeries?.[firstSeriesId],
|
||||
};
|
||||
}
|
|
@ -17,11 +17,19 @@ import { IndexPatternContextProvider } from './hooks/use_app_index_pattern';
|
|||
import {
|
||||
createKbnUrlStateStorage,
|
||||
withNotifyOnErrors,
|
||||
createSessionStorageStateStorage,
|
||||
} from '../../../../../../../src/plugins/kibana_utils/public/';
|
||||
import { UrlStorageContextProvider } from './hooks/use_url_storage';
|
||||
import { UrlStorageContextProvider } from './hooks/use_series_storage';
|
||||
import { useTrackPageview } from '../../..';
|
||||
import { TypedLensByValueInput } from '../../../../../lens/public';
|
||||
|
||||
export function ExploratoryViewPage() {
|
||||
export function ExploratoryViewPage({
|
||||
saveAttributes,
|
||||
useSessionStorage = false,
|
||||
}: {
|
||||
useSessionStorage?: boolean;
|
||||
saveAttributes?: (attr: TypedLensByValueInput['attributes'] | null) => void;
|
||||
}) {
|
||||
useTrackPageview({ app: 'observability-overview', path: 'exploratory-view' });
|
||||
useTrackPageview({ app: 'observability-overview', path: 'exploratory-view', delay: 15000 });
|
||||
|
||||
|
@ -39,17 +47,19 @@ export function ExploratoryViewPage() {
|
|||
|
||||
const history = useHistory();
|
||||
|
||||
const kbnUrlStateStorage = createKbnUrlStateStorage({
|
||||
history,
|
||||
useHash: uiSettings!.get('state:storeInSessionStorage'),
|
||||
...withNotifyOnErrors(notifications!.toasts),
|
||||
});
|
||||
const kbnUrlStateStorage = useSessionStorage
|
||||
? createSessionStorageStateStorage()
|
||||
: createKbnUrlStateStorage({
|
||||
history,
|
||||
useHash: uiSettings!.get('state:storeInSessionStorage'),
|
||||
...withNotifyOnErrors(notifications!.toasts),
|
||||
});
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<IndexPatternContextProvider>
|
||||
<UrlStorageContextProvider storage={kbnUrlStateStorage}>
|
||||
<ExploratoryView />
|
||||
<ExploratoryView saveAttributes={saveAttributes} />
|
||||
</UrlStorageContextProvider>
|
||||
</IndexPatternContextProvider>
|
||||
</Wrapper>
|
||||
|
|
|
@ -16,29 +16,23 @@ import { CoreStart } from 'kibana/public';
|
|||
import { I18nProvider } from '@kbn/i18n/react';
|
||||
import { coreMock } from 'src/core/public/mocks';
|
||||
import {
|
||||
KibanaServices,
|
||||
KibanaContextProvider,
|
||||
KibanaServices,
|
||||
} from '../../../../../../../src/plugins/kibana_react/public';
|
||||
import { ObservabilityPublicPluginsStart } from '../../../plugin';
|
||||
import { EuiThemeProvider } from '../../../../../../../src/plugins/kibana_react/common';
|
||||
import { lensPluginMock } from '../../../../../lens/public/mocks';
|
||||
import * as useAppIndexPatternHook from './hooks/use_app_index_pattern';
|
||||
import { IndexPatternContextProvider } from './hooks/use_app_index_pattern';
|
||||
import { AllSeries, UrlStorageContextProvider } from './hooks/use_url_storage';
|
||||
import {
|
||||
withNotifyOnErrors,
|
||||
createKbnUrlStateStorage,
|
||||
} from '../../../../../../../src/plugins/kibana_utils/public';
|
||||
import { AllSeries, UrlStorageContext } from './hooks/use_series_storage';
|
||||
|
||||
import * as fetcherHook from '../../../hooks/use_fetcher';
|
||||
import * as useUrlHook from './hooks/use_url_storage';
|
||||
import * as useSeriesFilterHook from './hooks/use_series_filters';
|
||||
import * as useHasDataHook from '../../../hooks/use_has_data';
|
||||
import * as useValuesListHook from '../../../hooks/use_values_list';
|
||||
import * as useAppIndexPatternHook from './hooks/use_app_index_pattern';
|
||||
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { getStubIndexPattern } from '../../../../../../../src/plugins/data/public/index_patterns/index_pattern.stub';
|
||||
import indexPatternData from './configurations/test_data/test_index_pattern.json';
|
||||
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { setIndexPatterns } from '../../../../../../../src/plugins/data/public/services';
|
||||
import { IndexPatternsContract } from '../../../../../../../src/plugins/data/common/index_patterns/index_patterns';
|
||||
|
@ -73,6 +67,11 @@ interface RenderRouterOptions<ExtraCore> extends KibanaProviderOptions<ExtraCore
|
|||
history?: History;
|
||||
renderOptions?: Omit<RenderOptions, 'queries'>;
|
||||
url?: Url;
|
||||
initSeries?: {
|
||||
data?: AllSeries;
|
||||
filters?: UrlFilter[];
|
||||
breakdown?: string;
|
||||
};
|
||||
}
|
||||
|
||||
function getSetting<T = any>(key: string): T {
|
||||
|
@ -127,17 +126,8 @@ export const mockCore: () => Partial<CoreStart & ObservabilityPublicPluginsStart
|
|||
export function MockKibanaProvider<ExtraCore extends Partial<CoreStart>>({
|
||||
children,
|
||||
core,
|
||||
history,
|
||||
kibanaProps,
|
||||
}: MockKibanaProviderProps<ExtraCore>) {
|
||||
const { notifications } = core!;
|
||||
|
||||
const kbnUrlStateStorage = createKbnUrlStateStorage({
|
||||
history,
|
||||
useHash: false,
|
||||
...withNotifyOnErrors(notifications!.toasts),
|
||||
});
|
||||
|
||||
const indexPattern = mockIndexPattern;
|
||||
|
||||
setIndexPatterns(({
|
||||
|
@ -149,11 +139,7 @@ export function MockKibanaProvider<ExtraCore extends Partial<CoreStart>>({
|
|||
<KibanaContextProvider services={{ ...core }} {...kibanaProps}>
|
||||
<EuiThemeProvider darkMode={false}>
|
||||
<I18nProvider>
|
||||
<IndexPatternContextProvider>
|
||||
<UrlStorageContextProvider storage={kbnUrlStateStorage}>
|
||||
{children}
|
||||
</UrlStorageContextProvider>
|
||||
</IndexPatternContextProvider>
|
||||
<IndexPatternContextProvider>{children}</IndexPatternContextProvider>
|
||||
</I18nProvider>
|
||||
</EuiThemeProvider>
|
||||
</KibanaContextProvider>
|
||||
|
@ -184,6 +170,7 @@ export function render<ExtraCore>(
|
|||
kibanaProps,
|
||||
renderOptions,
|
||||
url,
|
||||
initSeries = {},
|
||||
}: RenderRouterOptions<ExtraCore> = {}
|
||||
) {
|
||||
if (url) {
|
||||
|
@ -195,15 +182,20 @@ export function render<ExtraCore>(
|
|||
...customCore,
|
||||
};
|
||||
|
||||
const seriesContextValue = mockSeriesStorageContext(initSeries);
|
||||
|
||||
return {
|
||||
...reactTestLibRender(
|
||||
<MockRouter history={history} kibanaProps={kibanaProps} core={core}>
|
||||
{ui}
|
||||
<UrlStorageContext.Provider value={{ ...seriesContextValue }}>
|
||||
{ui}
|
||||
</UrlStorageContext.Provider>
|
||||
</MockRouter>,
|
||||
renderOptions
|
||||
),
|
||||
history,
|
||||
core,
|
||||
...seriesContextValue,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -256,7 +248,7 @@ export const mockUseValuesList = (values?: string[]) => {
|
|||
return { spy, onRefreshTimeRange };
|
||||
};
|
||||
|
||||
export const mockUrlStorage = ({
|
||||
function mockSeriesStorageContext({
|
||||
data,
|
||||
filters,
|
||||
breakdown,
|
||||
|
@ -264,7 +256,7 @@ export const mockUrlStorage = ({
|
|||
data?: AllSeries;
|
||||
filters?: UrlFilter[];
|
||||
breakdown?: string;
|
||||
}) => {
|
||||
}) {
|
||||
const mockDataSeries = data || {
|
||||
'performance-distribution': {
|
||||
reportType: 'pld',
|
||||
|
@ -282,18 +274,18 @@ export const mockUrlStorage = ({
|
|||
const removeSeries = jest.fn();
|
||||
const setSeries = jest.fn();
|
||||
|
||||
const spy = jest.spyOn(useUrlHook, 'useUrlStorage').mockReturnValue({
|
||||
const getSeries = jest.fn().mockReturnValue(series);
|
||||
|
||||
return {
|
||||
firstSeriesId,
|
||||
allSeriesIds,
|
||||
removeSeries,
|
||||
setSeries,
|
||||
series,
|
||||
getSeries,
|
||||
firstSeries: mockDataSeries[firstSeriesId],
|
||||
allSeries: mockDataSeries,
|
||||
} as any);
|
||||
|
||||
return { spy, removeSeries, setSeries };
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export function mockUseSeriesFilter() {
|
||||
const removeFilter = jest.fn();
|
||||
|
|
|
@ -7,13 +7,11 @@
|
|||
|
||||
import React from 'react';
|
||||
import { fireEvent, screen, waitFor } from '@testing-library/react';
|
||||
import { mockUrlStorage, render } from '../../rtl_helpers';
|
||||
import { render } from '../../rtl_helpers';
|
||||
import { SeriesChartTypesSelect, XYChartTypesSelect } from './chart_types';
|
||||
|
||||
describe.skip('SeriesChartTypesSelect', function () {
|
||||
it('should render properly', async function () {
|
||||
mockUrlStorage({});
|
||||
|
||||
render(<SeriesChartTypesSelect seriesId={'series-id'} defaultChartType={'line'} />);
|
||||
|
||||
await waitFor(() => {
|
||||
|
@ -22,9 +20,9 @@ describe.skip('SeriesChartTypesSelect', function () {
|
|||
});
|
||||
|
||||
it('should call set series on change', async function () {
|
||||
const { setSeries } = mockUrlStorage({});
|
||||
|
||||
render(<SeriesChartTypesSelect seriesId={'series-id'} defaultChartType={'line'} />);
|
||||
const { setSeries } = render(
|
||||
<SeriesChartTypesSelect seriesId={'series-id'} defaultChartType={'line'} />
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
screen.getByText(/chart type/i);
|
||||
|
@ -44,8 +42,6 @@ describe.skip('SeriesChartTypesSelect', function () {
|
|||
|
||||
describe('XYChartTypesSelect', function () {
|
||||
it('should render properly', async function () {
|
||||
mockUrlStorage({});
|
||||
|
||||
render(<XYChartTypesSelect value={'line'} onChange={jest.fn()} label={'Chart type'} />);
|
||||
|
||||
await waitFor(() => {
|
||||
|
|
|
@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import { useKibana } from '../../../../../../../../../src/plugins/kibana_react/public';
|
||||
import { ObservabilityPublicPluginsStart } from '../../../../../plugin';
|
||||
import { useFetcher } from '../../../../..';
|
||||
import { useUrlStorage } from '../../hooks/use_url_storage';
|
||||
import { useSeriesStorage } from '../../hooks/use_series_storage';
|
||||
import { SeriesType } from '../../../../../../../lens/public';
|
||||
|
||||
const CHART_TYPE_LABEL = i18n.translate('xpack.observability.expView.chartTypes.label', {
|
||||
|
@ -27,7 +27,9 @@ export function SeriesChartTypesSelect({
|
|||
seriesTypes?: SeriesType[];
|
||||
defaultChartType: SeriesType;
|
||||
}) {
|
||||
const { series, setSeries, allSeries } = useUrlStorage(seriesId);
|
||||
const { getSeries, setSeries, allSeries } = useSeriesStorage();
|
||||
|
||||
const series = getSeries(seriesId);
|
||||
|
||||
const seriesType = series?.seriesType ?? defaultChartType;
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import React from 'react';
|
||||
import { fireEvent, screen } from '@testing-library/react';
|
||||
import { mockAppIndexPattern, mockUrlStorage, render } from '../../rtl_helpers';
|
||||
import { mockAppIndexPattern, render } from '../../rtl_helpers';
|
||||
import { dataTypes, DataTypesCol } from './data_types_col';
|
||||
|
||||
describe('DataTypesCol', function () {
|
||||
|
@ -24,9 +24,7 @@ describe('DataTypesCol', function () {
|
|||
});
|
||||
|
||||
it('should set series on change', function () {
|
||||
const { setSeries } = mockUrlStorage({});
|
||||
|
||||
render(<DataTypesCol seriesId={seriesId} />);
|
||||
const { setSeries } = render(<DataTypesCol seriesId={seriesId} />);
|
||||
|
||||
fireEvent.click(screen.getByText(/user experience \(rum\)/i));
|
||||
|
||||
|
@ -35,18 +33,18 @@ describe('DataTypesCol', function () {
|
|||
});
|
||||
|
||||
it('should set series on change on already selected', function () {
|
||||
mockUrlStorage({
|
||||
const initSeries = {
|
||||
data: {
|
||||
[seriesId]: {
|
||||
dataType: 'synthetics',
|
||||
reportType: 'upp',
|
||||
dataType: 'synthetics' as const,
|
||||
reportType: 'upp' as const,
|
||||
breakdown: 'monitor.status',
|
||||
time: { from: 'now-15m', to: 'now' },
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
render(<DataTypesCol seriesId={seriesId} />);
|
||||
render(<DataTypesCol seriesId={seriesId} />, { initSeries });
|
||||
|
||||
const button = screen.getByRole('button', {
|
||||
name: /Synthetic Monitoring/i,
|
||||
|
|
|
@ -10,7 +10,7 @@ import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
|||
import styled from 'styled-components';
|
||||
import { AppDataType } from '../../types';
|
||||
import { useAppIndexPatternContext } from '../../hooks/use_app_index_pattern';
|
||||
import { useUrlStorage } from '../../hooks/use_url_storage';
|
||||
import { useSeriesStorage } from '../../hooks/use_series_storage';
|
||||
import { ReportToDataTypeMap } from '../../configurations/constants';
|
||||
|
||||
export const dataTypes: Array<{ id: AppDataType; label: string }> = [
|
||||
|
@ -22,8 +22,9 @@ export const dataTypes: Array<{ id: AppDataType; label: string }> = [
|
|||
];
|
||||
|
||||
export function DataTypesCol({ seriesId }: { seriesId: string }) {
|
||||
const { series, setSeries, removeSeries } = useUrlStorage(seriesId);
|
||||
const { getSeries, setSeries, removeSeries } = useSeriesStorage();
|
||||
|
||||
const series = getSeries(seriesId);
|
||||
const { loading } = useAppIndexPatternContext();
|
||||
|
||||
const onDataTypeChange = (dataType?: AppDataType) => {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import React from 'react';
|
||||
import { fireEvent, screen } from '@testing-library/react';
|
||||
import { mockUrlStorage, render } from '../../rtl_helpers';
|
||||
import { render } from '../../rtl_helpers';
|
||||
import { OperationTypeSelect } from './operation_type_select';
|
||||
|
||||
describe('OperationTypeSelect', function () {
|
||||
|
@ -18,35 +18,35 @@ describe('OperationTypeSelect', function () {
|
|||
});
|
||||
|
||||
it('should display selected value', function () {
|
||||
mockUrlStorage({
|
||||
const initSeries = {
|
||||
data: {
|
||||
'performance-distribution': {
|
||||
dataType: 'ux',
|
||||
reportType: 'kpi',
|
||||
operationType: 'median',
|
||||
dataType: 'ux' as const,
|
||||
reportType: 'kpi' as const,
|
||||
operationType: 'median' as const,
|
||||
time: { from: 'now-15m', to: 'now' },
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
render(<OperationTypeSelect seriesId={'series-id'} />);
|
||||
render(<OperationTypeSelect seriesId={'series-id'} />, { initSeries });
|
||||
|
||||
screen.getByText('Median');
|
||||
});
|
||||
|
||||
it('should call set series on change', function () {
|
||||
const { setSeries } = mockUrlStorage({
|
||||
const initSeries = {
|
||||
data: {
|
||||
'series-id': {
|
||||
dataType: 'ux',
|
||||
reportType: 'kpi',
|
||||
operationType: 'median',
|
||||
dataType: 'ux' as const,
|
||||
reportType: 'kpi' as const,
|
||||
operationType: 'median' as const,
|
||||
time: { from: 'now-15m', to: 'now' },
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
render(<OperationTypeSelect seriesId={'series-id'} />);
|
||||
const { setSeries } = render(<OperationTypeSelect seriesId={'series-id'} />, { initSeries });
|
||||
|
||||
fireEvent.click(screen.getByTestId('operationTypeSelect'));
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import React, { useEffect } from 'react';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiSuperSelect } from '@elastic/eui';
|
||||
|
||||
import { useUrlStorage } from '../../hooks/use_url_storage';
|
||||
import { useSeriesStorage } from '../../hooks/use_series_storage';
|
||||
import { OperationType } from '../../../../../../../lens/public';
|
||||
|
||||
export function OperationTypeSelect({
|
||||
|
@ -19,7 +19,9 @@ export function OperationTypeSelect({
|
|||
seriesId: string;
|
||||
defaultOperationType?: OperationType;
|
||||
}) {
|
||||
const { series, setSeries } = useUrlStorage(seriesId);
|
||||
const { getSeries, setSeries } = useSeriesStorage();
|
||||
|
||||
const series = getSeries(seriesId);
|
||||
|
||||
const operationType = series?.operationType;
|
||||
|
||||
|
|
|
@ -7,9 +7,8 @@
|
|||
|
||||
import React from 'react';
|
||||
import { fireEvent, screen } from '@testing-library/react';
|
||||
import { render } from '../../../../../utils/test_helper';
|
||||
import { getDefaultConfigs } from '../../configurations/default_configs';
|
||||
import { mockIndexPattern, mockUrlStorage } from '../../rtl_helpers';
|
||||
import { mockIndexPattern, render } from '../../rtl_helpers';
|
||||
import { ReportBreakdowns } from './report_breakdowns';
|
||||
import { USER_AGENT_OS } from '../../configurations/constants/elasticsearch_fieldnames';
|
||||
|
||||
|
@ -22,8 +21,6 @@ describe('Series Builder ReportBreakdowns', function () {
|
|||
});
|
||||
|
||||
it('should render properly', function () {
|
||||
mockUrlStorage({});
|
||||
|
||||
render(<ReportBreakdowns dataViewSeries={dataViewSeries} seriesId={seriesId} />);
|
||||
|
||||
screen.getByText('Select an option: , is selected');
|
||||
|
@ -31,9 +28,9 @@ describe('Series Builder ReportBreakdowns', function () {
|
|||
});
|
||||
|
||||
it('should set new series breakdown on change', function () {
|
||||
const { setSeries } = mockUrlStorage({});
|
||||
|
||||
render(<ReportBreakdowns dataViewSeries={dataViewSeries} seriesId={seriesId} />);
|
||||
const { setSeries } = render(
|
||||
<ReportBreakdowns dataViewSeries={dataViewSeries} seriesId={seriesId} />
|
||||
);
|
||||
|
||||
const btn = screen.getByRole('button', {
|
||||
name: /select an option: Browser family , is selected/i,
|
||||
|
@ -53,9 +50,9 @@ describe('Series Builder ReportBreakdowns', function () {
|
|||
});
|
||||
});
|
||||
it('should set undefined on new series on no select breakdown', function () {
|
||||
const { setSeries } = mockUrlStorage({});
|
||||
|
||||
render(<ReportBreakdowns dataViewSeries={dataViewSeries} seriesId={seriesId} />);
|
||||
const { setSeries } = render(
|
||||
<ReportBreakdowns dataViewSeries={dataViewSeries} seriesId={seriesId} />
|
||||
);
|
||||
|
||||
const btn = screen.getByRole('button', {
|
||||
name: /select an option: Browser family , is selected/i,
|
||||
|
|
|
@ -11,7 +11,6 @@ import { getDefaultConfigs } from '../../configurations/default_configs';
|
|||
import {
|
||||
mockAppIndexPattern,
|
||||
mockIndexPattern,
|
||||
mockUrlStorage,
|
||||
mockUseValuesList,
|
||||
render,
|
||||
} from '../../rtl_helpers';
|
||||
|
@ -28,21 +27,23 @@ describe('Series Builder ReportDefinitionCol', function () {
|
|||
indexPattern: mockIndexPattern,
|
||||
});
|
||||
|
||||
const { setSeries } = mockUrlStorage({
|
||||
const initSeries = {
|
||||
data: {
|
||||
[seriesId]: {
|
||||
dataType: 'ux',
|
||||
reportType: 'pld',
|
||||
dataType: 'ux' as const,
|
||||
reportType: 'pld' as const,
|
||||
time: { from: 'now-30d', to: 'now' },
|
||||
reportDefinitions: { [SERVICE_NAME]: ['elastic-co'] },
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
mockUseValuesList(['elastic-co']);
|
||||
|
||||
it('should render properly', async function () {
|
||||
render(<ReportDefinitionCol dataViewSeries={dataViewSeries} seriesId={seriesId} />);
|
||||
render(<ReportDefinitionCol dataViewSeries={dataViewSeries} seriesId={seriesId} />, {
|
||||
initSeries,
|
||||
});
|
||||
|
||||
screen.getByText('Web Application');
|
||||
screen.getByText('Environment');
|
||||
|
@ -51,7 +52,9 @@ describe('Series Builder ReportDefinitionCol', function () {
|
|||
});
|
||||
|
||||
it('should render selected report definitions', async function () {
|
||||
render(<ReportDefinitionCol dataViewSeries={dataViewSeries} seriesId={seriesId} />);
|
||||
render(<ReportDefinitionCol dataViewSeries={dataViewSeries} seriesId={seriesId} />, {
|
||||
initSeries,
|
||||
});
|
||||
|
||||
expect(await screen.findByText('elastic-co')).toBeInTheDocument();
|
||||
|
||||
|
@ -59,7 +62,10 @@ describe('Series Builder ReportDefinitionCol', function () {
|
|||
});
|
||||
|
||||
it('should be able to remove selected definition', async function () {
|
||||
render(<ReportDefinitionCol dataViewSeries={dataViewSeries} seriesId={seriesId} />);
|
||||
const { setSeries } = render(
|
||||
<ReportDefinitionCol dataViewSeries={dataViewSeries} seriesId={seriesId} />,
|
||||
{ initSeries }
|
||||
);
|
||||
|
||||
expect(
|
||||
await screen.findByLabelText('Remove elastic-co from selection in this group')
|
||||
|
|
|
@ -9,7 +9,7 @@ import React from 'react';
|
|||
import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule } from '@elastic/eui';
|
||||
import styled from 'styled-components';
|
||||
import { useAppIndexPatternContext } from '../../hooks/use_app_index_pattern';
|
||||
import { useUrlStorage } from '../../hooks/use_url_storage';
|
||||
import { useSeriesStorage } from '../../hooks/use_series_storage';
|
||||
import { CustomReportField } from '../custom_report_field';
|
||||
import { DataSeries, URLReportDefinition } from '../../types';
|
||||
import { SeriesChartTypesSelect } from './chart_types';
|
||||
|
@ -38,9 +38,11 @@ export function ReportDefinitionCol({
|
|||
}) {
|
||||
const { indexPattern } = useAppIndexPatternContext();
|
||||
|
||||
const { series, setSeries } = useUrlStorage(seriesId);
|
||||
const { getSeries, setSeries } = useSeriesStorage();
|
||||
|
||||
const { reportDefinitions: selectedReportDefinitions = {} } = series;
|
||||
const series = getSeries(seriesId);
|
||||
|
||||
const { reportDefinitions: selectedReportDefinitions = {} } = series ?? {};
|
||||
|
||||
const { reportDefinitions, defaultSeriesType, hasOperationType, yAxisColumns } = dataViewSeries;
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import React, { useMemo } from 'react';
|
|||
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
import { isEmpty } from 'lodash';
|
||||
import FieldValueSuggestions from '../../../field_value_suggestions';
|
||||
import { useUrlStorage } from '../../hooks/use_url_storage';
|
||||
import { useSeriesStorage } from '../../hooks/use_series_storage';
|
||||
import { useAppIndexPatternContext } from '../../hooks/use_app_index_pattern';
|
||||
import { ESFilter } from '../../../../../../../../../typings/elasticsearch';
|
||||
import { PersistableFilter } from '../../../../../../../lens/common';
|
||||
|
@ -25,7 +25,9 @@ interface Props {
|
|||
}
|
||||
|
||||
export function ReportDefinitionField({ seriesId, field, dataSeries, onChange }: Props) {
|
||||
const { series } = useUrlStorage(seriesId);
|
||||
const { getSeries } = useSeriesStorage();
|
||||
|
||||
const series = getSeries(seriesId);
|
||||
|
||||
const { indexPattern } = useAppIndexPatternContext();
|
||||
|
||||
|
|
|
@ -7,10 +7,9 @@
|
|||
|
||||
import React from 'react';
|
||||
import { screen } from '@testing-library/react';
|
||||
import { render } from '../../../../../utils/test_helper';
|
||||
import { ReportFilters } from './report_filters';
|
||||
import { getDefaultConfigs } from '../../configurations/default_configs';
|
||||
import { mockIndexPattern, mockUrlStorage } from '../../rtl_helpers';
|
||||
import { mockIndexPattern, render } from '../../rtl_helpers';
|
||||
|
||||
describe('Series Builder ReportFilters', function () {
|
||||
const seriesId = 'test-series-id';
|
||||
|
@ -20,7 +19,7 @@ describe('Series Builder ReportFilters', function () {
|
|||
reportType: 'pld',
|
||||
indexPattern: mockIndexPattern,
|
||||
});
|
||||
mockUrlStorage({});
|
||||
|
||||
it('should render properly', function () {
|
||||
render(<ReportFilters dataViewSeries={dataViewSeries} seriesId={seriesId} />);
|
||||
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
|
||||
import React from 'react';
|
||||
import { fireEvent, screen } from '@testing-library/react';
|
||||
import { mockAppIndexPattern, mockUrlStorage, render } from '../../rtl_helpers';
|
||||
import { mockAppIndexPattern, render } from '../../rtl_helpers';
|
||||
import { ReportTypesCol, SELECTED_DATA_TYPE_FOR_REPORT } from './report_types_col';
|
||||
import { ReportTypes } from '../series_builder';
|
||||
import { DEFAULT_TIME } from '../../configurations/constants';
|
||||
import { NEW_SERIES_KEY } from '../../hooks/use_url_storage';
|
||||
import { NEW_SERIES_KEY } from '../../hooks/use_series_storage';
|
||||
|
||||
describe('ReportTypesCol', function () {
|
||||
const seriesId = 'test-series-id';
|
||||
|
@ -30,8 +30,9 @@ describe('ReportTypesCol', function () {
|
|||
});
|
||||
|
||||
it('should set series on change', function () {
|
||||
const { setSeries } = mockUrlStorage({});
|
||||
render(<ReportTypesCol reportTypes={ReportTypes.synthetics} seriesId={seriesId} />);
|
||||
const { setSeries } = render(
|
||||
<ReportTypesCol reportTypes={ReportTypes.synthetics} seriesId={seriesId} />
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByText(/monitor duration/i));
|
||||
|
||||
|
@ -46,18 +47,21 @@ describe('ReportTypesCol', function () {
|
|||
});
|
||||
|
||||
it('should set selected as filled', function () {
|
||||
const { setSeries } = mockUrlStorage({
|
||||
const initSeries = {
|
||||
data: {
|
||||
[NEW_SERIES_KEY]: {
|
||||
dataType: 'synthetics',
|
||||
reportType: 'upp',
|
||||
dataType: 'synthetics' as const,
|
||||
reportType: 'upp' as const,
|
||||
breakdown: 'monitor.status',
|
||||
time: { from: 'now-15m', to: 'now' },
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
render(<ReportTypesCol reportTypes={ReportTypes.synthetics} seriesId={seriesId} />);
|
||||
const { setSeries } = render(
|
||||
<ReportTypesCol reportTypes={ReportTypes.synthetics} seriesId={seriesId} />,
|
||||
{ initSeries }
|
||||
);
|
||||
|
||||
const button = screen.getByRole('button', {
|
||||
name: /pings histogram/i,
|
||||
|
|
|
@ -11,7 +11,7 @@ import { FormattedMessage } from '@kbn/i18n/react';
|
|||
import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui';
|
||||
import styled from 'styled-components';
|
||||
import { ReportViewTypeId, SeriesUrl } from '../../types';
|
||||
import { useUrlStorage } from '../../hooks/use_url_storage';
|
||||
import { useSeriesStorage } from '../../hooks/use_series_storage';
|
||||
import { DEFAULT_TIME } from '../../configurations/constants';
|
||||
import { useAppIndexPatternContext } from '../../hooks/use_app_index_pattern';
|
||||
|
||||
|
@ -21,10 +21,9 @@ interface Props {
|
|||
}
|
||||
|
||||
export function ReportTypesCol({ seriesId, reportTypes }: Props) {
|
||||
const {
|
||||
series: { reportType: selectedReportType, ...restSeries },
|
||||
setSeries,
|
||||
} = useUrlStorage(seriesId);
|
||||
const { setSeries, getSeries } = useSeriesStorage();
|
||||
|
||||
const { reportType: selectedReportType, ...restSeries } = getSeries(seriesId);
|
||||
|
||||
const { loading, hasData, selectedApp } = useAppIndexPatternContext();
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import React from 'react';
|
||||
import { EuiSuperSelect } from '@elastic/eui';
|
||||
import { useUrlStorage } from '../hooks/use_url_storage';
|
||||
import { useSeriesStorage } from '../hooks/use_series_storage';
|
||||
import { ReportDefinition } from '../types';
|
||||
|
||||
interface Props {
|
||||
|
@ -18,7 +18,9 @@ interface Props {
|
|||
}
|
||||
|
||||
export function CustomReportField({ field, seriesId, options: opts }: Props) {
|
||||
const { series, setSeries } = useUrlStorage(seriesId);
|
||||
const { getSeries, setSeries } = useSeriesStorage();
|
||||
|
||||
const series = getSeries(seriesId);
|
||||
|
||||
const { reportDefinitions: rtd = {} } = series;
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ import { ReportTypesCol } from './columns/report_types_col';
|
|||
import { ReportDefinitionCol } from './columns/report_definition_col';
|
||||
import { ReportFilters } from './columns/report_filters';
|
||||
import { ReportBreakdowns } from './columns/report_breakdowns';
|
||||
import { NEW_SERIES_KEY, useUrlStorage } from '../hooks/use_url_storage';
|
||||
import { NEW_SERIES_KEY, useSeriesStorage } from '../hooks/use_series_storage';
|
||||
import { useAppIndexPatternContext } from '../hooks/use_app_index_pattern';
|
||||
import { getDefaultConfigs } from '../configurations/default_configs';
|
||||
|
||||
|
@ -53,7 +53,9 @@ export function SeriesBuilder({
|
|||
seriesId: string;
|
||||
seriesBuilderRef: RefObject<HTMLDivElement>;
|
||||
}) {
|
||||
const { series, setSeries, removeSeries } = useUrlStorage(seriesId);
|
||||
const { getSeries, setSeries, removeSeries } = useSeriesStorage();
|
||||
|
||||
const series = getSeries(seriesId);
|
||||
|
||||
const {
|
||||
dataType,
|
||||
|
@ -156,9 +158,8 @@ export function SeriesBuilder({
|
|||
reportDefinitions,
|
||||
};
|
||||
|
||||
setSeries(newSeriesId, newSeriesN).then(() => {
|
||||
removeSeries(NEW_SERIES_KEY);
|
||||
});
|
||||
setSeries(newSeriesId, newSeriesN);
|
||||
removeSeries(NEW_SERIES_KEY);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import { EuiSuperDatePicker } from '@elastic/eui';
|
||||
import React, { useEffect } from 'react';
|
||||
import { useHasData } from '../../../../hooks/use_has_data';
|
||||
import { useUrlStorage } from '../hooks/use_url_storage';
|
||||
import { useSeriesStorage } from '../hooks/use_series_storage';
|
||||
import { useQuickTimeRanges } from '../../../../hooks/use_quick_time_ranges';
|
||||
import { DEFAULT_TIME } from '../configurations/constants';
|
||||
|
||||
|
@ -30,7 +30,9 @@ export function SeriesDatePicker({ seriesId }: Props) {
|
|||
|
||||
const commonlyUsedRanges = useQuickTimeRanges();
|
||||
|
||||
const { series, setSeries } = useUrlStorage(seriesId);
|
||||
const { getSeries, setSeries } = useSeriesStorage();
|
||||
|
||||
const series = getSeries(seriesId);
|
||||
|
||||
function onTimeChange({ start, end }: { start: string; end: string }) {
|
||||
onRefreshTimeRange();
|
||||
|
|
|
@ -6,62 +6,67 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { mockUrlStorage, mockUseHasData, render } from '../rtl_helpers';
|
||||
import { mockUseHasData, render } from '../rtl_helpers';
|
||||
import { fireEvent, waitFor } from '@testing-library/react';
|
||||
import { SeriesDatePicker } from './index';
|
||||
import { DEFAULT_TIME } from '../configurations/constants';
|
||||
|
||||
describe('SeriesDatePicker', function () {
|
||||
it('should render properly', function () {
|
||||
mockUrlStorage({
|
||||
const initSeries = {
|
||||
data: {
|
||||
'uptime-pings-histogram': {
|
||||
dataType: 'synthetics',
|
||||
reportType: 'upp',
|
||||
dataType: 'synthetics' as const,
|
||||
reportType: 'upp' as const,
|
||||
breakdown: 'monitor.status',
|
||||
time: { from: 'now-30m', to: 'now' },
|
||||
},
|
||||
},
|
||||
});
|
||||
const { getByText } = render(<SeriesDatePicker seriesId={'series-id'} />);
|
||||
};
|
||||
const { getByText } = render(<SeriesDatePicker seriesId={'series-id'} />, { initSeries });
|
||||
|
||||
getByText('Last 30 minutes');
|
||||
});
|
||||
|
||||
it('should set defaults', async function () {
|
||||
const { setSeries: setSeries1 } = mockUrlStorage({
|
||||
const initSeries = {
|
||||
data: {
|
||||
'uptime-pings-histogram': {
|
||||
reportType: 'upp',
|
||||
dataType: 'synthetics',
|
||||
reportType: 'upp' as const,
|
||||
dataType: 'synthetics' as const,
|
||||
breakdown: 'monitor.status',
|
||||
},
|
||||
},
|
||||
} as any);
|
||||
render(<SeriesDatePicker seriesId={'uptime-pings-histogram'} />);
|
||||
};
|
||||
const { setSeries: setSeries1 } = render(
|
||||
<SeriesDatePicker seriesId={'uptime-pings-histogram'} />,
|
||||
{ initSeries: initSeries as any }
|
||||
);
|
||||
expect(setSeries1).toHaveBeenCalledTimes(1);
|
||||
expect(setSeries1).toHaveBeenCalledWith('uptime-pings-histogram', {
|
||||
breakdown: 'monitor.status',
|
||||
dataType: 'synthetics',
|
||||
reportType: 'upp',
|
||||
dataType: 'synthetics' as const,
|
||||
reportType: 'upp' as const,
|
||||
time: DEFAULT_TIME,
|
||||
});
|
||||
});
|
||||
|
||||
it('should set series data', async function () {
|
||||
const { setSeries } = mockUrlStorage({
|
||||
const initSeries = {
|
||||
data: {
|
||||
'uptime-pings-histogram': {
|
||||
dataType: 'synthetics',
|
||||
reportType: 'upp',
|
||||
dataType: 'synthetics' as const,
|
||||
reportType: 'upp' as const,
|
||||
breakdown: 'monitor.status',
|
||||
time: { from: 'now-30m', to: 'now' },
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const { onRefreshTimeRange } = mockUseHasData();
|
||||
const { getByTestId } = render(<SeriesDatePicker seriesId={'series-id'} />);
|
||||
const { getByTestId, setSeries } = render(<SeriesDatePicker seriesId={'series-id'} />, {
|
||||
initSeries,
|
||||
});
|
||||
|
||||
await waitFor(function () {
|
||||
fireEvent.click(getByTestId('superDatePickerToggleQuickMenuButton'));
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
import React from 'react';
|
||||
import { fireEvent, screen } from '@testing-library/react';
|
||||
import { Breakdowns } from './breakdowns';
|
||||
import { mockIndexPattern, mockUrlStorage, render } from '../../rtl_helpers';
|
||||
import { NEW_SERIES_KEY } from '../../hooks/use_url_storage';
|
||||
import { mockIndexPattern, render } from '../../rtl_helpers';
|
||||
import { NEW_SERIES_KEY } from '../../hooks/use_series_storage';
|
||||
import { getDefaultConfigs } from '../../configurations/default_configs';
|
||||
import { USER_AGENT_OS } from '../../configurations/constants/elasticsearch_fieldnames';
|
||||
|
||||
|
@ -21,8 +21,6 @@ describe('Breakdowns', function () {
|
|||
});
|
||||
|
||||
it('should render properly', async function () {
|
||||
mockUrlStorage({});
|
||||
|
||||
render(
|
||||
<Breakdowns
|
||||
seriesId={'series-id'}
|
||||
|
@ -35,14 +33,15 @@ describe('Breakdowns', function () {
|
|||
});
|
||||
|
||||
it('should call set series on change', function () {
|
||||
const { setSeries } = mockUrlStorage({ breakdown: USER_AGENT_OS });
|
||||
const initSeries = { breakdown: USER_AGENT_OS };
|
||||
|
||||
render(
|
||||
const { setSeries } = render(
|
||||
<Breakdowns
|
||||
seriesId={'series-id'}
|
||||
breakdowns={dataViewSeries.breakdowns}
|
||||
reportViewConfig={dataViewSeries}
|
||||
/>
|
||||
/>,
|
||||
{ initSeries }
|
||||
);
|
||||
|
||||
screen.getAllByText('Operating system');
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
import React from 'react';
|
||||
import { EuiSuperSelect } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { useSeriesStorage } from '../../hooks/use_series_storage';
|
||||
import { USE_BREAK_DOWN_COLUMN } from '../../configurations/constants';
|
||||
import { useUrlStorage } from '../../hooks/use_url_storage';
|
||||
import { DataSeries } from '../../types';
|
||||
|
||||
interface Props {
|
||||
|
@ -19,7 +19,9 @@ interface Props {
|
|||
}
|
||||
|
||||
export function Breakdowns({ reportViewConfig, seriesId, breakdowns = [] }: Props) {
|
||||
const { setSeries, series } = useUrlStorage(seriesId);
|
||||
const { setSeries, getSeries } = useSeriesStorage();
|
||||
|
||||
const series = getSeries(seriesId);
|
||||
|
||||
const selectedBreakdown = series.breakdown;
|
||||
const NO_BREAKDOWN = 'no_breakdown';
|
||||
|
|
|
@ -8,12 +8,12 @@
|
|||
import React from 'react';
|
||||
import { fireEvent, screen } from '@testing-library/react';
|
||||
import { FilterExpanded } from './filter_expanded';
|
||||
import { mockAppIndexPattern, mockUrlStorage, mockUseValuesList, render } from '../../rtl_helpers';
|
||||
import { mockAppIndexPattern, mockUseValuesList, render } from '../../rtl_helpers';
|
||||
import { USER_AGENT_NAME } from '../../configurations/constants/elasticsearch_fieldnames';
|
||||
|
||||
describe('FilterExpanded', function () {
|
||||
it('should render properly', async function () {
|
||||
mockUrlStorage({ filters: [{ field: USER_AGENT_NAME, values: ['Chrome'] }] });
|
||||
const initSeries = { filters: [{ field: USER_AGENT_NAME, values: ['Chrome'] }] };
|
||||
mockAppIndexPattern();
|
||||
|
||||
render(
|
||||
|
@ -22,13 +22,14 @@ describe('FilterExpanded', function () {
|
|||
label={'Browser Family'}
|
||||
field={USER_AGENT_NAME}
|
||||
goBack={jest.fn()}
|
||||
/>
|
||||
/>,
|
||||
{ initSeries }
|
||||
);
|
||||
|
||||
screen.getByText('Browser Family');
|
||||
});
|
||||
it('should call go back on click', async function () {
|
||||
mockUrlStorage({ filters: [{ field: USER_AGENT_NAME, values: ['Chrome'] }] });
|
||||
const initSeries = { filters: [{ field: USER_AGENT_NAME, values: ['Chrome'] }] };
|
||||
const goBack = jest.fn();
|
||||
|
||||
render(
|
||||
|
@ -37,7 +38,8 @@ describe('FilterExpanded', function () {
|
|||
label={'Browser Family'}
|
||||
field={USER_AGENT_NAME}
|
||||
goBack={goBack}
|
||||
/>
|
||||
/>,
|
||||
{ initSeries }
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByText('Browser Family'));
|
||||
|
@ -47,7 +49,7 @@ describe('FilterExpanded', function () {
|
|||
});
|
||||
|
||||
it('should call useValuesList on load', async function () {
|
||||
mockUrlStorage({ filters: [{ field: USER_AGENT_NAME, values: ['Chrome'] }] });
|
||||
const initSeries = { filters: [{ field: USER_AGENT_NAME, values: ['Chrome'] }] };
|
||||
|
||||
const { spy } = mockUseValuesList(['Chrome', 'Firefox']);
|
||||
|
||||
|
@ -59,7 +61,8 @@ describe('FilterExpanded', function () {
|
|||
label={'Browser Family'}
|
||||
field={USER_AGENT_NAME}
|
||||
goBack={goBack}
|
||||
/>
|
||||
/>,
|
||||
{ initSeries }
|
||||
);
|
||||
|
||||
expect(spy).toHaveBeenCalledTimes(1);
|
||||
|
@ -71,7 +74,7 @@ describe('FilterExpanded', function () {
|
|||
);
|
||||
});
|
||||
it('should filter display values', async function () {
|
||||
mockUrlStorage({ filters: [{ field: USER_AGENT_NAME, values: ['Chrome'] }] });
|
||||
const initSeries = { filters: [{ field: USER_AGENT_NAME, values: ['Chrome'] }] };
|
||||
|
||||
mockUseValuesList(['Chrome', 'Firefox']);
|
||||
|
||||
|
@ -81,7 +84,8 @@ describe('FilterExpanded', function () {
|
|||
label={'Browser Family'}
|
||||
field={USER_AGENT_NAME}
|
||||
goBack={jest.fn()}
|
||||
/>
|
||||
/>,
|
||||
{ initSeries }
|
||||
);
|
||||
|
||||
expect(screen.queryByText('Firefox')).toBeTruthy();
|
||||
|
|
|
@ -11,7 +11,7 @@ import styled from 'styled-components';
|
|||
import { rgba } from 'polished';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { useAppIndexPatternContext } from '../../hooks/use_app_index_pattern';
|
||||
import { useUrlStorage } from '../../hooks/use_url_storage';
|
||||
import { useSeriesStorage } from '../../hooks/use_series_storage';
|
||||
import { UrlFilter } from '../../types';
|
||||
import { FilterValueButton } from './filter_value_btn';
|
||||
import { useValuesList } from '../../../../../hooks/use_values_list';
|
||||
|
@ -33,7 +33,9 @@ export function FilterExpanded({ seriesId, field, label, goBack, nestedField, is
|
|||
|
||||
const [isOpen, setIsOpen] = useState({ value: '', negate: false });
|
||||
|
||||
const { series } = useUrlStorage(seriesId);
|
||||
const { getSeries } = useSeriesStorage();
|
||||
|
||||
const series = getSeries(seriesId);
|
||||
|
||||
const { values, loading } = useValuesList({
|
||||
query: value,
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import React from 'react';
|
||||
import { fireEvent, screen } from '@testing-library/react';
|
||||
import { FilterValueButton } from './filter_value_btn';
|
||||
import { mockUrlStorage, mockUseSeriesFilter, mockUseValuesList, render } from '../../rtl_helpers';
|
||||
import { mockUseSeriesFilter, mockUseValuesList, render } from '../../rtl_helpers';
|
||||
import {
|
||||
USER_AGENT_NAME,
|
||||
USER_AGENT_VERSION,
|
||||
|
@ -75,7 +75,6 @@ describe('FilterValueButton', function () {
|
|||
});
|
||||
});
|
||||
it('should remove filter on click if already selected', async function () {
|
||||
mockUrlStorage({});
|
||||
const { removeFilter } = mockUseSeriesFilter();
|
||||
|
||||
render(
|
||||
|
|
|
@ -8,7 +8,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import React, { useMemo } from 'react';
|
||||
import { EuiFilterButton, hexToRgb } from '@elastic/eui';
|
||||
import { useAppIndexPatternContext } from '../../hooks/use_app_index_pattern';
|
||||
import { useUrlStorage } from '../../hooks/use_url_storage';
|
||||
import { useSeriesStorage } from '../../hooks/use_series_storage';
|
||||
import { useSeriesFilters } from '../../hooks/use_series_filters';
|
||||
import { euiStyled } from '../../../../../../../../../src/plugins/kibana_react/common';
|
||||
import FieldValueSuggestions from '../../../field_value_suggestions';
|
||||
|
@ -37,7 +37,9 @@ export function FilterValueButton({
|
|||
nestedField,
|
||||
allSelectedValues,
|
||||
}: Props) {
|
||||
const { series } = useUrlStorage(seriesId);
|
||||
const { getSeries } = useSeriesStorage();
|
||||
|
||||
const series = getSeries(seriesId);
|
||||
|
||||
const { indexPattern } = useAppIndexPatternContext();
|
||||
|
||||
|
|
|
@ -8,14 +8,14 @@
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import React from 'react';
|
||||
import { EuiButtonIcon } from '@elastic/eui';
|
||||
import { useUrlStorage } from '../../hooks/use_url_storage';
|
||||
import { useSeriesStorage } from '../../hooks/use_series_storage';
|
||||
|
||||
interface Props {
|
||||
seriesId: string;
|
||||
}
|
||||
|
||||
export function RemoveSeries({ seriesId }: Props) {
|
||||
const { removeSeries } = useUrlStorage();
|
||||
const { removeSeries } = useSeriesStorage();
|
||||
|
||||
const onClick = () => {
|
||||
removeSeries(seriesId);
|
||||
|
|
|
@ -9,14 +9,15 @@ import React from 'react';
|
|||
import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { RemoveSeries } from './remove_series';
|
||||
import { NEW_SERIES_KEY, useUrlStorage } from '../../hooks/use_url_storage';
|
||||
import { NEW_SERIES_KEY, useSeriesStorage } from '../../hooks/use_series_storage';
|
||||
import { ReportToDataTypeMap } from '../../configurations/constants';
|
||||
|
||||
interface Props {
|
||||
seriesId: string;
|
||||
}
|
||||
export function SeriesActions({ seriesId }: Props) {
|
||||
const { series, removeSeries, setSeries } = useUrlStorage(seriesId);
|
||||
const { getSeries, removeSeries, setSeries } = useSeriesStorage();
|
||||
const series = getSeries(seriesId);
|
||||
|
||||
const onEdit = () => {
|
||||
removeSeries(seriesId);
|
||||
|
|
|
@ -19,7 +19,7 @@ import { FilterExpanded } from './filter_expanded';
|
|||
import { DataSeries } from '../../types';
|
||||
import { FieldLabels } from '../../configurations/constants/constants';
|
||||
import { SelectedFilters } from '../selected_filters';
|
||||
import { useUrlStorage } from '../../hooks/use_url_storage';
|
||||
import { useSeriesStorage } from '../../hooks/use_series_storage';
|
||||
|
||||
interface Props {
|
||||
seriesId: string;
|
||||
|
@ -53,7 +53,8 @@ export function SeriesFilter({ series, isNew, seriesId, defaultFilters = [] }: P
|
|||
};
|
||||
});
|
||||
|
||||
const { setSeries, series: urlSeries } = useUrlStorage(seriesId);
|
||||
const { setSeries, getSeries } = useSeriesStorage();
|
||||
const urlSeries = getSeries(seriesId);
|
||||
|
||||
const button = (
|
||||
<EuiButtonEmpty
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
|
||||
import React from 'react';
|
||||
import { screen, waitFor } from '@testing-library/react';
|
||||
import { mockAppIndexPattern, mockIndexPattern, mockUrlStorage, render } from '../rtl_helpers';
|
||||
import { mockAppIndexPattern, mockIndexPattern, render } from '../rtl_helpers';
|
||||
import { SelectedFilters } from './selected_filters';
|
||||
import { getDefaultConfigs } from '../configurations/default_configs';
|
||||
import { NEW_SERIES_KEY } from '../hooks/use_url_storage';
|
||||
import { NEW_SERIES_KEY } from '../hooks/use_series_storage';
|
||||
import { USER_AGENT_NAME } from '../configurations/constants/elasticsearch_fieldnames';
|
||||
|
||||
describe('SelectedFilters', function () {
|
||||
|
@ -23,9 +23,9 @@ describe('SelectedFilters', function () {
|
|||
});
|
||||
|
||||
it('should render properly', async function () {
|
||||
mockUrlStorage({ filters: [{ field: USER_AGENT_NAME, values: ['Chrome'] }] });
|
||||
const initSeries = { filters: [{ field: USER_AGENT_NAME, values: ['Chrome'] }] };
|
||||
|
||||
render(<SelectedFilters seriesId={'series-id'} series={dataViewSeries} />);
|
||||
render(<SelectedFilters seriesId={'series-id'} series={dataViewSeries} />, { initSeries });
|
||||
|
||||
await waitFor(() => {
|
||||
screen.getByText('Chrome');
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import React, { Fragment } from 'react';
|
||||
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
import { useUrlStorage } from '../hooks/use_url_storage';
|
||||
import { useSeriesStorage } from '../hooks/use_series_storage';
|
||||
import { FilterLabel } from '../components/filter_label';
|
||||
import { DataSeries, UrlFilter } from '../types';
|
||||
import { useAppIndexPatternContext } from '../hooks/use_app_index_pattern';
|
||||
|
@ -20,7 +20,9 @@ interface Props {
|
|||
isNew?: boolean;
|
||||
}
|
||||
export function SelectedFilters({ seriesId, isNew, series: dataSeries }: Props) {
|
||||
const { series } = useUrlStorage(seriesId);
|
||||
const { getSeries } = useSeriesStorage();
|
||||
|
||||
const series = getSeries(seriesId);
|
||||
|
||||
const { reportDefinitions = {} } = series;
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import { EuiBasicTable, EuiIcon, EuiSpacer, EuiText } from '@elastic/eui';
|
|||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { SeriesFilter } from './columns/series_filter';
|
||||
import { DataSeries } from '../types';
|
||||
import { NEW_SERIES_KEY, useUrlStorage } from '../hooks/use_url_storage';
|
||||
import { NEW_SERIES_KEY, useSeriesStorage } from '../hooks/use_series_storage';
|
||||
import { getDefaultConfigs } from '../configurations/default_configs';
|
||||
import { DatePickerCol } from './columns/date_picker_col';
|
||||
import { useAppIndexPatternContext } from '../hooks/use_app_index_pattern';
|
||||
|
@ -19,7 +19,7 @@ import { SeriesActions } from './columns/series_actions';
|
|||
import { ChartEditOptions } from './chart_edit_options';
|
||||
|
||||
export function SeriesEditor() {
|
||||
const { allSeries, firstSeriesId } = useUrlStorage();
|
||||
const { allSeries, firstSeriesId } = useSeriesStorage();
|
||||
|
||||
const columns = [
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue