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.
Files changed (41) hide show
  1. package/dist/components/index.js +1196 -1285
  2. package/dist/pages/index.js +1315 -579
  3. package/dist/services/index.js +202 -0
  4. package/dist/utils/index.js +28 -0
  5. package/package.json +1 -1
  6. package/src/@daf/core/components/Charts/RadarChart/index.jsx +3 -12
  7. package/src/@daf/core/components/Charts/style.js +1 -2
  8. package/src/@daf/core/components/Dashboard/Map/ChainIcon/index.js +123 -104
  9. package/src/@daf/core/components/Dashboard/Widget/VegetationWidget/index.jsx +4 -0
  10. package/src/@daf/core/components/Table/index.jsx +11 -6
  11. package/src/@daf/pages/Events/Activities/columns.js +15 -11
  12. package/src/@daf/pages/Events/Incidents/columns.js +15 -11
  13. package/src/@daf/pages/Events/Testimonials/columns.js +173 -0
  14. package/src/@daf/pages/Events/Testimonials/config.js +175 -0
  15. package/src/@daf/pages/Events/columns.js +7 -3
  16. package/src/@daf/pages/Locations/ConflictAreas/columns.js +140 -0
  17. package/src/@daf/pages/Locations/ConflictAreas/config.js +41 -0
  18. package/src/@daf/pages/Locations/MineSite/columns.js +21 -12
  19. package/src/@daf/pages/Locations/MineSite/config.js +2 -1
  20. package/src/@daf/pages/Locations/columns.js +7 -3
  21. package/src/@daf/pages/Stakeholders/ArmedGroups/columns.js +110 -0
  22. package/src/@daf/pages/Stakeholders/ArmedGroups/config.js +41 -0
  23. package/src/@daf/pages/Stakeholders/Operators/columns.js +30 -14
  24. package/src/@daf/pages/Stakeholders/Workers/columns.js +23 -13
  25. package/src/@daf/pages/Stakeholders/columns.js +8 -4
  26. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/BiodiversityHabitat/ObservedFauna.jsx +11 -6
  27. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MangroveGrowth/PlantedSpecies.jsx +10 -25
  28. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MangroveGrowth/SeedlingsHeight.jsx +13 -10
  29. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MangroveGrowth/VegetationHealth.jsx +4 -19
  30. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/SoilWaterProfile/SoilType.jsx +10 -22
  31. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/SoilWaterProfile/WaterQuality.jsx +10 -26
  32. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/chartHelpers.js +0 -74
  33. package/src/@daf/pages/TablePage/config.js +1 -1
  34. package/src/@daf/pages/TablePage/helper.js +45 -0
  35. package/src/@daf/services/EventsService.js +115 -0
  36. package/src/@daf/services/LinkedSubjects.js +1 -0
  37. package/src/@daf/services/WorkersService.js +80 -0
  38. package/src/helpers/errorHandling.js +142 -74
  39. package/src/services.js +3 -1
  40. package/src/utils.js +1 -1
  41. package/dist/style/datastake/mapbox-gl.css +0 -330
@@ -105,11 +105,15 @@ export const getColumns = ({t, goTo, user, options, activeTab, getRedirectLink,
105
105
  return <div className="daf-default-cell" />;
106
106
  }
107
107
 
108
- const sources = sourceAvatarConfig(val, user, applications);
108
+ if (!val || val?.length === 0) {
109
+ return "-";
110
+ }
111
+
112
+ const sources = sourceAvatarConfig(val, user, applications);
109
113
 
110
- return <AvatarGroup items={sources}></AvatarGroup>;
114
+ return <AvatarGroup items={sources} />;
111
115
  },
112
- },
116
+ },
113
117
  {
114
118
  title: t("Last Update"),
115
119
  dataIndex: "updatedAt",
@@ -0,0 +1,110 @@
1
+ import React from 'react';
2
+ import { Tooltip } from 'antd';
3
+ import { findOptions, getLinkValue } from '../../../../helpers/StringHelper.js';
4
+ import { renderDateFormatted } from '../../../../helpers/Forms.js';
5
+ import CustomIcon from '../../../core/components/Icon/CustomIcon.jsx';
6
+ import AvatarGroup from '../../../core/components/AvatarGroup/index.jsx';
7
+ import sourceAvatarConfig from '../../../../helpers/sourceAvatarConfig.js';
8
+ import MoreMenu from '../../../core/components/Table/MoreMenu/index.jsx';
9
+ import NavigationAction from '../../../core/components/Table/NavigationAction/index.jsx';
10
+ import { renderStatusTag } from '../../../utils/tags.js';
11
+
12
+ export const getColumns = ({t, goTo, user, options, activeTab, getRedirectLink, theme, subject, data, applications}) => [
13
+ {
14
+ dataIndex: 'datastakeId',
15
+ title: t('ID'),
16
+ ellipsis: true,
17
+ show: true,
18
+ key: "datastakeId",
19
+ sorter: () => 0 + 0,
20
+ render: (v, all) => {
21
+ if (all.empty) {
22
+ return <div className="daf-default-cell" />
23
+ }
24
+
25
+ return <Tooltip title={v}>{v}</Tooltip>;
26
+ },
27
+ },
28
+ {
29
+ dataIndex: 'name',
30
+ title: t('Name'),
31
+ ellipsis: true,
32
+ show: true,
33
+ key: "name",
34
+ sorter: () => 0 + 0,
35
+ render: (v, all) => {
36
+ if (all.empty) {
37
+ return <div className="daf-default-cell" />
38
+ }
39
+
40
+ return <Tooltip title={v}>{v}</Tooltip>;
41
+ },
42
+ },
43
+ {
44
+ title: t("Last Update"),
45
+ dataIndex: "updatedAt",
46
+ key: "updatedAt",
47
+ render: (date, all) => {
48
+ if (all.empty) {
49
+ return <div className="daf-default-cell" />;
50
+ }
51
+
52
+ const _date = date ? renderDateFormatted(date, "DD MMM YYYY", user?.language || 'en') : "-";
53
+ return <Tooltip title={_date}>{_date}</Tooltip>;
54
+ },
55
+ ellipsis: true,
56
+ },
57
+ {
58
+ title: t("Sources"),
59
+ dataIndex: "sources",
60
+ key: "sources",
61
+ show: activeTab !== "own",
62
+ render: (val, all) => {
63
+ if (all.empty) {
64
+ return <div className="daf-default-cell" />;
65
+ }
66
+
67
+ if (!val || val?.length === 0) {
68
+ return "-";
69
+ }
70
+
71
+ const sources = sourceAvatarConfig(val, user, applications);
72
+
73
+ return <AvatarGroup items={sources} />;
74
+ },
75
+ },
76
+ {
77
+ title: t("Status"),
78
+ dataIndex: 'status',
79
+ ellipsis: true,
80
+ show: activeTab == "own",
81
+ render: (v, all) => {
82
+ if (all.empty) {
83
+ return <div className="daf-default-cell" />
84
+ }
85
+ const _val = all?.published || all?.status === "submitted" ? "submitted" : v;
86
+
87
+ return renderStatusTag({ value: _val, t });
88
+ },
89
+ },
90
+ {
91
+ id: 'actions',
92
+ title: "",
93
+ width: 60,
94
+ render: (_, all) => {
95
+ if (all.empty) {
96
+ return <div className="daf-default-cell" />;
97
+ }
98
+
99
+ const onClick = () => {
100
+ let link = `/app/view/${subject}/${all.datastakeId}`;
101
+ if (activeTab === "shared") {
102
+ link += `?sourceId=${all?.authorId?.id}`;
103
+ }
104
+ goTo(getRedirectLink(link));
105
+ };
106
+
107
+ return <NavigationAction onClick={onClick} theme={theme} />;
108
+ }
109
+ }
110
+ ].filter((column) => column.show !== false);
@@ -0,0 +1,41 @@
1
+ import { getStatusOptions } from '../../../utils/filters';
2
+
3
+ export const getFiltersConfig = ({t}) => {
4
+ return {
5
+ status: {
6
+ type: "select",
7
+ label: "Status",
8
+ placeholder: () => `${t("Filter by")} ${t("Status").toLowerCase()}`,
9
+ style: { flex: 1 },
10
+ labelStyle: { fley: 1 },
11
+ getLabel: (option) => option.label,
12
+ getValue: (option) => option.value,
13
+ },
14
+ timeframe: {
15
+ type: "timeframe",
16
+ label: "Timeframe",
17
+ style: { flex: 1 },
18
+ },
19
+ }
20
+ }
21
+
22
+ export const getFilterOptions = (options, t) => {
23
+ const _default = {
24
+ status: getStatusOptions(t) || [],
25
+ timeframe: [],
26
+ }
27
+
28
+ return _default;
29
+ }
30
+
31
+ export const formConfig = {
32
+ namespace: 'armed-groups',
33
+ view: ['scoping', 'new'],
34
+ scope: 'global',
35
+ formType: 'armed-group',
36
+ }
37
+
38
+ export const viewConfig = {
39
+ title: "Armed Groups",
40
+ createTitle: "New Armed Group",
41
+ }
@@ -49,7 +49,13 @@ export const getColumns = ({t, goTo, user, options, activeTab, getRedirectLink,
49
49
  return <div className="daf-default-cell" />
50
50
  }
51
51
 
52
- const country = findOptions(v, data?.options?.positionSupplyChainOptions || data?.options?.optionPositionSupplyChain);
52
+ const positionSupplyChainOptions = [
53
+ ...(data?.options?.positionSupplyChainOptions || []),
54
+ ...(options?.positionSupplyChainOptions || []),
55
+ ...(options?.optionPositionSupplyChain || [])
56
+ ]
57
+
58
+ const country = findOptions(v, positionSupplyChainOptions);
53
59
 
54
60
  return country ? <Tooltip title={country}>{country}</Tooltip> : '-';
55
61
  },
@@ -66,7 +72,13 @@ export const getColumns = ({t, goTo, user, options, activeTab, getRedirectLink,
66
72
  return <div className="daf-default-cell" />
67
73
  }
68
74
 
69
- const subCategory = findOptions(v, data?.options?.subCategoriesOptions || data?.options?.subCategory);
75
+ const subCategoriesOptions = [
76
+ ...(data?.options?.subCategoriesOptions || []),
77
+ ...(options?.subCategoriesOptions || []),
78
+ ...(options?.subCategory || [])
79
+ ]
80
+
81
+ const subCategory = findOptions(v, subCategoriesOptions);
70
82
 
71
83
  return subCategory ? <Tooltip title={subCategory}>{subCategory}</Tooltip> : '-';
72
84
  },
@@ -116,21 +128,25 @@ export const getColumns = ({t, goTo, user, options, activeTab, getRedirectLink,
116
128
  },
117
129
  ellipsis: true,
118
130
  },
119
- {
120
- title: t("Sources"),
121
- dataIndex: "sources",
122
- key: "sources",
123
- show: activeTab !== "own",
124
- render: (val, all) => {
125
- if (all.empty) {
126
- return <div className="daf-default-cell" />;
127
- }
131
+ {
132
+ title: t("Sources"),
133
+ dataIndex: "sources",
134
+ key: "sources",
135
+ show: activeTab !== "own",
136
+ render: (val, all) => {
137
+ if (all.empty) {
138
+ return <div className="daf-default-cell" />;
139
+ }
140
+
141
+ if (!val || val?.length === 0) {
142
+ return "-";
143
+ }
128
144
 
129
- const sources = sourceAvatarConfig(val, user, applications);
145
+ const sources = sourceAvatarConfig(val, user, applications);
130
146
 
131
- return <AvatarGroup items={sources}></AvatarGroup>;
132
- },
147
+ return <AvatarGroup items={sources} />;
133
148
  },
149
+ },
134
150
  {
135
151
  title: t("Status"),
136
152
  dataIndex: 'status',
@@ -66,7 +66,13 @@ export const getColumns = ({t, goTo, user, options, activeTab, getRedirectLink,
66
66
  return <div className="daf-default-cell" />
67
67
  }
68
68
 
69
- const activity = findOptions(v, data?.options?.activityAtSiteOptions || data?.options?.activityAtSite);
69
+ const activityAtSiteOptions = [
70
+ ...(data?.options?.activityAtSiteOptions || []),
71
+ ...(options?.activityAtSiteOptions || []),
72
+ ...(options?.activityAtSite || [])
73
+ ]
74
+
75
+ const activity = findOptions(v, activityAtSiteOptions);
70
76
 
71
77
  return activity ? <Tooltip title={activity}>{activity}</Tooltip> : '-';
72
78
  },
@@ -101,20 +107,24 @@ export const getColumns = ({t, goTo, user, options, activeTab, getRedirectLink,
101
107
  ellipsis: true,
102
108
  },
103
109
  {
104
- title: t("Sources"),
105
- dataIndex: "sources",
106
- key: "sources",
107
- show: activeTab !== "own",
108
- render: (val, all) => {
109
- if (all.empty) {
110
- return <div className="daf-default-cell" />;
111
- }
110
+ title: t("Sources"),
111
+ dataIndex: "sources",
112
+ key: "sources",
113
+ show: activeTab !== "own",
114
+ render: (val, all) => {
115
+ if (all.empty) {
116
+ return <div className="daf-default-cell" />;
117
+ }
112
118
 
113
- const sources = sourceAvatarConfig(val, user, applications);
119
+ if (!val || val?.length === 0) {
120
+ return "-";
121
+ }
114
122
 
115
- return <AvatarGroup items={sources}></AvatarGroup>;
116
- },
117
- },
123
+ const sources = sourceAvatarConfig(val, user, applications);
124
+
125
+ return <AvatarGroup items={sources} />;
126
+ },
127
+ },
118
128
  {
119
129
  title: t("Status"),
120
130
  dataIndex: "status",
@@ -43,7 +43,9 @@ export const getColumns = ({t, goTo, user, options, activeTab, getRedirectLink,
43
43
  return <div className="daf-default-cell" />
44
44
  }
45
45
 
46
- const category = findOptions(v, options?.categoriesOptions);
46
+ const categoriesOptions = [...(options?.categoriesOptions || []), ...(options?.category || [])]
47
+
48
+ const category = findOptions(v, categoriesOptions);
47
49
 
48
50
  return category ? <Tooltip title={category}>{category}</Tooltip> : '-';
49
51
  },
@@ -58,7 +60,9 @@ export const getColumns = ({t, goTo, user, options, activeTab, getRedirectLink,
58
60
  return <div className="daf-default-cell" />
59
61
  }
60
62
 
61
- const subCategory = findOptions(v, options?.subCategoriesOptions);
63
+ const subCategoriesOptions = [...(options?.subCategoriesOptions || []), ...(options?.subCategory || [])];
64
+
65
+ const subCategory = findOptions(v, subCategoriesOptions);
62
66
 
63
67
  return subCategory ? <Tooltip title={subCategory}>{subCategory}</Tooltip> : '-';
64
68
  },
@@ -89,12 +93,12 @@ export const getColumns = ({t, goTo, user, options, activeTab, getRedirectLink,
89
93
  return <div className="daf-default-cell" />;
90
94
  }
91
95
  if (!val || val?.length === 0) {
92
- return "--";
96
+ return "-";
93
97
  }
94
98
 
95
99
  const sources = sourceAvatarConfig(val, user, applications);
96
100
 
97
- return <AvatarGroup items={sources}></AvatarGroup>;
101
+ return <AvatarGroup items={sources} />;
98
102
  },
99
103
  },
100
104
  {
@@ -1,6 +1,6 @@
1
1
  import React, { useMemo } from 'react';
2
2
  import { Widget, BarChart } from '../../../../../../../../src/index.js';
3
- import { calculateNaturalAxisConfig, mergeDefaultCategories } from '../chartHelpers.js';
3
+ import { calculateNiceAxisConfig, mergeDefaultCategories } from '../chartHelpers.js';
4
4
 
5
5
  const ObservedFauna = ({
6
6
  observedFaunaChart,
@@ -32,11 +32,16 @@ const ObservedFauna = ({
32
32
  }, [observedFaunaChart, options]);
33
33
 
34
34
  const xAxisConfig = useMemo(() => {
35
- const maxValue = chartData && chartData.length > 0
36
- ? Math.max(...chartData.map(item => Number(item?.value) || 0))
37
- : 0;
38
-
39
- return calculateNaturalAxisConfig(maxValue);
35
+ return calculateNiceAxisConfig(
36
+ chartData,
37
+ 'value',
38
+ 1.2, // multiplier: 20% padding
39
+ {
40
+ min: 0,
41
+ max: 10,
42
+ tickMethod: () => [0, 2, 4, 6, 8, 10]
43
+ }
44
+ );
40
45
  }, [chartData]);
41
46
 
42
47
  return (
@@ -2,14 +2,7 @@ import React, { useMemo, useCallback } from 'react';
2
2
  import { Widget, PieChart } from '../../../../../../../../src/index.js';
3
3
  import { renderTooltipJsx } from '../../../../../../utils/tooltip.js';
4
4
 
5
- // Color mapping for planted species
6
- const PLANTED_SPECIES_COLORS = {
7
- rhyzophora_mangle: '#016C6E',
8
- rhyzophora: '#00AEB1',
9
- rhyzophora_sp: '#A0EBEC',
10
- };
11
-
12
- const DEFAULT_COLOR = '#9E9E9E';
5
+ const COLORS = ['#6AD99E', '#F5C2AC', '#F0A888', '#DF571E', '#C04B19', '#9B3D14', '#7A2F0F'];
13
6
 
14
7
  const PlantedSpecies = ({
15
8
  plantedSpeciesChart,
@@ -34,7 +27,7 @@ const PlantedSpecies = ({
34
27
  return data.map((item, index) => ({
35
28
  value: Number(item?.count) || 0,
36
29
  percent: total > 0 ? (Number(item?.count) || 0) / total : 0,
37
- color: PLANTED_SPECIES_COLORS[item?.name] || DEFAULT_COLOR,
30
+ color: COLORS[index % COLORS.length],
38
31
  label: optionsMap[item?.name] || item?.name || '',
39
32
  key: item?.name || `item-${index}`,
40
33
  }));
@@ -51,26 +44,18 @@ const PlantedSpecies = ({
51
44
  return null;
52
45
  }
53
46
 
54
- // Calculate total from all items
55
- const total = pieData.reduce((sum, dataItem) => sum + (dataItem.value || 0), 0);
56
-
57
- // Show all items in the tooltip, sorted by value (descending)
58
- const allItems = pieData
59
- .filter(dataItem => dataItem.value > 0)
60
- .sort((a, b) => b.value - a.value)
61
- .map(dataItem => ({
62
- color: dataItem.color,
63
- label: dataItem.label || '',
64
- value: dataItem.value || 0,
65
- }));
66
-
67
47
  return renderTooltipJsx({
68
48
  title: t("Planted Species"),
69
- subTitle: total.toLocaleString(),
70
- items: allItems,
49
+ items: [
50
+ {
51
+ color: item.color,
52
+ label: item.label || '',
53
+ value: item.value || 0,
54
+ },
55
+ ],
71
56
  });
72
57
  },
73
- [t, isEmpty, pieData]
58
+ [t, isEmpty]
74
59
  );
75
60
 
76
61
  return (
@@ -1,6 +1,6 @@
1
1
  import React, { useMemo } from 'react';
2
2
  import { Widget, ColumnChart } from '../../../../../../../../src/index.js';
3
- import { calculateNaturalAxisConfig, mergeDefaultCategories } from '../chartHelpers.js';
3
+ import { calculateNiceAxisConfig, mergeDefaultCategories } from '../chartHelpers.js';
4
4
 
5
5
  // Default height ranges to always display
6
6
  const DEFAULT_HEIGHT_RANGES = [
@@ -26,13 +26,16 @@ const SeedlingsHeight = ({
26
26
  }, [seedlingsHeightChart]);
27
27
 
28
28
  const yAxisConfig = useMemo(() => {
29
- // Calculate max value from data
30
- const maxValue = chartData && chartData.length > 0
31
- ? Math.max(...chartData.map(item => Number(item?.value) || 0))
32
- : 0;
33
-
34
- // Use the helper function to calculate natural number axis configuration
35
- return calculateNaturalAxisConfig(maxValue);
29
+ return calculateNiceAxisConfig(
30
+ chartData,
31
+ 'value',
32
+ 2, // multiplier: double the max value
33
+ {
34
+ min: 0,
35
+ max: 20,
36
+ tickMethod: () => [0, 5, 10, 15, 20]
37
+ }
38
+ );
36
39
  }, [chartData]);
37
40
 
38
41
  return (
@@ -55,10 +58,10 @@ const SeedlingsHeight = ({
55
58
  const item = data[0]?.data || data[0];
56
59
  return {
57
60
  title: t("Seedlings Height"),
61
+ subTitle: title,
58
62
  items: [
59
63
  {
60
- color: "#016C6E",
61
- label: title,
64
+ label: t("Count"),
62
65
  value: item?.value || 0,
63
66
  },
64
67
  ],
@@ -2,22 +2,7 @@ import React, { useMemo, useCallback } from 'react';
2
2
  import { Widget, PieChart } from '../../../../../../../../src/index.js';
3
3
  import { renderTooltipJsx } from '../../../../../../utils/tooltip.js';
4
4
 
5
- // Color mapping for vegetation health conditions
6
- const VEGETATION_HEALTH_COLORS = {
7
- healthy_leaves: '#6AD99E',
8
- white_spots: '#E8F0F0',
9
- yellowing_leaves: '#CDC14F',
10
- black_spots: '#2E3131',
11
- reddish_spots: '#CB2525',
12
- leaf_mosaic: '#B59E76',
13
- spider_webs: '#F8F6EF',
14
- damage_from_insects: '#DE8954',
15
- dry_dead_leaves: '#767870',
16
- no_leaves: '#F97066',
17
- other: '#BDBDBD',
18
- };
19
-
20
- const DEFAULT_COLOR = '#9E9E9E';
5
+ const COLORS = ['#016C6E', '#F5C2AC', '#F0A888', '#DF571E', '#C04B19', '#9B3D14', '#7A2F0F'];
21
6
 
22
7
  const VegetationHealth = ({
23
8
  vegetationHealthChart,
@@ -41,15 +26,15 @@ const VegetationHealth = ({
41
26
  return data.map((item, index) => ({
42
27
  value: Number(item?.count) || 0,
43
28
  percent: total > 0 ? (Number(item?.count) || 0) / total : 0,
44
- color: VEGETATION_HEALTH_COLORS[item?.name] || DEFAULT_COLOR,
29
+ color: COLORS[index % COLORS.length],
45
30
  label: optionsMap[item?.name] || item?.name || '',
46
31
  key: item?.name || `item-${index}`,
47
32
  }));
48
33
  }, [vegetationHealthChart, optionsMap]);
49
34
 
50
35
  const isEmpty = useMemo(() => {
51
- return !vegetationHealthChart || vegetationHealthChart.length === 0 ||
52
- vegetationHealthChart.every(item => !item?.count || Number(item.count) === 0);
36
+ return !vegetationHealthChart || vegetationHealthChart.length === 0 ||
37
+ vegetationHealthChart.every(item => !item?.count || Number(item.count) === 0);
53
38
  }, [vegetationHealthChart]);
54
39
 
55
40
  const getTooltipChildren = useCallback(
@@ -3,15 +3,7 @@ import { Widget, PieChart } from '../../../../../../../../src/index.js';
3
3
  import { renderTooltipJsx } from '../../../../../../utils/tooltip.js';
4
4
  import { renderPercentage } from '../../../../../../utils/numbers.js';
5
5
 
6
- // Color mapping for soil types
7
- const SOIL_TYPE_COLORS = {
8
- sandy: '#00AEB1',
9
- mixed: '#016C6E',
10
- clay: '#A0EBEC',
11
- muddy: '#4FB3A1',
12
- };
13
-
14
- const DEFAULT_COLOR = '#9E9E9E';
6
+ const COLORS = ['#016C6E', '#4FB3A1', '#A8E6CF', '#FFD93D', '#F0A888', '#DF571E', '#C04B19'];
15
7
 
16
8
  const SoilType = ({
17
9
  soilTypeChart,
@@ -36,7 +28,7 @@ const SoilType = ({
36
28
  return data.map((item, index) => ({
37
29
  value: Number(item?.count) || 0,
38
30
  percent: total > 0 ? (Number(item?.count) || 0) / total : 0,
39
- color: SOIL_TYPE_COLORS[item?.soilType] || DEFAULT_COLOR,
31
+ color: COLORS[index % COLORS.length],
40
32
  label: optionsMap[item?.soilType] || item?.soilType || '',
41
33
  key: item?.soilType || `item-${index}`,
42
34
  }));
@@ -53,21 +45,17 @@ const SoilType = ({
53
45
  return null;
54
46
  }
55
47
 
56
- // Show all items in the tooltip, sorted by percentage (descending)
57
- const allItems = pieData
58
- .filter(dataItem => dataItem.value > 0)
59
- .sort((a, b) => b.percent - a.percent)
60
- .map(dataItem => ({
61
- color: dataItem.color,
62
- label: dataItem.label || '',
63
- value: renderPercentage(Math.round(dataItem.percent * 100)),
64
- }));
65
-
66
48
  return renderTooltipJsx({
67
49
  title: t("Soil Type"),
68
- items: allItems,
50
+ items: [
51
+ {
52
+ color: item.color,
53
+ label: optionsMap[item.label] || item.label || '',
54
+ value: `${ renderPercentage(item.percent.toFixed(2) * 100)}`,
55
+ },
56
+ ],
69
57
  });
70
- }, [t, isEmpty, pieData]);
58
+ }, [t, isEmpty, optionsMap]);
71
59
 
72
60
  return (
73
61
  <Widget
@@ -1,20 +1,8 @@
1
1
  import React, { useMemo, useCallback } from 'react';
2
2
  import { Widget, PieChart } from '../../../../../../../../src/index.js';
3
3
  import { renderTooltipJsx } from '../../../../../../utils/tooltip.js';
4
- import { renderPercentage } from '../../../../../../utils/numbers.js';
5
4
 
6
- // Color mapping for water quality types
7
- const WATER_QUALITY_COLORS = {
8
- fairly_clear: '#32D583',
9
- turbid: '#FFA940',
10
- polluted: '#F97066',
11
- oil_traces: '#2B3644',
12
- no_water: '#DAD6CE',
13
- clear: '#6AD99E',
14
- other: '#9E9E9E',
15
- };
16
-
17
- const DEFAULT_COLOR = '#9E9E9E';
5
+ const COLORS = ['#6AD99E', '#FFD93D', '#F0A888', '#DF571E', '#B0B0B0', '#016C6E', '#4FB3A1'];
18
6
 
19
7
  const WaterQuality = ({
20
8
  waterQualityChart,
@@ -38,7 +26,7 @@ const WaterQuality = ({
38
26
  return data.map((item, index) => ({
39
27
  value: Number(item?.count) || 0,
40
28
  percent: total > 0 ? (Number(item?.count) || 0) / total : 0,
41
- color: WATER_QUALITY_COLORS[item?.waterQuality] || DEFAULT_COLOR,
29
+ color: COLORS[index % COLORS.length],
42
30
  label: optionsMap[item?.waterQuality] || item?.waterQuality || '',
43
31
  key: item?.waterQuality || `item-${index}`,
44
32
  }));
@@ -55,22 +43,18 @@ const WaterQuality = ({
55
43
  return null;
56
44
  }
57
45
 
58
- // Show all items in the tooltip, sorted by percentage (descending)
59
- const allItems = pieData
60
- .filter(dataItem => dataItem.value > 0)
61
- .sort((a, b) => b.percent - a.percent)
62
- .map(dataItem => ({
63
- color: dataItem.color,
64
- label: dataItem.label || '',
65
- value: renderPercentage(Math.round(dataItem.percent * 100)),
66
- }));
67
-
68
46
  return renderTooltipJsx({
69
47
  title: t("Water Quality"),
70
- items: allItems,
48
+ items: [
49
+ {
50
+ color: item.color,
51
+ label: item.label || '',
52
+ value: `${Math.round(item.percent * 100)}%`,
53
+ },
54
+ ],
71
55
  });
72
56
  },
73
- [t, isEmpty, pieData]
57
+ [t, isEmpty]
74
58
  );
75
59
 
76
60
  return (