From e2b7e4007255dd054f98af1c1d339d46c760a520 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Tue, 21 Jan 2020 13:41:36 -0500 Subject: [PATCH] [Uptime] Handle locations with names but no geo data (#55234) * Handle locations with names but no geo data. * Fix broken types, add a comment explaining some weird ts-related code. Co-authored-by: Elastic Machine --- .../location_map/embeddables/embedded_map.tsx | 6 ++--- .../location_map/embeddables/map_config.ts | 4 ++-- .../functional/location_map/location_map.tsx | 24 ++++++++++++------- .../elasticsearch_monitors_adapter.ts | 14 ++++++----- 4 files changed, 28 insertions(+), 20 deletions(-) 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 index 98780d23c5a629..11f6565734782e 100644 --- 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 @@ -12,6 +12,7 @@ import { start } from '../../../../../../../../../src/legacy/core_plugins/embedd import * as i18n from './translations'; // @ts-ignore import { MAP_SAVED_OBJECT_TYPE } from '../../../../../../maps/common/constants'; +import { Location } from '../../../../../common/runtime_types'; import { MapEmbeddable } from './types'; import { getLayerList } from './map_config'; @@ -22,10 +23,7 @@ export interface EmbeddedMapProps { downPoints: LocationPoint[]; } -export interface LocationPoint { - lat: string; - lon: string; -} +export type LocationPoint = Required; const EmbeddedPanel = styled.div` z-index: auto; 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 index d4601baefdf30c..a43edae4382527 100644 --- 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 @@ -5,7 +5,7 @@ */ import lowPolyLayerFeatures from './low_poly_layer.json'; -import { LocationPoint } from './embedded_map'; +import { LocationPoint } from './embedded_map.js'; import { UptimeAppColors } from '../../../../uptime_app'; /** @@ -16,7 +16,7 @@ import { UptimeAppColors } from '../../../../uptime_app'; export const getLayerList = ( upPoints: LocationPoint[], downPoints: LocationPoint[], - { gray, danger }: Pick + { danger }: Pick ) => { return [getLowPolyLayer(), getDownPointsLayer(downPoints, danger), getUpPointsLayer(upPoints)]; }; 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 index d35e1281260e2e..c93e16d0a080b5 100644 --- 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 @@ -9,7 +9,7 @@ import styled from 'styled-components'; import { EuiFlexGroup, EuiFlexItem, EuiErrorBoundary } from '@elastic/eui'; import { LocationStatusTags } from './location_status_tags'; import { EmbeddedMap, LocationPoint } from './embeddables/embedded_map'; -import { MonitorLocations } from '../../../../common/runtime_types'; +import { MonitorLocations, MonitorLocation } from '../../../../common/runtime_types'; import { UNNAMED_LOCATION } from '../../../../common/constants'; import { LocationMissingWarning } from './location_missing'; @@ -32,15 +32,23 @@ export const LocationMap = ({ monitorLocations }: LocationMapProps) => { let isGeoInfoMissing = false; if (monitorLocations?.locations) { - monitorLocations.locations.forEach((item: any) => { - if (item.geo?.name !== UNNAMED_LOCATION) { - if (item.summary.down === 0) { - upPoints.push(item.geo.location); + monitorLocations.locations.forEach((item: MonitorLocation) => { + if (item.geo?.name === UNNAMED_LOCATION || !item.geo?.location) { + isGeoInfoMissing = true; + } else if ( + item.geo?.name !== UNNAMED_LOCATION && + !!item.geo.location.lat && + !!item.geo.location.lon + ) { + // TypeScript doesn't infer that the above checks in this block's condition + // ensure that lat and lon are defined when we try to pass the location object directly, + // but if we destructure the values it does. Improvement to this block is welcome. + const { lat, lon } = item.geo.location; + if (item?.summary?.down === 0) { + upPoints.push({ lat, lon }); } else { - downPoints.push(item.geo.location); + downPoints.push({ lat, lon }); } - } else if (item.geo?.name === UNNAMED_LOCATION) { - isGeoInfoMissing = true; } }); } 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 c86e0db9ae04ad..e433931f03c8e6 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 @@ -346,16 +346,18 @@ export const elasticsearchMonitorsAdapter: UMMonitorsAdapter = { const result = await callES('search', params); const locations = result?.aggregations?.location?.buckets ?? []; - const getGeo = (locGeo: any) => { + const getGeo = (locGeo: { name: string; location?: string }) => { if (locGeo) { const { name, location } = locGeo; - const latLon = location.trim().split(','); + const latLon = location?.trim().split(','); return { name, - location: { - lat: latLon[0], - lon: latLon[1], - }, + location: latLon + ? { + lat: latLon[0], + lon: latLon[1], + } + : undefined, }; } else { return {