[Maps] add drawing toolbar to create filters to map (#33686)

This commit is contained in:
Thomas Neirynck 2019-05-07 17:19:34 -04:00 committed by GitHub
parent 1ef872c784
commit 2dd07b1b4e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 836 additions and 58 deletions

View file

@ -52,6 +52,7 @@ export const LICENSE_WHITELIST = [
'CC-BY-3.0',
'CC-BY-4.0',
'Eclipse Distribution License - v 1.0',
'FreeBSD',
'ISC',
'ISC*',
'MIT OR GPL-2.0',

View file

@ -178,6 +178,7 @@
"@kbn/i18n": "1.0.0",
"@kbn/interpreter": "1.0.0",
"@kbn/ui-framework": "1.0.0",
"@mapbox/mapbox-gl-draw": "^1.1.1",
"@samverschueren/stream-to-observable": "^0.3.0",
"@scant/router": "^0.1.0",
"@slack/client": "^4.8.0",
@ -255,6 +256,7 @@
"lodash.uniqby": "^4.7.0",
"lz-string": "^1.4.4",
"mapbox-gl": "0.52.0",
"mapbox-gl-draw-rectangle-mode": "^1.0.4",
"markdown-it": "^8.4.1",
"mime": "^2.2.2",
"mkdirp": "0.5.1",

View file

@ -28,3 +28,8 @@ export const APP_ICON = 'gisApp';
export const SOURCE_DATA_ID_ORIGIN = 'source';
export const FEATURE_ID_PROPERTY_NAME = '__kbn__feature_id__';
export const ES_GEO_FIELD_TYPE = {
GEO_POINT: 'geo_point',
GEO_SHAPE: 'geo_shape'
};

View file

@ -23,29 +23,39 @@
.mapContainer {
flex-grow: 1;
.mapboxgl-popup {
z-index: 100;
border-color: $euiColorEmptyShade;
}
.mapboxgl-popup-content {
background-color: $euiColorEmptyShade;
}
.mapboxgl-popup-tip {
border-top-color: $euiColorEmptyShade !important;
}
.mapboxgl-ctrl-top-left .mapboxgl-ctrl {
margin-left: $euiSizeM;
margin-top: $euiSizeM;
}
.mapboxgl-ctrl-group:not(:empty) {
@include euiBottomShadowLarge;
background-color: $euiColorEmptyShade;
border-radius: $euiBorderRadius;
> button {
@include size($euiSizeXL);
+ button {
border: none;
}
}
}
}
.mapboxgl-popup {
z-index: 100;
border-color: $euiColorEmptyShade;
}
.mapboxgl-popup-content {
background-color: $euiColorEmptyShade;
}
.mapboxgl-popup-tip {
border-top-color: $euiColorEmptyShade !important;
}
// This is not good practice to create such a generic class.
// I can't seem to find it being applied anywhere in GIS
// .hidden {
// display: none
// }
// EUIFIXTODO:
.euiColorPicker__emptySwatch {
position: relative;
}

View file

@ -52,6 +52,12 @@ export const TRACK_CURRENT_LAYER_STATE = 'TRACK_CURRENT_LAYER_STATE';
export const ROLLBACK_TO_TRACKED_LAYER_STATE = 'ROLLBACK_TO_TRACKED_LAYER_STATE';
export const REMOVE_TRACKED_LAYER_STATE = 'REMOVE_TRACKED_LAYER_STATE';
export const SET_TOOLTIP_STATE = 'SET_TOOLTIP_STATE';
export const UPDATE_DRAW_STATE = 'UPDATE_DRAW_STATE';
export const DRAW_TYPE = {
BOUNDS: 'BOUNDS',
POLYGON: 'POLYGON'
};
export const SET_SCROLL_ZOOM = 'SET_SCROLL_ZOOM';
function getLayerLoadingCallbacks(dispatch, layerId) {
@ -685,3 +691,15 @@ export function setJoinsForLayer(layer, joins) {
dispatch(syncDataForLayer(layer.getId()));
};
}
export function updateDrawState(drawState) {
return async (dispatch) => {
if (drawState !== null) {
await dispatch(setTooltipState(null));//tooltips just get in the way
}
dispatch({
type: UPDATE_DRAW_STATE,
drawState: drawState
});
};
}

View file

@ -2,3 +2,4 @@
@import './layer_addpanel/layer_addpanel';
@import './layer_panel/index';
@import './widget_overlay/index';
@import './toolbar_overlay/index';

View file

@ -7,6 +7,7 @@
import React, { Component } from 'react';
import { MBMapContainer } from '../map/mb';
import { WidgetOverlay } from '../widget_overlay/index';
import { ToolbarOverlay } from '../toolbar_overlay/index';
import { LayerPanel } from '../layer_panel/index';
import { AddLayerPanel } from '../layer_addpanel/index';
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
@ -47,13 +48,13 @@ export class GisMap extends Component {
interval
);
}
}
};
clearRefreshTimer = () => {
if (this.refreshTimerId) {
clearInterval(this.refreshTimerId);
}
}
};
render() {
const {
@ -91,6 +92,7 @@ export class GisMap extends Component {
<EuiFlexGroup gutterSize="none" responsive={false}>
<EuiFlexItem className="mapMapWrapper">
<MBMapContainer/>
<ToolbarOverlay />
<WidgetOverlay/>
</EuiFlexItem>

View file

@ -13,9 +13,17 @@ import {
setMouseCoordinates,
clearMouseCoordinates,
clearGoto,
setTooltipState
setTooltipState,
updateDrawState
} from '../../../actions/store_actions';
import { getTooltipState, getLayerList, getMapReady, getGoto, getScrollZoom } from '../../../selectors/map_selectors';
import {
getTooltipState,
getLayerList,
getMapReady,
getGoto,
getDrawState,
getScrollZoom
} from '../../../selectors/map_selectors';
import { getIsFilterable } from '../../../store/ui';
import { getInspectorAdapters } from '../../../store/non_serializable_instances';
@ -27,7 +35,8 @@ function mapStateToProps(state = {}) {
goto: getGoto(state),
inspectorAdapters: getInspectorAdapters(state),
tooltipState: getTooltipState(state),
scrollZoom: getScrollZoom(state),
drawState: getDrawState(state),
scrollZoom: getScrollZoom(state)
};
}
@ -55,6 +64,9 @@ function mapDispatchToProps(dispatch) {
},
setTooltipState(tooltipState) {
dispatch(setTooltipState(tooltipState));
},
disableDrawState() {
dispatch(updateDrawState(null));
}
};
}

View file

@ -9,10 +9,21 @@ import React from 'react';
import ReactDOM from 'react-dom';
import { ResizeChecker } from 'ui/resize_checker';
import { syncLayerOrder, removeOrphanedSourcesAndLayers, createMbMapInstance } from './utils';
import { DECIMAL_DEGREES_PRECISION, FEATURE_ID_PROPERTY_NAME, ZOOM_PRECISION } from '../../../../common/constants';
import {
DECIMAL_DEGREES_PRECISION,
FEATURE_ID_PROPERTY_NAME,
ZOOM_PRECISION
} from '../../../../common/constants';
import mapboxgl from 'mapbox-gl';
import MapboxDraw from '@mapbox/mapbox-gl-draw';
import DrawRectangle from 'mapbox-gl-draw-rectangle-mode';
import { FeatureTooltip } from '../feature_tooltip';
import { DRAW_TYPE } from '../../../actions/store_actions';
import { filterBarQueryFilter } from '../../../kibana_services';
import { createShapeFilterWithMeta, createExtentFilterWithMeta } from '../../../elasticsearch_geo_utils';
const mbDrawModes = MapboxDraw.modes;
mbDrawModes.draw_rectangle = DrawRectangle;
const TOOLTIP_TYPE = {
HOVER: 'HOVER',
@ -21,6 +32,21 @@ const TOOLTIP_TYPE = {
export class MBMapContainer extends React.Component {
state = {
isDrawingFilter: false
};
static getDerivedStateFromProps(nextProps, prevState) {
const nextIsDrawingFilter = nextProps.drawState !== null;
if (nextIsDrawingFilter === prevState.isDrawingFilter) {
return null;
}
return {
isDrawingFilter: nextIsDrawingFilter
};
}
constructor() {
super();
this._mbMap = null;
@ -29,22 +55,69 @@ export class MBMapContainer extends React.Component {
closeButton: false,
closeOnClick: false,
});
this._mbDrawControl = new MapboxDraw({
displayControlsDefault: false,
modes: mbDrawModes
});
this._mbDrawControlAdded = false;
}
_onTooltipClose = () => {
this.props.setTooltipState(null);
};
_onDraw = async (e) => {
if (!e.features.length) {
return;
}
const { geoField, geoFieldType, indexPatternId, drawType } = this.props.drawState;
this.props.disableDrawState();
let filter;
if (drawType === DRAW_TYPE.POLYGON) {
filter = createShapeFilterWithMeta(e.features[0].geometry, indexPatternId, geoField, geoFieldType);
} else if (drawType === DRAW_TYPE.BOUNDS) {
const coordinates = e.features[0].geometry.coordinates[0];
const extent = {
minLon: coordinates[0][0],
minLat: coordinates[0][1],
maxLon: coordinates[0][0],
maxLat: coordinates[0][1]
};
for (let i = 1; i < coordinates.length; i++) {
extent.minLon = Math.min(coordinates[i][0], extent.minLon);
extent.minLat = Math.min(coordinates[i][1], extent.minLat);
extent.maxLon = Math.max(coordinates[i][0], extent.maxLon);
extent.maxLat = Math.max(coordinates[i][1], extent.maxLat);
}
filter = createExtentFilterWithMeta(extent, indexPatternId, geoField, geoFieldType);
}
if (!filter) {
return;
}
filterBarQueryFilter.addFilters([filter]);
};
_debouncedSync = _.debounce(() => {
if (this._isMounted) {
this._syncMbMapWithLayerList();
this._syncMbMapWithInspector();
this._syncDrawControl();
}
}, 256);
_lockTooltip = (e) => {
if (this.state.isDrawingFilter) {
//ignore click events when in draw mode
return;
}
this._updateHoverTooltipState.cancel();//ignore any possible moves
const features = this._getFeaturesUnderPointer(e.point);
@ -54,7 +127,7 @@ export class MBMapContainer extends React.Component {
}
const targetFeature = features[0];
const layer = this._getLayer(targetFeature.layer.id);
const layer = this._getLayerByMbLayerId(targetFeature.layer.id);
const popupAnchorLocation = this._justifyAnchorLocation(e.lngLat, targetFeature);
this.props.setTooltipState({
type: TOOLTIP_TYPE.LOCKED,
@ -66,6 +139,11 @@ export class MBMapContainer extends React.Component {
_updateHoverTooltipState = _.debounce((e) => {
if (this.state.isDrawingFilter) {
//ignore hover events when in draw mode
return;
}
if (this.props.tooltipState && this.props.tooltipState.type === TOOLTIP_TYPE.LOCKED) {
//ignore hover events when tooltip is locked
return;
@ -85,7 +163,7 @@ export class MBMapContainer extends React.Component {
}
}
const layer = this._getLayer(targetFeature.layer.id);
const layer = this._getLayerByMbLayerId(targetFeature.layer.id);
const popupAnchorLocation = this._justifyAnchorLocation(e.lngLat, targetFeature);
this.props.setTooltipState({
@ -97,6 +175,7 @@ export class MBMapContainer extends React.Component {
}, 100);
_justifyAnchorLocation(mbLngLat, targetFeature) {
let popupAnchorLocation = [mbLngLat.lng, mbLngLat.lat]; // default popup location to mouse location
if (targetFeature.geometry.type === 'Point') {
@ -195,6 +274,30 @@ export class MBMapContainer extends React.Component {
this.props.onMapDestroyed();
}
_removeDrawControl() {
if (!this._mbDrawControlAdded) {
return;
}
this._mbMap.getCanvas().style.cursor = '';
this._mbMap.off('draw.create', this._onDraw);
this._mbMap.removeControl(this._mbDrawControl);
this._mbDrawControlAdded = false;
}
_updateDrawControl() {
if (!this._mbDrawControlAdded) {
this._mbMap.addControl(this._mbDrawControl);
this._mbDrawControlAdded = true;
this._mbMap.getCanvas().style.cursor = 'crosshair';
this._mbMap.on('draw.create', this._onDraw);
}
const mbDrawMode = this.props.drawState.drawType === DRAW_TYPE.POLYGON ?
this._mbDrawControl.modes.DRAW_POLYGON : 'draw_rectangle';
this._mbDrawControl.changeMode(mbDrawMode);
}
async _initializeMap() {
this._mbMap = await createMbMapInstance({
@ -293,6 +396,14 @@ export class MBMapContainer extends React.Component {
}
}
_syncDrawControl() {
if (this.state.isDrawingFilter) {
this._updateDrawControl();
} else {
this._removeDrawControl();
}
}
_syncMbMapWithMapState = () => {
const {
isMapReady,
@ -326,7 +437,13 @@ export class MBMapContainer extends React.Component {
};
_getLayer(mbLayerId) {
_getLayerById(layerId) {
return this.props.layerList.find((layer) => {
return layer.getId() === layerId;
});
}
_getLayerByMbLayerId(mbLayerId) {
return this.props.layerList.find((layer) => {
const mbLayerIds = layer.getMbLayerIds();
return mbLayerIds.indexOf(mbLayerId) > -1;

View file

@ -0,0 +1,17 @@
.mapToolbarOverlay {
position: absolute;
top: ($euiSizeM * 2) + ($euiSizeXL * 2); // Position and height of mapbox controls plus margin
left: $euiSizeM;
z-index: 2; // Sit on top of mapbox controls shadow
}
.mapToolbarOverlay__button {
@include size($euiSizeXL);
background-color: $euiColorEmptyShade !important;
&:enabled,
&:enabled:hover,
&:enabled:focus {
@include euiBottomShadowLarge;
}
}

View file

@ -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 { connect } from 'react-redux';
import { ToolbarOverlay } from './view';
import { getDrawState, getUniqueIndexPatternIds } from '../../selectors/map_selectors';
import { getIsFilterable } from '../../store/ui';
import { updateDrawState } from '../../actions/store_actions';
function mapStateToProps(state = {}) {
return {
isFilterable: getIsFilterable(state),
drawState: getDrawState(state),
uniqueIndexPatternIds: getUniqueIndexPatternIds(state)
};
}
function mapDispatchToProps(dispatch) {
return {
initiateDraw: (options) => {
dispatch(updateDrawState(options));
}
};
}
const connectedToolbarOverlay = connect(mapStateToProps, mapDispatchToProps)(ToolbarOverlay);
export { connectedToolbarOverlay as ToolbarOverlay };

View file

@ -0,0 +1,282 @@
/*
* 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, { Fragment } from 'react';
import {
EuiFlexGroup,
EuiFlexItem,
EuiButtonIcon,
EuiPopover,
EuiContextMenu,
EuiSelectable,
EuiHighlight,
EuiTextColor,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { getIndexPatternsFromIds } from '../../index_pattern_util';
import _ from 'lodash';
import { DRAW_TYPE } from '../../actions/store_actions';
import { ES_GEO_FIELD_TYPE } from '../../../common/constants';
const RESET_STATE = {
isPopoverOpen: false,
drawType: null
};
export class ToolbarOverlay extends React.Component {
state = {
isPopoverOpen: false,
uniqueIndexPatternsAndGeoFields: [],
drawType: null
};
_toggleToolbar = () => {
if (!this._isMounted) {
return;
}
this.setState(prevState => ({
isPopoverOpen: !prevState.isPopoverOpen,
drawType: null
}));
};
_closePopover = () => {
if (!this._isMounted) {
return;
}
this.setState(RESET_STATE);
};
_onIndexPatternSelection = (options) => {
if (!this._isMounted) {
return;
}
const selection = options.find((option) => option.checked);
const drawType = this.state.drawType;
this.setState(RESET_STATE, () => {
if (drawType) {
this.props.initiateDraw({ drawType: drawType, ...selection.value });
}
});
};
_activateDrawForFirstIndexPattern = (drawType) => {
if (!this._isMounted) {
return;
}
const indexPatternAndGeofield = this.state.uniqueIndexPatternsAndGeoFields[0];
this.setState(RESET_STATE, () => {
this.props.initiateDraw({ drawType: drawType, ...indexPatternAndGeofield });
});
};
componentDidMount() {
this._isMounted = true;
}
componentWillUnmount() {
this._isMounted = false;
}
async _getuniqueIndexPatternAndFieldCombos() {
try {
const indexPatterns = await getIndexPatternsFromIds(this.props.uniqueIndexPatternIds);
const uniqueIndexPatternsAndGeofields = [];
indexPatterns.forEach((indexPattern) => {
indexPattern.fields.forEach(field => {
if (field.type === ES_GEO_FIELD_TYPE.GEO_POINT || field.type === ES_GEO_FIELD_TYPE.GEO_SHAPE) {
uniqueIndexPatternsAndGeofields.push({
geoField: field.name,
geoFieldType: field.type,
indexPatternTitle: indexPattern.title,
indexPatternId: indexPattern.id
});
}
});
});
if (this._isMounted && !_.isEqual(this.state.uniqueIndexPatternsAndGeoFields, uniqueIndexPatternsAndGeofields)) {
this.setState({
uniqueIndexPatternsAndGeoFields: uniqueIndexPatternsAndGeofields
});
}
} catch(e) {
// swallow errors.
// the Layer-TOC will indicate which layers are disfunctional on a per-layer basis
return [];
}
}
componentDidUpdate() {
this._getuniqueIndexPatternAndFieldCombos();
}
_getDrawActionsPanel() {
const drawPolygonAction = {
name: i18n.translate('xpack.maps.toolbarOverlay.drawShapeLabel', {
defaultMessage: 'Draw shape to filter data',
}),
};
const drawBoundsAction = {
name: i18n.translate('xpack.maps.toolbarOverlay.drawBoundsLabel', {
defaultMessage: 'Draw bounds to filter data',
}),
};
if (this.state.uniqueIndexPatternsAndGeoFields.length === 1) {
drawPolygonAction.onClick = () => this._activateDrawForFirstIndexPattern(DRAW_TYPE.POLYGON);
drawBoundsAction.onClick = () => this._activateDrawForFirstIndexPattern(DRAW_TYPE.BOUNDS);
} else {
drawPolygonAction.panel = this._getIndexPatternSelectionPanel(1);
drawPolygonAction.onClick = () => {
this.setState({ drawType: DRAW_TYPE.POLYGON });
};
drawBoundsAction.panel = this._getIndexPatternSelectionPanel(2);
drawBoundsAction.onClick = () => {
this.setState({ drawType: DRAW_TYPE.BOUNDS });
};
}
return flattenPanelTree({
id: 0,
title: i18n.translate('xpack.maps.toolbarOverlay.tools.toolbarTitle', {
defaultMessage: 'Tools',
}),
items: [drawPolygonAction, drawBoundsAction]
});
}
_getIndexPatternSelectionPanel(id) {
const options = this.state.uniqueIndexPatternsAndGeoFields.map((indexPatternAndGeoField) => {
return {
label: `${indexPatternAndGeoField.indexPatternTitle} : ${indexPatternAndGeoField.geoField}`,
value: indexPatternAndGeoField
};
});
const renderGeoField = (option, searchValue) => {
return (
<Fragment>
<EuiTextColor color="subdued">
<small>
<EuiHighlight search={searchValue}>{option.value.indexPatternTitle}</EuiHighlight>
</small>
</EuiTextColor>
<br />
<EuiHighlight search={searchValue}>
{option.value.geoField}
</EuiHighlight>
</Fragment>
);
};
const indexPatternSelection = (
<EuiSelectable
searchable
searchProps={{
placeholder: i18n.translate('xpack.maps.toolbarOverlay.indexPattern.filterListTitle', {
defaultMessage: 'Filter list',
}),
compressed: true,
}}
options={options}
/**
* *TODO*: FIX this handler as EuiSelectable passes back the full options
* list with the selected option set with `checked: 'on'`
*/
onChange={this._onIndexPatternSelection}
renderOption={renderGeoField}
listProps={{
rowHeight: 50,
showIcons: false,
}}
>
{(list, search) => (
<div>
{search}
{list}
</div>
)}
</EuiSelectable>
);
return {
id: id,
title: i18n.translate('xpack.maps.toolbarOverlay.geofield.toolbarTitle', {
defaultMessage: 'Select geo field',
}),
content: indexPatternSelection
};
}
_renderToolbarButton() {
return (
<EuiButtonIcon
className="mapToolbarOverlay__button"
color="text"
iconType="wrench"
onClick={this._toggleToolbar}
aria-label={i18n.translate('xpack.maps.toolbarOverlay.toolbarIconTitle', {
defaultMessage: 'Tools',
})}
title={i18n.translate('xpack.maps.toolbarOverlay.toolbarIconTitle', {
defaultMessage: 'Tools',
})}
/>
);
}
render() {
if (
!this.props.isFilterable ||
!this.state.uniqueIndexPatternsAndGeoFields.length
) {
return null;
}
return (
<EuiFlexGroup className="mapToolbarOverlay" responsive={false} direction="row" alignItems="flexEnd" gutterSize="s">
<EuiFlexItem>
<EuiPopover
id="contextMenu"
button={this._renderToolbarButton()}
isOpen={this.state.isPopoverOpen}
closePopover={this._closePopover}
panelPaddingSize="none"
withTitle
anchorPosition="leftUp"
>
<EuiContextMenu
initialPanelId={0}
panels={this._getDrawActionsPanel()}
/>
</EuiPopover>
</EuiFlexItem>
</EuiFlexGroup>
);
}
}
function flattenPanelTree(tree, array = []) {
array.push(tree);
if (tree.items) {
tree.items.forEach(item => {
if (item.panel) {
flattenPanelTree(item.panel, array);
item.panel = item.panel.id;
}
});
}
return array;
}

View file

@ -6,6 +6,7 @@
import _ from 'lodash';
import { i18n } from '@kbn/i18n';
import { DECIMAL_DEGREES_PRECISION, ES_GEO_FIELD_TYPE } from '../common/constants';
/**
* Converts Elasticsearch search results into GeoJson FeatureCollection
@ -25,9 +26,9 @@ export function hitsToGeoJson(hits, flattenHit, geoFieldName, geoFieldType) {
const properties = flattenHit(hits[i]);
tmpGeometriesAccumulator.length = 0;//truncate accumulator
if (geoFieldType === 'geo_point') {
if (geoFieldType === ES_GEO_FIELD_TYPE.GEO_POINT) {
geoPointToGeometry(properties[geoFieldName], tmpGeometriesAccumulator);
} else if (geoFieldType === 'geo_shape') {
} else if (geoFieldType === ES_GEO_FIELD_TYPE.GEO_SHAPE) {
geoShapeToGeometry(properties[geoFieldName], tmpGeometriesAccumulator);
} else {
const errorMessage = i18n.translate('xpack.maps.elasticsearch_geo_utils.unsupportedFieldTypeErrorMessage', {
@ -184,8 +185,7 @@ const BOTTOM_RIGHT_INDEX = 2;
export function createExtentFilter(mapExtent, geoFieldName, geoFieldType) {
const safePolygon = convertMapExtentToPolygon(mapExtent);
if (geoFieldType === 'geo_point') {
if (geoFieldType === ES_GEO_FIELD_TYPE.GEO_POINT) {
const verticies = safePolygon.coordinates[POLYGON_COORDINATES_EXTERIOR_INDEX];
return {
geo_bounding_box: {
@ -195,7 +195,7 @@ export function createExtentFilter(mapExtent, geoFieldName, geoFieldType) {
}
}
};
} else if (geoFieldType === 'geo_shape') {
} else if (geoFieldType === ES_GEO_FIELD_TYPE.GEO_SHAPE) {
return {
geo_shape: {
[geoFieldName]: {
@ -205,7 +205,7 @@ export function createExtentFilter(mapExtent, geoFieldName, geoFieldType) {
}
};
} else {
const errorMessage = i18n.translate('xpack.maps.elasticsearch_geo_utils.unsupportedGeoFieldTypeErrorMessage', {
const errorMessage = i18n.translate('xpack.maps.elasticsearch_geo_utils.extent.unsupportedGeoFieldTypeErrorMessage', {
defaultMessage: `Unsupported field type, expected: geo_shape or geo_point, you provided: {geoFieldType}`,
values: { geoFieldType }
});
@ -213,6 +213,85 @@ export function createExtentFilter(mapExtent, geoFieldName, geoFieldType) {
}
}
export function createExtentFilterWithMeta(mapExtent, indexPatternId, geoFieldName, geoFieldType) {
const roundedExtent = {
minLon: _.round(mapExtent.minLon, DECIMAL_DEGREES_PRECISION),
minLat: _.round(mapExtent.minLat, DECIMAL_DEGREES_PRECISION),
maxLon: _.round(mapExtent.maxLon, DECIMAL_DEGREES_PRECISION),
maxLat: _.round(mapExtent.maxLat, DECIMAL_DEGREES_PRECISION)
};
const filter = createExtentFilter(roundedExtent, geoFieldName, geoFieldType);
filter.meta = {
negate: false,
index: indexPatternId,
alias: i18n.translate('xpack.maps.elasticsearch_geo_utils.extentFilter.aliasTitle', {
defaultMessage: `extent at {coordinate}`,
values: {
coordinate: `[${roundedExtent.minLon}, ${roundedExtent.minLat}, ${roundedExtent.maxLon}, ${roundedExtent.maxLat}]`
}
})
};
return filter;
}
export function createShapeFilterWithMeta(geojsonPolygon, indexPatternId, geoFieldName, geoFieldType) {
const filter = {
meta: {
negate: false,
index: indexPatternId,
alias: i18n.translate('xpack.maps.elasticsearch_geo_utils.shapeFilter.aliasTitle', {
defaultMessage: `shape at {coordinate}`,
values: {
// eslint-disable-next-line max-len
coordinate: `${_.round(geojsonPolygon.coordinates[0][0][0], DECIMAL_DEGREES_PRECISION)}, ${_.round(geojsonPolygon.coordinates[0][0][1], DECIMAL_DEGREES_PRECISION)}`
}
})
}
};
if (geoFieldType === ES_GEO_FIELD_TYPE.GEO_POINT) {
const pointsArray = geojsonPolygon.coordinates[0].map(coordinatePair => {
return {
lon: _.round(coordinatePair[0], DECIMAL_DEGREES_PRECISION),
lat: _.round(coordinatePair[1], DECIMAL_DEGREES_PRECISION)
};
});
filter.geo_polygon = {
ignore_unmapped: true,
[geoFieldName]: {
points: pointsArray
}
};
} else if (geoFieldType === ES_GEO_FIELD_TYPE.GEO_SHAPE) {
const geojsonCoordinateArray = geojsonPolygon.coordinates[0].map(coordinatePair => {
return [_.round(coordinatePair[0], DECIMAL_DEGREES_PRECISION), _.round(coordinatePair[1], DECIMAL_DEGREES_PRECISION)];
});
filter.geo_shape = {
ignore_unmapped: true,
[geoFieldName]: {
shape: {
type: 'Polygon',
coordinates: [geojsonCoordinateArray]
},
relation: 'INTERSECTS'
}
};
} else {
const errorMessage = i18n.translate('xpack.maps.elasticsearch_geo_utils.shape.unsupportedGeoFieldTypeErrorMessage', {
defaultMessage: `Unsupported field type, expected: geo_shape or geo_point, you provided: {geoFieldType}`,
values: { geoFieldType }
});
throw new Error(errorMessage);
}
return filter;
}
function formatEnvelopeAsPolygon({ maxLat, maxLon, minLat, minLon }) {
// GeoJSON mandates that the outer polygon must be counterclockwise to avoid ambiguous polygons
// when the shape crosses the dateline

View file

@ -24,8 +24,6 @@ import 'ui/autoload/styles';
import 'ui/autoload/all';
import 'react-vis/dist/style.css';
import 'mapbox-gl/dist/mapbox-gl.css';
import './angular/services/gis_map_saved_object_loader';
import './angular/map_controller';
import listingTemplate from './angular/listing_ng_wrapper.html';

View file

@ -0,0 +1,21 @@
/*
* 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 { indexPatternService } from './kibana_services';
export async function getIndexPatternsFromIds(indexPatternIds) {
const promises = [];
indexPatternIds.forEach((id) => {
const indexPatternPromise = indexPatternService.get(id);
if (indexPatternPromise) {
promises.push(indexPatternPromise);
}
});
return await Promise.all(promises);
}

View file

@ -113,6 +113,8 @@ export const getQuery = ({ map }) => map.mapState.query;
export const getFilters = ({ map }) => map.mapState.filters;
export const getDrawState = ({ map }) => map.mapState.drawState;
export const getRefreshConfig = ({ map }) => {
if (map.mapState.refreshConfig) {
return map.mapState.refreshConfig;

View file

@ -20,9 +20,10 @@ import {
EuiComboBox,
EuiSpacer,
} from '@elastic/eui';
import { ES_GEO_FIELD_TYPE } from '../../../../../common/constants';
function filterGeoField({ type }) {
return ['geo_point'].includes(type);
return [ES_GEO_FIELD_TYPE.GEO_POINT].includes(type);
}
const requestTypeOptions = [
@ -206,7 +207,7 @@ export class CreateSourceEditor extends Component {
placeholder={i18n.translate('xpack.maps.source.esGeoGrid.indexPatternPlaceholder', {
defaultMessage: 'Select index pattern'
})}
fieldTypes={['geo_point']}
fieldTypes={[ES_GEO_FIELD_TYPE.GEO_POINT]}
onNoIndexPatterns={this._onNoIndexPatterns}
/>
</EuiFormRow>

View file

@ -176,9 +176,7 @@ export class ESGeoGridSource extends AbstractESSource {
}
async getGeoJsonWithMeta(layerName, searchFilters) {
const featureCollection = await this.getGeoJsonPoints(layerName, searchFilters);
return {
data: featureCollection,
meta: {

View file

@ -16,11 +16,11 @@ import { NoIndexPatternCallout } from '../../../components/no_index_pattern_call
import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
import { kfetch } from 'ui/kfetch';
import { GIS_API_PATH } from '../../../../../common/constants';
import { ES_GEO_FIELD_TYPE, GIS_API_PATH } from '../../../../../common/constants';
import { DEFAULT_ES_DOC_LIMIT, DEFAULT_FILTER_BY_MAP_BOUNDS } from './constants';
function filterGeoField(field) {
return ['geo_point', 'geo_shape'].includes(field.type);
return [ES_GEO_FIELD_TYPE.GEO_POINT, ES_GEO_FIELD_TYPE.GEO_SHAPE].includes(field.type);
}
const RESET_INDEX_PATTERN_STATE = {
indexPattern: undefined,
@ -252,7 +252,7 @@ export class CreateSourceEditor extends Component {
placeholder={i18n.translate('xpack.maps.source.esSearch.selectIndexPatternPlaceholder', {
defaultMessage: 'Select index pattern'
})}
fieldTypes={['geo_point', 'geo_shape']}
fieldTypes={[ES_GEO_FIELD_TYPE.GEO_POINT, ES_GEO_FIELD_TYPE.GEO_SHAPE]}
onNoIndexPatterns={this._onNoIndexPatterns}
/>
</EuiFormRow>

View file

@ -19,6 +19,7 @@ import { ESAggMetricTooltipProperty } from '../tooltips/es_aggmetric_tooltip_pro
import uuid from 'uuid/v4';
import { copyPersistentState } from '../../../store/util';
import { ES_GEO_FIELD_TYPE } from '../../../../common/constants';
export class AbstractESSource extends AbstractVectorSource {
@ -245,7 +246,7 @@ export class AbstractESSource extends AbstractVectorSource {
const geoField = await this._getGeoField();
// geo_bounds aggregation only supports geo_point
// there is currently no backend support for getting bounding box of geo_shape field
return geoField.type !== 'geo_shape';
return geoField.type !== ES_GEO_FIELD_TYPE.GEO_SHAPE;
} catch (error) {
return false;
}

View file

@ -16,10 +16,6 @@ export class AbstractSource {
throw new Error('Must implement Source.createDescriptor');
}
static renderDropdownDisplayOption() {
throw new Error('Must implement Source.renderDropdownDisplayOption');
}
constructor(descriptor, inspectorAdapters) {
this._descriptor = descriptor;
this._inspectorAdapters = inspectorAdapters;

View file

@ -38,6 +38,7 @@ import {
REMOVE_TRACKED_LAYER_STATE,
UPDATE_SOURCE_DATA_REQUEST,
SET_TOOLTIP_STATE,
UPDATE_DRAW_STATE,
SET_SCROLL_ZOOM
} from '../actions/store_actions';
@ -102,17 +103,26 @@ const INITIAL_STATE = {
filters: [],
refreshConfig: null,
refreshTimerLastTriggeredAt: null,
drawState: null
},
selectedLayerId: null,
__transientLayerId: null,
layerList: [],
waitingForMapReadyLayerList: [],
waitingForMapReadyLayerList: []
};
export function map(state = INITIAL_STATE, action) {
switch (action.type) {
case UPDATE_DRAW_STATE:
return {
...state,
mapState: {
...state.mapState,
drawState: action.drawState
}
};
case REMOVE_TRACKED_LAYER_STATE:
return removeTrackedLayerState(state, action.layerId);
case TRACK_CURRENT_LAYER_STATE:

186
yarn.lock
View file

@ -1938,23 +1938,76 @@
dependencies:
core-js "^2.5.7"
"@mapbox/geojson-area@0.2.2":
"@mapbox/extent@0.4.0":
version "0.4.0"
resolved "https://registry.yarnpkg.com/@mapbox/extent/-/extent-0.4.0.tgz#3e591f32e1f0c3981c864239f7b0ac06e610f8a9"
integrity sha1-PlkfMuHww5gchkI597CsBuYQ+Kk=
"@mapbox/geojson-area@0.2.2", "@mapbox/geojson-area@^0.2.1":
version "0.2.2"
resolved "https://registry.yarnpkg.com/@mapbox/geojson-area/-/geojson-area-0.2.2.tgz#18d7814aa36bf23fbbcc379f8e26a22927debf10"
integrity sha1-GNeBSqNr8j+7zDefjiaiKSfevxA=
dependencies:
wgs84 "0.0.0"
"@mapbox/geojson-coords@0.0.0":
version "0.0.0"
resolved "https://registry.yarnpkg.com/@mapbox/geojson-coords/-/geojson-coords-0.0.0.tgz#4847a5b96059666e527a2139e75e35d84fd58f50"
integrity sha1-SEeluWBZZm5SeiE551412E/Vj1A=
dependencies:
"@mapbox/geojson-normalize" "0.0.1"
geojson-flatten "~0.2.1"
"@mapbox/geojson-extent@^0.3.2":
version "0.3.2"
resolved "https://registry.yarnpkg.com/@mapbox/geojson-extent/-/geojson-extent-0.3.2.tgz#a1bdb2015afd0e031c18c3f29f7eb229e4e1950f"
integrity sha1-ob2yAVr9DgMcGMPyn36yKeThlQ8=
dependencies:
"@mapbox/extent" "0.4.0"
"@mapbox/geojson-coords" "0.0.0"
rw "~0.1.4"
traverse "~0.6.6"
"@mapbox/geojson-normalize@0.0.1":
version "0.0.1"
resolved "https://registry.yarnpkg.com/@mapbox/geojson-normalize/-/geojson-normalize-0.0.1.tgz#1da1e6b3a7add3ad29909b30f438f60581b7cd80"
integrity sha1-HaHms6et060pkJsw9Dj2BYG3zYA=
"@mapbox/geojson-types@^1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@mapbox/geojson-types/-/geojson-types-1.0.2.tgz#9aecf642cb00eab1080a57c4f949a65b4a5846d6"
integrity sha512-e9EBqHHv3EORHrSfbR9DqecPNn+AmuAoQxV6aL8Xu30bJMJR1o8PZLZzpk1Wq7/NfCbuhmakHTPYRhoqLsXRnw==
"@mapbox/geojsonhint@^2.0.0":
version "2.2.0"
resolved "https://registry.yarnpkg.com/@mapbox/geojsonhint/-/geojsonhint-2.2.0.tgz#75ca94706e9a56e6debf4e1c78fabdc67978b883"
integrity sha512-8qQYRB+/2z2JsN5s6D0WAnpo69+3V3nvJsSFLwMB1dsaWz1V4oZeuoje9srbYAxxL8PXCwIywfhYa3GxOkBv5Q==
dependencies:
concat-stream "^1.6.1"
jsonlint-lines "1.7.1"
minimist "1.2.0"
vfile "^4.0.0"
vfile-reporter "^5.1.1"
"@mapbox/jsonlint-lines-primitives@^2.0.2":
version "2.0.2"
resolved "https://registry.yarnpkg.com/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz#ce56e539f83552b58d10d672ea4d6fc9adc7b234"
integrity sha1-zlblOfg1UrWNENZy6k1vya3HsjQ=
"@mapbox/mapbox-gl-draw@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@mapbox/mapbox-gl-draw/-/mapbox-gl-draw-1.1.1.tgz#b88a7919c8de04eb7946885e747e22049c3a3138"
integrity sha512-Xg+R0VUXKdXC7MaSSMiWfz96eLssJZa28/D6MxK/Xc19G5HvU6w/wytm8EeI28T7Sa2C7FII/0/XOwuAfJgDJw==
dependencies:
"@mapbox/geojson-area" "^0.2.1"
"@mapbox/geojson-extent" "^0.3.2"
"@mapbox/geojson-normalize" "0.0.1"
"@mapbox/geojsonhint" "^2.0.0"
"@mapbox/point-geometry" "0.1.0"
hat "0.0.3"
lodash.isequal "^4.2.0"
xtend "^4.0.1"
"@mapbox/mapbox-gl-supported@^1.4.0":
version "1.4.0"
resolved "https://registry.yarnpkg.com/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-1.4.0.tgz#36946b22944fe2cfa43cfafd5ef36fdb54a069e4"
@ -3739,7 +3792,7 @@
resolved "https://registry.yarnpkg.com/@types/type-detect/-/type-detect-4.0.1.tgz#3b0f5ac82ea630090cbf57c57a1bf5a63a29b9b6"
integrity sha512-0+S1S9Iq0oJ9w9IaBC5W/z1WsPNDUIAJG+THGmqR4vUAxUPCzIY+dApTvyGsaBUWjafTDL0Dg8Z9+iRuk3/BQA==
"@types/unist@*", "@types/unist@^2.0.0":
"@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2":
version "2.0.3"
resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e"
integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==
@ -4314,6 +4367,11 @@ JSONStream@1.1.1:
jsonparse "^1.1.0"
through ">=2.2.7 <3"
"JSV@>= 4.0.x":
version "4.0.2"
resolved "https://registry.yarnpkg.com/JSV/-/JSV-4.0.2.tgz#d077f6825571f82132f9dffaed587b4029feff57"
integrity sha1-0Hf2glVx+CEy+d/67Vh7QCn+/1c=
abab@^1.0.3, abab@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e"
@ -4779,6 +4837,11 @@ ansi-styles@^3.1.0, ansi-styles@^3.2.0:
dependencies:
color-convert "^1.9.0"
ansi-styles@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178"
integrity sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=
ansi-wrap@0.1.0, ansi-wrap@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf"
@ -7190,6 +7253,15 @@ chalk@^2.3.0:
escape-string-regexp "^1.0.5"
supports-color "^5.2.0"
chalk@~0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f"
integrity sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=
dependencies:
ansi-styles "~1.0.0"
has-color "~0.1.0"
strip-ansi "~0.1.0"
chalk@~0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.5.1.tgz#663b3a648b68b55d04690d49167aa837858f2174"
@ -8006,7 +8078,7 @@ concat-stream@1.5.1:
readable-stream "~2.0.0"
typedarray "~0.0.5"
concat-stream@1.6.2, concat-stream@^1.4.6, concat-stream@^1.5.0:
concat-stream@1.6.2, concat-stream@^1.4.6, concat-stream@^1.5.0, concat-stream@^1.6.1:
version "1.6.2"
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"
integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==
@ -12235,6 +12307,14 @@ geojson-area@^0.2.1:
dependencies:
wgs84 "0.0.0"
geojson-flatten@~0.2.1:
version "0.2.4"
resolved "https://registry.yarnpkg.com/geojson-flatten/-/geojson-flatten-0.2.4.tgz#8f3396f31a0f5b747e39c9e6a14088f43ba4ecfb"
integrity sha512-LiX6Jmot8adiIdZ/fthbcKKPOfWjTQchX/ggHnwMZ2e4b0I243N1ANUos0LvnzepTEsj0+D4fIJ5bKhBrWnAHA==
dependencies:
get-stdin "^6.0.0"
minimist "1.2.0"
geojson-normalize@0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/geojson-normalize/-/geojson-normalize-0.0.0.tgz#2dbc3678cd1b31b8179e876bda70cd120dde35c0"
@ -13501,6 +13581,11 @@ has-binary2@~1.0.2:
dependencies:
isarray "2.0.1"
has-color@~0.1.0:
version "0.1.7"
resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f"
integrity sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=
has-cors@1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39"
@ -13644,6 +13729,11 @@ hastscript@^5.0.0:
property-information "^5.0.1"
space-separated-tokens "^1.0.0"
hat@0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/hat/-/hat-0.0.3.tgz#bb014a9e64b3788aed8005917413d4ff3d502d8a"
integrity sha1-uwFKnmSzeIrtgAWRdBPU/z1QLYo=
hawk@~3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4"
@ -16205,6 +16295,14 @@ jsonify@~0.0.0:
resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=
jsonlint-lines@1.7.1:
version "1.7.1"
resolved "https://registry.yarnpkg.com/jsonlint-lines/-/jsonlint-lines-1.7.1.tgz#507de680d3fb8c4be1641cc57d6f679f29f178ff"
integrity sha1-UH3mgNP7jEvhZBzFfW9nnynxeP8=
dependencies:
JSV ">= 4.0.x"
nomnom ">= 1.5.x"
jsonparse@^1.1.0:
version "1.3.1"
resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"
@ -17058,7 +17156,7 @@ lodash.isempty@^4.4.0:
resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e"
integrity sha1-b4bL7di+TsmHvpqvM8loTbGzHn4=
lodash.isequal@^4.0.0, lodash.isequal@^4.1.1, lodash.isequal@^4.5.0:
lodash.isequal@^4.0.0, lodash.isequal@^4.1.1, lodash.isequal@^4.2.0, lodash.isequal@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=
@ -17571,6 +17669,11 @@ map-visit@^1.0.0:
dependencies:
object-visit "^1.0.0"
mapbox-gl-draw-rectangle-mode@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/mapbox-gl-draw-rectangle-mode/-/mapbox-gl-draw-rectangle-mode-1.0.4.tgz#42987d68872a5fb5cc5d76d3375ee20cd8bab8f7"
integrity sha512-BdF6nwEK2p8n9LQoMPzBO8LhddW1fe+d5vK8HQIei+4VcRnUbKNsEj7Z15FsJxCHzsc2BQKXbESx5GaE8x0imQ==
mapbox-gl@0.52.0:
version "0.52.0"
resolved "https://registry.yarnpkg.com/mapbox-gl/-/mapbox-gl-0.52.0.tgz#a43b61caa339ae28e43c87ecfbe9ce4032795859"
@ -18772,6 +18875,14 @@ nodemailer@^4.6.4:
resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-4.6.4.tgz#f0d72d0c6a6ec5f4369fa8f4bf5127a31baa2014"
integrity sha512-SD4uuX7NMzZ5f5m1XHDd13J4UC3SmdJk8DsmU1g6Nrs5h3x9LcXr6EBPZIqXRJ3LrF7RdklzGhZRF/TuylTcLg==
"nomnom@>= 1.5.x":
version "1.8.1"
resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.8.1.tgz#2151f722472ba79e50a76fc125bb8c8f2e4dc2a7"
integrity sha1-IVH3Ikcrp55Qp2/BJbuMjy5Nwqc=
dependencies:
chalk "~0.4.0"
underscore "~1.6.0"
"nopt@2 || 3", nopt@3.x, nopt@~3.0.6:
version "3.0.6"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9"
@ -22494,7 +22605,7 @@ repeat-string@^0.2.2:
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-0.2.2.tgz#c7a8d3236068362059a7e4651fc6884e8b1fb4ae"
integrity sha1-x6jTI2BoNiBZp+RlH8aITosftK4=
repeat-string@^1.5.2, repeat-string@^1.5.4, repeat-string@^1.6.1:
repeat-string@^1.5.0, repeat-string@^1.5.2, repeat-string@^1.5.4, repeat-string@^1.6.1:
version "1.6.1"
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc=
@ -22979,6 +23090,11 @@ rw@1, rw@^1.3.3:
resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4"
integrity sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=
rw@~0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/rw/-/rw-0.1.4.tgz#4903cbd80248ae0ede685bf58fd236a7a9b29a3e"
integrity sha1-SQPL2AJIrg7eaFv1j9I2p6mymj4=
rx-lite-aggregates@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be"
@ -24424,6 +24540,11 @@ strip-ansi@^5.2.0:
dependencies:
ansi-regex "^4.1.0"
strip-ansi@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991"
integrity sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=
strip-bom-stream@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz#f87db5ef2613f6968aa545abfe1ec728b6a829ca"
@ -25406,7 +25527,7 @@ tr46@^1.0.0, tr46@^1.0.1:
dependencies:
punycode "^2.1.0"
traverse@0.6.6:
traverse@0.6.6, traverse@~0.6.6:
version "0.6.6"
resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137"
integrity sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=
@ -26152,6 +26273,11 @@ underscore.string@~3.3.4:
sprintf-js "^1.0.3"
util-deprecate "^1.0.2"
underscore@~1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8"
integrity sha1-izixDKze9jM3uLJOT/htRa6lKag=
underscore@~1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.7.0.tgz#6bbaf0877500d36be34ecaa584e0db9fef035209"
@ -26307,6 +26433,13 @@ unist-util-stringify-position@^1.0.0, unist-util-stringify-position@^1.1.1:
resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-1.1.1.tgz#3ccbdc53679eed6ecf3777dd7f5e3229c1b6aa3c"
integrity sha1-PMvcU2ee7W7PN3fdf14yKcG2qjw=
unist-util-stringify-position@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.0.tgz#4c452c0dbcbc509f7bcd366e9a8afd646f9d51ae"
integrity sha512-Uz5negUTrf9zm2ZT2Z9kdOL7Mr7FJLyq3ByqagUi7QZRVK1HnspVazvSqwHt73jj7APHtpuJ4K110Jm8O6/elw==
dependencies:
"@types/unist" "^2.0.2"
unist-util-visit-parents@1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-1.1.2.tgz#f6e3afee8bdbf961c0e6f028ea3c0480028c3d06"
@ -26963,6 +27096,36 @@ vfile-message@^1.0.0:
dependencies:
unist-util-stringify-position "^1.1.1"
vfile-message@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.0.tgz#750bbb86fe545988a67e899b329bbcabb73edef6"
integrity sha512-YS6qg6UpBfIeiO+6XlhPOuJaoLvt1Y9g2cmlwqhBOOU0XRV8j5RLeoz72t6PWLvNXq3EBG1fQ05wNPrUoz0deQ==
dependencies:
"@types/unist" "^2.0.2"
unist-util-stringify-position "^1.1.1"
vfile-reporter@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/vfile-reporter/-/vfile-reporter-5.1.1.tgz#419688c7e9dcaf65ba81bfdb0ad443e9e0248e09"
integrity sha512-A/cfKvfVmeEmAKx1yyOWggCjC/k184Vkl5pVJAw5CEdppHd5FHBVcdyJ1JBSqIdJjJqyhZY4ZD3JycHr/uwmlA==
dependencies:
repeat-string "^1.5.0"
string-width "^2.0.0"
supports-color "^5.4.0"
unist-util-stringify-position "^1.0.0"
vfile-sort "^2.1.2"
vfile-statistics "^1.1.0"
vfile-sort@^2.1.2:
version "2.2.0"
resolved "https://registry.yarnpkg.com/vfile-sort/-/vfile-sort-2.2.0.tgz#383a8727ec4c5daf37c05683684a5eb686366d39"
integrity sha512-RgxLXVWrJBWb2GuP8FsSkqK7HmbjXjnI8qx3nD6NTWhsWaelaKvJuxfh1F1d1lkCPD7imo4zzi8cf6IOMgaTnQ==
vfile-statistics@^1.1.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vfile-statistics/-/vfile-statistics-1.1.2.tgz#c50132627e4669a3afa07c64ff1e7aa7695e8151"
integrity sha512-16wAC9eEGXdsD35LX9m/iXCRIZyX5LIrDgDtAF92rbATSqsBRbC4n05e0Rj5vt3XRpcKu0UJeWnTxWsSyvNZ+w==
vfile@^2.0.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/vfile/-/vfile-2.3.0.tgz#e62d8e72b20e83c324bc6c67278ee272488bf84a"
@ -26983,6 +27146,17 @@ vfile@^3.0.0, vfile@^3.0.1:
unist-util-stringify-position "^1.0.0"
vfile-message "^1.0.0"
vfile@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.0.0.tgz#ebf3b48af9fcde524d5e08d5f75812058a5f78ad"
integrity sha512-WMNeHy5djSl895BqE86D7WqA0Ie5fAIeGCa7V1EqiXyJg5LaGch2SUaZueok5abYQGH6mXEAsZ45jkoILIOlyA==
dependencies:
"@types/unist" "^2.0.2"
is-buffer "^2.0.0"
replace-ext "1.0.0"
unist-util-stringify-position "^2.0.0"
vfile-message "^2.0.0"
vinyl-file@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/vinyl-file/-/vinyl-file-2.0.0.tgz#a7ebf5ffbefda1b7d18d140fcb07b223efb6751a"