mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Synthetics] Adjust disrupted UI elements on small screens and when flyout is open (#152812)
Fixes #150615 Fixes #147944 ## Summary Takes care of wrapping and overflowing of panels on small screens or when monitor test run flyout is open in push mode. The PR addresses the Monitor Overview, Management, Monitor Details and Monitor Add/Edit pages.
This commit is contained in:
parent
b06400373c
commit
e29265e51c
42 changed files with 586 additions and 198 deletions
|
@ -136,8 +136,10 @@ journey(`TestNowMode`, async ({ page, params }) => {
|
|||
await services.addTestSummaryDocument({ testRunId, docType: 'stepEnd', stepIndex: 1 });
|
||||
|
||||
await page.waitForSelector('text=1 step completed');
|
||||
await page.waitForSelector('text=Go to https://www.google.com');
|
||||
await page.waitForSelector('text=1.42 s');
|
||||
await page.waitForSelector(
|
||||
'.euiTableRowCell--hideForMobile :has-text("Go to https://www.google.com")'
|
||||
);
|
||||
await page.waitForSelector('.euiTableRowCell--hideForMobile :has-text("1.42 s")');
|
||||
await page.waitForSelector('text=Complete');
|
||||
});
|
||||
|
||||
|
@ -146,7 +148,7 @@ journey(`TestNowMode`, async ({ page, params }) => {
|
|||
await retry.tryForTime(90 * 1000, async () => {
|
||||
await page.waitForSelector('text=2 steps completed');
|
||||
await page.waitForSelector('text="Go to step 2"');
|
||||
await page.waitForSelector('text=788 ms');
|
||||
await page.waitForSelector('div:has-text("788 ms")');
|
||||
await page.waitForSelector('text=IN PROGRESS');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -65,6 +65,6 @@ journey(`TestRunDetailsPage`, async ({ page, params }) => {
|
|||
|
||||
await page.waitForSelector('text=Test run details');
|
||||
await page.waitForSelector('text=Go to https://www.google.com');
|
||||
await page.waitForSelector('text=After 2.12 s');
|
||||
await page.waitForSelector('div:has-text("After 2.12 s")');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -38,9 +38,18 @@ export const LocationStatusBadges = ({
|
|||
const locationsToDisplay = locations.slice(0, toDisplay);
|
||||
|
||||
return (
|
||||
<EuiFlexGroup wrap gutterSize="xs" css={{ maxWidth: 450, overflow: 'hidden' }}>
|
||||
<EuiFlexGroup
|
||||
gutterSize="xs"
|
||||
css={{ maxWidth: 450, overflow: 'hidden' }}
|
||||
wrap
|
||||
responsive={false}
|
||||
>
|
||||
{locationsToDisplay.map((loc) => (
|
||||
<EuiFlexItem key={loc.id} grow={false} css={{ overflow: 'hidden' }}>
|
||||
<EuiFlexItem
|
||||
key={loc.id}
|
||||
grow={false}
|
||||
css={{ overflow: 'hidden', flexBasis: 'fit-content' }}
|
||||
>
|
||||
<MonitorDetailLinkForLocation
|
||||
configId={configId}
|
||||
locationId={loc.id}
|
||||
|
|
|
@ -68,6 +68,7 @@ export const MonitorDetailsPanel = ({
|
|||
return (
|
||||
<PanelWithTitle
|
||||
paddingSize="m"
|
||||
margin="none"
|
||||
title={MONITOR_DETAILS_LABEL}
|
||||
titleLeftAlign
|
||||
hasBorder={hasBorder}
|
||||
|
|
|
@ -9,8 +9,16 @@ import { EuiPanel, EuiTitle, useEuiTheme, EuiPanelProps } from '@elastic/eui';
|
|||
import React from 'react';
|
||||
|
||||
export const PanelWithTitle: React.FC<
|
||||
{ title?: string; titleLeftAlign?: boolean } & EuiPanelProps
|
||||
> = ({ title, hasBorder = true, hasShadow = false, children, titleLeftAlign, ...props }) => {
|
||||
{ title?: string; titleLeftAlign?: boolean; margin?: string } & EuiPanelProps
|
||||
> = ({
|
||||
title,
|
||||
hasBorder = true,
|
||||
hasShadow = false,
|
||||
children,
|
||||
titleLeftAlign,
|
||||
margin,
|
||||
...props
|
||||
}) => {
|
||||
const { euiTheme } = useEuiTheme();
|
||||
|
||||
return (
|
||||
|
@ -19,7 +27,7 @@ export const PanelWithTitle: React.FC<
|
|||
<EuiTitle size="xs">
|
||||
<h3
|
||||
css={{
|
||||
margin: euiTheme.size.s,
|
||||
margin: margin ?? euiTheme.size.s,
|
||||
marginBottom: 0,
|
||||
...(titleLeftAlign ? { marginLeft: 0 } : {}),
|
||||
}}
|
||||
|
|
|
@ -5,11 +5,13 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { EuiButtonEmpty, EuiButtonIcon } from '@elastic/eui';
|
||||
import React from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { useSelectedLocation } from '../../monitor_details/hooks/use_selected_location';
|
||||
import { EuiButtonEmpty, EuiButtonIcon } from '@elastic/eui';
|
||||
import { CommonProps } from '@elastic/eui/src/components/common';
|
||||
|
||||
import { useSyntheticsSettingsContext } from '../../../contexts';
|
||||
import { useSelectedLocation } from '../../monitor_details/hooks/use_selected_location';
|
||||
|
||||
export const StepDetailsLinkIcon = ({
|
||||
stepIndex,
|
||||
|
@ -18,7 +20,8 @@ export const StepDetailsLinkIcon = ({
|
|||
asButton,
|
||||
label,
|
||||
target = '_self',
|
||||
}: {
|
||||
...commonProps
|
||||
}: CommonProps & {
|
||||
checkGroup: string;
|
||||
label?: string;
|
||||
configId: string;
|
||||
|
@ -29,13 +32,16 @@ export const StepDetailsLinkIcon = ({
|
|||
const { basePath } = useSyntheticsSettingsContext();
|
||||
const selectedLocation = useSelectedLocation();
|
||||
|
||||
const stepDetailsLink = `${basePath}/app/synthetics/monitor/${configId}/test-run/${checkGroup}/step/${stepIndex}?locationId=${selectedLocation?.id}`;
|
||||
|
||||
if (asButton) {
|
||||
return (
|
||||
<EuiButtonEmpty
|
||||
data-test-subj="syntheticsStepDetailsLinkIconButton"
|
||||
{...commonProps}
|
||||
flush="left"
|
||||
iconType="apmTrace"
|
||||
href={`${basePath}/app/synthetics/monitor/${configId}/test-run/${checkGroup}/step/${stepIndex}?locationId=${selectedLocation?.id}`}
|
||||
href={stepDetailsLink}
|
||||
>
|
||||
{label ?? VIEW_DETAILS}
|
||||
</EuiButtonEmpty>
|
||||
|
@ -44,10 +50,11 @@ export const StepDetailsLinkIcon = ({
|
|||
|
||||
return (
|
||||
<EuiButtonIcon
|
||||
{...commonProps}
|
||||
aria-label={VIEW_DETAILS}
|
||||
title={VIEW_DETAILS}
|
||||
size="s"
|
||||
href={`${basePath}/app/synthetics/monitor/${configId}/test-run/${checkGroup}/step/${stepIndex}?locationId=${selectedLocation?.id}`}
|
||||
href={stepDetailsLink}
|
||||
target={target}
|
||||
iconType="apmTrace"
|
||||
/>
|
||||
|
|
|
@ -6,7 +6,14 @@
|
|||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React, { CSSProperties, ReactElement, useCallback, useEffect, useState } from 'react';
|
||||
import React, {
|
||||
CSSProperties,
|
||||
ReactElement,
|
||||
PropsWithChildren,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useState,
|
||||
} from 'react';
|
||||
import {
|
||||
EuiBasicTable,
|
||||
EuiBasicTableColumn,
|
||||
|
@ -14,7 +21,10 @@ import {
|
|||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiText,
|
||||
EuiTextProps,
|
||||
EuiTitle,
|
||||
useEuiTheme,
|
||||
useIsWithinMinBreakpoint,
|
||||
} from '@elastic/eui';
|
||||
import { EuiThemeComputed } from '@elastic/eui/src/services/theme/types';
|
||||
|
||||
|
@ -22,7 +32,11 @@ import { StepTabs } from '../../test_run_details/step_tabs';
|
|||
import { ResultDetails } from './result_details';
|
||||
import { JourneyStep } from '../../../../../../common/runtime_types';
|
||||
import { JourneyStepScreenshotContainer } from '../screenshot/journey_step_screenshot_container';
|
||||
import { ScreenshotImageSize, THUMBNAIL_SCREENSHOT_SIZE } from '../screenshot/screenshot_size';
|
||||
import {
|
||||
ScreenshotImageSize,
|
||||
THUMBNAIL_SCREENSHOT_SIZE,
|
||||
THUMBNAIL_SCREENSHOT_SIZE_MOBILE,
|
||||
} from '../screenshot/screenshot_size';
|
||||
import { StepDetailsLinkIcon } from '../links/step_details_link';
|
||||
|
||||
import { parseBadgeStatus, getTextColorForMonitorStatus } from './status_badge';
|
||||
|
@ -61,6 +75,7 @@ export const BrowserStepsList = ({
|
|||
const [itemIdToExpandedRowMap, setItemIdToExpandedRowMap] = useState<
|
||||
Record<string, ReactElement>
|
||||
>({});
|
||||
const isTabletOrGreater = useIsWithinMinBreakpoint('s');
|
||||
|
||||
const toggleDetails = useCallback(
|
||||
(item: JourneyStep) => {
|
||||
|
@ -118,8 +133,13 @@ export const BrowserStepsList = ({
|
|||
field: 'synthetics.step.index',
|
||||
name: '#',
|
||||
render: (stepIndex: number, item: JourneyStep) => (
|
||||
<StepNumber stepIndex={stepIndex} step={item} euiTheme={euiTheme} />
|
||||
<StyleForStepStatus step={item} euiTheme={euiTheme}>
|
||||
{stepIndex}
|
||||
</StyleForStepStatus>
|
||||
),
|
||||
mobileOptions: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
]
|
||||
: []),
|
||||
|
@ -139,15 +159,20 @@ export const BrowserStepsList = ({
|
|||
/>
|
||||
),
|
||||
mobileOptions: {
|
||||
render: (item: JourneyStep) => (
|
||||
<EuiText>
|
||||
<strong>
|
||||
{item.synthetics?.step?.index!}. {item.synthetics?.step?.name}
|
||||
</strong>
|
||||
</EuiText>
|
||||
render: (step: JourneyStep) => (
|
||||
<MobileRowDetails
|
||||
journeyStep={step}
|
||||
stepsLoading={loading}
|
||||
showStepNumber={showStepNumber}
|
||||
showLastSuccessful={showLastSuccessful}
|
||||
isExpanded={Boolean(itemIdToExpandedRowMap[step._id])}
|
||||
isTestNowMode={testNowMode}
|
||||
euiTheme={euiTheme}
|
||||
/>
|
||||
),
|
||||
header: SCREENSHOT_LABEL,
|
||||
header: false,
|
||||
enlarge: true,
|
||||
width: '100%',
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -166,6 +191,9 @@ export const BrowserStepsList = ({
|
|||
</EuiText>
|
||||
);
|
||||
},
|
||||
mobileOptions: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'synthetics.step.status',
|
||||
|
@ -177,6 +205,9 @@ export const BrowserStepsList = ({
|
|||
isExpanded={Boolean(itemIdToExpandedRowMap[item._id]) && !testNowMode}
|
||||
/>
|
||||
),
|
||||
mobileOptions: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
...(showLastSuccessful
|
||||
? [
|
||||
|
@ -189,6 +220,9 @@ export const BrowserStepsList = ({
|
|||
isExpanded={Boolean(itemIdToExpandedRowMap[item._id])}
|
||||
/>
|
||||
),
|
||||
mobileOptions: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
]
|
||||
: [
|
||||
|
@ -208,7 +242,6 @@ export const BrowserStepsList = ({
|
|||
align: 'right',
|
||||
field: 'timestamp',
|
||||
name: '',
|
||||
mobileOptions: { show: false },
|
||||
render: (_val: string, item) => (
|
||||
<StepDetailsLinkIcon
|
||||
checkGroup={item.monitor.check_group}
|
||||
|
@ -217,12 +250,14 @@ export const BrowserStepsList = ({
|
|||
target={testNowMode ? '_blank' : undefined}
|
||||
/>
|
||||
),
|
||||
mobileOptions: { show: false },
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiBasicTable
|
||||
css={{ overflowX: isTabletOrGreater ? 'auto' : undefined }}
|
||||
cellProps={(row) => {
|
||||
if (itemIdToExpandedRowMap[row._id]) {
|
||||
return {
|
||||
|
@ -234,8 +269,8 @@ export const BrowserStepsList = ({
|
|||
loading={loading}
|
||||
columns={columns}
|
||||
error={error?.message}
|
||||
isExpandable={true}
|
||||
hasActions={true}
|
||||
isExpandable={showExpand}
|
||||
hasActions={false}
|
||||
items={stepEnds}
|
||||
noItemsMessage={
|
||||
loading
|
||||
|
@ -254,15 +289,16 @@ export const BrowserStepsList = ({
|
|||
);
|
||||
};
|
||||
|
||||
const StepNumber = ({
|
||||
stepIndex,
|
||||
const StyleForStepStatus = ({
|
||||
step,
|
||||
textSize = 's',
|
||||
euiTheme,
|
||||
}: {
|
||||
stepIndex: number;
|
||||
children,
|
||||
}: PropsWithChildren<{
|
||||
step: JourneyStep;
|
||||
textSize?: EuiTextProps['size'];
|
||||
euiTheme: EuiThemeComputed;
|
||||
}) => {
|
||||
}>) => {
|
||||
const status = parseBadgeStatus(step.synthetics?.step?.status ?? '');
|
||||
|
||||
return (
|
||||
|
@ -270,14 +306,107 @@ const StepNumber = ({
|
|||
css={{
|
||||
fontWeight: euiTheme.font.weight.bold,
|
||||
}}
|
||||
size="s"
|
||||
size={textSize}
|
||||
color={euiTheme.colors[getTextColorForMonitorStatus(status)] as CSSProperties['color']}
|
||||
>
|
||||
{stepIndex}
|
||||
{children}
|
||||
</EuiText>
|
||||
);
|
||||
};
|
||||
|
||||
const MobileRowDetails = ({
|
||||
journeyStep,
|
||||
showStepNumber,
|
||||
showLastSuccessful,
|
||||
stepsLoading,
|
||||
isExpanded,
|
||||
isTestNowMode,
|
||||
euiTheme,
|
||||
}: {
|
||||
journeyStep: JourneyStep;
|
||||
showStepNumber: boolean;
|
||||
showLastSuccessful: boolean;
|
||||
stepsLoading: boolean;
|
||||
isExpanded: boolean;
|
||||
isTestNowMode: boolean;
|
||||
euiTheme: EuiThemeComputed;
|
||||
}) => {
|
||||
return (
|
||||
<EuiFlexGroup direction="column" gutterSize="s">
|
||||
<EuiTitle size="s">
|
||||
<h4>
|
||||
<StyleForStepStatus step={journeyStep} textSize="relative" euiTheme={euiTheme}>
|
||||
{showStepNumber && journeyStep.synthetics?.step?.index
|
||||
? `${journeyStep.synthetics.step.index}. `
|
||||
: null}{' '}
|
||||
{journeyStep.synthetics?.step?.name}
|
||||
</StyleForStepStatus>
|
||||
</h4>
|
||||
</EuiTitle>
|
||||
<EuiFlexGroup justifyContent="spaceEvenly" responsive={false} wrap={true} gutterSize="xl">
|
||||
<JourneyStepScreenshotContainer
|
||||
checkGroup={journeyStep.monitor.check_group}
|
||||
initialStepNumber={journeyStep.synthetics?.step?.index}
|
||||
stepStatus={journeyStep.synthetics.payload?.status}
|
||||
allStepsLoaded={!stepsLoading}
|
||||
retryFetchOnRevisit={true}
|
||||
size={THUMBNAIL_SCREENSHOT_SIZE_MOBILE}
|
||||
timestamp={journeyStep?.['@timestamp']}
|
||||
/>
|
||||
<div>
|
||||
<EuiFlexGroup direction="column" gutterSize="s">
|
||||
{[
|
||||
{
|
||||
title: RESULT_LABEL,
|
||||
description: (
|
||||
<ResultDetails
|
||||
step={journeyStep}
|
||||
pingStatus={journeyStep?.synthetics?.step?.status ?? 'skipped'}
|
||||
isExpanded={isExpanded && !isTestNowMode}
|
||||
/>
|
||||
),
|
||||
},
|
||||
...[
|
||||
showLastSuccessful
|
||||
? {
|
||||
title: LAST_SUCCESSFUL,
|
||||
description: (
|
||||
<ResultDetailsSuccessful step={journeyStep} isExpanded={isExpanded} />
|
||||
),
|
||||
}
|
||||
: {
|
||||
title: STEP_DURATION,
|
||||
description: <StepDurationText step={journeyStep} />,
|
||||
},
|
||||
],
|
||||
].map(({ title, description }) => (
|
||||
<EuiFlexGroup
|
||||
key={title}
|
||||
css={{ maxWidth: 'fit-content' }}
|
||||
direction="row"
|
||||
alignItems="baseline"
|
||||
gutterSize="xs"
|
||||
responsive={false}
|
||||
wrap={true}
|
||||
>
|
||||
<EuiText size="xs">{title}</EuiText>
|
||||
{description}
|
||||
</EuiFlexGroup>
|
||||
))}
|
||||
</EuiFlexGroup>
|
||||
</div>
|
||||
</EuiFlexGroup>
|
||||
<StepDetailsLinkIcon
|
||||
css={{ marginLeft: 'auto' }}
|
||||
checkGroup={journeyStep.monitor.check_group}
|
||||
stepIndex={journeyStep.synthetics?.step?.index}
|
||||
configId={journeyStep.config_id!}
|
||||
asButton={true}
|
||||
/>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
};
|
||||
|
||||
const RESULT_LABEL = i18n.translate('xpack.synthetics.monitor.result.label', {
|
||||
defaultMessage: 'Result',
|
||||
});
|
||||
|
|
|
@ -16,7 +16,7 @@ export const StatusBadge = ({ status }: { status: MonitorStatus }) => {
|
|||
}
|
||||
|
||||
return (
|
||||
<EuiBadge color={getBadgeColorForMonitorStatus(status)}>
|
||||
<EuiBadge color={getBadgeColorForMonitorStatus(status)} css={{ maxWidth: 'max-content' }}>
|
||||
{status === 'succeeded' ? COMPLETE_LABEL : status === 'failed' ? FAILED_LABEL : SKIPPED_LABEL}
|
||||
</EuiBadge>
|
||||
);
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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 { LazyObservabilityPageTemplateProps } from '@kbn/observability-plugin/public';
|
||||
import React from 'react';
|
||||
import { euiStyled } from '@kbn/kibana-react-plugin/common';
|
||||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
|
||||
import { ClientPluginsStart } from '../../../../../plugin';
|
||||
|
||||
export const WrappedPageTemplate = (props: LazyObservabilityPageTemplateProps) => {
|
||||
const { observability } = useKibana<ClientPluginsStart>().services;
|
||||
const PageTemplateComponent = observability.navigation.PageTemplate;
|
||||
|
||||
return <PageTemplateComponent {...props} />;
|
||||
};
|
||||
|
||||
export const SyntheticsPageTemplateComponent = euiStyled(WrappedPageTemplate)`
|
||||
&&& {
|
||||
.euiPageHeaderContent__top {
|
||||
flex-wrap: wrap;
|
||||
.euiTitle {
|
||||
min-width: 160px;
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
|
@ -27,6 +27,7 @@ import {
|
|||
EuiOutsideClickDetector,
|
||||
useIsWithinMaxBreakpoint,
|
||||
} from '@elastic/eui';
|
||||
import { euiStyled } from '@kbn/kibana-react-plugin/common';
|
||||
|
||||
import { SYNTHETICS_API_URLS } from '../../../../../../common/constants';
|
||||
import { SyntheticsSettingsContext } from '../../../contexts';
|
||||
|
@ -118,7 +119,7 @@ export const JourneyScreenshotDialog = ({
|
|||
}}
|
||||
onKeyDown={onKeyDown}
|
||||
>
|
||||
<EuiModalBody>
|
||||
<ModalBodyStyled css={{ display: 'flex' }}>
|
||||
<ScreenshotImage
|
||||
label={stepCountLabel}
|
||||
imgSrc={imgSrc}
|
||||
|
@ -127,7 +128,7 @@ export const JourneyScreenshotDialog = ({
|
|||
hasBorder={false}
|
||||
size={'full'}
|
||||
/>
|
||||
</EuiModalBody>
|
||||
</ModalBodyStyled>
|
||||
|
||||
<EuiModalFooter
|
||||
css={{
|
||||
|
@ -149,7 +150,7 @@ export const JourneyScreenshotDialog = ({
|
|||
{loading ? (
|
||||
<EuiProgress data-test-subj="screenshotImageLoadingProgress" size="xs" />
|
||||
) : null}
|
||||
<EuiFlexGroup alignItems="center" justifyContent="center">
|
||||
<EuiFlexGroup alignItems="center" justifyContent="center" responsive={false}>
|
||||
<EuiFlexItem grow={true}>
|
||||
<EuiButtonEmpty
|
||||
data-test-subj="screenshotImagePreviousButton"
|
||||
|
@ -165,7 +166,7 @@ export const JourneyScreenshotDialog = ({
|
|||
{prevAriaLabel}
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFlexItem grow={false} css={{ flexBasis: 'fit-content' }}>
|
||||
<EuiText color={euiTheme.colors.text}>{stepCountLabel}</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={true}>
|
||||
|
@ -206,6 +207,17 @@ export const JourneyScreenshotDialog = ({
|
|||
) : null;
|
||||
};
|
||||
|
||||
const ModalBodyStyled = euiStyled(EuiModalBody)`
|
||||
&&& {
|
||||
& > div {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 24px;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const getScreenshotUrl = ({
|
||||
basePath,
|
||||
checkGroup,
|
||||
|
|
|
@ -16,6 +16,7 @@ export type ScreenshotImageSize =
|
|||
| 'full';
|
||||
|
||||
export const THUMBNAIL_SCREENSHOT_SIZE: ScreenshotImageSize = [96, 64];
|
||||
export const THUMBNAIL_SCREENSHOT_SIZE_MOBILE: ScreenshotImageSize = [180, 112];
|
||||
export const POPOVER_SCREENSHOT_SIZE: ScreenshotImageSize = [640, 360];
|
||||
|
||||
export function getConfinedScreenshotSize(
|
||||
|
|
|
@ -41,8 +41,8 @@ export const AdvancedConfig = ({ readOnly }: { readOnly: boolean }) => {
|
|||
title={<h4>{configGroup.title}</h4>}
|
||||
fullWidth
|
||||
key={configGroup.title}
|
||||
descriptionFlexItemProps={{ style: { minWidth: 200 } }}
|
||||
fieldFlexItemProps={{ style: { minWidth: 500 } }}
|
||||
descriptionFlexItemProps={{ style: { minWidth: 208 } }}
|
||||
fieldFlexItemProps={{ style: { minWidth: 208 } }}
|
||||
style={{ flexWrap: 'wrap' }}
|
||||
>
|
||||
{configGroup.components.map((field) => {
|
||||
|
|
|
@ -7,12 +7,14 @@
|
|||
import React from 'react';
|
||||
|
||||
import styled from 'styled-components';
|
||||
import useThrottle from 'react-use/lib/useThrottle';
|
||||
|
||||
import { EuiPanel } from '@elastic/eui';
|
||||
import { euiStyled } from '@kbn/kibana-react-plugin/common';
|
||||
import { CodeEditor as MonacoCodeEditor } from '@kbn/kibana-react-plugin/public';
|
||||
|
||||
import { MonacoEditorLangId } from '../types';
|
||||
import { useDimensions } from '../../../hooks';
|
||||
|
||||
const CodeEditorContainer = styled(EuiPanel)`
|
||||
padding: 0;
|
||||
|
@ -39,29 +41,39 @@ export const CodeEditor = ({
|
|||
height = '250px',
|
||||
readOnly,
|
||||
}: CodeEditorProps) => {
|
||||
const { elementRef: containerRef, width: containerWidth } = useDimensions<HTMLDivElement>();
|
||||
const containerWidthThrottled = useThrottle(containerWidth, 500);
|
||||
|
||||
return (
|
||||
<CodeEditorContainer borderRadius="none" hasShadow={false} hasBorder={true}>
|
||||
<MonacoCodeContainer
|
||||
id={`${id}-editor`}
|
||||
aria-label={ariaLabel}
|
||||
data-test-subj="codeEditorContainer"
|
||||
<>
|
||||
<CodeEditorContainer
|
||||
panelRef={containerRef as React.Ref<HTMLDivElement>}
|
||||
borderRadius="none"
|
||||
hasShadow={false}
|
||||
hasBorder={true}
|
||||
>
|
||||
<MonacoCodeEditor
|
||||
languageId={languageId}
|
||||
width="100%"
|
||||
height={height}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
options={{
|
||||
renderValidationDecorations: value ? 'on' : 'off',
|
||||
readOnly,
|
||||
}}
|
||||
isCopyable={true}
|
||||
allowFullScreen={true}
|
||||
placeholder={placeholder}
|
||||
/>
|
||||
</MonacoCodeContainer>
|
||||
</CodeEditorContainer>
|
||||
<MonacoCodeContainer
|
||||
id={`${id}-editor`}
|
||||
aria-label={ariaLabel}
|
||||
data-test-subj="codeEditorContainer"
|
||||
>
|
||||
<MonacoCodeEditor
|
||||
languageId={languageId}
|
||||
width={containerWidthThrottled ?? '100%'}
|
||||
height={height}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
options={{
|
||||
renderValidationDecorations: value ? 'on' : 'off',
|
||||
readOnly,
|
||||
}}
|
||||
isCopyable={true}
|
||||
allowFullScreen={true}
|
||||
placeholder={placeholder}
|
||||
/>
|
||||
</MonacoCodeContainer>
|
||||
</CodeEditorContainer>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -10,10 +10,13 @@ import 'jest-canvas-mock';
|
|||
import React, { useState, useCallback } from 'react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { fireEvent, waitFor } from '@testing-library/react';
|
||||
import { mockGlobals } from '../../../utils/testing';
|
||||
import { render } from '../../../utils/testing/rtl_helpers';
|
||||
import { RequestBodyField } from './request_body_field';
|
||||
import { Mode } from '../types';
|
||||
|
||||
mockGlobals();
|
||||
|
||||
jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => ({
|
||||
htmlIdGenerator: () => () => `id-${Math.random()}`,
|
||||
}));
|
||||
|
|
|
@ -7,9 +7,12 @@
|
|||
|
||||
import React from 'react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { mockGlobals } from '../../../utils/testing';
|
||||
import { render } from '../../../utils/testing/rtl_helpers';
|
||||
import { SourceField } from './source_field';
|
||||
|
||||
mockGlobals();
|
||||
|
||||
jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => ({
|
||||
...jest.requireActual('@elastic/eui/lib/services/accessibility/html_id_generator'),
|
||||
htmlIdGenerator: () => () => `id-${Math.random()}`,
|
||||
|
|
|
@ -1118,7 +1118,7 @@ export const FIELD = (readOnly?: boolean): FieldMap => ({
|
|||
{
|
||||
value: DEFAULT_BROWSER_ADVANCED_FIELDS[ConfigKey.THROTTLING_CONFIG],
|
||||
inputDisplay: (
|
||||
<EuiFlexGroup alignItems="baseline" gutterSize="xs">
|
||||
<EuiFlexGroup alignItems="baseline" gutterSize="xs" responsive={false}>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText>
|
||||
{i18n.translate('xpack.synthetics.monitorConfig.throttling.options.default', {
|
||||
|
|
|
@ -56,7 +56,7 @@ export const ActionBar = ({ readOnly = false }: { readOnly: boolean }) => {
|
|||
<Redirect to={MONITORS_ROUTE} />
|
||||
) : (
|
||||
<>
|
||||
<EuiFlexGroup alignItems="center">
|
||||
<EuiFlexGroup alignItems="center" wrap={true}>
|
||||
<EuiFlexItem grow={true}>
|
||||
{isEdit && defaultValues && (
|
||||
<div>
|
||||
|
@ -84,7 +84,7 @@ export const ActionBar = ({ readOnly = false }: { readOnly: boolean }) => {
|
|||
<EuiFlexItem grow={false}>
|
||||
<RunTestButton />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFlexItem grow={false} css={{ marginLeft: 'auto' }}>
|
||||
<NoPermissionsTooltip
|
||||
canEditSynthetics={canEditSynthetics}
|
||||
canAddPrivateMonitor={isEdit || canSavePrivateLocation}
|
||||
|
|
|
@ -6,9 +6,12 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { mockGlobals } from '../../utils/testing';
|
||||
import { render } from '../../utils/testing/rtl_helpers';
|
||||
import { MonitorAddPage } from './monitor_add_page';
|
||||
|
||||
mockGlobals();
|
||||
|
||||
jest.mock('@kbn/kibana-react-plugin/public', () => {
|
||||
const original = jest.requireActual('@kbn/kibana-react-plugin/public');
|
||||
return {
|
||||
|
|
|
@ -6,12 +6,15 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { mockGlobals } from '../../utils/testing';
|
||||
import { render } from '../../utils/testing/rtl_helpers';
|
||||
import { MonitorEditPage } from './monitor_edit_page';
|
||||
import { ConfigKey } from '../../../../../common/runtime_types';
|
||||
|
||||
import * as observabilityPublic from '@kbn/observability-plugin/public';
|
||||
|
||||
mockGlobals();
|
||||
|
||||
jest.mock('@kbn/observability-plugin/public');
|
||||
|
||||
jest.mock('@kbn/kibana-react-plugin/public', () => {
|
||||
|
|
|
@ -16,10 +16,10 @@ interface Props {
|
|||
export const Step = ({ description, children }: Props) => {
|
||||
return (
|
||||
<EuiFlexGroup gutterSize="s" wrap>
|
||||
<EuiFlexItem style={{ minWidth: 200 }}>
|
||||
<EuiFlexItem style={{ minWidth: 208 }}>
|
||||
<EuiText>{description}</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem style={{ minWidth: 500 }}>{children}</EuiFlexItem>
|
||||
<EuiFlexItem style={{ minWidth: 208 }}>{children}</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -49,7 +49,7 @@ const MONITOR_DETAILS_STEP = (readOnly: boolean = false): Step => ({
|
|||
});
|
||||
|
||||
const SCRIPT_RECORDER_BTNS = (
|
||||
<EuiFlexGroup justifyContent="flexStart">
|
||||
<EuiFlexGroup justifyContent="flexStart" wrap={true}>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
data-test-subj="syntheticsLaunchSyntheticsRecorderButton"
|
||||
|
|
|
@ -14,6 +14,7 @@ import {
|
|||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiBadge,
|
||||
useIsWithinMinBreakpoint,
|
||||
} from '@elastic/eui';
|
||||
import { useHistory, useParams } from 'react-router-dom';
|
||||
import moment from 'moment';
|
||||
|
@ -55,6 +56,8 @@ export const ErrorsList = ({
|
|||
return moment(b.state.started_at).valueOf() - moment(a.state.started_at).valueOf();
|
||||
})?.[0];
|
||||
|
||||
const isTabletOrGreater = useIsWithinMinBreakpoint('s');
|
||||
|
||||
const columns = [
|
||||
{
|
||||
field: 'item.state.started_at',
|
||||
|
@ -77,18 +80,21 @@ export const ErrorsList = ({
|
|||
}
|
||||
|
||||
return (
|
||||
<EuiFlexGroup gutterSize="m" alignItems="center">
|
||||
<EuiFlexGroup gutterSize="m" alignItems="center" wrap={true}>
|
||||
<EuiFlexItem grow={false} className="eui-textNoWrap">
|
||||
{link}
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiBadge iconType="clock" iconSide="right">
|
||||
<EuiBadge iconType="clock" iconSide="right" css={{ maxWidth: 'max-content' }}>
|
||||
{ACTIVE_LABEL}
|
||||
</EuiBadge>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
},
|
||||
mobileOptions: {
|
||||
header: false,
|
||||
},
|
||||
},
|
||||
...(isBrowserType
|
||||
? [
|
||||
|
@ -169,6 +175,7 @@ export const ErrorsList = ({
|
|||
<div>
|
||||
<EuiSpacer />
|
||||
<EuiInMemoryTable
|
||||
css={{ overflowX: isTabletOrGreater ? 'auto' : undefined }}
|
||||
tableLayout="auto"
|
||||
tableCaption={ERRORS_LIST_LABEL}
|
||||
loading={loading}
|
||||
|
|
|
@ -31,10 +31,10 @@ export const ErrorsTabContent = ({
|
|||
|
||||
return (
|
||||
<>
|
||||
<EuiFlexGroup gutterSize="m">
|
||||
<EuiFlexGroup gutterSize="m" wrap={true}>
|
||||
<EuiFlexItem grow={1}>
|
||||
<PanelWithTitle title={OVERVIEW_LABEL} titleLeftAlign>
|
||||
<EuiFlexGroup>
|
||||
<PanelWithTitle title={OVERVIEW_LABEL} titleLeftAlign css={{ minWidth: 260 }}>
|
||||
<EuiFlexGroup wrap={true} responsive={false}>
|
||||
<EuiFlexItem>
|
||||
{monitorId && (
|
||||
<MonitorErrorsCount
|
||||
|
@ -58,8 +58,8 @@ export const ErrorsTabContent = ({
|
|||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiFlexGroup gutterSize="m">
|
||||
<EuiFlexItem grow={2}>
|
||||
<EuiFlexGroup gutterSize="m" wrap={true}>
|
||||
<EuiFlexItem grow={2} css={{ minWidth: 260 }}>
|
||||
<PanelWithTitle title={ERRORS_LABEL}>
|
||||
<ErrorsList errorStates={errorStates} loading={loading} />
|
||||
</PanelWithTitle>
|
||||
|
|
|
@ -55,8 +55,8 @@ export const MonitorHistory = () => {
|
|||
<SyntheticsDatePicker fullWidth={true} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexGroup gutterSize="m">
|
||||
<EuiFlexItem grow={1}>
|
||||
<EuiFlexGroup gutterSize="m" wrap={true}>
|
||||
<EuiFlexItem css={{ flexBasis: '36%' }}>
|
||||
{/* @ts-expect-error Current @elastic/eui has the wrong types for the ref */}
|
||||
<EuiPanel hasShadow={false} hasBorder={true} panelRef={statsRef}>
|
||||
<EuiTitle size="xs">
|
||||
|
@ -127,7 +127,7 @@ export const MonitorHistory = () => {
|
|||
</EuiFlexGrid>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={2}>
|
||||
<EuiFlexItem css={{ flexBasis: '60%', minWidth: 260 }}>
|
||||
<EuiPanel hasShadow={false} hasBorder={true}>
|
||||
<EuiTitle size="xs">
|
||||
<h3>{DURATION_TREND_LABEL}</h3>
|
||||
|
|
|
@ -7,12 +7,12 @@
|
|||
|
||||
import React from 'react';
|
||||
import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiText, EuiTitle } from '@elastic/eui';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { useSyntheticsSettingsContext } from '../../../contexts';
|
||||
import { useSelectedLocation } from '../hooks/use_selected_location';
|
||||
|
||||
import { ConfigKey } from '../../../../../../common/runtime_types';
|
||||
import { MONITOR_HISTORY_ROUTE } from '../../../../../../common/constants';
|
||||
import { stringifyUrlParams } from '../../../utils/url_params';
|
||||
import { useGetUrlParams } from '../../../hooks';
|
||||
|
||||
import { useSelectedMonitor } from '../hooks/use_selected_monitor';
|
||||
|
||||
|
@ -25,9 +25,18 @@ export const MonitorStatusHeader = ({
|
|||
periodCaption,
|
||||
showViewHistoryButton,
|
||||
}: MonitorStatusPanelProps) => {
|
||||
const history = useHistory();
|
||||
const params = useGetUrlParams();
|
||||
const { basePath } = useSyntheticsSettingsContext();
|
||||
const { monitor } = useSelectedMonitor();
|
||||
const selectedLocation = useSelectedLocation();
|
||||
const search = stringifyUrlParams({
|
||||
locationId: selectedLocation?.id,
|
||||
dateRangeStart: 'now-24h',
|
||||
dateRangeEnd: 'now',
|
||||
});
|
||||
const viewDetailsUrl = `${basePath}/app/synthetics${MONITOR_HISTORY_ROUTE.replace(
|
||||
':monitorId',
|
||||
monitor?.[ConfigKey.CONFIG_ID] ?? ''
|
||||
)}${search}`;
|
||||
|
||||
const isLast24Hours = from === 'now-24h' && to === 'now';
|
||||
const periodCaptionText = !!periodCaption
|
||||
|
@ -43,45 +52,33 @@ export const MonitorStatusHeader = ({
|
|||
css={{
|
||||
marginBottom: 0,
|
||||
}}
|
||||
wrap={true}
|
||||
>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiTitle size="xs">
|
||||
<h4>{labels.STATUS_LABEL}</h4>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
{periodCaptionText ? (
|
||||
<EuiFlexGroup alignItems="center" responsive={false} wrap={false}>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText size="xs" color="subdued">
|
||||
{periodCaptionText}
|
||||
</EuiText>
|
||||
<EuiTitle size="xs">
|
||||
<h4>{labels.STATUS_LABEL}</h4>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
) : null}
|
||||
<EuiFlexItem grow={true} />
|
||||
{periodCaptionText ? (
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText size="xs" color="subdued">
|
||||
{periodCaptionText}
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
) : null}
|
||||
</EuiFlexGroup>
|
||||
|
||||
{showViewHistoryButton ? (
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButtonEmpty
|
||||
href={
|
||||
monitor?.[ConfigKey.CONFIG_ID]
|
||||
? history.createHref({
|
||||
pathname: MONITOR_HISTORY_ROUTE.replace(
|
||||
':monitorId',
|
||||
monitor[ConfigKey.CONFIG_ID]
|
||||
),
|
||||
search: stringifyUrlParams(
|
||||
{ ...params, dateRangeStart: 'now-24h', dateRangeEnd: 'now' },
|
||||
true
|
||||
),
|
||||
})
|
||||
: undefined
|
||||
}
|
||||
data-test-subj="monitorStatusChartViewHistoryButton"
|
||||
size="xs"
|
||||
iconType="list"
|
||||
>
|
||||
{labels.VIEW_HISTORY_LABEL}
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
<EuiButtonEmpty
|
||||
css={{ marginLeft: 'auto' }}
|
||||
href={viewDetailsUrl}
|
||||
data-test-subj="monitorStatusChartViewHistoryButton"
|
||||
size="xs"
|
||||
iconType="list"
|
||||
>
|
||||
{labels.VIEW_HISTORY_LABEL}
|
||||
</EuiButtonEmpty>
|
||||
) : null}
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
|
|
|
@ -60,6 +60,7 @@ export const LastTestRun = () => {
|
|||
latestPing={latestPing}
|
||||
loading={loading}
|
||||
stepsLoading={stepsLoading}
|
||||
isErrorDetails={false}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
@ -99,9 +100,7 @@ export const LastTestRunComponent = ({
|
|||
color="danger"
|
||||
iconType="warning"
|
||||
>
|
||||
{isErrorDetails ? (
|
||||
<></>
|
||||
) : (
|
||||
{isErrorDetails ? null : (
|
||||
<EuiButton
|
||||
data-test-subj="monitorTestRunViewErrorDetails"
|
||||
color="danger"
|
||||
|
@ -186,21 +185,21 @@ const PanelHeader = ({
|
|||
|
||||
return (
|
||||
<>
|
||||
<EuiFlexGroup alignItems="center" gutterSize="s">
|
||||
<EuiFlexGroup alignItems="center" gutterSize="s" responsive={false} wrap={true}>
|
||||
<EuiFlexItem grow={false}>{TitleNode}</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFlexItem grow={false} css={{ flexBasis: 'fit-content' }}>
|
||||
<StatusBadge
|
||||
status={parseBadgeStatus(latestPing?.summary?.down! > 0 ? 'fail' : 'success')}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={true}>
|
||||
<EuiText size="xs" color={euiTheme.colors.darkShade}>
|
||||
<EuiText css={{ whiteSpace: 'nowrap' }} size="xs" color={euiTheme.colors.darkShade}>
|
||||
{lastRunTimestamp}
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
|
||||
{isBrowserMonitor ? (
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFlexItem css={{ marginLeft: 'auto' }} grow={false}>
|
||||
<EuiButtonEmpty
|
||||
data-test-subj="monitorSummaryViewLastTestRun"
|
||||
size="xs"
|
||||
|
|
|
@ -47,7 +47,7 @@ export const MonitorAlerts = ({
|
|||
|
||||
return (
|
||||
<EuiPanel hasShadow={false} paddingSize="m" hasBorder>
|
||||
<EuiFlexGroup alignItems="center" gutterSize="m">
|
||||
<EuiFlexGroup alignItems="center" gutterSize="m" wrap={true}>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiTitle size="xs">
|
||||
<h3>
|
||||
|
@ -98,7 +98,7 @@ export const MonitorAlerts = ({
|
|||
<AlertActions monitorId={monitorId} from={from} to={to} />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiFlexGroup gutterSize="xs">
|
||||
<EuiFlexGroup gutterSize="xs" wrap={true}>
|
||||
<EuiFlexItem style={{ width: 80 }} grow={false}>
|
||||
<ExploratoryViewEmbeddable
|
||||
dataTestSubj="monitorActiveAlertsCount"
|
||||
|
@ -130,7 +130,7 @@ export const MonitorAlerts = ({
|
|||
]}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexItem css={{ minWidth: 80 }}>
|
||||
<ExploratoryViewEmbeddable
|
||||
sparklineMode
|
||||
customHeight="100px"
|
||||
|
@ -193,7 +193,7 @@ export const MonitorAlerts = ({
|
|||
]}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexItem css={{ minWidth: 80 }}>
|
||||
<ExploratoryViewEmbeddable
|
||||
sparklineMode
|
||||
customHeight="100px"
|
||||
|
|
|
@ -9,6 +9,7 @@ import React from 'react';
|
|||
import { EuiTitle, EuiPanel, EuiFlexGroup, EuiFlexItem, EuiText, EuiSpacer } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { LoadWhenInView } from '@kbn/observability-plugin/public';
|
||||
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';
|
||||
|
@ -32,6 +33,7 @@ export const MonitorSummary = () => {
|
|||
const { from, to } = useMonitorRangeFrom();
|
||||
|
||||
const monitorId = useMonitorQueryId();
|
||||
const isFlyoutOpen = !!useTestFlyoutOpen();
|
||||
|
||||
const dateLabel = from === 'now-30d/d' ? LAST_30_DAYS_LABEL : TO_DATE_LABEL;
|
||||
|
||||
|
@ -42,12 +44,12 @@ export const MonitorSummary = () => {
|
|||
|
||||
return (
|
||||
<MonitorPendingWrapper>
|
||||
<EuiFlexGroup gutterSize="m">
|
||||
<EuiFlexItem grow={1}>
|
||||
<EuiFlexGroup gutterSize="m" wrap={true} responsive={false}>
|
||||
<EuiFlexItem grow={1} css={{ flexBasis: '36%', minWidth: 260 }}>
|
||||
<MonitorDetailsPanelContainer />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={2}>
|
||||
<EuiPanel hasShadow={false} hasBorder paddingSize="m" css={{ height: 120 }}>
|
||||
<EuiFlexItem grow={1} css={{ flexBasis: '60%' }}>
|
||||
<EuiPanel hasShadow={false} grow={false} hasBorder paddingSize="m">
|
||||
<EuiFlexGroup alignItems="center" gutterSize="m">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiTitle size="xs">
|
||||
|
@ -60,39 +62,45 @@ export const MonitorSummary = () => {
|
|||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiFlexGroup gutterSize="s">
|
||||
<EuiFlexItem grow={false}>
|
||||
<AvailabilityPanel from={from} to={to} id="availabilityPercentageSummary" />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<AvailabilitySparklines from={from} to={to} id="availabilitySparklineSummary" />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false} style={{ marginLeft: 40 }}>
|
||||
<DurationPanel from={from} to={to} id="durationAvgValueSummary" />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<DurationSparklines from={from} to={to} id="durationAvgSparklineSummary" />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false} style={{ marginLeft: 40 }}>
|
||||
{monitorId && (
|
||||
<MonitorErrorsCount
|
||||
from={from}
|
||||
to={to}
|
||||
monitorId={[monitorId]}
|
||||
id="monitorErrorsCountSummary"
|
||||
/>
|
||||
)}
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
{monitorId && (
|
||||
<MonitorErrorSparklines
|
||||
from={from}
|
||||
to={to}
|
||||
monitorId={[monitorId]}
|
||||
id="monitorErrorsSparklineSummary"
|
||||
/>
|
||||
)}
|
||||
</EuiFlexItem>
|
||||
<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}>
|
||||
{monitorId && (
|
||||
<MonitorErrorsCount
|
||||
from={from}
|
||||
to={to}
|
||||
monitorId={[monitorId]}
|
||||
id="monitorErrorsCountSummary"
|
||||
/>
|
||||
)}
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem css={{ minWidth: 100 }}>
|
||||
{monitorId && (
|
||||
<MonitorErrorSparklines
|
||||
from={from}
|
||||
to={to}
|
||||
monitorId={[monitorId]}
|
||||
id="monitorErrorsSparklineSummary"
|
||||
/>
|
||||
)}
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexGroup>
|
||||
</EuiPanel>
|
||||
<EuiSpacer size="m" />
|
||||
|
@ -125,11 +133,11 @@ export const MonitorSummary = () => {
|
|||
showViewHistoryButton={true}
|
||||
/>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiFlexGroup gutterSize="m">
|
||||
<EuiFlexItem>
|
||||
<EuiFlexGroup gutterSize="m" wrap={true}>
|
||||
<EuiFlexItem css={isFlyoutOpen ? { minWidth: 260 } : undefined}>
|
||||
<LastTestRun />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexItem css={{ minWidth: 260 }}>
|
||||
<MonitorAlerts dateLabel={dateLabel} from={from} to={to} />
|
||||
<EuiSpacer size="m" />
|
||||
<StepDurationPanel />
|
||||
|
|
|
@ -9,9 +9,20 @@ import React, { MouseEvent, useMemo, useState } from 'react';
|
|||
import { useHistory, useParams } from 'react-router-dom';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiBasicTable, EuiBasicTableColumn, EuiPanel, EuiText } from '@elastic/eui';
|
||||
import {
|
||||
EuiBasicTable,
|
||||
EuiBasicTableColumn,
|
||||
EuiButtonEmpty,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiPanel,
|
||||
EuiText,
|
||||
useIsWithinMinBreakpoint,
|
||||
} from '@elastic/eui';
|
||||
import { Criteria } from '@elastic/eui/src/components/basic_table/basic_table';
|
||||
import { EuiTableSortingType } from '@elastic/eui/src/components/basic_table/table_types';
|
||||
import { THUMBNAIL_SCREENSHOT_SIZE_MOBILE } from '../../common/screenshot/screenshot_size';
|
||||
import { getErrorDetailsUrl } from '../monitor_errors/errors_list';
|
||||
|
||||
import { TestRunsTableHeader } from './test_runs_table_header';
|
||||
import { MONITOR_TYPES } from '../../../../../../common/constants';
|
||||
|
@ -29,7 +40,7 @@ import { useSelectedMonitor } from '../hooks/use_selected_monitor';
|
|||
import { useSelectedLocation } from '../hooks/use_selected_location';
|
||||
import { useMonitorPings } from '../hooks/use_monitor_pings';
|
||||
import { JourneyLastScreenshot } from '../../common/screenshot/journey_last_screenshot';
|
||||
import { useSyntheticsRefreshContext } from '../../../contexts';
|
||||
import { useSyntheticsRefreshContext, useSyntheticsSettingsContext } from '../../../contexts';
|
||||
|
||||
type SortableField = 'timestamp' | 'monitor.status' | 'monitor.duration.us';
|
||||
|
||||
|
@ -47,6 +58,7 @@ export const TestRunsTable = ({
|
|||
showViewHistoryButton = true,
|
||||
}: TestRunsTableProps) => {
|
||||
const history = useHistory();
|
||||
const { basePath } = useSyntheticsSettingsContext();
|
||||
const { monitorId } = useParams<{ monitorId: string }>();
|
||||
const [page, setPage] = useState({ index: 0, size: 10 });
|
||||
|
||||
|
@ -71,6 +83,7 @@ export const TestRunsTable = ({
|
|||
const pingsError = useSelector(selectPingsError);
|
||||
const { monitor } = useSelectedMonitor();
|
||||
const selectedLocation = useSelectedLocation();
|
||||
const isTabletOrGreater = useIsWithinMinBreakpoint('s');
|
||||
|
||||
const isBrowserMonitor = monitor?.[ConfigKey.MONITOR_TYPE] === DataStream.BROWSER;
|
||||
|
||||
|
@ -105,6 +118,18 @@ export const TestRunsTable = ({
|
|||
timestamp={timestamp}
|
||||
/>
|
||||
),
|
||||
mobileOptions: {
|
||||
header: false,
|
||||
render: (item) => (
|
||||
<EuiFlexGroup css={{ width: '100%', height: '100%' }} alignItems="center">
|
||||
<JourneyLastScreenshot
|
||||
checkGroupId={item.monitor.check_group}
|
||||
size={THUMBNAIL_SCREENSHOT_SIZE_MOBILE}
|
||||
timestamp={item.timestamp}
|
||||
/>
|
||||
</EuiFlexGroup>
|
||||
),
|
||||
},
|
||||
},
|
||||
]
|
||||
: []) as Array<EuiBasicTableColumn<Ping>>),
|
||||
|
@ -117,6 +142,17 @@ export const TestRunsTable = ({
|
|||
render: (timestamp: string, ping: Ping) => (
|
||||
<TestDetailsLink isBrowserMonitor={isBrowserMonitor} timestamp={timestamp} ping={ping} />
|
||||
),
|
||||
mobileOptions: {
|
||||
header: false,
|
||||
render: (item) => (
|
||||
<MobileRowDetails
|
||||
ping={item}
|
||||
isBrowserMonitor={isBrowserMonitor}
|
||||
basePath={basePath}
|
||||
locationId={selectedLocation?.id}
|
||||
/>
|
||||
),
|
||||
},
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
|
@ -125,6 +161,9 @@ export const TestRunsTable = ({
|
|||
name: RESULT_LABEL,
|
||||
sortable: true,
|
||||
render: (status: string) => <StatusBadge status={parseBadgeStatus(status ?? 'skipped')} />,
|
||||
mobileOptions: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
|
@ -134,6 +173,9 @@ export const TestRunsTable = ({
|
|||
render: (errorMessage: string) => (
|
||||
<EuiText size="s">{errorMessage?.length > 0 ? errorMessage : '-'}</EuiText>
|
||||
),
|
||||
mobileOptions: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
align: 'right',
|
||||
|
@ -142,6 +184,9 @@ export const TestRunsTable = ({
|
|||
name: DURATION_LABEL,
|
||||
sortable: true,
|
||||
render: (durationUs: number) => <EuiText size="s">{formatTestDuration(durationUs)}</EuiText>,
|
||||
mobileOptions: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -150,7 +195,6 @@ export const TestRunsTable = ({
|
|||
return {};
|
||||
}
|
||||
return {
|
||||
height: '85px',
|
||||
'data-test-subj': `row-${item.monitor.check_group}`,
|
||||
onClick: (evt: MouseEvent) => {
|
||||
const targetElem = evt.target as HTMLElement;
|
||||
|
@ -180,6 +224,7 @@ export const TestRunsTable = ({
|
|||
pings={pings}
|
||||
/>
|
||||
<EuiBasicTable
|
||||
css={{ overflowX: isTabletOrGreater ? 'auto' : undefined }}
|
||||
compressed={false}
|
||||
loading={pingsLoading}
|
||||
columns={columns}
|
||||
|
@ -213,6 +258,77 @@ export const TestRunsTable = ({
|
|||
);
|
||||
};
|
||||
|
||||
export const MobileRowDetails = ({
|
||||
ping,
|
||||
isBrowserMonitor,
|
||||
basePath,
|
||||
locationId,
|
||||
}: {
|
||||
ping: Ping;
|
||||
isBrowserMonitor: boolean;
|
||||
basePath: string;
|
||||
locationId?: string;
|
||||
}) => {
|
||||
return (
|
||||
<EuiFlexGroup direction="column" gutterSize="m">
|
||||
<TestDetailsLink isBrowserMonitor={isBrowserMonitor} timestamp={ping.timestamp} ping={ping} />
|
||||
<EuiFlexGroup
|
||||
justifyContent="spaceBetween"
|
||||
alignItems="center"
|
||||
wrap={false}
|
||||
responsive={false}
|
||||
>
|
||||
<EuiFlexItem css={{ flexBasis: 'fit-content' }}>
|
||||
<StatusBadge status={parseBadgeStatus(ping?.monitor?.status ?? 'skipped')} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem css={{ textAlign: 'right' }}>
|
||||
{ping?.state?.id! &&
|
||||
ping.config_id &&
|
||||
locationId &&
|
||||
parseBadgeStatus(ping?.monitor?.status ?? 'skipped') === 'failed' ? (
|
||||
<EuiButtonEmpty
|
||||
data-test-subj="monitorTestRunsListViewErrorDetails"
|
||||
color="danger"
|
||||
href={getErrorDetailsUrl({
|
||||
basePath,
|
||||
configId: ping.config_id,
|
||||
locationId,
|
||||
stateId: ping?.state?.id!,
|
||||
})}
|
||||
>
|
||||
{i18n.translate('xpack.synthetics.monitorDetails.summary.viewErrorDetails', {
|
||||
defaultMessage: 'View error details',
|
||||
})}
|
||||
</EuiButtonEmpty>
|
||||
) : null}
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
||||
<EuiFlexGroup direction="column" gutterSize="s">
|
||||
{[
|
||||
{
|
||||
title: DURATION_LABEL,
|
||||
description: formatTestDuration(ping?.monitor?.duration?.us),
|
||||
},
|
||||
].map(({ title, description }) => (
|
||||
<EuiFlexGroup
|
||||
key={title}
|
||||
css={{ maxWidth: 'fit-content' }}
|
||||
direction="row"
|
||||
alignItems="baseline"
|
||||
gutterSize="xs"
|
||||
responsive={false}
|
||||
wrap={true}
|
||||
>
|
||||
<EuiText size="xs">{title}</EuiText>
|
||||
{description}
|
||||
</EuiFlexGroup>
|
||||
))}
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
};
|
||||
|
||||
export const LAST_10_TEST_RUNS = i18n.translate(
|
||||
'xpack.synthetics.monitorDetails.summary.lastTenTestRuns',
|
||||
{
|
||||
|
|
|
@ -35,7 +35,7 @@ export const MonitorStats = ({
|
|||
<EuiFlexGroup gutterSize="l">
|
||||
<EuiPanel
|
||||
data-test-subj="syntheticsManagementSummaryStats"
|
||||
css={{ display: 'flex', flexDirection: 'column', gap: euiTheme.size.l, flexGrow: 0 }}
|
||||
css={{ display: 'flex', flexDirection: 'column', gap: euiTheme.size.l, flexGrow: 1 }}
|
||||
hasBorder={true}
|
||||
hasShadow={false}
|
||||
>
|
||||
|
@ -56,7 +56,13 @@ export const MonitorStats = ({
|
|||
</EuiPanel>
|
||||
|
||||
<EuiPanel
|
||||
css={{ display: 'flex', flexDirection: 'column', gap: euiTheme.size.l }}
|
||||
css={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: euiTheme.size.l,
|
||||
flexGrow: 12,
|
||||
minWidth: 260,
|
||||
}}
|
||||
hasBorder={true}
|
||||
hasShadow={false}
|
||||
>
|
||||
|
|
|
@ -68,7 +68,12 @@ export const OverviewGrid = memo(() => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<EuiFlexGroup justifyContent="spaceBetween" alignItems="baseline" responsive={false}>
|
||||
<EuiFlexGroup
|
||||
justifyContent="spaceBetween"
|
||||
alignItems="baseline"
|
||||
responsive={false}
|
||||
wrap={true}
|
||||
>
|
||||
<EuiFlexItem grow={true}>
|
||||
<OverviewPaginationInfo
|
||||
page={page}
|
||||
|
|
|
@ -62,7 +62,10 @@ export function TestResultHeader({
|
|||
{isCompleted ? (
|
||||
<EuiFlexGroup alignItems="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiBadge color={summaryDoc?.summary?.down! > 0 ? 'danger' : 'success'}>
|
||||
<EuiBadge
|
||||
color={summaryDoc?.summary?.down! > 0 ? 'danger' : 'success'}
|
||||
css={{ maxWidth: 'max-content' }}
|
||||
>
|
||||
{summaryDoc?.summary?.down! > 0 ? FAILED_LABEL : COMPLETED_LABEL}
|
||||
</EuiBadge>
|
||||
</EuiFlexItem>
|
||||
|
|
|
@ -44,17 +44,17 @@ export const StepMetaInfo = ({
|
|||
const isFailed = step.synthetics.step?.status === 'failed';
|
||||
|
||||
return (
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFlexItem grow={true}>
|
||||
<EuiTitle size="xxs">
|
||||
<h3>{STEP_NAME}</h3>
|
||||
</EuiTitle>
|
||||
<EuiText size="m">{step?.synthetics.step?.name}</EuiText>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiFlexGroup gutterSize="m" alignItems="center">
|
||||
<EuiFlexGroup gutterSize="m" alignItems="center" wrap={false}>
|
||||
<EuiFlexItem grow={false}>
|
||||
<StatusBadge status={parseBadgeStatus(step?.synthetics.step?.status)} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFlexItem grow={true}>
|
||||
{AFTER_LABEL}
|
||||
{formatTestDuration(step?.synthetics.step?.duration.us)}
|
||||
</EuiFlexItem>
|
||||
|
|
|
@ -25,8 +25,8 @@ export const StepScreenshotDetails = ({
|
|||
|
||||
return (
|
||||
<EuiPanel hasShadow={false} hasBorder={false} color="subdued">
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem css={{ alignItems: 'flex-start' }} grow={false}>
|
||||
<EuiFlexGroup wrap={true}>
|
||||
<EuiFlexItem css={{ margin: '0 auto' }} grow={false}>
|
||||
{step ? (
|
||||
<JourneyStepScreenshotContainer
|
||||
key={stepIndex}
|
||||
|
|
|
@ -47,8 +47,8 @@ export const TestRunDetails = () => {
|
|||
<>
|
||||
<TestRunErrorInfo journeyDetails={stepsData?.details} hasNoSteps={hasNoSteps} />
|
||||
{!hasNoSteps && (
|
||||
<EuiFlexGroup gutterSize="m">
|
||||
<EuiFlexItem grow={2} style={{ minWidth: 0 }}>
|
||||
<EuiFlexGroup gutterSize="m" wrap={true}>
|
||||
<EuiFlexItem css={{ flexBasis: '60%', minWidth: 260 }}>
|
||||
<EuiPanel hasShadow={false} hasBorder>
|
||||
<EuiFlexGroup alignItems="center">
|
||||
<EuiFlexItem grow={true}>
|
||||
|
@ -86,7 +86,7 @@ export const TestRunDetails = () => {
|
|||
<EuiSpacer size="m" />
|
||||
<TestRunSteps isLoading={stepsLoading} steps={stepsData?.steps ?? []} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={1}>
|
||||
<EuiFlexItem css={{ flexBasis: '36%', minWidth: 'min-content' }}>
|
||||
<StepDurationPanel legendPosition="bottom" />
|
||||
<EuiSpacer size="m" />
|
||||
<MonitorDetailsPanelContainer hideEnabled hideLocations />
|
||||
|
|
|
@ -21,6 +21,7 @@ import { useInspectorContext } from '@kbn/observability-plugin/public';
|
|||
import { useSyntheticsPrivileges } from './hooks/use_synthetics_priviliges';
|
||||
import { ClientPluginsStart } from '../../plugin';
|
||||
import { getMonitorsRoute } from './components/monitors_page/route_config';
|
||||
import { SyntheticsPageTemplateComponent } from './components/common/page_template/synthetics_page_template';
|
||||
import { getMonitorDetailsRoute } from './components/monitor_details/route_config';
|
||||
import { getStepDetailsRoute } from './components/step_details_page/route_config';
|
||||
import { getTestRunDetailsRoute } from './components/test_run_details/route_config';
|
||||
|
@ -54,13 +55,6 @@ const baseTitle = i18n.translate('xpack.synthetics.routes.baseTitle', {
|
|||
defaultMessage: 'Synthetics - Kibana',
|
||||
});
|
||||
|
||||
export const MONITOR_MANAGEMENT_LABEL = i18n.translate(
|
||||
'xpack.synthetics.monitorManagement.heading',
|
||||
{
|
||||
defaultMessage: 'Monitor Management',
|
||||
}
|
||||
);
|
||||
|
||||
const getRoutes = (
|
||||
euiTheme: EuiThemeComputed,
|
||||
history: ReturnType<typeof useHistory>,
|
||||
|
@ -177,7 +171,7 @@ const RouteInit: React.FC<Pick<RouteProps, 'path' | 'title'>> = ({ path, title }
|
|||
};
|
||||
|
||||
export const PageRouter: FC = () => {
|
||||
const { application, observability } = useKibana<ClientPluginsStart>().services;
|
||||
const { application } = useKibana<ClientPluginsStart>().services;
|
||||
const { addInspectorRequest } = useInspectorContext();
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const history = useHistory();
|
||||
|
@ -189,7 +183,6 @@ export const PageRouter: FC = () => {
|
|||
location,
|
||||
application.getUrlForApp(PLUGIN.SYNTHETICS_PLUGIN_ID)
|
||||
);
|
||||
const PageTemplateComponent = observability.navigation.PageTemplate;
|
||||
|
||||
apiService.addInspectorRequest = addInspectorRequest;
|
||||
|
||||
|
@ -209,21 +202,21 @@ export const PageRouter: FC = () => {
|
|||
<Route path={path} key={dataTestSubj} exact={true}>
|
||||
<div className={APP_WRAPPER_CLASS} data-test-subj={dataTestSubj}>
|
||||
<RouteInit title={title} path={path} />
|
||||
<PageTemplateComponent
|
||||
<SyntheticsPageTemplateComponent
|
||||
pageHeader={isUnPrivileged ? undefined : pageHeader}
|
||||
data-test-subj={'synthetics-page-template'}
|
||||
isPageDataLoaded={true}
|
||||
{...pageTemplateProps}
|
||||
>
|
||||
{isUnPrivileged || <RouteComponent />}
|
||||
</PageTemplateComponent>
|
||||
</SyntheticsPageTemplateComponent>
|
||||
</div>
|
||||
</Route>
|
||||
)
|
||||
)}
|
||||
<Route
|
||||
component={() => (
|
||||
<PageTemplateComponent>
|
||||
<SyntheticsPageTemplateComponent>
|
||||
<NotFoundPrompt
|
||||
actions={[
|
||||
<EuiButtonEmpty
|
||||
|
@ -240,7 +233,7 @@ export const PageRouter: FC = () => {
|
|||
</EuiButtonEmpty>,
|
||||
]}
|
||||
/>
|
||||
</PageTemplateComponent>
|
||||
</SyntheticsPageTemplateComponent>
|
||||
)}
|
||||
/>
|
||||
</Switch>
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export class MockResizeObserver implements ResizeObserver {
|
||||
private elements: Set<Element> = new Set();
|
||||
|
||||
observe(target: Element) {
|
||||
this.elements.add(target);
|
||||
}
|
||||
unobserve(target: Element) {
|
||||
this.elements.delete(target);
|
||||
}
|
||||
disconnect() {
|
||||
this.elements.clear();
|
||||
}
|
||||
}
|
|
@ -5,4 +5,5 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
export * from './mock_globals';
|
||||
export * from './rtl_helpers';
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* 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 { MockResizeObserver } from './__mocks__/resize_observer.mock';
|
||||
|
||||
export function mockGlobals() {
|
||||
global.ResizeObserver = MockResizeObserver;
|
||||
}
|
|
@ -35346,7 +35346,6 @@
|
|||
"xpack.synthetics.monitorManagement.getAPIKeyReducedPermissions.description": "Utilisez une clé d’API pour transmettre des moniteurs à distance à partir d'un pipeline CLI ou CD. Pour générer une clé d’API, vous devez disposer des autorisations de gérer les clés d’API et d’un accès en écriture à Uptime. Veuillez contacter votre administrateur.",
|
||||
"xpack.synthetics.monitorManagement.getProjectApiKey.label": "Générer une clé d'API de projet",
|
||||
"xpack.synthetics.monitorManagement.getProjectAPIKeyLabel.generate": "Générer une clé d'API de projet",
|
||||
"xpack.synthetics.monitorManagement.heading": "Gestion des moniteurs",
|
||||
"xpack.synthetics.monitorManagement.hostFieldLabel": "Hôte",
|
||||
"xpack.synthetics.monitorManagement.inProgress": "EN COURS",
|
||||
"xpack.synthetics.monitorManagement.invalidLabel": "Non valide",
|
||||
|
|
|
@ -35325,7 +35325,6 @@
|
|||
"xpack.synthetics.monitorManagement.getAPIKeyReducedPermissions.description": "APIキーを使用して、CLIまたはCDパイプラインからリモートでモニターをプッシュします。APIキーを生成するには、APIキーを管理する権限とアップタイム書き込み権限が必要です。管理者にお問い合わせください。",
|
||||
"xpack.synthetics.monitorManagement.getProjectApiKey.label": "プロジェクトAPIキーを生成",
|
||||
"xpack.synthetics.monitorManagement.getProjectAPIKeyLabel.generate": "プロジェクトAPIキーを生成",
|
||||
"xpack.synthetics.monitorManagement.heading": "モニター管理",
|
||||
"xpack.synthetics.monitorManagement.hostFieldLabel": "ホスト",
|
||||
"xpack.synthetics.monitorManagement.inProgress": "進行中",
|
||||
"xpack.synthetics.monitorManagement.invalidLabel": "無効",
|
||||
|
|
|
@ -35340,7 +35340,6 @@
|
|||
"xpack.synthetics.monitorManagement.getAPIKeyReducedPermissions.description": "使用 API 密钥从 CLI 或 CD 管道远程推送监测。要生成 API 密钥,您必须有权管理 API 密钥并具有 Uptime 写入权限。请联系您的管理员。",
|
||||
"xpack.synthetics.monitorManagement.getProjectApiKey.label": "生成项目 API 密钥",
|
||||
"xpack.synthetics.monitorManagement.getProjectAPIKeyLabel.generate": "生成项目 API 密钥",
|
||||
"xpack.synthetics.monitorManagement.heading": "监测管理",
|
||||
"xpack.synthetics.monitorManagement.hostFieldLabel": "主机",
|
||||
"xpack.synthetics.monitorManagement.inProgress": "进行中",
|
||||
"xpack.synthetics.monitorManagement.invalidLabel": "无效",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue