diff --git a/x-pack/legacy/plugins/maps/public/angular/map_controller.js b/x-pack/legacy/plugins/maps/public/angular/map_controller.js index 91b54d2698c1d5..70d5195feef423 100644 --- a/x-pack/legacy/plugins/maps/public/angular/map_controller.js +++ b/x-pack/legacy/plugins/maps/public/angular/map_controller.js @@ -38,7 +38,6 @@ import { setGotoWithCenter, replaceLayerList, setQuery, - clearTransientLayerStateAndCloseFlyout, setMapSettings, enableFullScreen, updateFlyout, @@ -535,7 +534,6 @@ app.controller( addHelpMenuToAppChrome(); async function doSave(saveOptions) { - await store.dispatch(clearTransientLayerStateAndCloseFlyout()); savedMap.syncWithStore(store.getState()); let id; diff --git a/x-pack/plugins/maps/common/descriptor_types/descriptor_types.d.ts b/x-pack/plugins/maps/common/descriptor_types/descriptor_types.d.ts index 4bdafcabaad06f..b412375874f686 100644 --- a/x-pack/plugins/maps/common/descriptor_types/descriptor_types.d.ts +++ b/x-pack/plugins/maps/common/descriptor_types/descriptor_types.d.ts @@ -132,6 +132,7 @@ export type SourceDescriptor = export type LayerDescriptor = { __dataRequests?: DataRequestDescriptor[]; __isInErrorState?: boolean; + __isPreviewLayer?: boolean; __errorMessage?: string; __trackedLayerDescriptor?: LayerDescriptor; alpha?: number; diff --git a/x-pack/plugins/maps/public/actions/layer_actions.ts b/x-pack/plugins/maps/public/actions/layer_actions.ts index cac79093ce4379..51e251a5d8e202 100644 --- a/x-pack/plugins/maps/public/actions/layer_actions.ts +++ b/x-pack/plugins/maps/public/actions/layer_actions.ts @@ -9,10 +9,10 @@ import { Query } from 'src/plugins/data/public'; import { MapStoreState } from '../reducers/store'; import { getLayerById, + getLayerList, getLayerListRaw, getSelectedLayerId, getMapReady, - getTransientLayerId, } from '../selectors/map_selectors'; import { FLYOUT_STATE } from '../reducers/ui'; import { cancelRequest } from '../reducers/non_serializable_instances'; @@ -27,7 +27,6 @@ import { SET_JOINS, SET_LAYER_VISIBILITY, SET_SELECTED_LAYER, - SET_TRANSIENT_LAYER, SET_WAITING_FOR_READY_HIDDEN_LAYERS, TRACK_CURRENT_LAYER_STATE, UPDATE_LAYER_ORDER, @@ -139,6 +138,41 @@ export function addLayerWithoutDataSync(layerDescriptor: LayerDescriptor) { }; } +export function addPreviewLayers(layerDescriptors: LayerDescriptor[]) { + return (dispatch: Dispatch) => { + dispatch(removePreviewLayers()); + + layerDescriptors.forEach((layerDescriptor) => { + dispatch(addLayer({ ...layerDescriptor, __isPreviewLayer: true })); + }); + }; +} + +export function removePreviewLayers() { + return (dispatch: Dispatch, getState: () => MapStoreState) => { + getLayerList(getState()).forEach((layer) => { + if (layer.isPreviewLayer()) { + dispatch(removeLayer(layer.getId())); + } + }); + }; +} + +export function promotePreviewLayers() { + return (dispatch: Dispatch, getState: () => MapStoreState) => { + getLayerList(getState()).forEach((layer) => { + if (layer.isPreviewLayer()) { + dispatch({ + type: UPDATE_LAYER_PROP, + id: layer.getId(), + propName: '__isPreviewLayer', + newValue: false, + }); + } + }); + }; +} + export function setLayerVisibility(layerId: string, makeVisible: boolean) { return async (dispatch: Dispatch, getState: () => MapStoreState) => { // if the current-state is invisible, we also want to sync data @@ -193,31 +227,17 @@ export function setSelectedLayer(layerId: string | null) { }; } -export function removeTransientLayer() { +export function setFirstPreviewLayerToSelectedLayer() { return async (dispatch: Dispatch, getState: () => MapStoreState) => { - const transientLayerId = getTransientLayerId(getState()); - if (transientLayerId) { - await dispatch(removeLayerFromLayerList(transientLayerId)); - await dispatch(setTransientLayer(null)); + const firstPreviewLayer = getLayerList(getState()).find((layer) => { + return layer.isPreviewLayer(); + }); + if (firstPreviewLayer) { + dispatch(setSelectedLayer(firstPreviewLayer.getId())); } }; } -export function setTransientLayer(layerId: string | null) { - return { - type: SET_TRANSIENT_LAYER, - transientLayerId: layerId, - }; -} - -export function clearTransientLayerStateAndCloseFlyout() { - return async (dispatch: Dispatch) => { - await dispatch(updateFlyout(FLYOUT_STATE.NONE)); - await dispatch(setSelectedLayer(null)); - await dispatch(removeTransientLayer()); - }; -} - export function updateLayerOrder(newLayerOrder: number[]) { return { type: UPDATE_LAYER_ORDER, diff --git a/x-pack/plugins/maps/public/actions/map_action_constants.ts b/x-pack/plugins/maps/public/actions/map_action_constants.ts index 0a32dba1194295..25a86e4c50d07d 100644 --- a/x-pack/plugins/maps/public/actions/map_action_constants.ts +++ b/x-pack/plugins/maps/public/actions/map_action_constants.ts @@ -5,7 +5,6 @@ */ export const SET_SELECTED_LAYER = 'SET_SELECTED_LAYER'; -export const SET_TRANSIENT_LAYER = 'SET_TRANSIENT_LAYER'; export const UPDATE_LAYER_ORDER = 'UPDATE_LAYER_ORDER'; export const ADD_LAYER = 'ADD_LAYER'; export const SET_LAYER_ERROR_STATUS = 'SET_LAYER_ERROR_STATUS'; diff --git a/x-pack/plugins/maps/public/classes/layers/layer.tsx b/x-pack/plugins/maps/public/classes/layers/layer.tsx index 19a0152a19df7c..2250d5663378cd 100644 --- a/x-pack/plugins/maps/public/classes/layers/layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/layer.tsx @@ -75,6 +75,7 @@ export interface ILayer { getInFlightRequestTokens(): symbol[]; getPrevRequestToken(dataId: string): symbol | undefined; destroy: () => void; + isPreviewLayer: () => boolean; } export type Footnote = { icon: ReactElement; @@ -174,6 +175,10 @@ export class AbstractLayer implements ILayer { return this.getSource().isJoinable(); } + isPreviewLayer(): boolean { + return !!this._descriptor.__isPreviewLayer; + } + supportsElasticsearchFilters(): boolean { return this.getSource().isESSource(); } diff --git a/x-pack/plugins/maps/public/classes/layers/layer_wizard_registry.ts b/x-pack/plugins/maps/public/classes/layers/layer_wizard_registry.ts index 7698fb7c0947e1..2bdeb6446cf288 100644 --- a/x-pack/plugins/maps/public/classes/layers/layer_wizard_registry.ts +++ b/x-pack/plugins/maps/public/classes/layers/layer_wizard_registry.ts @@ -9,7 +9,7 @@ import { ReactElement } from 'react'; import { LayerDescriptor } from '../../../common/descriptor_types'; export type RenderWizardArguments = { - previewLayer: (layerDescriptor: LayerDescriptor | null, isIndexingSource?: boolean) => void; + previewLayers: (layerDescriptors: LayerDescriptor[], isIndexingSource?: boolean) => void; mapColors: string[]; // upload arguments isIndexingTriggered: boolean; diff --git a/x-pack/plugins/maps/public/classes/layers/solution_layers/observability/observability_layer_template.tsx b/x-pack/plugins/maps/public/classes/layers/solution_layers/observability/observability_layer_template.tsx index bfd78d54900591..3f3c556dcae1e5 100644 --- a/x-pack/plugins/maps/public/classes/layers/solution_layers/observability/observability_layer_template.tsx +++ b/x-pack/plugins/maps/public/classes/layers/solution_layers/observability/observability_layer_template.tsx @@ -53,13 +53,12 @@ export class ObservabilityLayerTemplate extends Component { function previewGeojsonFile(geojsonFile: unknown, name: string) { if (!geojsonFile) { - previewLayer(null); + previewLayers([]); return; } const sourceDescriptor = GeojsonFileSource.createDescriptor(geojsonFile, name); const layerDescriptor = VectorLayer.createDescriptor({ sourceDescriptor }, mapColors); // TODO figure out a better way to handle passing this information back to layer_addpanel - previewLayer(layerDescriptor, true); + previewLayers([layerDescriptor], true); } function viewIndexedData(indexResponses: { @@ -72,7 +72,7 @@ export const uploadLayerWizardConfig: LayerWizard = { ) ); if (!indexPatternId || !geoField) { - previewLayer(null); + previewLayers([]); } else { const esSearchSourceConfig = { indexPatternId, @@ -85,7 +85,7 @@ export const uploadLayerWizardConfig: LayerWizard = { ? SCALING_TYPES.CLUSTERS : SCALING_TYPES.LIMIT, }; - previewLayer(createDefaultLayerDescriptor(esSearchSourceConfig, mapColors)); + previewLayers([createDefaultLayerDescriptor(esSearchSourceConfig, mapColors)]); importSuccessHandler(indexResponses); } } diff --git a/x-pack/plugins/maps/public/classes/sources/ems_file_source/ems_boundaries_layer_wizard.tsx b/x-pack/plugins/maps/public/classes/sources/ems_file_source/ems_boundaries_layer_wizard.tsx index 4f1edca75b3086..7eec84ef5bb2e1 100644 --- a/x-pack/plugins/maps/public/classes/sources/ems_file_source/ems_boundaries_layer_wizard.tsx +++ b/x-pack/plugins/maps/public/classes/sources/ems_file_source/ems_boundaries_layer_wizard.tsx @@ -22,11 +22,11 @@ export const emsBoundariesLayerWizardConfig: LayerWizard = { defaultMessage: 'Administrative boundaries from Elastic Maps Service', }), icon: 'emsApp', - renderWizard: ({ previewLayer, mapColors }: RenderWizardArguments) => { + renderWizard: ({ previewLayers, mapColors }: RenderWizardArguments) => { const onSourceConfigChange = (sourceConfig: Partial) => { const sourceDescriptor = EMSFileSource.createDescriptor(sourceConfig); const layerDescriptor = VectorLayer.createDescriptor({ sourceDescriptor }, mapColors); - previewLayer(layerDescriptor); + previewLayers([layerDescriptor]); }; return ; }, diff --git a/x-pack/plugins/maps/public/classes/sources/ems_tms_source/ems_base_map_layer_wizard.tsx b/x-pack/plugins/maps/public/classes/sources/ems_tms_source/ems_base_map_layer_wizard.tsx index 7a25609c6a5d10..60e67b1ae70534 100644 --- a/x-pack/plugins/maps/public/classes/sources/ems_tms_source/ems_base_map_layer_wizard.tsx +++ b/x-pack/plugins/maps/public/classes/sources/ems_tms_source/ems_base_map_layer_wizard.tsx @@ -22,12 +22,12 @@ export const emsBaseMapLayerWizardConfig: LayerWizard = { defaultMessage: 'Tile map service from Elastic Maps Service', }), icon: 'emsApp', - renderWizard: ({ previewLayer }: RenderWizardArguments) => { + renderWizard: ({ previewLayers }: RenderWizardArguments) => { const onSourceConfigChange = (sourceConfig: unknown) => { const layerDescriptor = VectorTileLayer.createDescriptor({ sourceDescriptor: EMSTMSSource.createDescriptor(sourceConfig), }); - previewLayer(layerDescriptor); + previewLayers([layerDescriptor]); }; return ; diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/clusters_layer_wizard.tsx b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/clusters_layer_wizard.tsx index 84bdee2a64bd84..b9d5faa8e18f1b 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/clusters_layer_wizard.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/clusters_layer_wizard.tsx @@ -34,10 +34,10 @@ export const clustersLayerWizardConfig: LayerWizard = { defaultMessage: 'Geospatial data grouped in grids with metrics for each gridded cell', }), icon: 'logoElasticsearch', - renderWizard: ({ previewLayer }: RenderWizardArguments) => { + renderWizard: ({ previewLayers }: RenderWizardArguments) => { const onSourceConfigChange = (sourceConfig: Partial) => { if (!sourceConfig) { - previewLayer(null); + previewLayers([]); return; } @@ -93,7 +93,7 @@ export const clustersLayerWizardConfig: LayerWizard = { }, }), }); - previewLayer(layerDescriptor); + previewLayers([layerDescriptor]); }; return ( diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/heatmap_layer_wizard.tsx b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/heatmap_layer_wizard.tsx index d0e45cb05ca064..79252c7febf8c9 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/heatmap_layer_wizard.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/heatmap_layer_wizard.tsx @@ -21,17 +21,17 @@ export const heatmapLayerWizardConfig: LayerWizard = { defaultMessage: 'Geospatial data grouped in grids to show density', }), icon: 'logoElasticsearch', - renderWizard: ({ previewLayer }: RenderWizardArguments) => { + renderWizard: ({ previewLayers }: RenderWizardArguments) => { const onSourceConfigChange = (sourceConfig: Partial) => { if (!sourceConfig) { - previewLayer(null); + previewLayers([]); return; } const layerDescriptor = HeatmapLayer.createDescriptor({ sourceDescriptor: ESGeoGridSource.createDescriptor(sourceConfig), }); - previewLayer(layerDescriptor); + previewLayers([layerDescriptor]); }; return ( diff --git a/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/point_2_point_layer_wizard.tsx b/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/point_2_point_layer_wizard.tsx index 8d7bf0d2af661c..5169af9bdddf2f 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/point_2_point_layer_wizard.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/point_2_point_layer_wizard.tsx @@ -28,10 +28,10 @@ export const point2PointLayerWizardConfig: LayerWizard = { defaultMessage: 'Aggregated data paths between the source and destination', }), icon: 'logoElasticsearch', - renderWizard: ({ previewLayer }: RenderWizardArguments) => { + renderWizard: ({ previewLayers }: RenderWizardArguments) => { const onSourceConfigChange = (sourceConfig: unknown) => { if (!sourceConfig) { - previewLayer(null); + previewLayers([]); return; } @@ -64,7 +64,7 @@ export const point2PointLayerWizardConfig: LayerWizard = { }, }), }); - previewLayer(layerDescriptor); + previewLayers([layerDescriptor]); }; return ; diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_documents_layer_wizard.tsx b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_documents_layer_wizard.tsx index 8898735427ccb7..888de2e7297cba 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_documents_layer_wizard.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_documents_layer_wizard.tsx @@ -28,14 +28,14 @@ export const esDocumentsLayerWizardConfig: LayerWizard = { defaultMessage: 'Vector data from a Kibana index pattern', }), icon: 'logoElasticsearch', - renderWizard: ({ previewLayer, mapColors }: RenderWizardArguments) => { + renderWizard: ({ previewLayers, mapColors }: RenderWizardArguments) => { const onSourceConfigChange = (sourceConfig: unknown) => { if (!sourceConfig) { - previewLayer(null); + previewLayers([]); return; } - previewLayer(createDefaultLayerDescriptor(sourceConfig, mapColors)); + previewLayers([createDefaultLayerDescriptor(sourceConfig, mapColors)]); }; return ; }, diff --git a/x-pack/plugins/maps/public/classes/sources/kibana_regionmap_source/kibana_regionmap_layer_wizard.tsx b/x-pack/plugins/maps/public/classes/sources/kibana_regionmap_source/kibana_regionmap_layer_wizard.tsx index 309cb3abd83b25..b778dc00764590 100644 --- a/x-pack/plugins/maps/public/classes/sources/kibana_regionmap_source/kibana_regionmap_layer_wizard.tsx +++ b/x-pack/plugins/maps/public/classes/sources/kibana_regionmap_source/kibana_regionmap_layer_wizard.tsx @@ -24,11 +24,11 @@ export const kibanaRegionMapLayerWizardConfig: LayerWizard = { defaultMessage: 'Vector data from hosted GeoJSON configured in kibana.yml', }), icon: 'logoKibana', - renderWizard: ({ previewLayer, mapColors }: RenderWizardArguments) => { + renderWizard: ({ previewLayers, mapColors }: RenderWizardArguments) => { const onSourceConfigChange = (sourceConfig: unknown) => { const sourceDescriptor = KibanaRegionmapSource.createDescriptor(sourceConfig); const layerDescriptor = VectorLayer.createDescriptor({ sourceDescriptor }, mapColors); - previewLayer(layerDescriptor); + previewLayers([layerDescriptor]); }; return ; diff --git a/x-pack/plugins/maps/public/classes/sources/kibana_tilemap_source/kibana_base_map_layer_wizard.tsx b/x-pack/plugins/maps/public/classes/sources/kibana_tilemap_source/kibana_base_map_layer_wizard.tsx index 46513985ed1ab2..227c0182b98dee 100644 --- a/x-pack/plugins/maps/public/classes/sources/kibana_tilemap_source/kibana_base_map_layer_wizard.tsx +++ b/x-pack/plugins/maps/public/classes/sources/kibana_tilemap_source/kibana_base_map_layer_wizard.tsx @@ -24,12 +24,12 @@ export const kibanaBasemapLayerWizardConfig: LayerWizard = { defaultMessage: 'Tile map service configured in kibana.yml', }), icon: 'logoKibana', - renderWizard: ({ previewLayer }: RenderWizardArguments) => { + renderWizard: ({ previewLayers }: RenderWizardArguments) => { const onSourceConfigChange = () => { const layerDescriptor = TileLayer.createDescriptor({ sourceDescriptor: KibanaTilemapSource.createDescriptor(), }); - previewLayer(layerDescriptor); + previewLayers([layerDescriptor]); }; return ; }, diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/layer_wizard.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/layer_wizard.tsx index 86f8108d5e23bc..c29302a2058b21 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/layer_wizard.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/layer_wizard.tsx @@ -19,11 +19,11 @@ export const mvtVectorSourceWizardConfig: LayerWizard = { defaultMessage: 'Vector source wizard', }), icon: 'grid', - renderWizard: ({ previewLayer, mapColors }: RenderWizardArguments) => { + renderWizard: ({ previewLayers, mapColors }: RenderWizardArguments) => { const onSourceConfigChange = (sourceConfig: MVTSingleLayerVectorSourceConfig) => { const sourceDescriptor = MVTSingleLayerVectorSource.createDescriptor(sourceConfig); const layerDescriptor = TiledVectorLayer.createDescriptor({ sourceDescriptor }, mapColors); - previewLayer(layerDescriptor); + previewLayers([layerDescriptor]); }; return ; diff --git a/x-pack/plugins/maps/public/classes/sources/wms_source/wms_layer_wizard.tsx b/x-pack/plugins/maps/public/classes/sources/wms_source/wms_layer_wizard.tsx index 9261b8866d115f..62eeef234f4141 100644 --- a/x-pack/plugins/maps/public/classes/sources/wms_source/wms_layer_wizard.tsx +++ b/x-pack/plugins/maps/public/classes/sources/wms_source/wms_layer_wizard.tsx @@ -18,17 +18,17 @@ export const wmsLayerWizardConfig: LayerWizard = { defaultMessage: 'Maps from OGC Standard WMS', }), icon: 'grid', - renderWizard: ({ previewLayer }: RenderWizardArguments) => { + renderWizard: ({ previewLayers }: RenderWizardArguments) => { const onSourceConfigChange = (sourceConfig: unknown) => { if (!sourceConfig) { - previewLayer(null); + previewLayers([]); return; } const layerDescriptor = TileLayer.createDescriptor({ sourceDescriptor: WMSSource.createDescriptor(sourceConfig), }); - previewLayer(layerDescriptor); + previewLayers([layerDescriptor]); }; return ; }, diff --git a/x-pack/plugins/maps/public/classes/sources/xyz_tms_source/layer_wizard.tsx b/x-pack/plugins/maps/public/classes/sources/xyz_tms_source/layer_wizard.tsx index 574aaa262569f9..b99b17c1d22d47 100644 --- a/x-pack/plugins/maps/public/classes/sources/xyz_tms_source/layer_wizard.tsx +++ b/x-pack/plugins/maps/public/classes/sources/xyz_tms_source/layer_wizard.tsx @@ -16,12 +16,12 @@ export const tmsLayerWizardConfig: LayerWizard = { defaultMessage: 'Tile map service configured in interface', }), icon: 'grid', - renderWizard: ({ previewLayer }: RenderWizardArguments) => { + renderWizard: ({ previewLayers }: RenderWizardArguments) => { const onSourceConfigChange = (sourceConfig: XYZTMSSourceConfig) => { const layerDescriptor = TileLayer.createDescriptor({ sourceDescriptor: XYZTMSSource.createDescriptor(sourceConfig), }); - previewLayer(layerDescriptor); + previewLayers([layerDescriptor]); }; return ; }, diff --git a/x-pack/plugins/maps/public/connected_components/add_layer_panel/flyout_body/flyout_body.tsx b/x-pack/plugins/maps/public/connected_components/add_layer_panel/flyout_body/flyout_body.tsx index 75fb7a5bc4accc..b287064938ce55 100644 --- a/x-pack/plugins/maps/public/connected_components/add_layer_panel/flyout_body/flyout_body.tsx +++ b/x-pack/plugins/maps/public/connected_components/add_layer_panel/flyout_body/flyout_body.tsx @@ -24,7 +24,7 @@ export const FlyoutBody = (props: Props) => { } const renderWizardArgs = { - previewLayer: props.previewLayer, + previewLayers: props.previewLayers, mapColors: props.mapColors, isIndexingTriggered: props.isIndexingTriggered, onRemove: props.onRemove, diff --git a/x-pack/plugins/maps/public/connected_components/add_layer_panel/flyout_footer/index.ts b/x-pack/plugins/maps/public/connected_components/add_layer_panel/flyout_footer/index.ts index 968429ce912265..470e83f2d80900 100644 --- a/x-pack/plugins/maps/public/connected_components/add_layer_panel/flyout_footer/index.ts +++ b/x-pack/plugins/maps/public/connected_components/add_layer_panel/flyout_footer/index.ts @@ -7,22 +7,24 @@ import { AnyAction, Dispatch } from 'redux'; import { connect } from 'react-redux'; import { FlyoutFooter } from './view'; -import { getSelectedLayer } from '../../../selectors/map_selectors'; -import { clearTransientLayerStateAndCloseFlyout } from '../../../actions'; +import { hasPreviewLayers, isLoadingPreviewLayers } from '../../../selectors/map_selectors'; +import { removePreviewLayers, updateFlyout } from '../../../actions'; import { MapStoreState } from '../../../reducers/store'; +import { FLYOUT_STATE } from '../../../reducers/ui'; function mapStateToProps(state: MapStoreState) { - const selectedLayer = getSelectedLayer(state); - const hasLayerSelected = !!selectedLayer; return { - hasLayerSelected, - isLoading: hasLayerSelected && selectedLayer!.isLayerLoading(), + hasPreviewLayers: hasPreviewLayers(state), + isLoading: isLoadingPreviewLayers(state), }; } function mapDispatchToProps(dispatch: Dispatch) { return { - closeFlyout: () => dispatch(clearTransientLayerStateAndCloseFlyout()), + closeFlyout: () => { + dispatch(updateFlyout(FLYOUT_STATE.NONE)); + dispatch(removePreviewLayers()); + }, }; } diff --git a/x-pack/plugins/maps/public/connected_components/add_layer_panel/flyout_footer/view.tsx b/x-pack/plugins/maps/public/connected_components/add_layer_panel/flyout_footer/view.tsx index 6f4d25a9c6c3ed..2e122324c50fb0 100644 --- a/x-pack/plugins/maps/public/connected_components/add_layer_panel/flyout_footer/view.tsx +++ b/x-pack/plugins/maps/public/connected_components/add_layer_panel/flyout_footer/view.tsx @@ -20,7 +20,7 @@ interface Props { disableNextButton: boolean; nextButtonText: string; closeFlyout: () => void; - hasLayerSelected: boolean; + hasPreviewLayers: boolean; isLoading: boolean; } @@ -30,14 +30,14 @@ export const FlyoutFooter = ({ disableNextButton, nextButtonText, closeFlyout, - hasLayerSelected, + hasPreviewLayers, isLoading, }: Props) => { const nextButton = showNextButton ? ( ) { return { - previewLayer: async (layerDescriptor: LayerDescriptor) => { - await dispatch(setSelectedLayer(null)); - await dispatch(removeTransientLayer()); - dispatch(addLayer(layerDescriptor)); - dispatch(setSelectedLayer(layerDescriptor.id)); - dispatch(setTransientLayer(layerDescriptor.id)); + addPreviewLayers: (layerDescriptors: LayerDescriptor[]) => { + dispatch(addPreviewLayers(layerDescriptors)); }, - removeTransientLayer: () => { - dispatch(setSelectedLayer(null)); - dispatch(removeTransientLayer()); - }, - selectLayerAndAdd: () => { - dispatch(setTransientLayer(null)); + promotePreviewLayers: () => { + dispatch(setFirstPreviewLayerToSelectedLayer()); dispatch(updateFlyout(FLYOUT_STATE.LAYER_PANEL)); + dispatch(promotePreviewLayers()); }, setIndexingTriggered: () => dispatch(updateIndexingStage(INDEXING_STAGE.TRIGGERED)), resetIndexing: () => dispatch(updateIndexingStage(null)), diff --git a/x-pack/plugins/maps/public/connected_components/add_layer_panel/view.tsx b/x-pack/plugins/maps/public/connected_components/add_layer_panel/view.tsx index d382a4085fe195..c1b6dcc1e12a6c 100644 --- a/x-pack/plugins/maps/public/connected_components/add_layer_panel/view.tsx +++ b/x-pack/plugins/maps/public/connected_components/add_layer_panel/view.tsx @@ -17,17 +17,15 @@ interface Props { isIndexingReady: boolean; isIndexingSuccess: boolean; isIndexingTriggered: boolean; - previewLayer: (layerDescriptor: LayerDescriptor) => void; - removeTransientLayer: () => void; + addPreviewLayers: (layerDescriptors: LayerDescriptor[]) => void; + promotePreviewLayers: () => void; resetIndexing: () => void; - selectLayerAndAdd: () => void; setIndexingTriggered: () => void; } interface State { importView: boolean; isIndexingSource: boolean; - layerDescriptor: LayerDescriptor | null; layerImportAddReady: boolean; layerWizard: LayerWizard | null; } @@ -37,7 +35,6 @@ export class AddLayerPanel extends Component { state = { layerWizard: null, - layerDescriptor: null, // TODO get this from redux store instead of storing locally isIndexingSource: false, importView: false, layerImportAddReady: false, @@ -57,21 +54,13 @@ export class AddLayerPanel extends Component { } } - _previewLayer = (layerDescriptor: LayerDescriptor | null, isIndexingSource?: boolean) => { + _previewLayers = (layerDescriptors: LayerDescriptor[], isIndexingSource?: boolean) => { if (!this._isMounted) { return; } - if (!layerDescriptor) { - this.setState({ - layerDescriptor: null, - isIndexingSource: false, - }); - this.props.removeTransientLayer(); - return; - } - this.setState({ layerDescriptor, isIndexingSource: !!isIndexingSource }); - this.props.previewLayer(layerDescriptor); + this.setState({ isIndexingSource: layerDescriptors.length ? !!isIndexingSource : false }); + this.props.addPreviewLayers(layerDescriptors); }; _clearLayerData = ({ keepSourceType = false }: { keepSourceType: boolean }) => { @@ -80,7 +69,6 @@ export class AddLayerPanel extends Component { } const newState: Partial = { - layerDescriptor: null, isIndexingSource: false, }; if (!keepSourceType) { @@ -90,7 +78,7 @@ export class AddLayerPanel extends Component { // @ts-ignore this.setState(newState); - this.props.removeTransientLayer(); + this.props.addPreviewLayers([]); }; _onWizardSelect = (layerWizard: LayerWizard) => { @@ -101,7 +89,7 @@ export class AddLayerPanel extends Component { if (this.state.isIndexingSource && !this.props.isIndexingTriggered) { this.props.setIndexingTriggered(); } else { - this.props.selectLayerAndAdd(); + this.props.promotePreviewLayers(); if (this.state.importView) { this.setState({ layerImportAddReady: false, @@ -126,7 +114,7 @@ export class AddLayerPanel extends Component { }); const isNextBtnEnabled = this.state.importView ? this.props.isIndexingReady || this.props.isIndexingSuccess - : !!this.state.layerDescriptor; + : true; return ( @@ -141,7 +129,7 @@ export class AddLayerPanel extends Component { onClear={() => this._clearLayerData({ keepSourceType: false })} onRemove={() => this._clearLayerData({ keepSourceType: true })} onWizardSelect={this._onWizardSelect} - previewLayer={this._previewLayer} + previewLayers={this._previewLayers} /> { - await dispatch(removeTransientLayer()); await dispatch(setSelectedLayer(layerId)); dispatch(updateFlyout(FLYOUT_STATE.LAYER_PANEL)); }, diff --git a/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/view.js b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/view.js index c0ce24fef9cd86..b17078ae371139 100644 --- a/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/view.js +++ b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/view.js @@ -239,7 +239,8 @@ export class TOCEntry extends React.Component { 'mapTocEntry-isDragging': this.props.isDragging, 'mapTocEntry-isDraggingOver': this.props.isDraggingOver, 'mapTocEntry-isSelected': - this.props.selectedLayer && this.props.selectedLayer.getId() === this.props.layer.getId(), + this.props.layer.isPreviewLayer() || + (this.props.selectedLayer && this.props.selectedLayer.getId() === this.props.layer.getId()), }); return ( diff --git a/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/view.test.js b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/view.test.js index 90d756484c47f4..543be9395d0bc2 100644 --- a/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/view.test.js +++ b/x-pack/plugins/maps/public/connected_components/widget_overlay/layer_control/layer_toc/toc_entry/view.test.js @@ -21,6 +21,9 @@ const mockLayer = { getDisplayName: () => { return 'layer 1'; }, + isPreviewLayer: () => { + return false; + }, isVisible: () => { return true; }, diff --git a/x-pack/plugins/maps/public/reducers/map.d.ts b/x-pack/plugins/maps/public/reducers/map.d.ts index 8fc655b2c837a6..33794fcf8657da 100644 --- a/x-pack/plugins/maps/public/reducers/map.d.ts +++ b/x-pack/plugins/maps/public/reducers/map.d.ts @@ -66,7 +66,6 @@ export type MapState = { openTooltips: TooltipState[]; mapState: MapContext; selectedLayerId: string | null; - __transientLayerId: string | null; layerList: LayerDescriptor[]; waitingForMapReadyLayerList: LayerDescriptor[]; settings: MapSettings; diff --git a/x-pack/plugins/maps/public/reducers/map.js b/x-pack/plugins/maps/public/reducers/map.js index a76768b4ba5077..317c11eb7680c6 100644 --- a/x-pack/plugins/maps/public/reducers/map.js +++ b/x-pack/plugins/maps/public/reducers/map.js @@ -6,7 +6,6 @@ import { SET_SELECTED_LAYER, - SET_TRANSIENT_LAYER, UPDATE_LAYER_ORDER, LAYER_DATA_LOAD_STARTED, LAYER_DATA_LOAD_ENDED, @@ -126,7 +125,6 @@ export const DEFAULT_MAP_STATE = { hideViewControl: false, }, selectedLayerId: null, - __transientLayerId: null, layerList: [], waitingForMapReadyLayerList: [], settings: getDefaultMapSettings(), @@ -285,9 +283,6 @@ export function map(state = DEFAULT_MAP_STATE, action) { case SET_SELECTED_LAYER: const selectedMatch = state.layerList.find((layer) => layer.id === action.selectedLayerId); return { ...state, selectedLayerId: selectedMatch ? action.selectedLayerId : null }; - case SET_TRANSIENT_LAYER: - const transientMatch = state.layerList.find((layer) => layer.id === action.transientLayerId); - return { ...state, __transientLayerId: transientMatch ? action.transientLayerId : null }; case UPDATE_LAYER_ORDER: return { ...state, diff --git a/x-pack/plugins/maps/public/selectors/map_selectors.ts b/x-pack/plugins/maps/public/selectors/map_selectors.ts index 28084cac19f1a7..467f1074e88e72 100644 --- a/x-pack/plugins/maps/public/selectors/map_selectors.ts +++ b/x-pack/plugins/maps/public/selectors/map_selectors.ts @@ -137,9 +137,6 @@ export const getSelectedLayerId = ({ map }: MapStoreState): string | null => { return !map.selectedLayerId || !map.layerList ? null : map.selectedLayerId; }; -export const getTransientLayerId = ({ map }: MapStoreState): string | null => - map.__transientLayerId; - export const getLayerListRaw = ({ map }: MapStoreState): LayerDescriptor[] => map.layerList ? map.layerList : []; @@ -331,15 +328,28 @@ export const getSelectedLayer = createSelector( } ); -export const getMapColors = createSelector( - getTransientLayerId, - getLayerListRaw, - (transientLayerId, layerList) => - layerList.reduce((accu: string[], layer: LayerDescriptor) => { - if (layer.id === transientLayerId) { - return accu; - } - const color: string | undefined = _.get(layer, 'style.properties.fillColor.options.color'); +export const hasPreviewLayers = createSelector(getLayerList, (layerList) => { + return layerList.some((layer) => { + return layer.isPreviewLayer(); + }); +}); + +export const isLoadingPreviewLayers = createSelector(getLayerList, (layerList) => { + return layerList.some((layer) => { + return layer.isPreviewLayer() && layer.isLayerLoading(); + }); +}); + +export const getMapColors = createSelector(getLayerListRaw, (layerList) => + layerList + .filter((layerDescriptor) => { + return !layerDescriptor.__isPreviewLayer; + }) + .reduce((accu: string[], layerDescriptor: LayerDescriptor) => { + const color: string | undefined = _.get( + layerDescriptor, + 'style.properties.fillColor.options.color' + ); if (color) accu.push(color); return accu; }, []) @@ -373,24 +383,20 @@ export const getQueryableUniqueIndexPatternIds = createSelector(getLayerList, (l return _.uniq(indexPatternIds); }); -export const hasDirtyState = createSelector( - getLayerListRaw, - getTransientLayerId, - (layerListRaw, transientLayerId) => { - if (transientLayerId) { +export const hasDirtyState = createSelector(getLayerListRaw, (layerListRaw) => { + return layerListRaw.some((layerDescriptor) => { + if (layerDescriptor.__isPreviewLayer) { return true; } - return layerListRaw.some((layerDescriptor) => { - const trackedState = layerDescriptor[TRACKED_LAYER_DESCRIPTOR]; - if (!trackedState) { - return false; - } - const currentState = copyPersistentState(layerDescriptor); - return !_.isEqual(currentState, trackedState); - }); - } -); + const trackedState = layerDescriptor[TRACKED_LAYER_DESCRIPTOR]; + if (!trackedState) { + return false; + } + const currentState = copyPersistentState(layerDescriptor); + return !_.isEqual(currentState, trackedState); + }); +}); export const areLayersLoaded = createSelector( getLayerList,