Skip to content

Commit

Permalink
Add deprecated message to tile_map and region_map visualizations. (el…
Browse files Browse the repository at this point in the history
…astic#77683)

* Add deprecation message to coordinate map and region map

* clean up text

* add default distro link and view in maps link

* move url generation into onClick handler

* create tile map layer descritor

* set metrics and color and scaling

* lazy load createTileMapLayerDescriptor

* tslint fixes

* tslint cleanup for OSS code

* add region map deprecation message

* tslint cleanup

* consolidate logic into LegacyMapDeprecationMessage

* fix jest test

* fix tile-map and region_map in OSS distro

* tslint fixes

* assert urlGenerator exists

* update message text

* ensure legacy-ids get correctly evaluated (#37)

* handle 6.x region map saved objects

* turn off field meta

* fix type

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
Co-authored-by: Thomas Neirynck <thomas@elastic.co>
# Conflicts:
#	src/plugins/visualizations/public/vis_types/base_vis_type.ts
  • Loading branch information
nreese committed Sep 28, 2020
1 parent 8f456ba commit efcb715
Show file tree
Hide file tree
Showing 24 changed files with 899 additions and 84 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import React from 'react';
import { EuiButton, EuiCallOut, EuiLink } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';

interface Props {
isMapsAvailable: boolean;
onClick: (e: React.MouseEvent<HTMLButtonElement>) => Promise<void>;
visualizationLabel: string;
}

export function LegacyMapDeprecationMessage(props: Props) {
const getMapsMessage = !props.isMapsAvailable ? (
<FormattedMessage
id="maps_legacy.defaultDistributionMessage"
defaultMessage="To get Maps, upgrade to the {defaultDistribution} of Elasticsearch and Kibana."
values={{
defaultDistribution: (
<EuiLink
color="accent"
external
href="https://www.elastic.co/downloads/kibana"
target="_blank"
>
default distribution
</EuiLink>
),
}}
/>
) : null;

const button = props.isMapsAvailable ? (
<div>
<EuiButton onClick={props.onClick} size="s">
<FormattedMessage id="maps_legacy.openInMapsButtonLabel" defaultMessage="View in Maps" />
</EuiButton>
</div>
) : null;

return (
<EuiCallOut
className="hide-for-sharing"
data-test-subj="deprecatedVisInfo"
size="s"
title={i18n.translate('maps_legacy.legacyMapDeprecationTitle', {
defaultMessage: '{label} will migrate to Maps in 8.0.',
values: { label: props.visualizationLabel },
})}
>
<p>
<FormattedMessage
id="maps_legacy.legacyMapDeprecationMessage"
defaultMessage="With Maps, you can add multiple layers and indices, plot individual documents, symbolize features from data values, add heatmaps, grids, and clusters, and more. {getMapsMessage}"
values={{ getMapsMessage }}
/>
</p>
{button}
</EuiCallOut>
);
}
1 change: 1 addition & 0 deletions src/plugins/maps_legacy/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export * from './common/types';
export { ORIGIN } from './common/constants/origin';

export { WmsOptions } from './components/wms_options';
export { LegacyMapDeprecationMessage } from './components/legacy_map_deprecation_message';

export { lazyLoadMapsLegacyModules } from './lazy_load_bundle';

Expand Down
3 changes: 2 additions & 1 deletion src/plugins/region_map/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"expressions",
"mapsLegacy",
"kibanaLegacy",
"data"
"data",
"share"
],
"requiredBundles": [
"kibanaUtils",
Expand Down
93 changes: 93 additions & 0 deletions src/plugins/region_map/public/get_deprecation_message.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

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

function getEmsLayerId(id: string | number, layerId: string) {
if (typeof id === 'string') {
return id;
}

// Region maps from 6.x will have numerical EMS id refering to S3 bucket id.
// In this case, use layerId with contains the EMS layer name.
const split = layerId.split('.');
return split.length === 2 ? split[1] : undefined;
}

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 query = getQueryService();
const createUrlParams: { [key: string]: any } = {
label: vis.title ? vis.title : title,
emsLayerId: vis.params.selectedLayer.isEMS
? getEmsLayerId(vis.params.selectedLayer.id, vis.params.selectedLayer.layerId)
: undefined,
leftFieldName: vis.params.selectedLayer.isEMS ? vis.params.selectedJoinField.name : undefined,
colorSchema: vis.params.colorSchema,
indexPatternId: vis.data.indexPattern?.id,
indexPatternTitle: vis.data.indexPattern?.title,
metricAgg: 'count',
filters: query.filterManager.getFilters(),
query: query.queryString.getQuery(),
timeRange: query.timefilter.timefilter.getTime(),
};

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

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

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

return (
<LegacyMapDeprecationMessage
isMapsAvailable={!!mapsRegionMapUrlGenerator}
onClick={onClick}
visualizationLabel={title}
/>
);
}
10 changes: 10 additions & 0 deletions src/plugins/region_map/public/kibana_services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@
* under the License.
*/

import { CoreStart } from 'kibana/public';
import { NotificationsStart } from 'kibana/public';
import { createGetterSetter } from '../../kibana_utils/public';
import { DataPublicPluginStart } from '../../data/public';
import { KibanaLegacyStart } from '../../kibana_legacy/public';
import { SharePluginStart } from '../../share/public';

export const [getCoreService, setCoreService] = createGetterSetter<CoreStart>('Core');

export const [getFormatService, setFormatService] = createGetterSetter<
DataPublicPluginStart['fieldFormats']
Expand All @@ -30,6 +34,12 @@ export const [getNotifications, setNotifications] = createGetterSetter<Notificat
'Notifications'
);

export const [getQueryService, setQueryService] = createGetterSetter<
DataPublicPluginStart['query']
>('Query');

export const [getShareService, setShareService] = createGetterSetter<SharePluginStart>('Share');

export const [getKibanaLegacy, setKibanaLegacy] = createGetterSetter<KibanaLegacyStart>(
'KibanaLegacy'
);
22 changes: 17 additions & 5 deletions src/plugins/region_map/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,19 @@ import { createRegionMapFn } from './region_map_fn';
// @ts-ignore
import { createRegionMapTypeDefinition } from './region_map_type';
import { IServiceSettings, MapsLegacyPluginSetup } from '../../maps_legacy/public';
import { setFormatService, setNotifications, setKibanaLegacy } from './kibana_services';
import {
setCoreService,
setFormatService,
setNotifications,
setKibanaLegacy,
setQueryService,
setShareService,
} from './kibana_services';
import { DataPublicPluginStart } from '../../data/public';
import { RegionMapsConfigType } from './index';
import { MapsLegacyConfig } from '../../maps_legacy/config';
import { KibanaLegacyStart } from '../../kibana_legacy/public';
import { SharePluginStart } from '../../share/public';

/** @private */
interface RegionMapVisualizationDependencies {
Expand All @@ -57,6 +65,7 @@ export interface RegionMapPluginStartDependencies {
data: DataPublicPluginStart;
notifications: NotificationsStart;
kibanaLegacy: KibanaLegacyStart;
share: SharePluginStart;
}

/** @internal */
Expand Down Expand Up @@ -108,10 +117,13 @@ export class RegionMapPlugin implements Plugin<RegionMapPluginSetup, RegionMapPl
};
}

// @ts-ignore
public start(core: CoreStart, { data, kibanaLegacy }: RegionMapPluginStartDependencies) {
setFormatService(data.fieldFormats);
public start(core: CoreStart, plugins: RegionMapPluginStartDependencies) {
setCoreService(core);
setFormatService(plugins.data.fieldFormats);
setQueryService(plugins.data.query);
setNotifications(core.notifications);
setKibanaLegacy(kibanaLegacy);
setKibanaLegacy(plugins.kibanaLegacy);
setShareService(plugins.share);
return {};
}
}
3 changes: 3 additions & 0 deletions src/plugins/region_map/public/region_map_type.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,16 @@ import { RegionMapOptions } from './components/region_map_options';
import { truncatedColorSchemas } from '../../charts/public';
import { Schemas } from '../../vis_default_editor/public';
import { ORIGIN } from '../../maps_legacy/public';
import { getDeprecationMessage } from './get_deprecation_message';

export function createRegionMapTypeDefinition(dependencies) {
const { uiSettings, regionmapsConfig, getServiceSettings } = dependencies;
const visualization = createRegionMapVisualization(dependencies);

return {
name: 'region_map',
isDeprecated: true,
getDeprecationMessage,
title: i18n.translate('regionMap.mapVis.regionMapTitle', { defaultMessage: 'Region Map' }),
description: i18n.translate('regionMap.mapVis.regionMapDescription', {
defaultMessage:
Expand Down
3 changes: 2 additions & 1 deletion src/plugins/tile_map/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"expressions",
"mapsLegacy",
"kibanaLegacy",
"data"
"data",
"share"
],
"requiredBundles": [
"kibanaUtils",
Expand Down
89 changes: 89 additions & 0 deletions src/plugins/tile_map/public/get_deprecation_message.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { i18n } from '@kbn/i18n';
import React from 'react';
import { UrlGeneratorContract } from 'src/plugins/share/public';
import { getCoreService, 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 query = getQueryService();
const createUrlParams: { [key: string]: any } = {
label: vis.title ? vis.title : title,
mapType: vis.params.mapType,
colorSchema: vis.params.colorSchema,
indexPatternId: vis.data.indexPattern?.id,
metricAgg: 'count',
filters: query.filterManager.getFilters(),
query: query.queryString.getQuery(),
timeRange: query.timefilter.timefilter.getTime(),
};

const bucketAggs = vis.data?.aggs?.byType('buckets');
if (bucketAggs?.length && bucketAggs[0].type.dslName === 'geohash_grid') {
createUrlParams.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) => {
return (
!indexPatterns.isNestedField(field) && field.aggregatable && field.type === 'geo_point'
);
});
if (geoField) {
createUrlParams.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;
}

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

return (
<LegacyMapDeprecationMessage
isMapsAvailable={!!mapsTileMapUrlGenerator}
onClick={onClick}
visualizationLabel={title}
/>
);
}
Loading

0 comments on commit efcb715

Please sign in to comment.