[Security Solution][THI] remove usages of EUI json tokens (#210482)

## Summary

This PR is probably the final PR that makes the changes to support EUI
Borealis. It focuses on removing all the usage of EUI Json tokens.

You will notice different approaches while removing the tokens:
- for some cases, the changes were done using `css from
'@emotions/react'` as the components using the tokens were already using
`euiTheme` or adding it was straightforward and required the minimal
amount of changes
- for some cases, where the css changes were pretty involved, a hook was
created to be able to import the styles and apply them in the components
- finally for other cases, esepcially if the styled components were
extracted in a different file and were used within many others, I
decided to create reusable components. This allowed to not change all
the files impacted and limit the number of files modified in this PR.

Feel free to comment on any of the approaches and suggest better
options!

https://github.com/elastic/kibana/issues/201889

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Philippe Oberti 2025-02-11 22:11:55 +01:00 committed by GitHub
parent 6df81592ea
commit 161ce34cf7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 204 additions and 159 deletions

View file

@ -496,7 +496,6 @@ module.exports = {
/x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]timelines[\/\\]components[\/\\]timeline[\/\\]data_providers[\/\\]provider_item_actions.tsx/,
/x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]timelines[\/\\]components[\/\\]timeline[\/\\]data_providers[\/\\]providers.tsx/,
/x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]timelines[\/\\]components[\/\\]timeline[\/\\]index.tsx/,
/x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]timelines[\/\\]components[\/\\]timeline[\/\\]kpi[\/\\]kpis.tsx/,
/x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]timelines[\/\\]components[\/\\]timeline[\/\\]properties[\/\\]helpers.test.tsx/,
/x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]timelines[\/\\]components[\/\\]timeline[\/\\]properties[\/\\]helpers.tsx/,
/x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]timelines[\/\\]components[\/\\]timeline[\/\\]properties[\/\\]notes_flyout.test.tsx/,

View file

@ -5,15 +5,14 @@
* 2.0.
*/
import type { EuiTheme } from '@kbn/kibana-react-plugin/common';
import type { ColumnHeaderOptions } from '../../common/types';
import {
addBuildingBlockStyle,
hasCellActions,
mapSortDirectionToDirection,
mapSortingColumns,
addBuildingBlockStyle,
} from './helpers';
import { euiThemeVars } from '@kbn/ui-theme';
import { mockDnsEvent } from '../../mock/mock_timeline_data';
describe('helpers', () => {
@ -178,7 +177,7 @@ describe('helpers', () => {
});
describe('addBuildingBlockStyle', () => {
const THEME = { eui: euiThemeVars, darkMode: false };
const THEME = { eui: { euiColorHighlight: 'euiColorHighlight' }, darkMode: false } as EuiTheme;
test('it calls `setCellProps` with background color when event is a building block', () => {
const mockedSetCellProps = jest.fn();
@ -191,12 +190,12 @@ describe('helpers', () => {
expect(mockedSetCellProps).toBeCalledWith({
style: {
backgroundColor: euiThemeVars.euiColorHighlight,
backgroundColor: 'euiColorHighlight',
},
});
});
test('it call `setCellProps` reseting the background color when event is not a building block', () => {
test('it call `setCellProps` resetting the background color when event is not a building block', () => {
const mockedSetCellProps = jest.fn();
addBuildingBlockStyle(mockDnsEvent, THEME, mockedSetCellProps);

View file

@ -5,7 +5,6 @@
* 2.0.
*/
import { euiThemeVars } from '@kbn/ui-theme';
import type { TimelineEventsType } from '../../../../common/types';
/**
@ -22,8 +21,7 @@ import type { TimelineEventsType } from '../../../../common/types';
* `EuiButtonIcon` has a `margin-left: -4px`, which is subtracted from the
* `width`
*/
export const DEFAULT_ACTION_BUTTON_WIDTH =
parseInt(euiThemeVars.euiSizeXL, 10) - parseInt(euiThemeVars.euiSizeXS, 10); // px
export const DEFAULT_ACTION_BUTTON_WIDTH = 28; // px
export const isAlert = (eventType: TimelineEventsType | Omit<TimelineEventsType, 'all'>): boolean =>
eventType === 'signal';
@ -46,7 +44,7 @@ export const getActionsColumnWidth = (actionButtonCount: number): number => {
// `EuiDataGridRowCell` applies additional `padding-left` and
// `padding-right`, which must be added to the content width to prevent the
// content from being partially hidden due to the space occupied by padding:
const leftRightCellPadding = parseInt(euiThemeVars.euiDataGridCellPaddingM, 10) * 2; // parseInt ignores the trailing `px`, e.g. `6px`
const leftRightCellPadding = 12;
return contentWidth + leftRightCellPadding;
};

View file

@ -6,9 +6,8 @@
*/
import React, { useMemo } from 'react';
import { EuiPanel, EuiSpacer, EuiTitle } from '@elastic/eui';
import styled from '@emotion/styled';
import { euiThemeVars } from '@kbn/ui-theme';
import { EuiPanel, EuiSpacer, EuiTitle, useEuiTheme } from '@elastic/eui';
import { css } from '@emotion/react';
import { FormattedMessage } from '@kbn/i18n-react';
import { ALERT_REASON_BODY_TEST_ID } from './test_ids';
import { useAlertReasonPanelContext } from './context';
@ -16,17 +15,11 @@ import { getRowRenderer } from '../../../timelines/components/timeline/body/rend
import { defaultRowRenderers } from '../../../timelines/components/timeline/body/renderers';
import { FlyoutError } from '../../shared/components/flyout_error';
const ReasonContainerWrapper = styled.div`
overflow-x: auto;
padding-block: ${euiThemeVars.euiSizeS};
`;
const ReasonContainer = styled.div``;
/**
* Alert reason renderer on a preview panel on top of the right section of expandable flyout
*/
export const AlertReason: React.FC = () => {
const { euiTheme } = useEuiTheme();
const { dataAsNestedObject, scopeId } = useAlertReasonPanelContext();
const renderer = useMemo(
@ -65,9 +58,14 @@ export const AlertReason: React.FC = () => {
</h6>
</EuiTitle>
<EuiSpacer size="m" />
<ReasonContainerWrapper>
<ReasonContainer className={'eui-displayInlineBlock'}>{rowRenderer}</ReasonContainer>
</ReasonContainerWrapper>
<div
css={css`
overflow-x: auto;
padding-block: ${euiTheme.size.s};
`}
>
<div className={'eui-displayInlineBlock'}>{rowRenderer}</div>
</div>
</EuiPanel>
);
};

View file

@ -7,25 +7,18 @@
import type { FC } from 'react';
import React, { useMemo } from 'react';
import { EuiFlexItem, EuiTitle } from '@elastic/eui';
import styled from '@emotion/styled';
import { euiThemeVars } from '@kbn/ui-theme';
import { EuiFlexItem, EuiTitle, useEuiTheme } from '@elastic/eui';
import { css } from '@emotion/react';
import { getRowRenderer } from '../../../../timelines/components/timeline/body/renderers/get_row_renderer';
import { defaultRowRenderers } from '../../../../timelines/components/timeline/body/renderers';
import { useDocumentDetailsContext } from '../../shared/context';
import { EVENT_RENDERER_TEST_ID } from './test_ids';
const ReasonPreviewContainerWrapper = styled.div`
overflow-x: auto;
padding-block: ${euiThemeVars.euiSizeS};
`;
const ReasonPreviewContainer = styled.div``;
/**
* Event renderer of an event document
*/
export const EventRenderer: FC = () => {
const { euiTheme } = useEuiTheme();
const { dataAsNestedObject, scopeId } = useDocumentDetailsContext();
const renderer = useMemo(
@ -52,11 +45,14 @@ export const EventRenderer: FC = () => {
<EuiTitle size="xxs">
<h5>{'Event renderer'}</h5>
</EuiTitle>
<ReasonPreviewContainerWrapper>
<ReasonPreviewContainer className={'eui-displayInlineBlock'}>
{rowRenderer}
</ReasonPreviewContainer>
</ReasonPreviewContainerWrapper>
<div
css={css`
overflow-x: auto;
padding-block: ${euiTheme.size.s};
`}
>
<div className={'eui-displayInlineBlock'}>{rowRenderer}</div>
</div>
</EuiFlexItem>
);
};

View file

@ -5,17 +5,15 @@
* 2.0.
*/
import { darkMode, euiThemeVars } from '@kbn/ui-theme';
import { useEuiTheme } from '@elastic/eui';
import { useMemo } from 'react';
type ResolverColorNames =
| 'copyableFieldBackground'
| 'descriptionText'
| 'full'
| 'graphControls'
| 'graphControlsBackground'
| 'graphControlsBorderColor'
| 'linkColor'
| 'resolverBackground'
| 'resolverEdge'
| 'resolverEdgeText'
@ -29,22 +27,24 @@ type ColorMap = Record<ResolverColorNames, string>;
* Get access to Kibana-theme based colors.
*/
export function useColors(): ColorMap {
return useMemo(() => {
return {
copyableFieldBackground: euiThemeVars.euiColorLightShade,
descriptionText: euiThemeVars.euiTextColor,
full: euiThemeVars.euiColorFullShade,
graphControls: euiThemeVars.euiColorDarkestShade,
graphControlsBackground: euiThemeVars.euiColorEmptyShade,
graphControlsBorderColor: euiThemeVars.euiColorLightShade,
processBackingFill: `${euiThemeVars.euiColorPrimary}${darkMode ? '1F' : '0F'}`, // Add opacity 0F = 6% , 1F = 12%
resolverBackground: euiThemeVars.euiColorEmptyShade,
resolverEdge: darkMode ? euiThemeVars.euiColorLightShade : euiThemeVars.euiColorLightestShade,
resolverBreadcrumbBackground: euiThemeVars.euiColorLightestShade,
resolverEdgeText: darkMode ? euiThemeVars.euiColorFullShade : euiThemeVars.euiColorDarkShade,
triggerBackingFill: `${euiThemeVars.euiColorDanger}${darkMode ? '1F' : '0F'}`,
pillStroke: euiThemeVars.euiColorLightShade,
linkColor: euiThemeVars.euiLinkColor,
};
}, []);
const { euiTheme, colorMode } = useEuiTheme();
const darkMode = useMemo(() => colorMode === 'DARK', [colorMode]);
return useMemo(
() => ({
descriptionText: euiTheme.colors.textParagraph,
full: euiTheme.colors.fullShade,
graphControls: euiTheme.colors.darkestShade,
graphControlsBackground: euiTheme.colors.emptyShade,
graphControlsBorderColor: euiTheme.colors.lightShade,
processBackingFill: `${euiTheme.colors.primary}${darkMode ? '1F' : '0F'}`, // Add opacity 0F = 6% , 1F = 12%
resolverBackground: euiTheme.colors.emptyShade,
resolverEdge: darkMode ? euiTheme.colors.lightShade : euiTheme.colors.lightestShade,
resolverBreadcrumbBackground: euiTheme.colors.lightestShade,
resolverEdgeText: darkMode ? euiTheme.colors.fullShade : euiTheme.colors.darkShade,
triggerBackingFill: `${euiTheme.colors.danger}${darkMode ? '1F' : '0F'}`,
pillStroke: euiTheme.colors.lightShade,
}),
[darkMode, euiTheme]
);
}

View file

@ -6,11 +6,10 @@
*/
import { i18n } from '@kbn/i18n';
import { euiThemeVars } from '@kbn/ui-theme';
import type { EuiButtonColor } from '@elastic/eui';
import { useEuiTheme } from '@elastic/eui';
import { useMemo } from 'react';
import type { ResolverProcessType, NodeDataStatus } from '../types';
import type { NodeDataStatus, ResolverProcessType } from '../types';
import { useSymbolIDs } from './use_symbol_ids';
import { useColors } from './use_colors';
@ -22,6 +21,8 @@ export function useCubeAssets(
cubeType: NodeDataStatus,
isProcessTrigger: boolean
): NodeStyleConfig {
const { euiTheme } = useEuiTheme();
const SymbolIds = useSymbolIDs({ id });
const colorMap = useColors();
@ -36,7 +37,7 @@ export function useCubeAssets(
}),
isLabelFilled: true,
labelButtonFill: 'primary',
strokeColor: euiThemeVars.euiColorPrimary,
strokeColor: euiTheme.colors.primary,
},
loadingCube: {
backingFill: colorMap.processBackingFill,
@ -47,7 +48,7 @@ export function useCubeAssets(
}),
isLabelFilled: false,
labelButtonFill: 'primary',
strokeColor: euiThemeVars.euiColorPrimary,
strokeColor: euiTheme.colors.primary,
},
errorCube: {
backingFill: colorMap.processBackingFill,
@ -58,7 +59,7 @@ export function useCubeAssets(
}),
isLabelFilled: false,
labelButtonFill: 'primary',
strokeColor: euiThemeVars.euiColorPrimary,
strokeColor: euiTheme.colors.primary,
},
runningTriggerCube: {
backingFill: colorMap.triggerBackingFill,
@ -69,7 +70,7 @@ export function useCubeAssets(
}),
isLabelFilled: true,
labelButtonFill: 'danger',
strokeColor: euiThemeVars.euiColorDanger,
strokeColor: euiTheme.colors.danger,
},
terminatedProcessCube: {
backingFill: colorMap.processBackingFill,
@ -83,7 +84,7 @@ export function useCubeAssets(
),
isLabelFilled: false,
labelButtonFill: 'primary',
strokeColor: euiThemeVars.euiColorPrimary,
strokeColor: euiTheme.colors.primary,
},
terminatedTriggerCube: {
backingFill: colorMap.triggerBackingFill,
@ -97,10 +98,10 @@ export function useCubeAssets(
),
isLabelFilled: false,
labelButtonFill: 'danger',
strokeColor: euiThemeVars.euiColorDanger,
strokeColor: euiTheme.colors.danger,
},
}),
[SymbolIds, colorMap]
[SymbolIds, colorMap, euiTheme]
);
if (cubeType === 'terminated') {
@ -132,6 +133,7 @@ const processTypeToCube: Record<ResolverProcessType, keyof NodeStyleMap> = {
processError: 'errorCube',
unknownEvent: 'runningProcessCube',
};
interface NodeStyleMap {
runningProcessCube: NodeStyleConfig;
runningTriggerCube: NodeStyleConfig;
@ -140,6 +142,7 @@ interface NodeStyleMap {
loadingCube: NodeStyleConfig;
errorCube: NodeStyleConfig;
}
interface NodeStyleConfig {
backingFill: string;
cubeSymbol: string;

View file

@ -5,14 +5,12 @@
* 2.0.
*/
import React from 'react';
import type { EuiSuperSelectOption, EuiFormRowProps } from '@elastic/eui';
import { EuiIcon, EuiBadge, EuiButtonEmpty, EuiFormRow } from '@elastic/eui';
import styled, { css } from 'styled-components';
import { euiThemeVars } from '@kbn/ui-theme';
import React, { memo } from 'react';
import type { EuiBadgeProps, EuiFormRowProps, EuiSuperSelectOption } from '@elastic/eui';
import { EuiBadge, EuiButtonEmpty, EuiFormRow, EuiIcon, useEuiTheme } from '@elastic/eui';
import styled from 'styled-components';
import { css } from '@emotion/react';
import type { sourcererModel } from '../store';
import * as i18n from './translations';
export const FormRow = styled(EuiFormRow)<EuiFormRowProps & { $expandAdvancedOptions: boolean }>`
@ -33,6 +31,7 @@ export const StyledButtonEmpty = styled(EuiButtonEmpty)`
export const ResetButton = styled(EuiButtonEmpty)`
width: fit-content;
&:enabled:focus,
&:focus {
background-color: transparent;
@ -43,23 +42,54 @@ export const PopoverContent = styled.div`
width: 600px;
`;
export const StyledBadge = styled(EuiBadge)`
margin-left: ${euiThemeVars.euiSizeXS};
&,
.euiBadge__text {
cursor: pointer;
}
`;
interface StyledBadgeProps {
color?: EuiBadgeProps['color'];
children: React.ReactNode;
'data-test-subj'?: string;
}
export const Blockquote = styled.span`
${({ theme }) => css`
display: block;
border-color: ${theme.eui.euiColorDarkShade};
border-left: ${theme.eui.euiBorderThick};
margin: ${theme.eui.euiSizeS} 0 ${theme.eui.euiSizeS} ${theme.eui.euiSizeS};
padding: ${theme.eui.euiSizeS};
`}
`;
export const StyledBadge = memo(
({ color, children, 'data-test-subj': dataTestSubj }: StyledBadgeProps) => {
const { euiTheme } = useEuiTheme();
return (
<EuiBadge
color={color}
data-test-subj={dataTestSubj}
css={css`
margin-left: ${euiTheme.size.xs};
&,
.euiBadge__text {
cursor: pointer;
}
`}
>
{children}
</EuiBadge>
);
}
);
StyledBadge.displayName = 'StyledBadge';
export const Blockquote = memo(({ children }: { children: React.ReactNode }) => {
const { euiTheme } = useEuiTheme();
return (
<span
css={css`
display: block;
border-color: ${euiTheme.colors.darkShade};
border-left: ${euiTheme.border.thick};
margin: ${euiTheme.size.s} 0 ${euiTheme.size.s} ${euiTheme.size.s};
padding: ${euiTheme.size.s};
`}
>
{children}
</span>
);
});
Blockquote.displayName = 'Blockquote';
interface GetDataViewSelectOptionsProps {
dataViewId: string;

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import React, { useMemo, useEffect, useRef, useLayoutEffect } from 'react';
import React, { useEffect, useLayoutEffect, useMemo, useRef } from 'react';
import {
EuiFlexGroup,
EuiFlexItem,
@ -13,7 +13,6 @@ import {
EuiLoadingSpinner,
EuiSpacer,
} from '@elastic/eui';
import { euiThemeVars } from '@kbn/ui-theme';
import { useDispatch } from 'react-redux';
import styled, { css } from 'styled-components';
import { dataTableSelectors, tableDefaults } from '@kbn/securitysolution-data-table';
@ -50,13 +49,13 @@ const OverlayContainer = styled.div`
`;
const FullScreenOverlayStyles = css`
background-color: ${({ theme }) => `${theme.eui.euiColorEmptyShade};`}
background-color: ${({ theme }) => `${theme.eui.euiColorEmptyShade};`}
position: fixed;
top: 0;
bottom: 2em;
left: 0;
right: 0;
z-index: ${euiThemeVars.euiZLevel3};
z-index: 3000;
`;
const FullScreenOverlayContainer = styled.div`
@ -71,6 +70,7 @@ const ScrollableFlexItem = styled(EuiFlexItem)`
${({ theme }) => `background-color: ${theme.eui.euiColorEmptyShade};`}
overflow: hidden;
width: 100%;
&.${SESSION_VIEW_FULL_SCREEN} {
${({ theme }) => `padding: 0 ${theme.eui.euiSizeM}`}
}

View file

@ -5,31 +5,41 @@
* 2.0.
*/
import React, { useMemo } from 'react';
import styled from 'styled-components';
import { EuiFlexItem, EuiFlexGroup, EuiToolTip, EuiBadge } from '@elastic/eui';
import React, { memo, useMemo } from 'react';
import { css } from '@emotion/react';
import { EuiBadge, EuiFlexGroup, EuiFlexItem, EuiToolTip, useEuiTheme } from '@elastic/eui';
import numeral from '@elastic/numeral';
import { euiThemeVars } from '@kbn/ui-theme';
import { DEFAULT_NUMBER_FORMAT } from '../../../../../common/constants';
import { useUiSetting$ } from '../../../../common/lib/kibana';
import type { TimelineKpiStrategyResponse } from '../../../../../common/search_strategy';
import { getEmptyValue } from '../../../../common/components/empty_value';
import * as i18n from './translations';
export const StatsContainer = styled.span`
font-size: ${euiThemeVars.euiFontSizeXS};
font-weight: ${euiThemeVars.euiFontWeightSemiBold};
padding-right: 16px;
.smallDot {
width: 3px !important;
display: inline-block;
}
.euiBadge__text {
text-align: center;
width: 100%;
}
`;
export const StatsContainer = memo(({ children }: { children: React.ReactNode }) => {
const { euiTheme } = useEuiTheme();
return (
<span
css={css`
font-size: ${euiTheme.font.scale.xs};
font-weight: ${euiTheme.font.weight.semiBold};
padding-right: ${euiTheme.size.base};
.smallDot {
width: 3px !important;
display: inline-block;
}
.euiBadge__text {
text-align: center;
width: 100%;
}
`}
>
{children}
</span>
);
});
StatsContainer.displayName = 'StatsContainer';
export const TimelineKPIs = React.memo(({ kpis }: { kpis: TimelineKpiStrategyResponse | null }) => {
const kpiFormat = '0,0.[000]a';

View file

@ -5,13 +5,12 @@
* 2.0.
*/
import { EuiCallOut, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { EuiCallOut, EuiFlexGroup, EuiFlexItem, useEuiTheme } from '@elastic/eui';
import React, { useMemo } from 'react';
import type { FilterManager } from '@kbn/data-plugin/public';
import { InPortal } from 'react-reverse-portal';
import { IS_DRAGGING_CLASS_NAME } from '@kbn/securitysolution-t-grid';
import styled from '@emotion/styled';
import { euiThemeVars } from '@kbn/ui-theme';
import { css } from '@emotion/react';
import { useTimelineEventsCountPortal } from '../../../../../../common/hooks/use_timeline_events_count';
import {
type TimelineStatus,
@ -25,7 +24,7 @@ import { timelineDefaults } from '../../../../../store/defaults';
import * as i18n from './translations';
import { StatefulSearchOrFilter } from '../../../search_or_filter';
import { DataProviders } from '../../../data_providers';
import { StyledEuiFlyoutHeader, EventsCountBadge, TabHeaderContainer } from '../../shared/layout';
import { EventsCountBadge, StyledEuiFlyoutHeader, TabHeaderContainer } from '../../shared/layout';
interface Props {
activeTab: TimelineTabs;
@ -38,24 +37,27 @@ interface Props {
totalCount: number;
}
const DataProvidersContainer = styled.div<{ $shouldShowQueryBuilder: boolean }>`
position: relative;
width: 100%;
transition: 0.5s ease-in-out;
overflow: hidden;
const useStyles = (shouldShowQueryBuilder: boolean) => {
const { euiTheme } = useEuiTheme();
${(props) =>
props.$shouldShowQueryBuilder
? `display: block; max-height: 300px; visibility: visible; margin-block-start: 0px;`
: `display: block; max-height: 0px; visibility: hidden; margin-block-start:-${euiThemeVars.euiSizeS};`}
.${IS_DRAGGING_CLASS_NAME} & {
return css`
position: relative;
width: 100%;
transition: 0.5s ease-in-out;
overflow: hidden;
display: block;
max-height: 300px;
visibility: visible;
margin-block-start: 0px;
}
`;
max-height: ${shouldShowQueryBuilder ? '300px' : '0'};
visibility: ${shouldShowQueryBuilder ? 'visible' : 'hidden'};
margin-block-start: ${shouldShowQueryBuilder ? '0' : -euiTheme.size.s};
. ${IS_DRAGGING_CLASS_NAME} & {
display: block;
max-height: 300px;
visibility: visible;
margin-block-start: 0;
}
`;
};
const QueryTabHeaderComponent: React.FC<Props> = ({
activeTab,
@ -78,13 +80,14 @@ const QueryTabHeaderComponent: React.FC<Props> = ({
const timelineType = useDeepEqualSelector(
(state) => (getTimeline(state, timelineId) ?? timelineDefaults).timelineType
);
const isDataProviderVisible = useDeepEqualSelector(
(state) => getIsDataProviderVisible(state, timelineId) ?? timelineDefaults.isDataProviderVisible
);
const shouldShowQueryBuilder =
isDataProviderVisible || timelineType === TimelineTypeEnum.template;
const shouldShowQueryBuilder = useMemo(
() => isDataProviderVisible || timelineType === TimelineTypeEnum.template,
[isDataProviderVisible, timelineType]
);
const dataProviderStyles = useStyles(shouldShowQueryBuilder);
return (
<StyledEuiFlyoutHeader data-test-subj={`${activeTab}-tab-flyout-header`} hasBorder={false}>
@ -123,12 +126,9 @@ const QueryTabHeaderComponent: React.FC<Props> = ({
</EuiFlexItem>
)}
{show ? (
<DataProvidersContainer
className="data-providers-container"
$shouldShowQueryBuilder={shouldShowQueryBuilder}
>
<div css={dataProviderStyles} className="data-providers-container">
<DataProviders timelineId={timelineId} />
</DataProvidersContainer>
</div>
) : null}
</EuiFlexGroup>
</TabHeaderContainer>

View file

@ -5,10 +5,9 @@
* 2.0.
*/
import type { EuiDataGridProps } from '@elastic/eui';
import { EuiFlexGroup, EuiFlexItem, EuiHideFor } from '@elastic/eui';
import React, { useMemo, useCallback, useState, useRef, useEffect } from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiHideFor, useEuiTheme } from '@elastic/eui';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useDispatch } from 'react-redux';
import { generateFilters } from '@kbn/data-plugin/public';
import type { DataView, DataViewField } from '@kbn/data-plugin/common';
import type { SortOrder } from '@kbn/saved-search-plugin/public';
@ -16,8 +15,9 @@ import type { DataLoadingState, UnifiedDataTableProps } from '@kbn/unified-data-
import { useColumns } from '@kbn/unified-data-table';
import { popularizeField } from '@kbn/unified-data-table/src/utils/popularize_field';
import type { DropType } from '@kbn/dom-drag-drop';
import { DropOverlayWrapper, Droppable, useDragDropContext } from '@kbn/dom-drag-drop';
import styled from 'styled-components';
import { Droppable, DropOverlayWrapper, useDragDropContext } from '@kbn/dom-drag-drop';
import { css } from '@emotion/react';
import type {
UnifiedFieldListSidebarContainerApi,
UnifiedFieldListSidebarContainerProps,
@ -40,7 +40,7 @@ import type {
} from '../../../../../common/types/timeline';
import type { inputsModel } from '../../../../common/store';
import { getColumnHeader } from '../body/column_headers/helpers';
import { StyledPageContentWrapper, StyledMainEuiPanel, StyledSplitFlexItem } from './styles';
import { StyledMainEuiPanel, StyledPageContentWrapper } from './styles';
import { DRAG_DROP_FIELD } from './data_table/translations';
import { TimelineResizableLayout } from './resizable_layout';
import TimelineDataTable from './data_table';
@ -81,6 +81,7 @@ const SidebarPanelFlexGroup = styled(EuiFlexGroup)`
.euiFlexItem:last-child {
/* padding-right: ${(props) => (props.theme as EuiTheme).eui.euiSizeS}; */
}
.unifiedFieldListSidebar__list {
padding-left: 0px;
}
@ -138,6 +139,7 @@ const UnifiedTimelineComponent: React.FC<Props> = ({
leadingControlColumns,
onUpdatePageIndex,
}) => {
const { euiTheme } = useEuiTheme();
const dispatch = useDispatch();
const unifiedFieldListContainerRef = useRef<UnifiedFieldListSidebarContainerApi>(null);
@ -397,7 +399,12 @@ const UnifiedTimelineComponent: React.FC<Props> = ({
) : null}
</EuiFlexItem>
<EuiHideFor sizes={HIDE_FOR_SIZES}>
<StyledSplitFlexItem grow={false} className="thinBorderSplit" />
<EuiFlexItem
grow={false}
css={css`
border-right: ${euiTheme.border.thin};
`}
/>
</EuiHideFor>
</SidebarPanelFlexGroup>
}

View file

@ -7,7 +7,6 @@
import styled, { createGlobalStyle } from 'styled-components';
import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiProgress } from '@elastic/eui';
import { euiThemeVars } from '@kbn/ui-theme';
export const StyledTableFlexGroup = styled(EuiFlexGroup).attrs(({ className = '' }) => ({
className: `${className}`,
@ -29,12 +28,6 @@ export const StyledUnifiedTableFlexItem = styled(EuiFlexItem).attrs(({ className
overflow: hidden;
`;
export const StyledSplitFlexItem = styled(EuiFlexItem).attrs(({ className = '' }) => ({
className: `${className}`,
}))`
border-right: ${euiThemeVars.euiBorderThin};
`;
export const StyledEuiProgress = styled(EuiProgress)`
z-index: 2;
`;
@ -74,16 +67,19 @@ export const StyledTimelineUnifiedDataTable = styled.div.attrs(({ className = ''
.udtTimeline [data-gridcell-column-id|='select'] {
border-right: none;
}
.udtTimeline [data-gridcell-column-id|='openDetails'] {
/* custom row height based on number of lines */
.euiDataGridRowCell__content--lineCountHeight,
/* auto row height */
/* auto row height */
.euiDataGridRowCell__content--autoHeight {
margin-top: 9px;
}
/* single row height */
.euiDataGridRowCell__content--defaultHeight {
margin-top: 3px;
}
@ -103,14 +99,16 @@ export const StyledTimelineUnifiedDataTable = styled.div.attrs(({ className = ''
.udtTimeline [data-gridcell-column-id|='select'] {
/* custom row height based on number of lines */
.euiDataGridRowCell__content--lineCountHeight,
/* auto row height */
/* auto row height */
.euiDataGridRowCell__content--autoHeight {
margin-top: 6px;
}
/* single row height */
.euiDataGridRowCell__content--defaultHeight {
margin-top: 3px;
}
@ -142,12 +140,14 @@ export const StyledTimelineUnifiedDataTable = styled.div.attrs(({ className = ''
rgba(245, 167, 0, 0.05) 10px
);
}
.udtTimeline .euiDataGridRow:has(.eqlSequence),
.udtTimeline .euiDataGridRow.eqlSequence {
.euiDataGridRowCell--controlColumn.euiDataGridRowCell--lastColumn,
.udt--customRow {
${({ theme }) => `border-left: 4px solid ${theme.eui.euiColorPrimary}`};
}
background: repeating-linear-gradient(
127deg,
rgba(0, 107, 180, 0.2),
@ -156,12 +156,14 @@ export const StyledTimelineUnifiedDataTable = styled.div.attrs(({ className = ''
rgba(0, 107, 180, 0.05) 10px
);
}
.udtTimeline .euiDataGridRow:has(.eqlNonSequence),
.udtTimeline .euiDataGridRow.eqlNonSequence {
.euiDataGridRowCell--controlColumn.euiDataGridRowCell--lastColumn,
.udt--customRow {
${({ theme }) => `border-left: 4px solid ${theme.eui.euiColorAccent};`}
}
background: repeating-linear-gradient(
127deg,
rgba(221, 10, 115, 0.2),
@ -170,6 +172,7 @@ export const StyledTimelineUnifiedDataTable = styled.div.attrs(({ className = ''
rgba(221, 10, 115, 0.05) 10px
);
}
.udtTimeline .euiDataGridRow:has(.nonRawEvent),
.udtTimeline .euiDataGridRow.nonRawEvent {
.euiDataGridRowCell--controlColumn.euiDataGridRowCell--lastColumn,
@ -177,6 +180,7 @@ export const StyledTimelineUnifiedDataTable = styled.div.attrs(({ className = ''
${({ theme }) => `border-left: 4px solid ${theme.eui.euiColorWarning};`}
}
}
.udtTimeline .euiDataGridRow:has(.rawEvent),
.udtTimeline .euiDataGridRow.rawEvent {
.euiDataGridRowCell--controlColumn.euiDataGridRowCell--lastColumn,
@ -193,6 +197,7 @@ export const StyledTimelineUnifiedDataTable = styled.div.attrs(({ className = ''
.udtTimeline .rightPosition {
position: absolute;
right: 5px;
button {
${({ theme }) => `color: ${theme.eui.euiColorDarkShade};`}
}