From 4632f3ef8597d44444382728a8b0abe6979d2c24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez?= Date: Tue, 31 Mar 2020 13:12:44 +0200 Subject: [PATCH] [Logs UI] Log stream row rendering (#60773) --- .../log_entry_actions_column.tsx | 98 +++++++++++++++++++ .../log_entry_field_column.test.tsx | 6 -- .../log_entry_field_column.tsx | 14 +-- .../log_text_stream/log_entry_icon_column.tsx | 67 ------------- .../log_entry_message_column.tsx | 15 +-- .../logging/log_text_stream/log_entry_row.tsx | 40 ++++---- .../log_entry_timestamp_column.tsx | 34 +------ .../logging/log_text_stream/text_styles.tsx | 10 +- .../category_example_message.tsx | 11 +-- .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - 11 files changed, 131 insertions(+), 166 deletions(-) create mode 100644 x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_actions_column.tsx delete mode 100644 x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_icon_column.tsx diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_actions_column.tsx b/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_actions_column.tsx new file mode 100644 index 0000000000000..e02346c4e758a --- /dev/null +++ b/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_actions_column.tsx @@ -0,0 +1,98 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useCallback } from 'react'; +import { EuiButtonIcon } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; + +import { LogEntryColumnContent } from './log_entry_column'; +import { + euiStyled, + ActionMenu, + Section, + SectionTitle, + SectionLinks, + SectionLink, +} from '../../../../../observability/public'; + +interface LogEntryActionsColumnProps { + isHovered: boolean; + isMenuOpen: boolean; + onOpenMenu: () => void; + onCloseMenu: () => void; + onViewDetails: () => void; +} + +const MENU_LABEL = i18n.translate('xpack.infra.logEntryItemView.logEntryActionsMenuToolTip', { + defaultMessage: 'View Details', +}); + +const LOG_DETAILS_LABEL = i18n.translate('xpack.infra.logs.logEntryActionsDetailsButton', { + defaultMessage: 'View actions for line', +}); + +export const LogEntryActionsColumn: React.FC = ({ + isHovered, + isMenuOpen, + onOpenMenu, + onCloseMenu, + onViewDetails, +}) => { + const handleClickViewDetails = useCallback(() => { + onCloseMenu(); + onViewDetails(); + }, [onCloseMenu, onViewDetails]); + + const button = ( + + + + ); + + return ( + + {isHovered || isMenuOpen ? ( + + +
+ + + + + + +
+
+
+ ) : null} +
+ ); +}; + +const ActionsColumnContent = euiStyled(LogEntryColumnContent)` + overflow: hidden; + user-select: none; +`; + +const ButtonWrapper = euiStyled.div` + background: ${props => props.theme.eui.euiColorPrimary}; + border-radius: 50%; +`; + +// this prevents the button from influencing the line height +const AbsoluteWrapper = euiStyled.div` + overflow: hidden; + position: absolute; +`; diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_field_column.test.tsx b/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_field_column.test.tsx index 5fc4606a774d5..d6068b6e60992 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_field_column.test.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_field_column.test.tsx @@ -25,8 +25,6 @@ describe('LogEntryFieldColumn', () => { columnValue={column} highlights={[]} isActiveHighlight={false} - isHighlighted={false} - isHovered={false} wrapMode="pre-wrapped" />, { wrappingComponent: EuiThemeProvider } as any // https://github.com/DefinitelyTyped/DefinitelyTyped/issues/36075 @@ -58,8 +56,6 @@ describe('LogEntryFieldColumn', () => { columnValue={column} highlights={[]} isActiveHighlight={false} - isHighlighted={false} - isHovered={false} wrapMode="pre-wrapped" />, { wrappingComponent: EuiThemeProvider } as any // https://github.com/DefinitelyTyped/DefinitelyTyped/issues/36075 @@ -81,8 +77,6 @@ describe('LogEntryFieldColumn', () => { columnValue={column} highlights={[]} isActiveHighlight={false} - isHighlighted={false} - isHovered={false} wrapMode="pre-wrapped" />, { wrappingComponent: EuiThemeProvider } as any // https://github.com/DefinitelyTyped/DefinitelyTyped/issues/36075 diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_field_column.tsx b/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_field_column.tsx index 202108cda5ac0..c73c9674f9683 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_field_column.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_field_column.tsx @@ -13,7 +13,6 @@ import { ActiveHighlightMarker, highlightFieldValue, HighlightMarker } from './h import { LogEntryColumnContent } from './log_entry_column'; import { LogColumn } from '../../../../common/http_api'; import { - hoveredContentStyle, longWrappedContentStyle, preWrappedContentStyle, unwrappedContentStyle, @@ -24,8 +23,6 @@ interface LogEntryFieldColumnProps { columnValue: LogColumn; highlights: LogColumn[]; isActiveHighlight: boolean; - isHighlighted: boolean; - isHovered: boolean; wrapMode: WrapMode; } @@ -33,8 +30,6 @@ export const LogEntryFieldColumn: React.FunctionComponent { const value = useMemo(() => { @@ -63,11 +58,7 @@ export const LogEntryFieldColumn: React.FunctionComponent - {formattedValue} - - ); + return {formattedValue}; }; const CommaSeparatedLi = euiStyled.li` @@ -81,15 +72,12 @@ const CommaSeparatedLi = euiStyled.li` `; interface LogEntryColumnContentProps { - isHighlighted: boolean; - isHovered: boolean; wrapMode: WrapMode; } const FieldColumnContent = euiStyled(LogEntryColumnContent)` text-overflow: ellipsis; - ${props => (props.isHovered || props.isHighlighted ? hoveredContentStyle : '')}; ${props => props.wrapMode === 'long' ? longWrappedContentStyle diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_icon_column.tsx b/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_icon_column.tsx deleted file mode 100644 index a4099cdf5a1fb..0000000000000 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_icon_column.tsx +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { EuiButtonIcon } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import React from 'react'; - -import { LogEntryColumnContent } from './log_entry_column'; -import { hoveredContentStyle } from './text_styles'; -import { euiStyled } from '../../../../../observability/public'; - -interface LogEntryIconColumnProps { - isHighlighted: boolean; - isHovered: boolean; -} - -export const LogEntryIconColumn: React.FunctionComponent = ({ - children, - isHighlighted, - isHovered, -}) => { - return ( - - {children} - - ); -}; - -export const LogEntryDetailsIconColumn: React.FunctionComponent void; -}> = ({ isHighlighted, isHovered, openFlyout }) => { - const label = i18n.translate('xpack.infra.logEntryItemView.viewDetailsToolTip', { - defaultMessage: 'View Details', - }); - - return ( - - {isHovered ? ( - - - - ) : null} - - ); -}; - -interface IconColumnContentProps { - isHighlighted: boolean; - isHovered: boolean; -} - -const IconColumnContent = euiStyled(LogEntryColumnContent)` - background-color: ${props => props.theme.eui.euiColorEmptyShade}; - overflow: hidden; - user-select: none; - - ${props => (props.isHovered || props.isHighlighted ? hoveredContentStyle : '')}; -`; - -// this prevents the button from influencing the line height -const AbsoluteIconButtonWrapper = euiStyled.div` - overflow: hidden; - position: absolute; -`; diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_message_column.tsx b/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_message_column.tsx index 5ad7cba6427d1..0fe0cbdfac593 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_message_column.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_message_column.tsx @@ -18,7 +18,6 @@ import { import { ActiveHighlightMarker, highlightFieldValue, HighlightMarker } from './highlighting'; import { LogEntryColumnContent } from './log_entry_column'; import { - hoveredContentStyle, longWrappedContentStyle, preWrappedContentStyle, unwrappedContentStyle, @@ -30,13 +29,11 @@ interface LogEntryMessageColumnProps { columnValue: LogColumn; highlights: LogColumn[]; isActiveHighlight: boolean; - isHighlighted: boolean; - isHovered: boolean; wrapMode: WrapMode; } export const LogEntryMessageColumn = memo( - ({ columnValue, highlights, isActiveHighlight, isHighlighted, isHovered, wrapMode }) => { + ({ columnValue, highlights, isActiveHighlight, wrapMode }) => { const message = useMemo( () => isMessageColumn(columnValue) @@ -45,24 +42,16 @@ export const LogEntryMessageColumn = memo( [columnValue, highlights, isActiveHighlight] ); - return ( - - {message} - - ); + return {message}; } ); interface MessageColumnContentProps { - isHovered: boolean; - isHighlighted: boolean; wrapMode: WrapMode; } const MessageColumnContent = euiStyled(LogEntryColumnContent)` text-overflow: ellipsis; - - ${props => (props.isHovered || props.isHighlighted ? hoveredContentStyle : '')}; ${props => props.wrapMode === 'long' ? longWrappedContentStyle diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_row.tsx b/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_row.tsx index ce264245d385b..7d7df796d13ad 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_row.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_row.tsx @@ -17,10 +17,10 @@ import { import { TextScale } from '../../../../common/log_text_scale'; import { LogEntryColumn, LogEntryColumnWidths, iconColumnId } from './log_entry_column'; import { LogEntryFieldColumn } from './log_entry_field_column'; -import { LogEntryDetailsIconColumn } from './log_entry_icon_column'; +import { LogEntryActionsColumn } from './log_entry_actions_column'; import { LogEntryMessageColumn } from './log_entry_message_column'; import { LogEntryTimestampColumn } from './log_entry_timestamp_column'; -import { monospaceTextStyle } from './text_styles'; +import { monospaceTextStyle, hoveredContentStyle, highlightedContentStyle } from './text_styles'; import { LogEntry, LogColumn } from '../../../../common/http_api'; interface LogEntryRowProps { @@ -50,14 +50,13 @@ export const LogEntryRow = memo( wrap, }: LogEntryRowProps) => { const [isHovered, setIsHovered] = useState(false); + const [isMenuOpen, setIsMenuOpen] = useState(false); - const setItemIsHovered = useCallback(() => { - setIsHovered(true); - }, []); + const openMenu = useCallback(() => setIsMenuOpen(true), []); + const closeMenu = useCallback(() => setIsMenuOpen(false), []); - const setItemIsNotHovered = useCallback(() => { - setIsHovered(false); - }, []); + const setItemIsHovered = useCallback(() => setIsHovered(true), []); + const setItemIsNotHovered = useCallback(() => setIsHovered(false), []); const openFlyout = useCallback(() => openFlyoutWithItem?.(logEntry.id), [ openFlyoutWithItem, @@ -105,6 +104,7 @@ export const LogEntryRow = memo( } onMouseEnter={setItemIsHovered} onMouseLeave={setItemIsNotHovered} + isHighlighted={isHighlighted} scale={scale} > {columnConfigurations.map(columnConfiguration => { @@ -119,11 +119,7 @@ export const LogEntryRow = memo( {...columnWidth} > {isTimestampColumn(column) ? ( - + ) : null} ); @@ -141,9 +137,7 @@ export const LogEntryRow = memo( ) : null} @@ -164,8 +158,6 @@ export const LogEntryRow = memo( columnValue={column} highlights={highlightsByColumnId[column.columnId] || []} isActiveHighlight={isActiveHighlight} - isHighlighted={isHighlighted} - isHovered={isHovered} wrapMode={wrap ? 'long' : 'pre-wrapped'} /> ) : null} @@ -177,10 +169,12 @@ export const LogEntryRow = memo( key="logColumn iconLogColumn iconLogColumn:details" {...columnWidths[iconColumnId]} > - @@ -190,6 +184,7 @@ export const LogEntryRow = memo( interface LogEntryRowWrapperProps { scale: TextScale; + isHighlighted?: boolean; } export const LogEntryRowWrapper = euiStyled.div.attrs(() => ({ @@ -204,4 +199,9 @@ export const LogEntryRowWrapper = euiStyled.div.attrs(() => ({ overflow: hidden; ${props => monospaceTextStyle(props.scale)}; + ${props => (props.isHighlighted ? highlightedContentStyle : '')} + + &:hover { + ${hoveredContentStyle} + } `; diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_timestamp_column.tsx b/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_timestamp_column.tsx index f3ea9c81108c6..cf9c75a361b55 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_timestamp_column.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_timestamp_column.tsx @@ -4,54 +4,28 @@ * you may not use this file except in compliance with the Elastic License. */ -import { darken, transparentize } from 'polished'; import React, { memo } from 'react'; -import { euiStyled, css } from '../../../../../observability/public'; +import { euiStyled } from '../../../../../observability/public'; import { TimeFormat, useFormattedTime } from '../../formatted_time'; import { LogEntryColumnContent } from './log_entry_column'; interface LogEntryTimestampColumnProps { format?: TimeFormat; - isHighlighted: boolean; - isHovered: boolean; time: number; } export const LogEntryTimestampColumn = memo( - ({ format = 'time', isHighlighted, isHovered, time }) => { + ({ format = 'time', time }) => { const formattedTime = useFormattedTime(time, { format }); - return ( - - {formattedTime} - - ); + return {formattedTime}; } ); -const hoveredContentStyle = css` - background-color: ${props => - props.theme.darkMode - ? transparentize(0.9, darken(0.05, props.theme.eui.euiColorHighlight)) - : darken(0.05, props.theme.eui.euiColorHighlight)}; - border-color: ${props => - props.theme.darkMode - ? transparentize(0.7, darken(0.2, props.theme.eui.euiColorHighlight)) - : darken(0.2, props.theme.eui.euiColorHighlight)}; - color: ${props => props.theme.eui.euiColorFullShade}; -`; - -interface TimestampColumnContentProps { - isHovered: boolean; - isHighlighted: boolean; -} - -const TimestampColumnContent = euiStyled(LogEntryColumnContent)` +const TimestampColumnContent = euiStyled(LogEntryColumnContent)` color: ${props => props.theme.eui.euiColorDarkShade}; overflow: hidden; text-overflow: clip; white-space: pre; - - ${props => (props.isHovered || props.isHighlighted ? hoveredContentStyle : '')}; `; diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/text_styles.tsx b/x-pack/plugins/infra/public/components/logging/log_text_stream/text_styles.tsx index 434258343eefb..69a6abbca4b34 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/text_styles.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_text_stream/text_styles.tsx @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { darken, transparentize } from 'polished'; import React, { useMemo, useState, useCallback } from 'react'; import { euiStyled, css } from '../../../../../observability/public'; @@ -30,10 +29,11 @@ export const monospaceTextStyle = (scale: TextScale) => css` `; export const hoveredContentStyle = css` - background-color: ${props => - props.theme.darkMode - ? transparentize(0.9, darken(0.05, props.theme.eui.euiColorHighlight)) - : darken(0.05, props.theme.eui.euiColorHighlight)}; + background-color: ${props => props.theme.eui.euiFocusBackgroundColor}; +`; + +export const highlightedContentStyle = css` + background-color: ${props => props.theme.eui.euiFocusBackgroundColor}; `; export const longWrappedContentStyle = css` diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_example_message.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_example_message.tsx index 023082154565c..3855706bb6d47 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_example_message.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_example_message.tsx @@ -34,12 +34,7 @@ export const CategoryExampleMessage: React.FunctionComponent<{ return ( - + @@ -63,8 +56,6 @@ export const CategoryExampleMessage: React.FunctionComponent<{ highlights: [], }} highlights={noHighlights} - isHovered={false} - isHighlighted={false} isActiveHighlight={false} wrapMode="none" /> diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 1f7a1294fe786..ccfb2707a51b9 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -6303,7 +6303,6 @@ "xpack.infra.logEntryActionsMenu.apmActionLabel": "APMで表示", "xpack.infra.logEntryActionsMenu.buttonLabel": "アクション", "xpack.infra.logEntryActionsMenu.uptimeActionLabel": "監視ステータスを表示", - "xpack.infra.logEntryItemView.viewDetailsToolTip": "詳細を表示", "xpack.infra.logFlyout.fieldColumnLabel": "フィールド", "xpack.infra.logFlyout.filterAriaLabel": "フィルター", "xpack.infra.logFlyout.flyoutTitle": "ログイベントドキュメントの詳細", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index f93216662ca7c..06eb805d5af0e 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -6303,7 +6303,6 @@ "xpack.infra.logEntryActionsMenu.apmActionLabel": "在 APM 中查看", "xpack.infra.logEntryActionsMenu.buttonLabel": "操作", "xpack.infra.logEntryActionsMenu.uptimeActionLabel": "查看监测状态", - "xpack.infra.logEntryItemView.viewDetailsToolTip": "查看详情", "xpack.infra.logFlyout.fieldColumnLabel": "字段", "xpack.infra.logFlyout.filterAriaLabel": "筛选", "xpack.infra.logFlyout.flyoutTitle": "日志事件文档详情",