datastake-daf 0.6.142 → 0.6.144

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16857,7 +16857,7 @@ function StakeholderIcon$1({
16857
16857
  const isSmall = isSmallMarker(zoom) || isExtraSmallMarker(zoom);
16858
16858
  const isMedium = isMediumMarker(zoom);
16859
16859
  const isSelected = React.useMemo(() => selectedMarkersId.includes(data.datastakeId), [selectedMarkersId, data.datastakeId]);
16860
- const isOpen = React.useMemo(() => openPopupIdRef.current === data.datastakeId, [openPopupIdRef.current, data.datastakeId]);
16860
+ React.useMemo(() => openPopupIdRef.current === data.datastakeId, [openPopupIdRef.current, data.datastakeId]);
16861
16861
  const linkNodesData = React.useMemo(() => {
16862
16862
  const nodes = [];
16863
16863
  const links = data.links || [];
@@ -16999,39 +16999,44 @@ function StakeholderIcon$1({
16999
16999
  });
17000
17000
  });
17001
17001
  }, [mapRef, x, y, parentData, linkNodesData, isSelected, zoom, isForceOpen]);
17002
- return /*#__PURE__*/jsxRuntime.jsx(antd.Popover, {
17003
- content: renderTooltipJsx({
17004
- title: data.name,
17005
- subTitle: data.subTitle,
17006
- total: data.sources,
17007
- className: "pt-0 pb-0",
17008
- items: renderTooltip(data),
17009
- link,
17010
- onClickLink: () => {
17011
- const popovers = document.querySelectorAll(".ant-popover");
17012
- popovers.forEach(popover => {
17013
- if (popover && popover.parentNode) {
17014
- popover.parentNode.removeChild(popover);
17015
- }
17016
- });
17017
- onClickLink(data);
17018
- }
17019
- }),
17020
- trigger: "click",
17021
- open: isOpen,
17022
- children: /*#__PURE__*/jsxRuntime.jsx(StakeholderMarker, {
17023
- className: `${data.type} ${isSelected ? "selected" : selectedMarkersId.length > 0 ? "unselected" : ""}
17002
+ return /*#__PURE__*/jsxRuntime.jsx(jsxRuntime.Fragment, {
17003
+ children: /*#__PURE__*/jsxRuntime.jsx(antd.Popover, {
17004
+ content: renderTooltipJsx({
17005
+ title: data.name,
17006
+ subTitle: data.subTitle,
17007
+ total: data.sources,
17008
+ className: "pt-0 pb-0",
17009
+ items: renderTooltip(data),
17010
+ link,
17011
+ onClickLink: () => {
17012
+ const popovers = document.querySelectorAll(".ant-popover");
17013
+ popovers.forEach(popover => {
17014
+ if (popover && popover.parentNode) {
17015
+ popover.parentNode.removeChild(popover);
17016
+ }
17017
+ });
17018
+ onClickLink(data);
17019
+ }
17020
+ })
17021
+ // trigger="click"
17022
+ // zIndex={1000}
17023
+ // open={isOpen}
17024
+ ,
17025
+ getPopupContainer: () => document.getElementById(data.datastakeId),
17026
+ children: /*#__PURE__*/jsxRuntime.jsx(StakeholderMarker, {
17027
+ className: `${data.type} ${isSelected ? "selected" : selectedMarkersId.length > 0 ? "unselected" : ""}
17024
17028
  ${isSmall ? "small" : isMedium ? "medium" : "large"}
17025
17029
  ${className}`,
17026
- onClick: () => handleSelectMarker(data),
17027
- style: {
17028
- opacity: isExtraSmallMarker(zoom) && !isForceOpen ? 0 : 1,
17029
- pointerEvents: isExtraSmallMarker(zoom) && !isForceOpen ? "none" : "auto"
17030
- },
17031
- children: !isSmall && /*#__PURE__*/jsxRuntime.jsx(CustomIcon, {
17032
- name: getStakeholderIcon(data?.type || ""),
17033
- size: isMedium ? 13 : 16,
17034
- color: !isSelected && selectedMarkersId.length > 0 ? "white" : "white"
17030
+ onClick: () => handleSelectMarker(data),
17031
+ style: {
17032
+ opacity: isExtraSmallMarker(zoom) && !isForceOpen ? 0 : 1,
17033
+ pointerEvents: isExtraSmallMarker(zoom) && !isForceOpen ? "none" : "auto"
17034
+ },
17035
+ children: !isSmall && /*#__PURE__*/jsxRuntime.jsx(CustomIcon, {
17036
+ name: getStakeholderIcon(data?.type || ""),
17037
+ size: isMedium ? 13 : 16,
17038
+ color: !isSelected && selectedMarkersId.length > 0 ? "white" : "white"
17039
+ })
17035
17040
  })
17036
17041
  })
17037
17042
  });
@@ -17091,7 +17096,7 @@ function LocationIcon({
17091
17096
  }, [data.stakeholders, zoom]);
17092
17097
  React.useEffect(() => {
17093
17098
  stakeholdersOfLocation.map((stakeholder, index) => {
17094
- const markerId = `${index}${stakeholder.datastakeId}`;
17099
+ const markerId = `${stakeholder.datastakeId}`;
17095
17100
  const {
17096
17101
  x,
17097
17102
  y,
@@ -17213,8 +17218,14 @@ function LocationIcon({
17213
17218
  items: renderTooltip(data),
17214
17219
  link,
17215
17220
  onClickLink: () => onClickLink(data)
17216
- }),
17217
- open: (!openPopupIdRef.current || openPopupIdRef.current === data.datastakeId) && isHovering,
17221
+ })
17222
+ // open={
17223
+ // (!openPopupIdRef.current || openPopupIdRef.current === data.datastakeId) &&
17224
+ // isHovering
17225
+ // }
17226
+ ,
17227
+
17228
+ getPopupContainer: () => document.getElementById("map"),
17218
17229
  children: /*#__PURE__*/jsxRuntime.jsxs("div", {
17219
17230
  style: {
17220
17231
  position: "relative",
@@ -17240,7 +17251,9 @@ function LocationIcon({
17240
17251
  },
17241
17252
  zoom: zoom,
17242
17253
  onMouseEnter: () => setIsHovering(true),
17243
- onMouseLeave: () => setIsHovering(false),
17254
+ onMouseLeave: () => {
17255
+ setIsHovering(false);
17256
+ },
17244
17257
  selectedMarkersId: selectedMarkersId
17245
17258
  })]
17246
17259
  })
@@ -17945,7 +17958,6 @@ const useMap$1 = ({
17945
17958
  handleSelectMarker
17946
17959
  });
17947
17960
  function handleSelectMarker(clickedMarker) {
17948
- destroyAllPopovers();
17949
17961
  setSelectedMarkersId(prev => {
17950
17962
  if (prev.includes(clickedMarker.datastakeId)) {
17951
17963
  openPopupIdRef.current = null;
@@ -17967,14 +17979,14 @@ const useMap$1 = ({
17967
17979
  setMarkerWithPopup(null);
17968
17980
  }
17969
17981
  function destroyAllPopovers() {
17970
- if (isStakeholder(markerWithPopup?.type)) {
17971
- const popovers = document.querySelectorAll(".ant-popover");
17972
- popovers.forEach(popover => {
17973
- if (popover && popover.parentNode) {
17974
- popover.parentNode.removeChild(popover);
17975
- }
17976
- });
17977
- }
17982
+ // if (isStakeholder(markerWithPopup?.type)) {
17983
+ // const popovers = document.querySelectorAll(".ant-popover");
17984
+ // popovers.forEach((popover) => {
17985
+ // if (popover && popover.parentNode) {
17986
+ // popover.parentNode.removeChild(popover);
17987
+ // }
17988
+ // });
17989
+ // }
17978
17990
  }
17979
17991
  const addAllDataToMap = () => {
17980
17992
  if (type === "chain" && markerWithPopup && isStakeholder(markerWithPopup?.type)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "datastake-daf",
3
- "version": "0.6.142",
3
+ "version": "0.6.144",
4
4
  "dependencies": {
5
5
  "@ant-design/icons": "^5.2.5",
6
6
  "@antv/g2": "^5.1.1",
@@ -221,48 +221,53 @@ export default function StakeholderIcon({
221
221
  }, [mapRef, x, y, parentData, linkNodesData, isSelected, zoom, isForceOpen]);
222
222
 
223
223
  return (
224
- <Popover
225
- content={renderTooltipJsx({
226
- title: data.name,
227
- subTitle: data.subTitle,
228
- total: data.sources,
229
- className: "pt-0 pb-0",
230
- items: renderTooltip(data),
231
- link,
232
- onClickLink: () => {
233
- const popovers = document.querySelectorAll(".ant-popover");
224
+ <>
225
+ <Popover
226
+ content={renderTooltipJsx({
227
+ title: data.name,
228
+ subTitle: data.subTitle,
229
+ total: data.sources,
230
+ className: "pt-0 pb-0",
231
+ items: renderTooltip(data),
232
+ link,
233
+ onClickLink: () => {
234
+ const popovers = document.querySelectorAll(".ant-popover");
234
235
 
235
- popovers.forEach((popover) => {
236
- if (popover && popover.parentNode) {
237
- popover.parentNode.removeChild(popover);
238
- }
239
- });
240
- onClickLink(data);
241
- },
242
- })}
243
- trigger="click"
244
- open={isOpen}
245
- >
246
- <StakeholderMarker
247
- className={`${data.type} ${
248
- isSelected ? "selected" : selectedMarkersId.length > 0 ? "unselected" : ""
249
- }
236
+ popovers.forEach((popover) => {
237
+ if (popover && popover.parentNode) {
238
+ popover.parentNode.removeChild(popover);
239
+ }
240
+ });
241
+ onClickLink(data);
242
+ },
243
+ })}
244
+ // trigger="click"
245
+ // zIndex={1000}
246
+ // open={isOpen}
247
+ getPopupContainer={() => document.getElementById(data.datastakeId)}
248
+ >
249
+ <StakeholderMarker
250
+ className={`${data.type} ${
251
+ isSelected ? "selected" : selectedMarkersId.length > 0 ? "unselected" : ""
252
+ }
250
253
  ${isSmall ? "small" : isMedium ? "medium" : "large"}
251
254
  ${className}`}
252
- onClick={() => handleSelectMarker(data)}
253
- style={{
254
- opacity: isExtraSmallMarker(zoom) && !isForceOpen ? 0 : 1,
255
- pointerEvents: isExtraSmallMarker(zoom) && !isForceOpen ? "none" : "auto",
256
- }}
257
- >
258
- {!isSmall && (
259
- <CustomIcon
260
- name={getStakeholderIcon(data?.type || "")}
261
- size={isMedium ? 13 : 16}
262
- color={!isSelected && selectedMarkersId.length > 0 ? "white" : "white"}
263
- />
264
- )}
265
- </StakeholderMarker>
266
- </Popover>
255
+ onClick={() => handleSelectMarker(data)}
256
+ style={{
257
+ opacity: isExtraSmallMarker(zoom) && !isForceOpen ? 0 : 1,
258
+ pointerEvents: isExtraSmallMarker(zoom) && !isForceOpen ? "none" : "auto",
259
+ }}
260
+ >
261
+ {!isSmall && (
262
+ <CustomIcon
263
+ name={getStakeholderIcon(data?.type || "")}
264
+ size={isMedium ? 13 : 16}
265
+ color={!isSelected && selectedMarkersId.length > 0 ? "white" : "white"}
266
+ />
267
+ )}
268
+ </StakeholderMarker>
269
+ </Popover>
270
+ {/* <div id="ant-popover-container-custom" style={{ zIndex: 1000, position: "relative" }} /> */}
271
+ </>
267
272
  );
268
273
  }
@@ -75,7 +75,7 @@ export default function LocationIcon({
75
75
 
76
76
  useEffect(() => {
77
77
  stakeholdersOfLocation.map((stakeholder, index) => {
78
- const markerId = `${index}${stakeholder.datastakeId}`;
78
+ const markerId = `${stakeholder.datastakeId}`;
79
79
  const { x, y, radius, center } = getStakeholderPosition({
80
80
  zoom,
81
81
  totalMarkers: stakeholdersOfLocation.length,
@@ -208,10 +208,12 @@ export default function LocationIcon({
208
208
  link,
209
209
  onClickLink: () => onClickLink(data),
210
210
  })}
211
- open={
212
- (!openPopupIdRef.current || openPopupIdRef.current === data.datastakeId) &&
213
- isHovering
214
- }
211
+ // open={
212
+ // (!openPopupIdRef.current || openPopupIdRef.current === data.datastakeId) &&
213
+ // isHovering
214
+ // }
215
+
216
+ getPopupContainer={() => document.getElementById("map")}
215
217
  >
216
218
  <div style={{ position: "relative", display: "inline-block" }}>
217
219
  {(isSelected || selectedMarkersId.length === 0) && (
@@ -237,7 +239,9 @@ export default function LocationIcon({
237
239
  }}
238
240
  zoom={zoom}
239
241
  onMouseEnter={() => setIsHovering(true)}
240
- onMouseLeave={() => setIsHovering(false)}
242
+ onMouseLeave={() => {
243
+ setIsHovering(false);
244
+ }}
241
245
  selectedMarkersId={selectedMarkersId}
242
246
  />
243
247
  </div>
@@ -2,371 +2,361 @@ import * as L from "leaflet";
2
2
  import { useEffect, useState, createRef, useMemo, useRef } from "react";
3
3
 
4
4
  import {
5
- defaultMapConfig,
6
- filterValidGPS,
7
- findCoordinatesByCountry,
8
- SET_VIEW_DEFAULT_ZOOM,
9
- useMapConfig,
5
+ defaultMapConfig,
6
+ filterValidGPS,
7
+ findCoordinatesByCountry,
8
+ SET_VIEW_DEFAULT_ZOOM,
9
+ useMapConfig,
10
10
  } from "../../../../hooks/useMapHelper";
11
11
  import { useMapHelper } from "./helper";
12
12
  import { isLocation, isStakeholder } from "./ChainIcon/utils";
13
13
 
14
14
  export const useMap = ({
15
- type,
16
- data: allData = null,
17
- user = null,
18
- polygon,
19
- app,
20
- renderTooltip,
21
- mapConfig,
22
- tooltipAsText,
23
- renderMarker,
24
- onClickLink,
25
- link,
26
- isSatellite = false,
15
+ type,
16
+ data: allData = null,
17
+ user = null,
18
+ polygon,
19
+ app,
20
+ renderTooltip,
21
+ mapConfig,
22
+ tooltipAsText,
23
+ renderMarker,
24
+ onClickLink,
25
+ link,
26
+ isSatellite = false,
27
27
  }) => {
28
- const container = createRef();
29
- const [data, setData] = useState([]);
30
- const [mapRef, setMapRef] = useState(null);
31
- const { TILE_LAYER_URL, MAP_TOKEN } = useMapConfig({ app, isSatellite });
32
- const [initialMarkerSetIsDone, setInitialMarkerSetIsDone] = useState(false);
33
- const [mapCenter, setMapCenter] = useState([0, 0]);
34
- const [emptyStateIsVisible, setEmptyStateIsVisible] = useState(false);
35
- const [polygonLayer, setPolygonLayer] = useState();
36
- const [zoom, setZoom] = useState(SET_VIEW_DEFAULT_ZOOM);
37
- const [selectedMarkersId, setSelectedMarkersId] = useState([]);
38
- const openPopupIdRef = useRef(null);
39
- const [markerWithPopup, setMarkerWithPopup] = useState(null);
40
-
41
- // USED TO GENERATE HIGHLIGHT TABLE
42
- const highlightTable = useMemo(() => {
43
- if (!data || type !== "chain") return {};
44
- const graph = new Map();
45
- const stakeToLoc = new Map();
46
- const nodeTypes = new Map();
47
-
48
- for (const loc of data) {
49
- const locId = loc.datastakeId;
50
- nodeTypes.set(locId, loc.type);
51
-
52
- if (!graph.has(locId)) graph.set(locId, new Set());
53
-
54
- for (const stk of loc.stakeholders || []) {
55
- const stkId = stk.datastakeId;
56
- nodeTypes.set(stkId, stk.type);
57
-
58
- stakeToLoc.set(stkId, locId);
59
-
60
- if (!graph.has(stkId)) graph.set(stkId, new Set());
61
-
62
- graph.get(stkId).add(locId);
63
- graph.get(locId).add(stkId);
64
-
65
- for (const target of stk.links || []) {
66
- if (!graph.has(target)) graph.set(target, new Set());
67
- graph.get(stkId).add(target);
68
- graph.get(target).add(stkId);
69
- }
70
- }
71
-
72
- for (const target of loc.links || []) {
73
- if (!graph.has(target)) graph.set(target, new Set());
74
- graph.get(locId).add(target);
75
- graph.get(target).add(locId);
76
- }
77
- }
78
-
79
- const highlightTable = {};
80
-
81
- for (const [node] of graph) {
82
- const visited = new Set();
83
- const queue = [node];
84
-
85
- while (queue.length) {
86
- const current = queue.shift();
87
- if (visited.has(current)) continue;
88
-
89
- const currentType = nodeTypes.get(current);
90
-
91
- if (current !== node && isLocation(currentType)) continue;
92
-
93
- visited.add(current);
94
-
95
- for (const neighbor of graph.get(current)) {
96
- if (!visited.has(neighbor)) queue.push(neighbor);
97
- }
98
- }
99
-
100
- if (!isLocation(nodeTypes.get(node)) && stakeToLoc.has(node)) {
101
- visited.add(stakeToLoc.get(node));
102
- }
103
-
104
- visited.add(node);
105
-
106
- const extraLocs = new Set();
107
- for (const n of visited) {
108
- for (const neighbor of graph.get(n) || []) {
109
- if (isLocation(nodeTypes.get(neighbor))) {
110
- extraLocs.add(neighbor);
111
- }
112
- }
113
- }
114
- for (const loc of extraLocs) {
115
- visited.add(loc);
116
- }
117
-
118
- highlightTable[node] = [...visited];
119
- }
120
-
121
- return highlightTable;
122
- }, [data, type]);
123
-
124
- const {
125
- addIconToMapInitialy,
126
- activeMarker,
127
- mapOptionsButtonsConfig,
128
- mapMarkers,
129
- clearMapMarkers,
130
- getZoom,
131
- polylinesRef,
132
- activeStakeholder,
133
- setActiveMarker,
134
- } = useMapHelper({
135
- mapRef,
136
- allData,
137
- mapCenter,
138
- renderTooltip,
139
- onClickLink,
140
- link,
141
- tooltipAsText,
142
- renderMarker,
143
- type,
144
- zoom,
145
- selectedMarkersId,
146
- openPopupIdRef,
147
- handleSelectMarker,
148
- });
149
-
150
- function handleSelectMarker(clickedMarker) {
151
- destroyAllPopovers();
152
- setSelectedMarkersId((prev) => {
153
- if (prev.includes(clickedMarker.datastakeId)) {
154
- openPopupIdRef.current = null;
155
- setMarkerWithPopup(null);
156
- return [];
157
- } else {
158
- setMarkerWithPopup(
159
- isStakeholder(clickedMarker.type) ? clickedMarker : null
160
- );
161
- const newSelectedMarkersId = highlightTable[clickedMarker.datastakeId];
162
- openPopupIdRef.current = clickedMarker.datastakeId;
163
- return newSelectedMarkersId;
164
- }
165
- });
166
- }
167
-
168
- function handleZoomChange() {
169
- openPopupIdRef.current = null;
170
- const zoom = mapRef.getZoom();
171
- setZoom(zoom);
172
- setActiveMarker(null);
173
- setMarkerWithPopup(null);
174
- }
175
-
176
- function destroyAllPopovers() {
177
- if (isStakeholder(markerWithPopup?.type)) {
178
- const popovers = document.querySelectorAll(".ant-popover");
179
-
180
- popovers.forEach((popover) => {
181
- if (popover && popover.parentNode) {
182
- popover.parentNode.removeChild(popover);
183
- }
184
- });
185
- }
186
- }
187
-
188
- const addAllDataToMap = () => {
189
- if (
190
- type === "chain" &&
191
- markerWithPopup &&
192
- isStakeholder(markerWithPopup?.type)
193
- ) {
194
- // destroyAllPopovers();
195
- if (polylinesRef.current.length) {
196
- polylinesRef.current.forEach((polyline) => {
197
- mapRef.removeLayer(polyline);
198
- });
199
- }
200
- }
201
- clearMapMarkers();
202
- if (data) {
203
- const maxTotal = Math.max(...(data || []).map((d) => d.total));
204
- data.forEach((d, i) => {
205
- addIconToMapInitialy(
206
- [d?.marker?.lat, d?.marker?.lng],
207
- "location",
208
- d.category || "mineSite",
209
- d,
210
- maxTotal,
211
- i
212
- );
213
- });
214
-
215
- polylinesRef.current.forEach((polyline) => {
216
- mapRef.addLayer(polyline);
217
- });
218
-
219
- mapRef.invalidateSize();
220
- mapRef.fire("moveend");
221
- }
222
- };
223
-
224
- const createInstance = () => {
225
- const c = L.DomUtil.get(document.getElementById(container.current));
226
- if (c != null) {
227
- c._leaflet_id = null;
228
- }
229
-
230
- const map = L.map(container.current, {
231
- ...defaultMapConfig,
232
- ...(mapConfig || {}),
233
- });
234
- return map;
235
- };
236
-
237
- useEffect(() => {
238
- if (initialMarkerSetIsDone) {
239
- setInitialMarkerSetIsDone(undefined);
240
- }
241
- }, []);
242
-
243
- useEffect(() => {
244
- if (!mapRef) {
245
- const instance = createInstance();
246
- setMapRef(instance);
247
- }
248
- }, []);
249
-
250
- useEffect(() => {
251
- if (mapRef) {
252
- if (polygonLayer) {
253
- mapRef.removeLayer(polygonLayer);
254
- }
255
-
256
- if (Array.isArray(polygon)) {
257
- const layer = L.polygon(polygon, { color: "#00809E" }).addTo(mapRef);
258
- setPolygonLayer(layer);
259
- }
260
- }
261
- }, [polygon, mapRef]);
262
-
263
- useEffect(() => {
264
- if (allData) {
265
- if (allData.length === 0) {
266
- setEmptyStateIsVisible(true);
267
- } else if (emptyStateIsVisible) {
268
- setEmptyStateIsVisible(false);
269
- }
270
- setData(filterValidGPS(allData));
271
- } else {
272
- if (data) {
273
- setData(null);
274
- }
275
- }
276
- }, [allData]);
277
-
278
- useEffect(() => {
279
- if (allData) {
280
- setData(filterValidGPS(allData));
281
- }
282
- }, [allData]);
283
-
284
- useEffect(() => {
285
- if (mapRef) {
286
- L.control.scale().addTo(mapRef);
287
- L.tileLayer(TILE_LAYER_URL, { access_token: MAP_TOKEN }).addTo(mapRef);
288
- }
289
- }, [mapRef]);
290
-
291
- useEffect(() => {
292
- if (mapRef) {
293
- if (type === "chain") {
294
- mapRef.on("zoomend", handleZoomChange);
295
- mapRef.on("movestart", destroyAllPopovers);
296
- }
297
- }
298
-
299
- return () => {
300
- if (mapRef) {
301
- if (type === "chain") {
302
- mapRef.off("zoomend", handleZoomChange);
303
- mapRef.off("movestart", destroyAllPopovers);
304
- }
305
- }
306
- };
307
- }, [mapRef, markerWithPopup]);
308
-
309
- useEffect(() => {
310
- if (mapRef) {
311
- if (allData && allData.length) {
312
- const pos = allData.map((m) =>
313
- Array.isArray(m.area)
314
- ? m.area
315
- : [Number(m.marker?.lat ?? 0), Number(m.marker?.lng ?? 0)]
316
- );
317
- const bounds = new L.LatLngBounds(pos);
318
- mapRef.fitBounds(bounds, { padding: [20, 20] });
319
- }
320
- }
321
- }, [allData, mapRef]);
322
-
323
- useEffect(() => {
324
- if (mapRef) {
325
- if (user && !(allData || []).length) {
326
- const coordinates = findCoordinatesByCountry(user.country) || [0, 0];
327
- mapRef.setView([coordinates[1], coordinates[0]], SET_VIEW_DEFAULT_ZOOM);
328
- setMapCenter([coordinates[1], coordinates[0]]);
329
- }
330
- }
331
- }, [user, mapRef]);
332
-
333
- useEffect(() => {
334
- if (mapRef && data) {
335
- if (!initialMarkerSetIsDone) {
336
- setInitialMarkerSetIsDone(true);
337
- } else {
338
- clearMapMarkers();
339
- }
340
- addAllDataToMap();
341
- }
342
- }, [
343
- data,
344
- mapRef,
345
- zoom,
346
- selectedMarkersId,
347
- markerWithPopup,
348
- openPopupIdRef.current,
349
- polylinesRef.current.length,
350
- activeStakeholder,
351
- ]);
352
-
353
- useEffect(() => {
354
- const marker = mapMarkers.find((m) => m.id === activeMarker);
355
- if (getZoom && marker && mapRef) {
356
- mapRef.setView(
357
- [marker.coordinates[0], marker.coordinates[1]],
358
- getZoom(mapRef)
359
- );
360
- }
361
- }, [activeMarker, mapRef]);
362
-
363
- return {
364
- container,
365
- activeMarker,
366
- mapOptionsButtonsConfig,
367
- emptyStateIsVisible,
368
- setEmptyStateIsVisible,
369
- zoom,
370
- setZoom,
371
- };
28
+ const container = createRef();
29
+ const [data, setData] = useState([]);
30
+ const [mapRef, setMapRef] = useState(null);
31
+ const { TILE_LAYER_URL, MAP_TOKEN } = useMapConfig({ app, isSatellite });
32
+ const [initialMarkerSetIsDone, setInitialMarkerSetIsDone] = useState(false);
33
+ const [mapCenter, setMapCenter] = useState([0, 0]);
34
+ const [emptyStateIsVisible, setEmptyStateIsVisible] = useState(false);
35
+ const [polygonLayer, setPolygonLayer] = useState();
36
+ const [zoom, setZoom] = useState(SET_VIEW_DEFAULT_ZOOM);
37
+ const [selectedMarkersId, setSelectedMarkersId] = useState([]);
38
+ const openPopupIdRef = useRef(null);
39
+ const [markerWithPopup, setMarkerWithPopup] = useState(null);
40
+
41
+ // USED TO GENERATE HIGHLIGHT TABLE
42
+ const highlightTable = useMemo(() => {
43
+ if (!data || type !== "chain") return {};
44
+ const graph = new Map();
45
+ const stakeToLoc = new Map();
46
+ const nodeTypes = new Map();
47
+
48
+ for (const loc of data) {
49
+ const locId = loc.datastakeId;
50
+ nodeTypes.set(locId, loc.type);
51
+
52
+ if (!graph.has(locId)) graph.set(locId, new Set());
53
+
54
+ for (const stk of loc.stakeholders || []) {
55
+ const stkId = stk.datastakeId;
56
+ nodeTypes.set(stkId, stk.type);
57
+
58
+ stakeToLoc.set(stkId, locId);
59
+
60
+ if (!graph.has(stkId)) graph.set(stkId, new Set());
61
+
62
+ graph.get(stkId).add(locId);
63
+ graph.get(locId).add(stkId);
64
+
65
+ for (const target of stk.links || []) {
66
+ if (!graph.has(target)) graph.set(target, new Set());
67
+ graph.get(stkId).add(target);
68
+ graph.get(target).add(stkId);
69
+ }
70
+ }
71
+
72
+ for (const target of loc.links || []) {
73
+ if (!graph.has(target)) graph.set(target, new Set());
74
+ graph.get(locId).add(target);
75
+ graph.get(target).add(locId);
76
+ }
77
+ }
78
+
79
+ const highlightTable = {};
80
+
81
+ for (const [node] of graph) {
82
+ const visited = new Set();
83
+ const queue = [node];
84
+
85
+ while (queue.length) {
86
+ const current = queue.shift();
87
+ if (visited.has(current)) continue;
88
+
89
+ const currentType = nodeTypes.get(current);
90
+
91
+ if (current !== node && isLocation(currentType)) continue;
92
+
93
+ visited.add(current);
94
+
95
+ for (const neighbor of graph.get(current)) {
96
+ if (!visited.has(neighbor)) queue.push(neighbor);
97
+ }
98
+ }
99
+
100
+ if (!isLocation(nodeTypes.get(node)) && stakeToLoc.has(node)) {
101
+ visited.add(stakeToLoc.get(node));
102
+ }
103
+
104
+ visited.add(node);
105
+
106
+ const extraLocs = new Set();
107
+ for (const n of visited) {
108
+ for (const neighbor of graph.get(n) || []) {
109
+ if (isLocation(nodeTypes.get(neighbor))) {
110
+ extraLocs.add(neighbor);
111
+ }
112
+ }
113
+ }
114
+ for (const loc of extraLocs) {
115
+ visited.add(loc);
116
+ }
117
+
118
+ highlightTable[node] = [...visited];
119
+ }
120
+
121
+ return highlightTable;
122
+ }, [data, type]);
123
+
124
+ const {
125
+ addIconToMapInitialy,
126
+ activeMarker,
127
+ mapOptionsButtonsConfig,
128
+ mapMarkers,
129
+ clearMapMarkers,
130
+ getZoom,
131
+ polylinesRef,
132
+ activeStakeholder,
133
+ setActiveMarker,
134
+ } = useMapHelper({
135
+ mapRef,
136
+ allData,
137
+ mapCenter,
138
+ renderTooltip,
139
+ onClickLink,
140
+ link,
141
+ tooltipAsText,
142
+ renderMarker,
143
+ type,
144
+ zoom,
145
+ selectedMarkersId,
146
+ openPopupIdRef,
147
+ handleSelectMarker,
148
+ });
149
+
150
+ function handleSelectMarker(clickedMarker) {
151
+ destroyAllPopovers();
152
+ setSelectedMarkersId((prev) => {
153
+ if (prev.includes(clickedMarker.datastakeId)) {
154
+ openPopupIdRef.current = null;
155
+ setMarkerWithPopup(null);
156
+ return [];
157
+ } else {
158
+ setMarkerWithPopup(isStakeholder(clickedMarker.type) ? clickedMarker : null);
159
+ const newSelectedMarkersId = highlightTable[clickedMarker.datastakeId];
160
+ openPopupIdRef.current = clickedMarker.datastakeId;
161
+ return newSelectedMarkersId;
162
+ }
163
+ });
164
+ }
165
+
166
+ function handleZoomChange() {
167
+ openPopupIdRef.current = null;
168
+ const zoom = mapRef.getZoom();
169
+ setZoom(zoom);
170
+ setActiveMarker(null);
171
+ setMarkerWithPopup(null);
172
+ }
173
+
174
+ function destroyAllPopovers() {
175
+ // if (isStakeholder(markerWithPopup?.type)) {
176
+ // const popovers = document.querySelectorAll(".ant-popover");
177
+ // popovers.forEach((popover) => {
178
+ // if (popover && popover.parentNode) {
179
+ // popover.parentNode.removeChild(popover);
180
+ // }
181
+ // });
182
+ // }
183
+ }
184
+
185
+ const addAllDataToMap = () => {
186
+ if (type === "chain" && markerWithPopup && isStakeholder(markerWithPopup?.type)) {
187
+ // destroyAllPopovers();
188
+ if (polylinesRef.current.length) {
189
+ polylinesRef.current.forEach((polyline) => {
190
+ mapRef.removeLayer(polyline);
191
+ });
192
+ }
193
+ }
194
+ clearMapMarkers();
195
+ if (data) {
196
+ const maxTotal = Math.max(...(data || []).map((d) => d.total));
197
+ data.forEach((d, i) => {
198
+ addIconToMapInitialy(
199
+ [d?.marker?.lat, d?.marker?.lng],
200
+ "location",
201
+ d.category || "mineSite",
202
+ d,
203
+ maxTotal,
204
+ i,
205
+ );
206
+ });
207
+
208
+ polylinesRef.current.forEach((polyline) => {
209
+ mapRef.addLayer(polyline);
210
+ });
211
+
212
+ mapRef.invalidateSize();
213
+ mapRef.fire("moveend");
214
+ }
215
+ };
216
+
217
+ const createInstance = () => {
218
+ const c = L.DomUtil.get(document.getElementById(container.current));
219
+ if (c != null) {
220
+ c._leaflet_id = null;
221
+ }
222
+
223
+ const map = L.map(container.current, {
224
+ ...defaultMapConfig,
225
+ ...(mapConfig || {}),
226
+ });
227
+ return map;
228
+ };
229
+
230
+ useEffect(() => {
231
+ if (initialMarkerSetIsDone) {
232
+ setInitialMarkerSetIsDone(undefined);
233
+ }
234
+ }, []);
235
+
236
+ useEffect(() => {
237
+ if (!mapRef) {
238
+ const instance = createInstance();
239
+ setMapRef(instance);
240
+ }
241
+ }, []);
242
+
243
+ useEffect(() => {
244
+ if (mapRef) {
245
+ if (polygonLayer) {
246
+ mapRef.removeLayer(polygonLayer);
247
+ }
248
+
249
+ if (Array.isArray(polygon)) {
250
+ const layer = L.polygon(polygon, { color: "#00809E" }).addTo(mapRef);
251
+ setPolygonLayer(layer);
252
+ }
253
+ }
254
+ }, [polygon, mapRef]);
255
+
256
+ useEffect(() => {
257
+ if (allData) {
258
+ if (allData.length === 0) {
259
+ setEmptyStateIsVisible(true);
260
+ } else if (emptyStateIsVisible) {
261
+ setEmptyStateIsVisible(false);
262
+ }
263
+ setData(filterValidGPS(allData));
264
+ } else {
265
+ if (data) {
266
+ setData(null);
267
+ }
268
+ }
269
+ }, [allData]);
270
+
271
+ useEffect(() => {
272
+ if (allData) {
273
+ setData(filterValidGPS(allData));
274
+ }
275
+ }, [allData]);
276
+
277
+ useEffect(() => {
278
+ if (mapRef) {
279
+ L.control.scale().addTo(mapRef);
280
+ L.tileLayer(TILE_LAYER_URL, { access_token: MAP_TOKEN }).addTo(mapRef);
281
+ }
282
+ }, [mapRef]);
283
+
284
+ useEffect(() => {
285
+ if (mapRef) {
286
+ if (type === "chain") {
287
+ mapRef.on("zoomend", handleZoomChange);
288
+ mapRef.on("movestart", destroyAllPopovers);
289
+ }
290
+ }
291
+
292
+ return () => {
293
+ if (mapRef) {
294
+ if (type === "chain") {
295
+ mapRef.off("zoomend", handleZoomChange);
296
+ mapRef.off("movestart", destroyAllPopovers);
297
+ }
298
+ }
299
+ };
300
+ }, [mapRef, markerWithPopup]);
301
+
302
+ useEffect(() => {
303
+ if (mapRef) {
304
+ if (allData && allData.length) {
305
+ const pos = allData.map((m) =>
306
+ Array.isArray(m.area)
307
+ ? m.area
308
+ : [Number(m.marker?.lat ?? 0), Number(m.marker?.lng ?? 0)],
309
+ );
310
+ const bounds = new L.LatLngBounds(pos);
311
+ mapRef.fitBounds(bounds, { padding: [20, 20] });
312
+ }
313
+ }
314
+ }, [allData, mapRef]);
315
+
316
+ useEffect(() => {
317
+ if (mapRef) {
318
+ if (user && !(allData || []).length) {
319
+ const coordinates = findCoordinatesByCountry(user.country) || [0, 0];
320
+ mapRef.setView([coordinates[1], coordinates[0]], SET_VIEW_DEFAULT_ZOOM);
321
+ setMapCenter([coordinates[1], coordinates[0]]);
322
+ }
323
+ }
324
+ }, [user, mapRef]);
325
+
326
+ useEffect(() => {
327
+ if (mapRef && data) {
328
+ if (!initialMarkerSetIsDone) {
329
+ setInitialMarkerSetIsDone(true);
330
+ } else {
331
+ clearMapMarkers();
332
+ }
333
+ addAllDataToMap();
334
+ }
335
+ }, [
336
+ data,
337
+ mapRef,
338
+ zoom,
339
+ selectedMarkersId,
340
+ markerWithPopup,
341
+ openPopupIdRef.current,
342
+ polylinesRef.current.length,
343
+ activeStakeholder,
344
+ ]);
345
+
346
+ useEffect(() => {
347
+ const marker = mapMarkers.find((m) => m.id === activeMarker);
348
+ if (getZoom && marker && mapRef) {
349
+ mapRef.setView([marker.coordinates[0], marker.coordinates[1]], getZoom(mapRef));
350
+ }
351
+ }, [activeMarker, mapRef]);
352
+
353
+ return {
354
+ container,
355
+ activeMarker,
356
+ mapOptionsButtonsConfig,
357
+ emptyStateIsVisible,
358
+ setEmptyStateIsVisible,
359
+ zoom,
360
+ setZoom,
361
+ };
372
362
  };