datastake-daf 0.6.766 → 0.6.768
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.
- package/dist/components/index.js +269 -140
- package/dist/pages/index.js +4736 -5657
- package/dist/utils/index.js +16 -1
- package/package.json +4 -1
- package/src/@daf/core/components/Dashboard/Map/ChainIcon/Markers/StakeholderMarker.js +5 -2
- package/src/@daf/core/components/Dashboard/Map/ChainIcon/index.js +67 -28
- package/src/@daf/core/components/Dashboard/Map/StakeholderIcon/index.js +3 -0
- package/src/@daf/core/components/Dashboard/Map/hook.js +57 -33
- package/src/@daf/core/components/Graphs/TradeRelationship/index.jsx +49 -11
- package/src/@daf/core/components/Graphs/components/BaseGraph.jsx +8 -4
- package/src/@daf/core/components/Screens/BaseScreen/index.jsx +1 -1
- package/src/@daf/core/components/Screens/TableScreen/TablePageWithTabs/index.jsx +1 -1
- package/src/@daf/core/components/UI/MissingTagButton/index.jsx +36 -0
- package/src/@daf/hooks/useMapHelper.js +5 -0
- package/src/@daf/pages/Dashboards/SupplyChain/components/SupplyChainMap/index.js +3 -2
- package/src/@daf/pages/Documents/config.js +0 -10
- package/src/@daf/pages/Documents/index.jsx +51 -108
- package/src/@daf/pages/Events/Activities/config.js +1 -11
- package/src/@daf/pages/Events/Activities/index.jsx +47 -105
- package/src/@daf/pages/Events/Incidents/config.js +1 -11
- package/src/@daf/pages/Events/Incidents/index.jsx +47 -105
- package/src/@daf/pages/Events/config.js +18 -34
- package/src/@daf/pages/Events/helper.js +0 -1
- package/src/@daf/pages/Events/index.jsx +49 -111
- package/src/@daf/pages/Locations/MineSite/columns.js +1 -1
- package/src/@daf/pages/Locations/MineSite/config.js +0 -10
- package/src/@daf/pages/Locations/MineSite/index.jsx +47 -105
- package/src/@daf/pages/Locations/config.js +4 -16
- package/src/@daf/pages/Locations/index.jsx +53 -110
- package/src/@daf/pages/Stakeholders/Operators/config.js +0 -10
- package/src/@daf/pages/Stakeholders/Operators/index.jsx +47 -105
- package/src/@daf/pages/Stakeholders/Workers/config.js +0 -10
- package/src/@daf/pages/Stakeholders/Workers/index.jsx +47 -105
- package/src/@daf/pages/Stakeholders/config.js +3 -15
- package/src/@daf/pages/Stakeholders/index.jsx +53 -109
- package/src/@daf/pages/Summary/Operator/components/TradeRelationships/index.js +5 -1
- package/src/@daf/pages/TablePage/config.js +78 -0
- package/src/@daf/pages/{Events → TablePage}/create.jsx +11 -8
- package/src/@daf/pages/TablePage/hook.js +123 -0
- package/src/@daf/pages/TablePage/index.jsx +142 -0
- package/src/constants/locales/en/translation.js +5 -0
- package/src/constants/locales/fr/translation.js +5 -0
- package/src/index.js +1 -0
- package/src/@daf/pages/Documents/create.jsx +0 -105
- package/src/@daf/pages/Events/Activities/create.jsx +0 -104
- package/src/@daf/pages/Events/Incidents/create.jsx +0 -104
- package/src/@daf/pages/Locations/MineSite/create.jsx +0 -104
- package/src/@daf/pages/Locations/create.jsx +0 -104
- package/src/@daf/pages/Stakeholders/Operators/create.jsx +0 -104
- package/src/@daf/pages/Stakeholders/Workers/create.jsx +0 -104
- package/src/@daf/pages/Stakeholders/create.jsx +0 -105
package/dist/utils/index.js
CHANGED
|
@@ -7085,7 +7085,12 @@ const defaultMapConfig = {
|
|
|
7085
7085
|
maxZoom: 18,
|
|
7086
7086
|
preferCanvas: true,
|
|
7087
7087
|
zoomControl: false,
|
|
7088
|
-
maxBounds: maxBounds
|
|
7088
|
+
maxBounds: maxBounds,
|
|
7089
|
+
zoomSnap: 0.5,
|
|
7090
|
+
zoomDelta: 0.5,
|
|
7091
|
+
wheelPxPerZoomLevel: 150,
|
|
7092
|
+
zoomAnimation: true,
|
|
7093
|
+
zoomAnimationThreshold: 10
|
|
7089
7094
|
};
|
|
7090
7095
|
|
|
7091
7096
|
styled__default["default"].div`
|
|
@@ -7724,6 +7729,11 @@ function getRedirectPath(user, fallback = '', app, isDatastake) {
|
|
|
7724
7729
|
}
|
|
7725
7730
|
|
|
7726
7731
|
const en = {
|
|
7732
|
+
"accounts": "Accounts",
|
|
7733
|
+
"users": "Users",
|
|
7734
|
+
"subjects": "Subjects",
|
|
7735
|
+
"active-users": "Active Users",
|
|
7736
|
+
"total-data-points": "Total Data Points",
|
|
7727
7737
|
"Identified Customers": "Identified Customers",
|
|
7728
7738
|
"Identified Suppliers": "Identified Suppliers",
|
|
7729
7739
|
"Associated Mine Sites": "Associated Mine Sites",
|
|
@@ -9037,6 +9047,11 @@ const en = {
|
|
|
9037
9047
|
};
|
|
9038
9048
|
|
|
9039
9049
|
const fr = {
|
|
9050
|
+
"accounts": "Comptes",
|
|
9051
|
+
"users": "Utilisateurs",
|
|
9052
|
+
"subjects": "Sujets",
|
|
9053
|
+
"active-users": "Utilisateurs Actifs",
|
|
9054
|
+
"total-data-points": "Total Points de Données",
|
|
9040
9055
|
"Identified Customers": "Clients identifiés",
|
|
9041
9056
|
"Identified Suppliers": "Fournisseurs identifiés",
|
|
9042
9057
|
"Associated Mine Sites": "Sites miniers associés",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "datastake-daf",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.768",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"@ant-design/icons": "^5.2.5",
|
|
6
6
|
"@antv/g2": "^5.1.1",
|
|
@@ -15,6 +15,9 @@
|
|
|
15
15
|
"buffer": "^6.0.3",
|
|
16
16
|
"countries-list": "^2.6.1",
|
|
17
17
|
"country-city-location": "^1.0.13",
|
|
18
|
+
"d3-selection": "^3.0.0",
|
|
19
|
+
"d3-transition": "^3.0.1",
|
|
20
|
+
"d3-zoom": "^3.0.0",
|
|
18
21
|
"dayjs": "^1.11.12",
|
|
19
22
|
"deepmerge": "^4.3.1",
|
|
20
23
|
"docx": "^9.5.1",
|
|
@@ -90,7 +90,7 @@ export default function StakeholderIcon({
|
|
|
90
90
|
useEffect(() => {
|
|
91
91
|
linkNodesData.map((node) => {
|
|
92
92
|
const isConnectingToStakeholder = node.isStakeholder;
|
|
93
|
-
const id = `${data.datastakeId}-${node.stakeholderId}`;
|
|
93
|
+
const id = `${data.datastakeId}-${node.stakeholderId || node.datastakeId}`;
|
|
94
94
|
const targetsParentId = node.parentId;
|
|
95
95
|
const targetMarkerIndex = node.stakeholdersIndex;
|
|
96
96
|
const isSibling = targetsParentId === parentId;
|
|
@@ -234,7 +234,10 @@ export default function StakeholderIcon({
|
|
|
234
234
|
onClickLink(data);
|
|
235
235
|
},
|
|
236
236
|
})}
|
|
237
|
-
getPopupContainer={() =>
|
|
237
|
+
getPopupContainer={(triggerNode) => {
|
|
238
|
+
const mapElement = document.getElementById("map");
|
|
239
|
+
return mapElement || triggerNode.parentElement || document.body;
|
|
240
|
+
}}
|
|
238
241
|
>
|
|
239
242
|
<StakeholderMarker
|
|
240
243
|
className={`${data.type} ${
|
|
@@ -32,7 +32,8 @@ export default function LocationIcon({
|
|
|
32
32
|
activeMarker,
|
|
33
33
|
setActiveMarker,
|
|
34
34
|
}) {
|
|
35
|
-
const
|
|
35
|
+
const rootsMapRef = useRef(new Map());
|
|
36
|
+
const markersRef = useRef([])
|
|
36
37
|
const isSelected = selectedMarkersId.includes(data.datastakeId);
|
|
37
38
|
const Marker = useMemo(() => {
|
|
38
39
|
if (isMineSite(data.type)) {
|
|
@@ -75,7 +76,22 @@ export default function LocationIcon({
|
|
|
75
76
|
}, [data.stakeholders, zoom]);
|
|
76
77
|
|
|
77
78
|
useEffect(() => {
|
|
78
|
-
|
|
79
|
+
const currentRoots = rootsMapRef.current;
|
|
80
|
+
const currentMarkers = markersRef.current;
|
|
81
|
+
|
|
82
|
+
currentMarkers.forEach(marker => {
|
|
83
|
+
if (mapRef.hasLayer(marker)) {
|
|
84
|
+
mapRef.removeLayer(marker);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
currentRoots.forEach(root => {
|
|
88
|
+
root.unmount();
|
|
89
|
+
});
|
|
90
|
+
currentRoots.clear();
|
|
91
|
+
markersRef.current = [];
|
|
92
|
+
|
|
93
|
+
// Create new markers
|
|
94
|
+
stakeholdersOfLocation.forEach((stakeholder, index) => {
|
|
79
95
|
const markerId = `${stakeholder.datastakeId}`;
|
|
80
96
|
const { x, y, radius, center } = getStakeholderPosition({
|
|
81
97
|
zoom,
|
|
@@ -94,6 +110,7 @@ export default function LocationIcon({
|
|
|
94
110
|
const pathLocLatLng = mapRef.layerPointToLatLng(pathLocPoint);
|
|
95
111
|
const isForceOpen = activeMarker?.datastakeId === data.datastakeId;
|
|
96
112
|
const iconSize = isSmallMarker(zoom) || isExtraSmallMarker(zoom) ? [11, 11] : [25, 25];
|
|
113
|
+
|
|
97
114
|
const marker = L.marker(stakeholderLatLng, {
|
|
98
115
|
icon: L.divIcon({
|
|
99
116
|
html: `<div id="${markerId}"></div>`,
|
|
@@ -102,31 +119,38 @@ export default function LocationIcon({
|
|
|
102
119
|
}),
|
|
103
120
|
}).addTo(mapRef);
|
|
104
121
|
|
|
105
|
-
|
|
106
|
-
root.current = createRoot(div);
|
|
122
|
+
markersRef.current.push(marker);
|
|
107
123
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
124
|
+
setTimeout(() => {
|
|
125
|
+
const div = document.getElementById(markerId);
|
|
126
|
+
if (div && !rootsMapRef.current.has(markerId)) {
|
|
127
|
+
const root = createRoot(div);
|
|
128
|
+
rootsMapRef.current.set(markerId, root);
|
|
129
|
+
|
|
130
|
+
root.render(
|
|
131
|
+
<StakeholderIcon
|
|
132
|
+
data={stakeholder}
|
|
133
|
+
zoom={zoom}
|
|
134
|
+
allData={allData}
|
|
135
|
+
link={link}
|
|
136
|
+
parentId={data.datastakeId}
|
|
137
|
+
renderTooltip={renderTooltip}
|
|
138
|
+
onClickLink={onClickLink}
|
|
139
|
+
selectedMarkersId={selectedMarkersId}
|
|
140
|
+
handleSelectMarker={handleSelectMarker}
|
|
141
|
+
mapRef={mapRef}
|
|
142
|
+
radius={radius}
|
|
143
|
+
index={index}
|
|
144
|
+
x={x}
|
|
145
|
+
y={y}
|
|
146
|
+
openPopupIdRef={openPopupIdRef}
|
|
147
|
+
polylinesRef={polylinesRef}
|
|
148
|
+
isForceOpen={isForceOpen}
|
|
149
|
+
activeMarker={activeMarker}
|
|
150
|
+
/>,
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
}, 0);
|
|
130
154
|
|
|
131
155
|
setMapMarkers((prev) => {
|
|
132
156
|
const array = [
|
|
@@ -162,6 +186,19 @@ export default function LocationIcon({
|
|
|
162
186
|
listOfPolylines: polylinesRef.current,
|
|
163
187
|
});
|
|
164
188
|
});
|
|
189
|
+
|
|
190
|
+
return () => {
|
|
191
|
+
markersRef.current.forEach(marker => {
|
|
192
|
+
if (mapRef.hasLayer(marker)) {
|
|
193
|
+
mapRef.removeLayer(marker);
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
rootsMapRef.current.forEach(root => {
|
|
197
|
+
root.unmount();
|
|
198
|
+
});
|
|
199
|
+
rootsMapRef.current.clear();
|
|
200
|
+
markersRef.current = [];
|
|
201
|
+
};
|
|
165
202
|
}, [stakeholdersOfLocation, selectedMarkersId, activeMarker]);
|
|
166
203
|
|
|
167
204
|
linkedNodesData.map((node) => {
|
|
@@ -213,8 +250,10 @@ export default function LocationIcon({
|
|
|
213
250
|
// (!openPopupIdRef.current || openPopupIdRef.current === data.datastakeId) &&
|
|
214
251
|
// isHovering
|
|
215
252
|
// }
|
|
216
|
-
|
|
217
|
-
|
|
253
|
+
getPopupContainer={(triggerNode) => {
|
|
254
|
+
const mapElement = document.getElementById("map");
|
|
255
|
+
return mapElement || triggerNode.parentElement || document.body;
|
|
256
|
+
}}
|
|
218
257
|
>
|
|
219
258
|
<div style={{ position: "relative", display: "inline-block" }}>
|
|
220
259
|
{(isSelected || selectedMarkersId.length === 0) && (
|
|
@@ -42,6 +42,7 @@ export default function StakeholderIcon({
|
|
|
42
42
|
link,
|
|
43
43
|
onClickLink: () => onClickLink(marker),
|
|
44
44
|
})}
|
|
45
|
+
getPopupContainer={() => document.getElementById("map")}
|
|
45
46
|
>
|
|
46
47
|
<div
|
|
47
48
|
key="single-marker"
|
|
@@ -91,6 +92,7 @@ export default function StakeholderIcon({
|
|
|
91
92
|
link,
|
|
92
93
|
onClickLink: () => onClickLink(marker),
|
|
93
94
|
})}
|
|
95
|
+
getPopupContainer={() => document.getElementById("map")}
|
|
94
96
|
>
|
|
95
97
|
<div
|
|
96
98
|
style={{
|
|
@@ -132,6 +134,7 @@ export default function StakeholderIcon({
|
|
|
132
134
|
link,
|
|
133
135
|
onClickLink: () => onClickLink(marker),
|
|
134
136
|
})}
|
|
137
|
+
getPopupContainer={() => document.getElementById("map")}
|
|
135
138
|
>
|
|
136
139
|
<Style
|
|
137
140
|
// onClick={toggleOpen}
|
|
@@ -82,43 +82,37 @@ export const useMap = ({
|
|
|
82
82
|
const highlightTable = {};
|
|
83
83
|
|
|
84
84
|
for (const [node] of graph) {
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if (current !== node && isLocation(currentType)) continue;
|
|
95
|
-
|
|
96
|
-
visited.add(current);
|
|
97
|
-
|
|
98
|
-
for (const neighbor of graph.get(current)) {
|
|
99
|
-
if (!visited.has(neighbor)) queue.push(neighbor);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
if (!isLocation(nodeTypes.get(node)) && stakeToLoc.has(node)) {
|
|
104
|
-
visited.add(stakeToLoc.get(node));
|
|
85
|
+
const highlighted = new Set();
|
|
86
|
+
|
|
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);
|
|
105
93
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
94
|
+
|
|
95
|
+
for (const neighbor of graph.get(node) || []) {
|
|
96
|
+
const neighborIsStakeholder = !isLocation(nodeTypes.get(neighbor));
|
|
97
|
+
|
|
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 {
|
|
107
|
+
highlighted.add(neighbor);
|
|
108
|
+
highlighted.add(neighborParent);
|
|
114
109
|
}
|
|
110
|
+
} else {
|
|
111
|
+
highlighted.add(neighbor);
|
|
115
112
|
}
|
|
116
113
|
}
|
|
117
|
-
for (const loc of extraLocs) {
|
|
118
|
-
visited.add(loc);
|
|
119
|
-
}
|
|
120
114
|
|
|
121
|
-
highlightTable[node] = [...
|
|
115
|
+
highlightTable[node] = [...highlighted];
|
|
122
116
|
}
|
|
123
117
|
|
|
124
118
|
return highlightTable;
|
|
@@ -283,7 +277,15 @@ export const useMap = ({
|
|
|
283
277
|
useEffect(() => {
|
|
284
278
|
if (mapRef) {
|
|
285
279
|
L.control.scale().addTo(mapRef);
|
|
286
|
-
L.tileLayer(TILE_LAYER_URL, {
|
|
280
|
+
L.tileLayer(TILE_LAYER_URL, {
|
|
281
|
+
access_token: MAP_TOKEN,
|
|
282
|
+
keepBuffer: 4,
|
|
283
|
+
updateWhenZooming: false,
|
|
284
|
+
updateInterval: 200,
|
|
285
|
+
maxNativeZoom: 18,
|
|
286
|
+
tileSize: 256,
|
|
287
|
+
fadeAnimation: true,
|
|
288
|
+
}).addTo(mapRef);
|
|
287
289
|
}
|
|
288
290
|
}, [mapRef]);
|
|
289
291
|
|
|
@@ -362,6 +364,28 @@ export const useMap = ({
|
|
|
362
364
|
}
|
|
363
365
|
}, [activeMarker, mapRef]);
|
|
364
366
|
|
|
367
|
+
useEffect(() => {
|
|
368
|
+
if (mapRef && type === "chain") {
|
|
369
|
+
const handleMapClick = (e) => {
|
|
370
|
+
const clickedElement = e.originalEvent.target;
|
|
371
|
+
const isMarkerClick = clickedElement.closest('.marker-chain') ||
|
|
372
|
+
clickedElement.closest('.leaflet-marker-icon');
|
|
373
|
+
|
|
374
|
+
if (!isMarkerClick && selectedMarkersId.length > 0) {
|
|
375
|
+
setSelectedMarkersId([]);
|
|
376
|
+
openPopupIdRef.current = null;
|
|
377
|
+
setMarkerWithPopup(null);
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
|
|
381
|
+
mapRef.on('click', handleMapClick);
|
|
382
|
+
|
|
383
|
+
return () => {
|
|
384
|
+
mapRef.off('click', handleMapClick);
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
}, [mapRef, type, selectedMarkersId]);
|
|
388
|
+
|
|
365
389
|
return {
|
|
366
390
|
container,
|
|
367
391
|
activeMarker,
|
|
@@ -21,6 +21,7 @@ function TradeRelationship({
|
|
|
21
21
|
onFilterChange = () => {},
|
|
22
22
|
renderTooltipItems = () => [],
|
|
23
23
|
getTotal = () => 0,
|
|
24
|
+
onRenderComplete = () => {},
|
|
24
25
|
}) {
|
|
25
26
|
const reactFlowWrapper = useRef(null);
|
|
26
27
|
const [nodes, setNodes] = useNodesState([]);
|
|
@@ -30,6 +31,27 @@ function TradeRelationship({
|
|
|
30
31
|
// const [initCenter, setInitCenter] = useState(true);
|
|
31
32
|
const [associatedNodes, setAssociatedNodes] = useState(null);
|
|
32
33
|
|
|
34
|
+
const isFullyRenderedRef = useRef(false);
|
|
35
|
+
const [isFullyRendered, setIsFullyRendered] = useState(false);
|
|
36
|
+
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
isFullyRenderedRef.current = false;
|
|
39
|
+
setIsFullyRendered(false);
|
|
40
|
+
setActiveNode(null);
|
|
41
|
+
}, [data]);
|
|
42
|
+
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
if (nodes.length > 0 && edges.length > 0 && !isFullyRenderedRef.current) {
|
|
45
|
+
const timeoutId = setTimeout(() => {
|
|
46
|
+
isFullyRenderedRef.current = true;
|
|
47
|
+
setIsFullyRendered(true);
|
|
48
|
+
onRenderComplete(true);
|
|
49
|
+
}, 200);
|
|
50
|
+
|
|
51
|
+
return () => clearTimeout(timeoutId);
|
|
52
|
+
}
|
|
53
|
+
}, [nodes.length, edges.length, associatedNodes]);
|
|
54
|
+
|
|
33
55
|
useEffect(() => {
|
|
34
56
|
setActiveNode(null);
|
|
35
57
|
}, [data]);
|
|
@@ -58,7 +80,7 @@ function TradeRelationship({
|
|
|
58
80
|
[edges, activeNode, associatedNodes]
|
|
59
81
|
);
|
|
60
82
|
|
|
61
|
-
useEffect(() => {
|
|
83
|
+
useEffect(() => {
|
|
62
84
|
let yInit = 0;
|
|
63
85
|
let xInit = 0;
|
|
64
86
|
const isBilateral = data?.sources?.length >= 1;
|
|
@@ -71,10 +93,9 @@ function TradeRelationship({
|
|
|
71
93
|
setEdges([]);
|
|
72
94
|
return;
|
|
73
95
|
}
|
|
74
|
-
|
|
75
96
|
const _nodes = [
|
|
76
97
|
{
|
|
77
|
-
id: data.id,
|
|
98
|
+
id: data.id?.toString(),
|
|
78
99
|
type: "expandedNode",
|
|
79
100
|
position: {
|
|
80
101
|
x: xInit,
|
|
@@ -89,10 +110,10 @@ function TradeRelationship({
|
|
|
89
110
|
if (isBilateral) {
|
|
90
111
|
(data.sources || []).forEach((source) => {
|
|
91
112
|
const hasPrev = false;
|
|
92
|
-
|
|
113
|
+
const edge = {
|
|
93
114
|
id: `e-${data.id}-${source}`,
|
|
94
|
-
source: source,
|
|
95
|
-
type: "
|
|
115
|
+
source: source?.toString(),
|
|
116
|
+
type: "defaultEdge",
|
|
96
117
|
target: data?.id?.toString(),
|
|
97
118
|
sourceHandle: "left",
|
|
98
119
|
targetHandle: "right",
|
|
@@ -106,7 +127,8 @@ function TradeRelationship({
|
|
|
106
127
|
tooltipTitle,
|
|
107
128
|
moreLeft: false,
|
|
108
129
|
},
|
|
109
|
-
}
|
|
130
|
+
};
|
|
131
|
+
_edges.push(edge);
|
|
110
132
|
});
|
|
111
133
|
}
|
|
112
134
|
|
|
@@ -164,7 +186,7 @@ function TradeRelationship({
|
|
|
164
186
|
? false
|
|
165
187
|
: true;
|
|
166
188
|
|
|
167
|
-
|
|
189
|
+
const edge = {
|
|
168
190
|
id: `e-${ch.id}-${source}`,
|
|
169
191
|
source: hasPrev ? source : ch?.id?.toString(),
|
|
170
192
|
type: isCustom ? "verticalPath" : "defaultEdge",
|
|
@@ -182,7 +204,8 @@ function TradeRelationship({
|
|
|
182
204
|
tooltipTitle,
|
|
183
205
|
moreLeft: prevChildren.length > children.length,
|
|
184
206
|
},
|
|
185
|
-
}
|
|
207
|
+
};
|
|
208
|
+
_edges.push(edge);
|
|
186
209
|
|
|
187
210
|
if (isCustom) {
|
|
188
211
|
customIndex += 1;
|
|
@@ -230,11 +253,25 @@ function TradeRelationship({
|
|
|
230
253
|
maxHeight: 0,
|
|
231
254
|
});
|
|
232
255
|
|
|
256
|
+
// Check for potential ID mismatches
|
|
257
|
+
const nodeIds = _nodes.map(n => n.id);
|
|
258
|
+
const edgeIssues = _edges.filter(e => {
|
|
259
|
+
const sourceExists = nodeIds.includes(e.source);
|
|
260
|
+
const targetExists = nodeIds.includes(e.target);
|
|
261
|
+
return !sourceExists || !targetExists;
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
// Set nodes first
|
|
233
265
|
setNodes(_nodes);
|
|
234
|
-
|
|
266
|
+
|
|
267
|
+
const timeoutId = setTimeout(() => {
|
|
268
|
+
setEdges(_edges);
|
|
269
|
+
}, 100); // 100ms is imperceptible to users but ensures React Flow is ready
|
|
270
|
+
|
|
271
|
+
// Cleanup to prevent memory leaks if component unmounts quickly
|
|
272
|
+
return () => clearTimeout(timeoutId);
|
|
235
273
|
}, [data, activeNode]);
|
|
236
274
|
|
|
237
|
-
// Used to find associated nodes, when a node is selected
|
|
238
275
|
useEffect(() => {
|
|
239
276
|
if (activeNode) {
|
|
240
277
|
let _associatedNodesRight = [activeNode];
|
|
@@ -293,6 +330,7 @@ function TradeRelationship({
|
|
|
293
330
|
|
|
294
331
|
return (
|
|
295
332
|
<BaseGraph
|
|
333
|
+
key={JSON.stringify(nodes) + JSON.stringify(edges)}
|
|
296
334
|
nodes={mappedNodes}
|
|
297
335
|
edges={mappedEdges}
|
|
298
336
|
maxZoom={maxZoom}
|
|
@@ -49,18 +49,22 @@ const BaseGraph = forwardRef(function BaseGraph(
|
|
|
49
49
|
return result;
|
|
50
50
|
}, [nodes.length, mandatoryNodesToFit?.length, mandatoryNodesToFit]);
|
|
51
51
|
|
|
52
|
+
// In BaseGraph.jsx, replace the useEffect with:
|
|
52
53
|
useEffect(() => {
|
|
53
54
|
if (nodesToFit.length === 0) return;
|
|
54
55
|
|
|
55
|
-
requestAnimationFrame
|
|
56
|
+
// Use setTimeout instead of requestAnimationFrame to ensure nodes are rendered
|
|
57
|
+
const timer = setTimeout(() => {
|
|
56
58
|
fitView({
|
|
57
59
|
padding: 0.4,
|
|
58
60
|
nodes: [...nodesToFit],
|
|
59
61
|
// duration: withDuration ? 300 : undefined,
|
|
60
62
|
maxZoom: 0.9,
|
|
61
63
|
});
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
+
}, 100); // Small delay to ensure nodes are rendered
|
|
65
|
+
|
|
66
|
+
return () => clearTimeout(timer);
|
|
67
|
+
}, [nodesToFit.length, nodesToFit.map(n => `${n.id}-${n.width}-${n.height}`).join(','), withDuration]);
|
|
64
68
|
|
|
65
69
|
return (
|
|
66
70
|
<ComponentWithFocus>
|
|
@@ -86,7 +90,7 @@ const BaseGraph = forwardRef(function BaseGraph(
|
|
|
86
90
|
fitView={true} // zoom out on default
|
|
87
91
|
fitViewOptions={{
|
|
88
92
|
padding: 0.2, //zoom out on default
|
|
89
|
-
|
|
93
|
+
duration: withDuration ? 300 : undefined,
|
|
90
94
|
}}
|
|
91
95
|
{...props}
|
|
92
96
|
>
|
|
@@ -134,7 +134,7 @@ const BaseScreen = ({
|
|
|
134
134
|
<div className="daf-table-wrapper pagination-w-padding">
|
|
135
135
|
<DAFTable
|
|
136
136
|
columns={columns}
|
|
137
|
-
data={data?.data}
|
|
137
|
+
data={Array.isArray(data?.data) ? data?.data : data?.data?.data}
|
|
138
138
|
loading={loading}
|
|
139
139
|
hideOnLoading={false}
|
|
140
140
|
pagination={pagination}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { Tag, Tooltip } from 'antd'
|
|
3
|
+
import { formatClassname } from '../../../../../helpers/ClassesHelper.js'
|
|
4
|
+
|
|
5
|
+
function MissingTagButton({
|
|
6
|
+
hasMissing,
|
|
7
|
+
setHighlightMandatory,
|
|
8
|
+
highlightMandatory,
|
|
9
|
+
t,
|
|
10
|
+
}) {
|
|
11
|
+
return (
|
|
12
|
+
<>
|
|
13
|
+
{hasMissing ? (
|
|
14
|
+
<Tag
|
|
15
|
+
onClick={() => setHighlightMandatory(!highlightMandatory)}
|
|
16
|
+
className={formatClassname(['ml-2 highlight-tag', highlightMandatory && 'highlighted'])}
|
|
17
|
+
style={{textAlign: "center"}}
|
|
18
|
+
>
|
|
19
|
+
{t('missing-inputs')}
|
|
20
|
+
</Tag>
|
|
21
|
+
) : (
|
|
22
|
+
<Tooltip title={t('all-inputs-fullfilled')}>
|
|
23
|
+
<Tag
|
|
24
|
+
onClick={() => setHighlightMandatory(!highlightMandatory)}
|
|
25
|
+
className={formatClassname(['ml-2 highlight-tag disabled'])}
|
|
26
|
+
style={{textAlign: "center"}}
|
|
27
|
+
>
|
|
28
|
+
{t('missing-inputs')}
|
|
29
|
+
</Tag>
|
|
30
|
+
</Tooltip>
|
|
31
|
+
)}
|
|
32
|
+
</>
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export default MissingTagButton;
|
|
@@ -9,6 +9,11 @@ export const defaultMapConfig = {
|
|
|
9
9
|
preferCanvas: true,
|
|
10
10
|
zoomControl: false,
|
|
11
11
|
maxBounds: maxBounds,
|
|
12
|
+
zoomSnap: 0.5,
|
|
13
|
+
zoomDelta: 0.5,
|
|
14
|
+
wheelPxPerZoomLevel: 150,
|
|
15
|
+
zoomAnimation: true,
|
|
16
|
+
zoomAnimationThreshold: 10,
|
|
12
17
|
};
|
|
13
18
|
|
|
14
19
|
export const filterValidGPS = (data) => {
|
|
@@ -4,6 +4,7 @@ import Widget from '../../../../../core/components/Dashboard/Widget/index.jsx';
|
|
|
4
4
|
import Map from '../../../../../core/components/Dashboard/Map/index.jsx';
|
|
5
5
|
import { getTagColor } from '../../../../../utils/productTag.js';
|
|
6
6
|
import PropTypes from 'prop-types';
|
|
7
|
+
import { findOptions } from '../../../../../../helpers/StringHelper.js';
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
function SupplyChainMap({selectedSources = {}, t = () => {}, goTo = () => {}, options = {}, getRedirectLink = () => {} }) {
|
|
@@ -34,13 +35,13 @@ function SupplyChainMap({selectedSources = {}, t = () => {}, goTo = () => {}, op
|
|
|
34
35
|
data={Array.isArray(data) && data.length > 0 ? data : []}
|
|
35
36
|
renderTooltip={(data) => {
|
|
36
37
|
const productsText = data?.products?.[0];
|
|
37
|
-
const minerals = options?.
|
|
38
|
+
const minerals = options?.mineralOptions || [];
|
|
38
39
|
const participants = data?.stakeholders?.map((stakeholder) => stakeholder.name);
|
|
39
40
|
return [
|
|
40
41
|
{
|
|
41
42
|
label: t("Products"),
|
|
42
43
|
value:
|
|
43
|
-
|
|
44
|
+
findOptions(productsText, minerals) ||
|
|
44
45
|
productsText ||
|
|
45
46
|
"-",
|
|
46
47
|
...(productsText && { tag: getTagColor(productsText) }),
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
export const checkboxConfig = {
|
|
2
|
-
name: 'Name',
|
|
3
|
-
datastakeId: 'ID'
|
|
4
|
-
}
|
|
5
|
-
|
|
6
1
|
export const getFiltersConfig = ({t}) => {
|
|
7
2
|
return {
|
|
8
3
|
timeframe: {
|
|
@@ -13,11 +8,6 @@ export const getFiltersConfig = ({t}) => {
|
|
|
13
8
|
}
|
|
14
9
|
}
|
|
15
10
|
|
|
16
|
-
export const filtersConfig = {
|
|
17
|
-
name: '',
|
|
18
|
-
datastakeId: '',
|
|
19
|
-
};
|
|
20
|
-
|
|
21
11
|
export const getFilterOptions = (options, t) => {
|
|
22
12
|
const { timeframe = [] } = options || {};
|
|
23
13
|
const _default = {
|