Skip to content

Commit

Permalink
[9.0] [Synthetics] Fix overview error popover !! (elastic#211431) (el…
Browse files Browse the repository at this point in the history
…astic#212123)

# Backport

This will backport the following commits from `main` to `9.0`:
- [[Synthetics] Fix overview error popover !!
(elastic#211431)](elastic#211431)

<!--- Backport version: 9.6.6 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sorenlouv/backport)

<!--BACKPORT
[{"author":{"name":"Shahzad","email":"shahzad31comp@gmail.com"},"sourceCommit":{"committedDate":"2025-02-21T16:38:54Z","message":"[Synthetics]
Fix overview error popover !! (elastic#211431)\n\n## Summary\n\nFix overview
error popover !!\n\nPings aren't being returned as part of overview data
anymore, so had to\nadd redux actions to fetch it separately via an
existing API\n\nFixes
https://github.com/elastic/kibana/issues/211745\n\n\n<img width=\"1728\"
alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/2244948f-e42d-443d-b6e7-42e0a72b1bfa\"\n/>\n\n---------\n\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>\nCo-authored-by:
Justin Kambic
<jk@elastic.co>","sha":"aaf73ff5f67a9163773ff43868f329e3b5693242","branchLabelMapping":{"^v9.1.0$":"main","^v8.19.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","Team:obs-ux-management","backport:version","v8.18.0","v9.1.0"],"title":"[Synthetics]
Fix overview error popover
!!","number":211431,"url":"https://github.com/elastic/kibana/pull/211431","mergeCommit":{"message":"[Synthetics]
Fix overview error popover !! (elastic#211431)\n\n## Summary\n\nFix overview
error popover !!\n\nPings aren't being returned as part of overview data
anymore, so had to\nadd redux actions to fetch it separately via an
existing API\n\nFixes
https://github.com/elastic/kibana/issues/211745\n\n\n<img width=\"1728\"
alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/2244948f-e42d-443d-b6e7-42e0a72b1bfa\"\n/>\n\n---------\n\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>\nCo-authored-by:
Justin Kambic
<jk@elastic.co>","sha":"aaf73ff5f67a9163773ff43868f329e3b5693242"}},"sourceBranch":"main","suggestedTargetBranches":["9.0","8.18"],"targetPullRequestStates":[{"branch":"9.0","label":"v9.0.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.18","label":"v8.18.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/211431","number":211431,"mergeCommit":{"message":"[Synthetics]
Fix overview error popover !! (elastic#211431)\n\n## Summary\n\nFix overview
error popover !!\n\nPings aren't being returned as part of overview data
anymore, so had to\nadd redux actions to fetch it separately via an
existing API\n\nFixes
https://github.com/elastic/kibana/issues/211745\n\n\n<img width=\"1728\"
alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/2244948f-e42d-443d-b6e7-42e0a72b1bfa\"\n/>\n\n---------\n\nCo-authored-by:
kibanamachine
<42973632+kibanamachine@users.noreply.github.com>\nCo-authored-by:
Justin Kambic
<jk@elastic.co>","sha":"aaf73ff5f67a9163773ff43868f329e3b5693242"}}]}]
BACKPORT-->

Co-authored-by: Shahzad <shahzad31comp@gmail.com>
  • Loading branch information
kibanamachine and shahzad31 authored Feb 21, 2025
1 parent 2e7ba5b commit 83e37ba
Show file tree
Hide file tree
Showing 17 changed files with 235 additions and 100 deletions.
1 change: 0 additions & 1 deletion packages/kbn-babel-preset/styled_components_files.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ export const OverviewStatusMetaDataCodec = t.intersection([
t.partial({
projectId: t.string,
updated_at: t.string,
ping: OverviewPingCodec,
timestamp: t.string,
spaceId: t.string,
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { OverviewLoader } from '../overview_loader';
import { useFilteredGroupMonitors } from './use_filtered_group_monitors';
import { OverviewStatusMetaData } from '../../types';
import { selectOverviewStatus } from '../../../../../state/overview_status';
import { MetricItem } from '../metric_item';
import { MetricItem } from '../metric_item/metric_item';

const PER_ROW = 4;
const DEFAULT_ROW_SIZE = 2;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* 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 { EuiButtonIcon, useEuiShadow, useEuiTheme } from '@elastic/eui';
import * as React from 'react';
import { useRef } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { i18n } from '@kbn/i18n';
import { css } from '@emotion/react';
import { useSyntheticsSettingsContext } from '../../../../../contexts';
import { selectErrorPopoverState, toggleErrorPopoverOpen } from '../../../../../state';

export const MetricErrorIcon = ({ configIdByLocation }: { configIdByLocation: string }) => {
const isPopoverOpen = useSelector(selectErrorPopoverState);
const dispatch = useDispatch();

const setIsPopoverOpen = () => {
dispatch(toggleErrorPopoverOpen(configIdByLocation));
};
const timer = useRef<NodeJS.Timeout | null>(null);
const euiShadow = useEuiShadow('s');

const theme = useEuiTheme().euiTheme;
const { darkMode } = useSyntheticsSettingsContext();

return (
<div
css={css`
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
width: 32px;
height: 32px;
background: ${darkMode ? theme.colors.backgroundBaseSubdued : theme.colors.lightestShade};
border: 1px solid ${darkMode ? theme.colors.darkShade : theme.colors.lightShade};
box-shadow: ${euiShadow};
border-radius: 16px;
flex: none;
order: 0;
flex-grow: 0;
`}
onMouseEnter={() => {
// show popover with delay
if (timer.current) {
clearTimeout(timer.current);
}
timer.current = setTimeout(() => {
setIsPopoverOpen();
}, 300);
}}
onMouseLeave={() => {
if (isPopoverOpen) {
return;
} else if (timer.current) {
clearTimeout(timer.current);
}
}}
onClick={() => {
if (configIdByLocation === isPopoverOpen) {
dispatch(toggleErrorPopoverOpen(null));
} else {
dispatch(toggleErrorPopoverOpen(configIdByLocation));
}
}}
onKeyDown={(e) => {
if (e.key === 'Enter') {
if (configIdByLocation === isPopoverOpen) {
dispatch(toggleErrorPopoverOpen(null));
} else {
dispatch(toggleErrorPopoverOpen(configIdByLocation));
}
}
}}
>
<EuiButtonIcon
data-test-subj="syntheticsMetricItemIconButton"
iconType="warning"
color="danger"
size="m"
aria-label={ERROR_DETAILS}
/>
</div>
);
};
const ERROR_DETAILS = i18n.translate('xpack.synthetics.errorDetails.label', {
defaultMessage: 'Error details',
});
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,25 @@ import { useKibana } from '@kbn/kibana-react-plugin/public';
import moment from 'moment';
import React, { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { OverviewStatusMetaData } from '../../../../../../../common/runtime_types';
import { ClientPluginsStart } from '../../../../../../plugin';
import { useLocationName, useStatusByLocationOverview } from '../../../../hooks';
import { OverviewStatusMetaData } from '../../../../../../../../common/runtime_types';
import { ClientPluginsStart } from '../../../../../../../plugin';
import { useLocationName, useStatusByLocationOverview } from '../../../../../hooks';
import {
selectErrorPopoverState,
selectOverviewTrends,
toggleErrorPopoverOpen,
} from '../../../../state';
} from '../../../../../state';
import {
hideTestNowFlyoutAction,
manualTestRunInProgressSelector,
toggleTestNowFlyoutAction,
} from '../../../../state/manual_test_runs';
import { formatDuration } from '../../../../utils/formatting';
import { ActionsPopover } from './actions_popover';
import { MetricItemBody } from './metric_item/metric_item_body';
import { MetricItemExtra } from './metric_item/metric_item_extra';
} from '../../../../../state/manual_test_runs';
import { formatDuration } from '../../../../../utils/formatting';
import { ActionsPopover } from '../actions_popover';
import { MetricItemBody } from './metric_item_body';
import { MetricItemExtra } from './metric_item_extra';
import { MetricItemIcon } from './metric_item_icon';
import { FlyoutParamProps } from './types';
import { FlyoutParamProps } from '../types';

const METRIC_ITEM_HEIGHT = 160;

Expand Down Expand Up @@ -75,7 +75,7 @@ export const MetricItem = ({
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
const isErrorPopoverOpen = useSelector(selectErrorPopoverState);
const locationName = useLocationName(monitor);
const { status, timestamp, ping, configIdByLocation } = useStatusByLocationOverview({
const { status, timestamp, configIdByLocation } = useStatusByLocationOverview({
configId: monitor.configId,
locationId: monitor.locationId,
});
Expand Down Expand Up @@ -190,7 +190,6 @@ export const MetricItem = ({
<MetricItemIcon
monitor={monitor}
status={status}
ping={ping}
timestamp={timestamp}
configIdByLocation={configIdByLocation}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,24 @@ import {
EuiPopoverTitle,
EuiPopoverFooter,
EuiButton,
useEuiShadow,
EuiCallOut,
EuiFlexGroup,
EuiFlexItem,
EuiLink,
EuiSpacer,
EuiSkeletonText,
} from '@elastic/eui';
import { useDispatch, useSelector } from 'react-redux';
import styled from 'styled-components';
import styled from '@emotion/styled';
import { i18n } from '@kbn/i18n';
import { euiStyled } from '@kbn/kibana-react-plugin/common';
import { useRef } from 'react';
import { selectErrorPopoverState, toggleErrorPopoverOpen } from '../../../../state';
import { useErrorDetailsLink } from '../../../common/links/error_details_link';
import { OverviewPing, OverviewStatusMetaData } from '../../../../../../../common/runtime_types';
import { isTestRunning, manualTestRunSelector } from '../../../../state/manual_test_runs';
import { useDateFormat } from '../../../../../../hooks/use_date_format';

import { MetricErrorIcon } from './metric_error_icon';
import { OverviewStatusMetaData } from '../../../../../../../../common/runtime_types';
import { isTestRunning, manualTestRunSelector } from '../../../../../state/manual_test_runs';
import { selectErrorPopoverState, toggleErrorPopoverOpen } from '../../../../../state';
import { useErrorDetailsLink } from '../../../../common/links/error_details_link';
import { useDateFormat } from '../../../../../../../hooks/use_date_format';
import { useLatestError } from './use_latest_error';

const Container = styled.div`
display: inline-block;
Expand All @@ -43,35 +44,31 @@ const Container = styled.div`
export const MetricItemIcon = ({
monitor,
status,
ping,
timestamp,
configIdByLocation,
}: {
monitor: OverviewStatusMetaData;
status: string;
configIdByLocation: string;
timestamp?: string;
ping?: OverviewPing;
}) => {
const testNowRun = useSelector(manualTestRunSelector(monitor.configId));
const isPopoverOpen = useSelector(selectErrorPopoverState);
const { latestPing } = useLatestError({
configIdByLocation,
monitorId: monitor.configId,
locationLabel: monitor.locationLabel,
});

const dispatch = useDispatch();

const timer = useRef<NodeJS.Timeout | null>(null);

const setIsPopoverOpen = () => {
dispatch(toggleErrorPopoverOpen(configIdByLocation));
};

const inProgress = isTestRunning(testNowRun);

const errorLink = useErrorDetailsLink({
configId: monitor.configId,
stateId: ping?.state?.id!,
stateId: latestPing?.state?.id!,
locationId: monitor.locationId,
});
const euiShadow = useEuiShadow('s');

const formatter = useDateFormat();
const testTime = formatter(timestamp);
Expand All @@ -94,42 +91,7 @@ export const MetricItemIcon = ({
return (
<Container>
<EuiPopover
button={
<StyledIcon
onMouseEnter={() => {
// show popover with delay
if (timer.current) {
clearTimeout(timer.current);
}
timer.current = setTimeout(() => {
setIsPopoverOpen();
}, 300);
}}
onMouseLeave={() => {
if (isPopoverOpen) {
return;
} else if (timer.current) {
clearTimeout(timer.current);
}
}}
boxShadow={euiShadow}
onClick={() => {
if (configIdByLocation === isPopoverOpen) {
dispatch(toggleErrorPopoverOpen(null));
} else {
dispatch(toggleErrorPopoverOpen(configIdByLocation));
}
}}
>
<EuiButtonIcon
data-test-subj="syntheticsMetricItemIconButton"
iconType="warning"
color="danger"
size="m"
aria-label={ERROR_DETAILS}
/>
</StyledIcon>
}
button={<MetricErrorIcon configIdByLocation={configIdByLocation} />}
isOpen={configIdByLocation === isPopoverOpen}
closePopover={closePopover}
anchorPosition="upCenter"
Expand All @@ -145,27 +107,43 @@ export const MetricItemIcon = ({
data-test-subj="syntheticsMetricItemIconButton"
iconType="cross"
onClick={closePopover}
aria-label={i18n.translate(
'xpack.synthetics.metricItemIcon.euiButtonIcon.closePopover',
{
defaultMessage: 'Close popover',
}
)}
/>
</EuiFlexItem>
</EuiFlexGroup>
</EuiPopoverTitle>
<div style={{ width: '300px' }}>
{ping?.url?.full && (
<div style={{ width: '300px', overflowWrap: 'break-word' }}>
{latestPing?.url?.full && (
<>
{i18n.translate('xpack.synthetics.metricItemIcon.div.urlLabel', {
defaultMessage: 'URL: ',
})}
<EuiLink
data-test-subj="syntheticsMetricItemIconLink"
href={ping.url.full}
href={latestPing.url.full}
target="_blank"
>
{ping.url.full}
{latestPing.url.full}
</EuiLink>
<EuiSpacer size="s" />
</>
)}
<EuiCallOut title={ping?.error?.message} color="danger" iconType="warning" />
<EuiCallOut
title={
latestPing?.error?.message ? (
latestPing?.error?.message
) : (
<EuiSkeletonText lines={2} />
)
}
color="danger"
iconType="warning"
/>
</div>
<EuiPopoverFooter>
<EuiButton
Expand All @@ -181,14 +159,14 @@ export const MetricItemIcon = ({
</Container>
);
} else {
if (ping?.url) {
if (latestPing?.url) {
return (
<Container>
<EuiButtonIcon
title={ping.url.full}
title={latestPing.url.full}
color="text"
data-test-subj="syntheticsMetricItemIconButton"
href={ping.url.full}
href={latestPing.url.full}
iconType="link"
target="_blank"
aria-label={i18n.translate('xpack.synthetics.metricItemIcon.euiButtonIcon.monitorUrl', {
Expand All @@ -209,22 +187,3 @@ const ERROR_DETAILS = i18n.translate('xpack.synthetics.errorDetails.label', {
const TEST_IN_PROGRESS = i18n.translate('xpack.synthetics.inProgress.label', {
defaultMessage: 'Manual test run is in progress.',
});

const StyledIcon = euiStyled.div<{ boxShadow: string }>`
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
width: 32px;
height: 32px;
background: ${({ theme }) =>
theme.darkMode ? theme.eui.euiColorDarkestShade : theme.eui.euiColorLightestShade};
border: 1px solid ${({ theme }) =>
theme.darkMode ? theme.eui.euiColorDarkShade : theme.eui.euiColorLightShade};
${({ boxShadow }) => boxShadow}
border-radius: 16px;
flex: none;
order: 0;
flex-grow: 0;
`;
Loading

0 comments on commit 83e37ba

Please sign in to comment.