datastake-daf 0.6.780 → 0.6.782

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.
@@ -5,14 +5,13 @@ const VILLAGE = "village";
5
5
  const EXPORTER = "exporter";
6
6
  const PROCESSOR = "mineralProcessor";
7
7
  const DEPOT = "depot";
8
- const OPERATOR = "miningOperator";
9
8
 
10
9
  const MAX_EXTRA_SMALL_ZOOM_THRESHOLD = 2;
11
10
  const MAX_SMALL_ZOOM_THRESHOLD = 3;
12
11
  const MAX_MEDIUM_ZOOM_THRESHOLD = 6;
13
12
 
14
13
  const LOCATION_TYPES = [MINE_SITE, VILLAGE];
15
- const STAKEHOLDER_TYPES = [EXPORTER, PROCESSOR, DEPOT, OPERATOR];
14
+ const STAKEHOLDER_TYPES = [EXPORTER, PROCESSOR, DEPOT];
16
15
 
17
16
  const RADIUS_SMALL = 15;
18
17
  const RADIUS_MEDIUM = 35;
@@ -101,6 +100,7 @@ export function getStakeholderPosition({ zoom, totalMarkers, markerIndex }) {
101
100
 
102
101
  let radius;
103
102
  let center = {
103
+ // NOT BEING USED FOR NOW AND MAYBE NEVER
104
104
  left: 0,
105
105
  top: 0,
106
106
  };
@@ -117,32 +117,6 @@ export function getStakeholderPosition({ zoom, totalMarkers, markerIndex }) {
117
117
  return { x, y, center, radius, angleDeg };
118
118
  }
119
119
 
120
- function applyAnimationDirect(el, isShortLink) {
121
- if (!(el instanceof SVGElement) || isShortLink) return;
122
-
123
- el.style.strokeDasharray = "10, 10";
124
- el.style.strokeDashoffset = "0";
125
-
126
- el.style.animation = "dash-flow 1.2s linear infinite";
127
-
128
- el.classList.add('animated-polyline');
129
- }
130
-
131
- function removeAnimationFromElement(element) {
132
- if (!element) return;
133
-
134
- element.classList.remove('animated-polyline');
135
- element.style.animation = '';
136
- element.style.strokeDasharray = '';
137
- }
138
-
139
- function applyAnimationToPolyline(polyline, isShortLink) {
140
- const element = polyline.getElement();
141
- if (element) {
142
- applyAnimationDirect(element, isShortLink);
143
- }
144
- }
145
-
146
120
  export function createPolyline({
147
121
  L,
148
122
  startLatLng,
@@ -153,62 +127,32 @@ export function createPolyline({
153
127
  listOfPolylines = [],
154
128
  isFromStakeholder = false,
155
129
  isForceOpen = false,
156
- stakeholderType = null,
157
- animated = false,
158
- mapRef
159
130
  }) {
160
- const lineWidth = isFromStakeholder && isExtraSmallMarker(zoom) && !isForceOpen ? 0 : 1.2;
161
-
162
- const isShortLink = stakeholderType === OPERATOR || isFromStakeholder;
163
- const shouldAnimate = animated;
131
+ const width = isFromStakeholder && isExtraSmallMarker(zoom) && !isForceOpen ? 0 : 1.2;
164
132
 
165
- const lineCoordinates = [
133
+ const coordinates = [
166
134
  [startLatLng.lat, startLatLng.lng],
167
135
  [endLatLng.lat, endLatLng.lng],
168
136
  ];
169
-
170
- const polylineStyle = {
137
+ const style = {
171
138
  color: "var(--base-gray-70)",
172
- weight: lineWidth,
173
- opacity: isSelected ? 1 : 0.5,
174
- smoothFactor: 0,
139
+ weight: width,
140
+ opacity: 0.5,
141
+ smoothFactor: 1,
175
142
  id,
176
- dashArray: isShortLink ? "0, 0" : (shouldAnimate ? "10, 10" : (!isSelected ? "5, 5" : "10, 10")),
177
- renderer: L.svg()
143
+ dashArray: !isSelected ? "5, 5" : "0, 0",
178
144
  };
179
145
 
180
- const existingPolyline = listOfPolylines.find(p => p.options.id === id);
181
-
182
- if (existingPolyline) {
183
- removeAnimationFromElement(existingPolyline.getElement());
184
-
185
- existingPolyline.setLatLngs(lineCoordinates);
186
- existingPolyline.setStyle(polylineStyle);
187
-
188
- if (shouldAnimate && isSelected) {
189
- existingPolyline.once('add', () => {
190
- applyAnimationToPolyline(existingPolyline, isShortLink);
191
- });
192
-
193
- applyAnimationToPolyline(existingPolyline, isShortLink);
194
- }
195
-
196
- return existingPolyline;
197
- }
146
+ const newPolyline = L.polyline(coordinates, style);
198
147
 
199
- const newPolyline = L.polyline(lineCoordinates, polylineStyle);
200
-
201
- newPolyline.addTo(mapRef);
202
- listOfPolylines.push(newPolyline);
203
-
204
- if (shouldAnimate && isSelected) {
205
- newPolyline.once('add', () => {
206
- applyAnimationToPolyline(newPolyline, isShortLink);
207
- });
208
-
209
- applyAnimationToPolyline(newPolyline, isShortLink);
148
+ if (listOfPolylines.find((p) => p.options.id === id)) {
149
+ const polylineToUpdateCoordinates = listOfPolylines.find((p) => p.options.id === id);
150
+ polylineToUpdateCoordinates.setLatLngs(coordinates);
151
+ polylineToUpdateCoordinates.setStyle(style);
152
+ } else {
153
+ listOfPolylines.push(newPolyline);
210
154
  }
211
-
155
+
212
156
  return newPolyline;
213
157
  }
214
158
 
@@ -369,7 +369,6 @@ export function useMapHelper({
369
369
  onClickLink={onClickLink}
370
370
  activeStakeholder={activeStakeholder}
371
371
  setActiveStakeholder={setActiveStakeholder}
372
- mapRef={mapRef}
373
372
  />,
374
373
  );
375
374
 
@@ -31,7 +31,7 @@ export const useMap = ({
31
31
  const container = createRef();
32
32
  const [data, setData] = useState([]);
33
33
  const [mapRef, setMapRef] = useState(null);
34
- const { TILE_LAYER_URL, MAP_TOKEN } = useMapConfig({ app, isSatellite, mapRef: container });
34
+ const { TILE_LAYER_URL, MAP_TOKEN } = useMapConfig({ app, isSatellite });
35
35
  const [initialMarkerSetIsDone, setInitialMarkerSetIsDone] = useState(false);
36
36
  const [mapCenter, setMapCenter] = useState([0, 0]);
37
37
  const [emptyStateIsVisible, setEmptyStateIsVisible] = useState(false);
@@ -48,7 +48,6 @@ export const useMap = ({
48
48
  const stakeToLoc = new Map();
49
49
  const nodeTypes = new Map();
50
50
 
51
- // Build the graph
52
51
  for (const loc of data) {
53
52
  const locId = loc.datastakeId;
54
53
  nodeTypes.set(locId, loc.type);
@@ -82,45 +81,34 @@ export const useMap = ({
82
81
 
83
82
  const highlightTable = {};
84
83
 
85
- // Perform BFS/DFS to find all connected nodes in the entire chain
86
84
  for (const [node] of graph) {
87
85
  const highlighted = new Set();
88
- const queue = [node];
89
- const visited = new Set([node]);
90
86
 
91
- while (queue.length > 0) {
92
- const current = queue.shift();
93
- highlighted.add(current);
94
-
95
- // Add parent location if current is stakeholder
96
- const currentIsStakeholder = !isLocation(nodeTypes.get(current));
97
- if (currentIsStakeholder && stakeToLoc.has(current)) {
98
- const parentLoc = stakeToLoc.get(current);
99
- if (!visited.has(parentLoc)) {
100
- highlighted.add(parentLoc);
101
- visited.add(parentLoc);
102
- queue.push(parentLoc);
103
- }
104
- }
87
+ highlighted.add(node);
88
+
89
+ const nodeIsStakeholder = !isLocation(nodeTypes.get(node));
90
+ if (nodeIsStakeholder && stakeToLoc.has(node)) {
91
+ const parentLoc = stakeToLoc.get(node);
92
+ highlighted.add(parentLoc);
93
+ }
94
+
95
+ for (const neighbor of graph.get(node) || []) {
96
+ const neighborIsStakeholder = !isLocation(nodeTypes.get(neighbor));
105
97
 
106
- // Traverse all neighbors
107
- for (const neighbor of graph.get(current) || []) {
108
- if (!visited.has(neighbor)) {
109
- visited.add(neighbor);
110
- queue.push(neighbor);
98
+ if (neighborIsStakeholder && stakeToLoc.has(neighbor)) {
99
+ const neighborParent = stakeToLoc.get(neighbor);
100
+
101
+ if (
102
+ (isLocation(nodeTypes.get(node)) && neighborParent === node) ||
103
+ (nodeIsStakeholder && stakeToLoc.get(node) === neighborParent)
104
+ ) {
105
+ highlighted.add(neighbor);
106
+ } else {
111
107
  highlighted.add(neighbor);
112
-
113
- // If neighbor is stakeholder, add its parent location
114
- const neighborIsStakeholder = !isLocation(nodeTypes.get(neighbor));
115
- if (neighborIsStakeholder && stakeToLoc.has(neighbor)) {
116
- const neighborParent = stakeToLoc.get(neighbor);
117
- if (!visited.has(neighborParent)) {
118
- highlighted.add(neighborParent);
119
- visited.add(neighborParent);
120
- queue.push(neighborParent);
121
- }
122
- }
108
+ highlighted.add(neighborParent);
123
109
  }
110
+ } else {
111
+ highlighted.add(neighbor);
124
112
  }
125
113
  }
126
114
 
@@ -163,21 +151,10 @@ export const useMap = ({
163
151
  destroyAllPopovers();
164
152
  setSelectedMarkersId((prev) => {
165
153
  if (prev.includes(clickedMarker.datastakeId)) {
166
- // Deselecting - clear polylines
167
154
  openPopupIdRef.current = null;
168
155
  setMarkerWithPopup(null);
169
156
  return [];
170
157
  } else {
171
- // CLEAR OLD POLYLINES BEFORE SELECTING NEW MARKER
172
- if (polylinesRef.current.length > 0) {
173
- polylinesRef.current.forEach((polyline) => {
174
- if (mapRef.hasLayer(polyline)) {
175
- mapRef.removeLayer(polyline);
176
- }
177
- });
178
- polylinesRef.current = [];
179
- }
180
-
181
158
  setMarkerWithPopup(isStakeholder(clickedMarker.type) ? clickedMarker : null);
182
159
  const newSelectedMarkersId = highlightTable[clickedMarker.datastakeId];
183
160
  openPopupIdRef.current = clickedMarker.datastakeId;
@@ -214,22 +191,12 @@ export const useMap = ({
214
191
  });
215
192
  }
216
193
  }
217
-
218
- if (type === "chain" && selectedMarkersId.length === 0) {
219
- if (polylinesRef.current.length) {
220
- polylinesRef.current.forEach((polyline) => {
221
- if (mapRef.hasLayer(polyline)) {
222
- mapRef.removeLayer(polyline);
223
- }
224
- });
225
- polylinesRef.current = [];
226
- }
227
- }
228
-
229
194
  clearMapMarkers();
230
195
  if (data) {
196
+ // Filters out locations that are not connected to any stakeholders
197
+ const excludedType = ['village', 'town', 'area', 'territory']
231
198
  const filteredData = data?.filter((obj) =>
232
- obj.type === 'mineSite' || (obj?.stakeholders?.length > 0 ||
199
+ !excludedType.includes(obj?.type) && (obj?.stakeholders?.length > 0 ||
233
200
  data.some((other) =>
234
201
  other.datastakeId !== obj.datastakeId &&
235
202
  (other.stakeholders || []).some((stk) =>
@@ -251,11 +218,9 @@ export const useMap = ({
251
218
  );
252
219
  });
253
220
 
254
- if (selectedMarkersId.length > 0) {
255
- polylinesRef.current.forEach((polyline) => {
256
- mapRef.addLayer(polyline);
257
- });
258
- }
221
+ polylinesRef.current.forEach((polyline) => {
222
+ mapRef.addLayer(polyline);
223
+ });
259
224
 
260
225
  mapRef.invalidateSize();
261
226
  mapRef.fire("moveend");
@@ -7,8 +7,6 @@ const Style = styled.div`
7
7
  width: 100%;
8
8
  height: 472px;
9
9
 
10
-
11
-
12
10
  .filter-cont {
13
11
  position: absolute;
14
12
  top: 24px;
@@ -111,24 +109,11 @@ const Style = styled.div`
111
109
  align-items: center;
112
110
  }
113
111
 
114
- .marker-chain {
115
- display: flex;
116
- align-items: center;
117
- justify-content: center;
118
- }
119
-
120
- .animated-polyline {
121
- stroke-dasharray: 10 10;
122
- animation: dash-flow 1.5s linear infinite;
123
- stroke-linecap: round;
124
- }
125
-
126
- @keyframes dash-flow {
127
- to {
128
- stroke-dashoffset: -20;
129
- }
130
- }
131
-
112
+ .marker-chain {
113
+ display: flex;
114
+ align-items: center;
115
+ justify-content: center;
116
+ }
132
117
 
133
118
  }
134
119
 
@@ -0,0 +1,84 @@
1
+ import { useState, useEffect, useMemo } from "react";
2
+
3
+ export const useViewFormUrlParams = ({
4
+ params,
5
+ pathname,
6
+ search,
7
+ searchParams,
8
+ setSearchParams,
9
+ push,
10
+ }) => {
11
+ const [namespace, setNamespace] = useState(params.namespace);
12
+ const [id, setId] = useState(params.id);
13
+ const [group, setGroup] = useState(params.group);
14
+ const [subsection, setSubsection] = useState(params.subsection);
15
+ const [source, setSource] = useState(searchParams.get("source") || null);
16
+ const [version, setVersion] = useState(searchParams.get("version") || null);
17
+
18
+ useEffect(() => {
19
+ if (
20
+ (id && params.id !== id) ||
21
+ (namespace && namespace !== params.namespace)
22
+ ) {
23
+ setGroup(undefined);
24
+ setSubsection(undefined);
25
+ } else {
26
+ setGroup(params.group);
27
+ setSubsection(params.subsection);
28
+ }
29
+ setNamespace(params.namespace);
30
+ setId(params.id);
31
+ }, [params, id, namespace]);
32
+
33
+ useEffect(() => {
34
+ if (source && version) {
35
+ const newParams = new URLSearchParams(searchParams);
36
+ newParams.set("source", source);
37
+ newParams.set("version", version);
38
+ setSearchParams(newParams);
39
+ }
40
+ }, [source, version]);
41
+
42
+ const updateSourceAndVersion = (newSource, newVersion) => {
43
+ const newParams = new URLSearchParams(searchParams);
44
+ if (newSource && newVersion) {
45
+ newParams.set("source", newSource);
46
+ newParams.set("version", newVersion);
47
+ } else {
48
+ newParams.delete("source");
49
+ newParams.delete("version");
50
+ }
51
+ setSearchParams(newParams);
52
+ setSource(newSource);
53
+ setVersion(newVersion);
54
+ };
55
+
56
+ const clearSourceAndVersion = () => {
57
+ updateSourceAndVersion(null, null);
58
+ };
59
+
60
+ const match = useMemo(
61
+ () => ({
62
+ params,
63
+ path: pathname,
64
+ }),
65
+ [params, pathname],
66
+ );
67
+
68
+ return {
69
+ namespace,
70
+ id,
71
+ group,
72
+ subsection,
73
+ source,
74
+ version,
75
+ params,
76
+ searchParams,
77
+ setSource,
78
+ setVersion,
79
+ updateSourceAndVersion,
80
+ clearSourceAndVersion,
81
+ match,
82
+ search,
83
+ };
84
+ }
@@ -82,7 +82,7 @@ const CycleOutcomes = ({
82
82
  <section style={{ flex: 1 }}>
83
83
  <StatCard
84
84
  title={t("Total Area Restored")}
85
- value={totalAreaRestored?Number(totalAreaRestored.current).toLocaleString() : 0}
85
+ value={totalAreaRestored?Number(totalAreaRestored.current).toLocaleString() + " ha" : 0 + " ha"}
86
86
  icon="Tree"
87
87
  change={totalAreaRestoredChange}
88
88
  />