Skip to content

Commit

Permalink
Integrate to saved object
Browse files Browse the repository at this point in the history
Signed-off-by: Junqiu Lei <[email protected]>
  • Loading branch information
junqiu-lei committed Dec 21, 2022
1 parent bb53bc1 commit 1b76052
Show file tree
Hide file tree
Showing 12 changed files with 149 additions and 41 deletions.
6 changes: 6 additions & 0 deletions maps_dashboards/public/_variables.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

$mapHeaderOffset: 154px;
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
} from '@elastic/eui';
import './add_layer_panel.scss';
import { DOCUMENTS, OPENSEARCH_MAP_LAYER, CUSTOM_MAP, Layer } from '../../../common';
import { getLayerConfigMap } from '../../utils/getIntialLayerConfig';
import { getLayerConfigMap } from '../../utils/getIntialConfig';

interface Props {
setIsLayerConfigVisible: Function;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ export const LayerConfigPanel = ({
};
const onUpdate = () => {
updateLayer();
updateIndexPatterns();
closeLayerConfigPanel(false);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,7 @@ import { layersFunctionMap } from '../../model/layersFunctions';
import { useOpenSearchDashboards } from '../../../../../src/plugins/opensearch_dashboards_react/public';
import { MapServices } from '../../types';
import { doDataLayerRender } from '../../model/DataLayerController';
import {
IOpenSearchDashboardsSearchResponse,
isCompleteResponse,
buildOpenSearchQuery,
} from '../../../../../src/plugins/data/common';
import { IndexPattern } from '../../../../../src/plugins/data/public';
import { MapState } from '../../model/mapState';

interface MaplibreRef {
current: Maplibre | null;
Expand All @@ -53,10 +48,18 @@ interface Props {
layers: MapLayerSpecification[];
layersIndexPatterns: IndexPattern[];
setLayersIndexPatterns: (indexPatterns: IndexPattern[]) => void;
mapState: MapState;
}

export const LayerControlPanel = memo(
({ maplibreRef, setLayers, layers, layersIndexPatterns, setLayersIndexPatterns }: Props) => {
({
maplibreRef,
setLayers,
layers,
layersIndexPatterns,
setLayersIndexPatterns,
mapState,
}: Props) => {
const { services } = useOpenSearchDashboards<MapServices>();
const {
data: { indexPatterns },
Expand All @@ -79,15 +82,15 @@ export const LayerControlPanel = memo(
if (layers.length <= 0) {
return;
}

if (initialLayersLoaded) {
if (!selectedLayerConfig) {
return;
}
if (selectedLayerConfig.type === DASHBOARDS_MAPS_LAYER_TYPE.OPENSEARCH_MAP) {
layersFunctionMap[selectedLayerConfig.type].render(maplibreRef, selectedLayerConfig);
} else {
doDataLayerRender(selectedLayerConfig, services, layersIndexPatterns, maplibreRef);
updateIndexPatterns();
doDataLayerRender(selectedLayerConfig, mapState, services, maplibreRef);
}
if (addLayerId !== selectedLayerConfig.id) {
setSelectedLayerConfig(undefined);
Expand All @@ -97,7 +100,7 @@ export const LayerControlPanel = memo(
if (layer.type === DASHBOARDS_MAPS_LAYER_TYPE.OPENSEARCH_MAP) {
layersFunctionMap[layer.type].render(maplibreRef, layer);
} else {
doDataLayerRender(layer, services, layersIndexPatterns, maplibreRef);
doDataLayerRender(layer, mapState, services, maplibreRef);
}
});
setInitialLayersLoaded(true);
Expand Down Expand Up @@ -148,14 +151,9 @@ export const LayerControlPanel = memo(
setSelectedLayerConfig(layer);
setIsLayerConfigVisible(true);
};
const isLayerExists = (name: string) => {
return layers.findIndex((layer) => layer.name === name) > -1;
};

const onClickLayerName = (layer: MapLayerSpecification) => {
setSelectedLayerConfig(layer);
setIsLayerConfigVisible(true);
};
const isLayerExists = (name: string) => {
return layers.findIndex((layer) => layer.name === name) > -1;
};

const [layerVisibility, setLayerVisibility] = useState(new Map<string, boolean>([]));
layers.forEach((layer) => {
Expand All @@ -182,6 +180,9 @@ export const LayerControlPanel = memo(
if (selectedLayerConfig.type === DASHBOARDS_MAPS_LAYER_TYPE.OPENSEARCH_MAP) {
return;
}
if (!selectedLayerConfig.source.indexPatternId) {
return;
}
const findIndexPattern = layersIndexPatterns.find(
(indexPattern) => indexPattern.id === selectedLayerConfig.source.indexPatternId
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
*/

@import "maplibre-gl/dist/maplibre-gl.css";
@import "../../variables";

/* stylelint-disable no-empty-source */
.map-container {
width: 100%;
min-height: calc(100vh - 154px);
min-height: calc(100vh - #{$mapHeaderOffset});
}

.maplibregl-ctrl-top-left {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ import './map_container.scss';
import { MAP_INITIAL_STATE, MAP_GLYPHS } from '../../../common';
import { MapLayerSpecification } from '../../model/mapLayerType';
import { IndexPattern } from '../../../../../src/plugins/data/public';
import { MapState } from '../../model/mapState';

interface MapContainerProps {
setLayers: (layers: MapLayerSpecification[]) => void;
layers: MapLayerSpecification[];
layersIndexPatterns: IndexPattern[];
setLayersIndexPatterns: (indexPatterns: IndexPattern[]) => void;
maplibreRef: React.MutableRefObject<Maplibre | null>;
mapState: MapState;
}

export const MapContainer = ({
Expand All @@ -26,6 +28,7 @@ export const MapContainer = ({
layersIndexPatterns,
setLayersIndexPatterns,
maplibreRef,
mapState,
}: MapContainerProps) => {
const mapContainer = useRef(null);
const [mounted, setMounted] = useState(false);
Expand Down Expand Up @@ -70,6 +73,7 @@ export const MapContainer = ({
setLayers={setLayers}
layersIndexPatterns={layersIndexPatterns}
setLayersIndexPatterns={setLayersIndexPatterns}
mapState={mapState}
/>
)}
</div>
Expand Down
19 changes: 13 additions & 6 deletions maps_dashboards/public/components/map_page/map_page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,30 @@ import { MapServices } from '../../types';
import { useOpenSearchDashboards } from '../../../../../src/plugins/opensearch_dashboards_react/public';
import { MapSavedObjectAttributes } from '../../../common/map_saved_object_attributes';
import { DASHBOARDS_MAPS_LAYER_TYPE, OPENSEARCH_MAP_LAYER } from '../../../common';
import { getLayerConfigMap } from '../../utils/getIntialLayerConfig';
import { getLayerConfigMap, getInitialMapState } from '../../utils/getIntialConfig';
import { IndexPattern } from '../../../../../src/plugins/data/public';
import { MapState } from '../../model/mapState';

export const MapPage = () => {
const { services } = useOpenSearchDashboards<MapServices>();
const {
savedObjects: { client: savedObjectsClient },
} = services;
const [layers, setLayers] = useState<MapLayerSpecification[]>([]);
const { id: mapIdFromUrl } = useParams<{ id: string }>();
const [savedMapObject, setSavedMapObject] =
useState<SimpleSavedObject<MapSavedObjectAttributes> | null>();
const [layersIndexPatterns, setLayersIndexPatterns] = useState<IndexPattern[]>([]);
const maplibreRef = useRef<Maplibre | null>(null);
const { services } = useOpenSearchDashboards<MapServices>();
const {
savedObjects: { client: savedObjectsClient },
} = services;
const [mapState, setMapState] = useState<MapState>(getInitialMapState());

useEffect(() => {
if (mapIdFromUrl) {
savedObjectsClient.get<MapSavedObjectAttributes>('map', mapIdFromUrl).then((res) => {
setSavedMapObject(res);
const layerList = JSON.parse(res.attributes.layerList as string);
const layerList: MapLayerSpecification[] = JSON.parse(res.attributes.layerList as string);
const savedMapState: MapState = JSON.parse(res.attributes.mapState as string);
setMapState(savedMapState);
setLayers(layerList);
const savedIndexPatterns: IndexPattern[] = [];
layerList.forEach(async (layer: MapLayerSpecification) => {
Expand All @@ -60,13 +64,16 @@ export const MapPage = () => {
layers={layers}
layersIndexPatterns={layersIndexPatterns}
maplibreRef={maplibreRef}
mapState={mapState}
setMapState={setMapState}
/>
<MapContainer
layers={layers}
setLayers={setLayers}
layersIndexPatterns={layersIndexPatterns}
setLayersIndexPatterns={setLayersIndexPatterns}
maplibreRef={maplibreRef}
mapState={mapState}
/>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
checkForDuplicateTitle,
} from '../../../../../src/plugins/saved_objects/public';
import { MapServices } from '../../types';
import { MapState } from '../../model/mapState';

const SAVED_OBJECT_TYPE = 'map';

Expand All @@ -23,6 +24,7 @@ interface GetTopNavConfigParams {
description: string;
setTitle: (title: string) => void;
setDescription: (description: string) => void;
mapState: MapState;
}

export const getTopNavConfig = (
Expand All @@ -33,7 +35,15 @@ export const getTopNavConfig = (
history,
overlays,
}: MapServices,
{ mapIdFromUrl, layers, title, description, setTitle, setDescription }: GetTopNavConfigParams
{
mapIdFromUrl,
layers,
title,
description,
setTitle,
setDescription,
mapState,
}: GetTopNavConfigParams
) => {
const topNavConfig: TopNavMenuData[] = [
{
Expand All @@ -50,6 +60,7 @@ export const getTopNavConfig = (
title: newTitle,
description: newDescription,
layerList: JSON.stringify(layers),
mapState: JSON.stringify(mapState),
};
try {
await checkForDuplicateTitle(
Expand Down
49 changes: 42 additions & 7 deletions maps_dashboards/public/components/map_top_nav/top_nav_menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import React, { useCallback, useEffect, useState } from 'react';
import { SimpleSavedObject } from 'opensearch-dashboards/public';
import { IndexPattern } from '../../../../../src/plugins/data/public';
import { IndexPattern, Query, TimeRange } from '../../../../../src/plugins/data/public';
import { DASHBOARDS_MAPS_LAYER_TYPE, PLUGIN_ID } from '../../../common';
import { getTopNavConfig } from './get_top_nav_config';
import { useOpenSearchDashboards } from '../../../../../src/plugins/opensearch_dashboards_react/public';
Expand All @@ -14,13 +14,16 @@ import { MapSavedObjectAttributes } from '../../../common/map_saved_object_attri
import { getSavedMapBreadcrumbs } from '../../utils/breadcrumbs';
import { doDataLayerRender } from '../../model/DataLayerController';
import { MapLayerSpecification } from '../../model/mapLayerType';
import { MapState } from '../../model/mapState';

interface MapTopNavMenuProps {
mapIdFromUrl: string;
layers: any;
layers: MapLayerSpecification[];
savedMapObject: SimpleSavedObject<MapSavedObjectAttributes> | null | undefined;
layersIndexPatterns: IndexPattern[];
maplibreRef: any;
mapState: MapState;
setMapState: (mapState: MapState) => void;
}

export const MapTopNavMenu = ({
Expand All @@ -29,6 +32,8 @@ export const MapTopNavMenu = ({
layers,
layersIndexPatterns,
maplibreRef,
mapState,
setMapState,
}: MapTopNavMenuProps) => {
const { services } = useOpenSearchDashboards<MapServices>();
const {
Expand All @@ -42,7 +47,11 @@ export const MapTopNavMenu = ({

const [title, setTitle] = useState<string>('');
const [description, setDescription] = useState<string>('');

const [timeFrom, setTimeFrom] = useState<string>('');
const [timeTo, setTimeTo] = useState<string>('');
const [queryConfig, setQueryConfig] = useState<Query>({ query: '', language: 'kuery' });
const [refreshIntervalValue, setRefreshIntervalValue] = useState<number>(60000);
const [isRefreshPaused, setIsRefreshPaused] = useState<boolean>(false);
const changeTitle = useCallback(
(newTitle: string) => {
chrome.setBreadcrumbs(getSavedMapBreadcrumbs(newTitle, navigateToApp));
Expand All @@ -62,15 +71,33 @@ export const MapTopNavMenu = ({
changeTitle(title || 'Create');
}, [title, changeTitle]);

const handleRefresh = () => {
const refreshDataLayerRender = useCallback(() => {
layers.forEach((layer: MapLayerSpecification) => {
if (layer.type === DASHBOARDS_MAPS_LAYER_TYPE.OPENSEARCH_MAP) {
return;
}
doDataLayerRender(layer, services, layersIndexPatterns, maplibreRef);
doDataLayerRender(layer, mapState, services, maplibreRef);
});
}, [mapState]);

const handleQuerySubmit = ({ query, dateRange }: { query?: Query; dateRange: TimeRange }) => {
if (query) {
setMapState({ ...mapState, query });
}
if (dateRange) {
setMapState({ ...mapState, timeFilters: dateRange });
}
};

useEffect(() => {
setTimeFrom(mapState.timeFilters.from);
setTimeTo(mapState.timeFilters.to);
setQueryConfig(mapState.query);
setIsRefreshPaused(mapState.refreshInterval.pause);
setRefreshIntervalValue(mapState.refreshInterval.value);
refreshDataLayerRender();
}, [mapState, refreshDataLayerRender]);

return (
<TopNavMenu
appName={PLUGIN_ID}
Expand All @@ -81,15 +108,23 @@ export const MapTopNavMenu = ({
description,
setTitle,
setDescription,
mapState,
})}
setMenuMountPoint={setHeaderActionMenu}
indexPatterns={layersIndexPatterns || []}
showSearchBar
showFilterBar={false}
showDatePicker={true}
showSaveQuery
onQuerySubmit={handleRefresh}
showQueryBar={true}
showSaveQuery={true}
showQueryInput={true}
onQuerySubmit={handleQuerySubmit}
useDefaultBehaviors
dateRangeFrom={timeFrom}
dateRangeTo={timeTo}
query={queryConfig}
isRefreshPaused={isRefreshPaused}
refreshInterval={refreshIntervalValue}
/>
);
};
Loading

0 comments on commit 1b76052

Please sign in to comment.