datastake-daf 0.6.772 → 0.6.774

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.
@@ -7570,6 +7570,8 @@ const Style$e = styled__default["default"].div`
7570
7570
  width: 100%;
7571
7571
  height: 472px;
7572
7572
 
7573
+
7574
+
7573
7575
  .filter-cont {
7574
7576
  position: absolute;
7575
7577
  top: 24px;
@@ -7672,11 +7674,24 @@ const Style$e = styled__default["default"].div`
7672
7674
  align-items: center;
7673
7675
  }
7674
7676
 
7675
- .marker-chain {
7676
- display: flex;
7677
- align-items: center;
7678
- justify-content: center;
7679
- }
7677
+ .marker-chain {
7678
+ display: flex;
7679
+ align-items: center;
7680
+ justify-content: center;
7681
+ }
7682
+
7683
+ .animated-polyline {
7684
+ stroke-dasharray: 10 10;
7685
+ animation: dash-flow 1.5s linear infinite;
7686
+ stroke-linecap: round;
7687
+ }
7688
+
7689
+ @keyframes dash-flow {
7690
+ to {
7691
+ stroke-dashoffset: -20;
7692
+ }
7693
+ }
7694
+
7680
7695
 
7681
7696
  }
7682
7697
 
@@ -8200,18 +8215,15 @@ const VILLAGE = "village";
8200
8215
  const EXPORTER = "exporter";
8201
8216
  const PROCESSOR = "mineralProcessor";
8202
8217
  const DEPOT = "depot";
8218
+ const OPERATOR = "miningOperator";
8203
8219
  const MAX_EXTRA_SMALL_ZOOM_THRESHOLD = 2;
8204
8220
  const MAX_SMALL_ZOOM_THRESHOLD = 3;
8205
8221
  const MAX_MEDIUM_ZOOM_THRESHOLD = 6;
8206
8222
  const LOCATION_TYPES = [MINE_SITE, VILLAGE];
8207
- const STAKEHOLDER_TYPES = [EXPORTER, PROCESSOR, DEPOT];
8223
+ const STAKEHOLDER_TYPES = [EXPORTER, PROCESSOR, DEPOT, OPERATOR];
8208
8224
  const RADIUS_SMALL = 15;
8209
8225
  const RADIUS_MEDIUM = 35;
8210
8226
  const RADIUS_LARGE = 60;
8211
- const RADIUS_CURVE_SMALL = 10;
8212
- const RADIUS_CURVE_MEDIUM = 15;
8213
- const RADIUS_CURVE_LARGE = 20;
8214
- const TENSION = 0.2;
8215
8227
  function isLocation(type) {
8216
8228
  return LOCATION_TYPES.includes(type);
8217
8229
  }
@@ -8268,7 +8280,6 @@ function getStakeholderPosition({
8268
8280
  const isLarge = isLargeMarker(zoom);
8269
8281
  let radius;
8270
8282
  let center = {
8271
- // NOT BEING USED FOR NOW AND MAYBE NEVER
8272
8283
  left: 0,
8273
8284
  top: 0
8274
8285
  };
@@ -8292,6 +8303,25 @@ function getStakeholderPosition({
8292
8303
  angleDeg
8293
8304
  };
8294
8305
  }
8306
+ function applyAnimationDirect(el, isShortLink) {
8307
+ if (!(el instanceof SVGElement) || isShortLink) return;
8308
+ el.style.strokeDasharray = "10, 10";
8309
+ el.style.strokeDashoffset = "0";
8310
+ el.style.animation = "dash-flow 1.2s linear infinite";
8311
+ el.classList.add('animated-polyline');
8312
+ }
8313
+ function removeAnimationFromElement(element) {
8314
+ if (!element) return;
8315
+ element.classList.remove('animated-polyline');
8316
+ element.style.animation = '';
8317
+ element.style.strokeDasharray = '';
8318
+ }
8319
+ function applyAnimationToPolyline(polyline, isShortLink) {
8320
+ const element = polyline.getElement();
8321
+ if (element) {
8322
+ applyAnimationDirect(element, isShortLink);
8323
+ }
8324
+ }
8295
8325
  function createPolyline({
8296
8326
  L,
8297
8327
  startLatLng,
@@ -8301,109 +8331,47 @@ function createPolyline({
8301
8331
  zoom,
8302
8332
  listOfPolylines = [],
8303
8333
  isFromStakeholder = false,
8304
- isForceOpen = false
8334
+ isForceOpen = false,
8335
+ stakeholderType = null,
8336
+ animated = false,
8337
+ mapRef
8305
8338
  }) {
8306
- const width = isFromStakeholder && isExtraSmallMarker(zoom) && !isForceOpen ? 0 : 1.2;
8307
- const coordinates = [[startLatLng.lat, startLatLng.lng], [endLatLng.lat, endLatLng.lng]];
8308
- const style = {
8339
+ const lineWidth = isFromStakeholder && isExtraSmallMarker(zoom) && !isForceOpen ? 0 : 1.2;
8340
+ const isShortLink = stakeholderType === OPERATOR || isFromStakeholder;
8341
+ const shouldAnimate = animated;
8342
+ const lineCoordinates = [[startLatLng.lat, startLatLng.lng], [endLatLng.lat, endLatLng.lng]];
8343
+ const polylineStyle = {
8309
8344
  color: "var(--base-gray-70)",
8310
- weight: width,
8311
- opacity: 0.5,
8312
- smoothFactor: 1,
8345
+ weight: lineWidth,
8346
+ opacity: isSelected ? 1 : 0.5,
8347
+ smoothFactor: 0,
8313
8348
  id,
8314
- dashArray: !isSelected ? "5, 5" : "0, 0"
8349
+ dashArray: isShortLink ? "0, 0" : shouldAnimate ? "10, 10" : !isSelected ? "5, 5" : "10, 10",
8350
+ renderer: L.svg()
8315
8351
  };
8316
- const newPolyline = L.polyline(coordinates, style);
8317
- if (listOfPolylines.find(p => p.options.id === id)) {
8318
- const polylineToUpdateCoordinates = listOfPolylines.find(p => p.options.id === id);
8319
- polylineToUpdateCoordinates.setLatLngs(coordinates);
8320
- polylineToUpdateCoordinates.setStyle(style);
8321
- } else {
8322
- listOfPolylines.push(newPolyline);
8352
+ const existingPolyline = listOfPolylines.find(p => p.options.id === id);
8353
+ if (existingPolyline) {
8354
+ removeAnimationFromElement(existingPolyline.getElement());
8355
+ existingPolyline.setLatLngs(lineCoordinates);
8356
+ existingPolyline.setStyle(polylineStyle);
8357
+ if (shouldAnimate && isSelected) {
8358
+ existingPolyline.once('add', () => {
8359
+ applyAnimationToPolyline(existingPolyline, isShortLink);
8360
+ });
8361
+ applyAnimationToPolyline(existingPolyline, isShortLink);
8362
+ }
8363
+ return existingPolyline;
8323
8364
  }
8324
- return newPolyline;
8325
- }
8326
- function createCurvePath({
8327
- zoom,
8328
- totalMarkers,
8329
- markerIndex
8330
- }) {
8331
- const radius = getCurvePointRadius(zoom);
8332
- const {
8333
- x,
8334
- y,
8335
- angleDeg
8336
- } = getAngleDeg(totalMarkers, markerIndex, radius);
8337
- return {
8338
- x,
8339
- y,
8340
- angleDeg
8341
- };
8342
- }
8343
- function getCurvePointRadius(zoom) {
8344
- const isSmall = isSmallMarker(zoom) || isExtraSmallMarker(zoom);
8345
- const isMedium = isMediumMarker(zoom);
8346
- if (isSmall) {
8347
- return RADIUS_SMALL + RADIUS_CURVE_SMALL;
8348
- } else if (isMedium) {
8349
- return RADIUS_MEDIUM + RADIUS_CURVE_MEDIUM;
8350
- } else {
8351
- return RADIUS_LARGE + RADIUS_CURVE_LARGE;
8365
+ const newPolyline = L.polyline(lineCoordinates, polylineStyle);
8366
+ newPolyline.addTo(mapRef);
8367
+ listOfPolylines.push(newPolyline);
8368
+ if (shouldAnimate && isSelected) {
8369
+ newPolyline.once('add', () => {
8370
+ applyAnimationToPolyline(newPolyline, isShortLink);
8371
+ });
8372
+ applyAnimationToPolyline(newPolyline, isShortLink);
8352
8373
  }
8353
- }
8354
- function buildSmoothCurve(layerPoints, mapRef) {
8355
- const path = [];
8356
- for (let i = 0; i < layerPoints.length - 1; i++) {
8357
- const p0 = layerPoints[i];
8358
- const p1 = layerPoints[i + 1];
8359
- const pPrev = layerPoints[i - 1] || p0;
8360
- const pNext = layerPoints[i + 2] || p1;
8361
- const cp1 = L__namespace.point(p0.x + (p1.x - pPrev.x) * TENSION, p0.y + (p1.y - pPrev.y) * TENSION);
8362
- const cp2 = L__namespace.point(p1.x - (pNext.x - p0.x) * TENSION, p1.y - (pNext.y - p0.y) * TENSION);
8363
- if (i === 0) {
8364
- path.push("M", [mapRef.layerPointToLatLng(p0).lat, mapRef.layerPointToLatLng(p0).lng]);
8365
- }
8366
- path.push("C", [mapRef.layerPointToLatLng(cp1).lat, mapRef.layerPointToLatLng(cp1).lng], [mapRef.layerPointToLatLng(cp2).lat, mapRef.layerPointToLatLng(cp2).lng], [mapRef.layerPointToLatLng(p1).lat, mapRef.layerPointToLatLng(p1).lng]);
8367
- }
8368
- return path;
8369
- }
8370
- function getSiblingCurveStrength(zoom) {
8371
- if (isExtraSmallMarker(zoom)) return RADIUS_CURVE_SMALL / 2;
8372
- if (isSmallMarker(zoom)) return RADIUS_CURVE_MEDIUM;
8373
- if (isMediumMarker(zoom)) return RADIUS_CURVE_LARGE;
8374
- return RADIUS_CURVE_LARGE;
8375
- }
8376
- function buildCurveWIthTwoSiblings({
8377
- mapRef,
8378
- startLatLng,
8379
- endLatLng,
8380
- zoom,
8381
- isSelected,
8382
- id
8383
- }) {
8384
- const fromPoint = mapRef.latLngToLayerPoint(startLatLng);
8385
- const toPoint = mapRef.latLngToLayerPoint(endLatLng);
8386
- const midX = (fromPoint.x + toPoint.x) / 2;
8387
- const midY = (fromPoint.y + toPoint.y) / 2 + (isSmallMarker(zoom) ? RADIUS_CURVE_SMALL / 2 : 0);
8388
- const dx = toPoint.x - fromPoint.x;
8389
- const dy = toPoint.y - fromPoint.y;
8390
- const normal = L__namespace.point(-dy, dx);
8391
- const length = Math.sqrt(normal.x ** 2 + normal.y ** 2) || 1;
8392
- const normalized = normal.multiplyBy(1 / length);
8393
- const curveStrength = getSiblingCurveStrength(zoom);
8394
- const controlPoint = L__namespace.point(midX, midY).add(normalized.multiplyBy(curveStrength));
8395
- const latlngs = [startLatLng, mapRef.layerPointToLatLng(controlPoint), endLatLng];
8396
- const layerPoints = latlngs.map(latlng => mapRef.latLngToLayerPoint(latlng));
8397
- const path = buildSmoothCurve(layerPoints, mapRef);
8398
- const curve = L__namespace.curve(path, {
8399
- color: "var(--base-gray-70)",
8400
- weight: isExtraSmallMarker(zoom) ? 0 : 1.2,
8401
- opacity: 0.5,
8402
- smoothFactor: 1,
8403
- id,
8404
- dashArray: !isSelected ? "5, 5" : "0, 0"
8405
- });
8406
- mapRef.addLayer(curve);
8374
+ return newPolyline;
8407
8375
  }
8408
8376
 
8409
8377
  const StakeholderMarker = styled__default["default"].div`
@@ -8705,6 +8673,9 @@ function StakeholderIcon$1({
8705
8673
  return null;
8706
8674
  }, [parentId, allData]);
8707
8675
  React.useEffect(() => {
8676
+ if (selectedMarkersId.length === 0 || !isSelected) {
8677
+ return;
8678
+ }
8708
8679
  linkNodesData.map(node => {
8709
8680
  const isConnectingToStakeholder = node.isStakeholder;
8710
8681
  const id = `${data.datastakeId}-${node.stakeholderId || node.datastakeId}`;
@@ -8716,8 +8687,6 @@ function StakeholderIcon$1({
8716
8687
  const stakeholderPoint = centerPoint.add(L__namespace.point(x, y));
8717
8688
  const stakeholderLatLng = mapRef.layerPointToLatLng(stakeholderPoint);
8718
8689
  let endLatLng = L__namespace.latLng(node.gps.latitude, node.gps.longitude);
8719
- const areNextToEachOther = targetMarkerIndex === index + 1 || targetMarkerIndex === index - 1 || index === 0 && targetMarkerIndex === node.totalStakeholders - 1 || targetMarkerIndex === 0 && index === node.totalStakeholders - 1;
8720
- const areOnlyTwoSiblings = node.totalStakeholders === 2;
8721
8690
  if (isExtraSmallMarker(zoom) && !isForceOpen) {
8722
8691
  createPolyline({
8723
8692
  L: L__namespace,
@@ -8727,7 +8696,8 @@ function StakeholderIcon$1({
8727
8696
  zoom,
8728
8697
  isSelected,
8729
8698
  id,
8730
- listOfPolylines: polylinesRef.current
8699
+ listOfPolylines: polylinesRef.current,
8700
+ animated: true
8731
8701
  });
8732
8702
  return;
8733
8703
  }
@@ -8745,61 +8715,8 @@ function StakeholderIcon$1({
8745
8715
  const nodePoint = mapRef.latLngToLayerPoint(nodeLatLng);
8746
8716
  const endPoint = L__namespace.point(x + nodePoint.x + center.left, y + nodePoint.y + center.top);
8747
8717
  endLatLng = mapRef.layerPointToLatLng(endPoint);
8748
- if (isSibling && (!areNextToEachOther || areOnlyTwoSiblings)) {
8749
- if (areOnlyTwoSiblings) {
8750
- buildCurveWIthTwoSiblings({
8751
- mapRef,
8752
- startLatLng: stakeholderLatLng,
8753
- endLatLng,
8754
- zoom,
8755
- isSelected,
8756
- id
8757
- });
8758
- return;
8759
- }
8760
- const total = node.totalStakeholders;
8761
- let from = index;
8762
- let to = targetMarkerIndex;
8763
- let flip = false;
8764
- const forwardDistance = (to - from + total) % total;
8765
- const backwardDistance = (from - to + total) % total;
8766
- if (backwardDistance < forwardDistance) {
8767
- [from, to] = [to, from];
8768
- flip = true;
8769
- }
8770
- const intermediateIndices = [];
8771
- for (let i = 1; i < (to - from + total) % total; i++) {
8772
- intermediateIndices.push((from + i) % total);
8773
- }
8774
- const indices = [from, ...intermediateIndices, to];
8775
- const intermediatePoints = [];
8776
- for (const i of indices) {
8777
- const {
8778
- x,
8779
- y
8780
- } = createCurvePath({
8781
- zoom,
8782
- totalMarkers: node.totalStakeholders,
8783
- markerIndex: i
8784
- });
8785
- const point = centerPoint.add(L__namespace.point(x, y));
8786
- const latlng = mapRef.layerPointToLatLng(point);
8787
- intermediatePoints.push(latlng);
8788
- }
8789
- const latlngs = flip ? [endLatLng, ...intermediatePoints, stakeholderLatLng] : [stakeholderLatLng, ...intermediatePoints, endLatLng];
8790
- const layerPoints = latlngs.map(latlng => mapRef.latLngToLayerPoint(latlng));
8791
- const path = buildSmoothCurve(layerPoints, mapRef);
8792
- const curve = L__namespace?.curve?.(path, {
8793
- color: "var(--base-gray-70)",
8794
- weight: isExtraSmallMarker(zoom) ? 0 : 1,
8795
- opacity: isSelected ? 1 : 0.5,
8796
- smoothFactor: 1,
8797
- id
8798
- });
8799
- mapRef.addLayer(curve);
8800
- return;
8801
- }
8802
8718
  }
8719
+ // Always use straight lines
8803
8720
  createPolyline({
8804
8721
  L: L__namespace,
8805
8722
  mapRef,
@@ -8809,10 +8726,11 @@ function StakeholderIcon$1({
8809
8726
  isFromStakeholder: false,
8810
8727
  isSelected,
8811
8728
  id,
8812
- listOfPolylines: polylinesRef.current
8729
+ listOfPolylines: polylinesRef.current,
8730
+ animated: true
8813
8731
  });
8814
8732
  });
8815
- }, [mapRef, x, y, parentData, linkNodesData, isSelected, zoom, isForceOpen]);
8733
+ }, [mapRef, x, y, parentData, linkNodesData, isSelected, zoom, isForceOpen, selectedMarkersId]);
8816
8734
  return /*#__PURE__*/jsxRuntime.jsx(jsxRuntime.Fragment, {
8817
8735
  children: /*#__PURE__*/jsxRuntime.jsx(antd.Popover, {
8818
8736
  content: renderTooltipJsx({
@@ -8879,6 +8797,8 @@ function LocationIcon({
8879
8797
  const linkedNodesData = React.useMemo(() => {
8880
8798
  const nodes = [];
8881
8799
  const links = data.links || [];
8800
+
8801
+ // Add links from the location itself
8882
8802
  links.forEach(link => {
8883
8803
  allData.forEach(d => {
8884
8804
  if (d.datastakeId === link) {
@@ -8898,8 +8818,45 @@ function LocationIcon({
8898
8818
  }
8899
8819
  });
8900
8820
  });
8821
+
8822
+ // ADD: Also include links from this location's stakeholders
8823
+ const stakeholders = data.stakeholders || [];
8824
+ stakeholders.forEach(stakeholder => {
8825
+ const stakeholderLinks = stakeholder.links || [];
8826
+ stakeholderLinks.forEach(link => {
8827
+ allData.forEach(d => {
8828
+ // Check if it's a direct location link
8829
+ if (d.datastakeId === link) {
8830
+ // Avoid duplicates
8831
+ if (!nodes.find(n => n.datastakeId === link && !n.isStakeholder)) {
8832
+ nodes.push({
8833
+ ...d,
8834
+ fromStakeholderId: stakeholder.datastakeId
8835
+ });
8836
+ }
8837
+ }
8838
+ // Check if it's a stakeholder link
8839
+ if (d.stakeholders && d.stakeholders.length > 0) {
8840
+ d.stakeholders.forEach(targetStakeholder => {
8841
+ if (targetStakeholder.datastakeId === link) {
8842
+ // Avoid duplicates
8843
+ if (!nodes.find(n => n.isStakeholder && n.datastakeId === d.datastakeId && n.stakeholdersIndex === d.stakeholders.indexOf(targetStakeholder))) {
8844
+ nodes.push({
8845
+ ...d,
8846
+ isStakeholder: true,
8847
+ totalStakeholders: d.stakeholders.length,
8848
+ stakeholdersIndex: d.stakeholders.indexOf(targetStakeholder),
8849
+ fromStakeholderId: stakeholder.datastakeId
8850
+ });
8851
+ }
8852
+ }
8853
+ });
8854
+ }
8855
+ });
8856
+ });
8857
+ });
8901
8858
  return nodes;
8902
- }, [JSON.stringify(allData), JSON.stringify(data.links), zoom]);
8859
+ }, [JSON.stringify(allData), JSON.stringify(data.links), JSON.stringify(data.stakeholders), zoom]);
8903
8860
  const stakeholdersOfLocation = React.useMemo(() => {
8904
8861
  return data?.stakeholders || [];
8905
8862
  }, [data.stakeholders, zoom]);
@@ -8917,7 +8874,13 @@ function LocationIcon({
8917
8874
  currentRoots.clear();
8918
8875
  markersRef.current = [];
8919
8876
 
8920
- // Create new markers
8877
+ // Only create stakeholder markers if this location or any of its stakeholders are selected
8878
+ const shouldShowStakeholders = isSelected || stakeholdersOfLocation.some(stk => selectedMarkersId.includes(stk.datastakeId));
8879
+ if (!shouldShowStakeholders || selectedMarkersId.length === 0) {
8880
+ return;
8881
+ }
8882
+
8883
+ // Create new markers only when selected
8921
8884
  stakeholdersOfLocation.forEach((stakeholder, index) => {
8922
8885
  const markerId = `${stakeholder.datastakeId}`;
8923
8886
  const {
@@ -9003,7 +8966,9 @@ function LocationIcon({
9003
8966
  zoom,
9004
8967
  isFromStakeholder: true,
9005
8968
  isForceOpen,
9006
- listOfPolylines: polylinesRef.current
8969
+ listOfPolylines: polylinesRef.current,
8970
+ stakeholderType: stakeholder.type,
8971
+ animated: true
9007
8972
  });
9008
8973
  });
9009
8974
  return () => {
@@ -9018,38 +8983,88 @@ function LocationIcon({
9018
8983
  rootsMapRef.current.clear();
9019
8984
  markersRef.current = [];
9020
8985
  };
9021
- }, [stakeholdersOfLocation, selectedMarkersId, activeMarker]);
9022
- linkedNodesData.map(node => {
9023
- const id = `${data.datastakeId}-${node.datastakeId}`;
9024
- const isConnectingToStakeholder = node.isStakeholder;
9025
- const centerLatLng = L__namespace.latLng(data.gps.latitude, data.gps.longitude);
9026
- let endLatLng = L__namespace.latLng(node.gps.latitude, node.gps.longitude);
9027
- const isConnectingToStakeholderSelected = selectedMarkersId.includes(node.datastakeId);
9028
- if (isConnectingToStakeholder && !isExtraSmallMarker(zoom)) {
9029
- const {
9030
- x,
9031
- y
9032
- } = getStakeholderPosition({
8986
+ }, [stakeholdersOfLocation, selectedMarkersId, activeMarker, zoom]);
8987
+
8988
+ // Only create polylines for linked nodes when something is selected
8989
+ React.useEffect(() => {
8990
+ if (selectedMarkersId.length === 0) {
8991
+ return;
8992
+ }
8993
+
8994
+ // IMPORTANT: Only draw links if this location is actually selected
8995
+ // Not just highlighted as part of the chain
8996
+ if (!isSelected) {
8997
+ return;
8998
+ }
8999
+
9000
+ // Filter linkedNodesData to only include nodes that are in the selected chain
9001
+ const relevantLinks = linkedNodesData.filter(node => {
9002
+ // Check if the target node (location) is in the selected markers
9003
+ const targetLocationInSelection = selectedMarkersId.includes(node.datastakeId);
9004
+
9005
+ // If connecting to a stakeholder, check if that stakeholder is selected
9006
+ if (node.isStakeholder) {
9007
+ const stakeholderInSelection = node.stakeholdersIndex !== undefined && selectedMarkersId.includes(node.datastakeId);
9008
+ return stakeholderInSelection;
9009
+ }
9010
+ return targetLocationInSelection;
9011
+ });
9012
+ relevantLinks.forEach(node => {
9013
+ const id = node.fromStakeholderId ? `${node.fromStakeholderId}-${node.datastakeId}` : `${data.datastakeId}-${node.datastakeId}`;
9014
+ const isConnectingToStakeholder = node.isStakeholder;
9015
+
9016
+ // If the link is from a stakeholder, start from the stakeholder position
9017
+ let startLatLng;
9018
+ if (node.fromStakeholderId) {
9019
+ // Find the stakeholder index in this location's stakeholders
9020
+ const stakeholderIndex = stakeholdersOfLocation.findIndex(s => s.datastakeId === node.fromStakeholderId);
9021
+ if (stakeholderIndex !== -1) {
9022
+ const {
9023
+ x,
9024
+ y
9025
+ } = getStakeholderPosition({
9026
+ zoom,
9027
+ totalMarkers: stakeholdersOfLocation.length,
9028
+ markerIndex: stakeholderIndex
9029
+ });
9030
+ const centerLatLng = L__namespace.latLng(data.gps.latitude, data.gps.longitude);
9031
+ const centerPoint = mapRef.latLngToLayerPoint(centerLatLng);
9032
+ const stakeholderPoint = centerPoint.add(L__namespace.point(x, y));
9033
+ startLatLng = mapRef.layerPointToLatLng(stakeholderPoint);
9034
+ } else {
9035
+ startLatLng = L__namespace.latLng(data.gps.latitude, data.gps.longitude);
9036
+ }
9037
+ } else {
9038
+ startLatLng = L__namespace.latLng(data.gps.latitude, data.gps.longitude);
9039
+ }
9040
+ let endLatLng = L__namespace.latLng(node.gps.latitude, node.gps.longitude);
9041
+ const isConnectingToStakeholderSelected = selectedMarkersId.includes(node.datastakeId);
9042
+ if (isConnectingToStakeholder && !isExtraSmallMarker(zoom)) {
9043
+ const {
9044
+ x,
9045
+ y
9046
+ } = getStakeholderPosition({
9047
+ zoom,
9048
+ totalMarkers: node.totalStakeholders,
9049
+ markerIndex: node.stakeholdersIndex
9050
+ });
9051
+ const nodeLatLng = L__namespace.latLng(node.gps.latitude, node.gps.longitude);
9052
+ const nodePoint = mapRef.latLngToLayerPoint(nodeLatLng);
9053
+ const endPoint = L__namespace.point(x + nodePoint.x, y + nodePoint.y);
9054
+ endLatLng = mapRef.layerPointToLatLng(endPoint);
9055
+ }
9056
+ createPolyline({
9057
+ L: L__namespace,
9058
+ mapRef,
9059
+ startLatLng,
9060
+ endLatLng,
9061
+ isSelected: isConnectingToStakeholderSelected,
9062
+ id,
9033
9063
  zoom,
9034
- totalMarkers: node.totalStakeholders,
9035
- markerIndex: node.stakeholdersIndex
9064
+ listOfPolylines: polylinesRef.current
9036
9065
  });
9037
- const nodeLatLng = L__namespace.latLng(node.gps.latitude, node.gps.longitude);
9038
- const nodePoint = mapRef.latLngToLayerPoint(nodeLatLng);
9039
- const endPoint = L__namespace.point(x + nodePoint.x, y + nodePoint.y);
9040
- endLatLng = mapRef.layerPointToLatLng(endPoint);
9041
- }
9042
- createPolyline({
9043
- L: L__namespace,
9044
- mapRef,
9045
- startLatLng: centerLatLng,
9046
- endLatLng,
9047
- isSelected: isConnectingToStakeholderSelected,
9048
- id,
9049
- zoom,
9050
- listOfPolylines: polylinesRef.current
9051
9066
  });
9052
- });
9067
+ }, [linkedNodesData, selectedMarkersId, zoom, stakeholdersOfLocation, isSelected]);
9053
9068
  return /*#__PURE__*/jsxRuntime.jsx(antd.Popover, {
9054
9069
  content: renderTooltipJsx({
9055
9070
  title: data.name,
@@ -9565,7 +9580,8 @@ function useMapHelper$1({
9565
9580
  link: link,
9566
9581
  onClickLink: onClickLink,
9567
9582
  activeStakeholder: activeStakeholder,
9568
- setActiveStakeholder: setActiveStakeholder
9583
+ setActiveStakeholder: setActiveStakeholder,
9584
+ mapRef: mapRef
9569
9585
  }));
9570
9586
  roots.current.push(root);
9571
9587
  } else if (type === "location") {
@@ -9770,7 +9786,8 @@ const useMap = ({
9770
9786
  MAP_TOKEN
9771
9787
  } = useMapConfig({
9772
9788
  app,
9773
- isSatellite
9789
+ isSatellite,
9790
+ mapRef: container
9774
9791
  });
9775
9792
  const [initialMarkerSetIsDone, setInitialMarkerSetIsDone] = React.useState(false);
9776
9793
  const [mapCenter, setMapCenter] = React.useState([0, 0]);
@@ -9787,6 +9804,8 @@ const useMap = ({
9787
9804
  const graph = new Map();
9788
9805
  const stakeToLoc = new Map();
9789
9806
  const nodeTypes = new Map();
9807
+
9808
+ // Build the graph
9790
9809
  for (const loc of data) {
9791
9810
  const locId = loc.datastakeId;
9792
9811
  nodeTypes.set(locId, loc.type);
@@ -9811,26 +9830,45 @@ const useMap = ({
9811
9830
  }
9812
9831
  }
9813
9832
  const highlightTable = {};
9833
+
9834
+ // Perform BFS/DFS to find all connected nodes in the entire chain
9814
9835
  for (const [node] of graph) {
9815
9836
  const highlighted = new Set();
9816
- highlighted.add(node);
9817
- const nodeIsStakeholder = !isLocation(nodeTypes.get(node));
9818
- if (nodeIsStakeholder && stakeToLoc.has(node)) {
9819
- const parentLoc = stakeToLoc.get(node);
9820
- highlighted.add(parentLoc);
9821
- }
9822
- for (const neighbor of graph.get(node) || []) {
9823
- const neighborIsStakeholder = !isLocation(nodeTypes.get(neighbor));
9824
- if (neighborIsStakeholder && stakeToLoc.has(neighbor)) {
9825
- const neighborParent = stakeToLoc.get(neighbor);
9826
- if (isLocation(nodeTypes.get(node)) && neighborParent === node || nodeIsStakeholder && stakeToLoc.get(node) === neighborParent) {
9827
- highlighted.add(neighbor);
9828
- } else {
9837
+ const queue = [node];
9838
+ const visited = new Set([node]);
9839
+ while (queue.length > 0) {
9840
+ const current = queue.shift();
9841
+ highlighted.add(current);
9842
+
9843
+ // Add parent location if current is stakeholder
9844
+ const currentIsStakeholder = !isLocation(nodeTypes.get(current));
9845
+ if (currentIsStakeholder && stakeToLoc.has(current)) {
9846
+ const parentLoc = stakeToLoc.get(current);
9847
+ if (!visited.has(parentLoc)) {
9848
+ highlighted.add(parentLoc);
9849
+ visited.add(parentLoc);
9850
+ queue.push(parentLoc);
9851
+ }
9852
+ }
9853
+
9854
+ // Traverse all neighbors
9855
+ for (const neighbor of graph.get(current) || []) {
9856
+ if (!visited.has(neighbor)) {
9857
+ visited.add(neighbor);
9858
+ queue.push(neighbor);
9829
9859
  highlighted.add(neighbor);
9830
- highlighted.add(neighborParent);
9860
+
9861
+ // If neighbor is stakeholder, add its parent location
9862
+ const neighborIsStakeholder = !isLocation(nodeTypes.get(neighbor));
9863
+ if (neighborIsStakeholder && stakeToLoc.has(neighbor)) {
9864
+ const neighborParent = stakeToLoc.get(neighbor);
9865
+ if (!visited.has(neighborParent)) {
9866
+ highlighted.add(neighborParent);
9867
+ visited.add(neighborParent);
9868
+ queue.push(neighborParent);
9869
+ }
9870
+ }
9831
9871
  }
9832
- } else {
9833
- highlighted.add(neighbor);
9834
9872
  }
9835
9873
  }
9836
9874
  highlightTable[node] = [...highlighted];
@@ -9895,19 +9933,29 @@ const useMap = ({
9895
9933
  });
9896
9934
  }
9897
9935
  }
9936
+ if (type === "chain" && selectedMarkersId.length === 0) {
9937
+ if (polylinesRef.current.length) {
9938
+ polylinesRef.current.forEach(polyline => {
9939
+ if (mapRef.hasLayer(polyline)) {
9940
+ mapRef.removeLayer(polyline);
9941
+ }
9942
+ });
9943
+ polylinesRef.current = [];
9944
+ }
9945
+ }
9898
9946
  clearMapMarkers();
9899
9947
  if (data) {
9900
- // Filters out locations that are not connected to any stakeholders
9901
- const excludedType = ['village', 'town', 'area', 'territory'];
9902
- const filteredData = data?.filter(obj => !excludedType.includes(obj?.type) && (obj?.stakeholders?.length > 0 || data.some(other => other.datastakeId !== obj.datastakeId && (other.stakeholders || []).some(stk => (stk.links || []).includes(obj.datastakeId)))));
9948
+ const filteredData = data?.filter(obj => obj.type === 'mineSite' || obj?.stakeholders?.length > 0 || data.some(other => other.datastakeId !== obj.datastakeId && (other.stakeholders || []).some(stk => (stk.links || []).includes(obj.datastakeId))));
9903
9949
  const maxTotal = Math.max(...(data || []).map(d => d.total));
9904
9950
  const dataToRender = type === "chain" ? filteredData : data;
9905
9951
  dataToRender.forEach((d, i) => {
9906
9952
  addIconToMapInitialy([d?.marker?.lat, d?.marker?.lng], "location", d.category || "mineSite", d, maxTotal, i);
9907
9953
  });
9908
- polylinesRef.current.forEach(polyline => {
9909
- mapRef.addLayer(polyline);
9910
- });
9954
+ if (selectedMarkersId.length > 0) {
9955
+ polylinesRef.current.forEach(polyline => {
9956
+ mapRef.addLayer(polyline);
9957
+ });
9958
+ }
9911
9959
  mapRef.invalidateSize();
9912
9960
  mapRef.fire("moveend");
9913
9961
  }