datastake-daf 0.6.817 → 0.6.819

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 (35) hide show
  1. package/dist/components/index.js +1215 -1074
  2. package/dist/pages/index.js +264 -89
  3. package/dist/services/index.js +0 -5
  4. package/package.json +1 -1
  5. package/public/Vegetation/damage-from-insects-default.svg +1 -0
  6. package/public/Vegetation/dry-or-dead-default.svg +1 -0
  7. package/public/Vegetation/healthy-default.svg +1 -0
  8. package/public/Vegetation/yellowing.svg +1 -0
  9. package/src/@daf/core/components/Charts/RadarChart/index.jsx +53 -2
  10. package/src/@daf/core/components/Charts/style.js +1 -1
  11. package/src/@daf/core/components/Dashboard/Widget/VegetationWidget/index.jsx +0 -4
  12. package/src/@daf/core/components/ViewForm/components/Records/config.js +1 -0
  13. package/src/@daf/core/components/ViewForm/components/Records/index.jsx +0 -1
  14. package/src/@daf/pages/Dashboards/SupplyChain/components/KeyIndicators/config.js +2 -2
  15. package/src/@daf/pages/Dashboards/SupplyChain/components/KeyIndicators/index.js +3 -2
  16. package/src/@daf/pages/Dashboards/SupplyChain/index.jsx +4 -1
  17. package/src/@daf/pages/Dashboards/UserDashboard/components/KeyIndicators/config.js +3 -3
  18. package/src/@daf/pages/Dashboards/UserDashboard/components/KeyIndicators/index.jsx +4 -2
  19. package/src/@daf/pages/Dashboards/UserDashboard/components/MineSites/config.js +2 -2
  20. package/src/@daf/pages/Dashboards/UserDashboard/config.js +2 -2
  21. package/src/@daf/pages/Dashboards/UserDashboard/index.jsx +1 -0
  22. package/src/@daf/pages/Dashboards/helper.js +2 -2
  23. package/src/@daf/pages/Events/config.js +1 -1
  24. package/src/@daf/pages/Locations/MineSite/columns.js +1 -1
  25. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/BiodiversityHabitat/ObservedFauna.jsx +6 -11
  26. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/BiodiversityHabitat/index.jsx +4 -2
  27. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MangroveGrowth/PlantedSpecies.jsx +25 -10
  28. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MangroveGrowth/SeedlingsHeight.jsx +10 -13
  29. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MangroveGrowth/VegetationHealth.jsx +19 -4
  30. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/SoilWaterProfile/SoilType.jsx +22 -10
  31. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/SoilWaterProfile/WaterQuality.jsx +26 -10
  32. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/chartHelpers.js +74 -0
  33. package/src/@daf/pages/TablePage/create.jsx +3 -1
  34. package/src/@daf/pages/TablePage/hook.js +2 -0
  35. package/src/@daf/services/LinkedSubjects.js +1 -1
@@ -1458,11 +1458,6 @@ 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
- });
1466
1461
  return this.apiGet({
1467
1462
  url: `forms/${namespace === "documents" ? namespace : getNamespace(namespace)}`,
1468
1463
  isApp: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "datastake-daf",
3
- "version": "0.6.817",
3
+ "version": "0.6.819",
4
4
  "dependencies": {
5
5
  "@ant-design/icons": "^5.2.5",
6
6
  "@antv/g2": "^5.1.1",
@@ -8,3 +8,4 @@
8
8
 
9
9
 
10
10
 
11
+
@@ -1,4 +1,4 @@
1
- import React, { useRef, useEffect } from "react";
1
+ import React, { useRef, useEffect, useCallback } from "react";
2
2
  import { Radar } from "@antv/g2plot";
3
3
  import { theme } from "antd";
4
4
  import { renderTooltip } from "../../../../utils/tooltip";
@@ -39,6 +39,46 @@ const RadarChart = ({
39
39
  legendStyle
40
40
  } = useLegendConfig({legendConfig, isPdf});
41
41
 
42
+ // Helper function to wrap long text labels to multiple lines
43
+ // Ensures text is never hidden - wraps to multiple lines if needed
44
+ const wrapLabel = useCallback((text, maxLength = 10) => {
45
+ if (!text) {
46
+ return '';
47
+ }
48
+
49
+ const formattedText = formattedXAxis(text);
50
+
51
+ // If text is short enough, return as is
52
+ if (formattedText.length <= maxLength) {
53
+ return formattedText;
54
+ }
55
+
56
+ // Split by spaces to find word boundaries
57
+ const words = formattedText.split(' ');
58
+ const lines = [];
59
+ let currentLine = '';
60
+
61
+ words.forEach((word, index) => {
62
+ // If adding this word would exceed maxLength, start a new line
63
+ if (currentLine && (currentLine + ' ' + word).length > maxLength) {
64
+ if (currentLine) {
65
+ lines.push(currentLine);
66
+ }
67
+ currentLine = word;
68
+ } else {
69
+ currentLine = currentLine ? currentLine + ' ' + word : word;
70
+ }
71
+
72
+ // If it's the last word, add it to lines
73
+ if (index === words.length - 1 && currentLine) {
74
+ lines.push(currentLine);
75
+ }
76
+ });
77
+
78
+ // Ensure we always return something - never empty
79
+ return lines.length > 0 ? lines.join('\n') : formattedText;
80
+ }, [formattedXAxis]);
81
+
42
82
  useEffect(() => {
43
83
  if (!containerRef.current) {
44
84
  return;
@@ -59,9 +99,19 @@ const RadarChart = ({
59
99
  }
60
100
  : { showCrosshairs: false, showMarkers: true, ...tooltipConfig },
61
101
  color: color || token.colorPrimary7,
102
+ // Increased padding to ensure labels are never clipped
103
+ padding: [50, 50, 50, 50],
62
104
  xAxis: {
63
105
  label: {
64
- formatter: formattedXAxis,
106
+ formatter: (text) => wrapLabel(text, 10),
107
+ offset: 15,
108
+ autoRotate: false,
109
+ autoHide: false, // Never hide labels
110
+ autoEllipsis: false, // Never truncate with ellipsis
111
+ style: {
112
+ fontSize: 12,
113
+ fill: '#666',
114
+ },
65
115
  },
66
116
  line: null,
67
117
  tickLine: null,
@@ -129,6 +179,7 @@ const RadarChart = ({
129
179
  formattedXAxis,
130
180
  score,
131
181
  token.colorPrimary7,
182
+ wrapLabel,
132
183
  rest,
133
184
  ]);
134
185
 
@@ -2,7 +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)'};
5
+ width: ${props => props.isPdf ? (props.width ? props.width : '1000px') : 'calc(100% - 48px)'};
6
6
  `;
7
7
 
8
8
  export default Container;
@@ -16,16 +16,12 @@ 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)
20
19
  const allVegetationKeys = vegetationConfig.map(item => item.key);
21
20
 
22
- // Filter to show only specific keys if filterKeys is provided
23
21
  if (filterKeys && Array.isArray(filterKeys)) {
24
22
  vegetationConfig = vegetationConfig.filter(item => filterKeys.includes(item.key));
25
23
  }
26
24
 
27
- // Map growthObservations to VEGETATION_KEYS
28
- // Handle both formats: growthObservations keys (e.g., "yellowing_leaves") and VEGETATION_KEYS (e.g., "yellowing")
29
25
  const mappedGrowthObservations = Array.isArray(growthObservations)
30
26
  ? growthObservations
31
27
  .map(obs => {
@@ -4,6 +4,7 @@ export const getSourcesType = (subject) => {
4
4
  locations: "location",
5
5
  location: "location",
6
6
  "production-sites": "location",
7
+ scl: "location",
7
8
 
8
9
  stakeholders: "stakeholder",
9
10
  stakeholder: "stakeholder",
@@ -39,7 +39,6 @@ const Records = ({
39
39
  const { data } = await VersionService.getSources({ type, id, params: {
40
40
  source: selectedSource,
41
41
  } });
42
- console.log({data})
43
42
  setVersions(data);
44
43
  } catch (error) {
45
44
  console.error('Error fetching versions:', error);
@@ -2,7 +2,7 @@ import React from "react";
2
2
  import CustomIcon from '../../../../../core/components/Icon/CustomIcon.jsx';
3
3
  import KeyIndicatorNavigateLabel from '../../../../../core/components/UI/KeyIndicatorNavigateLabel/index.jsx';
4
4
 
5
- export const getRowConfig = ({ t, data = {}, goTo, getRedirectLink, theme = {} }) => [
5
+ export const getRowConfig = ({ t, data = {}, goTo, getRedirectLink, theme = {}, APP }) => [
6
6
  {
7
7
  label: (
8
8
  <KeyIndicatorNavigateLabel
@@ -10,7 +10,7 @@ export const getRowConfig = ({ t, data = {}, goTo, getRedirectLink, theme = {} }
10
10
  getRedirectLink={getRedirectLink}
11
11
  theme={theme}
12
12
  label="Identified Mine Sites"
13
- link="/app/production-sites"
13
+ link={APP === 'nashiriki' ? '/app/scl' : '/app/production-sites'}
14
14
  />
15
15
  ),
16
16
  render: () => {
@@ -13,7 +13,7 @@ const defaultFetchConfig = {
13
13
  },
14
14
  };
15
15
 
16
- function KeyIndicators({selectedSources = {}, theme = {}, getRedirectLink = () => {}, t = () => {}, goTo = () => {} }) {
16
+ function KeyIndicators({selectedSources = {}, theme = {}, getRedirectLink = () => {}, t = () => {}, goTo = () => {}, APP }) {
17
17
  const fetchConfig = useMemo(() => ({
18
18
  ...defaultFetchConfig,
19
19
  filters: { ...defaultFetchConfig.filters, sources: selectedSources?.partners || [] },
@@ -29,8 +29,9 @@ function KeyIndicators({selectedSources = {}, theme = {}, getRedirectLink = () =
29
29
  goTo,
30
30
  getRedirectLink,
31
31
  theme,
32
+ APP
32
33
  })
33
- }, [t, data, goTo, getRedirectLink, theme])
34
+ }, [t, data, goTo, getRedirectLink, theme, APP])
34
35
 
35
36
  return (
36
37
  <KeyIndicatorsWidget
@@ -21,6 +21,8 @@ function SupplyChain({
21
21
  informationSources,
22
22
  hardcodedData,
23
23
  breadcrumbs = [],
24
+ supportText,
25
+ APP,
24
26
  }) {
25
27
 
26
28
  const sourceOptions = useMemo(() => {
@@ -69,12 +71,13 @@ function SupplyChain({
69
71
  />
70
72
  </div>
71
73
  }
74
+ supportText={supportText}
72
75
  breadcrumbs={breadcrumbs}
73
76
  />
74
77
  }
75
78
  >
76
79
  <section>
77
- <KeyIndicators selectedSources={selectedPartners} theme={theme} t={t} goTo={goTo} getRedirectLink={getRedirectLink} />
80
+ <KeyIndicators selectedSources={selectedPartners} theme={theme} t={t} goTo={goTo} getRedirectLink={getRedirectLink} APP={APP} />
78
81
  </section>
79
82
  <section>
80
83
  <SupplyChainMap selectedSources={selectedPartners} t={t} goTo={goTo} options={options} getRedirectLink={getRedirectLink} />
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import CustomIcon from '../../../../../core/components/Icon/CustomIcon.jsx';
3
3
  import KeyIndicatorNavigateLabel from '../../../../../core/components/UI/KeyIndicatorNavigateLabel/index.jsx';
4
4
 
5
- export const getRowConfig = ({ t, data = {}, goTo, getRedirectLink, theme = {} }) => [
5
+ export const getRowConfig = ({ t, data = {}, goTo, getRedirectLink, theme = {}, APP }) => [
6
6
  {
7
7
  label: (
8
8
  <KeyIndicatorNavigateLabel
@@ -35,8 +35,8 @@ export const getRowConfig = ({ t, data = {}, goTo, getRedirectLink, theme = {} }
35
35
  t={t}
36
36
  getRedirectLink={getRedirectLink}
37
37
  theme={theme}
38
- label="Activities"
39
- link="/app/activities"
38
+ label={APP === 'nashiriki' ? 'Corrective Actions' : 'Activities'}
39
+ link={APP === 'nashiriki' ? '/app/corrective-actions' : '/app/activities'}
40
40
  />
41
41
  ),
42
42
  render: () => {
@@ -17,6 +17,7 @@ function KeyIndicators({
17
17
  getRedirectLink = () => {},
18
18
  theme = {},
19
19
  partners = [],
20
+ APP,
20
21
  }) {
21
22
  const fetchConfig = useMemo(
22
23
  () => ({
@@ -33,9 +34,10 @@ function KeyIndicators({
33
34
  data: { ...data, partners },
34
35
  goTo,
35
36
  getRedirectLink,
36
- theme
37
+ theme,
38
+ APP
37
39
  }),
38
- [t, data, goTo, getRedirectLink, partners, theme],
40
+ [t, data, goTo, getRedirectLink, partners, theme, APP],
39
41
  );
40
42
 
41
43
  return (
@@ -9,7 +9,7 @@ export const getTabs = (t) => {
9
9
  export const getFiltersConfig = ({t, filters, activeTab, options}) => {
10
10
  const value = filters.type ? { value: filters.type } : {};
11
11
 
12
- const eventCategoryOptions = (options?.eventCategoryOptions || [])?.map((item) => ({
12
+ const eventCategoryOptions = (options?.eventCategoryOptions || options?.categoryOptions || [])?.map((item) => ({
13
13
  value: item.value,
14
14
  label: typeof item.label === 'object' ? Object.values(item.label)[1] : item.label,
15
15
  }))
@@ -22,7 +22,7 @@ export const getFiltersConfig = ({t, filters, activeTab, options}) => {
22
22
  key: "category",
23
23
  type: "select",
24
24
  ...value,
25
- options: options?.categoriesOptions ?? [],
25
+ options: options?.categoriesOptions || options?.category || [],
26
26
  },
27
27
  ];
28
28
  }
@@ -2,12 +2,12 @@ export const getActionWidgetsConfig = ({ goTo, getRedirectLink, APP, t }) => [
2
2
  {
3
3
  icon: "MineSite",
4
4
  title: t("Create Mine Site"),
5
- onClick: () => goTo(getRedirectLink("/app/production-sites?create=true")),
5
+ onClick: () => goTo(getRedirectLink(`/app/${APP === 'nashiriki' ? 'scl' : 'production-sites'}?create=true`)),
6
6
  },
7
7
  {
8
8
  icon: "FileEdit",
9
9
  title: "Report Activity",
10
- onClick: () => goTo(getRedirectLink("/app/activities?create=true")),
10
+ onClick: () => goTo(getRedirectLink(`/app/${APP === 'nashiriki' ? 'corrective-actions' : 'activities'}?create=true`)),
11
11
  },
12
12
  {
13
13
  icon: "ReportIncidents",
@@ -67,6 +67,7 @@ function UserDashboard({
67
67
  t={t}
68
68
  goTo={goTo}
69
69
  getRedirectLink={getRedirectLink}
70
+ APP={APP}
70
71
  />
71
72
  </section>
72
73
  <section>
@@ -53,7 +53,7 @@ export const mapDataForChainOfCustody = (data = {}, options = {}, goTo = () => {
53
53
  number: 0,
54
54
  name: item.name,
55
55
  sources: parentId ? [parentId] : [],
56
- subTitle: findOptions(item?.category, options?.categoriesOptions),
56
+ subTitle: findOptions(item?.category, options?.categoriesOptions || options?.category || []),
57
57
  leftIcon: type === "client" ? rightIcon : leftIcon,
58
58
  leftBackground: type === "client" ? rightBackground : leftBackground,
59
59
  topIcon: mapIcon(item.category),
@@ -70,7 +70,7 @@ export const mapDataForChainOfCustody = (data = {}, options = {}, goTo = () => {
70
70
  id: data.id,
71
71
  number: 0,
72
72
  name: data.name,
73
- subTitle: findOptions(data?.category, options?.categoriesOptions),
73
+ subTitle: findOptions(data?.category, options?.categoriesOptions || options?.category || []),
74
74
  leftIcon: middleIcon,
75
75
  leftBackground: theme.colorPrimary10,
76
76
  topIcon: mapIcon(data.category),
@@ -117,7 +117,7 @@ export const getFilterOptions = (options, t) => {
117
117
  eventCategoryOptions,
118
118
  } = options || {};
119
119
 
120
- const catOptions = eventCategoryOptions?.map((item) => ({
120
+ const catOptions = (eventCategoryOptions || categoryOptions || [])?.map((item) => ({
121
121
  value: item.value,
122
122
  label: typeof item.label === 'object' ? Object.values(item.label)[1] : item.label,
123
123
  }))
@@ -188,7 +188,7 @@ export const getColumns = ({t, goTo, user, options, activeTab, getRedirectLink,
188
188
  label: t("Summary"),
189
189
  value: "Summary",
190
190
  onClick: () => {
191
- let link = `/app/${subject === 'scl' ? 'summary/scl' : 'mine-summary'}/${all.datastakeId}`
191
+ let link = `/app/mine-summary/${all.datastakeId}`
192
192
  if (activeTab === "shared") {
193
193
  link += `?sourceId=${all?.authorId?.id}`;
194
194
  }
@@ -1,6 +1,6 @@
1
1
  import React, { useMemo } from 'react';
2
2
  import { Widget, BarChart } from '../../../../../../../../src/index.js';
3
- import { calculateNiceAxisConfig, mergeDefaultCategories } from '../chartHelpers.js';
3
+ import { calculateNaturalAxisConfig, mergeDefaultCategories } from '../chartHelpers.js';
4
4
 
5
5
  const ObservedFauna = ({
6
6
  observedFaunaChart,
@@ -32,16 +32,11 @@ const ObservedFauna = ({
32
32
  }, [observedFaunaChart, options]);
33
33
 
34
34
  const xAxisConfig = useMemo(() => {
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
- );
35
+ const maxValue = chartData && chartData.length > 0
36
+ ? Math.max(...chartData.map(item => Number(item?.value) || 0))
37
+ : 0;
38
+
39
+ return calculateNaturalAxisConfig(maxValue);
45
40
  }, [chartData]);
46
41
 
47
42
  return (
@@ -83,8 +83,8 @@ const BiodiversityHabitat = ({
83
83
  t={t}
84
84
  />
85
85
 
86
- <div style={{ display: "flex", gap: "24px" }}>
87
- <section style={{ flex: 1 }}>
86
+ <div style={{ display: "flex", gap: "24px", flexWrap: "wrap" }}>
87
+ <section style={{ flex: 1, minWidth: "300px" }}>
88
88
  <ObservedFauna
89
89
  observedFaunaChart={observedFauna}
90
90
  t={t}
@@ -92,11 +92,13 @@ const BiodiversityHabitat = ({
92
92
  />
93
93
  </section>
94
94
 
95
+ <section style={{ flex: 1, minWidth: "300px" }}>
95
96
  <InvasiveSpecies
96
97
  invasiveSpeciesChart={invasiveSpecies}
97
98
  t={t}
98
99
  options={options}
99
100
  />
101
+ </section>
100
102
 
101
103
  </div>
102
104
  </Widget>
@@ -2,7 +2,14 @@ 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
- const COLORS = ['#6AD99E', '#F5C2AC', '#F0A888', '#DF571E', '#C04B19', '#9B3D14', '#7A2F0F'];
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';
6
13
 
7
14
  const PlantedSpecies = ({
8
15
  plantedSpeciesChart,
@@ -27,7 +34,7 @@ const PlantedSpecies = ({
27
34
  return data.map((item, index) => ({
28
35
  value: Number(item?.count) || 0,
29
36
  percent: total > 0 ? (Number(item?.count) || 0) / total : 0,
30
- color: COLORS[index % COLORS.length],
37
+ color: PLANTED_SPECIES_COLORS[item?.name] || DEFAULT_COLOR,
31
38
  label: optionsMap[item?.name] || item?.name || '',
32
39
  key: item?.name || `item-${index}`,
33
40
  }));
@@ -44,18 +51,26 @@ const PlantedSpecies = ({
44
51
  return null;
45
52
  }
46
53
 
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
+
47
67
  return renderTooltipJsx({
48
68
  title: t("Planted Species"),
49
- items: [
50
- {
51
- color: item.color,
52
- label: item.label || '',
53
- value: item.value || 0,
54
- },
55
- ],
69
+ subTitle: total.toLocaleString(),
70
+ items: allItems,
56
71
  });
57
72
  },
58
- [t, isEmpty]
73
+ [t, isEmpty, pieData]
59
74
  );
60
75
 
61
76
  return (
@@ -1,6 +1,6 @@
1
1
  import React, { useMemo } from 'react';
2
2
  import { Widget, ColumnChart } from '../../../../../../../../src/index.js';
3
- import { calculateNiceAxisConfig, mergeDefaultCategories } from '../chartHelpers.js';
3
+ import { calculateNaturalAxisConfig, mergeDefaultCategories } from '../chartHelpers.js';
4
4
 
5
5
  // Default height ranges to always display
6
6
  const DEFAULT_HEIGHT_RANGES = [
@@ -26,16 +26,13 @@ const SeedlingsHeight = ({
26
26
  }, [seedlingsHeightChart]);
27
27
 
28
28
  const yAxisConfig = useMemo(() => {
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
- );
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);
39
36
  }, [chartData]);
40
37
 
41
38
  return (
@@ -58,10 +55,10 @@ const SeedlingsHeight = ({
58
55
  const item = data[0]?.data || data[0];
59
56
  return {
60
57
  title: t("Seedlings Height"),
61
- subTitle: title,
62
58
  items: [
63
59
  {
64
- label: t("Count"),
60
+ color: "#016C6E",
61
+ label: title,
65
62
  value: item?.value || 0,
66
63
  },
67
64
  ],
@@ -2,7 +2,22 @@ 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
- const COLORS = ['#016C6E', '#F5C2AC', '#F0A888', '#DF571E', '#C04B19', '#9B3D14', '#7A2F0F'];
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';
6
21
 
7
22
  const VegetationHealth = ({
8
23
  vegetationHealthChart,
@@ -26,15 +41,15 @@ const VegetationHealth = ({
26
41
  return data.map((item, index) => ({
27
42
  value: Number(item?.count) || 0,
28
43
  percent: total > 0 ? (Number(item?.count) || 0) / total : 0,
29
- color: COLORS[index % COLORS.length],
44
+ color: VEGETATION_HEALTH_COLORS[item?.name] || DEFAULT_COLOR,
30
45
  label: optionsMap[item?.name] || item?.name || '',
31
46
  key: item?.name || `item-${index}`,
32
47
  }));
33
48
  }, [vegetationHealthChart, optionsMap]);
34
49
 
35
50
  const isEmpty = useMemo(() => {
36
- return !vegetationHealthChart || vegetationHealthChart.length === 0 ||
37
- vegetationHealthChart.every(item => !item?.count || Number(item.count) === 0);
51
+ return !vegetationHealthChart || vegetationHealthChart.length === 0 ||
52
+ vegetationHealthChart.every(item => !item?.count || Number(item.count) === 0);
38
53
  }, [vegetationHealthChart]);
39
54
 
40
55
  const getTooltipChildren = useCallback(
@@ -3,7 +3,15 @@ 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
- const COLORS = ['#016C6E', '#4FB3A1', '#A8E6CF', '#FFD93D', '#F0A888', '#DF571E', '#C04B19'];
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';
7
15
 
8
16
  const SoilType = ({
9
17
  soilTypeChart,
@@ -28,7 +36,7 @@ const SoilType = ({
28
36
  return data.map((item, index) => ({
29
37
  value: Number(item?.count) || 0,
30
38
  percent: total > 0 ? (Number(item?.count) || 0) / total : 0,
31
- color: COLORS[index % COLORS.length],
39
+ color: SOIL_TYPE_COLORS[item?.soilType] || DEFAULT_COLOR,
32
40
  label: optionsMap[item?.soilType] || item?.soilType || '',
33
41
  key: item?.soilType || `item-${index}`,
34
42
  }));
@@ -45,17 +53,21 @@ const SoilType = ({
45
53
  return null;
46
54
  }
47
55
 
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
+
48
66
  return renderTooltipJsx({
49
67
  title: t("Soil Type"),
50
- items: [
51
- {
52
- color: item.color,
53
- label: optionsMap[item.label] || item.label || '',
54
- value: `${ renderPercentage(item.percent.toFixed(2) * 100)}`,
55
- },
56
- ],
68
+ items: allItems,
57
69
  });
58
- }, [t, isEmpty, optionsMap]);
70
+ }, [t, isEmpty, pieData]);
59
71
 
60
72
  return (
61
73
  <Widget