diff --git a/x-pack/legacy/plugins/uptime/common/runtime_types/common.ts b/x-pack/legacy/plugins/uptime/common/runtime_types/common.ts new file mode 100644 index 0000000000000..84e3ae33294f0 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/common/runtime_types/common.ts @@ -0,0 +1,27 @@ +/* + * 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 * as t from 'io-ts'; + +export const LocationType = t.partial({ + lat: t.string, + lon: t.string, +}); + +export const CheckGeoType = t.partial({ + name: t.string, + location: LocationType, +}); + +export const SummaryType = t.partial({ + up: t.number, + down: t.number, + geo: CheckGeoType, +}); + +export type Summary = t.TypeOf; +export type CheckGeo = t.TypeOf; +export type Location = t.TypeOf; diff --git a/x-pack/legacy/plugins/uptime/common/runtime_types/index.ts b/x-pack/legacy/plugins/uptime/common/runtime_types/index.ts index a88e28f2e5a09..224892eb91783 100644 --- a/x-pack/legacy/plugins/uptime/common/runtime_types/index.ts +++ b/x-pack/legacy/plugins/uptime/common/runtime_types/index.ts @@ -4,5 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +export * from './common'; export * from './snapshot'; export * from './monitor/monitor_details'; +export * from './monitor/monitor_locations'; diff --git a/x-pack/legacy/plugins/uptime/common/runtime_types/monitor/monitor_locations.ts b/x-pack/legacy/plugins/uptime/common/runtime_types/monitor/monitor_locations.ts new file mode 100644 index 0000000000000..a40453b3671b7 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/common/runtime_types/monitor/monitor_locations.ts @@ -0,0 +1,22 @@ +/* + * 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 * as t from 'io-ts'; +import { CheckGeoType, SummaryType } from '../common'; + +// IO type for validation +export const MonitorLocationType = t.partial({ + summary: SummaryType, + geo: CheckGeoType, +}); + +// Typescript type for type checking +export type MonitorLocation = t.TypeOf; + +export const MonitorLocationsType = t.intersection([ + t.type({ monitorId: t.string }), + t.partial({ locations: t.array(MonitorLocationType) }), +]); +export type MonitorLocations = t.TypeOf; diff --git a/x-pack/legacy/plugins/uptime/public/apps/index.ts b/x-pack/legacy/plugins/uptime/public/apps/index.ts index 53a74022778f4..06776842aa6de 100644 --- a/x-pack/legacy/plugins/uptime/public/apps/index.ts +++ b/x-pack/legacy/plugins/uptime/public/apps/index.ts @@ -7,6 +7,7 @@ import chrome from 'ui/chrome'; import { npStart } from 'ui/new_platform'; import { Plugin } from './plugin'; +import 'uiExports/embeddableFactories'; new Plugin( { opaqueId: Symbol('uptime'), env: {} as any, config: { get: () => ({} as any) } }, diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/__snapshots__/monitor_status.bar.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/__snapshots__/monitor_status.bar.test.tsx.snap index 204dcdbe5b516..4fda42e510bba 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/__snapshots__/monitor_status.bar.test.tsx.snap +++ b/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/__snapshots__/monitor_status.bar.test.tsx.snap @@ -2,71 +2,67 @@ exports[`MonitorStatusBar component renders duration in ms, not us 1`] = `
-
- -
-
- Up -
+
-
-
-
+
+
- 1234ms -
-
+
+ 1234ms +
+
+ 15 minutes ago +
`; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/__mocks__/mock.ts b/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/__mocks__/mock.ts new file mode 100644 index 0000000000000..9b902651690bf --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/__mocks__/mock.ts @@ -0,0 +1,185 @@ +/* + * 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 lowPolyLayerFeatures from '../low_poly_layer.json'; + +export const mockDownPointsLayer = { + id: 'down_points', + label: 'Down Locations', + sourceDescriptor: { + type: 'GEOJSON_FILE', + __featureCollection: { + features: [ + { + type: 'feature', + geometry: { + type: 'Point', + coordinates: [13.399262, 52.487239], + }, + }, + { + type: 'feature', + geometry: { + type: 'Point', + coordinates: [13.399262, 55.487239], + }, + }, + { + type: 'feature', + geometry: { + type: 'Point', + coordinates: [14.399262, 54.487239], + }, + }, + ], + type: 'FeatureCollection', + }, + }, + visible: true, + style: { + type: 'VECTOR', + properties: { + fillColor: { + type: 'STATIC', + options: { + color: '#BC261E', + }, + }, + lineColor: { + type: 'STATIC', + options: { + color: '#fff', + }, + }, + lineWidth: { + type: 'STATIC', + options: { + size: 2, + }, + }, + iconSize: { + type: 'STATIC', + options: { + size: 6, + }, + }, + }, + }, + type: 'VECTOR', +}; + +export const mockUpPointsLayer = { + id: 'up_points', + label: 'Up Locations', + sourceDescriptor: { + type: 'GEOJSON_FILE', + __featureCollection: { + features: [ + { + type: 'feature', + geometry: { + type: 'Point', + coordinates: [13.399262, 52.487239], + }, + }, + { + type: 'feature', + geometry: { + type: 'Point', + coordinates: [13.399262, 55.487239], + }, + }, + { + type: 'feature', + geometry: { + type: 'Point', + coordinates: [14.399262, 54.487239], + }, + }, + ], + type: 'FeatureCollection', + }, + }, + visible: true, + style: { + type: 'VECTOR', + properties: { + fillColor: { + type: 'STATIC', + options: { + color: '#98A2B2', + }, + }, + lineColor: { + type: 'STATIC', + options: { + color: '#fff', + }, + }, + lineWidth: { + type: 'STATIC', + options: { + size: 2, + }, + }, + iconSize: { + type: 'STATIC', + options: { + size: 6, + }, + }, + }, + }, + type: 'VECTOR', +}; + +export const mockLayerList = [ + { + id: 'low_poly_layer', + label: 'World countries', + minZoom: 0, + maxZoom: 24, + alpha: 1, + sourceDescriptor: { + id: 'b7486535-171b-4d3b-bb2e-33c1a0a2854c', + type: 'GEOJSON_FILE', + __featureCollection: lowPolyLayerFeatures, + }, + visible: true, + style: { + type: 'VECTOR', + properties: { + fillColor: { + type: 'STATIC', + options: { + color: '#cad3e4', + }, + }, + lineColor: { + type: 'STATIC', + options: { + color: '#fff', + }, + }, + lineWidth: { + type: 'STATIC', + options: { + size: 0, + }, + }, + iconSize: { + type: 'STATIC', + options: { + size: 6, + }, + }, + }, + }, + type: 'VECTOR', + }, + mockDownPointsLayer, + mockUpPointsLayer, +]; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/embedded_map.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/embedded_map.tsx new file mode 100644 index 0000000000000..a5578d9e05667 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/embedded_map.tsx @@ -0,0 +1,102 @@ +/* + * 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, { useEffect, useState } from 'react'; +import uuid from 'uuid'; +import styled from 'styled-components'; + +import { start } from '../../../../../../../../../src/legacy/core_plugins/embeddable_api/public/np_ready/public/legacy'; +import * as i18n from './translations'; +// @ts-ignore +import { MAP_SAVED_OBJECT_TYPE } from '../../../../../../maps/common/constants'; + +import { MapEmbeddable } from './types'; +import { getLayerList } from './map_config'; + +export interface EmbeddedMapProps { + upPoints: LocationPoint[]; + downPoints: LocationPoint[]; +} + +export interface LocationPoint { + lat: string; + lon: string; +} + +const EmbeddedPanel = styled.div` + z-index: auto; + flex: 1; + display: flex; + flex-direction: column; + height: 100%; + position: relative; + .embPanel__content { + display: flex; + flex: 1 1 100%; + z-index: 1; + min-height: 0; // Absolute must for Firefox to scroll contents + } + &&& .mapboxgl-canvas { + animation: none !important; + } +`; + +export const EmbeddedMap = ({ upPoints, downPoints }: EmbeddedMapProps) => { + const [embeddable, setEmbeddable] = useState(); + + useEffect(() => { + async function setupEmbeddable() { + const mapState = { + layerList: getLayerList(upPoints, downPoints), + title: i18n.MAP_TITLE, + }; + // @ts-ignore + const embeddableObject = await factory.createFromState(mapState, input, undefined); + + setEmbeddable(embeddableObject); + } + setupEmbeddable(); + }, []); + + useEffect(() => { + if (embeddable) { + embeddable.setLayerList(getLayerList(upPoints, downPoints)); + } + }, [upPoints, downPoints]); + + useEffect(() => { + if (embeddableRoot.current && embeddable) { + embeddable.render(embeddableRoot.current); + } + }, [embeddable]); + + const factory = start.getEmbeddableFactory(MAP_SAVED_OBJECT_TYPE); + + const input = { + id: uuid.v4(), + filters: [], + hidePanelTitles: true, + query: { query: '', language: 'kuery' }, + refreshConfig: { value: 0, pause: false }, + viewMode: 'view', + isLayerTOCOpen: false, + hideFilterActions: true, + mapCenter: { lon: 11, lat: 47, zoom: 0 }, + disableInteractive: true, + disableTooltipControl: true, + hideToolbarOverlay: true, + }; + + const embeddableRoot: React.RefObject = React.createRef(); + + return ( + +
+ + ); +}; + +EmbeddedMap.displayName = 'EmbeddedMap'; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/low_poly_layer.json b/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/low_poly_layer.json new file mode 100644 index 0000000000000..7a309cd01ebc7 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/low_poly_layer.json @@ -0,0 +1,2898 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + "34.21666", + "31.32333" + ], + [ + "35.98361", + "34.52750" + ], + [ + "34.65943", + "36.80527" + ], + [ + "32.77166", + "36.02888" + ], + [ + "29.67722", + "36.11833" + ], + [ + "27.25500", + "36.96500" + ], + [ + "27.51166", + "40.30555" + ], + [ + "33.33860", + "42.01985" + ], + [ + "38.35582", + "40.91027" + ], + [ + "41.77609", + "41.84193" + ], + [ + "41.59748", + "43.22151" + ], + [ + "45.16512", + "42.70333" + ], + [ + "47.91547", + "41.22499" + ], + [ + "49.76062", + "42.71076" + ], + [ + "49.44831", + "45.53038" + ], + [ + "47.30249", + "50.03194" + ], + [ + "52.34180", + "51.78075" + ], + [ + "55.69249", + "50.53249" + ], + [ + "58.33777", + "51.15610" + ], + [ + "57.97027", + "54.38819" + ], + [ + "59.64166", + "55.55867" + ], + [ + "57.22169", + "56.85096" + ], + [ + "59.44912", + "58.48804" + ], + [ + "59.57756", + "63.93287" + ], + [ + "66.10887", + "67.48123" + ], + [ + "64.52222", + "68.90305" + ], + [ + "67.05498", + "68.85637" + ], + [ + "69.32735", + "72.94540" + ], + [ + "73.52553", + "71.81582" + ], + [ + "80.82610", + "72.08693" + ], + [ + "80.51860", + "73.57346" + ], + [ + "89.25278", + "75.50305" + ], + [ + "97.18359", + "75.92804" + ], + [ + "104.07138", + "77.73221" + ], + [ + "111.10387", + "76.75526" + ], + [ + "113.47054", + "73.50096" + ], + [ + "118.63443", + "73.57166" + ], + [ + "131.53580", + "70.87776" + ], + [ + "137.45190", + "71.34109" + ], + [ + "141.02414", + "72.58582" + ], + [ + "149.18524", + "72.22249" + ], + [ + "152.53830", + "70.83777" + ], + [ + "159.72968", + "69.83472" + ], + [ + "170.61194", + "68.75633" + ], + [ + "170.47189", + "70.13416" + ], + [ + "180.00000", + "68.98010" + ], + [ + "180.00000", + "65.06891" + ], + [ + "179.55373", + "62.61971" + ], + [ + "173.54178", + "61.74430" + ], + [ + "170.64194", + "60.41750" + ], + [ + "163.36023", + "59.82388" + ], + [ + "161.93858", + "58.06763" + ], + [ + "163.34996", + "56.19596" + ], + [ + "156.74524", + "51.07791" + ], + [ + "155.54413", + "55.30360" + ], + [ + "155.94206", + "56.65353" + ], + [ + "161.91248", + "60.41972" + ], + [ + "159.24747", + "61.92222" + ], + [ + "152.35718", + "59.02332" + ], + [ + "143.21109", + "59.37666" + ], + [ + "137.72580", + "56.17500" + ], + [ + "137.29327", + "54.07500" + ], + [ + "141.41483", + "53.29361" + ], + [ + "140.17609", + "48.45013" + ], + [ + "135.42233", + "43.75611" + ], + [ + "133.15485", + "42.68263" + ], + [ + "131.81052", + "43.32555" + ], + [ + "129.70204", + "40.83069" + ], + [ + "127.51763", + "39.73957" + ], + [ + "129.42944", + "37.05986" + ], + [ + "129.23749", + "35.18990" + ], + [ + "126.37556", + "34.79138" + ], + [ + "126.38860", + "37.88721" + ], + [ + "124.32395", + "39.91589" + ], + [ + "121.64804", + "38.99638" + ], + [ + "121.17747", + "40.92194" + ], + [ + "118.11053", + "38.14639" + ], + [ + "120.82054", + "36.64527" + ], + [ + "120.24873", + "34.31145" + ], + [ + "121.84693", + "30.85305" + ], + [ + "120.93526", + "27.98222" + ], + [ + "119.58074", + "25.67996" + ], + [ + "116.48172", + "22.93902" + ], + [ + "112.28194", + "21.70139" + ], + [ + "107.36693", + "21.26527" + ], + [ + "105.63857", + "18.89065" + ], + [ + "108.82916", + "15.42194" + ], + [ + "109.46186", + "12.86097" + ], + [ + "109.02168", + "11.36225" + ], + [ + "104.79893", + "8.79222" + ], + [ + "104.98177", + "10.10444" + ], + [ + "100.97635", + "13.46281" + ], + [ + "99.15082", + "10.36472" + ], + [ + "100.57809", + "7.22014" + ], + [ + "103.18192", + "5.28278" + ], + [ + "103.37455", + "1.53347" + ], + [ + "101.28574", + "2.84354" + ], + [ + "100.35553", + "5.96389" + ], + [ + "98.27415", + "8.27444" + ], + [ + "98.74720", + "11.67486" + ], + [ + "97.72457", + "15.84666" + ], + [ + "95.42859", + "15.72972" + ], + [ + "93.72436", + "19.93243" + ], + [ + "91.70444", + "22.48055" + ], + [ + "86.96332", + "21.38194" + ], + [ + "86.42123", + "19.98493" + ], + [ + "80.27943", + "15.69917" + ], + [ + "79.85811", + "10.28583" + ], + [ + "76.99860", + "8.36527" + ], + [ + "74.85526", + "12.75500" + ], + [ + "73.44748", + "16.05861" + ], + [ + "72.56485", + "21.37506" + ], + [ + "70.82513", + "20.69597" + ], + [ + "66.50005", + "25.40381" + ], + [ + "61.76083", + "25.03208" + ], + [ + "57.31909", + "25.77146" + ], + [ + "56.80888", + "27.12361" + ], + [ + "54.78846", + "26.49041" + ], + [ + "51.43027", + "27.93777" + ], + [ + "50.63916", + "29.47042" + ], + [ + "47.95943", + "30.03305" + ], + [ + "48.83887", + "27.61972" + ], + [ + "51.28236", + "24.30000" + ], + [ + "53.58777", + "24.04417" + ], + [ + "55.85944", + "25.72042" + ], + [ + "57.17131", + "23.93444" + ], + [ + "59.82861", + "22.29166" + ], + [ + "57.80569", + "18.97097" + ], + [ + "55.03194", + "17.01472" + ], + [ + "52.18916", + "15.60528" + ], + [ + "45.04232", + "12.75239" + ], + [ + "43.47888", + "12.67500" + ], + [ + "42.78933", + "16.46083" + ], + [ + "40.75694", + "19.76417" + ], + [ + "39.17486", + "21.10402" + ], + [ + "39.06277", + "22.58333" + ], + [ + "35.16055", + "28.05666" + ], + [ + "34.21666", + "31.32333" + ] + ] + ], + [ + [ + [ + "-169.69496", + "66.06806" + ], + [ + "-173.67308", + "64.34679" + ], + [ + "-179.32083", + "65.53012" + ], + [ + "-180.00000", + "65.06891" + ], + [ + "-180.00000", + "68.98010" + ], + [ + "-169.69496", + "66.06806" + ] + ] + ], + [ + [ + [ + "139.93851", + "40.42860" + ], + [ + "142.06970", + "39.54666" + ], + [ + "140.95358", + "38.14805" + ], + [ + "140.33218", + "35.12985" + ], + [ + "137.02879", + "34.56784" + ], + [ + "136.71246", + "36.75139" + ], + [ + "139.42622", + "38.15458" + ], + [ + "139.93851", + "40.42860" + ] + ] + ], + [ + [ + [ + "119.89259", + "15.80112" + ], + [ + "120.58527", + "18.51139" + ], + [ + "122.51833", + "17.04389" + ], + [ + "121.38026", + "15.30250" + ], + [ + "119.89259", + "15.80112" + ] + ] + ], + [ + [ + [ + "122.32916", + "7.30833" + ], + [ + "126.18610", + "9.24277" + ], + [ + "125.37762", + "6.72361" + ], + [ + "123.45888", + "7.81055" + ], + [ + "122.32916", + "7.30833" + ] + ] + ], + [ + [ + [ + "111.89638", + "-3.57389" + ], + [ + "110.23193", + "-2.97111" + ], + [ + "108.84549", + "0.81056" + ], + [ + "109.64857", + "2.07341" + ], + [ + "113.01054", + "3.16055" + ], + [ + "115.37886", + "4.91167" + ], + [ + "116.75417", + "7.01805" + ], + [ + "119.27582", + "5.34500" + ], + [ + "117.27540", + "3.22000" + ], + [ + "117.87192", + "1.87667" + ], + [ + "117.44479", + "-0.52397" + ], + [ + "115.96624", + "-3.60875" + ], + [ + "113.03471", + "-2.98972" + ], + [ + "111.89638", + "-3.57389" + ] + ] + ], + [ + [ + [ + "102.97601", + "0.64348" + ], + [ + "103.36081", + "-0.70222" + ], + [ + "106.05525", + "-3.03139" + ], + [ + "105.72887", + "-5.89826" + ], + [ + "102.32610", + "-4.00611" + ], + [ + "100.90555", + "-2.31944" + ], + [ + "98.70383", + "1.55979" + ], + [ + "95.53108", + "4.68278" + ], + [ + "97.51483", + "5.24944" + ], + [ + "100.41219", + "2.29306" + ], + [ + "102.97601", + "0.64348" + ] + ] + ], + [ + [ + [ + "120.82723", + "1.23406" + ], + [ + "120.01999", + "-0.07528" + ], + [ + "122.47623", + "-3.16090" + ], + [ + "120.32888", + "-5.51208" + ], + [ + "119.35491", + "-5.40007" + ], + [ + "118.88860", + "-2.89319" + ], + [ + "119.77805", + "0.22972" + ], + [ + "120.82723", + "1.23406" + ] + ] + ], + [ + [ + [ + "136.04913", + "-2.69806" + ], + [ + "137.87579", + "-1.47306" + ], + [ + "144.51373", + "-3.82222" + ], + [ + "145.76639", + "-5.48528" + ], + [ + "147.46661", + "-5.97086" + ], + [ + "146.08969", + "-8.09111" + ], + [ + "144.21738", + "-7.79465" + ], + [ + "143.36510", + "-9.01222" + ], + [ + "141.11996", + "-9.23097" + ], + [ + "139.09454", + "-7.56181" + ], + [ + "138.06525", + "-5.40896" + ], + [ + "135.20468", + "-4.45972" + ], + [ + "132.72275", + "-2.81722" + ], + [ + "131.25555", + "-0.82278" + ], + [ + "134.02950", + "-0.96694" + ], + [ + "134.99495", + "-3.33653" + ], + [ + "136.04913", + "-2.69806" + ] + ] + ], + [ + [ + [ + "110.05640", + "-7.89751" + ], + [ + "106.56721", + "-7.41694" + ], + [ + "106.07582", + "-5.88194" + ], + [ + "110.39360", + "-6.97903" + ], + [ + "110.05640", + "-7.89751" + ] + ] + ] + ] + }, + "properties": { + "CONTINENT": "Asia" + } + }, + { + "type": "Feature", + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + "-25.28167", + "71.39166" + ], + [ + "-23.56056", + "70.10609" + ], + [ + "-26.36333", + "68.66748" + ], + [ + "-31.99916", + "68.09526" + ], + [ + "-34.71999", + "66.33832" + ], + [ + "-41.15541", + "64.96235" + ], + [ + "-43.08722", + "60.10027" + ], + [ + "-47.68986", + "61.00680" + ], + [ + "-50.31562", + "62.49430" + ], + [ + "-53.23333", + "65.68283" + ], + [ + "-53.62778", + "67.81470" + ], + [ + "-50.58930", + "69.92373" + ], + [ + "-54.68694", + "72.36721" + ], + [ + "-58.15958", + "75.50860" + ], + [ + "-68.50056", + "76.08693" + ], + [ + "-72.55222", + "78.52110" + ], + [ + "-60.80666", + "81.87997" + ], + [ + "-30.38833", + "83.60220" + ], + [ + "-16.00500", + "80.72859" + ], + [ + "-22.03695", + "77.68568" + ], + [ + "-19.33681", + "75.40207" + ], + [ + "-24.46305", + "73.53581" + ], + [ + "-25.28167", + "71.39166" + ] + ] + ], + [ + [ + [ + "-87.64890", + "76.33804" + ], + [ + "-86.47916", + "79.76167" + ], + [ + "-90.43666", + "81.88750" + ], + [ + "-70.26001", + "83.11388" + ], + [ + "-61.07639", + "82.32083" + ], + [ + "-78.78194", + "76.57221" + ], + [ + "-87.64890", + "76.33804" + ] + ] + ], + [ + [ + [ + "-123.83389", + "73.70027" + ], + [ + "-115.31903", + "73.47707" + ], + [ + "-123.29306", + "71.14610" + ], + [ + "-123.83389", + "73.70027" + ] + ] + ], + [ + [ + [ + "-65.32806", + "62.66610" + ], + [ + "-68.61583", + "62.26389" + ], + [ + "-77.33667", + "65.17609" + ], + [ + "-72.25835", + "67.24803" + ], + [ + "-77.30506", + "69.83395" + ], + [ + "-85.87465", + "70.07943" + ], + [ + "-89.90348", + "71.35304" + ], + [ + "-89.03958", + "73.25499" + ], + [ + "-81.57251", + "73.71971" + ], + [ + "-67.21986", + "69.94081" + ], + [ + "-67.23819", + "68.35790" + ], + [ + "-61.26458", + "66.62609" + ], + [ + "-65.56204", + "64.73154" + ], + [ + "-65.32806", + "62.66610" + ] + ] + ], + [ + [ + [ + "-105.02444", + "72.21999" + ], + [ + "-100.99973", + "70.17276" + ], + [ + "-101.85139", + "68.98442" + ], + [ + "-113.04173", + "68.49374" + ], + [ + "-116.53221", + "69.40887" + ], + [ + "-119.13445", + "71.77457" + ], + [ + "-114.66666", + "73.37247" + ], + [ + "-105.02444", + "72.21999" + ] + ] + ], + [ + [ + [ + "-77.36667", + "8.67500" + ], + [ + "-77.88972", + "7.22889" + ], + [ + "-79.69778", + "8.86666" + ], + [ + "-81.73862", + "8.16250" + ], + [ + "-85.65668", + "9.90500" + ], + [ + "-85.66959", + "11.05500" + ], + [ + "-87.93779", + "13.15639" + ], + [ + "-91.38474", + "13.97889" + ], + [ + "-93.93861", + "16.09389" + ], + [ + "-96.47612", + "15.64361" + ], + [ + "-103.45001", + "18.31361" + ], + [ + "-105.67834", + "20.38305" + ], + [ + "-105.18945", + "21.43750" + ], + [ + "-106.91570", + "23.86514" + ], + [ + "-109.43750", + "25.82027" + ], + [ + "-109.44431", + "26.71555" + ], + [ + "-112.16195", + "28.97139" + ], + [ + "-113.09167", + "31.22972" + ], + [ + "-115.69667", + "29.77423" + ], + [ + "-117.40944", + "33.24416" + ], + [ + "-120.60583", + "34.55860" + ], + [ + "-124.33118", + "40.27246" + ], + [ + "-124.52444", + "42.86610" + ], + [ + "-123.87161", + "45.52898" + ], + [ + "-124.71431", + "48.39708" + ], + [ + "-124.03510", + "49.91801" + ], + [ + "-127.17315", + "50.92221" + ], + [ + "-130.88640", + "55.70791" + ], + [ + "-133.81302", + "57.97293" + ], + [ + "-136.65891", + "58.21652" + ], + [ + "-140.40335", + "59.69804" + ], + [ + "-146.75543", + "60.95249" + ], + [ + "-154.23567", + "58.13069" + ], + [ + "-157.55139", + "58.38777" + ], + [ + "-165.42244", + "60.55215" + ], + [ + "-164.40112", + "63.21499" + ], + [ + "-168.13196", + "65.66296" + ], + [ + "-161.66779", + "67.02054" + ], + [ + "-166.82362", + "68.34873" + ], + [ + "-156.59673", + "71.35144" + ], + [ + "-151.22986", + "70.37296" + ], + [ + "-143.21555", + "70.11026" + ], + [ + "-137.25500", + "68.94832" + ], + [ + "-127.18096", + "70.27638" + ], + [ + "-114.06652", + "68.46970" + ], + [ + "-112.39584", + "67.67915" + ], + [ + "-98.11124", + "67.83887" + ], + [ + "-90.43639", + "68.87442" + ], + [ + "-85.55499", + "69.85970" + ], + [ + "-81.33570", + "69.18498" + ], + [ + "-81.50222", + "67.00096" + ], + [ + "-85.89726", + "66.16802" + ], + [ + "-87.98736", + "64.18845" + ], + [ + "-92.71001", + "62.46583" + ], + [ + "-94.78972", + "59.09222" + ], + [ + "-92.41875", + "57.33270" + ], + [ + "-88.81500", + "56.82444" + ], + [ + "-85.00195", + "55.29666" + ], + [ + "-82.30777", + "55.14888" + ], + [ + "-82.27390", + "52.95638" + ], + [ + "-78.57945", + "52.11138" + ], + [ + "-79.76181", + "54.65166" + ], + [ + "-76.67979", + "56.03645" + ], + [ + "-78.57299", + "58.62888" + ], + [ + "-77.50835", + "62.56166" + ], + [ + "-73.68346", + "62.47999" + ], + [ + "-70.14848", + "61.08458" + ], + [ + "-67.56610", + "58.22360" + ], + [ + "-64.74538", + "60.23075" + ], + [ + "-61.09055", + "55.84415" + ], + [ + "-57.34969", + "54.57496" + ], + [ + "-56.95160", + "51.42458" + ], + [ + "-60.00500", + "50.24888" + ], + [ + "-66.44903", + "50.26777" + ], + [ + "-64.21167", + "48.88499" + ], + [ + "-64.90430", + "46.84597" + ], + [ + "-63.66708", + "45.81666" + ], + [ + "-70.19187", + "43.57555" + ], + [ + "-70.72610", + "41.72777" + ], + [ + "-74.13390", + "40.70082" + ], + [ + "-75.96083", + "37.15221" + ], + [ + "-76.34326", + "34.88194" + ], + [ + "-78.82750", + "33.73027" + ], + [ + "-81.48843", + "31.11347" + ], + [ + "-80.03534", + "26.79569" + ], + [ + "-81.73659", + "25.95944" + ], + [ + "-84.01098", + "30.09764" + ], + [ + "-88.98083", + "30.41833" + ], + [ + "-94.75417", + "29.36791" + ], + [ + "-97.56041", + "26.84208" + ], + [ + "-97.74223", + "22.01250" + ], + [ + "-95.80112", + "18.74500" + ], + [ + "-94.46918", + "18.14625" + ], + [ + "-90.73167", + "19.36153" + ], + [ + "-90.27972", + "21.06305" + ], + [ + "-86.82973", + "21.42923" + ], + [ + "-88.28250", + "17.62389" + ], + [ + "-88.13696", + "15.68285" + ], + [ + "-84.26015", + "15.82597" + ], + [ + "-83.18695", + "14.32389" + ], + [ + "-83.84751", + "11.17458" + ], + [ + "-82.24278", + "9.00236" + ], + [ + "-79.53445", + "9.62014" + ], + [ + "-77.36667", + "8.67500" + ] + ] + ], + [ + [ + [ + "-55.19333", + "46.98499" + ], + [ + "-59.40361", + "47.89423" + ], + [ + "-56.68250", + "51.33943" + ], + [ + "-55.56114", + "49.36818" + ], + [ + "-52.83465", + "48.09965" + ], + [ + "-55.19333", + "46.98499" + ] + ] + ], + [ + [ + [ + "-73.03644", + "18.45622" + ], + [ + "-72.79834", + "19.94278" + ], + [ + "-69.94932", + "19.67680" + ], + [ + "-68.89528", + "18.39639" + ], + [ + "-73.03644", + "18.45622" + ] + ] + ] + ] + }, + "properties": { + "CONTINENT": "North America" + } + }, + { + "type": "Feature", + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + "64.52222", + "68.90305" + ], + [ + "66.10887", + "67.48123" + ], + [ + "59.57756", + "63.93287" + ], + [ + "59.44912", + "58.48804" + ], + [ + "57.22169", + "56.85096" + ], + [ + "59.64166", + "55.55867" + ], + [ + "57.97027", + "54.38819" + ], + [ + "58.33777", + "51.15610" + ], + [ + "55.69249", + "50.53249" + ], + [ + "52.34180", + "51.78075" + ], + [ + "47.30249", + "50.03194" + ], + [ + "49.44831", + "45.53038" + ], + [ + "49.76062", + "42.71076" + ], + [ + "47.91547", + "41.22499" + ], + [ + "45.16512", + "42.70333" + ], + [ + "41.59748", + "43.22151" + ], + [ + "39.94553", + "43.39693" + ], + [ + "34.70249", + "46.17582" + ], + [ + "30.83277", + "46.54832" + ], + [ + "28.78083", + "44.66096" + ], + [ + "28.01305", + "41.98222" + ], + [ + "26.36041", + "40.95388" + ], + [ + "22.59500", + "40.01221" + ], + [ + "23.96055", + "38.28166" + ], + [ + "22.15246", + "37.01854" + ], + [ + "19.30721", + "40.64531" + ], + [ + "19.59771", + "41.80611" + ], + [ + "15.15167", + "44.19639" + ], + [ + "13.02958", + "41.26014" + ], + [ + "8.74722", + "44.42805" + ], + [ + "6.16528", + "43.05055" + ], + [ + "4.05625", + "43.56277" + ], + [ + "3.20167", + "41.89278" + ], + [ + "0.99306", + "41.04805" + ], + [ + "0.20722", + "38.73221" + ], + [ + "-2.12292", + "36.73347" + ], + [ + "-5.61361", + "36.00610" + ], + [ + "-6.95992", + "37.22184" + ], + [ + "-8.98924", + "37.02631" + ], + [ + "-9.49083", + "38.79388" + ], + [ + "-8.66014", + "40.69111" + ], + [ + "-9.16972", + "43.18583" + ], + [ + "-1.44389", + "43.64055" + ], + [ + "-1.11463", + "46.31658" + ], + [ + "-2.68528", + "48.50166" + ], + [ + "1.43875", + "50.10083" + ], + [ + "5.59917", + "53.30028" + ], + [ + "13.80854", + "53.85479" + ], + [ + "21.24506", + "54.95506" + ], + [ + "21.05223", + "56.81749" + ], + [ + "23.43159", + "59.95382" + ], + [ + "21.42416", + "60.57930" + ], + [ + "21.58500", + "64.43971" + ], + [ + "17.09861", + "61.60278" + ], + [ + "19.07264", + "59.73819" + ], + [ + "16.37982", + "56.66333" + ], + [ + "12.46007", + "56.29666" + ], + [ + "10.51569", + "59.30624" + ], + [ + "8.12750", + "58.09888" + ], + [ + "5.50847", + "58.66764" + ], + [ + "4.94944", + "61.41041" + ], + [ + "9.54528", + "63.76611" + ], + [ + "15.28833", + "68.03055" + ], + [ + "21.30000", + "70.24693" + ], + [ + "28.20778", + "71.07999" + ], + [ + "32.80605", + "69.30277" + ], + [ + "43.75180", + "67.31152" + ], + [ + "53.60437", + "68.90818" + ], + [ + "64.52222", + "68.90305" + ] + ] + ], + [ + [ + [ + "-13.49944", + "65.06915" + ], + [ + "-18.77500", + "63.39139" + ], + [ + "-22.04556", + "64.04666" + ], + [ + "-22.42167", + "66.43332" + ], + [ + "-16.41736", + "66.27603" + ], + [ + "-13.49944", + "65.06915" + ] + ] + ], + [ + [ + [ + "-4.19667", + "57.48583" + ], + [ + "-0.07931", + "54.11340" + ], + [ + "0.25389", + "50.73861" + ], + [ + "-3.43722", + "50.60500" + ], + [ + "-4.19639", + "53.20611" + ], + [ + "-2.89979", + "53.72499" + ], + [ + "-6.22778", + "56.69722" + ], + [ + "-4.19667", + "57.48583" + ] + ] + ], + [ + [ + [ + "12.44167", + "37.80611" + ], + [ + "15.64794", + "38.26458" + ], + [ + "15.08139", + "36.64916" + ], + [ + "12.44167", + "37.80611" + ] + ] + ] + ] + }, + "properties": { + "CONTINENT": "Europe" + } + }, + { + "type": "Feature", + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + "34.21666", + "31.32333" + ], + [ + "34.90380", + "29.48671" + ], + [ + "33.93833", + "26.65528" + ], + [ + "36.88625", + "22.05319" + ], + [ + "37.43569", + "18.85389" + ], + [ + "38.58902", + "18.06680" + ], + [ + "39.71805", + "15.08805" + ], + [ + "41.17222", + "14.63069" + ], + [ + "43.32750", + "12.47673" + ], + [ + "44.27833", + "10.44778" + ], + [ + "50.09319", + "11.51458" + ], + [ + "51.14555", + "10.63361" + ], + [ + "48.00055", + "4.52306" + ], + [ + "46.02555", + "2.43722" + ], + [ + "43.48861", + "0.65000" + ], + [ + "40.12548", + "-3.26569" + ], + [ + "38.77611", + "-6.03972" + ], + [ + "40.38777", + "-11.31778" + ], + [ + "40.57833", + "-15.49889" + ], + [ + "34.89069", + "-19.86042" + ], + [ + "35.45611", + "-24.16945" + ], + [ + "32.81111", + "-25.61209" + ], + [ + "32.39444", + "-28.53139" + ], + [ + "27.90000", + "-33.04056" + ], + [ + "24.82472", + "-34.20167" + ], + [ + "22.53916", + "-34.01118" + ], + [ + "20.00000", + "-34.82200" + ], + [ + "17.84750", + "-32.83083" + ], + [ + "18.21791", + "-31.73458" + ], + [ + "15.09500", + "-26.73528" + ], + [ + "14.51139", + "-22.55278" + ], + [ + "11.76764", + "-17.98820" + ], + [ + "11.73125", + "-15.85070" + ], + [ + "13.84944", + "-10.95611" + ], + [ + "13.39180", + "-8.39375" + ], + [ + "11.77417", + "-4.54264" + ], + [ + "9.70250", + "-2.44792" + ], + [ + "9.29833", + "-0.37167" + ], + [ + "9.96514", + "3.08521" + ], + [ + "8.89861", + "4.58833" + ], + [ + "5.93583", + "4.33833" + ], + [ + "4.41021", + "6.35993" + ], + [ + "1.46889", + "6.18639" + ], + [ + "-2.05889", + "4.73083" + ], + [ + "-4.46806", + "5.29556" + ], + [ + "-7.43639", + "4.34917" + ], + [ + "-9.23889", + "5.12278" + ], + [ + "-12.50417", + "7.38861" + ], + [ + "-13.49313", + "9.56008" + ], + [ + "-15.00542", + "10.77194" + ], + [ + "-17.17556", + "14.65444" + ], + [ + "-16.03945", + "17.73458" + ], + [ + "-16.91625", + "21.94542" + ], + [ + "-12.96271", + "27.92048" + ], + [ + "-11.51195", + "28.30375" + ], + [ + "-9.64097", + "30.16500" + ], + [ + "-8.53833", + "33.25055" + ], + [ + "-6.84306", + "34.01861" + ], + [ + "-5.91874", + "35.79065" + ], + [ + "-1.97972", + "35.07333" + ], + [ + "1.18250", + "36.51221" + ], + [ + "9.85868", + "37.32833" + ], + [ + "11.12667", + "35.24194" + ], + [ + "11.17430", + "33.21006" + ], + [ + "15.16583", + "32.39861" + ], + [ + "15.75430", + "31.38972" + ], + [ + "18.95750", + "30.27639" + ], + [ + "20.56763", + "32.56091" + ], + [ + "29.03500", + "30.82417" + ], + [ + "30.35545", + "31.50284" + ], + [ + "34.21666", + "31.32333" + ] + ] + ], + [ + [ + [ + "48.03140", + "-14.06341" + ], + [ + "49.94333", + "-13.03945" + ], + [ + "50.48277", + "-15.40583" + ], + [ + "49.36833", + "-18.35139" + ], + [ + "47.13305", + "-24.92806" + ], + [ + "44.01708", + "-24.98083" + ], + [ + "43.23888", + "-22.28250" + ], + [ + "44.48277", + "-19.96584" + ], + [ + "43.93139", + "-17.50056" + ], + [ + "44.87360", + "-16.21028" + ], + [ + "48.03140", + "-14.06341" + ] + ] + ] + ] + }, + "properties": { + "CONTINENT": "Africa" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + "-77.88972", + "7.22889" + ], + [ + "-77.36667", + "8.67500" + ], + [ + "-75.63432", + "9.44819" + ], + [ + "-74.86081", + "11.12549" + ], + [ + "-68.84368", + "11.44708" + ], + [ + "-68.11424", + "10.48493" + ], + [ + "-61.87959", + "10.72833" + ], + [ + "-61.61987", + "9.90528" + ], + [ + "-57.51919", + "6.27077" + ], + [ + "-52.97320", + "5.47305" + ], + [ + "-51.25931", + "4.15250" + ], + [ + "-49.90320", + "1.17444" + ], + [ + "-51.92751", + "-1.33486" + ], + [ + "-48.42722", + "-1.66028" + ], + [ + "-47.28556", + "-0.59917" + ], + [ + "-42.23584", + "-2.83778" + ], + [ + "-39.99875", + "-2.84653" + ], + [ + "-37.17445", + "-4.91861" + ], + [ + "-35.47973", + "-5.16611" + ], + [ + "-34.83129", + "-6.98180" + ], + [ + "-35.32751", + "-9.22889" + ], + [ + "-39.05709", + "-13.38028" + ], + [ + "-38.87195", + "-15.87417" + ], + [ + "-39.70403", + "-19.42361" + ], + [ + "-42.03445", + "-22.91917" + ], + [ + "-44.67521", + "-23.05570" + ], + [ + "-48.02612", + "-25.01500" + ], + [ + "-48.84251", + "-28.61778" + ], + [ + "-52.21764", + "-31.74500" + ], + [ + "-54.14077", + "-34.66466" + ], + [ + "-56.15834", + "-34.92722" + ], + [ + "-56.67834", + "-36.92361" + ], + [ + "-58.30112", + "-38.48500" + ], + [ + "-62.06875", + "-39.50848" + ], + [ + "-62.39001", + "-40.90195" + ], + [ + "-65.13014", + "-40.84417" + ], + [ + "-65.24945", + "-44.31306" + ], + [ + "-67.58435", + "-46.00030" + ], + [ + "-65.78979", + "-47.96584" + ], + [ + "-68.94112", + "-50.38806" + ], + [ + "-68.99014", + "-51.62445" + ], + [ + "-72.11501", + "-53.68764" + ], + [ + "-74.28924", + "-50.48049" + ], + [ + "-74.74139", + "-47.71146" + ], + [ + "-72.61389", + "-44.47278" + ], + [ + "-73.99432", + "-40.96695" + ], + [ + "-73.22404", + "-39.41688" + ], + [ + "-73.67709", + "-37.34729" + ], + [ + "-71.44667", + "-32.66500" + ], + [ + "-71.69585", + "-30.50667" + ], + [ + "-70.91389", + "-27.62445" + ], + [ + "-70.05334", + "-21.42565" + ], + [ + "-70.31202", + "-18.43750" + ], + [ + "-71.49424", + "-17.30223" + ], + [ + "-75.05139", + "-15.46597" + ], + [ + "-76.39480", + "-13.88417" + ], + [ + "-78.99459", + "-8.21965" + ], + [ + "-81.17473", + "-6.08667" + ], + [ + "-81.27640", + "-4.28083" + ], + [ + "-79.95632", + "-3.20778" + ], + [ + "-80.91279", + "-1.03653" + ], + [ + "-80.10084", + "0.77028" + ], + [ + "-78.88929", + "1.23837" + ], + [ + "-77.43445", + "4.03139" + ], + [ + "-77.88972", + "7.22889" + ] + ] + ] + }, + "properties": { + "CONTINENT": "South America" + } + }, + { + "type": "Feature", + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + "177.91779", + "-38.94280" + ], + [ + "175.95523", + "-41.25528" + ], + [ + "173.75165", + "-39.27000" + ], + [ + "174.94025", + "-38.10111" + ], + [ + "177.91779", + "-38.94280" + ] + ] + ], + [ + [ + [ + "171.18524", + "-44.93833" + ], + [ + "169.45801", + "-46.62333" + ], + [ + "166.47690", + "-45.80972" + ], + [ + "168.37233", + "-44.04056" + ], + [ + "171.15166", + "-42.56042" + ], + [ + "172.63025", + "-40.51056" + ], + [ + "174.23636", + "-41.83722" + ], + [ + "171.18524", + "-44.93833" + ] + ] + ] + ] + }, + "properties": { + "CONTINENT": "Oceania" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + "151.54025", + "-24.04583" + ], + [ + "153.18192", + "-25.94944" + ], + [ + "153.62419", + "-28.66104" + ], + [ + "152.52969", + "-32.40361" + ], + [ + "151.45456", + "-33.31681" + ], + [ + "149.97163", + "-37.52222" + ], + [ + "146.87357", + "-38.65166" + ], + [ + "143.54295", + "-38.85923" + ], + [ + "140.52997", + "-38.00028" + ], + [ + "138.09225", + "-34.13493" + ], + [ + "135.49586", + "-34.61708" + ], + [ + "134.18414", + "-32.48666" + ], + [ + "131.14859", + "-31.47403" + ], + [ + "125.97227", + "-32.26674" + ], + [ + "123.73499", + "-33.77972" + ], + [ + "120.00499", + "-33.92889" + ], + [ + "117.93414", + "-35.12534" + ], + [ + "115.00895", + "-34.26243" + ], + [ + "115.73998", + "-31.86806" + ], + [ + "113.64346", + "-26.65431" + ], + [ + "113.38971", + "-24.42944" + ], + [ + "114.03027", + "-21.84167" + ], + [ + "116.70749", + "-20.64917" + ], + [ + "121.02748", + "-19.59222" + ], + [ + "122.95623", + "-16.58681" + ], + [ + "126.85790", + "-13.75097" + ], + [ + "129.08942", + "-14.89944" + ], + [ + "130.57927", + "-12.40465" + ], + [ + "132.67198", + "-11.50813" + ], + [ + "135.23135", + "-12.29445" + ], + [ + "135.45135", + "-14.93278" + ], + [ + "136.76581", + "-15.90445" + ], + [ + "140.83330", + "-17.45194" + ], + [ + "141.66553", + "-15.02653" + ], + [ + "141.59412", + "-12.53167" + ], + [ + "142.78830", + "-11.08056" + ], + [ + "143.78220", + "-14.41333" + ], + [ + "145.31580", + "-14.94555" + ], + [ + "146.27762", + "-18.88701" + ], + [ + "147.43192", + "-19.41236" + ], + [ + "150.81912", + "-22.73194" + ], + [ + "151.54025", + "-24.04583" + ] + ] + ] + }, + "properties": { + "CONTINENT": "Australia" + } + } + ] +} \ No newline at end of file diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/map_config.test.ts b/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/map_config.test.ts new file mode 100644 index 0000000000000..1e8e5b6012a79 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/map_config.test.ts @@ -0,0 +1,40 @@ +/* + * 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 { getLayerList } from './map_config'; +import { mockLayerList } from './__mocks__/mock'; +import { LocationPoint } from './embedded_map'; + +jest.mock('uuid', () => { + return { + v4: jest.fn(() => 'uuid.v4()'), + }; +}); + +describe('map_config', () => { + let upPoints: LocationPoint[]; + let downPoints: LocationPoint[]; + + beforeEach(() => { + upPoints = [ + { lat: '52.487239', lon: '13.399262' }, + { lat: '55.487239', lon: '13.399262' }, + { lat: '54.487239', lon: '14.399262' }, + ]; + downPoints = [ + { lat: '52.487239', lon: '13.399262' }, + { lat: '55.487239', lon: '13.399262' }, + { lat: '54.487239', lon: '14.399262' }, + ]; + }); + + describe('#getLayerList', () => { + test('it returns the low poly layer', () => { + const layerList = getLayerList(upPoints, downPoints); + expect(layerList).toStrictEqual(mockLayerList); + }); + }); +}); diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/map_config.ts b/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/map_config.ts new file mode 100644 index 0000000000000..608df8b235f00 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/map_config.ts @@ -0,0 +1,167 @@ +/* + * 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 lowPolyLayerFeatures from './low_poly_layer.json'; +import { LocationPoint } from './embedded_map'; + +/** + * Returns `Source/Destination Point-to-point` Map LayerList configuration, with a source, + * destination, and line layer for each of the provided indexPatterns + * + */ +export const getLayerList = (upPoints: LocationPoint[], downPoints: LocationPoint[]) => { + return [getLowPolyLayer(), getDownPointsLayer(downPoints), getUpPointsLayer(upPoints)]; +}; + +export const getLowPolyLayer = () => { + return { + id: 'low_poly_layer', + label: 'World countries', + minZoom: 0, + maxZoom: 24, + alpha: 1, + sourceDescriptor: { + id: 'b7486535-171b-4d3b-bb2e-33c1a0a2854c', + type: 'GEOJSON_FILE', + __featureCollection: lowPolyLayerFeatures, + }, + visible: true, + style: { + type: 'VECTOR', + properties: { + fillColor: { + type: 'STATIC', + options: { + color: '#cad3e4', + }, + }, + lineColor: { + type: 'STATIC', + options: { + color: '#fff', + }, + }, + lineWidth: { + type: 'STATIC', + options: { + size: 0, + }, + }, + iconSize: { + type: 'STATIC', + options: { + size: 6, + }, + }, + }, + }, + type: 'VECTOR', + }; +}; + +export const getDownPointsLayer = (downPoints: LocationPoint[]) => { + const features = downPoints?.map(point => ({ + type: 'feature', + geometry: { + type: 'Point', + coordinates: [+point.lon, +point.lat], + }, + })); + return { + id: 'down_points', + label: 'Down Locations', + sourceDescriptor: { + type: 'GEOJSON_FILE', + __featureCollection: { + features, + type: 'FeatureCollection', + }, + }, + visible: true, + style: { + type: 'VECTOR', + properties: { + fillColor: { + type: 'STATIC', + options: { + color: '#BC261E', + }, + }, + lineColor: { + type: 'STATIC', + options: { + color: '#fff', + }, + }, + lineWidth: { + type: 'STATIC', + options: { + size: 2, + }, + }, + iconSize: { + type: 'STATIC', + options: { + size: 6, + }, + }, + }, + }, + type: 'VECTOR', + }; +}; + +export const getUpPointsLayer = (upPoints: LocationPoint[]) => { + const features = upPoints?.map(point => ({ + type: 'feature', + geometry: { + type: 'Point', + coordinates: [+point.lon, +point.lat], + }, + })); + return { + id: 'up_points', + label: 'Up Locations', + sourceDescriptor: { + type: 'GEOJSON_FILE', + __featureCollection: { + features, + type: 'FeatureCollection', + }, + }, + visible: true, + style: { + type: 'VECTOR', + properties: { + fillColor: { + type: 'STATIC', + options: { + color: '#98A2B2', + }, + }, + lineColor: { + type: 'STATIC', + options: { + color: '#fff', + }, + }, + lineWidth: { + type: 'STATIC', + options: { + size: 2, + }, + }, + iconSize: { + type: 'STATIC', + options: { + size: 6, + }, + }, + }, + }, + type: 'VECTOR', + }; +}; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/translations.ts b/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/translations.ts new file mode 100644 index 0000000000000..a5f68228efb1a --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/translations.ts @@ -0,0 +1,14 @@ +/* + * 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 { i18n } from '@kbn/i18n'; + +export const MAP_TITLE = i18n.translate( + 'xpack.uptime.components.embeddables.embeddedMap.embeddablePanelTitle', + { + defaultMessage: 'Monitor Observer Location Map', + } +); diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/types.ts b/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/types.ts new file mode 100644 index 0000000000000..5cac204ffb071 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/functional/location_map/embeddables/types.ts @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { Query } from 'src/plugins/data/common'; +import { TimeRange } from 'src/plugins/data/public'; +import { + EmbeddableInput, + EmbeddableOutput, + IEmbeddable, +} from '../../../../../../../../../src/legacy/core_plugins/embeddable_api/public/np_ready/public'; + +import { esFilters } from '../../../../../../../../../src/plugins/data/public'; + +export interface MapEmbeddableInput extends EmbeddableInput { + filters: esFilters.Filter[]; + query: Query; + refreshConfig: { + isPaused: boolean; + interval: number; + }; + timeRange?: TimeRange; +} + +export interface CustomProps { + setLayerList: Function; +} + +export type MapEmbeddable = IEmbeddable & CustomProps; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/index.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/location_map/index.tsx new file mode 100644 index 0000000000000..1f4b88b971c4c --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/functional/location_map/index.tsx @@ -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 * from './location_map'; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/location_map/location_map.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/location_map/location_map.tsx new file mode 100644 index 0000000000000..b271632cb631f --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/functional/location_map/location_map.tsx @@ -0,0 +1,38 @@ +/* + * 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 styled from 'styled-components'; +import { EmbeddedMap, LocationPoint } from './embeddables/embedded_map'; + +const MapPanel = styled.div` + height: 400px; + width: 520px; +`; + +interface LocationMapProps { + monitorLocations: any; +} + +export const LocationMap = ({ monitorLocations }: LocationMapProps) => { + const upPoints: LocationPoint[] = []; + const downPoints: LocationPoint[] = []; + + if (monitorLocations?.locations) { + monitorLocations.locations.forEach((item: any) => { + if (item.summary.down === 0) { + upPoints.push(item.geo.location); + } else { + downPoints.push(item.geo.location); + } + }); + } + return ( + + + + ); +}; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_bar/monitor_status_bar.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_bar/monitor_status_bar.tsx index 7ef6c3ed1e4bf..f36f0dff6745f 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_bar/monitor_status_bar.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_bar/monitor_status_bar.tsx @@ -4,8 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiFlexGroup, EuiFlexItem, EuiHealth, EuiLink, EuiPanel } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; +import { EuiFlexGroup, EuiFlexItem, EuiHealth, EuiLink } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { get } from 'lodash'; import moment from 'moment'; @@ -16,6 +15,7 @@ import { monitorStatusBarQuery } from '../../../queries'; import { EmptyStatusBar } from '../empty_status_bar'; import { convertMicrosecondsToMilliseconds } from '../../../lib/helper'; import { MonitorSSLCertificate } from './monitor_ssl_certificate'; +import * as labels from './translations'; interface MonitorStatusBarQueryResult { monitorStatus?: Ping[]; @@ -28,58 +28,33 @@ interface MonitorStatusBarProps { type Props = MonitorStatusBarProps & UptimeGraphQLQueryProps; export const MonitorStatusBarComponent = ({ data, monitorId }: Props) => { - if (data && data.monitorStatus && data.monitorStatus.length) { + if (data?.monitorStatus?.length) { const { monitor, timestamp, tls } = data.monitorStatus[0]; const duration: number | undefined = get(monitor, 'duration.us', undefined); const status = get<'up' | 'down'>(monitor, 'status', 'down'); const full = get(data.monitorStatus[0], 'url.full'); return ( - + <> - {status === 'up' - ? i18n.translate('xpack.uptime.monitorStatusBar.healthStatusMessage.upLabel', { - defaultMessage: 'Up', - }) - : i18n.translate('xpack.uptime.monitorStatusBar.healthStatusMessage.downLabel', { - defaultMessage: 'Down', - })} + {status === 'up' ? labels.upLabel : labels.downLabel} - + {full} {!!duration && ( - + { /> )} - + {moment(new Date(timestamp).valueOf()).fromNow()} - + ); } - return ( - - ); + return ; }; export const MonitorStatusBar = withUptimeGraphQL< diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_bar/translations.ts b/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_bar/translations.ts new file mode 100644 index 0000000000000..1c2844f4f6ccf --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_bar/translations.ts @@ -0,0 +1,49 @@ +/* + * 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 { i18n } from '@kbn/i18n'; + +export const healthStatusMessageAriaLabel = i18n.translate( + 'xpack.uptime.monitorStatusBar.healthStatusMessageAriaLabel', + { + defaultMessage: 'Monitor status', + } +); + +export const upLabel = i18n.translate('xpack.uptime.monitorStatusBar.healthStatusMessage.upLabel', { + defaultMessage: 'Up', +}); + +export const downLabel = i18n.translate( + 'xpack.uptime.monitorStatusBar.healthStatusMessage.downLabel', + { + defaultMessage: 'Down', + } +); + +export const monitorUrlLinkAriaLabel = i18n.translate( + 'xpack.uptime.monitorStatusBar.monitorUrlLinkAriaLabel', + { + defaultMessage: 'Monitor URL link', + } +); + +export const durationTextAriaLabel = i18n.translate( + 'xpack.uptime.monitorStatusBar.durationTextAriaLabel', + { + defaultMessage: 'Monitor duration in milliseconds', + } +); + +export const timestampFromNowTextAriaLabel = i18n.translate( + 'xpack.uptime.monitorStatusBar.timestampFromNowTextAriaLabel', + { + defaultMessage: 'Time since last check', + } +); + +export const loadingMessage = i18n.translate('xpack.uptime.monitorStatusBar.loadingMessage', { + defaultMessage: 'Loading…', +}); diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/index.ts b/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/index.ts new file mode 100644 index 0000000000000..234586e0b51f1 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/index.ts @@ -0,0 +1,34 @@ +/* + * 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 { connect } from 'react-redux'; +import { AppState } from '../../../state'; +import { getMonitorLocations } from '../../../state/selectors'; +import { fetchMonitorLocations } from '../../../state/actions/monitor'; +import { MonitorStatusDetailsComponent } from './monitor_status_details'; + +const mapStateToProps = (state: AppState, { monitorId }: any) => ({ + monitorLocations: getMonitorLocations(state, monitorId), +}); + +const mapDispatchToProps = (dispatch: any, ownProps: any) => ({ + loadMonitorLocations: () => { + const { dateStart, dateEnd, monitorId } = ownProps; + dispatch( + fetchMonitorLocations({ + monitorId, + dateStart, + dateEnd, + }) + ); + }, +}); + +export const MonitorStatusDetails = connect( + mapStateToProps, + mapDispatchToProps +)(MonitorStatusDetailsComponent); + +export * from './monitor_status_details'; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/monitor_status_details.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/monitor_status_details.tsx new file mode 100644 index 0000000000000..cf337eaec4bbc --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/monitor_status_details.tsx @@ -0,0 +1,45 @@ +/* + * 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, { useEffect } from 'react'; +import { EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui'; +import { LocationMap } from '../location_map'; +import { MonitorStatusBar } from '../monitor_status_bar'; + +interface MonitorStatusBarProps { + monitorId: string; + variables: any; + loadMonitorLocations: any; + monitorLocations: any; + dateStart: any; + dateEnd: any; +} + +export const MonitorStatusDetailsComponent = ({ + monitorId, + variables, + loadMonitorLocations, + monitorLocations, + dateStart, + dateEnd, +}: MonitorStatusBarProps) => { + useEffect(() => { + loadMonitorLocations(monitorId); + }, [monitorId, dateStart, dateEnd]); + + return ( + + + + + + + + + + + ); +}; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/translations.ts b/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/translations.ts new file mode 100644 index 0000000000000..1c2844f4f6ccf --- /dev/null +++ b/x-pack/legacy/plugins/uptime/public/components/functional/monitor_status_details/translations.ts @@ -0,0 +1,49 @@ +/* + * 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 { i18n } from '@kbn/i18n'; + +export const healthStatusMessageAriaLabel = i18n.translate( + 'xpack.uptime.monitorStatusBar.healthStatusMessageAriaLabel', + { + defaultMessage: 'Monitor status', + } +); + +export const upLabel = i18n.translate('xpack.uptime.monitorStatusBar.healthStatusMessage.upLabel', { + defaultMessage: 'Up', +}); + +export const downLabel = i18n.translate( + 'xpack.uptime.monitorStatusBar.healthStatusMessage.downLabel', + { + defaultMessage: 'Down', + } +); + +export const monitorUrlLinkAriaLabel = i18n.translate( + 'xpack.uptime.monitorStatusBar.monitorUrlLinkAriaLabel', + { + defaultMessage: 'Monitor URL link', + } +); + +export const durationTextAriaLabel = i18n.translate( + 'xpack.uptime.monitorStatusBar.durationTextAriaLabel', + { + defaultMessage: 'Monitor duration in milliseconds', + } +); + +export const timestampFromNowTextAriaLabel = i18n.translate( + 'xpack.uptime.monitorStatusBar.timestampFromNowTextAriaLabel', + { + defaultMessage: 'Time since last check', + } +); + +export const loadingMessage = i18n.translate('xpack.uptime.monitorStatusBar.loadingMessage', { + defaultMessage: 'Loading…', +}); diff --git a/x-pack/legacy/plugins/uptime/public/pages/monitor.tsx b/x-pack/legacy/plugins/uptime/public/pages/monitor.tsx index 86a0a9e4b0f0b..8c5fced2f2864 100644 --- a/x-pack/legacy/plugins/uptime/public/pages/monitor.tsx +++ b/x-pack/legacy/plugins/uptime/public/pages/monitor.tsx @@ -4,26 +4,19 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - // @ts-ignore No typings for EuiSpacer - EuiSpacer, -} from '@elastic/eui'; +import { EuiSpacer } from '@elastic/eui'; import { ApolloQueryResult, OperationVariables, QueryOptions } from 'apollo-client'; import gql from 'graphql-tag'; import React, { Fragment, useContext, useEffect, useState } from 'react'; import { getMonitorPageBreadcrumb } from '../breadcrumbs'; -import { - MonitorCharts, - MonitorPageTitle, - MonitorStatusBar, - PingList, -} from '../components/functional'; +import { MonitorCharts, MonitorPageTitle, PingList } from '../components/functional'; import { UMUpdateBreadcrumbs } from '../lib/lib'; import { UptimeSettingsContext } from '../contexts'; import { useUrlParams } from '../hooks'; import { stringifyUrlParams } from '../lib/helper/stringify_url_params'; import { useTrackPageview } from '../../../infra/public'; import { getTitle } from '../lib/helper/get_title'; +import { MonitorStatusDetails } from '../components/functional/monitor_status_details'; interface MonitorPageProps { logMonitorPageLoad: () => void; @@ -92,7 +85,12 @@ export const MonitorPage = ({ - + => { + const url = getApiPath(`/api/uptime/monitor/locations`, basePath); + + const params = { + dateStart, + dateEnd, + monitorId, + }; + const urlParams = new URLSearchParams(params).toString(); + const response = await fetch(`${url}?${urlParams}`); + + if (!response.ok) { + throw new Error(response.statusText); + } + return response.json().then(data => { + ThrowReporter.report(MonitorLocationsType.decode(data)); + return data; + }); +}; diff --git a/x-pack/legacy/plugins/uptime/public/state/effects/monitor.ts b/x-pack/legacy/plugins/uptime/public/state/effects/monitor.ts index 529b9041c9093..210004bb343bb 100644 --- a/x-pack/legacy/plugins/uptime/public/state/effects/monitor.ts +++ b/x-pack/legacy/plugins/uptime/public/state/effects/monitor.ts @@ -10,8 +10,11 @@ import { FETCH_MONITOR_DETAILS, FETCH_MONITOR_DETAILS_SUCCESS, FETCH_MONITOR_DETAILS_FAIL, + FETCH_MONITOR_LOCATIONS, + FETCH_MONITOR_LOCATIONS_SUCCESS, + FETCH_MONITOR_LOCATIONS_FAIL, } from '../actions/monitor'; -import { fetchMonitorDetails } from '../api'; +import { fetchMonitorDetails, fetchMonitorLocations } from '../api'; import { getBasePath } from '../selectors'; function* monitorDetailsEffect(action: Action) { @@ -25,6 +28,18 @@ function* monitorDetailsEffect(action: Action) { } } +function* monitorLocationsEffect(action: Action) { + const payload = action.payload; + try { + const basePath = yield select(getBasePath); + const response = yield call(fetchMonitorLocations, { basePath, ...payload }); + yield put({ type: FETCH_MONITOR_LOCATIONS_SUCCESS, payload: response }); + } catch (error) { + yield put({ type: FETCH_MONITOR_LOCATIONS_FAIL, payload: error.message }); + } +} + export function* fetchMonitorDetailsEffect() { yield takeLatest(FETCH_MONITOR_DETAILS, monitorDetailsEffect); + yield takeLatest(FETCH_MONITOR_LOCATIONS, monitorLocationsEffect); } diff --git a/x-pack/legacy/plugins/uptime/public/state/reducers/monitor.ts b/x-pack/legacy/plugins/uptime/public/state/reducers/monitor.ts index 4cacb6f8cab9e..220ab0b205462 100644 --- a/x-pack/legacy/plugins/uptime/public/state/reducers/monitor.ts +++ b/x-pack/legacy/plugins/uptime/public/state/reducers/monitor.ts @@ -10,16 +10,24 @@ import { FETCH_MONITOR_DETAILS, FETCH_MONITOR_DETAILS_SUCCESS, FETCH_MONITOR_DETAILS_FAIL, + FETCH_MONITOR_LOCATIONS, + FETCH_MONITOR_LOCATIONS_SUCCESS, + FETCH_MONITOR_LOCATIONS_FAIL, } from '../actions/monitor'; +import { MonitorLocations } from '../../../common/runtime_types'; + +type MonitorLocationsList = Map; export interface MonitorState { monitorDetailsList: MonitorDetailsState[]; + monitorLocationsList: MonitorLocationsList; loading: boolean; errors: any[]; } const initialState: MonitorState = { monitorDetailsList: [], + monitorLocationsList: new Map(), loading: false, errors: [], }; @@ -42,10 +50,27 @@ export function monitorReducer(state = initialState, action: MonitorActionTypes) loading: false, }; case FETCH_MONITOR_DETAILS_FAIL: - const error = action.payload; return { ...state, - errors: [...state.errors, error], + errors: [...state.errors, action.payload], + }; + case FETCH_MONITOR_LOCATIONS: + return { + ...state, + loading: true, + }; + case FETCH_MONITOR_LOCATIONS_SUCCESS: + const monLocations = state.monitorLocationsList; + monLocations.set(action.payload.monitorId, action.payload); + return { + ...state, + monitorLocationsList: monLocations, + loading: false, + }; + case FETCH_MONITOR_LOCATIONS_FAIL: + return { + ...state, + errors: [...state.errors, action.payload], }; default: return state; diff --git a/x-pack/legacy/plugins/uptime/public/state/selectors/__tests__/index.test.ts b/x-pack/legacy/plugins/uptime/public/state/selectors/__tests__/index.test.ts index 70cd2b19860ba..b61ed83663435 100644 --- a/x-pack/legacy/plugins/uptime/public/state/selectors/__tests__/index.test.ts +++ b/x-pack/legacy/plugins/uptime/public/state/selectors/__tests__/index.test.ts @@ -11,6 +11,7 @@ describe('state selectors', () => { const state: AppState = { monitor: { monitorDetailsList: [], + monitorLocationsList: new Map(), loading: false, errors: [], }, diff --git a/x-pack/legacy/plugins/uptime/public/state/selectors/index.ts b/x-pack/legacy/plugins/uptime/public/state/selectors/index.ts index 245b45a939950..1792c84c45220 100644 --- a/x-pack/legacy/plugins/uptime/public/state/selectors/index.ts +++ b/x-pack/legacy/plugins/uptime/public/state/selectors/index.ts @@ -14,3 +14,7 @@ export const isIntegrationsPopupOpen = ({ ui: { integrationsPopoverOpen } }: App export const getMonitorDetails = (state: AppState, summary: any) => { return state.monitor.monitorDetailsList[summary.monitor_id]; }; + +export const getMonitorLocations = (state: AppState, monitorId: string) => { + return state.monitor.monitorLocationsList?.get(monitorId); +}; diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/adapter_types.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/adapter_types.ts index f6ac587b0ceec..1191eb813a214 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/adapter_types.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/adapter_types.ts @@ -17,4 +17,10 @@ export interface UMMonitorsAdapter { getFilterBar(request: any, dateRangeStart: string, dateRangeEnd: string): Promise; getMonitorPageTitle(request: any, monitorId: string): Promise; getMonitorDetails(request: any, monitorId: string): Promise; + getMonitorLocations( + request: any, + monitorId: string, + dateStart: string, + dateEnd: string + ): Promise; } diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/elasticsearch_monitors_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/elasticsearch_monitors_adapter.ts index c7ebc77af3567..4009a4b1331fa 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/elasticsearch_monitors_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/elasticsearch_monitors_adapter.ts @@ -16,7 +16,12 @@ import { import { getHistogramIntervalFormatted } from '../../helper'; import { DatabaseAdapter } from '../database'; import { UMMonitorsAdapter } from './adapter_types'; -import { MonitorDetails, MonitorError } from '../../../../common/runtime_types'; +import { + MonitorDetails, + MonitorError, + MonitorLocations, + MonitorLocation, +} from '../../../../common/runtime_types'; const formatStatusBuckets = (time: any, buckets: any, docCount: any) => { let up = null; @@ -273,6 +278,11 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter { }; } + /** + * Fetch data for the monitor page title. + * @param request Kibana server request + * @param monitorId the ID to query + */ public async getMonitorDetails(request: any, monitorId: string): Promise { const params = { index: INDEX_NAMES.HEARTBEAT, @@ -320,4 +330,100 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter { timestamp: errorTimeStamp, }; } + + /** + * Fetch data for the monitor page title. + * @param request Kibana server request + * @param monitorId the ID to query + */ + public async getMonitorLocations( + request: any, + monitorId: string, + dateStart: string, + dateEnd: string + ): Promise { + const params = { + index: INDEX_NAMES.HEARTBEAT, + body: { + size: 0, + query: { + bool: { + filter: [ + { + match: { + 'monitor.id': monitorId, + }, + }, + { + exists: { + field: 'summary', + }, + }, + { + range: { + '@timestamp': { + gte: dateStart, + lte: dateEnd, + }, + }, + }, + ], + }, + }, + aggs: { + location: { + terms: { + field: 'observer.geo.name', + missing: '__location_missing__', + }, + aggs: { + most_recent: { + top_hits: { + size: 1, + sort: { + '@timestamp': { + order: 'desc', + }, + }, + _source: ['monitor', 'summary', 'observer'], + }, + }, + }, + }, + }, + }, + }; + + const result = await this.database.search(request, params); + const locations = result?.aggregations?.location?.buckets ?? []; + + const getGeo = (locGeo: any) => { + const { name, location } = locGeo; + const latLon = location.trim().split(','); + return { + name, + location: { + lat: latLon[0], + lon: latLon[1], + }, + }; + }; + + const monLocs: MonitorLocation[] = []; + locations.forEach((loc: any) => { + if (loc?.key !== '__location_missing__') { + const mostRecentLocation = loc.most_recent.hits.hits[0]._source; + const location: MonitorLocation = { + summary: mostRecentLocation?.summary, + geo: getGeo(mostRecentLocation?.observer?.geo), + }; + monLocs.push(location); + } + }); + + return { + monitorId, + locations: monLocs, + }; + } } diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/index.ts b/x-pack/legacy/plugins/uptime/server/rest_api/index.ts index 2810982fb0c6c..f18b9e8e44c36 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/index.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/index.ts @@ -9,7 +9,7 @@ import { createGetIndexPatternRoute } from './index_pattern'; import { createLogMonitorPageRoute, createLogOverviewPageRoute } from './telemetry'; import { createGetSnapshotCount } from './snapshot'; import { UMRestApiRouteCreator } from './types'; -import { createGetMonitorDetailsRoute } from './monitors'; +import { createGetMonitorDetailsRoute, createGetMonitorLocationsRoute } from './monitors'; export * from './types'; export { createRouteWithAuth } from './create_route_with_auth'; @@ -17,6 +17,7 @@ export const restApiRoutes: UMRestApiRouteCreator[] = [ createGetAllRoute, createGetIndexPatternRoute, createGetMonitorDetailsRoute, + createGetMonitorLocationsRoute, createGetSnapshotCount, createLogMonitorPageRoute, createLogOverviewPageRoute, diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/monitors/index.ts b/x-pack/legacy/plugins/uptime/server/rest_api/monitors/index.ts index 2c4b9e9fb1f3e..2279233d49a09 100644 --- a/x-pack/legacy/plugins/uptime/server/rest_api/monitors/index.ts +++ b/x-pack/legacy/plugins/uptime/server/rest_api/monitors/index.ts @@ -5,3 +5,4 @@ */ export { createGetMonitorDetailsRoute } from './monitors_details'; +export { createGetMonitorLocationsRoute } from './monitor_locations'; diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitor_locations.ts b/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitor_locations.ts new file mode 100644 index 0000000000000..4a91255bd19f2 --- /dev/null +++ b/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitor_locations.ts @@ -0,0 +1,33 @@ +/* + * 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 { schema } from '@kbn/config-schema'; +import { UMServerLibs } from '../../lib/lib'; +import { UMRestApiRouteCreator } from '../types'; + +export const createGetMonitorLocationsRoute: UMRestApiRouteCreator = (libs: UMServerLibs) => ({ + method: 'GET', + path: '/api/uptime/monitor/locations', + validate: { + query: schema.object({ + monitorId: schema.string(), + dateStart: schema.string(), + dateEnd: schema.string(), + }), + }, + options: { + tags: ['access:uptime'], + }, + handler: async (_context, request, response): Promise => { + const { monitorId, dateStart, dateEnd } = request.query; + + return response.ok({ + body: { + ...(await libs.monitors.getMonitorLocations(request, monitorId, dateStart, dateEnd)), + }, + }); + }, +});