[Uptime] Uptime to APM integration (#34892)
* Add integrations popover. * Add some more functionality, code is WIP/mocked. * Trying some things WIP. * Import settings values from context. * Remove obsolete comment. * Add links. * Rename component. Clean up placeholder text and add translations. * Minor tweaks. Rename component file. * Fix import for renamed file. * Add domain to api query result fixtures. * Change integration to utilize EuiTable's actions API. * Add translation for new column heading. * Update busted snapshot. * Add snapshot test for new component. * Refactor integration links to dedicated component. * Remove obsolete index export. * Update monitor list test snapshot. * Default monitor list to empty array instead of undefined. * Extract URL construction to helper function. * Make entire link text clickable for APM integration. * Update broken test snapshot. * Fix type and update test snapshot.
This commit is contained in:
parent
a343899f75
commit
5fdb23c31d
|
@ -0,0 +1,29 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`IntegrationLink component renders without errors 1`] = `
|
||||||
|
<EuiLink
|
||||||
|
aria-label="foo"
|
||||||
|
color="subdued"
|
||||||
|
href="/app/foo?kuery=localhost"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<EuiFlexGroup>
|
||||||
|
<EuiFlexItem
|
||||||
|
grow={false}
|
||||||
|
>
|
||||||
|
<EuiToolTip
|
||||||
|
content="info for bar"
|
||||||
|
delay="regular"
|
||||||
|
position="top"
|
||||||
|
>
|
||||||
|
<EuiIcon
|
||||||
|
type="apmApp"
|
||||||
|
/>
|
||||||
|
</EuiToolTip>
|
||||||
|
</EuiFlexItem>
|
||||||
|
<EuiFlexItem>
|
||||||
|
click for bar
|
||||||
|
</EuiFlexItem>
|
||||||
|
</EuiFlexGroup>
|
||||||
|
</EuiLink>
|
||||||
|
`;
|
|
@ -39,6 +39,11 @@ exports[`MonitorList component renders a monitor list without errors 1`] = `
|
||||||
"name": "URL",
|
"name": "URL",
|
||||||
"render": [Function],
|
"render": [Function],
|
||||||
},
|
},
|
||||||
|
Object {
|
||||||
|
"field": "ping.url.full",
|
||||||
|
"name": "URL",
|
||||||
|
"render": [Function],
|
||||||
|
},
|
||||||
Object {
|
Object {
|
||||||
"align": "right",
|
"align": "right",
|
||||||
"field": "upSeries",
|
"field": "upSeries",
|
||||||
|
@ -46,6 +51,12 @@ exports[`MonitorList component renders a monitor list without errors 1`] = `
|
||||||
"render": [Function],
|
"render": [Function],
|
||||||
"width": "180px",
|
"width": "180px",
|
||||||
},
|
},
|
||||||
|
Object {
|
||||||
|
"align": "right",
|
||||||
|
"field": "ping",
|
||||||
|
"name": "Integrations",
|
||||||
|
"render": [Function],
|
||||||
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
executeQueryOptions={Object {}}
|
executeQueryOptions={Object {}}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { IntegrationLink } from '../integration_link';
|
||||||
|
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||||
|
|
||||||
|
describe('IntegrationLink component', () => {
|
||||||
|
it('renders without errors', () => {
|
||||||
|
const component = shallowWithIntl(
|
||||||
|
<IntegrationLink
|
||||||
|
ariaLabel="foo"
|
||||||
|
href="/app/foo?kuery=localhost"
|
||||||
|
iconType="apmApp"
|
||||||
|
message="click for bar"
|
||||||
|
tooltipContent="info for bar"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
expect(component).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
|
@ -440,8 +440,11 @@ describe('MonitorList component', () => {
|
||||||
it('renders a monitor list without errors', () => {
|
it('renders a monitor list without errors', () => {
|
||||||
const component = shallowWithIntl(
|
const component = shallowWithIntl(
|
||||||
<MonitorListComponent
|
<MonitorListComponent
|
||||||
|
basePath="foo"
|
||||||
dangerColor="red"
|
dangerColor="red"
|
||||||
data={{ monitorStatus: { monitors } }}
|
data={{ monitorStatus: { monitors } }}
|
||||||
|
dateRangeStart="now-15m"
|
||||||
|
dateRangeEnd="now"
|
||||||
loading={false}
|
loading={false}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
@ -9,6 +9,7 @@ export { EmptyStatusBar } from './empty_status_bar';
|
||||||
export { ErrorList } from './error_list';
|
export { ErrorList } from './error_list';
|
||||||
export { FilterBar } from './filter_bar';
|
export { FilterBar } from './filter_bar';
|
||||||
export { FilterBarLoading } from './filter_bar_loading';
|
export { FilterBarLoading } from './filter_bar_loading';
|
||||||
|
export { IntegrationLink } from './integration_link';
|
||||||
export { MonitorCharts } from './monitor_charts';
|
export { MonitorCharts } from './monitor_charts';
|
||||||
export { MonitorList } from './monitor_list';
|
export { MonitorList } from './monitor_list';
|
||||||
export { MonitorPageTitle } from './monitor_page_title';
|
export { MonitorPageTitle } from './monitor_page_title';
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLink, EuiToolTip } from '@elastic/eui';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
interface IntegrationLinkProps {
|
||||||
|
ariaLabel: string;
|
||||||
|
href: string;
|
||||||
|
iconType: 'apmApp' | 'infraApp' | 'loggingApp';
|
||||||
|
message: string;
|
||||||
|
tooltipContent: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const IntegrationLink = ({
|
||||||
|
ariaLabel,
|
||||||
|
href,
|
||||||
|
iconType,
|
||||||
|
message,
|
||||||
|
tooltipContent,
|
||||||
|
}: IntegrationLinkProps) => (
|
||||||
|
<EuiLink aria-label={ariaLabel} color="subdued" href={href}>
|
||||||
|
<EuiFlexGroup>
|
||||||
|
<EuiFlexItem grow={false}>
|
||||||
|
<EuiToolTip content={tooltipContent} position="top">
|
||||||
|
<EuiIcon type={iconType} />
|
||||||
|
</EuiToolTip>
|
||||||
|
</EuiFlexItem>
|
||||||
|
<EuiFlexItem>{message}</EuiFlexItem>
|
||||||
|
</EuiFlexGroup>
|
||||||
|
</EuiLink>
|
||||||
|
);
|
|
@ -27,10 +27,11 @@ import { get } from 'lodash';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { LatestMonitor, MonitorSeriesPoint } from '../../../common/graphql/types';
|
import { LatestMonitor, MonitorSeriesPoint, Ping } from '../../../common/graphql/types';
|
||||||
import { UptimeGraphQLQueryProps, withUptimeGraphQL } from '../higher_order';
|
import { UptimeGraphQLQueryProps, withUptimeGraphQL } from '../higher_order';
|
||||||
import { monitorListQuery } from '../../queries';
|
import { monitorListQuery } from '../../queries';
|
||||||
import { MonitorSparkline } from './monitor_sparkline';
|
import { MonitorSparkline } from './monitor_sparkline';
|
||||||
|
import { MonitorListActionsPopover } from './monitor_list_actions_popover';
|
||||||
|
|
||||||
interface MonitorListQueryResult {
|
interface MonitorListQueryResult {
|
||||||
// TODO: clean up this ugly result data shape, there should be no nesting
|
// TODO: clean up this ugly result data shape, there should be no nesting
|
||||||
|
@ -40,7 +41,10 @@ interface MonitorListQueryResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface MonitorListProps {
|
interface MonitorListProps {
|
||||||
|
basePath: string;
|
||||||
dangerColor: string;
|
dangerColor: string;
|
||||||
|
dateRangeStart: string;
|
||||||
|
dateRangeEnd: string;
|
||||||
linkParameters?: string;
|
linkParameters?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,99 +57,139 @@ const monitorListPagination = {
|
||||||
pageSizeOptions: [5, 10, 20, 50],
|
pageSizeOptions: [5, 10, 20, 50],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const MonitorListComponent = ({ dangerColor, data, linkParameters, loading }: Props) => (
|
export const MonitorListComponent = ({
|
||||||
<EuiPanel paddingSize="s">
|
basePath,
|
||||||
<EuiTitle size="xs">
|
dangerColor,
|
||||||
<h5>
|
dateRangeStart,
|
||||||
<FormattedMessage
|
dateRangeEnd,
|
||||||
id="xpack.uptime.monitorList.monitoringStatusTitle"
|
data,
|
||||||
defaultMessage="Monitor status"
|
linkParameters,
|
||||||
/>
|
loading,
|
||||||
</h5>
|
}: Props) => {
|
||||||
</EuiTitle>
|
return (
|
||||||
<EuiSpacer size="s" />
|
<EuiPanel paddingSize="s">
|
||||||
<EuiInMemoryTable
|
<EuiTitle size="xs">
|
||||||
columns={[
|
<h5>
|
||||||
{
|
<FormattedMessage
|
||||||
field: 'ping.monitor.status',
|
id="xpack.uptime.monitorList.monitoringStatusTitle"
|
||||||
width: '150px',
|
defaultMessage="Monitor status"
|
||||||
name: i18n.translate('xpack.uptime.monitorList.statusColumnLabel', {
|
/>
|
||||||
defaultMessage: 'Status',
|
</h5>
|
||||||
}),
|
</EuiTitle>
|
||||||
render: (status: string, monitor: LatestMonitor) => (
|
<EuiSpacer size="s" />
|
||||||
<div>
|
<EuiInMemoryTable
|
||||||
<EuiHealth
|
columns={[
|
||||||
color={status === 'up' ? 'success' : 'danger'}
|
{
|
||||||
style={{ display: 'block' }}
|
field: 'ping.monitor.status',
|
||||||
>
|
width: '150px',
|
||||||
{status === 'up'
|
name: i18n.translate('xpack.uptime.monitorList.statusColumnLabel', {
|
||||||
? i18n.translate('xpack.uptime.monitorList.statusColumn.upLabel', {
|
defaultMessage: 'Status',
|
||||||
defaultMessage: 'Up',
|
}),
|
||||||
})
|
render: (status: string, monitor: LatestMonitor) => (
|
||||||
: i18n.translate('xpack.uptime.monitorList.statusColumn.downLabel', {
|
<div>
|
||||||
defaultMessage: 'Down',
|
<EuiHealth
|
||||||
})}
|
color={status === 'up' ? 'success' : 'danger'}
|
||||||
</EuiHealth>
|
style={{ display: 'block' }}
|
||||||
<EuiText size="xs" color="subdued">
|
>
|
||||||
{moment(get(monitor, 'ping.monitor.timestamp', undefined)).fromNow()}
|
{status === 'up'
|
||||||
</EuiText>
|
? i18n.translate('xpack.uptime.monitorList.statusColumn.upLabel', {
|
||||||
</div>
|
defaultMessage: 'Up',
|
||||||
),
|
})
|
||||||
},
|
: i18n.translate('xpack.uptime.monitorList.statusColumn.downLabel', {
|
||||||
{
|
defaultMessage: 'Down',
|
||||||
field: 'ping.monitor.id',
|
})}
|
||||||
name: i18n.translate('xpack.uptime.monitorList.idColumnLabel', {
|
</EuiHealth>
|
||||||
defaultMessage: 'ID',
|
|
||||||
}),
|
|
||||||
render: (id: string, monitor: LatestMonitor) => (
|
|
||||||
<EuiLink>
|
|
||||||
<Link
|
|
||||||
data-test-subj={`monitor-page-link-${id}`}
|
|
||||||
to={`/monitor/${id}${linkParameters}`}
|
|
||||||
>
|
|
||||||
{monitor.ping && monitor.ping.monitor && monitor.ping.monitor.name
|
|
||||||
? monitor.ping.monitor.name
|
|
||||||
: id}
|
|
||||||
</Link>
|
|
||||||
</EuiLink>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'ping.url.full',
|
|
||||||
name: i18n.translate('xpack.uptime.monitorList.urlColumnLabel', {
|
|
||||||
defaultMessage: 'URL',
|
|
||||||
}),
|
|
||||||
render: (url: string, monitor: LatestMonitor) => (
|
|
||||||
<div>
|
|
||||||
<EuiLink href={url} target="_blank" color="text">
|
|
||||||
{url} <EuiIcon size="s" type="popout" color="subdued" />
|
|
||||||
</EuiLink>
|
|
||||||
{monitor.ping && monitor.ping.monitor && monitor.ping.monitor.ip ? (
|
|
||||||
<EuiText size="xs" color="subdued">
|
<EuiText size="xs" color="subdued">
|
||||||
{monitor.ping.monitor.ip}
|
{moment(get(monitor, 'ping.monitor.timestamp', undefined)).fromNow()}
|
||||||
</EuiText>
|
</EuiText>
|
||||||
) : null}
|
</div>
|
||||||
</div>
|
),
|
||||||
),
|
},
|
||||||
},
|
{
|
||||||
{
|
field: 'ping.monitor.id',
|
||||||
field: 'upSeries',
|
name: i18n.translate('xpack.uptime.monitorList.idColumnLabel', {
|
||||||
width: '180px',
|
defaultMessage: 'ID',
|
||||||
align: 'right',
|
}),
|
||||||
name: i18n.translate('xpack.uptime.monitorList.monitorHistoryColumnLabel', {
|
render: (id: string, monitor: LatestMonitor) => (
|
||||||
defaultMessage: 'Downtime history',
|
<EuiLink>
|
||||||
}),
|
<Link
|
||||||
render: (downSeries: MonitorSeriesPoint, monitor: LatestMonitor) => (
|
data-test-subj={`monitor-page-link-${id}`}
|
||||||
<MonitorSparkline dangerColor={dangerColor} monitor={monitor} />
|
to={`/monitor/${id}${linkParameters}`}
|
||||||
),
|
>
|
||||||
},
|
{monitor.ping && monitor.ping.monitor && monitor.ping.monitor.name
|
||||||
]}
|
? monitor.ping.monitor.name
|
||||||
loading={loading}
|
: id}
|
||||||
items={(data && data.monitorStatus && data.monitorStatus.monitors) || undefined}
|
</Link>
|
||||||
pagination={monitorListPagination}
|
</EuiLink>
|
||||||
/>
|
),
|
||||||
</EuiPanel>
|
},
|
||||||
);
|
{
|
||||||
|
field: 'ping.url.full',
|
||||||
|
name: i18n.translate('xpack.uptime.monitorList.urlColumnLabel', {
|
||||||
|
defaultMessage: 'URL',
|
||||||
|
}),
|
||||||
|
render: (url: string, monitor: LatestMonitor) => (
|
||||||
|
<div>
|
||||||
|
<EuiLink href={url} target="_blank" color="text">
|
||||||
|
{url} <EuiIcon size="s" type="popout" color="subdued" />
|
||||||
|
</EuiLink>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'ping.url.full',
|
||||||
|
name: i18n.translate('xpack.uptime.monitorList.urlColumnLabel', {
|
||||||
|
defaultMessage: 'URL',
|
||||||
|
}),
|
||||||
|
render: (url: string, monitor: LatestMonitor) => (
|
||||||
|
<div>
|
||||||
|
<EuiLink href={url} target="_blank" color="text">
|
||||||
|
{url} <EuiIcon size="s" type="popout" color="subdued" />
|
||||||
|
</EuiLink>
|
||||||
|
{monitor.ping && monitor.ping.monitor && monitor.ping.monitor.ip ? (
|
||||||
|
<EuiText size="xs" color="subdued">
|
||||||
|
{monitor.ping.monitor.ip}
|
||||||
|
</EuiText>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'upSeries',
|
||||||
|
width: '180px',
|
||||||
|
align: 'right',
|
||||||
|
name: i18n.translate('xpack.uptime.monitorList.monitorHistoryColumnLabel', {
|
||||||
|
defaultMessage: 'Downtime history',
|
||||||
|
}),
|
||||||
|
render: (downSeries: MonitorSeriesPoint, monitor: LatestMonitor) => (
|
||||||
|
<MonitorSparkline dangerColor={dangerColor} monitor={monitor} />
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'right',
|
||||||
|
field: 'ping',
|
||||||
|
name: i18n.translate('xpack.uptime.monitorList.observabilityIntegrationsColumnLabel', {
|
||||||
|
defaultMessage: 'Integrations',
|
||||||
|
description:
|
||||||
|
'The heading column of some action buttons that will take users to other Obsevability apps',
|
||||||
|
}),
|
||||||
|
render: (ping: Ping, monitor: LatestMonitor) => (
|
||||||
|
<MonitorListActionsPopover
|
||||||
|
basePath={basePath}
|
||||||
|
dateRangeStart={dateRangeStart}
|
||||||
|
dateRangeEnd={dateRangeEnd}
|
||||||
|
monitor={monitor}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
loading={loading}
|
||||||
|
items={(data && data.monitorStatus && data.monitorStatus.monitors) || []}
|
||||||
|
pagination={monitorListPagination}
|
||||||
|
/>
|
||||||
|
</EuiPanel>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const MonitorList = withUptimeGraphQL<MonitorListQueryResult, MonitorListProps>(
|
export const MonitorList = withUptimeGraphQL<MonitorListQueryResult, MonitorListProps>(
|
||||||
MonitorListComponent,
|
MonitorListComponent,
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiPopover } from '@elastic/eui';
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { i18n } from '@kbn/i18n';
|
||||||
|
import { get } from 'lodash';
|
||||||
|
import { LatestMonitor } from '../../../common/graphql/types';
|
||||||
|
import { IntegrationLink } from './integration_link';
|
||||||
|
import { getApmHref } from '../../lib/helper';
|
||||||
|
|
||||||
|
interface MonitorListActionsPopoverProps {
|
||||||
|
basePath: string;
|
||||||
|
dateRangeStart: string;
|
||||||
|
dateRangeEnd: string;
|
||||||
|
monitor: LatestMonitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const MonitorListActionsPopover = ({
|
||||||
|
basePath,
|
||||||
|
dateRangeStart,
|
||||||
|
dateRangeEnd,
|
||||||
|
monitor,
|
||||||
|
monitor: { ping },
|
||||||
|
}: MonitorListActionsPopoverProps) => {
|
||||||
|
const popoverId = `${monitor.id.key}_popover`;
|
||||||
|
const [popoverIsVisible, setPopoverIsVisible] = useState<boolean>(false);
|
||||||
|
const domain = get(ping, 'url.domain', '');
|
||||||
|
return (
|
||||||
|
<EuiPopover
|
||||||
|
button={
|
||||||
|
<EuiButtonIcon
|
||||||
|
aria-label={i18n.translate(
|
||||||
|
'xpack.uptime.monitorList.observabilityIntegrationsColumn.popoverIconButton.ariaLabel',
|
||||||
|
{
|
||||||
|
defaultMessage: 'Opens integrations popover for monitor with url {monitorUrl}',
|
||||||
|
description:
|
||||||
|
'A message explaining that this button opens a popover with links to other apps for a given monitor',
|
||||||
|
values: { monitorUrl: monitor.id.url },
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
color="subdued"
|
||||||
|
iconType="boxesHorizontal"
|
||||||
|
onClick={() => setPopoverIsVisible(true)}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
closePopover={() => setPopoverIsVisible(false)}
|
||||||
|
id={popoverId}
|
||||||
|
isOpen={popoverIsVisible}
|
||||||
|
>
|
||||||
|
<EuiFlexGroup>
|
||||||
|
<EuiFlexItem>
|
||||||
|
<IntegrationLink
|
||||||
|
ariaLabel={i18n.translate('xpack.uptime.apmIntegrationAction.description', {
|
||||||
|
defaultMessage: 'Search APM for this monitor',
|
||||||
|
description:
|
||||||
|
'This value is shown to users when they hover over an icon that will take them to the APM app.',
|
||||||
|
})}
|
||||||
|
href={getApmHref(monitor, basePath, dateRangeStart, dateRangeEnd)}
|
||||||
|
iconType="apmApp"
|
||||||
|
message={i18n.translate('xpack.uptime.apmIntegrationAction.text', {
|
||||||
|
defaultMessage: 'Check APM for domain',
|
||||||
|
description:
|
||||||
|
'A message explaining that when the user clicks the associated link, it will navigate to the APM app and search for the selected domain',
|
||||||
|
})}
|
||||||
|
tooltipContent={i18n.translate(
|
||||||
|
'xpack.uptime.monitorList.observabilityIntegrationsColumn.apmIntegrationLink.tooltip',
|
||||||
|
{
|
||||||
|
defaultMessage: 'Click here to check APM for the domain "{domain}".',
|
||||||
|
description:
|
||||||
|
'A messsage shown in a tooltip explaining that the nested anchor tag will navigate to the APM app and search for the given URL domain.',
|
||||||
|
values: {
|
||||||
|
domain,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</EuiFlexItem>
|
||||||
|
</EuiFlexGroup>
|
||||||
|
</EuiPopover>
|
||||||
|
);
|
||||||
|
};
|
|
@ -5,10 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import qs from 'querystring';
|
import qs from 'querystring';
|
||||||
import {
|
import { UptimeUrlParams, getSupportedUrlParams } from '../lib/helper';
|
||||||
UptimeUrlParams,
|
|
||||||
getSupportedUrlParams,
|
|
||||||
} from '../lib/helper/url_params/get_supported_url_params';
|
|
||||||
|
|
||||||
interface Location {
|
interface Location {
|
||||||
pathname: string;
|
pathname: string;
|
||||||
|
|
|
@ -5,3 +5,5 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export { convertMicrosecondsToMilliseconds } from './convert_measurements';
|
export { convertMicrosecondsToMilliseconds } from './convert_measurements';
|
||||||
|
export { getApmHref } from './observability_integration';
|
||||||
|
export { UptimeUrlParams, getSupportedUrlParams } from './url_params';
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`getApmHref creates href with base path when present 1`] = `"/foo/app/apm#/services?kuery=url.domain:%20%22www.elastic.co%22&rangeFrom=now-15m&rangeTo=now"`;
|
||||||
|
|
||||||
|
exports[`getApmHref does not add a base path or extra slash when base path is undefined 1`] = `"/app/apm#/services?kuery=url.domain:%20%22www.elastic.co%22&rangeFrom=now-15m&rangeTo=now"`;
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { getApmHref } from '../get_apm_href';
|
||||||
|
import { LatestMonitor } from '../../../../../common/graphql/types';
|
||||||
|
|
||||||
|
describe('getApmHref', () => {
|
||||||
|
let monitor: LatestMonitor;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
monitor = {
|
||||||
|
id: {
|
||||||
|
key: 'monitorId',
|
||||||
|
},
|
||||||
|
ping: {
|
||||||
|
timestamp: 'foo',
|
||||||
|
url: {
|
||||||
|
domain: 'www.elastic.co',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
it('creates href with base path when present', () => {
|
||||||
|
const result = getApmHref(monitor, 'foo', 'now-15m', 'now');
|
||||||
|
expect(result).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not add a base path or extra slash when base path is undefined', () => {
|
||||||
|
const result = getApmHref(monitor, '', 'now-15m', 'now');
|
||||||
|
expect(result).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { get } from 'lodash';
|
||||||
|
import { LatestMonitor } from '../../../../common/graphql/types';
|
||||||
|
|
||||||
|
export const getApmHref = (
|
||||||
|
monitor: LatestMonitor,
|
||||||
|
basePath: string,
|
||||||
|
dateRangeStart: string,
|
||||||
|
dateRangeEnd: string
|
||||||
|
) =>
|
||||||
|
`${basePath && basePath.length ? `/${basePath}` : ''}/app/apm#/services?kuery=${encodeURI(
|
||||||
|
`url.domain: "${get(monitor, 'ping.url.domain')}"`
|
||||||
|
)}&rangeFrom=${dateRangeStart}&rangeTo=${dateRangeEnd}`;
|
|
@ -0,0 +1,7 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export { getApmHref } from './get_apm_href';
|
|
@ -4,4 +4,4 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export { getSupportedUrlParams } from './get_supported_url_params';
|
export { UptimeUrlParams, getSupportedUrlParams } from './get_supported_url_params';
|
||||||
|
|
|
@ -80,7 +80,10 @@ export const OverviewPage = ({ basePath, setBreadcrumbs, history, location }: Pr
|
||||||
<Snapshot colors={colors} variables={sharedProps} />
|
<Snapshot colors={colors} variables={sharedProps} />
|
||||||
<EuiSpacer size="s" />
|
<EuiSpacer size="s" />
|
||||||
<MonitorList
|
<MonitorList
|
||||||
|
basePath={basePath}
|
||||||
dangerColor={colors.danger}
|
dangerColor={colors.danger}
|
||||||
|
dateRangeStart={dateRangeStart}
|
||||||
|
dateRangeEnd={dateRangeEnd}
|
||||||
linkParameters={linkParameters}
|
linkParameters={linkParameters}
|
||||||
variables={sharedProps}
|
variables={sharedProps}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -30,6 +30,7 @@ export const monitorListQueryString = `
|
||||||
status
|
status
|
||||||
}
|
}
|
||||||
url {
|
url {
|
||||||
|
domain
|
||||||
full
|
full
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
"name": "",
|
"name": "",
|
||||||
"status": "up"
|
"status": "up"
|
||||||
},
|
},
|
||||||
"url": { "full": "https://www.google.com/" }
|
"url": { "domain": "www.google.com", "full": "https://www.google.com/" }
|
||||||
},
|
},
|
||||||
"upSeries": [
|
"upSeries": [
|
||||||
{ "x": 1548697620000, "y": 74 },
|
{ "x": 1548697620000, "y": 74 },
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
"name": "",
|
"name": "",
|
||||||
"status": "down"
|
"status": "down"
|
||||||
},
|
},
|
||||||
"url": { "full": "http://localhost:12349/" }
|
"url": { "domain": "localhost", "full": "http://localhost:12349/" }
|
||||||
},
|
},
|
||||||
"upSeries": [
|
"upSeries": [
|
||||||
{ "x": 1548697620000, "y": null },
|
{ "x": 1548697620000, "y": null },
|
||||||
|
@ -96,7 +96,7 @@
|
||||||
"name": "",
|
"name": "",
|
||||||
"status": "up"
|
"status": "up"
|
||||||
},
|
},
|
||||||
"url": { "full": "http://www.google.com/" }
|
"url": { "domain": "www.google.com", "full": "http://www.google.com/" }
|
||||||
},
|
},
|
||||||
"upSeries": [
|
"upSeries": [
|
||||||
{ "x": 1548697620000, "y": 58 },
|
{ "x": 1548697620000, "y": 58 },
|
||||||
|
@ -138,7 +138,7 @@
|
||||||
"name": "",
|
"name": "",
|
||||||
"status": "up"
|
"status": "up"
|
||||||
},
|
},
|
||||||
"url": { "full": "https://www.github.com/" }
|
"url": { "domain": "www.github.com", "full": "https://www.github.com/" }
|
||||||
},
|
},
|
||||||
"upSeries": [
|
"upSeries": [
|
||||||
{ "x": 1548697620000, "y": 69 },
|
{ "x": 1548697620000, "y": 69 },
|
||||||
|
@ -180,7 +180,7 @@
|
||||||
"name": "",
|
"name": "",
|
||||||
"status": "down"
|
"status": "down"
|
||||||
},
|
},
|
||||||
"url": { "full": "http://www.example.com/" }
|
"url": { "domain": "www.example.com", "full": "http://www.example.com/" }
|
||||||
},
|
},
|
||||||
"upSeries": [
|
"upSeries": [
|
||||||
{ "x": 1548697620000, "y": null },
|
{ "x": 1548697620000, "y": null },
|
||||||
|
@ -222,7 +222,7 @@
|
||||||
"name": "",
|
"name": "",
|
||||||
"status": "up"
|
"status": "up"
|
||||||
},
|
},
|
||||||
"url": { "full": "https://www.wikipedia.org/" }
|
"url": { "domain": "www.wikipedia.org", "full": "https://www.wikipedia.org/" }
|
||||||
},
|
},
|
||||||
"upSeries": [
|
"upSeries": [
|
||||||
{ "x": 1548697620000, "y": 5 },
|
{ "x": 1548697620000, "y": 5 },
|
||||||
|
@ -264,7 +264,7 @@
|
||||||
"name": "",
|
"name": "",
|
||||||
"status": "up"
|
"status": "up"
|
||||||
},
|
},
|
||||||
"url": { "full": "http://www.reddit.com/" }
|
"url": { "domain": "www.reddit.com", "full": "http://www.reddit.com/" }
|
||||||
},
|
},
|
||||||
"upSeries": [
|
"upSeries": [
|
||||||
{ "x": 1548697620000, "y": 79 },
|
{ "x": 1548697620000, "y": 79 },
|
||||||
|
@ -306,7 +306,7 @@
|
||||||
"name": "",
|
"name": "",
|
||||||
"status": "up"
|
"status": "up"
|
||||||
},
|
},
|
||||||
"url": { "full": "https://www.elastic.co" }
|
"url": { "domain": "www.elastic.co", "full": "https://www.elastic.co" }
|
||||||
},
|
},
|
||||||
"upSeries": [
|
"upSeries": [
|
||||||
{ "x": 1548697620000, "y": 79 },
|
{ "x": 1548697620000, "y": 79 },
|
||||||
|
@ -348,7 +348,7 @@
|
||||||
"name": "",
|
"name": "",
|
||||||
"status": "up"
|
"status": "up"
|
||||||
},
|
},
|
||||||
"url": { "full": "https://news.google.com/" }
|
"url": { "domain": "news.google.com", "full": "https://news.google.com/" }
|
||||||
},
|
},
|
||||||
"upSeries": [
|
"upSeries": [
|
||||||
{ "x": 1548697620000, "y": 5 },
|
{ "x": 1548697620000, "y": 5 },
|
||||||
|
@ -390,7 +390,7 @@
|
||||||
"name": "",
|
"name": "",
|
||||||
"status": "up"
|
"status": "up"
|
||||||
},
|
},
|
||||||
"url": { "full": "tcp://localhost:9200" }
|
"url": { "domain": "localhost", "full": "tcp://localhost:9200" }
|
||||||
},
|
},
|
||||||
"upSeries": [
|
"upSeries": [
|
||||||
{ "x": 1548697620000, "y": 1 },
|
{ "x": 1548697620000, "y": 1 },
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
"name": "",
|
"name": "",
|
||||||
"status": "down"
|
"status": "down"
|
||||||
},
|
},
|
||||||
"url": { "full": "http://localhost:12349/" }
|
"url": { "domain": "localhost", "full": "http://localhost:12349/" }
|
||||||
},
|
},
|
||||||
"upSeries": [
|
"upSeries": [
|
||||||
{ "x": 1548697620000, "y": null },
|
{ "x": 1548697620000, "y": null },
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
"name": "",
|
"name": "",
|
||||||
"status": "down"
|
"status": "down"
|
||||||
},
|
},
|
||||||
"url": { "full": "http://www.example.com/" }
|
"url": { "domain": "www.example.com", "full": "http://www.example.com/" }
|
||||||
},
|
},
|
||||||
"upSeries": [
|
"upSeries": [
|
||||||
{ "x": 1548697620000, "y": null },
|
{ "x": 1548697620000, "y": null },
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
"name": "",
|
"name": "",
|
||||||
"status": "up"
|
"status": "up"
|
||||||
},
|
},
|
||||||
"url": { "full": "https://www.google.com/" }
|
"url": { "domain": "www.google.com", "full": "https://www.google.com/" }
|
||||||
},
|
},
|
||||||
"upSeries": [
|
"upSeries": [
|
||||||
{ "x": 1548697620000, "y": 74 },
|
{ "x": 1548697620000, "y": 74 },
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
"name": "",
|
"name": "",
|
||||||
"status": "up"
|
"status": "up"
|
||||||
},
|
},
|
||||||
"url": { "full": "http://www.google.com/" }
|
"url": { "domain": "www.google.com", "full": "http://www.google.com/" }
|
||||||
},
|
},
|
||||||
"upSeries": [
|
"upSeries": [
|
||||||
{ "x": 1548697620000, "y": 58 },
|
{ "x": 1548697620000, "y": 58 },
|
||||||
|
@ -96,7 +96,7 @@
|
||||||
"name": "",
|
"name": "",
|
||||||
"status": "up"
|
"status": "up"
|
||||||
},
|
},
|
||||||
"url": { "full": "https://www.github.com/" }
|
"url": { "domain": "www.github.com", "full": "https://www.github.com/" }
|
||||||
},
|
},
|
||||||
"upSeries": [
|
"upSeries": [
|
||||||
{ "x": 1548697620000, "y": 69 },
|
{ "x": 1548697620000, "y": 69 },
|
||||||
|
@ -138,7 +138,7 @@
|
||||||
"name": "",
|
"name": "",
|
||||||
"status": "up"
|
"status": "up"
|
||||||
},
|
},
|
||||||
"url": { "full": "https://www.wikipedia.org/" }
|
"url": { "domain": "www.wikipedia.org", "full": "https://www.wikipedia.org/" }
|
||||||
},
|
},
|
||||||
"upSeries": [
|
"upSeries": [
|
||||||
{ "x": 1548697620000, "y": 5 },
|
{ "x": 1548697620000, "y": 5 },
|
||||||
|
@ -180,7 +180,7 @@
|
||||||
"name": "",
|
"name": "",
|
||||||
"status": "up"
|
"status": "up"
|
||||||
},
|
},
|
||||||
"url": { "full": "http://www.reddit.com/" }
|
"url": { "domain": "www.reddit.com", "full": "http://www.reddit.com/" }
|
||||||
},
|
},
|
||||||
"upSeries": [
|
"upSeries": [
|
||||||
{ "x": 1548697620000, "y": 79 },
|
{ "x": 1548697620000, "y": 79 },
|
||||||
|
@ -222,7 +222,7 @@
|
||||||
"name": "",
|
"name": "",
|
||||||
"status": "up"
|
"status": "up"
|
||||||
},
|
},
|
||||||
"url": { "full": "https://www.elastic.co" }
|
"url": { "domain": "www.elastic.co", "full": "https://www.elastic.co" }
|
||||||
},
|
},
|
||||||
"upSeries": [
|
"upSeries": [
|
||||||
{ "x": 1548697620000, "y": 79 },
|
{ "x": 1548697620000, "y": 79 },
|
||||||
|
@ -264,7 +264,7 @@
|
||||||
"name": "",
|
"name": "",
|
||||||
"status": "up"
|
"status": "up"
|
||||||
},
|
},
|
||||||
"url": { "full": "https://news.google.com/" }
|
"url": { "domain": "news.google.com", "full": "https://news.google.com/" }
|
||||||
},
|
},
|
||||||
"upSeries": [
|
"upSeries": [
|
||||||
{ "x": 1548697620000, "y": 5 },
|
{ "x": 1548697620000, "y": 5 },
|
||||||
|
@ -306,7 +306,7 @@
|
||||||
"name": "",
|
"name": "",
|
||||||
"status": "up"
|
"status": "up"
|
||||||
},
|
},
|
||||||
"url": { "full": "tcp://localhost:9200" }
|
"url": { "domain": "localhost", "full": "tcp://localhost:9200" }
|
||||||
},
|
},
|
||||||
"upSeries": [
|
"upSeries": [
|
||||||
{ "x": 1548697620000, "y": 1 },
|
{ "x": 1548697620000, "y": 1 },
|
||||||
|
|
Loading…
Reference in a new issue