Skip to content

Commit

Permalink
Maps locators (elastic#102810)
Browse files Browse the repository at this point in the history
* feat: ๐ŸŽธ implement maps locator

* feat: ๐ŸŽธ add tile map locator

* feat: ๐ŸŽธ add region map locator

* feat: ๐ŸŽธ register maps locators

* refactor: ๐Ÿ’ก remove usage of mpas url gen, replace by locator

* chore: ๐Ÿค– remove url generators

* refactor: ๐Ÿ’ก use locators in maps deprecation messages

* chore: ๐Ÿค– remove maps url generators

* refactor: ๐Ÿ’ก use new property name

* feat: ๐ŸŽธ use constant

Co-authored-by: Vadim Kibana <vadimkibana@gmail.com>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
3 people authored Jun 25, 2021
1 parent bc8ba83 commit bc6ee27
Show file tree
Hide file tree
Showing 7 changed files with 367 additions and 352 deletions.
32 changes: 11 additions & 21 deletions src/plugins/region_map/public/get_deprecation_message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@

import { i18n } from '@kbn/i18n';
import React from 'react';
import { UrlGeneratorContract } from 'src/plugins/share/public';
import { getCoreService, getQueryService, getShareService } from './kibana_services';
import { getQueryService, getShareService } from './kibana_services';
import { Vis } from '../../visualizations/public';
import { LegacyMapDeprecationMessage } from '../../maps_legacy/public';

Expand All @@ -25,24 +24,16 @@ function getEmsLayerId(id: string | number, layerId: string) {
}

export function getDeprecationMessage(vis: Vis) {
let mapsRegionMapUrlGenerator:
| UrlGeneratorContract<'MAPS_APP_REGION_MAP_URL_GENERATOR'>
| undefined;
try {
mapsRegionMapUrlGenerator = getShareService().urlGenerators.getUrlGenerator(
'MAPS_APP_REGION_MAP_URL_GENERATOR'
);
} catch (error) {
// ignore error thrown when url generator is not available
}

const title = i18n.translate('regionMap.mapVis.regionMapTitle', { defaultMessage: 'Region Map' });

async function onClick(e: React.MouseEvent<HTMLButtonElement>) {
e.preventDefault();

const locator = getShareService().url.locators.get('MAPS_APP_REGION_MAP_LOCATOR');
if (!locator) return;

const query = getQueryService();
const createUrlParams: { [key: string]: any } = {
const params: { [key: string]: any } = {
label: vis.title ? vis.title : title,
emsLayerId: vis.params.selectedLayer.isEMS
? getEmsLayerId(vis.params.selectedLayer.id, vis.params.selectedLayer.layerId)
Expand All @@ -59,23 +50,22 @@ export function getDeprecationMessage(vis: Vis) {

const bucketAggs = vis.data?.aggs?.byType('buckets');
if (bucketAggs?.length && bucketAggs[0].type.dslName === 'terms') {
createUrlParams.termsFieldName = bucketAggs[0].getField()?.name;
createUrlParams.termsSize = bucketAggs[0].getParam('size');
params.termsFieldName = bucketAggs[0].getField()?.name;
params.termsSize = bucketAggs[0].getParam('size');
}

const metricAggs = vis.data?.aggs?.byType('metrics');
if (metricAggs?.length) {
createUrlParams.metricAgg = metricAggs[0].type.dslName;
createUrlParams.metricFieldName = metricAggs[0].getField()?.name;
params.metricAgg = metricAggs[0].type.dslName;
params.metricFieldName = metricAggs[0].getField()?.name;
}

const url = await mapsRegionMapUrlGenerator!.createUrl(createUrlParams);
getCoreService().application.navigateToUrl(url);
locator.navigate(params);
}

return (
<LegacyMapDeprecationMessage
isMapsAvailable={!!mapsRegionMapUrlGenerator}
isMapsAvailable={!!getShareService().url.locators.get('MAPS_APP_REGION_MAP_LOCATOR')}
onClick={onClick}
visualizationLabel={title}
/>
Expand Down
30 changes: 11 additions & 19 deletions src/plugins/tile_map/public/get_deprecation_message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,24 @@

import { i18n } from '@kbn/i18n';
import React from 'react';
import { UrlGeneratorContract } from 'src/plugins/share/public';
import { getCoreService, getQueryService, getShareService } from './services';
import { getQueryService, getShareService } from './services';
import { indexPatterns } from '../../data/public';
import { Vis } from '../../visualizations/public';
import { LegacyMapDeprecationMessage } from '../../maps_legacy/public';

export function getDeprecationMessage(vis: Vis) {
let mapsTileMapUrlGenerator: UrlGeneratorContract<'MAPS_APP_TILE_MAP_URL_GENERATOR'> | undefined;
try {
mapsTileMapUrlGenerator = getShareService().urlGenerators.getUrlGenerator(
'MAPS_APP_TILE_MAP_URL_GENERATOR'
);
} catch (error) {
// ignore error thrown when url generator is not available
}

const title = i18n.translate('tileMap.vis.mapTitle', {
defaultMessage: 'Coordinate Map',
});

async function onClick(e: React.MouseEvent<HTMLButtonElement>) {
e.preventDefault();

const locator = getShareService().url.locators.get('MAPS_APP_TILE_MAP_LOCATOR');
if (!locator) return;

const query = getQueryService();
const createUrlParams: { [key: string]: any } = {
const params: { [key: string]: any } = {
label: vis.title ? vis.title : title,
mapType: vis.params.mapType,
colorSchema: vis.params.colorSchema,
Expand All @@ -45,7 +38,7 @@ export function getDeprecationMessage(vis: Vis) {

const bucketAggs = vis.data?.aggs?.byType('buckets');
if (bucketAggs?.length && bucketAggs[0].type.dslName === 'geohash_grid') {
createUrlParams.geoFieldName = bucketAggs[0].getField()?.name;
params.geoFieldName = bucketAggs[0].getField()?.name;
} else if (vis.data.indexPattern) {
// attempt to default to first geo point field when geohash is not configured yet
const geoField = vis.data.indexPattern.fields.find((field) => {
Expand All @@ -54,23 +47,22 @@ export function getDeprecationMessage(vis: Vis) {
);
});
if (geoField) {
createUrlParams.geoFieldName = geoField.name;
params.geoFieldName = geoField.name;
}
}

const metricAggs = vis.data?.aggs?.byType('metrics');
if (metricAggs?.length) {
createUrlParams.metricAgg = metricAggs[0].type.dslName;
createUrlParams.metricFieldName = metricAggs[0].getField()?.name;
params.metricAgg = metricAggs[0].type.dslName;
params.metricFieldName = metricAggs[0].getField()?.name;
}

const url = await mapsTileMapUrlGenerator!.createUrl(createUrlParams);
getCoreService().application.navigateToUrl(url);
locator.navigate(params);
}

return (
<LegacyMapDeprecationMessage
isMapsAvailable={!!mapsTileMapUrlGenerator}
isMapsAvailable={!!getShareService().url.locators.get('MAPS_APP_TILE_MAP_LOCATOR')}
onClick={onClick}
visualizationLabel={title}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,49 +5,49 @@
* 2.0.
*/

import { createMapsUrlGenerator } from './url_generator';
import { LAYER_TYPE, SOURCE_TYPES, SCALING_TYPES } from '../common/constants';
import { esFilters } from '../../../../src/plugins/data/public';
import { MapsAppLocatorDefinition } from './locators';
import { SerializableState } from '../../../../src/plugins/kibana_utils/common';
import { LayerDescriptor } from '../common/descriptor_types';

const APP_BASE_PATH: string = 'test/app/maps';
const MAP_ID: string = '2c9c1f60-1909-11e9-919b-ffe5949a18d2';
const LAYER_ID: string = '13823000-99b9-11ea-9eb6-d9e8adceb647';
const INDEX_PATTERN_ID: string = '90943e30-9a47-11e8-b64d-95841ca0b247';

describe('visualize url generator', () => {
test('creates a link to a new visualization', async () => {
const generator = createMapsUrlGenerator(() =>
Promise.resolve({
appBasePath: APP_BASE_PATH,
useHashedUrl: false,
})
);
const url = await generator.createUrl!({});
expect(url).toMatchInlineSnapshot(`"test/app/maps/map#/?_g=()&_a=()"`);
const locator = new MapsAppLocatorDefinition({
useHash: false,
});
const location = await locator.getLocation({});

expect(location).toMatchObject({
app: 'maps',
path: '/map#/?_g=()&_a=()',
state: {},
});
});

test('creates a link with global time range set up', async () => {
const generator = createMapsUrlGenerator(() =>
Promise.resolve({
appBasePath: APP_BASE_PATH,
useHashedUrl: false,
})
);
const url = await generator.createUrl!({
const locator = new MapsAppLocatorDefinition({
useHash: false,
});
const location = await locator.getLocation({
timeRange: { to: 'now', from: 'now-15m', mode: 'relative' },
});
expect(url).toMatchInlineSnapshot(
`"test/app/maps/map#/?_g=(time:(from:now-15m,mode:relative,to:now))&_a=()"`
);

expect(location).toMatchObject({
app: 'maps',
path: '/map#/?_g=(time:(from:now-15m,mode:relative,to:now))&_a=()',
state: {},
});
});

test('creates a link with initialLayers set up', async () => {
const generator = createMapsUrlGenerator(() =>
Promise.resolve({
appBasePath: APP_BASE_PATH,
useHashedUrl: false,
})
);
const locator = new MapsAppLocatorDefinition({
useHash: false,
});
const initialLayers = [
{
id: LAYER_ID,
Expand All @@ -64,22 +64,22 @@ describe('visualize url generator', () => {
},
},
];
const url = await generator.createUrl!({
initialLayers,
const location = await locator.getLocation({
initialLayers: (initialLayers as unknown) as LayerDescriptor[] & SerializableState,
});

expect(location).toMatchObject({
app: 'maps',
path: `/map#/?_g=()&_a=()&initialLayers=(id%3A'13823000-99b9-11ea-9eb6-d9e8adceb647'%2CsourceDescriptor%3A(geoField%3Atest%2Cid%3A'13823000-99b9-11ea-9eb6-d9e8adceb647'%2CindexPatternId%3A'90943e30-9a47-11e8-b64d-95841ca0b247'%2Clabel%3A'Sample%20Data'%2CscalingType%3ALIMIT%2CtooltipProperties%3A!()%2Ctype%3AES_SEARCH)%2Ctype%3AVECTOR%2Cvisible%3A!t)`,
state: {},
});
expect(url).toMatchInlineSnapshot(
`"test/app/maps/map#/?_g=()&_a=()&initialLayers=(id%3A'13823000-99b9-11ea-9eb6-d9e8adceb647'%2CsourceDescriptor%3A(geoField%3Atest%2Cid%3A'13823000-99b9-11ea-9eb6-d9e8adceb647'%2CindexPatternId%3A'90943e30-9a47-11e8-b64d-95841ca0b247'%2Clabel%3A'Sample%20Data'%2CscalingType%3ALIMIT%2CtooltipProperties%3A!()%2Ctype%3AES_SEARCH)%2Ctype%3AVECTOR%2Cvisible%3A!t)"`
);
});

test('creates a link with filters, time range, refresh interval and query to a saved visualization', async () => {
const generator = createMapsUrlGenerator(() =>
Promise.resolve({
appBasePath: APP_BASE_PATH,
useHashedUrl: false,
})
);
const url = await generator.createUrl!({
const locator = new MapsAppLocatorDefinition({
useHash: false,
});
const location = await locator.getLocation({
timeRange: { to: 'now', from: 'now-15m', mode: 'relative' },
refreshInterval: { pause: false, value: 300 },
mapId: MAP_ID,
Expand All @@ -106,8 +106,11 @@ describe('visualize url generator', () => {
],
query: { query: 'q2', language: 'kuery' },
});
expect(url).toMatchInlineSnapshot(
`"test/app/maps/map#/${MAP_ID}?_g=(filters:!(('$state':(store:globalState),meta:(alias:!n,disabled:!f,negate:!f),query:(query:q1))),refreshInterval:(pause:!f,value:300),time:(from:now-15m,mode:relative,to:now))&_a=(filters:!((meta:(alias:!n,disabled:!f,negate:!f),query:(query:q1))),query:(language:kuery,query:q2))"`
);

expect(location).toMatchObject({
app: 'maps',
path: `/map#/${MAP_ID}?_g=(filters:!(('$state':(store:globalState),meta:(alias:!n,disabled:!f,negate:!f),query:(query:q1))),refreshInterval:(pause:!f,value:300),time:(from:now-15m,mode:relative,to:now))&_a=(filters:!((meta:(alias:!n,disabled:!f,negate:!f),query:(query:q1))),query:(language:kuery,query:q2))`,
state: {},
});
});
});
Loading

0 comments on commit bc6ee27

Please sign in to comment.