datastake-daf 0.6.783 → 0.6.785
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 +78 -70
- package/dist/hooks/index.js +3 -1
- package/dist/pages/index.js +1082 -270
- package/dist/style/datastake/mapbox-gl.css +330 -0
- package/dist/utils/index.js +67 -0
- package/package.json +1 -1
- package/src/@daf/core/components/Charts/BarChart/index.jsx +1 -1
- package/src/@daf/core/components/Dashboard/Map/ChainIcon/utils.js +2 -2
- package/src/@daf/core/components/Screens/BaseScreen/index.jsx +1 -0
- package/src/@daf/core/components/Select/MultiSelect/index.jsx +4 -2
- package/src/@daf/core/components/Select/MultiSelect/style.js +15 -0
- package/src/@daf/hooks/useGetQueryParams.js +3 -1
- package/src/@daf/pages/Dashboards/UserDashboard/components/ContributionsGraph/hook.js +6 -7
- package/src/@daf/pages/Dashboards/UserDashboard/components/ContributionsGraph/index.jsx +1 -1
- package/src/@daf/pages/Documents/config.js +5 -5
- package/src/@daf/pages/Events/Activities/columns.js +5 -0
- package/src/@daf/pages/Events/Activities/config.js +21 -17
- package/src/@daf/pages/Events/Incidents/columns.js +5 -0
- package/src/@daf/pages/Events/Incidents/config.js +14 -11
- package/src/@daf/pages/Events/columns.js +6 -0
- package/src/@daf/pages/Events/config.js +0 -16
- package/src/@daf/pages/Locations/MineSite/columns.js +5 -1
- package/src/@daf/pages/Locations/MineSite/config.js +21 -24
- package/src/@daf/pages/Partners/columns.js +3 -1
- package/src/@daf/pages/Partners/config.js +13 -9
- package/src/@daf/pages/Partners/create.jsx +5 -2
- package/src/@daf/pages/Partners/edit.jsx +4 -2
- package/src/@daf/pages/Stakeholders/Operators/columns.js +6 -0
- package/src/@daf/pages/Stakeholders/Operators/config.js +8 -8
- package/src/@daf/pages/Stakeholders/Workers/columns.js +19 -13
- package/src/@daf/pages/Stakeholders/Workers/config.js +8 -23
- package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/KeyInformation/index.jsx +48 -0
- package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MangroveGrowth/PlantedSpecies.jsx +73 -0
- package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MangroveGrowth/SeedlingsHeight.jsx +44 -0
- package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MangroveGrowth/Stats.jsx +86 -0
- package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MangroveGrowth/VegetationHealth.jsx +73 -0
- package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MangroveGrowth/index.jsx +92 -0
- package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MonitoringScopeAndFindings/index.jsx +348 -0
- package/src/@daf/pages/Summary/Activities/MonitoringCampaign/config.js +35 -0
- package/src/@daf/pages/Summary/Activities/MonitoringCampaign/index.jsx +30 -0
- package/src/@daf/pages/Summary/Activities/PlantingCycle/components/CommunityParticipation/CommunityStats/helper.js +1 -1
- package/src/@daf/pages/Summary/Activities/PlantingCycle/components/CycleIndicators/index.jsx +1 -1
- package/src/@daf/pages/Summary/Activities/PlantingCycle/components/CycleOutcomes/index.jsx +1 -1
- package/src/@daf/pages/Summary/Activities/PlantingCycle/helper.js +0 -56
- package/src/@daf/pages/Summary/Minesite/index.jsx +6 -4
- package/src/@daf/pages/Summary/Operator/components/TradeRelationships/index.js +2 -0
- package/src/@daf/pages/Summary/Operator/index.jsx +6 -3
- package/src/@daf/pages/TablePage/index.jsx +8 -2
- package/src/@daf/pages/Template/components/LinkingTemplate/config.js +14 -1
- package/src/@daf/pages/Template/components/LinkingTemplate/index.jsx +4 -2
- package/src/@daf/pages/Template/index.jsx +1 -10
- package/src/@daf/pages/View/hooks/usePrepareForm.js +4 -4
- package/src/@daf/pages/View/index.jsx +2 -1
- package/src/@daf/utils/numbers.js +57 -0
- package/src/constants/locales/en/translation.js +3 -0
- package/src/constants/locales/fr/translation.js +3 -0
- package/src/constants/locales/sp/translation.js +3 -0
- package/src/pages.js +1 -0
- package/src/utils.js +1 -1
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
import React, { useMemo, useState } from 'react';
|
|
2
|
+
import { Widget, MineSiteMap } from '../../../../../../../../src/index.js';
|
|
3
|
+
import { useWidgetFetch } from '../../../../../../hooks/useWidgetFetch.js';
|
|
4
|
+
import { convertDMS } from '../../../../../../../../src/helpers/Map';
|
|
5
|
+
import CustomIcon from '../../../../../../../../src/@daf/core/components/Icon/CustomIcon.jsx';
|
|
6
|
+
import { renderDateFormatted } from '../../../../../../../../src/helpers/Forms';
|
|
7
|
+
|
|
8
|
+
const VISITS_TAB = "visits";
|
|
9
|
+
const GROWTH_AND_SURVIVAL_TAB = "growthAndSurvival";
|
|
10
|
+
const FAUNA_SIGHTINGS_TAB = "faunaSightings";
|
|
11
|
+
const INVASIVE_SPECIES_TAB = "invasiveSpecies";
|
|
12
|
+
const SYMPTOM_HOTSPOTS_TAB = "symptomHotspots";
|
|
13
|
+
const SOIL_TAB = "soil";
|
|
14
|
+
|
|
15
|
+
const MonitoringScopeAndFindings = ({
|
|
16
|
+
id,
|
|
17
|
+
getSummaryDetail,
|
|
18
|
+
loading = false,
|
|
19
|
+
t = (s) => s
|
|
20
|
+
}) => {
|
|
21
|
+
const [activeTab, setActiveTab] = useState(VISITS_TAB);
|
|
22
|
+
|
|
23
|
+
const defaultConfig = useMemo(
|
|
24
|
+
() => ({
|
|
25
|
+
basepath: "events/monitoring-campaign",
|
|
26
|
+
url: `/summary/${id}/monitoring-scope`,
|
|
27
|
+
stop: !id,
|
|
28
|
+
}),
|
|
29
|
+
[id],
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const customGetData = useMemo(() => {
|
|
33
|
+
if (getSummaryDetail && id) {
|
|
34
|
+
return ({ url, params = {} }) => {
|
|
35
|
+
const match = url.match(/\/summary\/[^/]+\/(.+)/);
|
|
36
|
+
if (match) {
|
|
37
|
+
const [, type] = match;
|
|
38
|
+
return getSummaryDetail(id, type, { ...params, tab: activeTab });
|
|
39
|
+
}
|
|
40
|
+
throw new Error(`Invalid URL format: ${url}`);
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return undefined;
|
|
44
|
+
}, [getSummaryDetail, id, activeTab]);
|
|
45
|
+
|
|
46
|
+
const { loading: monitoringScopeLoading, data: monitoringScopeData } = useWidgetFetch({
|
|
47
|
+
config: defaultConfig,
|
|
48
|
+
getData: customGetData
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const filtersConfig = useMemo(() => {
|
|
52
|
+
switch (activeTab) {
|
|
53
|
+
case GROWTH_AND_SURVIVAL_TAB:
|
|
54
|
+
return [
|
|
55
|
+
{
|
|
56
|
+
label: t("Mangrove Survival Rate"),
|
|
57
|
+
placeholder: t("Select"),
|
|
58
|
+
key: "mangroveSurvivalRate",
|
|
59
|
+
type: "slider",
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
label: t("Planting Density"),
|
|
63
|
+
placeholder: t("Select"),
|
|
64
|
+
key: "plantingDensity",
|
|
65
|
+
type: "select",
|
|
66
|
+
},
|
|
67
|
+
];
|
|
68
|
+
case FAUNA_SIGHTINGS_TAB:
|
|
69
|
+
return [
|
|
70
|
+
{
|
|
71
|
+
label: t("Fauna Observed"),
|
|
72
|
+
placeholder: t("Select"),
|
|
73
|
+
key: "faunaSightings",
|
|
74
|
+
type: "select",
|
|
75
|
+
options: [
|
|
76
|
+
{ label: t("Birds"), value: "birds" },
|
|
77
|
+
{ label: t("Crabs"), value: "crabs" },
|
|
78
|
+
{ label: t("Fish"), value: "fish" },
|
|
79
|
+
{ label: t("Molluscs"), value: "molluscs" },
|
|
80
|
+
{ label: t("Oysters"), value: "oysters" },
|
|
81
|
+
],
|
|
82
|
+
},
|
|
83
|
+
];
|
|
84
|
+
case INVASIVE_SPECIES_TAB:
|
|
85
|
+
return [
|
|
86
|
+
{
|
|
87
|
+
label: t("Fauna Observed"),
|
|
88
|
+
placeholder: t("Select"),
|
|
89
|
+
key: "invasiveSpecies",
|
|
90
|
+
type: "select",
|
|
91
|
+
options: [
|
|
92
|
+
{ label: t("Spiders"), value: "spiders" },
|
|
93
|
+
{ label: t("Scale insects"), value: "scaleInsects" },
|
|
94
|
+
{ label: t("Caterpillars"), value: "caterpillars" },
|
|
95
|
+
{ label: t("Unidentified pests"), value: "unidentifiedPests" },
|
|
96
|
+
{ label: t("Other"), value: "other" },
|
|
97
|
+
],
|
|
98
|
+
},
|
|
99
|
+
];
|
|
100
|
+
case SYMPTOM_HOTSPOTS_TAB:
|
|
101
|
+
return [
|
|
102
|
+
{
|
|
103
|
+
label: t("Symptom Hotspots"),
|
|
104
|
+
placeholder: t("Select"),
|
|
105
|
+
key: "symptomHotspots",
|
|
106
|
+
type: "select",
|
|
107
|
+
options: [
|
|
108
|
+
{ label: t("Reddish spots on leaves"), value: "reddishSpotsOnLeaves" },
|
|
109
|
+
{ label: t("Black spots on leaves"), value: "blackSpotsOnLeaves" },
|
|
110
|
+
{ label: t("Yellowing of leaves"), value: "yellowingOfLeaves" },
|
|
111
|
+
{ label: t("Presence of mosaic"), value: "presenceOfMosaic" },
|
|
112
|
+
],
|
|
113
|
+
},
|
|
114
|
+
];
|
|
115
|
+
case SOIL_TAB:
|
|
116
|
+
return [
|
|
117
|
+
{
|
|
118
|
+
label: t("Soil"),
|
|
119
|
+
placeholder: t("Select"),
|
|
120
|
+
key: "soil",
|
|
121
|
+
type: "select",
|
|
122
|
+
options: [
|
|
123
|
+
{ label: t("Sandy"), value: "sandy" },
|
|
124
|
+
{ label: t("Clay"), value: "clay" },
|
|
125
|
+
{ label: t("Muddy"), value: "muddy" },
|
|
126
|
+
{ label: t("Loamy"), value: "loamy" },
|
|
127
|
+
{ label: t("Mixed"), value: "mixed" },
|
|
128
|
+
],
|
|
129
|
+
},
|
|
130
|
+
];
|
|
131
|
+
default:
|
|
132
|
+
return [];
|
|
133
|
+
}
|
|
134
|
+
}, [activeTab, t]);
|
|
135
|
+
|
|
136
|
+
const mappedData = useMemo(() => {
|
|
137
|
+
if (!monitoringScopeData || !monitoringScopeData.plots) {
|
|
138
|
+
return [];
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const { plots = [], monitoringActivities = [] } = monitoringScopeData;
|
|
142
|
+
|
|
143
|
+
if (activeTab === VISITS_TAB) {
|
|
144
|
+
return plots.map((plot, index) => {
|
|
145
|
+
const area = plot?.perimeter ? plot.perimeter.map(coord =>
|
|
146
|
+
Array.isArray(coord) && coord.length >= 2
|
|
147
|
+
? [coord[1], coord[0]]
|
|
148
|
+
: coord
|
|
149
|
+
) : null;
|
|
150
|
+
|
|
151
|
+
const validArea = area && Array.isArray(area) && area.length >= 3 ? area : null;
|
|
152
|
+
|
|
153
|
+
const matchingActivity = monitoringActivities?.find(activity =>
|
|
154
|
+
activity.plotId === plot.id || activity.plotId === plot._id
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
const gps = matchingActivity?.locationCheckArrival ? {
|
|
158
|
+
latitude: matchingActivity.locationCheckArrival.latitude,
|
|
159
|
+
longitude: matchingActivity.locationCheckArrival.longitude
|
|
160
|
+
} : null;
|
|
161
|
+
|
|
162
|
+
return {
|
|
163
|
+
_id: plot._id || {},
|
|
164
|
+
area: validArea,
|
|
165
|
+
color: "#15FFFFB2",
|
|
166
|
+
datastakeId: plot.datastakeId || `PLOT-${String(index + 1).padStart(9, '0')}`,
|
|
167
|
+
gps: gps,
|
|
168
|
+
id: plot.id || plot._id || `plot-${index}`,
|
|
169
|
+
name: plot.name || t("Plot"),
|
|
170
|
+
date: matchingActivity?.date,
|
|
171
|
+
subTitle: matchingActivity?.date
|
|
172
|
+
? renderDateFormatted(matchingActivity.date, "DD MMM YY")
|
|
173
|
+
: plot.name,
|
|
174
|
+
plotName: plot.name,
|
|
175
|
+
territoryTitle: plot.name,
|
|
176
|
+
type: plot.type || 'Operational Plot',
|
|
177
|
+
lastVisit: matchingActivity?.date,
|
|
178
|
+
implementer: matchingActivity?.implementer,
|
|
179
|
+
areaHa: plot.area,
|
|
180
|
+
};
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return plots.map((plot, index) => {
|
|
185
|
+
const area = plot?.perimeter ? plot.perimeter.map(coord =>
|
|
186
|
+
Array.isArray(coord) && coord.length >= 2
|
|
187
|
+
? [coord[1], coord[0]]
|
|
188
|
+
: coord
|
|
189
|
+
) : null;
|
|
190
|
+
|
|
191
|
+
const validArea = area && Array.isArray(area) && area.length >= 3 ? area : null;
|
|
192
|
+
|
|
193
|
+
return {
|
|
194
|
+
_id: plot._id || {},
|
|
195
|
+
area: validArea,
|
|
196
|
+
color: "#15FFFFB2",
|
|
197
|
+
datastakeId: plot.datastakeId || `PLOT-${String(index + 1).padStart(9, '0')}`,
|
|
198
|
+
id: plot.id || plot._id || `plot-${index}`,
|
|
199
|
+
name: plot.name || t("Plot"),
|
|
200
|
+
plotName: plot.name,
|
|
201
|
+
territoryTitle: plot.name,
|
|
202
|
+
type: plot.type || 'Operational Plot',
|
|
203
|
+
};
|
|
204
|
+
});
|
|
205
|
+
}, [monitoringScopeData, activeTab, t]);
|
|
206
|
+
|
|
207
|
+
return (
|
|
208
|
+
<section>
|
|
209
|
+
<Widget
|
|
210
|
+
title={t("Monitoring Scope & Findings")}
|
|
211
|
+
className="v2-widget no-px no-p-body h-w-btn-header with-border-header"
|
|
212
|
+
style={{ height: '100%', display: 'flex', flexDirection: 'column' }}
|
|
213
|
+
tabsConfig={{
|
|
214
|
+
tabs: [
|
|
215
|
+
{
|
|
216
|
+
label: t("Visits"),
|
|
217
|
+
value: VISITS_TAB,
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
label: t("Growth & Survival"),
|
|
221
|
+
value: GROWTH_AND_SURVIVAL_TAB,
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
label: t("Fauna Sightings"),
|
|
225
|
+
value: FAUNA_SIGHTINGS_TAB,
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
label: t("Invasive Species"),
|
|
229
|
+
value: INVASIVE_SPECIES_TAB,
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
label: t("Symptom Hotspots"),
|
|
233
|
+
value: SYMPTOM_HOTSPOTS_TAB,
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
label: t("Soil"),
|
|
237
|
+
value: SOIL_TAB,
|
|
238
|
+
},
|
|
239
|
+
],
|
|
240
|
+
value: activeTab,
|
|
241
|
+
onChange: setActiveTab,
|
|
242
|
+
}}
|
|
243
|
+
>
|
|
244
|
+
<MineSiteMap
|
|
245
|
+
data={mappedData}
|
|
246
|
+
link={false}
|
|
247
|
+
style={{ height: '100%', width: '100%' }}
|
|
248
|
+
maxZoom={18}
|
|
249
|
+
isSatellite={true}
|
|
250
|
+
onClickLink={() => { }}
|
|
251
|
+
onFilterChange={() => { }}
|
|
252
|
+
primaryLink
|
|
253
|
+
showSider={false}
|
|
254
|
+
filtersConfig={filtersConfig}
|
|
255
|
+
renderTooltipForLocation={(data) => {
|
|
256
|
+
if (activeTab === VISITS_TAB && data.gps) {
|
|
257
|
+
const coordinates = data.gps?.latitude && data.gps?.longitude
|
|
258
|
+
? convertDMS(data.gps.latitude, data.gps.longitude)
|
|
259
|
+
: null;
|
|
260
|
+
|
|
261
|
+
if (!coordinates) {
|
|
262
|
+
return [];
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const iconColor = "#016C6E";
|
|
266
|
+
|
|
267
|
+
const tooltipItems = [
|
|
268
|
+
{
|
|
269
|
+
label: t("Coordinates"),
|
|
270
|
+
value: (
|
|
271
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '6px', flexWrap: 'nowrap' }}>
|
|
272
|
+
<div style={{ display: 'flex', alignItems: 'center' }}>
|
|
273
|
+
<CustomIcon
|
|
274
|
+
name="SpacingHeight"
|
|
275
|
+
width={14}
|
|
276
|
+
height={14}
|
|
277
|
+
color={iconColor}
|
|
278
|
+
/>
|
|
279
|
+
<span style={{ fontWeight: 600, marginLeft: '4px' }}>{coordinates[0]}</span>
|
|
280
|
+
</div>
|
|
281
|
+
<div style={{ display: 'flex', alignItems: 'center' }}>
|
|
282
|
+
<CustomIcon
|
|
283
|
+
name="SpacingWidth"
|
|
284
|
+
width={14}
|
|
285
|
+
height={14}
|
|
286
|
+
color={iconColor}
|
|
287
|
+
/>
|
|
288
|
+
<span style={{ fontWeight: 600, marginLeft: '4px' }}>{coordinates[1]}</span>
|
|
289
|
+
</div>
|
|
290
|
+
</div>
|
|
291
|
+
),
|
|
292
|
+
},
|
|
293
|
+
];
|
|
294
|
+
|
|
295
|
+
if (data.date) {
|
|
296
|
+
tooltipItems.push({
|
|
297
|
+
label: t("Date"),
|
|
298
|
+
value: renderDateFormatted(data.date, "DD MMM YY"),
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
if (data.implementer) {
|
|
303
|
+
tooltipItems.push({
|
|
304
|
+
label: t("Implementer"),
|
|
305
|
+
value: data.implementer,
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
return tooltipItems;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
return [];
|
|
313
|
+
}}
|
|
314
|
+
renderTooltipForTerritory={(data) => {
|
|
315
|
+
const items = [
|
|
316
|
+
{
|
|
317
|
+
label: t("Plot Name"),
|
|
318
|
+
value: data.plotName || data.name || "--",
|
|
319
|
+
},
|
|
320
|
+
];
|
|
321
|
+
|
|
322
|
+
if (activeTab === VISITS_TAB && data.lastVisit) {
|
|
323
|
+
items.push({
|
|
324
|
+
label: t("Last visit"),
|
|
325
|
+
value: renderDateFormatted(data.lastVisit, "DD MMM YY"),
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (activeTab === VISITS_TAB && data.areaHa) {
|
|
330
|
+
items.push({
|
|
331
|
+
label: t("Area"),
|
|
332
|
+
value: `${data.areaHa} ha`,
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
return items;
|
|
337
|
+
}}
|
|
338
|
+
renderTooltipTags={() => { }}
|
|
339
|
+
type="location-territory"
|
|
340
|
+
loading={loading || monitoringScopeLoading}
|
|
341
|
+
/>
|
|
342
|
+
</Widget>
|
|
343
|
+
</section>
|
|
344
|
+
);
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
export default MonitoringScopeAndFindings;
|
|
348
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
export const getKeyIndicatorsRowConfig = ({ t, data = {} }) => [
|
|
4
|
+
{
|
|
5
|
+
label: t('Region'),
|
|
6
|
+
render: () => {
|
|
7
|
+
return <div>{ data?.region || '-'}</div>;
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
label: t('Associated Plots'),
|
|
12
|
+
render: () => {
|
|
13
|
+
return <div>{data?.associatedPlotsCount || '0'}</div>
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
label: t('Implementation Partners'),
|
|
18
|
+
render: () => {
|
|
19
|
+
return <div>{data?.partnersCount || '0'}</div>
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
label: t('Total Activities'),
|
|
24
|
+
render: () => {
|
|
25
|
+
return <div>{data?.activitiesCount || '0'}</div>
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
label: t('Information Sources'),
|
|
30
|
+
render: () => {
|
|
31
|
+
return <div>{data?.informationSourcesCount || '0'}</div>
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
];
|
|
35
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { DashboardLayout, Header } from '../../../../../../src/index.js'
|
|
2
|
+
import KeyInformation from './components/KeyInformation/index.jsx';
|
|
3
|
+
import MonitoringScopeAndFindings from './components/MonitoringScopeAndFindings/index.jsx';
|
|
4
|
+
import MangroveGrowth from './components/MangroveGrowth/index.jsx';
|
|
5
|
+
|
|
6
|
+
const MonitoringCampaignSummary = ({ header, activityData, loading = false, id, projectId, t = () => { }, getSummaryDetail, navigate, selectOptions }) => {
|
|
7
|
+
return (
|
|
8
|
+
<DashboardLayout
|
|
9
|
+
header={
|
|
10
|
+
<Header
|
|
11
|
+
title={header?.title + ' Summary' || ''}
|
|
12
|
+
supportText={header?.supportText || ''}
|
|
13
|
+
onDownload={header?.onDownload}
|
|
14
|
+
downloadDisabled={header?.downloadDisabled}
|
|
15
|
+
actionButtons={header?.actionButtons}
|
|
16
|
+
breadcrumbs={header?.breadcrumbs}
|
|
17
|
+
goBackTo={header?.goBackTo}
|
|
18
|
+
loading={header?.loading}
|
|
19
|
+
/>
|
|
20
|
+
}
|
|
21
|
+
>
|
|
22
|
+
<KeyInformation id={id} t={t} getSummaryDetail={getSummaryDetail} loading={loading} />
|
|
23
|
+
<MonitoringScopeAndFindings id={id} t={t} getSummaryDetail={getSummaryDetail} loading={loading} />
|
|
24
|
+
<MangroveGrowth id={id} t={t} getSummaryDetail={getSummaryDetail} loading={loading} />
|
|
25
|
+
</DashboardLayout>
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export default MonitoringCampaignSummary;
|
|
30
|
+
|
package/src/@daf/pages/Summary/Activities/PlantingCycle/components/CycleIndicators/index.jsx
CHANGED
|
@@ -3,7 +3,7 @@ import { Widget, StatCard } from '../../../../../../../index.js';
|
|
|
3
3
|
import CyclePartners from './CyclePartners/index.jsx';
|
|
4
4
|
import HealthAndSafety from './HealthAndSafety/index.jsx';
|
|
5
5
|
import { useWidgetFetch } from '../../../../../../hooks/useWidgetFetch.js';
|
|
6
|
-
import { calculateStatChange } from '
|
|
6
|
+
import { calculateStatChange } from '../../../../../../utils/numbers.js';
|
|
7
7
|
|
|
8
8
|
const CycleIndicators = ({
|
|
9
9
|
id,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useMemo } from 'react';
|
|
2
2
|
import { Widget, StatCard } from '../../../../../../../../src/index.js';
|
|
3
3
|
import { useWidgetFetch } from '../../../../../../hooks/useWidgetFetch.js';
|
|
4
|
-
import { calculateStatChange } from '
|
|
4
|
+
import { calculateStatChange } from '../../../../../../utils/numbers.js';
|
|
5
5
|
import RestoredArea from './RestoredArea.jsx';
|
|
6
6
|
import PlantingActivitiesTimeline from './PlantingActivitiesTimeline.jsx';
|
|
7
7
|
|
|
@@ -281,60 +281,4 @@ export const getHealthAndSafetyTooltipChildren = (item, isEmpty, healthAndSafety
|
|
|
281
281
|
});
|
|
282
282
|
};
|
|
283
283
|
|
|
284
|
-
/**
|
|
285
|
-
* Calculates stat change object for StatCard component based on current and previous values
|
|
286
|
-
* @param {Object} data - Object with current and previous values
|
|
287
|
-
* @param {number} data.current - Current value
|
|
288
|
-
* @param {number} data.previous - Previous value
|
|
289
|
-
* @param {Object} options - Optional configuration
|
|
290
|
-
* @param {string} options.tooltipText - Custom tooltip text
|
|
291
|
-
* @param {string} options.format - Format type: 'percentage' (default) or 'absolute'
|
|
292
|
-
* @param {number} options.decimalPlaces - Number of decimal places for percentage (default: 1)
|
|
293
|
-
* @returns {Object|null} Change object for StatCard or null if data is invalid
|
|
294
|
-
*/
|
|
295
|
-
export const calculateStatChange = (data, options = {}) => {
|
|
296
|
-
if (!data || typeof data !== 'object') {
|
|
297
|
-
return null;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
const { current, previous } = data;
|
|
301
|
-
|
|
302
|
-
// Validate that both values are numbers
|
|
303
|
-
if (typeof current !== 'number' || typeof previous !== 'number') {
|
|
304
|
-
return null;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
// If previous is 0, we can't calculate percentage change
|
|
308
|
-
if (previous === 0) {
|
|
309
|
-
return null;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
const {
|
|
313
|
-
tooltipText,
|
|
314
|
-
format = 'percentage',
|
|
315
|
-
decimalPlaces = 1,
|
|
316
|
-
} = options;
|
|
317
|
-
|
|
318
|
-
// Calculate the difference
|
|
319
|
-
const difference = current - previous;
|
|
320
|
-
const isPositive = difference >= 0;
|
|
321
|
-
const direction = isPositive ? 'up' : 'down';
|
|
322
|
-
|
|
323
|
-
// Format the value
|
|
324
|
-
let value;
|
|
325
|
-
if (format === 'absolute') {
|
|
326
|
-
// Show absolute difference
|
|
327
|
-
value = Math.abs(difference).toLocaleString();
|
|
328
|
-
} else {
|
|
329
|
-
// Show percentage change
|
|
330
|
-
const percentageChange = (Math.abs(difference) / previous) * 100;
|
|
331
|
-
value = `${percentageChange.toFixed(decimalPlaces)}%`;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
return {
|
|
335
|
-
value,
|
|
336
|
-
direction,
|
|
337
|
-
tooltipText: tooltipText || undefined,
|
|
338
|
-
};
|
|
339
|
-
};
|
|
340
284
|
|
|
@@ -68,13 +68,12 @@ const MineSummary = ({
|
|
|
68
68
|
<DashboardLayout
|
|
69
69
|
header={
|
|
70
70
|
<Header
|
|
71
|
-
title={hasSelect ? t("Mine Review") : (singleItemData?.name || ""
|
|
71
|
+
title={hasSelect ? t("Mine Review") : (`${singleItemData?.name || ""} ${singleItemData?.name ? t("Summary") : ""}`)}
|
|
72
72
|
className="with-border-header h-w-btn-header no-px-body"
|
|
73
73
|
goBackTo={!hasSelect && goBack}
|
|
74
|
-
loading={loading}
|
|
75
74
|
breadcrumbs={breadcrumbs}
|
|
76
75
|
addedHeaderFirst
|
|
77
|
-
actionButtons={[
|
|
76
|
+
actionButtons={hasSelect ? [] :[
|
|
78
77
|
{
|
|
79
78
|
tooltip: t("Details"),
|
|
80
79
|
icon: "FileEdit",
|
|
@@ -90,7 +89,7 @@ const MineSummary = ({
|
|
|
90
89
|
},
|
|
91
90
|
]}
|
|
92
91
|
addedHeader={
|
|
93
|
-
<div className="flex flex-row gap-4"
|
|
92
|
+
<div className="flex flex-row gap-4">
|
|
94
93
|
<Multiselect
|
|
95
94
|
options={[...sourceOptions]}
|
|
96
95
|
isAvatarGroup
|
|
@@ -109,6 +108,9 @@ const MineSummary = ({
|
|
|
109
108
|
/>
|
|
110
109
|
</div>
|
|
111
110
|
}
|
|
111
|
+
onDownload={() => {
|
|
112
|
+
console.log("onDownload");
|
|
113
|
+
}}
|
|
112
114
|
/>
|
|
113
115
|
}
|
|
114
116
|
>
|
|
@@ -69,12 +69,12 @@ const OperatorSummary = ({
|
|
|
69
69
|
<DashboardLayout
|
|
70
70
|
header={
|
|
71
71
|
<Header
|
|
72
|
-
title={hasSelect ? t("Operator Review") : (singleItemData?.name || ""
|
|
72
|
+
title={hasSelect ? t("Operator Review") : (`${singleItemData?.name || ""} ${singleItemData?.name ? t("Summary") : ""}`)}
|
|
73
73
|
className="with-border-header h-w-btn-header no-px-body"
|
|
74
74
|
goBackTo={!hasSelect && goBack}
|
|
75
75
|
breadcrumbs={breadcrumbs}
|
|
76
76
|
addedHeaderFirst
|
|
77
|
-
actionButtons={[
|
|
77
|
+
actionButtons={hasSelect ? [] :[
|
|
78
78
|
{
|
|
79
79
|
tooltip: t("Details"),
|
|
80
80
|
icon: "FileEdit",
|
|
@@ -90,7 +90,7 @@ const OperatorSummary = ({
|
|
|
90
90
|
},
|
|
91
91
|
]}
|
|
92
92
|
addedHeader={
|
|
93
|
-
<div className="flex flex-row gap-4"
|
|
93
|
+
<div className="flex flex-row gap-4">
|
|
94
94
|
<Multiselect
|
|
95
95
|
options={[...sourceOptions]}
|
|
96
96
|
isAvatarGroup
|
|
@@ -109,6 +109,9 @@ const OperatorSummary = ({
|
|
|
109
109
|
/>
|
|
110
110
|
</div>
|
|
111
111
|
}
|
|
112
|
+
onDownload={() => {
|
|
113
|
+
console.log("onDownload");
|
|
114
|
+
}}
|
|
112
115
|
/>
|
|
113
116
|
}
|
|
114
117
|
>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useMemo } from 'react';
|
|
2
2
|
import TablePageWithTabs from '../../core/components/Screens/TableScreen/TablePageWithTabs/index.jsx';
|
|
3
3
|
import Create from './create.jsx';
|
|
4
4
|
import { displayMessage } from '../../../helpers/messages.js';
|
|
@@ -40,6 +40,12 @@ const TablePage = ({
|
|
|
40
40
|
breadcrumbs = [],
|
|
41
41
|
onDownload,
|
|
42
42
|
}) => {
|
|
43
|
+
const _options = useMemo(() => {
|
|
44
|
+
return {
|
|
45
|
+
...options,
|
|
46
|
+
...data?.options,
|
|
47
|
+
}
|
|
48
|
+
},[options, data?.options])
|
|
43
49
|
|
|
44
50
|
const {
|
|
45
51
|
activeTab,
|
|
@@ -56,7 +62,7 @@ const TablePage = ({
|
|
|
56
62
|
location,
|
|
57
63
|
getData,
|
|
58
64
|
extendingFilters,
|
|
59
|
-
options,
|
|
65
|
+
options: _options,
|
|
60
66
|
t,
|
|
61
67
|
goTo,
|
|
62
68
|
user,
|
|
@@ -72,4 +72,17 @@ export const renderType = ({ item = {}, t = (s) => s }) => {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
return "--";
|
|
75
|
-
};
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export const namespaceMap = {
|
|
78
|
+
locations: "location",
|
|
79
|
+
documents: "document",
|
|
80
|
+
stakeholders: "stakeholder",
|
|
81
|
+
events: "event",
|
|
82
|
+
incidents: "event",
|
|
83
|
+
correctiveActions: "event",
|
|
84
|
+
"production-sites": "location",
|
|
85
|
+
operators: "stakeholder",
|
|
86
|
+
workers: "stakeholder",
|
|
87
|
+
activities: "event",
|
|
88
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useEffect, useMemo } from 'react';
|
|
2
2
|
import { useFilters } from '../../../../hooks/useFilters.js';
|
|
3
3
|
import { getColumns } from './columns.js';
|
|
4
|
-
import { redirect } from './config.js';
|
|
4
|
+
import { redirect, namespaceMap } from './config.js';
|
|
5
5
|
import LinkedSubjectsService from '../../../../services/LinkedSubjects.js';
|
|
6
6
|
import { formatClassname } from '../../../../../helpers/ClassesHelper.js';
|
|
7
7
|
import Table from '../../../../core/components/Table/index.jsx';
|
|
@@ -44,9 +44,11 @@ const LinkingTemplate = ({
|
|
|
44
44
|
|
|
45
45
|
const dataSource = conf?.linkingTemplateContextData?.[id];
|
|
46
46
|
|
|
47
|
+
const _namespace = namespaceMap[namespace];
|
|
48
|
+
|
|
47
49
|
const changeData = async () => {
|
|
48
50
|
try {
|
|
49
|
-
const _data = await LinkedSubjectsService.getLinkedSubjects({ namespace, id, mod: conf.mod });
|
|
51
|
+
const _data = await LinkedSubjectsService.getLinkedSubjects({ namespace: _namespace, id, mod: conf.mod });
|
|
50
52
|
const data = (_data?.data || []).map((d, i) => ({ ...d, key: `${d.id}-${i}` }));
|
|
51
53
|
conf?.addData(id, data);
|
|
52
54
|
setPagination((prev) => ({
|
|
@@ -6,14 +6,5 @@ export function Template({
|
|
|
6
6
|
conf,
|
|
7
7
|
namespace,
|
|
8
8
|
}) {
|
|
9
|
-
|
|
10
|
-
case 'locations':
|
|
11
|
-
case 'documents':
|
|
12
|
-
case 'stakeholders':
|
|
13
|
-
case 'events':
|
|
14
|
-
return <LinkingTemplate conf={conf} namespace={namespace} />
|
|
15
|
-
default:
|
|
16
|
-
return null;
|
|
17
|
-
|
|
18
|
-
}
|
|
9
|
+
return <LinkingTemplate conf={conf} namespace={namespace} />
|
|
19
10
|
}
|