[maps] clean up isLayerGroup and isVectorGroup type guards (#174402)

PR updates type guards to include return type narrowing to avoid needing
to cast results

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Nathan Reese 2024-01-09 09:19:14 -07:00 committed by GitHub
parent 5d9b7e7554
commit 537614c36e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 172 additions and 77 deletions

View file

@ -45,7 +45,7 @@ import {
} from './map_action_constants';
import { InnerJoin } from '../classes/joins/inner_join';
import { ILayer } from '../classes/layers/layer';
import { IVectorLayer } from '../classes/layers/vector_layer';
import { hasVectorLayerMethod } from '../classes/layers/vector_layer';
import { DataRequestMeta, MapExtent, DataFilters } from '../../common/descriptor_types';
import { DataRequestAbortError } from '../classes/util/data_request';
import { scaleBounds } from '../../common/elasticsearch_util';
@ -175,7 +175,7 @@ function syncDataForAllJoinLayers() {
) => {
const syncPromises = getLayerList(getState())
.filter((layer) => {
return 'hasJoins' in layer ? (layer as IVectorLayer).hasJoins() : false;
return hasVectorLayerMethod(layer, 'hasJoins') ? layer.hasJoins() : false;
})
.map((layer) => {
return dispatch(syncDataForLayer(layer, false));
@ -438,11 +438,11 @@ function setGotoWithBounds(bounds: MapExtent) {
function setJoinError(layerId: string, joinIndex: number, error?: string) {
return (dispatch: Dispatch, getState: () => MapStoreState) => {
const layer = getLayerById(layerId, getState());
if (!layer || !('getJoins' in layer)) {
if (!layer || !hasVectorLayerMethod(layer, 'getJoins')) {
return;
}
const joins = (layer as IVectorLayer).getJoins().map((join: InnerJoin) => {
const joins = layer.getJoins().map((join: InnerJoin) => {
return join.toDescriptor();
});

View file

@ -61,7 +61,7 @@ import {
VectorStyleDescriptor,
} from '../../common/descriptor_types';
import { ILayer } from '../classes/layers/layer';
import { IVectorLayer } from '../classes/layers/vector_layer';
import { hasVectorLayerMethod } from '../classes/layers/vector_layer';
import { OnSourceChangeArgs } from '../classes/sources/source';
import {
DRAW_MODE,
@ -265,7 +265,7 @@ export function setLayerVisibility(layerId: string, makeVisible: boolean) {
}
if (isLayerGroup(layer)) {
(layer as LayerGroup).getChildren().forEach((childLayer) => {
layer.getChildren().forEach((childLayer) => {
dispatch(setLayerVisibility(childLayer.getId(), makeVisible));
});
}
@ -401,7 +401,8 @@ function updateMetricsProp(layerId: string, value: unknown) {
getState: () => MapStoreState
) => {
const layer = getLayerById(layerId, getState());
const previousFields = await (layer as IVectorLayer).getFields();
const previousFields =
layer && hasVectorLayerMethod(layer, 'getFields') ? await layer.getFields() : [];
dispatch({
type: UPDATE_SOURCE_PROP,
layerId,
@ -694,7 +695,7 @@ function removeLayerFromLayerList(layerId: string) {
}
if (isLayerGroup(layerGettingRemoved)) {
(layerGettingRemoved as LayerGroup).getChildren().forEach((childLayer) => {
layerGettingRemoved.getChildren().forEach((childLayer) => {
dispatch(removeLayerFromLayerList(childLayer.getId()));
});
}
@ -716,11 +717,11 @@ function updateStyleProperties(layerId: string, previousFields?: IField[]) {
return;
}
if (!('getFields' in targetLayer)) {
if (!hasVectorLayerMethod(targetLayer, 'getFields')) {
return;
}
const nextFields = await (targetLayer as IVectorLayer).getFields(); // take into account all fields, since labels can be driven by any field (source or join)
const nextFields = await targetLayer.getFields(); // take into account all fields, since labels can be driven by any field (source or join)
const { hasChanges, nextStyleDescriptor } = await (
style as IVectorStyle
).getDescriptorWithUpdatedStyleProps(nextFields, getMapColors(getState()), previousFields);
@ -769,7 +770,7 @@ export function updateLayerStyleForSelectedLayer(styleDescriptor: StyleDescripto
export function setJoinsForLayer(layer: ILayer, joins: Array<Partial<JoinDescriptor>>) {
return async (dispatch: ThunkDispatch<MapStoreState, void, AnyAction>) => {
const previousFields = await (layer as IVectorLayer).getFields();
const previousFields = hasVectorLayerMethod(layer, 'getFields') ? await layer.getFields() : [];
dispatch({
type: SET_JOINS,
layerId: layer.getId(),
@ -864,8 +865,8 @@ function clearInspectorAdapters(layer: ILayer, adapters: Adapters) {
});
}
if (adapters.requests && 'getValidJoins' in layer) {
(layer as IVectorLayer).getValidJoins().forEach((join) => {
if (adapters.requests && hasVectorLayerMethod(layer, 'getValidJoins')) {
layer.getValidJoins().forEach((join) => {
adapters.requests!.resetRequest(join.getRightJoinSource().getId());
});
}
@ -916,7 +917,7 @@ export function ungroupLayer(layerId: string) {
return;
}
(layer as LayerGroup).getChildren().forEach((childLayer) => {
layer.getChildren().forEach((childLayer) => {
dispatch(setLayerParent(childLayer.getId(), layer.getParent()));
});
};
@ -950,7 +951,7 @@ export function moveLayerToLeftOfTarget(moveLayerId: string, targetLayerId: stri
dispatch(updateLayerOrder(newOrder));
if (isLayerGroup(moveLayer)) {
(moveLayer as LayerGroup).getChildren().forEach((childLayer) => {
moveLayer.getChildren().forEach((childLayer) => {
dispatch(moveLayerToLeftOfTarget(childLayer.getId(), targetLayerId));
});
}

View file

@ -73,7 +73,7 @@ import {
Timeslice,
} from '../../common/descriptor_types';
import { INITIAL_LOCATION } from '../../common/constants';
import { isVectorLayer, IVectorLayer } from '../classes/layers/vector_layer';
import { hasVectorLayerMethod } from '../classes/layers/vector_layer';
import { SET_DRAW_MODE, pushDeletedFeatureId, clearDeletedFeatureIds } from './ui_actions';
import { expandToTileBoundaries, getTilesForExtent } from '../classes/util/geo_tile_utils';
import { getToasts } from '../kibana_services';
@ -439,14 +439,14 @@ export function addNewFeatureToIndex(geometries: Array<Geometry | Position[]>) {
return;
}
const layer = getLayerById(layerId, getState());
if (!layer || !isVectorLayer(layer)) {
if (!layer || !hasVectorLayerMethod(layer, 'addFeature')) {
return;
}
try {
dispatch(updateEditShape(DRAW_SHAPE.WAIT));
await asyncForEach(geometries, async (geometry) => {
await (layer as IVectorLayer).addFeature(geometry);
await layer.addFeature(geometry);
});
await dispatch(syncDataForLayerDueToDrawing(layer));
} catch (e) {
@ -477,13 +477,13 @@ export function deleteFeatureFromIndex(featureId: string) {
return;
}
const layer = getLayerById(layerId, getState());
if (!layer || !isVectorLayer(layer)) {
if (!layer || !hasVectorLayerMethod(layer, 'deleteFeature')) {
return;
}
try {
dispatch(updateEditShape(DRAW_SHAPE.WAIT));
await (layer as IVectorLayer).deleteFeature(featureId);
await layer.deleteFeature(featureId);
dispatch(pushDeletedFeatureId(featureId));
await dispatch(syncDataForLayerDueToDrawing(layer));
} catch (e) {

View file

@ -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
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import type { IVectorLayer } from '../vector_layer';
// mock IVectorLayer that passes isVectorLayer type guard
export const mockVectorLayer = {
addFeature: () => {},
canShowTooltip: () => {},
deleteFeature: () => {},
getFields: () => {},
getJoins: () => {},
getLeftJoinFields: () => {},
getMbTooltipLayerIds: () => {},
getValidJoins: () => {},
hasJoins: () => {},
supportsFeatureEditing: () => {},
} as unknown as IVectorLayer;

View file

@ -32,7 +32,7 @@ import { ILayer, LayerIcon, LayerMessage } from '../layer';
import { IStyle } from '../../styles/style';
import { LICENSED_FEATURES } from '../../../licensed_features';
export function isLayerGroup(layer: ILayer) {
export function isLayerGroup(layer: ILayer): layer is LayerGroup {
return layer instanceof LayerGroup;
}

View file

@ -7,7 +7,11 @@
export { syncBoundsData } from './bounds_data';
export type { IVectorLayer, VectorLayerArguments } from './vector_layer';
export { isVectorLayer, NO_RESULTS_ICON_AND_TOOLTIPCONTENT } from './vector_layer';
export {
isVectorLayer,
hasVectorLayerMethod,
NO_RESULTS_ICON_AND_TOOLTIPCONTENT,
} from './vector_layer';
export { BlendedVectorLayer } from './blended_vector_layer';
export { GeoJsonVectorLayer } from './geojson_vector_layer';

View file

@ -25,7 +25,9 @@ import {
import { ESTermSourceDescriptor, VectorStyleDescriptor } from '../../../../common/descriptor_types';
import { getDefaultDynamicProperties } from '../../styles/vector/vector_style_defaults';
import { IVectorSource } from '../../sources/vector_source';
import { AbstractVectorLayer } from './vector_layer';
import { mockVectorLayer } from '../__fixtures__/mock_vector_layer';
import { AbstractVectorLayer, isVectorLayer, hasVectorLayerMethod } from './vector_layer';
import type { ILayer } from '../layer';
class MockSource {
cloneDescriptor() {
@ -37,6 +39,30 @@ class MockSource {
}
}
describe('isVectorLayer', () => {
test('Should return true when Layer instance implements IVectorLayer interface', async () => {
expect(isVectorLayer(mockVectorLayer)).toBe(true);
});
test('Should return false when Layer instance does not implement IVectorLayer interface', async () => {
expect(isVectorLayer({} as unknown as ILayer)).toBe(false);
});
});
describe('hasVectorLayerMethod', () => {
test('Should return true when Layer instance implements specific method', async () => {
const mockLayer = {
getJoins: () => {},
} as unknown as ILayer;
expect(hasVectorLayerMethod(mockLayer, 'getJoins')).toBe(true);
});
test('Should return false when Layer instance does not implement specific method', async () => {
const mockLayer = {} as unknown as ILayer;
expect(hasVectorLayerMethod(mockLayer, 'getJoins')).toBe(false);
});
});
describe('cloneDescriptor', () => {
describe('with joins', () => {
const styleDescriptor = {

View file

@ -72,8 +72,26 @@ import { Mask } from './mask';
const SUPPORTS_FEATURE_EDITING_REQUEST_ID = 'SUPPORTS_FEATURE_EDITING_REQUEST_ID';
export function isVectorLayer(layer: ILayer) {
return (layer as IVectorLayer).canShowTooltip !== undefined;
export function isVectorLayer(layer: ILayer): layer is IVectorLayer {
return (
typeof (layer as IVectorLayer).addFeature === 'function' &&
typeof (layer as IVectorLayer).canShowTooltip === 'function' &&
typeof (layer as IVectorLayer).deleteFeature === 'function' &&
typeof (layer as IVectorLayer).getFields === 'function' &&
typeof (layer as IVectorLayer).getJoins === 'function' &&
typeof (layer as IVectorLayer).getLeftJoinFields === 'function' &&
typeof (layer as IVectorLayer).getMbTooltipLayerIds === 'function' &&
typeof (layer as IVectorLayer).getValidJoins === 'function' &&
typeof (layer as IVectorLayer).hasJoins === 'function' &&
typeof (layer as IVectorLayer).supportsFeatureEditing === 'function'
);
}
export function hasVectorLayerMethod(
layer: ILayer,
methodName: keyof IVectorLayer
): layer is Pick<IVectorLayer, typeof methodName> {
return typeof (layer as IVectorLayer)[methodName] === 'function';
}
export interface VectorLayerArguments {

View file

@ -37,6 +37,13 @@ import {
import { DataRequest } from '../../util/data_request';
import { FeatureGeometryFilterForm } from '../../../connected_components/mb_map/tooltip_control/features_tooltip';
export function hasVectorSourceMethod(
source: ISource,
methodName: keyof IVectorSource
): source is Pick<IVectorSource, typeof methodName> {
return typeof (source as IVectorSource)[methodName] === 'function';
}
export interface SourceStatus {
tooltipContent: string | null;
areResultsTrimmed: boolean;

View file

@ -23,7 +23,7 @@ export function RemoveLayerConfirmModal(props: Props) {
layerGroup.getChildren().forEach((childLayer) => {
count++;
if (isLayerGroup(childLayer)) {
count = count + getChildrenCount(childLayer as LayerGroup);
count = count + getChildrenCount(childLayer);
}
});
return count;
@ -34,7 +34,7 @@ export function RemoveLayerConfirmModal(props: Props) {
return null;
}
const numChildren = getChildrenCount(props.layer as LayerGroup);
const numChildren = getChildrenCount(props.layer);
return numChildren > 0 ? (
<p>
{i18n.translate('xpack.maps.deleteLayerConfirmModal.multiLayerWarning', {

View file

@ -66,18 +66,26 @@ exports[`EditLayerPanel is rendered 1`] = `
<LayerSettings
layer={
Object {
"addFeature": [Function],
"canShowTooltip": [Function],
"deleteFeature": [Function],
"getDescriptor": [Function],
"getDisplayName": [Function],
"getFields": [Function],
"getId": [Function],
"getJoins": [Function],
"getLayerTypeIconName": [Function],
"getLeftJoinFields": [Function],
"getMbTooltipLayerIds": [Function],
"getSource": [Function],
"getStyleForEditing": [Function],
"getType": [Function],
"getValidJoins": [Function],
"hasErrors": [Function],
"hasJoins": [Function],
"renderSourceSettingsEditor": [Function],
"supportsElasticsearchFilters": [Function],
"supportsFeatureEditing": [Function],
"supportsFitToBounds": [Function],
}
}
@ -90,18 +98,26 @@ exports[`EditLayerPanel is rendered 1`] = `
<JoinEditor
layer={
Object {
"addFeature": [Function],
"canShowTooltip": [Function],
"deleteFeature": [Function],
"getDescriptor": [Function],
"getDisplayName": [Function],
"getFields": [Function],
"getId": [Function],
"getJoins": [Function],
"getLayerTypeIconName": [Function],
"getLeftJoinFields": [Function],
"getMbTooltipLayerIds": [Function],
"getSource": [Function],
"getStyleForEditing": [Function],
"getType": [Function],
"getValidJoins": [Function],
"hasErrors": [Function],
"hasJoins": [Function],
"renderSourceSettingsEditor": [Function],
"supportsElasticsearchFilters": [Function],
"supportsFeatureEditing": [Function],
"supportsFitToBounds": [Function],
}
}

View file

@ -57,9 +57,11 @@ import React from 'react';
import { shallow } from 'enzyme';
import { LAYER_TYPE } from '../../../common/constants';
import { ILayer } from '../../classes/layers/layer';
import { mockVectorLayer } from '../../classes/layers/__fixtures__/mock_vector_layer';
import { EditLayerPanel } from './edit_layer_panel';
const mockLayer = {
...mockVectorLayer,
getId: () => {
return '1';
},

View file

@ -27,7 +27,7 @@ import { StyleSettings } from './style_settings';
import { StyleDescriptor, VectorLayerDescriptor } from '../../../common/descriptor_types';
import { getData, getCore } from '../../kibana_services';
import { ILayer } from '../../classes/layers/layer';
import { isVectorLayer, IVectorLayer } from '../../classes/layers/vector_layer';
import { isVectorLayer } from '../../classes/layers/vector_layer';
import { OnSourceChangeArgs } from '../../classes/sources/source';
import { IField } from '../../classes/fields/field';
import { isLayerGroup } from '../../classes/layers/layer_group';
@ -94,16 +94,16 @@ export class EditLayerPanel extends Component<Props, State> {
return;
}
const vectorLayer = this.props.selectedLayer as IVectorLayer;
if (!vectorLayer.getSource().supportsJoins() || vectorLayer.getLeftJoinFields === undefined) {
if (
!this.props.selectedLayer.getSource().supportsJoins() ||
this.props.selectedLayer.getLeftJoinFields === undefined
) {
return;
}
let leftJoinFields: JoinField[] = [];
try {
const leftFieldsInstances = await (
this.props.selectedLayer as IVectorLayer
).getLeftJoinFields();
const leftFieldsInstances = await this.props.selectedLayer.getLeftJoinFields();
const leftFieldPromises = leftFieldsInstances.map(async (field: IField) => {
return {
name: field.getName(),
@ -146,8 +146,7 @@ export class EditLayerPanel extends Component<Props, State> {
if (!this.props.selectedLayer || !isVectorLayer(this.props.selectedLayer)) {
return;
}
const vectorLayer = this.props.selectedLayer as IVectorLayer;
if (!vectorLayer.getSource().supportsJoins()) {
if (!this.props.selectedLayer.getSource().supportsJoins()) {
return null;
}
@ -155,7 +154,7 @@ export class EditLayerPanel extends Component<Props, State> {
<Fragment>
<EuiPanel>
<JoinEditor
layer={vectorLayer}
layer={this.props.selectedLayer}
leftJoinFields={this.state.leftJoinFields}
layerDisplayName={this.state.displayName}
/>

View file

@ -13,16 +13,19 @@ import { EditLayerPanel } from './edit_layer_panel';
import { getSelectedLayer } from '../../selectors/map_selectors';
import { updateLayerStyleForSelectedLayer, updateSourceProps } from '../../actions';
import { MapStoreState } from '../../reducers/store';
import { isVectorLayer, IVectorLayer } from '../../classes/layers/vector_layer';
import { OnSourceChangeArgs } from '../../classes/sources/source';
import type { OnSourceChangeArgs } from '../../classes/sources/source';
import { hasVectorSourceMethod } from '../../classes/sources/vector_source';
import { isLayerGroup } from '../../classes/layers/layer_group';
function mapStateToProps(state: MapStoreState) {
const selectedLayer = getSelectedLayer(state);
let key = 'none';
if (selectedLayer) {
key = isVectorLayer(selectedLayer)
? `${selectedLayer.getId()}${(selectedLayer as IVectorLayer).getSource().supportsJoins()}`
: selectedLayer.getId();
const source = !isLayerGroup(selectedLayer) && selectedLayer.getSource();
key =
source && hasVectorSourceMethod(source, 'supportsJoins')
? `${selectedLayer.getId()}${source.supportsJoins()}`
: selectedLayer.getId();
}
return {
key,

View file

@ -26,7 +26,7 @@ import { Attribution } from '../../../../common/descriptor_types';
import { AUTOSELECT_EMS_LOCALE, NO_EMS_LOCALE, MAX_ZOOM } from '../../../../common/constants';
import { AlphaSlider } from '../../../components/alpha_slider';
import { ILayer } from '../../../classes/layers/layer';
import { isVectorLayer, IVectorLayer } from '../../../classes/layers/vector_layer';
import { isVectorLayer } from '../../../classes/layers/vector_layer';
import { AttributionFormRow } from './attribution_form_row';
import { isLayerGroup } from '../../../classes/layers/layer_group';
@ -172,24 +172,19 @@ export function LayerSettings(props: Props) {
};
const renderDisableTooltips = () => {
if (!isVectorLayer(props.layer)) {
return null;
} else {
const layer = props.layer as unknown as IVectorLayer;
return (
<EuiFormRow display="columnCompressedSwitch">
<EuiSwitch
label={i18n.translate('xpack.maps.layerPanel.settingsPanel.DisableTooltips', {
defaultMessage: `Show tooltips`,
})}
disabled={!layer.canShowTooltip()}
checked={!layer.areTooltipsDisabled()}
onChange={onShowTooltipsChange}
compressed
/>
</EuiFormRow>
);
}
return !isVectorLayer(props.layer) ? null : (
<EuiFormRow display="columnCompressedSwitch">
<EuiSwitch
label={i18n.translate('xpack.maps.layerPanel.settingsPanel.DisableTooltips', {
defaultMessage: `Show tooltips`,
})}
disabled={!props.layer.canShowTooltip()}
checked={!props.layer.areTooltipsDisabled()}
onChange={onShowTooltipsChange}
compressed
/>
</EuiFormRow>
);
};
const renderShowLocaleSelector = () => {

View file

@ -18,6 +18,7 @@ import { Feature } from 'geojson';
import type { Map as MbMap, MapMouseEvent, MapGeoJSONFeature } from '@kbn/mapbox-gl';
import { TooltipControl } from './tooltip_control';
import { IVectorLayer } from '../../../classes/layers/vector_layer';
import { mockVectorLayer } from '../../../classes/layers/__fixtures__/mock_vector_layer';
import { IVectorSource } from '../../../classes/sources/vector_source';
// mutable map state
@ -26,6 +27,7 @@ let featuresAtLocation: MapGeoJSONFeature[] = [];
const layerId = 'tfi3f';
const mbLayerId = 'tfi3f_circle';
const mockLayer = {
...mockVectorLayer,
getMbLayerIds: () => {
return [mbLayerId];
},

View file

@ -322,7 +322,7 @@ export class TooltipControl extends Component<Props, {}> {
(accumulator: string[], layer: ILayer) => {
// tooltips are only supported for vector layers, filter out all other layer types
return layer.isVisible() && isVectorLayer(layer)
? accumulator.concat((layer as IVectorLayer).getMbTooltipLayerIds())
? accumulator.concat(layer.getMbTooltipLayerIds())
: accumulator;
},
[]

View file

@ -18,10 +18,10 @@ import {
getVisibilityToggleLabel,
} from '../action_labels';
import { ESSearchSource } from '../../../../../../classes/sources/es_search_source';
import { isVectorLayer, IVectorLayer } from '../../../../../../classes/layers/vector_layer';
import { hasVectorLayerMethod } from '../../../../../../classes/layers/vector_layer';
import { SCALING_TYPES, VECTOR_SHAPE_TYPE } from '../../../../../../../common/constants';
import { RemoveLayerConfirmModal } from '../../../../../../components/remove_layer_confirm_modal';
import { isLayerGroup, LayerGroup } from '../../../../../../classes/layers/layer_group';
import { isLayerGroup } from '../../../../../../classes/layers/layer_group';
export interface Props {
cloneLayer: (layerId: string) => void;
@ -71,10 +71,10 @@ export class TOCEntryActionsPopover extends Component<Props, State> {
}
async _loadFeatureEditing() {
if (!isVectorLayer(this.props.layer)) {
if (!hasVectorLayerMethod(this.props.layer, 'supportsFeatureEditing')) {
return;
}
const supportsFeatureEditing = (this.props.layer as IVectorLayer).supportsFeatureEditing();
const supportsFeatureEditing = this.props.layer.supportsFeatureEditing();
const isFeatureEditingEnabled = await this._getIsFeatureEditingEnabled();
if (
!this._isMounted ||
@ -87,7 +87,10 @@ export class TOCEntryActionsPopover extends Component<Props, State> {
}
async _getIsFeatureEditingEnabled(): Promise<boolean> {
const vectorLayer = this.props.layer as IVectorLayer;
if (!hasVectorLayerMethod(this.props.layer, 'hasJoins')) {
return false;
}
const source = this.props.layer.getSource();
if (!(source instanceof ESSearchSource)) {
return false;
@ -95,9 +98,9 @@ export class TOCEntryActionsPopover extends Component<Props, State> {
if (
(source as ESSearchSource).getSyncMeta().scalingType === SCALING_TYPES.CLUSTERS ||
vectorLayer.isPreviewLayer() ||
!vectorLayer.isVisible() ||
vectorLayer.hasJoins()
this.props.layer.isPreviewLayer() ||
!this.props.layer.isVisible() ||
this.props.layer.hasJoins()
) {
return false;
}
@ -211,10 +214,7 @@ export class TOCEntryActionsPopover extends Component<Props, State> {
this.props.cloneLayer(this.props.layer.getId());
},
});
if (
isLayerGroup(this.props.layer) &&
(this.props.layer as LayerGroup).getChildren().length > 0
) {
if (isLayerGroup(this.props.layer) && this.props.layer.getChildren().length > 0) {
actionItems.push({
name: i18n.translate('xpack.maps.layerTocActions.ungroupLayerTitle', {
defaultMessage: 'Ungroup layers',

View file

@ -15,8 +15,8 @@ import type { TimeRange } from '@kbn/es-query';
import { RasterTileLayer } from '../classes/layers/raster_tile_layer/raster_tile_layer';
import { EmsVectorTileLayer } from '../classes/layers/ems_vector_tile_layer/ems_vector_tile_layer';
import {
hasVectorLayerMethod,
BlendedVectorLayer,
IVectorLayer,
MvtVectorLayer,
GeoJsonVectorLayer,
} from '../classes/layers/vector_layer';
@ -351,7 +351,7 @@ export const getLayerList = createSelector(
if (!parentLayer || !isLayerGroup(parentLayer)) {
return;
}
(parentLayer as LayerGroup).setChildren(children);
parentLayer.setChildren(children);
});
return layers;
@ -402,11 +402,11 @@ export const getMapColors = createSelector(getLayerListRaw, (layerList) =>
);
export const getSelectedLayerJoinDescriptors = createSelector(getSelectedLayer, (selectedLayer) => {
if (!selectedLayer || !('getJoins' in selectedLayer)) {
if (!selectedLayer || !hasVectorLayerMethod(selectedLayer, 'getJoins')) {
return [];
}
return (selectedLayer as IVectorLayer).getJoins().map((join: InnerJoin) => {
return selectedLayer.getJoins().map((join: InnerJoin) => {
return join.toDescriptor();
});
});