forked from elastic/kibana
-
Notifications
You must be signed in to change notification settings - Fork 0
/
use_map_layers.tsx
75 lines (66 loc) · 2.47 KB
/
use_map_layers.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/*
* 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 { useEffect, useState } from 'react';
import {
MapLayerEventHandlers,
MapLayer,
OnDataLoadEndProps,
OnDataLoadErrorProps,
OnDataLoadProps,
} from '../types';
type Return = [boolean, MapLayer[], MapLayerEventHandlers];
export const mergeMapLayers = (
prevMapLayers: MapLayer[],
dataId: string,
layerId: string,
isLoading: boolean,
errorMessage = ''
) => {
if (prevMapLayers.find(ls => ls.layerId === layerId) === undefined) {
return [...prevMapLayers, { dataId, layerId, isLoading, errorMessage }];
} else {
return prevMapLayers.map<MapLayer>(ml => {
return ml.layerId === layerId
? { dataId: ml.dataId, layerId: ml.layerId, isLoading, errorMessage }
: ml;
});
}
};
export const isMapLoading = (mapLayers: MapLayer[]) =>
mapLayers.length !== 0 && mapLayers.some(ml => ml.isLoading);
/**
* Hook for keeping track of map layer state and when they are loading
*
* @returns
* isLoading: boolean of whether or not at least one layer is currently loading
* mapLayers: MapLayer[] current state of all layers
* mapLayerEventHandlers: MapLayerEventHandlers to pass into mapEmbeddableFactory.createFromState() to register handlers
*/
export const useMapLayers = (): Return => {
const [mapLayers, setMapLayers] = useState<MapLayer[]>([]);
const [isLoading, setIsLoading] = useState(false);
const eventHandlers: MapLayerEventHandlers = {
onDataLoad: ({ layerId, dataId }: OnDataLoadProps) => {
// TODO: Ask maps team why root layer is includes onDataLoad but not onDataLoadEnd
if (layerId.startsWith('root-layer')) {
return;
}
setMapLayers(prevMapLayers => mergeMapLayers(prevMapLayers, dataId, layerId, true));
},
onDataLoadEnd: ({ layerId, dataId, featuresCount }: OnDataLoadEndProps) => {
setMapLayers(prevMapLayers => mergeMapLayers(prevMapLayers, dataId, layerId, false));
},
onDataLoadError: ({ layerId, dataId, errorMessage }: OnDataLoadErrorProps) => {
setMapLayers(prevMapLayers =>
mergeMapLayers(prevMapLayers, dataId, layerId, false, errorMessage)
);
},
};
useEffect(() => {
setIsLoading(isMapLoading(mapLayers));
}, [setIsLoading(isMapLoading(mapLayers))]);
return [isLoading, mapLayers, eventHandlers];
};