[RAC] Add loading and empty states to the alerts table - Take II (#110504)
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
641cef7ca6
commit
4e9e7a8671
|
@ -5,7 +5,6 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { EuiLoadingContent, EuiPanel } from '@elastic/eui';
|
|
||||||
import { isEmpty } from 'lodash/fp';
|
import { isEmpty } from 'lodash/fp';
|
||||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { connect, ConnectedProps, useDispatch } from 'react-redux';
|
import { connect, ConnectedProps, useDispatch } from 'react-redux';
|
||||||
|
@ -369,11 +368,7 @@ export const AlertsTableComponent: React.FC<AlertsTableComponentProps> = ({
|
||||||
}, [dispatch, defaultTimelineModel, filterManager, tGridEnabled, timelineId]);
|
}, [dispatch, defaultTimelineModel, filterManager, tGridEnabled, timelineId]);
|
||||||
|
|
||||||
if (loading || indexPatternsLoading || isEmpty(selectedPatterns)) {
|
if (loading || indexPatternsLoading || isEmpty(selectedPatterns)) {
|
||||||
return (
|
return null;
|
||||||
<EuiPanel hasBorder={false} hasShadow={false} paddingSize="none">
|
|
||||||
<EuiLoadingContent data-test-subj="loading-alerts-panel" />
|
|
||||||
</EuiPanel>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 126 KiB |
|
@ -8,19 +8,12 @@
|
||||||
import type { AlertConsumers as AlertConsumersTyped } from '@kbn/rule-data-utils';
|
import type { AlertConsumers as AlertConsumersTyped } from '@kbn/rule-data-utils';
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
import { AlertConsumers as AlertConsumersNonTyped } from '@kbn/rule-data-utils/target_node/alerts_as_data_rbac';
|
import { AlertConsumers as AlertConsumersNonTyped } from '@kbn/rule-data-utils/target_node/alerts_as_data_rbac';
|
||||||
import {
|
import { EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui';
|
||||||
EuiEmptyPrompt,
|
|
||||||
EuiFlexGroup,
|
|
||||||
EuiFlexItem,
|
|
||||||
EuiPanel,
|
|
||||||
EuiLoadingContent,
|
|
||||||
} from '@elastic/eui';
|
|
||||||
import { isEmpty } from 'lodash/fp';
|
import { isEmpty } from 'lodash/fp';
|
||||||
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
|
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
|
||||||
import { useKibana } from '../../../../../../../src/plugins/kibana_react/public';
|
import { useKibana } from '../../../../../../../src/plugins/kibana_react/public';
|
||||||
import { Direction, EntityType } from '../../../../common/search_strategy';
|
import { Direction, EntityType } from '../../../../common/search_strategy';
|
||||||
import type { DocValueFields } from '../../../../common/search_strategy';
|
import type { DocValueFields } from '../../../../common/search_strategy';
|
||||||
|
@ -53,6 +46,7 @@ import { SELECTOR_TIMELINE_GLOBAL_CONTAINER, UpdatedFlexGroup, UpdatedFlexItem }
|
||||||
import { Sort } from '../body/sort';
|
import { Sort } from '../body/sort';
|
||||||
import { InspectButton, InspectButtonContainer } from '../../inspect';
|
import { InspectButton, InspectButtonContainer } from '../../inspect';
|
||||||
import { SummaryViewSelector, ViewSelection } from '../event_rendered_view/selector';
|
import { SummaryViewSelector, ViewSelection } from '../event_rendered_view/selector';
|
||||||
|
import { TGridLoading, TGridEmpty } from '../shared';
|
||||||
|
|
||||||
const AlertConsumers: typeof AlertConsumersTyped = AlertConsumersNonTyped;
|
const AlertConsumers: typeof AlertConsumersTyped = AlertConsumersNonTyped;
|
||||||
|
|
||||||
|
@ -269,6 +263,8 @@ const TGridIntegratedComponent: React.FC<TGridIntegratedProps> = ({
|
||||||
[deletedEventIds.length, totalCount]
|
[deletedEventIds.length, totalCount]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const hasAlerts = totalCountMinusDeleted > 0;
|
||||||
|
|
||||||
const nonDeletedEvents = useMemo(() => events.filter((e) => !deletedEventIds.includes(e._id)), [
|
const nonDeletedEvents = useMemo(() => events.filter((e) => !deletedEventIds.includes(e._id)), [
|
||||||
deletedEventIds,
|
deletedEventIds,
|
||||||
events,
|
events,
|
||||||
|
@ -300,7 +296,7 @@ const TGridIntegratedComponent: React.FC<TGridIntegratedProps> = ({
|
||||||
data-test-subj="events-viewer-panel"
|
data-test-subj="events-viewer-panel"
|
||||||
$isFullScreen={globalFullScreen}
|
$isFullScreen={globalFullScreen}
|
||||||
>
|
>
|
||||||
{isFirstUpdate.current && <EuiLoadingContent data-test-subj="loading-alerts-panel" />}
|
{isFirstUpdate.current && <TGridLoading height="short" />}
|
||||||
|
|
||||||
{graphOverlay}
|
{graphOverlay}
|
||||||
|
|
||||||
|
@ -325,33 +321,14 @@ const TGridIntegratedComponent: React.FC<TGridIntegratedProps> = ({
|
||||||
</UpdatedFlexGroup>
|
</UpdatedFlexGroup>
|
||||||
|
|
||||||
{!graphEventId && graphOverlay == null && (
|
{!graphEventId && graphOverlay == null && (
|
||||||
|
<>
|
||||||
|
{!hasAlerts && !loading && <TGridEmpty height="short" />}
|
||||||
|
{hasAlerts && (
|
||||||
<FullWidthFlexGroup
|
<FullWidthFlexGroup
|
||||||
$visible={!graphEventId && graphOverlay == null}
|
$visible={!graphEventId && graphOverlay == null}
|
||||||
gutterSize="none"
|
gutterSize="none"
|
||||||
>
|
>
|
||||||
<ScrollableFlexItem grow={1}>
|
<ScrollableFlexItem grow={1}>
|
||||||
{totalCountMinusDeleted === 0 && loading === false && (
|
|
||||||
<EuiEmptyPrompt
|
|
||||||
title={
|
|
||||||
<h2>
|
|
||||||
<FormattedMessage
|
|
||||||
id="xpack.timelines.tGrid.noResultsMatchSearchCriteriaTitle"
|
|
||||||
defaultMessage="No results match your search criteria"
|
|
||||||
/>
|
|
||||||
</h2>
|
|
||||||
}
|
|
||||||
titleSize="s"
|
|
||||||
body={
|
|
||||||
<p>
|
|
||||||
<FormattedMessage
|
|
||||||
id="xpack.timelines.tGrid.noResultsMatchSearchCriteriaDescription"
|
|
||||||
defaultMessage="Try searching over a longer period of time or modifying your search."
|
|
||||||
/>
|
|
||||||
</p>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{totalCountMinusDeleted > 0 && (
|
|
||||||
<StatefulBody
|
<StatefulBody
|
||||||
hasAlertsCrud={hasAlertsCrud}
|
hasAlertsCrud={hasAlertsCrud}
|
||||||
activePage={pageInfo.activePage}
|
activePage={pageInfo.activePage}
|
||||||
|
@ -377,10 +354,11 @@ const TGridIntegratedComponent: React.FC<TGridIntegratedProps> = ({
|
||||||
refetch={refetch}
|
refetch={refetch}
|
||||||
indexNames={indexNames}
|
indexNames={indexNames}
|
||||||
/>
|
/>
|
||||||
)}
|
|
||||||
</ScrollableFlexItem>
|
</ScrollableFlexItem>
|
||||||
</FullWidthFlexGroup>
|
</FullWidthFlexGroup>
|
||||||
)}
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</EventsContainerLoading>
|
</EventsContainerLoading>
|
||||||
)}
|
)}
|
||||||
</StyledEuiPanel>
|
</StyledEuiPanel>
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License
|
||||||
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
|
* 2.0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
EuiPanel,
|
||||||
|
EuiFlexGroup,
|
||||||
|
EuiFlexItem,
|
||||||
|
EuiLoadingSpinner,
|
||||||
|
EuiImage,
|
||||||
|
EuiText,
|
||||||
|
EuiTitle,
|
||||||
|
} from '@elastic/eui';
|
||||||
|
import { FormattedMessage } from '@kbn/i18n/react';
|
||||||
|
import { useKibana } from '../../../../../../../src/plugins/kibana_react/public';
|
||||||
|
import type { CoreStart } from '../../../../../../../src/core/public';
|
||||||
|
|
||||||
|
const heights = {
|
||||||
|
tall: 490,
|
||||||
|
short: 250,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const TGridLoading: React.FC<{ height?: keyof typeof heights }> = ({ height = 'tall' }) => {
|
||||||
|
return (
|
||||||
|
<EuiPanel color="subdued">
|
||||||
|
<EuiFlexGroup
|
||||||
|
style={{ height: heights[height] }}
|
||||||
|
alignItems="center"
|
||||||
|
justifyContent="center"
|
||||||
|
data-test-subj="loading-alerts-panel"
|
||||||
|
>
|
||||||
|
<EuiFlexItem grow={false}>
|
||||||
|
<EuiLoadingSpinner size="xl" />
|
||||||
|
</EuiFlexItem>
|
||||||
|
</EuiFlexGroup>
|
||||||
|
</EuiPanel>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const panelStyle = {
|
||||||
|
maxWidth: 500,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const TGridEmpty: React.FC<{ height?: keyof typeof heights }> = ({ height = 'tall' }) => {
|
||||||
|
const { http } = useKibana<CoreStart>().services;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<EuiPanel color="subdued">
|
||||||
|
<EuiFlexGroup style={{ height: heights[height] }} alignItems="center" justifyContent="center">
|
||||||
|
<EuiFlexItem grow={false}>
|
||||||
|
<EuiPanel hasBorder={true} style={panelStyle}>
|
||||||
|
<EuiFlexGroup>
|
||||||
|
<EuiFlexItem>
|
||||||
|
<EuiText size="s">
|
||||||
|
<EuiTitle>
|
||||||
|
<h3>
|
||||||
|
<FormattedMessage
|
||||||
|
id="xpack.timelines.tgrid.empty.title"
|
||||||
|
defaultMessage="No results match your search criteria"
|
||||||
|
/>
|
||||||
|
</h3>
|
||||||
|
</EuiTitle>
|
||||||
|
<p>
|
||||||
|
<FormattedMessage
|
||||||
|
id="xpack.timelines.tgrid.empty.description"
|
||||||
|
defaultMessage="Try searching over a longer period of time or modifying your search"
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
</EuiText>
|
||||||
|
</EuiFlexItem>
|
||||||
|
<EuiFlexItem grow={false}>
|
||||||
|
<EuiImage
|
||||||
|
size="200"
|
||||||
|
alt=""
|
||||||
|
url={http.basePath.prepend(
|
||||||
|
'/plugins/timelines/assets/illustration_product_no_results_magnifying_glass.svg'
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</EuiFlexItem>
|
||||||
|
</EuiFlexGroup>
|
||||||
|
</EuiPanel>
|
||||||
|
</EuiFlexItem>
|
||||||
|
</EuiFlexGroup>
|
||||||
|
</EuiPanel>
|
||||||
|
);
|
||||||
|
};
|
|
@ -4,8 +4,7 @@
|
||||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
import { EuiEmptyPrompt, EuiFlexGroup, EuiFlexItem, EuiLoadingContent } from '@elastic/eui';
|
import { EuiFlexItem } from '@elastic/eui';
|
||||||
import { FormattedMessage } from '@kbn/i18n/react';
|
|
||||||
import { isEmpty } from 'lodash/fp';
|
import { isEmpty } from 'lodash/fp';
|
||||||
import React, { useEffect, useMemo, useState, useRef } from 'react';
|
import React, { useEffect, useMemo, useState, useRef } from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
@ -39,10 +38,16 @@ import type { State } from '../../../store/t_grid';
|
||||||
import { useTimelineEvents } from '../../../container';
|
import { useTimelineEvents } from '../../../container';
|
||||||
import { StatefulBody } from '../body';
|
import { StatefulBody } from '../body';
|
||||||
import { LastUpdatedAt } from '../..';
|
import { LastUpdatedAt } from '../..';
|
||||||
import { SELECTOR_TIMELINE_GLOBAL_CONTAINER, UpdatedFlexItem, UpdatedFlexGroup } from '../styles';
|
import {
|
||||||
|
SELECTOR_TIMELINE_GLOBAL_CONTAINER,
|
||||||
|
UpdatedFlexItem,
|
||||||
|
UpdatedFlexGroup,
|
||||||
|
FullWidthFlexGroup,
|
||||||
|
} from '../styles';
|
||||||
import { InspectButton, InspectButtonContainer } from '../../inspect';
|
import { InspectButton, InspectButtonContainer } from '../../inspect';
|
||||||
import { useFetchIndex } from '../../../container/source';
|
import { useFetchIndex } from '../../../container/source';
|
||||||
import { AddToCaseAction } from '../../actions/timeline/cases/add_to_case_action';
|
import { AddToCaseAction } from '../../actions/timeline/cases/add_to_case_action';
|
||||||
|
import { TGridLoading, TGridEmpty } from '../shared';
|
||||||
|
|
||||||
export const EVENTS_VIEWER_HEADER_HEIGHT = 90; // px
|
export const EVENTS_VIEWER_HEADER_HEIGHT = 90; // px
|
||||||
const STANDALONE_ID = 'standalone-t-grid';
|
const STANDALONE_ID = 'standalone-t-grid';
|
||||||
|
@ -68,12 +73,6 @@ const EventsContainerLoading = styled.div.attrs(({ className = '' }) => ({
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const FullWidthFlexGroup = styled(EuiFlexGroup)<{ $visible: boolean }>`
|
|
||||||
overflow: hidden;
|
|
||||||
margin: 0;
|
|
||||||
display: ${({ $visible }) => ($visible ? 'flex' : 'none')};
|
|
||||||
`;
|
|
||||||
|
|
||||||
const ScrollableFlexItem = styled(EuiFlexItem)`
|
const ScrollableFlexItem = styled(EuiFlexItem)`
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
`;
|
`;
|
||||||
|
@ -255,6 +254,8 @@ const TGridStandaloneComponent: React.FC<TGridStandaloneProps> = ({
|
||||||
() => (totalCount > 0 ? totalCount - deletedEventIds.length : 0),
|
() => (totalCount > 0 ? totalCount - deletedEventIds.length : 0),
|
||||||
[deletedEventIds.length, totalCount]
|
[deletedEventIds.length, totalCount]
|
||||||
);
|
);
|
||||||
|
const hasAlerts = totalCountMinusDeleted > 0;
|
||||||
|
|
||||||
const activeCaseFlowId = useSelector((state: State) => tGridSelectors.activeCaseFlowId(state));
|
const activeCaseFlowId = useSelector((state: State) => tGridSelectors.activeCaseFlowId(state));
|
||||||
const selectedEvent = useMemo(() => {
|
const selectedEvent = useMemo(() => {
|
||||||
const matchedEvent = events.find((event) => event.ecs._id === activeCaseFlowId);
|
const matchedEvent = events.find((event) => event.ecs._id === activeCaseFlowId);
|
||||||
|
@ -338,14 +339,14 @@ const TGridStandaloneComponent: React.FC<TGridStandaloneProps> = ({
|
||||||
return (
|
return (
|
||||||
<InspectButtonContainer data-test-subj="events-viewer-panel">
|
<InspectButtonContainer data-test-subj="events-viewer-panel">
|
||||||
<AlertsTableWrapper>
|
<AlertsTableWrapper>
|
||||||
{isFirstUpdate.current && <EuiLoadingContent data-test-subj="loading-alerts-panel" />}
|
{isFirstUpdate.current && <TGridLoading />}
|
||||||
{canQueryTimeline ? (
|
{canQueryTimeline ? (
|
||||||
<>
|
<>
|
||||||
<EventsContainerLoading
|
<EventsContainerLoading
|
||||||
data-timeline-id={STANDALONE_ID}
|
data-timeline-id={STANDALONE_ID}
|
||||||
data-test-subj={`events-container-loading-${loading}`}
|
data-test-subj={`events-container-loading-${loading}`}
|
||||||
>
|
>
|
||||||
<UpdatedFlexGroup gutterSize="s" justifyContent="flexEnd" alignItems="baseline">
|
<UpdatedFlexGroup gutterSize="s" justifyContent="flexEnd" alignItems="center">
|
||||||
<UpdatedFlexItem grow={false} $show={!loading}>
|
<UpdatedFlexItem grow={false} $show={!loading}>
|
||||||
<InspectButton title={justTitle} inspect={inspect} loading={loading} />
|
<InspectButton title={justTitle} inspect={inspect} loading={loading} />
|
||||||
</UpdatedFlexItem>
|
</UpdatedFlexItem>
|
||||||
|
@ -354,28 +355,9 @@ const TGridStandaloneComponent: React.FC<TGridStandaloneProps> = ({
|
||||||
</UpdatedFlexItem>
|
</UpdatedFlexItem>
|
||||||
</UpdatedFlexGroup>
|
</UpdatedFlexGroup>
|
||||||
|
|
||||||
{totalCountMinusDeleted === 0 && loading === false && (
|
{!hasAlerts && !loading && <TGridEmpty />}
|
||||||
<EuiEmptyPrompt
|
|
||||||
title={
|
{hasAlerts && (
|
||||||
<h2>
|
|
||||||
<FormattedMessage
|
|
||||||
id="xpack.timelines.tGrid.noResultsMatchSearchCriteriaTitle"
|
|
||||||
defaultMessage="No results match your search criteria"
|
|
||||||
/>
|
|
||||||
</h2>
|
|
||||||
}
|
|
||||||
titleSize="s"
|
|
||||||
body={
|
|
||||||
<p>
|
|
||||||
<FormattedMessage
|
|
||||||
id="xpack.timelines.tGrid.noResultsMatchSearchCriteriaDescription"
|
|
||||||
defaultMessage="Try searching over a longer period of time or modifying your search."
|
|
||||||
/>
|
|
||||||
</p>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{totalCountMinusDeleted > 0 && (
|
|
||||||
<FullWidthFlexGroup direction="row" $visible={!graphEventId} gutterSize="none">
|
<FullWidthFlexGroup direction="row" $visible={!graphEventId} gutterSize="none">
|
||||||
<ScrollableFlexItem grow={1}>
|
<ScrollableFlexItem grow={1}>
|
||||||
<StatefulBody
|
<StatefulBody
|
||||||
|
|
|
@ -459,6 +459,13 @@ export const HideShowContainer = styled.div.attrs<{ $isVisible: boolean }>(
|
||||||
})
|
})
|
||||||
)<{ $isVisible: boolean }>``;
|
)<{ $isVisible: boolean }>``;
|
||||||
|
|
||||||
|
export const FullWidthFlexGroup = styled(EuiFlexGroup)<{ $visible?: boolean }>`
|
||||||
|
overflow: hidden;
|
||||||
|
margin: 0;
|
||||||
|
min-height: 490px;
|
||||||
|
display: ${({ $visible = true }) => ($visible ? 'flex' : 'none')};
|
||||||
|
`;
|
||||||
|
|
||||||
export const UpdatedFlexGroup = styled(EuiFlexGroup)`
|
export const UpdatedFlexGroup = styled(EuiFlexGroup)`
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: ${({ theme }) => theme.eui.euiZLevel1};
|
z-index: ${({ theme }) => theme.eui.euiZLevel1};
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { lazy, Suspense } from 'react';
|
import React, { lazy, Suspense } from 'react';
|
||||||
import { EuiLoadingContent, EuiLoadingSpinner, EuiPanel } from '@elastic/eui';
|
import { EuiLoadingSpinner } from '@elastic/eui';
|
||||||
import { I18nProvider } from '@kbn/i18n/react';
|
import { I18nProvider } from '@kbn/i18n/react';
|
||||||
import type { Store } from 'redux';
|
import type { Store } from 'redux';
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
|
@ -17,6 +17,7 @@ import type { LastUpdatedAtProps, LoadingPanelProps, FieldBrowserProps } from '.
|
||||||
import type { AddToCaseActionProps } from '../components/actions/timeline/cases/add_to_case_action';
|
import type { AddToCaseActionProps } from '../components/actions/timeline/cases/add_to_case_action';
|
||||||
import { initialTGridState } from '../store/t_grid/reducer';
|
import { initialTGridState } from '../store/t_grid/reducer';
|
||||||
import { createStore } from '../store/t_grid';
|
import { createStore } from '../store/t_grid';
|
||||||
|
import { TGridLoading } from '../components/t_grid/shared';
|
||||||
|
|
||||||
const initializeStore = ({
|
const initializeStore = ({
|
||||||
store,
|
store,
|
||||||
|
@ -51,13 +52,7 @@ export const getTGridLazy = (
|
||||||
) => {
|
) => {
|
||||||
initializeStore({ store, storage, setStore });
|
initializeStore({ store, storage, setStore });
|
||||||
return (
|
return (
|
||||||
<Suspense
|
<Suspense fallback={<TGridLoading height={props.type === 'standalone' ? 'tall' : 'short'} />}>
|
||||||
fallback={
|
|
||||||
<EuiPanel hasBorder={false} hasShadow={false} paddingSize="none">
|
|
||||||
<EuiLoadingContent />
|
|
||||||
</EuiPanel>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<TimelineLazy {...props} store={store} storage={storage} data={data} setStore={setStore} />
|
<TimelineLazy {...props} store={store} storage={storage} data={data} setStore={setStore} />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
);
|
);
|
||||||
|
|
|
@ -11,6 +11,7 @@ import ReactDOM from 'react-dom';
|
||||||
import { AppMountParameters, CoreStart } from 'kibana/public';
|
import { AppMountParameters, CoreStart } from 'kibana/public';
|
||||||
import { I18nProvider } from '@kbn/i18n/react';
|
import { I18nProvider } from '@kbn/i18n/react';
|
||||||
import { KibanaContextProvider } from '../../../../../../../../src/plugins/kibana_react/public';
|
import { KibanaContextProvider } from '../../../../../../../../src/plugins/kibana_react/public';
|
||||||
|
import { EuiThemeProvider } from '../../../../../../../../src/plugins/kibana_react/common';
|
||||||
import { TimelinesUIStart } from '../../../../../../../plugins/timelines/public';
|
import { TimelinesUIStart } from '../../../../../../../plugins/timelines/public';
|
||||||
import { DataPublicPluginStart } from '../../../../../../../../src/plugins/data/public';
|
import { DataPublicPluginStart } from '../../../../../../../../src/plugins/data/public';
|
||||||
|
|
||||||
|
@ -60,6 +61,7 @@ const AppRoot = React.memo(
|
||||||
<I18nProvider>
|
<I18nProvider>
|
||||||
<Router history={parameters.history}>
|
<Router history={parameters.history}>
|
||||||
<KibanaContextProvider services={coreStart}>
|
<KibanaContextProvider services={coreStart}>
|
||||||
|
<EuiThemeProvider>
|
||||||
{(timelinesPluginSetup &&
|
{(timelinesPluginSetup &&
|
||||||
timelinesPluginSetup.getTGrid &&
|
timelinesPluginSetup.getTGrid &&
|
||||||
timelinesPluginSetup.getTGrid<'standalone'>({
|
timelinesPluginSetup.getTGrid<'standalone'>({
|
||||||
|
@ -93,6 +95,7 @@ const AppRoot = React.memo(
|
||||||
unit: (n: number) => `${n}`,
|
unit: (n: number) => `${n}`,
|
||||||
})) ??
|
})) ??
|
||||||
null}
|
null}
|
||||||
|
</EuiThemeProvider>
|
||||||
</KibanaContextProvider>
|
</KibanaContextProvider>
|
||||||
</Router>
|
</Router>
|
||||||
</I18nProvider>
|
</I18nProvider>
|
||||||
|
|
Loading…
Reference in a new issue