Skip to content

Commit

Permalink
typescript map embeddable
Browse files Browse the repository at this point in the history
  • Loading branch information
stacey-gammon committed Mar 25, 2020
1 parent 4f863c6 commit ce18bb1
Show file tree
Hide file tree
Showing 13 changed files with 259 additions and 32 deletions.
44 changes: 44 additions & 0 deletions x-pack/legacy/plugins/maps/public/actions/map_actions.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
*/
/* eslint-disable @typescript-eslint/consistent-type-definitions */

import { Filter, Query } from 'src/plugins/data/public';
import { AnyAction } from 'redux';
import { LAYER_TYPE } from '../../common/constants';
import { DataMeta, MapFilters } from '../../common/data_request_descriptor_types';

Expand All @@ -24,3 +26,45 @@ export function updateSourceProp(
value: unknown,
newLayerType?: LAYER_TYPE
): void;

export interface MapCenter {
lat: string;
lon: string;
zoom: unknown;
}

export function setGotoWithCenter(config: MapCenter): AnyAction;

export function replaceLayerList(layerList: unknown): AnyAction;

export interface QueryGroup {
filters: Filter[];
query?: Query;
timeFilters: unknown;
refresh: unknown;
}

export function setQuery(query: QueryGroup): AnyAction;

export interface RefreshConfig {
isPaused: boolean;
interval: unknown;
}

export function setRefreshConfig(config: RefreshConfig): AnyAction;

export function disableScrollZoom(): AnyAction;

export function disableInteractive(disable: boolean): AnyAction;

export function disableTooltipControl(disable: boolean): AnyAction;

export function hideToolbarOverlay(hide: boolean): AnyAction;

export function hideLayerControl(hide: boolean): AnyAction;

export function hideViewControl(hide: boolean): AnyAction;

export function setHiddenLayers(layer: unknown): AnyAction;

export function addLayerWithoutDataSync(layer: unknown): AnyAction;
13 changes: 13 additions & 0 deletions x-pack/legacy/plugins/maps/public/actions/ui_actions.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* 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 { AnyAction } from 'redux';

export function setOpenTOCDetails(details: unknown): AnyAction;

export function setIsLayerTOCOpen(open: boolean): AnyAction;

export function setReadOnly(readOnly: boolean): AnyAction;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* 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.
*/

export function getInitialLayers(layers?: unknown): unknown[];
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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 from 'react';

export const GisMap: React.FC<{ addFilters: unknown; renderTooltipContent: unknown }>;
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,29 @@ import { Provider } from 'react-redux';
import { render, unmountComponentAtNode } from 'react-dom';
import 'mapbox-gl/dist/mapbox-gl.css';

import { Embeddable } from '../../../../../../src/legacy/core_plugins/embeddable_api/public/np_ready/public';
import { APPLY_FILTER_TRIGGER } from '../../../../../../src/plugins/ui_actions/public';
import { esFilters } from '../../../../../../src/plugins/data/public';

import { I18nContext } from 'ui/i18n';
import { npStart } from 'ui/new_platform';
import { Subscription } from 'rxjs';
import { Unsubscribe } from 'redux';
import {
Embeddable,
IContainer,
EmbeddableInput,
EmbeddableOutput,
} from '../../../../../../src/plugins/embeddable/public';
import { APPLY_FILTER_TRIGGER } from '../../../../../../src/plugins/ui_actions/public';
import {
esFilters,
IIndexPattern,
TimeRange,
Filter,
Query,
RefreshInterval,
} from '../../../../../../src/plugins/data/public';

import { GisMap } from '../connected_components/gis_map';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { createMapStore } from '../../../../../plugins/maps/public/reducers/store';
import { npStart } from 'ui/new_platform';
import { createMapStore, MapStore } from '../../../../../plugins/maps/public/reducers/store';
import {
setGotoWithCenter,
replaceLayerList,
Expand All @@ -32,6 +45,7 @@ import {
hideLayerControl,
hideViewControl,
setHiddenLayers,
MapCenter,
} from '../actions/map_actions';
import { setReadOnly, setIsLayerTOCOpen, setOpenTOCDetails } from '../actions/ui_actions';
import { getIsLayerTOCOpen, getOpenTOCDetails } from '../selectors/ui_selectors';
Expand All @@ -43,10 +57,58 @@ import {
import { getMapCenter, getMapZoom, getHiddenLayerIds } from '../selectors/map_selectors';
import { MAP_SAVED_OBJECT_TYPE } from '../../common/constants';

export class MapEmbeddable extends Embeddable {
interface MapConfig {
editUrl?: string;
indexPatterns: IIndexPattern[];
editable: boolean;
title?: string;
layerList: unknown;
}

export interface MapInput extends EmbeddableInput {
timeRange?: TimeRange;
filters: Filter[];
query?: Query;
refresh: unknown;
refreshConfig: RefreshInterval;
isLayerTOCOpen: boolean;
openTOCDetails: unknown;
disableTooltipControl: boolean;
disableInteractive: boolean;
hideToolbarOverlay: boolean;
hideLayerControl: boolean;
hideViewControl: boolean;
mapCenter: MapCenter;
hiddenLayers: unknown;
hideFilterActions: boolean;
}

export interface MapOutput extends EmbeddableOutput {
indexPatterns: IIndexPattern[];
}

export class MapEmbeddable extends Embeddable<MapInput, MapOutput> {
type = MAP_SAVED_OBJECT_TYPE;

constructor(config, initialInput, parent, renderTooltipContent, eventHandlers) {
private _renderTooltipContent?: unknown;
private _eventHandlers?: unknown;
private _layerList: unknown;
private _store: MapStore;
private _subscription: Subscription;
private _prevTimeRange?: TimeRange;
private _prevQuery?: Query;
private _prevRefreshConfig?: RefreshInterval;
private _prevFilters?: Filter[];
private _domNode?: HTMLElement;
private _unsubscribeFromStore?: Unsubscribe;

constructor(
config: MapConfig,
initialInput: MapInput,
parent?: IContainer,
renderTooltipContent?: unknown,
eventHandlers?: unknown
) {
super(
initialInput,
{
Expand All @@ -70,7 +132,7 @@ export class MapEmbeddable extends Embeddable {
return getInspectorAdapters(this._store.getState());
}

onContainerStateChanged(containerState) {
onContainerStateChanged(containerState: MapInput) {
if (
!_.isEqual(containerState.timeRange, this._prevTimeRange) ||
!_.isEqual(containerState.query, this._prevQuery) ||
Expand All @@ -84,7 +146,12 @@ export class MapEmbeddable extends Embeddable {
}
}

_dispatchSetQuery({ query, timeRange, filters, refresh }) {
_dispatchSetQuery({
query,
timeRange,
filters,
refresh,
}: Pick<MapInput, 'query' | 'timeRange' | 'filters' | 'refresh'>) {
this._prevTimeRange = timeRange;
this._prevQuery = query;
this._prevFilters = filters;
Expand All @@ -98,7 +165,7 @@ export class MapEmbeddable extends Embeddable {
);
}

_dispatchSetRefreshConfig({ refreshConfig }) {
_dispatchSetRefreshConfig({ refreshConfig }: Pick<MapInput, 'refreshConfig'>) {
this._prevRefreshConfig = refreshConfig;
this._store.dispatch(
setRefreshConfig({
Expand All @@ -113,7 +180,7 @@ export class MapEmbeddable extends Embeddable {
* @param {HTMLElement} domNode
* @param {ContainerState} containerState
*/
render(domNode) {
render(domNode: HTMLElement) {
this._store.dispatch(setEventHandlers(this._eventHandlers));
this._store.dispatch(setReadOnly(true));
this._store.dispatch(disableScrollZoom());
Expand All @@ -133,7 +200,6 @@ export class MapEmbeddable extends Embeddable {
if (_.has(this.input, 'disableTooltipControl') && this.input.disableTooltipControl) {
this._store.dispatch(disableTooltipControl(this.input.disableTooltipControl));
}

if (_.has(this.input, 'hideToolbarOverlay') && this.input.hideToolbarOverlay) {
this._store.dispatch(hideToolbarOverlay(this.input.hideToolbarOverlay));
}
Expand Down Expand Up @@ -182,12 +248,12 @@ export class MapEmbeddable extends Embeddable {
});
}

async setLayerList(layerList) {
async setLayerList(layerList: unknown) {
this._layerList = layerList;
return await this._store.dispatch(replaceLayerList(this._layerList));
}

addFilters = filters => {
addFilters = (filters: Filter[]) => {
npStart.plugins.uiActions.executeTriggerActions(APPLY_FILTER_TRIGGER, {
embeddable: this,
filters,
Expand All @@ -213,7 +279,7 @@ export class MapEmbeddable extends Embeddable {
this._dispatchSetQuery({
query: this._prevQuery,
timeRange: this._prevTimeRange,
filters: this._prevFilters,
filters: this._prevFilters ?? [],
refresh: true,
});
}
Expand All @@ -233,7 +299,7 @@ export class MapEmbeddable extends Embeddable {
mapCenter: {
lat: center.lat,
lon: center.lon,
zoom: zoom,
zoom,
},
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@ import _ from 'lodash';
import chrome from 'ui/chrome';
import { capabilities } from 'ui/capabilities';
import { i18n } from '@kbn/i18n';
import { npSetup, npStart } from 'ui/new_platform';
import { SavedObjectLoader } from 'src/plugins/saved_objects/public';
import { IIndexPattern } from 'src/plugins/data/public';
import {
EmbeddableFactory,
ErrorEmbeddable,
IContainer,
} from '../../../../../../src/legacy/core_plugins/embeddable_api/public/np_ready/public';
import { setup } from '../../../../../../src/legacy/core_plugins/embeddable_api/public/np_ready/public/legacy';
import { MapEmbeddable } from './map_embeddable';
import { MapEmbeddable, MapInput } from './map_embeddable';
import { getIndexPatternService } from '../kibana_services';

import { createMapPath, MAP_SAVED_OBJECT_TYPE, APP_ICON } from '../../common/constants';
Expand All @@ -25,7 +29,6 @@ import { getInitialLayers } from '../angular/get_initial_layers';
import { mergeInputWithSavedMap } from './merge_input_with_saved_map';
import '../angular/services/gis_map_saved_object_loader';
import { bindSetupCoreAndPlugins, bindStartCoreAndPlugins } from '../plugin';
import { npSetup, npStart } from 'ui/new_platform';

export class MapEmbeddableFactory extends EmbeddableFactory {
type = MAP_SAVED_OBJECT_TYPE;
Expand All @@ -44,8 +47,9 @@ export class MapEmbeddableFactory extends EmbeddableFactory {
bindSetupCoreAndPlugins(npSetup.core, npSetup.plugins);
bindStartCoreAndPlugins(npStart.core, npStart.plugins);
}
isEditable() {
return capabilities.get().maps.save;

async isEditable() {
return capabilities.get().maps.save as boolean;
}

// Not supported yet for maps types.
Expand All @@ -59,12 +63,12 @@ export class MapEmbeddableFactory extends EmbeddableFactory {
});
}

async _getIndexPatterns(layerList) {
async _getIndexPatterns(layerList: unknown[]): Promise<IIndexPattern[]> {
// Need to extract layerList from store to get queryable index pattern ids
const store = createMapStore();
let queryableIndexPatternIds;
try {
layerList.forEach(layerDescriptor => {
layerList.forEach((layerDescriptor: unknown) => {
store.dispatch(addLayerWithoutDataSync(layerDescriptor));
});
queryableIndexPatternIds = getQueryableUniqueIndexPatternIds(store.getState());
Expand All @@ -86,16 +90,16 @@ export class MapEmbeddableFactory extends EmbeddableFactory {
}
});
const indexPatterns = await Promise.all(promises);
return _.compact(indexPatterns);
return _.compact(indexPatterns) as IIndexPattern[];
}

async _fetchSavedMap(savedObjectId) {
async _fetchSavedMap(savedObjectId: string) {
const $injector = await chrome.dangerouslyGetActiveInjector();
const savedObjectLoader = $injector.get('gisMapSavedObjectLoader');
const savedObjectLoader = $injector.get<SavedObjectLoader>('gisMapSavedObjectLoader');
return await savedObjectLoader.get(savedObjectId);
}

async createFromSavedObject(savedObjectId, input, parent) {
async createFromSavedObject(savedObjectId: string, input: MapInput, parent?: IContainer) {
const savedMap = await this._fetchSavedMap(savedObjectId);
const layerList = getInitialLayers(savedMap.layerListJSON);
const indexPatterns = await this._getIndexPatterns(layerList);
Expand All @@ -106,7 +110,7 @@ export class MapEmbeddableFactory extends EmbeddableFactory {
title: savedMap.title,
editUrl: chrome.addBasePath(createMapPath(savedObjectId)),
indexPatterns,
editable: this.isEditable(),
editable: await this.isEditable(),
},
input,
parent
Expand All @@ -125,15 +129,20 @@ export class MapEmbeddableFactory extends EmbeddableFactory {
return embeddable;
}

async createFromState(state, input, parent, renderTooltipContent, eventHandlers) {
async createFromState(
state: { title?: string; layerList?: unknown[] },
input: MapInput,
parent: IContainer,
renderTooltipContent: unknown,
eventHandlers: unknown
) {
const layerList = state && state.layerList ? state.layerList : getInitialLayers();
const indexPatterns = await this._getIndexPatterns(layerList);

return new MapEmbeddable(
{
layerList,
title: state && state.title ? state.title : '',
editUrl: null,
indexPatterns,
editable: false,
},
Expand All @@ -144,7 +153,7 @@ export class MapEmbeddableFactory extends EmbeddableFactory {
);
}

async create(input) {
async create(input: MapInput) {
window.location.href = chrome.addBasePath(createMapPath(''));
return new ErrorEmbeddable(
'Maps can only be created with createFromSavedObject or createFromState',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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 { MapInput } from './map_embeddable';

export function mergeInputWithSavedMap(input: MapInput, savedmap: unknown): Partial<MapInput>;
Loading

0 comments on commit ce18bb1

Please sign in to comment.