[Synthetics] Fix broken colors for status panels !! (#211422)

## Summary

Fixes https://github.com/elastic/kibana/issues/208951

Fix broken colors for status panels, i have also fixed broken metric viz
which had some styling issues with new theme by setting minimum width.

### After
<img width="1724" alt="image"
src="https://github.com/user-attachments/assets/aea9c9a1-0be1-4b82-82e8-721d61a0fd05"
/>
This commit is contained in:
Shahzad 2025-02-19 18:15:28 +01:00 committed by GitHub
parent 6945828b57
commit 5908bf4195
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 143 additions and 87 deletions

View file

@ -247,6 +247,7 @@ const Wrapper = styled.div<{
}>`
height: ${(props) => (props.$customHeight ? `${props.$customHeight};` : `100%;`)};
position: relative;
min-width: 80px;
&&& {
> :nth-child(2) {
height: ${(props) =>
@ -266,16 +267,16 @@ const Wrapper = styled.div<{
: 'center;'};
}
justify-content: flex-end;
.legacyMtrVis__container {
&__container {
padding: 0;
> :nth-child(2) {
[data-test-subj='metric_label'] {
${({ noLabel }) =>
noLabel &&
` display: none;
`}
}
}
.legacyMtrVis__value {
&__value {
line-height: ${({ lineHeight }) => lineHeight}px !important;
font-size: ${({ fontSize }) => fontSize}px !important;
}

View file

@ -7,11 +7,11 @@
import React from 'react';
import moment from 'moment';
import { EuiProgress } from '@elastic/eui';
import { EuiProgress, useEuiTheme, VISUALIZATION_COLORS } from '@elastic/eui';
import { TooltipTable, TooltipHeader, TooltipValue, TooltipContainer } from '@elastic/charts';
import { MonitorStatusTimeBin, SUCCESS_VIZ_COLOR, DANGER_VIZ_COLOR } from './monitor_status_data';
import { MonitorStatusTimeBin } from './monitor_status_data';
import * as labels from './labels';
export const MonitorStatusCellTooltip = ({
@ -21,6 +21,14 @@ export const MonitorStatusCellTooltip = ({
timeBin?: MonitorStatusTimeBin;
isLoading: boolean;
}) => {
const { euiTheme } = useEuiTheme();
const isAmsterdam = euiTheme.flags.hasVisColorAdjustment;
const SUCCESS_COLOR = isAmsterdam ? VISUALIZATION_COLORS[0] : euiTheme.colors.success;
const DANGER_COLOR = isAmsterdam
? VISUALIZATION_COLORS[VISUALIZATION_COLORS.length - 1]
: euiTheme.colors.danger;
if (!timeBin) {
return <>{''}</>;
}
@ -58,14 +66,14 @@ export const MonitorStatusCellTooltip = ({
...commonTooltipValuesProps,
},
{
color: SUCCESS_VIZ_COLOR,
color: SUCCESS_COLOR,
label: labels.COMPLETE_LABEL,
value: timeBin.ups,
formattedValue: `${timeBin.ups}`,
...commonTooltipValuesProps,
},
{
color: DANGER_VIZ_COLOR,
color: DANGER_COLOR,
label: labels.FAILED_LABEL,
value: timeBin.downs,
formattedValue: `${timeBin.downs}`,

View file

@ -18,8 +18,6 @@ import {
import type { BrushEvent } from '@elastic/charts';
import { MonitorStatusHeatmapBucket } from '../../../../../../common/runtime_types';
export const SUCCESS_VIZ_COLOR = VISUALIZATION_COLORS[0];
export const DANGER_VIZ_COLOR = VISUALIZATION_COLORS[VISUALIZATION_COLORS.length - 1];
export const CHART_CELL_WIDTH = 17;
export interface MonitorStatusTimeBucket {
@ -58,23 +56,29 @@ export interface MonitorStatusPanelProps {
export function getColorBands(euiTheme: EuiThemeComputed, colorMode: EuiThemeColorModeStandard) {
const colorTransitionFn = colorMode === COLOR_MODES_STANDARD.dark ? transparentize : tint;
const isAmsterdam = euiTheme.flags.hasVisColorAdjustment;
const SUCCESS_COLOR = isAmsterdam ? VISUALIZATION_COLORS[0] : euiTheme.colors.success;
const DANGER_COLOR = isAmsterdam
? VISUALIZATION_COLORS[VISUALIZATION_COLORS.length - 1]
: euiTheme.colors.danger;
return [
{ color: DANGER_VIZ_COLOR, start: -Infinity, end: -1 },
{ color: DANGER_VIZ_COLOR, start: -1, end: -0.75 },
{ color: colorTransitionFn(DANGER_VIZ_COLOR, 0.25), start: -0.75, end: -0.5 },
{ color: colorTransitionFn(DANGER_VIZ_COLOR, 0.5), start: -0.5, end: -0.25 },
{ color: colorTransitionFn(DANGER_VIZ_COLOR, 0.75), start: -0.25, end: -0.000000001 },
{ color: DANGER_COLOR, start: -Infinity, end: -1 },
{ color: DANGER_COLOR, start: -1, end: -0.75 },
{ color: colorTransitionFn(DANGER_COLOR, 0.25), start: -0.75, end: -0.5 },
{ color: colorTransitionFn(DANGER_COLOR, 0.5), start: -0.5, end: -0.25 },
{ color: colorTransitionFn(DANGER_COLOR, 0.75), start: -0.25, end: -0.000000001 },
{
color: getSkippedVizColor(euiTheme),
start: -0.000000001,
end: 0.000000001,
},
{ color: colorTransitionFn(SUCCESS_VIZ_COLOR, 0.5), start: 0.000000001, end: 0.25 },
{ color: colorTransitionFn(SUCCESS_VIZ_COLOR, 0.35), start: 0.25, end: 0.5 },
{ color: colorTransitionFn(SUCCESS_VIZ_COLOR, 0.2), start: 0.5, end: 0.8 },
{ color: SUCCESS_VIZ_COLOR, start: 0.8, end: 1 },
{ color: SUCCESS_VIZ_COLOR, start: 1, end: Infinity },
{ color: colorTransitionFn(SUCCESS_COLOR, 0.5), start: 0.000000001, end: 0.25 },
{ color: colorTransitionFn(SUCCESS_COLOR, 0.35), start: 0.25, end: 0.5 },
{ color: colorTransitionFn(SUCCESS_COLOR, 0.2), start: 0.5, end: 0.8 },
{ color: SUCCESS_COLOR, start: 0.8, end: 1 },
{ color: SUCCESS_COLOR, start: 1, end: Infinity },
];
}

View file

@ -6,12 +6,25 @@
*/
import React, { useMemo } from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiText, useEuiTheme } from '@elastic/eui';
import {
EuiFlexGroup,
EuiFlexItem,
EuiIcon,
EuiText,
useEuiTheme,
VISUALIZATION_COLORS,
} from '@elastic/eui';
import * as labels from './labels';
import { DANGER_VIZ_COLOR, getSkippedVizColor, SUCCESS_VIZ_COLOR } from './monitor_status_data';
import { getSkippedVizColor } from './monitor_status_data';
export const MonitorStatusLegend = ({ brushable }: { brushable: boolean }) => {
const { euiTheme } = useEuiTheme();
const isAmsterdam = euiTheme.flags.hasVisColorAdjustment;
const SUCCESS_COLOR = isAmsterdam ? VISUALIZATION_COLORS[0] : euiTheme.colors.success;
const DANGER_COLOR = isAmsterdam
? VISUALIZATION_COLORS[VISUALIZATION_COLORS.length - 1]
: euiTheme.colors.danger;
const LegendItem = useMemo(() => {
return ({
@ -39,8 +52,8 @@ export const MonitorStatusLegend = ({ brushable }: { brushable: boolean }) => {
return (
<EuiFlexGroup wrap={true} responsive={false}>
<LegendItem color={SUCCESS_VIZ_COLOR} label={labels.COMPLETE_LABEL} />
<LegendItem color={DANGER_VIZ_COLOR} label={labels.FAILED_LABEL} />
<LegendItem color={SUCCESS_COLOR} label={labels.COMPLETE_LABEL} />
<LegendItem color={DANGER_COLOR} label={labels.FAILED_LABEL} />
<LegendItem color={getSkippedVizColor(euiTheme)} label={labels.SKIPPED_LABEL} />
{/*
// Hiding error for now until @elastic/chart's Heatmap chart supports annotations

View file

@ -8,8 +8,9 @@
import React, { useMemo, useRef } from 'react';
import { EuiPanel, useEuiTheme, EuiResizeObserver, EuiSpacer, EuiProgress } from '@elastic/eui';
import { Chart, Settings, Heatmap, ScaleType, Tooltip, LEGACY_LIGHT_THEME } from '@elastic/charts';
import { Chart, Settings, Heatmap, ScaleType, Tooltip } from '@elastic/charts';
import { i18n } from '@kbn/i18n';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import { MonitorStatusHeader } from './monitor_status_header';
import { MonitorStatusCellTooltip } from './monitor_status_cell_tooltip';
import { MonitorStatusLegend } from './monitor_status_legend';
@ -21,6 +22,7 @@ import {
MonitorStatusPanelProps,
} from './monitor_status_data';
import { useMonitorStatusData } from './use_monitor_status_data';
import { ClientPluginsStart } from '../../../../../plugin';
export const MonitorStatusPanel = ({
from = 'now-24h',
@ -34,6 +36,8 @@ export const MonitorStatusPanel = ({
const initialSizeRef = useRef<HTMLDivElement | null>(null);
const { loading, timeBins, handleResize, getTimeBinByXValue, xDomain, minsPerBin } =
useMonitorStatusData({ from, to, initialSizeRef });
const { charts } = useKibana<ClientPluginsStart>().services;
const baseTheme = charts.theme.useChartsBaseTheme();
const heatmap = useMemo(() => {
return getMonitorStatusChartTheme(euiTheme, brushable);
@ -59,7 +63,7 @@ export const MonitorStatusPanel = ({
{minsPerBin && (
<Chart
size={{
height: 60,
height: 80,
}}
>
<Tooltip
@ -74,8 +78,7 @@ export const MonitorStatusPanel = ({
showLegend={false}
xDomain={xDomain}
theme={{ heatmap }}
// TODO connect to charts.theme service see src/plugins/charts/public/services/theme/README.md
baseTheme={LEGACY_LIGHT_THEME}
baseTheme={baseTheme}
onBrushEnd={(brushArea) => {
onBrushed?.(getBrushData(brushArea));
}}

View file

@ -9,23 +9,18 @@ import React from 'react';
import { EuiTitle, EuiPanel, EuiFlexGroup, EuiFlexItem, EuiText, EuiSpacer } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { LoadWhenInView } from '@kbn/observability-shared-plugin/public';
import { SummaryPanel } from './summary_panel';
import { useTestFlyoutOpen } from '../../test_now_mode/hooks/use_test_flyout_open';
import { useMonitorDetailsPage } from '../use_monitor_details_page';
import { useMonitorRangeFrom } from '../hooks/use_monitor_range_from';
import { MonitorAlerts } from './monitor_alerts';
import { MonitorErrorSparklines } from './monitor_error_sparklines';
import { MonitorStatusPanel } from '../monitor_status/monitor_status_panel';
import { DurationSparklines } from './duration_sparklines';
import { MonitorDurationTrend } from './duration_trend';
import { StepDurationPanel } from './step_duration_panel';
import { AvailabilityPanel } from './availability_panel';
import { DurationPanel } from './duration_panel';
import { MonitorDetailsPanelContainer } from './monitor_details_panel_container';
import { AvailabilitySparklines } from './availability_sparklines';
import { LastTestRun } from './last_test_run';
import { LAST_10_TEST_RUNS, TestRunsTable } from './test_runs_table';
import { MonitorErrorsCount } from './monitor_errors_count';
import { MonitorPendingWrapper } from '../monitor_pending_wrapper';
export const MonitorSummary = () => {
@ -42,16 +37,18 @@ export const MonitorSummary = () => {
return (
<MonitorPendingWrapper>
<SummaryPanel dateLabel={dateLabel} from={from} to={to} />
<EuiSpacer size="m" />
<EuiFlexGroup gutterSize="m" wrap={true} responsive={false}>
<EuiFlexItem grow={1} css={{ flexBasis: '36%', minWidth: 260 }}>
<EuiFlexItem grow={2} css={{ minWidth: 260 }}>
<MonitorDetailsPanelContainer />
</EuiFlexItem>
<EuiFlexItem grow={1} css={{ flexBasis: '60%' }}>
<EuiPanel hasShadow={false} grow={false} hasBorder paddingSize="m">
<EuiFlexItem grow={3}>
<EuiPanel hasShadow={false} paddingSize="m" hasBorder>
<EuiFlexGroup alignItems="center" gutterSize="m">
<EuiFlexItem grow={false}>
<EuiTitle size="xs">
<h3>{SUMMARY_LABEL}</h3>
<h3>{DURATION_TREND_LABEL}</h3>
</EuiTitle>
</EuiFlexItem>
<EuiFlexItem>
@ -60,53 +57,8 @@ export const MonitorSummary = () => {
</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
<EuiFlexGroup gutterSize="s" wrap={true}>
<EuiFlexGroup gutterSize="s" wrap={false} responsive={false}>
<EuiFlexItem grow={false}>
<AvailabilityPanel from={from} to={to} id="availabilityPercentageSummary" />
</EuiFlexItem>
<EuiFlexItem css={{ minWidth: 100 }}>
<AvailabilitySparklines from={from} to={to} id="availabilitySparklineSummary" />
</EuiFlexItem>
</EuiFlexGroup>
<EuiFlexGroup gutterSize="s" wrap={false} responsive={false}>
<EuiFlexItem grow={false} css={{ minWidth: 86 }}>
<DurationPanel from={from} to={to} id="durationAvgValueSummary" />
</EuiFlexItem>
<EuiFlexItem css={{ minWidth: 100 }}>
<DurationSparklines from={from} to={to} id="durationAvgSparklineSummary" />
</EuiFlexItem>
</EuiFlexGroup>
<EuiFlexGroup gutterSize="s" wrap={false} responsive={false}>
<EuiFlexItem grow={false}>
<MonitorErrorsCount from={from} to={to} id="monitorErrorsCountSummary" />
</EuiFlexItem>
<EuiFlexItem css={{ minWidth: 100 }}>
<MonitorErrorSparklines from={from} to={to} id="monitorErrorsSparklineSummary" />
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexGroup>
<MonitorDurationTrend from={from} to={to} />
</EuiPanel>
<EuiSpacer size="m" />
<EuiFlexGroup gutterSize="m">
<EuiFlexItem>
<EuiPanel hasShadow={false} paddingSize="m" hasBorder>
<EuiFlexGroup alignItems="center" gutterSize="m">
<EuiFlexItem grow={false}>
<EuiTitle size="xs">
<h3>{DURATION_TREND_LABEL}</h3>
</EuiTitle>
</EuiFlexItem>
<EuiFlexItem>
<EuiText color="subdued" size="s">
{dateLabel}
</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
<MonitorDurationTrend from={from} to={to} />
</EuiPanel>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer size="m" />
@ -135,10 +87,6 @@ export const MonitorSummary = () => {
);
};
const SUMMARY_LABEL = i18n.translate('xpack.synthetics.detailsPanel.summary', {
defaultMessage: 'Summary',
});
const TO_DATE_LABEL = i18n.translate('xpack.synthetics.detailsPanel.toDate', {
defaultMessage: 'To date',
});

View file

@ -0,0 +1,79 @@
/*
* 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 { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiText, EuiTitle } from '@elastic/eui';
import React from 'react';
import { i18n } from '@kbn/i18n';
import { AvailabilityPanel } from './availability_panel';
import { AvailabilitySparklines } from './availability_sparklines';
import { DurationPanel } from './duration_panel';
import { DurationSparklines } from './duration_sparklines';
import { MonitorErrorsCount } from './monitor_errors_count';
import { MonitorErrorSparklines } from './monitor_error_sparklines';
export const SummaryPanel = ({
dateLabel,
from,
to,
}: {
dateLabel: string;
from: string;
to: string;
}) => {
return (
<EuiPanel hasShadow={false} grow={false} hasBorder paddingSize="m">
<EuiFlexGroup alignItems="center" gutterSize="m">
<EuiFlexItem grow={false}>
<EuiTitle size="xs">
<h3>{SUMMARY_LABEL}</h3>
</EuiTitle>
</EuiFlexItem>
<EuiFlexItem>
<EuiText color="subdued" size="s">
{dateLabel}
</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
<EuiFlexGroup gutterSize="m" wrap={true}>
<EuiFlexItem>
<EuiFlexGroup gutterSize="s" wrap={false} responsive={false}>
<EuiFlexItem grow={false} css={{ minWidth: 120 }}>
<AvailabilityPanel from={from} to={to} id="availabilityPercentageSummary" />
</EuiFlexItem>
<EuiFlexItem css={{ minWidth: 100 }}>
<AvailabilitySparklines from={from} to={to} id="availabilitySparklineSummary" />
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem>
<EuiFlexGroup gutterSize="s" wrap={false} responsive={false}>
<EuiFlexItem grow={false} css={{ minWidth: 120 }}>
<DurationPanel from={from} to={to} id="durationAvgValueSummary" />
</EuiFlexItem>
<EuiFlexItem css={{ minWidth: 100 }}>
<DurationSparklines from={from} to={to} id="durationAvgSparklineSummary" />
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem>
<EuiFlexGroup gutterSize="s" wrap={false} responsive={false}>
<EuiFlexItem grow={false} css={{ minWidth: 80 }}>
<MonitorErrorsCount from={from} to={to} id="monitorErrorsCountSummary" />
</EuiFlexItem>
<EuiFlexItem css={{ minWidth: 100 }}>
<MonitorErrorSparklines from={from} to={to} id="monitorErrorsSparklineSummary" />
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
</EuiPanel>
);
};
const SUMMARY_LABEL = i18n.translate('xpack.synthetics.detailsPanel.summary', {
defaultMessage: 'Summary',
});