Design cleanup details panel (#85044)
* cleanup overlay panel. fixed sizes, variable panel height, responsive breakpoint * cleanup metrics tab. use EuiFlexGrid + ChartSizeArray for chart sizing + fixed responsive issues on flex items * cleanup metadata tab. disabled responsive table and fixed alignment of filter icon + value * cleanup logs search. adjusted button size + spacing * fix responsivness on array values * remove responsive behavior on search + view-in-logs button * fix typecheck
This commit is contained in:
parent
c85f2545da
commit
c6ef1ae30b
|
@ -4,9 +4,9 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { EuiPortal, EuiTabs, EuiTab, EuiPanel, EuiTitle } from '@elastic/eui';
|
||||
import { EuiPortal, EuiTabs, EuiTab, EuiPanel, EuiTitle, EuiSpacer } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import React, { CSSProperties, useMemo, useState } from 'react';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiButtonEmpty } from '@elastic/eui';
|
||||
import { euiStyled } from '../../../../../../../observability/public';
|
||||
import { InfraWaffleMapNode, InfraWaffleMapOptions } from '../../../../../lib/lib';
|
||||
|
@ -15,7 +15,7 @@ import { MetricsTab } from './tabs/metrics/metrics';
|
|||
import { LogsTab } from './tabs/logs';
|
||||
import { ProcessesTab } from './tabs/processes';
|
||||
import { PropertiesTab } from './tabs/properties/index';
|
||||
import { OVERLAY_Y_START, OVERLAY_BOTTOM_MARGIN, OVERLAY_HEADER_SIZE } from './tabs/shared';
|
||||
import { OVERLAY_Y_START, OVERLAY_BOTTOM_MARGIN } from './tabs/shared';
|
||||
import { useLinkProps } from '../../../../../hooks/use_link_props';
|
||||
import { getNodeDetailUrl } from '../../../../link_to';
|
||||
import { findInventoryModel } from '../../../../../../common/inventory_models';
|
||||
|
@ -70,21 +70,23 @@ export const NodeContextPopover = ({
|
|||
|
||||
return (
|
||||
<EuiPortal>
|
||||
<EuiPanel hasShadow={true} paddingSize={'none'} style={panelStyle}>
|
||||
<OverlayPanel>
|
||||
<OverlayHeader>
|
||||
<OverlayHeaderTitleWrapper>
|
||||
<EuiFlexGroup responsive={false} gutterSize="m">
|
||||
<EuiFlexItem grow={true}>
|
||||
<EuiTitle size="s">
|
||||
<EuiTitle size="xs">
|
||||
<h4>{node.name}</h4>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFlexGroup gutterSize={'xs'} alignItems={'flexEnd'}>
|
||||
<EuiFlexGroup gutterSize="m" responsive={false}>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButtonEmpty
|
||||
size="xs"
|
||||
iconSide={'left'}
|
||||
iconType={'popout'}
|
||||
href={nodeDetailMenuItemLinkProps.href}
|
||||
flush="both"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.infra.infra.nodeDetails.openAsPage"
|
||||
|
@ -93,7 +95,7 @@ export const NodeContextPopover = ({
|
|||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButtonEmpty onClick={onClose} iconType={'cross'}>
|
||||
<EuiButtonEmpty size="xs" onClick={onClose} iconType="cross" flush="both">
|
||||
<FormattedMessage
|
||||
id="xpack.infra.infra.nodeDetails.close"
|
||||
defaultMessage="Close"
|
||||
|
@ -102,8 +104,9 @@ export const NodeContextPopover = ({
|
|||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</OverlayHeaderTitleWrapper>
|
||||
<EuiTabs>
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiTabs size="s">
|
||||
{tabs.map((tab, i) => (
|
||||
<EuiTab key={tab.id} isSelected={i === selectedTab} onClick={() => setSelectedTab(i)}>
|
||||
{tab.name}
|
||||
|
@ -112,32 +115,38 @@ export const NodeContextPopover = ({
|
|||
</EuiTabs>
|
||||
</OverlayHeader>
|
||||
{tabs[selectedTab].content}
|
||||
</EuiPanel>
|
||||
</OverlayPanel>
|
||||
</EuiPortal>
|
||||
);
|
||||
};
|
||||
|
||||
const OverlayHeader = euiStyled.div`
|
||||
border-color: ${(props) => props.theme.eui.euiBorderColor};
|
||||
border-bottom-width: ${(props) => props.theme.eui.euiBorderWidthThick};
|
||||
padding-bottom: 0;
|
||||
padding-top: ${(props) => props.theme.eui.paddingSizes.m};
|
||||
padding-right: ${(props) => props.theme.eui.paddingSizes.m};
|
||||
padding-left: ${(props) => props.theme.eui.paddingSizes.m};
|
||||
background-color: ${(props) => props.theme.eui.euiPageBackgroundColor};
|
||||
box-shadow: inset 0 -1px ${(props) => props.theme.eui.euiBorderColor};
|
||||
`;
|
||||
|
||||
const OverlayPanel = euiStyled(EuiPanel).attrs({ paddingSize: 'none' })`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
top: ${OVERLAY_Y_START}px;
|
||||
width: 100%;
|
||||
max-width: 720px;
|
||||
z-index: 2;
|
||||
max-height: calc(100vh - ${OVERLAY_Y_START + OVERLAY_BOTTOM_MARGIN}px);
|
||||
overflow: hidden;
|
||||
background-color: ${(props) => props.theme.eui.euiColorLightestShade};
|
||||
height: ${OVERLAY_HEADER_SIZE}px;
|
||||
`;
|
||||
|
||||
const OverlayHeaderTitleWrapper = euiStyled(EuiFlexGroup).attrs({ alignItems: 'center' })`
|
||||
padding: ${(props) => props.theme.eui.paddingSizes.s} ${(props) =>
|
||||
props.theme.eui.paddingSizes.m} 0;
|
||||
@media (max-width: 752px) {
|
||||
border-radius: 0px !important;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
top: 97px;
|
||||
bottom: 0;
|
||||
max-height: calc(100vh - 97px);
|
||||
max-width: 100%;
|
||||
}
|
||||
`;
|
||||
|
||||
const panelStyle: CSSProperties = {
|
||||
position: 'absolute',
|
||||
right: 10,
|
||||
top: OVERLAY_Y_START,
|
||||
width: '50%',
|
||||
maxWidth: 730,
|
||||
zIndex: 2,
|
||||
height: `calc(100vh - ${OVERLAY_Y_START + OVERLAY_BOTTOM_MARGIN}px)`,
|
||||
overflow: 'hidden',
|
||||
};
|
||||
|
|
|
@ -15,7 +15,6 @@ import { TabContent, TabProps } from './shared';
|
|||
import { LogStream } from '../../../../../../components/log_stream';
|
||||
import { useWaffleOptionsContext } from '../../../hooks/use_waffle_options';
|
||||
import { findInventoryFields } from '../../../../../../../common/inventory_models';
|
||||
import { euiStyled } from '../../../../../../../../observability/public';
|
||||
import { useLinkProps } from '../../../../../../hooks/use_link_props';
|
||||
import { getNodeLogsUrl } from '../../../../../link_to';
|
||||
|
||||
|
@ -51,22 +50,25 @@ const TabComponent = (props: TabProps) => {
|
|||
|
||||
return (
|
||||
<TabContent>
|
||||
<EuiFlexGroup gutterSize={'none'} alignItems="center">
|
||||
<EuiFlexGroup gutterSize={'m'} alignItems={'center'} responsive={false}>
|
||||
<EuiFlexItem>
|
||||
<QueryWrapper>
|
||||
<EuiFieldSearch
|
||||
fullWidth
|
||||
placeholder={i18n.translate('xpack.infra.nodeDetails.logs.textFieldPlaceholder', {
|
||||
defaultMessage: 'Search for log entries...',
|
||||
})}
|
||||
value={textQuery}
|
||||
isClearable
|
||||
onChange={onQueryChange}
|
||||
/>
|
||||
</QueryWrapper>
|
||||
<EuiFieldSearch
|
||||
fullWidth
|
||||
placeholder={i18n.translate('xpack.infra.nodeDetails.logs.textFieldPlaceholder', {
|
||||
defaultMessage: 'Search for log entries...',
|
||||
})}
|
||||
value={textQuery}
|
||||
isClearable
|
||||
onChange={onQueryChange}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButtonEmpty iconType={'popout'} {...nodeLogsMenuItemLinkProps}>
|
||||
<EuiButtonEmpty
|
||||
size={'xs'}
|
||||
flush={'both'}
|
||||
iconType={'popout'}
|
||||
{...nodeLogsMenuItemLinkProps}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.infra.nodeDetails.logs.openLogsLink"
|
||||
defaultMessage="Open in Logs"
|
||||
|
@ -79,11 +81,6 @@ const TabComponent = (props: TabProps) => {
|
|||
);
|
||||
};
|
||||
|
||||
const QueryWrapper = euiStyled.div`
|
||||
padding: ${(props) => props.theme.eui.paddingSizes.m};
|
||||
padding-right: 0;
|
||||
`;
|
||||
|
||||
export const LogsTab = {
|
||||
id: 'logs',
|
||||
name: i18n.translate('xpack.infra.nodeDetails.tabs.logs', {
|
||||
|
|
|
@ -11,7 +11,6 @@ import { EuiFlexGroup } from '@elastic/eui';
|
|||
import { EuiIcon } from '@elastic/eui';
|
||||
import { colorTransformer } from '../../../../../../../../common/color_palette';
|
||||
import { MetricsExplorerOptionsMetric } from '../../../../../metrics_explorer/hooks/use_metrics_explorer_options';
|
||||
import { euiStyled } from '../../../../../../../../../observability/public';
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
|
@ -20,33 +19,33 @@ interface Props {
|
|||
|
||||
export const ChartHeader = ({ title, metrics }: Props) => {
|
||||
return (
|
||||
<ChartHeaderWrapper>
|
||||
<EuiFlexGroup gutterSize={'s'} responsive={false}>
|
||||
<EuiFlexItem grow={1}>
|
||||
<EuiText>
|
||||
<strong>{title}</strong>
|
||||
<EuiText size={'s'}>
|
||||
<h4>{title}</h4>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFlexGroup gutterSize={'s'} alignItems={'center'}>
|
||||
<EuiFlexGroup gutterSize={'s'} alignItems={'center'} responsive={false}>
|
||||
{metrics.map((chartMetric) => (
|
||||
<EuiFlexGroup key={chartMetric.label!} gutterSize={'s'} alignItems={'center'}>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiIcon color={colorTransformer(chartMetric.color!)} type={'dot'} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText size={'xs'}>{chartMetric.label}</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiFlexItem key={chartMetric.label!}>
|
||||
<EuiFlexGroup
|
||||
key={chartMetric.label!}
|
||||
gutterSize={'xs'}
|
||||
alignItems={'center'}
|
||||
responsive={false}
|
||||
>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiIcon color={colorTransformer(chartMetric.color!)} type={'dot'} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText size={'xs'}>{chartMetric.label}</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
))}
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</ChartHeaderWrapper>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
};
|
||||
|
||||
const ChartHeaderWrapper = euiStyled.div`
|
||||
display: flex;
|
||||
width: 100%;
|
||||
padding: ${(props) => props.theme.eui.paddingSizes.s} ${(props) =>
|
||||
props.theme.eui.paddingSizes.m};
|
||||
`;
|
||||
|
|
|
@ -10,6 +10,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import {
|
||||
Axis,
|
||||
Chart,
|
||||
ChartSizeArray,
|
||||
niceTimeFormatter,
|
||||
Position,
|
||||
Settings,
|
||||
|
@ -17,7 +18,7 @@ import {
|
|||
PointerEvent,
|
||||
} from '@elastic/charts';
|
||||
import moment from 'moment';
|
||||
import { EuiLoadingChart } from '@elastic/eui';
|
||||
import { EuiLoadingChart, EuiSpacer, EuiFlexGrid, EuiFlexItem } from '@elastic/eui';
|
||||
import { TabContent, TabProps } from '../shared';
|
||||
import { useSnapshot } from '../../../../hooks/use_snaphot';
|
||||
import { useWaffleOptionsContext } from '../../../../hooks/use_waffle_options';
|
||||
|
@ -39,7 +40,6 @@ import { createInventoryMetricFormatter } from '../../../../lib/create_inventory
|
|||
import { calculateDomain } from '../../../../../metrics_explorer/components/helpers/calculate_domain';
|
||||
import { getTimelineChartTheme } from '../../../../../metrics_explorer/components/helpers/get_chart_theme';
|
||||
import { useUiSetting } from '../../../../../../../../../../../src/plugins/kibana_react/public';
|
||||
import { euiStyled } from '../../../../../../../../../observability/public';
|
||||
import { ChartHeader } from './chart_header';
|
||||
import {
|
||||
SYSTEM_METRIC_NAME,
|
||||
|
@ -56,6 +56,8 @@ import {
|
|||
import { TimeDropdown } from './time_dropdown';
|
||||
|
||||
const ONE_HOUR = 60 * 60 * 1000;
|
||||
const CHART_SIZE: ChartSizeArray = ['100%', 160];
|
||||
|
||||
const TabComponent = (props: TabProps) => {
|
||||
const cpuChartRef = useRef<Chart>(null);
|
||||
const networkChartRef = useRef<Chart>(null);
|
||||
|
@ -282,217 +284,184 @@ const TabComponent = (props: TabProps) => {
|
|||
|
||||
return (
|
||||
<TabContent>
|
||||
<TimepickerWrapper>
|
||||
<TimeDropdown value={time} onChange={updateTime} />
|
||||
</TimepickerWrapper>
|
||||
<ChartsContainer>
|
||||
<ChartContainerWrapper>
|
||||
<TimeDropdown value={time} onChange={updateTime} />
|
||||
|
||||
<EuiSpacer size={'l'} />
|
||||
|
||||
<EuiFlexGrid columns={2} gutterSize={'l'} responsive={false}>
|
||||
<EuiFlexItem>
|
||||
<ChartHeader title={CPU_CHART_TITLE} metrics={cpuChartMetrics} />
|
||||
<ChartContainer>
|
||||
<Chart ref={cpuChartRef}>
|
||||
<MetricExplorerSeriesChart
|
||||
type={MetricsExplorerChartType.line}
|
||||
metric={cpuChartMetrics[0]}
|
||||
id={'0'}
|
||||
series={systemMetricsTs!}
|
||||
stack={false}
|
||||
/>
|
||||
<MetricExplorerSeriesChart
|
||||
type={MetricsExplorerChartType.line}
|
||||
metric={cpuChartMetrics[1]}
|
||||
id={'0'}
|
||||
series={userMetricsTs}
|
||||
stack={false}
|
||||
/>
|
||||
<Axis
|
||||
id={'timestamp'}
|
||||
position={Position.Bottom}
|
||||
showOverlappingTicks={true}
|
||||
tickFormat={formatter}
|
||||
/>
|
||||
<Axis
|
||||
id={'values'}
|
||||
position={Position.Left}
|
||||
tickFormat={cpuFormatter}
|
||||
domain={getDomain(cpuTimeseries, cpuChartMetrics)}
|
||||
ticks={6}
|
||||
showGridLines
|
||||
/>
|
||||
<Settings
|
||||
onPointerUpdate={pointerUpdate}
|
||||
tooltip={tooltipProps}
|
||||
theme={getTimelineChartTheme(isDarkMode)}
|
||||
/>
|
||||
</Chart>
|
||||
</ChartContainer>
|
||||
</ChartContainerWrapper>
|
||||
<Chart ref={cpuChartRef} size={CHART_SIZE}>
|
||||
<MetricExplorerSeriesChart
|
||||
type={MetricsExplorerChartType.line}
|
||||
metric={cpuChartMetrics[0]}
|
||||
id={'0'}
|
||||
series={systemMetricsTs!}
|
||||
stack={false}
|
||||
/>
|
||||
<MetricExplorerSeriesChart
|
||||
type={MetricsExplorerChartType.line}
|
||||
metric={cpuChartMetrics[1]}
|
||||
id={'0'}
|
||||
series={userMetricsTs}
|
||||
stack={false}
|
||||
/>
|
||||
<Axis
|
||||
id={'timestamp'}
|
||||
position={Position.Bottom}
|
||||
showOverlappingTicks={true}
|
||||
tickFormat={formatter}
|
||||
/>
|
||||
<Axis
|
||||
id={'values'}
|
||||
position={Position.Left}
|
||||
tickFormat={cpuFormatter}
|
||||
domain={getDomain(cpuTimeseries, cpuChartMetrics)}
|
||||
ticks={6}
|
||||
showGridLines
|
||||
/>
|
||||
<Settings
|
||||
onPointerUpdate={pointerUpdate}
|
||||
tooltip={tooltipProps}
|
||||
theme={getTimelineChartTheme(isDarkMode)}
|
||||
/>
|
||||
</Chart>
|
||||
</EuiFlexItem>
|
||||
|
||||
<ChartContainerWrapper>
|
||||
<EuiFlexItem>
|
||||
<ChartHeader title={LOAD_CHART_TITLE} metrics={loadChartMetrics} />
|
||||
<ChartContainer>
|
||||
<Chart ref={loadChartRef}>
|
||||
<MetricExplorerSeriesChart
|
||||
type={MetricsExplorerChartType.line}
|
||||
metric={loadChartMetrics[0]}
|
||||
id="0"
|
||||
series={load1mMetricsTs}
|
||||
stack={false}
|
||||
/>
|
||||
<MetricExplorerSeriesChart
|
||||
type={MetricsExplorerChartType.line}
|
||||
metric={loadChartMetrics[1]}
|
||||
id="0"
|
||||
series={load5mMetricsTs}
|
||||
stack={false}
|
||||
/>
|
||||
<MetricExplorerSeriesChart
|
||||
type={MetricsExplorerChartType.line}
|
||||
metric={loadChartMetrics[2]}
|
||||
id="0"
|
||||
series={load15mMetricsTs}
|
||||
stack={false}
|
||||
/>
|
||||
<Axis
|
||||
id={'timestamp'}
|
||||
position={Position.Bottom}
|
||||
showOverlappingTicks={true}
|
||||
tickFormat={formatter}
|
||||
/>
|
||||
<Axis
|
||||
id={'values1'}
|
||||
position={Position.Left}
|
||||
tickFormat={loadFormatter}
|
||||
domain={getDomain(loadTimeseries, loadChartMetrics)}
|
||||
ticks={6}
|
||||
showGridLines
|
||||
/>
|
||||
<Settings
|
||||
onPointerUpdate={pointerUpdate}
|
||||
tooltip={tooltipProps}
|
||||
theme={getTimelineChartTheme(isDarkMode)}
|
||||
/>
|
||||
</Chart>
|
||||
</ChartContainer>
|
||||
</ChartContainerWrapper>
|
||||
<Chart ref={loadChartRef} size={CHART_SIZE}>
|
||||
<MetricExplorerSeriesChart
|
||||
type={MetricsExplorerChartType.line}
|
||||
metric={loadChartMetrics[0]}
|
||||
id="0"
|
||||
series={load1mMetricsTs}
|
||||
stack={false}
|
||||
/>
|
||||
<MetricExplorerSeriesChart
|
||||
type={MetricsExplorerChartType.line}
|
||||
metric={loadChartMetrics[1]}
|
||||
id="0"
|
||||
series={load5mMetricsTs}
|
||||
stack={false}
|
||||
/>
|
||||
<MetricExplorerSeriesChart
|
||||
type={MetricsExplorerChartType.line}
|
||||
metric={loadChartMetrics[2]}
|
||||
id="0"
|
||||
series={load15mMetricsTs}
|
||||
stack={false}
|
||||
/>
|
||||
<Axis
|
||||
id={'timestamp'}
|
||||
position={Position.Bottom}
|
||||
showOverlappingTicks={true}
|
||||
tickFormat={formatter}
|
||||
/>
|
||||
<Axis
|
||||
id={'values1'}
|
||||
position={Position.Left}
|
||||
tickFormat={loadFormatter}
|
||||
domain={getDomain(loadTimeseries, loadChartMetrics)}
|
||||
ticks={6}
|
||||
showGridLines
|
||||
/>
|
||||
<Settings
|
||||
onPointerUpdate={pointerUpdate}
|
||||
tooltip={tooltipProps}
|
||||
theme={getTimelineChartTheme(isDarkMode)}
|
||||
/>
|
||||
</Chart>
|
||||
</EuiFlexItem>
|
||||
|
||||
<ChartContainerWrapper>
|
||||
<EuiFlexItem>
|
||||
<ChartHeader title={MEMORY_CHART_TITLE} metrics={memoryChartMetrics} />
|
||||
<ChartContainer>
|
||||
<Chart ref={memoryChartRef}>
|
||||
<MetricExplorerSeriesChart
|
||||
type={MetricsExplorerChartType.line}
|
||||
metric={memoryChartMetrics[0]}
|
||||
id="0"
|
||||
series={usedMemoryMetricsTs}
|
||||
stack={false}
|
||||
/>
|
||||
<MetricExplorerSeriesChart
|
||||
type={MetricsExplorerChartType.line}
|
||||
metric={memoryChartMetrics[1]}
|
||||
id="0"
|
||||
series={freeMemoryMetricsTs}
|
||||
stack={false}
|
||||
/>
|
||||
<Axis
|
||||
id={'timestamp'}
|
||||
position={Position.Bottom}
|
||||
showOverlappingTicks={true}
|
||||
tickFormat={formatter}
|
||||
/>
|
||||
<Axis
|
||||
id={'values'}
|
||||
position={Position.Left}
|
||||
tickFormat={memoryFormatter}
|
||||
domain={getDomain(memoryTimeseries, memoryChartMetrics)}
|
||||
ticks={6}
|
||||
showGridLines
|
||||
/>
|
||||
<Settings
|
||||
onPointerUpdate={pointerUpdate}
|
||||
tooltip={tooltipProps}
|
||||
theme={getTimelineChartTheme(isDarkMode)}
|
||||
/>
|
||||
</Chart>
|
||||
</ChartContainer>
|
||||
</ChartContainerWrapper>
|
||||
<Chart ref={memoryChartRef} size={CHART_SIZE}>
|
||||
<MetricExplorerSeriesChart
|
||||
type={MetricsExplorerChartType.line}
|
||||
metric={memoryChartMetrics[0]}
|
||||
id="0"
|
||||
series={usedMemoryMetricsTs}
|
||||
stack={false}
|
||||
/>
|
||||
<MetricExplorerSeriesChart
|
||||
type={MetricsExplorerChartType.line}
|
||||
metric={memoryChartMetrics[1]}
|
||||
id="0"
|
||||
series={freeMemoryMetricsTs}
|
||||
stack={false}
|
||||
/>
|
||||
<Axis
|
||||
id={'timestamp'}
|
||||
position={Position.Bottom}
|
||||
showOverlappingTicks={true}
|
||||
tickFormat={formatter}
|
||||
/>
|
||||
<Axis
|
||||
id={'values'}
|
||||
position={Position.Left}
|
||||
tickFormat={memoryFormatter}
|
||||
domain={getDomain(memoryTimeseries, memoryChartMetrics)}
|
||||
ticks={6}
|
||||
showGridLines
|
||||
/>
|
||||
<Settings
|
||||
onPointerUpdate={pointerUpdate}
|
||||
tooltip={tooltipProps}
|
||||
theme={getTimelineChartTheme(isDarkMode)}
|
||||
/>
|
||||
</Chart>
|
||||
</EuiFlexItem>
|
||||
|
||||
<ChartContainerWrapper>
|
||||
<EuiFlexItem>
|
||||
<ChartHeader title={NETWORK_CHART_TITLE} metrics={networkChartMetrics} />
|
||||
<ChartContainer>
|
||||
<Chart ref={networkChartRef}>
|
||||
<MetricExplorerSeriesChart
|
||||
type={MetricsExplorerChartType.line}
|
||||
metric={networkChartMetrics[0]}
|
||||
id="0"
|
||||
series={rxMetricsTs}
|
||||
stack={false}
|
||||
/>
|
||||
<MetricExplorerSeriesChart
|
||||
type={MetricsExplorerChartType.line}
|
||||
metric={networkChartMetrics[1]}
|
||||
id="0"
|
||||
series={txMetricsTs}
|
||||
stack={false}
|
||||
/>
|
||||
<Axis
|
||||
id={'timestamp'}
|
||||
position={Position.Bottom}
|
||||
showOverlappingTicks={true}
|
||||
tickFormat={formatter}
|
||||
/>
|
||||
<Axis
|
||||
id={'values'}
|
||||
position={Position.Left}
|
||||
tickFormat={networkFormatter}
|
||||
domain={getDomain(networkTimeseries, networkChartMetrics)}
|
||||
ticks={6}
|
||||
showGridLines
|
||||
/>
|
||||
<Settings
|
||||
onPointerUpdate={pointerUpdate}
|
||||
tooltip={tooltipProps}
|
||||
theme={getTimelineChartTheme(isDarkMode)}
|
||||
/>
|
||||
</Chart>
|
||||
</ChartContainer>
|
||||
</ChartContainerWrapper>
|
||||
</ChartsContainer>
|
||||
<Chart ref={networkChartRef} size={CHART_SIZE}>
|
||||
<MetricExplorerSeriesChart
|
||||
type={MetricsExplorerChartType.line}
|
||||
metric={networkChartMetrics[0]}
|
||||
id="0"
|
||||
series={rxMetricsTs}
|
||||
stack={false}
|
||||
/>
|
||||
<MetricExplorerSeriesChart
|
||||
type={MetricsExplorerChartType.line}
|
||||
metric={networkChartMetrics[1]}
|
||||
id="0"
|
||||
series={txMetricsTs}
|
||||
stack={false}
|
||||
/>
|
||||
<Axis
|
||||
id={'timestamp'}
|
||||
position={Position.Bottom}
|
||||
showOverlappingTicks={true}
|
||||
tickFormat={formatter}
|
||||
/>
|
||||
<Axis
|
||||
id={'values'}
|
||||
position={Position.Left}
|
||||
tickFormat={networkFormatter}
|
||||
domain={getDomain(networkTimeseries, networkChartMetrics)}
|
||||
ticks={6}
|
||||
showGridLines
|
||||
/>
|
||||
<Settings
|
||||
onPointerUpdate={pointerUpdate}
|
||||
tooltip={tooltipProps}
|
||||
theme={getTimelineChartTheme(isDarkMode)}
|
||||
/>
|
||||
</Chart>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGrid>
|
||||
</TabContent>
|
||||
);
|
||||
};
|
||||
|
||||
const ChartsContainer = euiStyled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
`;
|
||||
|
||||
const ChartContainerWrapper = euiStyled.div`
|
||||
width: 50%
|
||||
`;
|
||||
|
||||
const TimepickerWrapper = euiStyled.div`
|
||||
padding: ${(props) => props.theme.eui.paddingSizes.m};
|
||||
width: 50%;
|
||||
`;
|
||||
|
||||
const ChartContainer: React.FC = ({ children }) => (
|
||||
<div
|
||||
style={{
|
||||
width: '100%',
|
||||
height: 150,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
|
||||
const LoadingPlaceholder = () => {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
height: '200px',
|
||||
padding: '16px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
|
|
|
@ -15,7 +15,7 @@ interface Props {
|
|||
|
||||
export const TimeDropdown = (props: Props) => (
|
||||
<EuiSelect
|
||||
compressed
|
||||
fullWidth={true}
|
||||
options={[
|
||||
{
|
||||
text: i18n.translate('xpack.infra.nodeDetails.metrics.last15Minutes', {
|
||||
|
|
|
@ -102,7 +102,9 @@ const TabComponent = (props: TabProps) => {
|
|||
};
|
||||
|
||||
const TableWrapper = euiStyled.div`
|
||||
margin-bottom: 20px
|
||||
&:not(:last-child) {
|
||||
margin-bottom: 16px
|
||||
}
|
||||
`;
|
||||
|
||||
const LoadingPlaceholder = () => {
|
||||
|
|
|
@ -4,18 +4,20 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { EuiText } from '@elastic/eui';
|
||||
import { EuiToolTip } from '@elastic/eui';
|
||||
import { EuiButtonIcon } from '@elastic/eui';
|
||||
import { EuiFlexGroup } from '@elastic/eui';
|
||||
import { EuiFlexItem } from '@elastic/eui';
|
||||
import { EuiLink } from '@elastic/eui';
|
||||
import { EuiBasicTable } from '@elastic/eui';
|
||||
import {
|
||||
EuiText,
|
||||
EuiToolTip,
|
||||
EuiButtonIcon,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiLink,
|
||||
EuiBasicTable,
|
||||
EuiSpacer,
|
||||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { first } from 'lodash';
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { euiStyled } from '../../../../../../../../../observability/public';
|
||||
|
||||
interface Row {
|
||||
name: string;
|
||||
|
@ -51,15 +53,19 @@ export const Table = (props: Props) => {
|
|||
render: (_name: string, item: Row) => {
|
||||
return (
|
||||
<span>
|
||||
<EuiToolTip
|
||||
content={i18n.translate('xpack.infra.nodeDetails.tabs.metadata.setFilterTooltip', {
|
||||
defaultMessage: 'View event with filter',
|
||||
})}
|
||||
>
|
||||
<EuiFlexGroup gutterSize={'xs'}>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFlexGroup gutterSize={'xs'} alignItems={'center'} responsive={false}>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiToolTip
|
||||
content={i18n.translate(
|
||||
'xpack.infra.nodeDetails.tabs.metadata.setFilterTooltip',
|
||||
{
|
||||
defaultMessage: 'View event with filter',
|
||||
}
|
||||
)}
|
||||
>
|
||||
<EuiButtonIcon
|
||||
color="text"
|
||||
color="subdued"
|
||||
size="s"
|
||||
iconType="filter"
|
||||
aria-label={i18n.translate(
|
||||
'xpack.infra.nodeDetails.tabs.metadata.filterAriaLabel',
|
||||
|
@ -69,13 +75,13 @@ export const Table = (props: Props) => {
|
|||
)}
|
||||
onClick={() => onClick(item)}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
{!Array.isArray(item.value) && item.value}
|
||||
{Array.isArray(item.value) && <ArrayValue values={item.value} />}
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiToolTip>
|
||||
</EuiToolTip>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
{!Array.isArray(item.value) && item.value}
|
||||
{Array.isArray(item.value) && <ArrayValue values={item.value} />}
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</span>
|
||||
);
|
||||
},
|
||||
|
@ -86,20 +92,21 @@ export const Table = (props: Props) => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<TitleWrapper>
|
||||
<EuiText>
|
||||
<h3>{title}</h3>
|
||||
</EuiText>
|
||||
</TitleWrapper>
|
||||
<TableWithoutHeader tableLayout="fixed" compressed columns={columns} items={rows} />
|
||||
<EuiText>
|
||||
<h4>{title}</h4>
|
||||
</EuiText>
|
||||
<EuiSpacer size={'s'} />
|
||||
<TableWithoutHeader
|
||||
tableLayout={'fixed'}
|
||||
compressed
|
||||
responsive={false}
|
||||
columns={columns}
|
||||
items={rows}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const TitleWrapper = euiStyled.div`
|
||||
margin-bottom: 10px
|
||||
`;
|
||||
|
||||
class TableWithoutHeader extends EuiBasicTable {
|
||||
renderTableHead() {
|
||||
return <></>;
|
||||
|
@ -123,7 +130,7 @@ const ArrayValue = (props: MoreProps) => {
|
|||
return (
|
||||
<>
|
||||
{!isExpanded && (
|
||||
<EuiFlexGroup gutterSize="none">
|
||||
<EuiFlexGroup gutterSize={'xs'} responsive={false} alignItems={'baseline'} wrap={true}>
|
||||
<EuiFlexItem grow={false}>
|
||||
{first(values)}
|
||||
{' ... '}
|
||||
|
@ -148,7 +155,7 @@ const ArrayValue = (props: MoreProps) => {
|
|||
))}
|
||||
<EuiLink onClick={collapse}>
|
||||
{i18n.translate('xpack.infra.nodeDetails.tabs.metadata.seeLess', {
|
||||
defaultMessage: 'See less',
|
||||
defaultMessage: 'Show less',
|
||||
})}
|
||||
</EuiLink>
|
||||
</div>
|
||||
|
|
|
@ -17,11 +17,9 @@ export interface TabProps {
|
|||
|
||||
export const OVERLAY_Y_START = 266;
|
||||
export const OVERLAY_BOTTOM_MARGIN = 16;
|
||||
export const OVERLAY_HEADER_SIZE = 96;
|
||||
const contentHeightOffset = OVERLAY_Y_START + OVERLAY_BOTTOM_MARGIN + OVERLAY_HEADER_SIZE;
|
||||
export const TabContent = euiStyled.div`
|
||||
padding: ${(props) => props.theme.eui.paddingSizes.s};
|
||||
height: calc(100vh - ${contentHeightOffset}px);
|
||||
padding: ${(props) => props.theme.eui.paddingSizes.m};
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
`;
|
||||
|
|
Loading…
Reference in a new issue