datastake-daf 0.6.816 → 0.6.817
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 +1196 -1285
- package/dist/pages/index.js +1315 -579
- package/dist/services/index.js +202 -0
- package/dist/utils/index.js +28 -0
- package/package.json +1 -1
- package/src/@daf/core/components/Charts/RadarChart/index.jsx +3 -12
- package/src/@daf/core/components/Charts/style.js +1 -2
- package/src/@daf/core/components/Dashboard/Map/ChainIcon/index.js +123 -104
- package/src/@daf/core/components/Dashboard/Widget/VegetationWidget/index.jsx +4 -0
- package/src/@daf/core/components/Table/index.jsx +11 -6
- package/src/@daf/pages/Events/Activities/columns.js +15 -11
- package/src/@daf/pages/Events/Incidents/columns.js +15 -11
- package/src/@daf/pages/Events/Testimonials/columns.js +173 -0
- package/src/@daf/pages/Events/Testimonials/config.js +175 -0
- package/src/@daf/pages/Events/columns.js +7 -3
- package/src/@daf/pages/Locations/ConflictAreas/columns.js +140 -0
- package/src/@daf/pages/Locations/ConflictAreas/config.js +41 -0
- package/src/@daf/pages/Locations/MineSite/columns.js +21 -12
- package/src/@daf/pages/Locations/MineSite/config.js +2 -1
- package/src/@daf/pages/Locations/columns.js +7 -3
- package/src/@daf/pages/Stakeholders/ArmedGroups/columns.js +110 -0
- package/src/@daf/pages/Stakeholders/ArmedGroups/config.js +41 -0
- package/src/@daf/pages/Stakeholders/Operators/columns.js +30 -14
- package/src/@daf/pages/Stakeholders/Workers/columns.js +23 -13
- package/src/@daf/pages/Stakeholders/columns.js +8 -4
- package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/BiodiversityHabitat/ObservedFauna.jsx +11 -6
- package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MangroveGrowth/PlantedSpecies.jsx +10 -25
- package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MangroveGrowth/SeedlingsHeight.jsx +13 -10
- package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MangroveGrowth/VegetationHealth.jsx +4 -19
- package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/SoilWaterProfile/SoilType.jsx +10 -22
- package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/SoilWaterProfile/WaterQuality.jsx +10 -26
- package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/chartHelpers.js +0 -74
- package/src/@daf/pages/TablePage/config.js +1 -1
- package/src/@daf/pages/TablePage/helper.js +45 -0
- package/src/@daf/services/EventsService.js +115 -0
- package/src/@daf/services/LinkedSubjects.js +1 -0
- package/src/@daf/services/WorkersService.js +80 -0
- package/src/helpers/errorHandling.js +142 -74
- package/src/services.js +3 -1
- package/src/utils.js +1 -1
- package/dist/style/datastake/mapbox-gl.css +0 -330
package/dist/services/index.js
CHANGED
|
@@ -1458,6 +1458,11 @@ class LinkedSubjectsService extends BaseService {
|
|
|
1458
1458
|
getForm({
|
|
1459
1459
|
namespace
|
|
1460
1460
|
}, language = "en", scope) {
|
|
1461
|
+
console.log({
|
|
1462
|
+
namespace,
|
|
1463
|
+
language,
|
|
1464
|
+
scope
|
|
1465
|
+
});
|
|
1461
1466
|
return this.apiGet({
|
|
1462
1467
|
url: `forms/${namespace === "documents" ? namespace : getNamespace(namespace)}`,
|
|
1463
1468
|
isApp: true,
|
|
@@ -1727,6 +1732,201 @@ class PartnerService extends BaseService {
|
|
|
1727
1732
|
}
|
|
1728
1733
|
var PartnerService$1 = createLazyService(PartnerService);
|
|
1729
1734
|
|
|
1735
|
+
class EventsService extends BaseService {
|
|
1736
|
+
getForm({
|
|
1737
|
+
scope
|
|
1738
|
+
}, language = "en") {
|
|
1739
|
+
return this.apiGet({
|
|
1740
|
+
isApp: true,
|
|
1741
|
+
url: `/forms/event`,
|
|
1742
|
+
params: {
|
|
1743
|
+
scope,
|
|
1744
|
+
language
|
|
1745
|
+
}
|
|
1746
|
+
});
|
|
1747
|
+
}
|
|
1748
|
+
getWithModule({
|
|
1749
|
+
query,
|
|
1750
|
+
signal,
|
|
1751
|
+
module
|
|
1752
|
+
}) {
|
|
1753
|
+
return this.apiGet({
|
|
1754
|
+
isApp: true,
|
|
1755
|
+
url: `/${module}/event`,
|
|
1756
|
+
params: query,
|
|
1757
|
+
signal
|
|
1758
|
+
});
|
|
1759
|
+
}
|
|
1760
|
+
getOne({
|
|
1761
|
+
id,
|
|
1762
|
+
module,
|
|
1763
|
+
signal
|
|
1764
|
+
}) {
|
|
1765
|
+
return this.apiGet({
|
|
1766
|
+
url: `/${module}/event/${id}`,
|
|
1767
|
+
isApp: true,
|
|
1768
|
+
signal
|
|
1769
|
+
});
|
|
1770
|
+
}
|
|
1771
|
+
get(query, signal) {
|
|
1772
|
+
return this.apiGet({
|
|
1773
|
+
isApp: true,
|
|
1774
|
+
url: "/event",
|
|
1775
|
+
params: query,
|
|
1776
|
+
signal
|
|
1777
|
+
});
|
|
1778
|
+
}
|
|
1779
|
+
getData(id, sourceId, source, version) {
|
|
1780
|
+
return this.apiGet({
|
|
1781
|
+
isApp: true,
|
|
1782
|
+
url: `/event/${id}`,
|
|
1783
|
+
params: {
|
|
1784
|
+
authorId: sourceId,
|
|
1785
|
+
source,
|
|
1786
|
+
version
|
|
1787
|
+
}
|
|
1788
|
+
});
|
|
1789
|
+
}
|
|
1790
|
+
getLinking(query) {
|
|
1791
|
+
return this.apiGet({
|
|
1792
|
+
isApp: true,
|
|
1793
|
+
url: "/event/linking",
|
|
1794
|
+
params: query
|
|
1795
|
+
});
|
|
1796
|
+
}
|
|
1797
|
+
submit(payload) {
|
|
1798
|
+
if (payload.id) {
|
|
1799
|
+
return this.apiPut({
|
|
1800
|
+
isApp: true,
|
|
1801
|
+
url: `/event/${payload.id}`,
|
|
1802
|
+
data: filterCreateData(payload)
|
|
1803
|
+
});
|
|
1804
|
+
}
|
|
1805
|
+
if (payload?.form) {
|
|
1806
|
+
delete payload.form;
|
|
1807
|
+
return this.apiPut({
|
|
1808
|
+
isApp: true,
|
|
1809
|
+
url: "/event",
|
|
1810
|
+
data: filterCreateData(payload)
|
|
1811
|
+
});
|
|
1812
|
+
}
|
|
1813
|
+
return this.apiPost({
|
|
1814
|
+
isApp: true,
|
|
1815
|
+
url: "/event",
|
|
1816
|
+
data: filterCreateData(payload)
|
|
1817
|
+
});
|
|
1818
|
+
}
|
|
1819
|
+
submitStep(data, id) {
|
|
1820
|
+
return this.apiPut({
|
|
1821
|
+
isApp: true,
|
|
1822
|
+
url: `/event/submit/${id}`,
|
|
1823
|
+
data: filterCreateData(data)
|
|
1824
|
+
});
|
|
1825
|
+
}
|
|
1826
|
+
remove(id, data) {
|
|
1827
|
+
return this.apiDelete({
|
|
1828
|
+
isApp: true,
|
|
1829
|
+
url: `/event/${id}/remove`,
|
|
1830
|
+
data: data
|
|
1831
|
+
});
|
|
1832
|
+
}
|
|
1833
|
+
submitForm(id) {
|
|
1834
|
+
const app = window.globalServicesConfig.application;
|
|
1835
|
+
return this.apiPost({
|
|
1836
|
+
isApp: true,
|
|
1837
|
+
url: `/${app}/versioning/submit/Event/${id}`
|
|
1838
|
+
});
|
|
1839
|
+
}
|
|
1840
|
+
getOptions() {
|
|
1841
|
+
return this.apiGet({
|
|
1842
|
+
isApp: true,
|
|
1843
|
+
url: `/forms/options`,
|
|
1844
|
+
params: {
|
|
1845
|
+
id: "categoryOptions,eventsType,testimonialsType,eventCategory,countries,eventCategoryOptions"
|
|
1846
|
+
}
|
|
1847
|
+
});
|
|
1848
|
+
}
|
|
1849
|
+
}
|
|
1850
|
+
var EventsService$1 = createLazyService(EventsService);
|
|
1851
|
+
|
|
1852
|
+
class WorkersService extends BaseService {
|
|
1853
|
+
get(params) {
|
|
1854
|
+
return this.apiGet({
|
|
1855
|
+
isApp: true,
|
|
1856
|
+
url: "/stakeholder",
|
|
1857
|
+
params
|
|
1858
|
+
});
|
|
1859
|
+
}
|
|
1860
|
+
getForm(scope = "modalNashirikiWorker", language = "en") {
|
|
1861
|
+
return this.apiGet({
|
|
1862
|
+
isApp: true,
|
|
1863
|
+
url: `/forms/stakeholder`,
|
|
1864
|
+
params: {
|
|
1865
|
+
scope,
|
|
1866
|
+
language
|
|
1867
|
+
}
|
|
1868
|
+
});
|
|
1869
|
+
}
|
|
1870
|
+
getData(id, sourceId, version, source) {
|
|
1871
|
+
return this.apiGet({
|
|
1872
|
+
isApp: true,
|
|
1873
|
+
url: `/stakeholder/${id}`,
|
|
1874
|
+
params: {
|
|
1875
|
+
authorId: sourceId,
|
|
1876
|
+
version,
|
|
1877
|
+
source
|
|
1878
|
+
}
|
|
1879
|
+
});
|
|
1880
|
+
}
|
|
1881
|
+
submit(payload) {
|
|
1882
|
+
if (payload.id) {
|
|
1883
|
+
// const { id, ...data } = payload;
|
|
1884
|
+
return this.apiPut({
|
|
1885
|
+
isApp: true,
|
|
1886
|
+
url: `/stakeholder/${payload.id}`,
|
|
1887
|
+
data: filterCreateData(payload)
|
|
1888
|
+
});
|
|
1889
|
+
}
|
|
1890
|
+
if (payload?.form) {
|
|
1891
|
+
delete payload.form;
|
|
1892
|
+
return this.apiPost({
|
|
1893
|
+
isApp: true,
|
|
1894
|
+
url: "/stakeholder",
|
|
1895
|
+
data: filterCreateData(payload)
|
|
1896
|
+
});
|
|
1897
|
+
}
|
|
1898
|
+
return this.apiPost({
|
|
1899
|
+
isApp: true,
|
|
1900
|
+
url: "/stakeholder",
|
|
1901
|
+
data: filterCreateData(payload)
|
|
1902
|
+
});
|
|
1903
|
+
}
|
|
1904
|
+
submitStep(data, id) {
|
|
1905
|
+
return this.apiPut({
|
|
1906
|
+
isApp: true,
|
|
1907
|
+
url: `/stakeholder/submit/${id}`,
|
|
1908
|
+
data: filterCreateData(data)
|
|
1909
|
+
});
|
|
1910
|
+
}
|
|
1911
|
+
remove(id, data) {
|
|
1912
|
+
return this.apiDelete({
|
|
1913
|
+
isApp: true,
|
|
1914
|
+
url: `/stakeholder/${id}/remove`,
|
|
1915
|
+
data: data
|
|
1916
|
+
});
|
|
1917
|
+
}
|
|
1918
|
+
getOptions() {
|
|
1919
|
+
return this.apiGet({
|
|
1920
|
+
isApp: true,
|
|
1921
|
+
url: `/forms/options`,
|
|
1922
|
+
params: {
|
|
1923
|
+
id: "activityAtSiteOptions,category,countries,optionPositionSupplyChain,subCategory"
|
|
1924
|
+
}
|
|
1925
|
+
});
|
|
1926
|
+
}
|
|
1927
|
+
}
|
|
1928
|
+
var WorkersService$1 = createLazyService(WorkersService);
|
|
1929
|
+
|
|
1730
1930
|
exports.AdminService = AdminService$1;
|
|
1731
1931
|
exports.AuthenticationService = AuthenticationService$1;
|
|
1732
1932
|
exports.BaseHTTPService = BaseHTTPService;
|
|
@@ -1736,6 +1936,7 @@ exports.DashboardService = DashboardService$1;
|
|
|
1736
1936
|
exports.DataStoreService = DataStoreService$1;
|
|
1737
1937
|
exports.ErrorHandler = ErrorHandler;
|
|
1738
1938
|
exports.ErrorService = ErrorService;
|
|
1939
|
+
exports.EventsService = EventsService$1;
|
|
1739
1940
|
exports.LinkedSubjectsService = LinkedSubjects;
|
|
1740
1941
|
exports.NotificationService = NotificationService$1;
|
|
1741
1942
|
exports.OperatorService = OperatorService$1;
|
|
@@ -1743,6 +1944,7 @@ exports.PartnerService = PartnerService$1;
|
|
|
1743
1944
|
exports.QueryService = QueryService$1;
|
|
1744
1945
|
exports.SourceService = SourceService$1;
|
|
1745
1946
|
exports.UserService = UserService$1;
|
|
1947
|
+
exports.WorkersService = WorkersService$1;
|
|
1746
1948
|
exports.configureServices = configureServices;
|
|
1747
1949
|
exports.createLazyService = createLazyService;
|
|
1748
1950
|
exports.getServicesConfig = getServicesConfig;
|
package/dist/utils/index.js
CHANGED
|
@@ -14105,6 +14105,32 @@ const buildQueryString = params => {
|
|
|
14105
14105
|
return query ? `?${query}` : '';
|
|
14106
14106
|
};
|
|
14107
14107
|
|
|
14108
|
+
/**
|
|
14109
|
+
* Check if a successful response contains embedded error data
|
|
14110
|
+
*/
|
|
14111
|
+
const isErrorResponse = data => {
|
|
14112
|
+
if (!data) return false;
|
|
14113
|
+
return (
|
|
14114
|
+
// Check for Exception names
|
|
14115
|
+
data.name && data.name.includes('Exception') ||
|
|
14116
|
+
// Check for nested response with error status
|
|
14117
|
+
data.response?.statusCode && data.response.statusCode >= 400 ||
|
|
14118
|
+
// Check for top-level error status
|
|
14119
|
+
data.statusCode && data.statusCode >= 400 ||
|
|
14120
|
+
// Check for explicit error flag
|
|
14121
|
+
data.error === true ||
|
|
14122
|
+
// Check for nested error property
|
|
14123
|
+
data.response?.error && data.response.error !== null
|
|
14124
|
+
);
|
|
14125
|
+
};
|
|
14126
|
+
|
|
14127
|
+
/**
|
|
14128
|
+
* Extract error message from various error response formats
|
|
14129
|
+
*/
|
|
14130
|
+
const getErrorMessage = data => {
|
|
14131
|
+
return data?.message || data?.response?.message || data?.response?.error || 'An error occurred';
|
|
14132
|
+
};
|
|
14133
|
+
|
|
14108
14134
|
/**
|
|
14109
14135
|
* Generic error handler factory for axios requests
|
|
14110
14136
|
* Highly configurable to adapt to different project needs
|
|
@@ -15091,6 +15117,7 @@ exports.formatToKebabCase = formatToKebabCase$1;
|
|
|
15091
15117
|
exports.getAdminLevelName = getAdminLevelName;
|
|
15092
15118
|
exports.getDefaultActiveFilters = getDefaultActiveFilters;
|
|
15093
15119
|
exports.getDivergenceOrEqual = getDivergenceOrEqual;
|
|
15120
|
+
exports.getErrorMessage = getErrorMessage;
|
|
15094
15121
|
exports.getImageUploadViewValue = getImageUploadViewValue;
|
|
15095
15122
|
exports.getInterface = getInterface;
|
|
15096
15123
|
exports.getNkey = getNkey;
|
|
@@ -15114,6 +15141,7 @@ exports.hasKeyInObject = hasKeyInObject;
|
|
|
15114
15141
|
exports.hasNotChanged = hasNotChanged;
|
|
15115
15142
|
exports.isArrayOfObjects = isArrayOfObjects;
|
|
15116
15143
|
exports.isEmptyOrSpaces = isEmptyOrSpaces;
|
|
15144
|
+
exports.isErrorResponse = isErrorResponse;
|
|
15117
15145
|
exports.isModuleApproved = isModuleApproved;
|
|
15118
15146
|
exports.isProxy = isProxy;
|
|
15119
15147
|
exports.isSuperAdmin = isSuperAdmin;
|
package/package.json
CHANGED
|
@@ -59,18 +59,9 @@ const RadarChart = ({
|
|
|
59
59
|
}
|
|
60
60
|
: { showCrosshairs: false, showMarkers: true, ...tooltipConfig },
|
|
61
61
|
color: color || token.colorPrimary7,
|
|
62
|
-
|
|
63
|
-
paddingX: 60,
|
|
64
|
-
paddingY: 60,
|
|
65
62
|
xAxis: {
|
|
66
63
|
label: {
|
|
67
64
|
formatter: formattedXAxis,
|
|
68
|
-
offset: 15,
|
|
69
|
-
style: {
|
|
70
|
-
fontSize: 12,
|
|
71
|
-
fill: '#666',
|
|
72
|
-
textAlign: 'center',
|
|
73
|
-
},
|
|
74
65
|
},
|
|
75
66
|
line: null,
|
|
76
67
|
tickLine: null,
|
|
@@ -151,9 +142,9 @@ const RadarChart = ({
|
|
|
151
142
|
}, []);
|
|
152
143
|
|
|
153
144
|
return (
|
|
154
|
-
<div className="flex flex-1 flex-column justify-content-center"
|
|
155
|
-
<div className="flex justify-content-center"
|
|
156
|
-
<Container ref={containerRef} height={height} isPdf={isPdf}
|
|
145
|
+
<div className="flex flex-1 flex-column justify-content-center">
|
|
146
|
+
<div className="flex justify-content-center">
|
|
147
|
+
<Container ref={containerRef} height={height} isPdf={isPdf}></Container>
|
|
157
148
|
</div>
|
|
158
149
|
{legendEnabled && legendPosition === 'bottom' && (
|
|
159
150
|
<CustomLegend
|
|
@@ -2,8 +2,7 @@ import styled from "styled-components";
|
|
|
2
2
|
|
|
3
3
|
const Container = styled.div`
|
|
4
4
|
height: ${props => props.height || '300px'};
|
|
5
|
-
width: ${props => props.isPdf ? (props.width ? props.width : '1000px') : 'calc(100% - 48px)'};
|
|
6
|
-
overflow: ${props => props.style?.overflow || 'visible'};
|
|
5
|
+
width: ${props => props.isPdf ? (props.width ? props.width : '1000px') : 'calc(100% - 48px)'};
|
|
7
6
|
`;
|
|
8
7
|
|
|
9
8
|
export default Container;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useMemo, useEffect, useRef, useState } from "react";
|
|
2
|
+
import { createPortal } from "react-dom";
|
|
2
3
|
import {
|
|
3
4
|
isMineSite,
|
|
4
5
|
getStakeholderPosition,
|
|
@@ -10,7 +11,6 @@ import {
|
|
|
10
11
|
import MineSiteMarker from "./Markers/SVG/MinesiteMarker.js";
|
|
11
12
|
import VillageMarker from "./Markers/SVG/VillageMarker.js";
|
|
12
13
|
import StakeholderIcon from "./Markers/StakeholderMarker.js";
|
|
13
|
-
import { createRoot } from "react-dom/client";
|
|
14
14
|
import * as L from "leaflet";
|
|
15
15
|
import { Popover } from "antd";
|
|
16
16
|
import { renderTooltipJsx } from "../../../../../utils/tooltip.js";
|
|
@@ -32,8 +32,8 @@ export default function LocationIcon({
|
|
|
32
32
|
activeMarker,
|
|
33
33
|
setActiveMarker,
|
|
34
34
|
}) {
|
|
35
|
-
const
|
|
36
|
-
const
|
|
35
|
+
const markersRef = useRef([]);
|
|
36
|
+
const [portalContainers, setPortalContainers] = useState([]);
|
|
37
37
|
const isSelected = selectedMarkersId.includes(data.datastakeId);
|
|
38
38
|
const Marker = useMemo(() => {
|
|
39
39
|
if (isMineSite(data.type)) {
|
|
@@ -114,25 +114,31 @@ export default function LocationIcon({
|
|
|
114
114
|
}, [JSON.stringify(allData), JSON.stringify(data.links), JSON.stringify(data.stakeholders), zoom]);
|
|
115
115
|
|
|
116
116
|
const stakeholdersOfLocation = useMemo(() => {
|
|
117
|
-
return data?.stakeholders || []
|
|
118
|
-
|
|
117
|
+
return (data?.stakeholders || []).filter(stakeholder => {
|
|
118
|
+
if (!stakeholder.links || stakeholder.links.length === 0) {
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const locationsWithThisStakeholder = allData
|
|
123
|
+
.filter(loc =>
|
|
124
|
+
loc.stakeholders?.some(s => s.datastakeId === stakeholder.datastakeId)
|
|
125
|
+
)
|
|
126
|
+
.map(loc => loc.datastakeId);
|
|
127
|
+
|
|
128
|
+
const primaryLocation = locationsWithThisStakeholder.sort()[0];
|
|
129
|
+
return data.datastakeId === primaryLocation;
|
|
130
|
+
});
|
|
131
|
+
}, [data.stakeholders, data.datastakeId, allData, zoom]);
|
|
119
132
|
|
|
120
133
|
useEffect(() => {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
currentMarkers.forEach(marker => {
|
|
125
|
-
if (mapRef.hasLayer(marker)) {
|
|
134
|
+
markersRef.current.forEach(marker => {
|
|
135
|
+
if (mapRef && mapRef.hasLayer(marker)) {
|
|
126
136
|
mapRef.removeLayer(marker);
|
|
127
137
|
}
|
|
128
138
|
});
|
|
129
|
-
currentRoots.forEach(root => {
|
|
130
|
-
root.unmount();
|
|
131
|
-
});
|
|
132
|
-
currentRoots.clear();
|
|
133
139
|
markersRef.current = [];
|
|
140
|
+
setPortalContainers([]);
|
|
134
141
|
|
|
135
|
-
// Only create stakeholder markers if this location or any of its stakeholders are selected
|
|
136
142
|
const shouldShowStakeholders = isSelected || stakeholdersOfLocation.some(stk =>
|
|
137
143
|
selectedMarkersId.includes(stk.datastakeId)
|
|
138
144
|
);
|
|
@@ -141,9 +147,11 @@ export default function LocationIcon({
|
|
|
141
147
|
return;
|
|
142
148
|
}
|
|
143
149
|
|
|
144
|
-
// Create
|
|
150
|
+
// Create markers and store their container references
|
|
151
|
+
const containers = [];
|
|
152
|
+
|
|
145
153
|
stakeholdersOfLocation.forEach((stakeholder, index) => {
|
|
146
|
-
const markerId = `${stakeholder.datastakeId}`;
|
|
154
|
+
const markerId = `${data.datastakeId}-${stakeholder.datastakeId}`;
|
|
147
155
|
const { x, y, radius, center } = getStakeholderPosition({
|
|
148
156
|
zoom,
|
|
149
157
|
totalMarkers: stakeholdersOfLocation.length,
|
|
@@ -162,46 +170,30 @@ export default function LocationIcon({
|
|
|
162
170
|
const isForceOpen = activeMarker?.datastakeId === data.datastakeId;
|
|
163
171
|
const iconSize = isSmallMarker(zoom) || isExtraSmallMarker(zoom) ? [11, 11] : [25, 25];
|
|
164
172
|
|
|
173
|
+
// Create container div
|
|
174
|
+
const containerDiv = document.createElement('div');
|
|
175
|
+
containerDiv.id = markerId;
|
|
176
|
+
|
|
165
177
|
const marker = L.marker(stakeholderLatLng, {
|
|
166
178
|
icon: L.divIcon({
|
|
167
|
-
html:
|
|
179
|
+
html: containerDiv.outerHTML,
|
|
168
180
|
className: "marker-chain",
|
|
169
181
|
iconSize: iconSize,
|
|
170
182
|
}),
|
|
171
183
|
}).addTo(mapRef);
|
|
172
184
|
|
|
173
185
|
markersRef.current.push(marker);
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
allData={allData}
|
|
186
|
-
link={link}
|
|
187
|
-
parentId={data.datastakeId}
|
|
188
|
-
renderTooltip={renderTooltip}
|
|
189
|
-
onClickLink={onClickLink}
|
|
190
|
-
selectedMarkersId={selectedMarkersId}
|
|
191
|
-
handleSelectMarker={handleSelectMarker}
|
|
192
|
-
mapRef={mapRef}
|
|
193
|
-
radius={radius}
|
|
194
|
-
index={index}
|
|
195
|
-
x={x}
|
|
196
|
-
y={y}
|
|
197
|
-
openPopupIdRef={openPopupIdRef}
|
|
198
|
-
polylinesRef={polylinesRef}
|
|
199
|
-
isForceOpen={isForceOpen}
|
|
200
|
-
activeMarker={activeMarker}
|
|
201
|
-
/>,
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
}, 0);
|
|
186
|
+
|
|
187
|
+
// Store container info for portal rendering
|
|
188
|
+
containers.push({
|
|
189
|
+
markerId,
|
|
190
|
+
stakeholder,
|
|
191
|
+
x,
|
|
192
|
+
y,
|
|
193
|
+
radius,
|
|
194
|
+
index,
|
|
195
|
+
isForceOpen,
|
|
196
|
+
});
|
|
205
197
|
|
|
206
198
|
setMapMarkers((prev) => {
|
|
207
199
|
const array = [
|
|
@@ -236,21 +228,23 @@ export default function LocationIcon({
|
|
|
236
228
|
isForceOpen,
|
|
237
229
|
listOfPolylines: polylinesRef.current,
|
|
238
230
|
stakeholderType: stakeholder.type,
|
|
239
|
-
animated: true,
|
|
231
|
+
animated: true,
|
|
240
232
|
});
|
|
241
233
|
});
|
|
242
234
|
|
|
235
|
+
// Update portal containers after markers are created
|
|
236
|
+
setTimeout(() => {
|
|
237
|
+
setPortalContainers(containers);
|
|
238
|
+
}, 0);
|
|
239
|
+
|
|
243
240
|
return () => {
|
|
244
241
|
markersRef.current.forEach(marker => {
|
|
245
|
-
if (mapRef.hasLayer(marker)) {
|
|
242
|
+
if (mapRef && mapRef.hasLayer(marker)) {
|
|
246
243
|
mapRef.removeLayer(marker);
|
|
247
244
|
}
|
|
248
245
|
});
|
|
249
|
-
rootsMapRef.current.forEach(root => {
|
|
250
|
-
root.unmount();
|
|
251
|
-
});
|
|
252
|
-
rootsMapRef.current.clear();
|
|
253
246
|
markersRef.current = [];
|
|
247
|
+
setPortalContainers([]);
|
|
254
248
|
};
|
|
255
249
|
}, [stakeholdersOfLocation, selectedMarkersId, activeMarker, zoom]);
|
|
256
250
|
|
|
@@ -344,56 +338,81 @@ useEffect(() => {
|
|
|
344
338
|
}, [linkedNodesData, selectedMarkersId, zoom, stakeholdersOfLocation, isSelected]);
|
|
345
339
|
|
|
346
340
|
return (
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
341
|
+
<>
|
|
342
|
+
<Popover
|
|
343
|
+
content={renderTooltipJsx({
|
|
344
|
+
title: data.name,
|
|
345
|
+
subTitle: data.subTitle,
|
|
346
|
+
total: data.sources,
|
|
347
|
+
className: "pt-0 pb-0",
|
|
348
|
+
items: renderTooltip(data),
|
|
349
|
+
link,
|
|
350
|
+
onClickLink: () => onClickLink(data),
|
|
351
|
+
isNewTab: true,
|
|
352
|
+
})}
|
|
353
|
+
getPopupContainer={(triggerNode) => {
|
|
354
|
+
const mapElement = document.getElementById("map");
|
|
355
|
+
return mapElement || triggerNode.parentElement || document.body;
|
|
356
|
+
}}
|
|
357
|
+
>
|
|
358
|
+
<div style={{ position: "relative", display: "inline-block" }}>
|
|
359
|
+
{(isSelected || selectedMarkersId.length === 0) && (
|
|
360
|
+
<div
|
|
361
|
+
style={{
|
|
362
|
+
position: "absolute",
|
|
363
|
+
bottom: "0",
|
|
364
|
+
left: "50%",
|
|
365
|
+
transform: "translateX(-50%)",
|
|
366
|
+
width: "12px",
|
|
367
|
+
height: "6px",
|
|
368
|
+
background: "rgba(0,0,0,0.15)",
|
|
369
|
+
borderRadius: "50%",
|
|
370
|
+
filter: "blur(3px)",
|
|
371
|
+
}}
|
|
372
|
+
/>
|
|
373
|
+
)}
|
|
374
|
+
<Marker
|
|
375
|
+
isSelected={isSelected}
|
|
376
|
+
onClick={() => {
|
|
377
|
+
handleSelectMarker(data);
|
|
378
|
+
setActiveMarker(isSelected ? null : data);
|
|
380
379
|
}}
|
|
380
|
+
zoom={zoom}
|
|
381
|
+
selectedMarkersId={selectedMarkersId}
|
|
381
382
|
/>
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
383
|
+
</div>
|
|
384
|
+
</Popover>
|
|
385
|
+
|
|
386
|
+
{/* Render stakeholder icons via portals */}
|
|
387
|
+
{portalContainers.map(({markerId, stakeholder, x, y, radius, index, isForceOpen}) => {
|
|
388
|
+
const container = document.getElementById(markerId);
|
|
389
|
+
if (!container) return null;
|
|
390
|
+
|
|
391
|
+
return createPortal(
|
|
392
|
+
<StakeholderIcon
|
|
393
|
+
key={markerId}
|
|
394
|
+
data={stakeholder}
|
|
395
|
+
zoom={zoom}
|
|
396
|
+
allData={allData}
|
|
397
|
+
link={link}
|
|
398
|
+
parentId={data.datastakeId}
|
|
399
|
+
renderTooltip={renderTooltip}
|
|
400
|
+
onClickLink={onClickLink}
|
|
401
|
+
selectedMarkersId={selectedMarkersId}
|
|
402
|
+
handleSelectMarker={handleSelectMarker}
|
|
403
|
+
mapRef={mapRef}
|
|
404
|
+
radius={radius}
|
|
405
|
+
index={index}
|
|
406
|
+
x={x}
|
|
407
|
+
y={y}
|
|
408
|
+
openPopupIdRef={openPopupIdRef}
|
|
409
|
+
polylinesRef={polylinesRef}
|
|
410
|
+
isForceOpen={isForceOpen}
|
|
411
|
+
activeMarker={activeMarker}
|
|
412
|
+
/>,
|
|
413
|
+
container
|
|
414
|
+
);
|
|
415
|
+
})}
|
|
416
|
+
</>
|
|
398
417
|
);
|
|
399
418
|
}
|
|
@@ -16,12 +16,16 @@ export default function VegetationWidget({
|
|
|
16
16
|
}) {
|
|
17
17
|
let vegetationConfig = getVegetationConfig();
|
|
18
18
|
|
|
19
|
+
// Get all VEGETATION_KEYS values before filtering (needed for mapping check)
|
|
19
20
|
const allVegetationKeys = vegetationConfig.map(item => item.key);
|
|
20
21
|
|
|
22
|
+
// Filter to show only specific keys if filterKeys is provided
|
|
21
23
|
if (filterKeys && Array.isArray(filterKeys)) {
|
|
22
24
|
vegetationConfig = vegetationConfig.filter(item => filterKeys.includes(item.key));
|
|
23
25
|
}
|
|
24
26
|
|
|
27
|
+
// Map growthObservations to VEGETATION_KEYS
|
|
28
|
+
// Handle both formats: growthObservations keys (e.g., "yellowing_leaves") and VEGETATION_KEYS (e.g., "yellowing")
|
|
25
29
|
const mappedGrowthObservations = Array.isArray(growthObservations)
|
|
26
30
|
? growthObservations
|
|
27
31
|
.map(obs => {
|
|
@@ -36,7 +36,12 @@ export default function DAFTable({
|
|
|
36
36
|
doEmptyRows,
|
|
37
37
|
...rest
|
|
38
38
|
}) {
|
|
39
|
-
const
|
|
39
|
+
const source = useMemo(() => {
|
|
40
|
+
if (data && Array.isArray(data)) {
|
|
41
|
+
return data;
|
|
42
|
+
}
|
|
43
|
+
return [];
|
|
44
|
+
}, [data]);
|
|
40
45
|
const projectData = (projects || []).find(p => p.id === selectedProject);
|
|
41
46
|
const [filtersInit, setFiltersInit] = useState(!loading);
|
|
42
47
|
|
|
@@ -85,11 +90,11 @@ export default function DAFTable({
|
|
|
85
90
|
} : filtersConfig;
|
|
86
91
|
}, [sourcesKey, sources, filtersConfig, t]);
|
|
87
92
|
|
|
88
|
-
useEffect(() => {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}, [data, data.length]);
|
|
93
|
+
// useEffect(() => {
|
|
94
|
+
// if (data && Array.isArray(data)) {
|
|
95
|
+
// setSource(data);
|
|
96
|
+
// }
|
|
97
|
+
// }, [data, data.length]);
|
|
93
98
|
|
|
94
99
|
const paginationPageSize = pagination?.pageSize;
|
|
95
100
|
const dataSource = useMemo(() => {
|