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.
Files changed (59) hide show
  1. package/dist/components/index.js +78 -70
  2. package/dist/hooks/index.js +3 -1
  3. package/dist/pages/index.js +1082 -270
  4. package/dist/style/datastake/mapbox-gl.css +330 -0
  5. package/dist/utils/index.js +67 -0
  6. package/package.json +1 -1
  7. package/src/@daf/core/components/Charts/BarChart/index.jsx +1 -1
  8. package/src/@daf/core/components/Dashboard/Map/ChainIcon/utils.js +2 -2
  9. package/src/@daf/core/components/Screens/BaseScreen/index.jsx +1 -0
  10. package/src/@daf/core/components/Select/MultiSelect/index.jsx +4 -2
  11. package/src/@daf/core/components/Select/MultiSelect/style.js +15 -0
  12. package/src/@daf/hooks/useGetQueryParams.js +3 -1
  13. package/src/@daf/pages/Dashboards/UserDashboard/components/ContributionsGraph/hook.js +6 -7
  14. package/src/@daf/pages/Dashboards/UserDashboard/components/ContributionsGraph/index.jsx +1 -1
  15. package/src/@daf/pages/Documents/config.js +5 -5
  16. package/src/@daf/pages/Events/Activities/columns.js +5 -0
  17. package/src/@daf/pages/Events/Activities/config.js +21 -17
  18. package/src/@daf/pages/Events/Incidents/columns.js +5 -0
  19. package/src/@daf/pages/Events/Incidents/config.js +14 -11
  20. package/src/@daf/pages/Events/columns.js +6 -0
  21. package/src/@daf/pages/Events/config.js +0 -16
  22. package/src/@daf/pages/Locations/MineSite/columns.js +5 -1
  23. package/src/@daf/pages/Locations/MineSite/config.js +21 -24
  24. package/src/@daf/pages/Partners/columns.js +3 -1
  25. package/src/@daf/pages/Partners/config.js +13 -9
  26. package/src/@daf/pages/Partners/create.jsx +5 -2
  27. package/src/@daf/pages/Partners/edit.jsx +4 -2
  28. package/src/@daf/pages/Stakeholders/Operators/columns.js +6 -0
  29. package/src/@daf/pages/Stakeholders/Operators/config.js +8 -8
  30. package/src/@daf/pages/Stakeholders/Workers/columns.js +19 -13
  31. package/src/@daf/pages/Stakeholders/Workers/config.js +8 -23
  32. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/KeyInformation/index.jsx +48 -0
  33. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MangroveGrowth/PlantedSpecies.jsx +73 -0
  34. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MangroveGrowth/SeedlingsHeight.jsx +44 -0
  35. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MangroveGrowth/Stats.jsx +86 -0
  36. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MangroveGrowth/VegetationHealth.jsx +73 -0
  37. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MangroveGrowth/index.jsx +92 -0
  38. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MonitoringScopeAndFindings/index.jsx +348 -0
  39. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/config.js +35 -0
  40. package/src/@daf/pages/Summary/Activities/MonitoringCampaign/index.jsx +30 -0
  41. package/src/@daf/pages/Summary/Activities/PlantingCycle/components/CommunityParticipation/CommunityStats/helper.js +1 -1
  42. package/src/@daf/pages/Summary/Activities/PlantingCycle/components/CycleIndicators/index.jsx +1 -1
  43. package/src/@daf/pages/Summary/Activities/PlantingCycle/components/CycleOutcomes/index.jsx +1 -1
  44. package/src/@daf/pages/Summary/Activities/PlantingCycle/helper.js +0 -56
  45. package/src/@daf/pages/Summary/Minesite/index.jsx +6 -4
  46. package/src/@daf/pages/Summary/Operator/components/TradeRelationships/index.js +2 -0
  47. package/src/@daf/pages/Summary/Operator/index.jsx +6 -3
  48. package/src/@daf/pages/TablePage/index.jsx +8 -2
  49. package/src/@daf/pages/Template/components/LinkingTemplate/config.js +14 -1
  50. package/src/@daf/pages/Template/components/LinkingTemplate/index.jsx +4 -2
  51. package/src/@daf/pages/Template/index.jsx +1 -10
  52. package/src/@daf/pages/View/hooks/usePrepareForm.js +4 -4
  53. package/src/@daf/pages/View/index.jsx +2 -1
  54. package/src/@daf/utils/numbers.js +57 -0
  55. package/src/constants/locales/en/translation.js +3 -0
  56. package/src/constants/locales/fr/translation.js +3 -0
  57. package/src/constants/locales/sp/translation.js +3 -0
  58. package/src/pages.js +1 -0
  59. package/src/utils.js +1 -1
@@ -3,7 +3,7 @@ export const getFiltersConfig = ({t}) => {
3
3
  country: {
4
4
  type: 'select',
5
5
  label: 'Country',
6
- placeholder: (t) => `${t('Filter by')} ${t('Country').toLowerCase()}`,
6
+ placeholder: () => `${t('Filter by')} ${t('Country').toLowerCase()}`,
7
7
  style: { flex: 1 },
8
8
  labelStyle: { flex: 1 },
9
9
  getLabel: (option) => option.label,
@@ -27,7 +27,7 @@ export const getFiltersConfig = ({t}) => {
27
27
 
28
28
  return t('Province');
29
29
  },
30
- placeholder: (t) => `${t('Filter by')} ${t('Province').toLowerCase()}`,
30
+ placeholder: () => `${t('Filter by')} ${t('Province').toLowerCase()}`,
31
31
  filters: (data) => ({
32
32
  country: data.country,
33
33
  level: 'level_1',
@@ -59,7 +59,7 @@ export const getFiltersConfig = ({t}) => {
59
59
  return t('Province');
60
60
  },
61
61
  show: (data) => !(data.country && data.administrativeLevel1),
62
- placeholder: (t) => `${t('Filter by')} ${t('Territory').toLowerCase()}`,
62
+ placeholder: () => `${t('Filter by')} ${t('Territory').toLowerCase()}`,
63
63
  filters: (data) => ({
64
64
  country: data.country,
65
65
  level: 'level_2',
@@ -75,31 +75,16 @@ export const getFiltersConfig = ({t}) => {
75
75
  activity: {
76
76
  type: 'select',
77
77
  label: 'Activity',
78
- placeholder: (t) => `${t('Filter by')} ${t('Activity').toLowerCase()}`,
78
+ placeholder: () => `${t('Filter by')} ${t('Activity').toLowerCase()}`,
79
79
  style: { flex: 1 },
80
80
  labelStyle: { flex: 1 },
81
81
  getLabel: (option) => option.label,
82
82
  getValue: (option) => option.value,
83
- filterOptions: (val) => {
84
- if (val) {
85
- const { option, filters } = val
86
- if (filters && option) {
87
- const { filters: optionFilters } = option;
88
- if (Array.isArray(optionFilters) && optionFilters.length) {
89
- const { value, condition } = optionFilters[0];
90
- if (condition === 'includes') {
91
- return value.includes('corporation');
92
- }
93
- }
94
- }
95
- }
96
- return true;
97
- },
98
83
  },
99
84
  positionInTheMineralSupplyChain: {
100
85
  type: 'select',
101
86
  label: 'Position',
102
- placeholder: (t) => `${t('Filter by')} ${t('Position').toLowerCase()}`,
87
+ placeholder: () => `${t('Filter by')} ${t('Position').toLowerCase()}`,
103
88
  style: { flex: 1 },
104
89
  labelStyle: { flex: 1 },
105
90
  getLabel: (option) => option.label,
@@ -108,7 +93,7 @@ export const getFiltersConfig = ({t}) => {
108
93
  status: {
109
94
  type: "select",
110
95
  label: "Status",
111
- placeholder: (t) => `${t("Filter by")} ${t("Status").toLowerCase()}`,
96
+ placeholder: () => `${t("Filter by")} ${t("Status").toLowerCase()}`,
112
97
  style: { flex: 1 },
113
98
  labelStyle: { fley: 1 },
114
99
  getLabel: (option) => option.label,
@@ -136,11 +121,11 @@ export const getFilterOptions = (options, t) => {
136
121
  status: [
137
122
  {
138
123
  value: "submitted",
139
- label: "Submitted",
124
+ label: t("Submitted"),
140
125
  },
141
126
  {
142
127
  value: "private",
143
- label: "Private",
128
+ label: t("Private"),
144
129
  },
145
130
  ],
146
131
  category: stakeholderCategoryOptions || categoryOptions,
@@ -0,0 +1,48 @@
1
+ import { useMemo } from 'react';
2
+ import { KeyIndicators } from '../../../../../../../../src/index.js';
3
+ import { getKeyIndicatorsRowConfig } from '../../config';
4
+ import { useWidgetFetch } from '../../../../../../hooks/useWidgetFetch.js';
5
+
6
+ const KeyInformation = ({ id, t = () => { }, getSummaryDetail, loading = false }) => {
7
+
8
+ const defaultConfig = useMemo(
9
+ () => ({
10
+ basepath: "events/monitoring-campaign",
11
+ url: `/summary/${id}/key-information`,
12
+ stop: !id,
13
+ }),
14
+ [id],
15
+ );
16
+
17
+ const customGetData = useMemo(() => {
18
+ if (getSummaryDetail && id) {
19
+ return ({ url, params = {} }) => {
20
+ const match = url.match(/\/summary\/[^/]+\/(.+)/);
21
+ if (match) {
22
+ const [, type] = match;
23
+ return getSummaryDetail(id, type, params);
24
+ }
25
+ throw new Error(`Invalid URL format: ${url}`);
26
+ };
27
+ }
28
+ return undefined;
29
+ }, [getSummaryDetail, id]);
30
+
31
+ const { loading: keyInformationLoading, data: keyInformationData } = useWidgetFetch({
32
+ config: defaultConfig,
33
+ getData: customGetData
34
+ });
35
+ const keyIndicatorsConfig = useMemo(() => getKeyIndicatorsRowConfig({ t, data: keyInformationData }), [t, keyInformationData]);
36
+ return (
37
+ <section>
38
+ <KeyIndicators
39
+ title={t("Key Information")}
40
+ config={keyIndicatorsConfig}
41
+ loading={loading || keyInformationLoading}
42
+ />
43
+ </section>
44
+ );
45
+ };
46
+
47
+ export default KeyInformation;
48
+
@@ -0,0 +1,73 @@
1
+ import React, { useMemo, useCallback } from 'react';
2
+ import { Widget, PieChart } from '../../../../../../../../src/index.js';
3
+ import { renderTooltipJsx } from '../../../../../../utils/tooltip.js';
4
+
5
+ const COLORS = ['#016C6E', '#F5C2AC', '#F0A888', '#DF571E', '#C04B19', '#9B3D14', '#7A2F0F'];
6
+
7
+ const PlantedSpecies = ({
8
+ plantedSpeciesChart,
9
+ t = (s) => s
10
+ }) => {
11
+ const pieData = useMemo(() => {
12
+ const data = plantedSpeciesChart || [];
13
+ const total = data.reduce((sum, item) => sum + (Number(item?.value) || 0), 0);
14
+
15
+ return data.map((item, index) => ({
16
+ value: Number(item?.value) || 0,
17
+ percent: total > 0 ? (Number(item?.value) || 0) / total : 0,
18
+ color: COLORS[index % COLORS.length],
19
+ label: item?.type || '',
20
+ key: item?.type || `item-${index}`,
21
+ }));
22
+ }, [plantedSpeciesChart]);
23
+
24
+ const isEmpty = useMemo(() => {
25
+ return !plantedSpeciesChart || plantedSpeciesChart.length === 0 ||
26
+ plantedSpeciesChart.every(item => !item?.value || Number(item.value) === 0);
27
+ }, [plantedSpeciesChart]);
28
+
29
+ const getTooltipChildren = useCallback(
30
+ (item) => {
31
+ if (isEmpty) {
32
+ return null;
33
+ }
34
+
35
+ return renderTooltipJsx({
36
+ title: t("Planted Species"),
37
+ items: [
38
+ {
39
+ color: item.color,
40
+ label: item.label || '',
41
+ value: item.value || 0,
42
+ },
43
+ ],
44
+ });
45
+ },
46
+ [t, isEmpty]
47
+ );
48
+
49
+ return (
50
+ <Widget
51
+ title={t("Planted Species")}
52
+ className="with-border-header h-w-btn-header"
53
+ >
54
+ <div className="flex flex-1 flex-column justify-content-center">
55
+ <div className="flex justify-content-center w-full">
56
+ <PieChart
57
+ data={pieData}
58
+ isPie
59
+ isEmpty={isEmpty}
60
+ getTooltipChildren={getTooltipChildren}
61
+ mouseXOffset={10}
62
+ mouseYOffset={10}
63
+ changeOpacityOnHover={false}
64
+ doConstraints={false}
65
+ />
66
+ </div>
67
+ </div>
68
+ </Widget>
69
+ );
70
+ };
71
+
72
+ export default PlantedSpecies;
73
+
@@ -0,0 +1,44 @@
1
+ import React from 'react';
2
+ import { Widget, ColumnChart } from '../../../../../../../../src/index.js';
3
+
4
+ const SeedlingsHeight = ({
5
+ seedlingsHeightChart,
6
+ t = (s) => s
7
+ }) => {
8
+ return (
9
+ <Widget
10
+ title={t("Seedlings Height")}
11
+ className="with-border-header h-w-btn-header"
12
+ >
13
+ <div className="flex flex-1 flex-column justify-content-center">
14
+ <div className="flex justify-content-center w-full">
15
+ <ColumnChart
16
+ data={seedlingsHeightChart || []}
17
+ xFieldKey="label"
18
+ yFieldKey="value"
19
+ animated={true}
20
+ height={200}
21
+ color="#016C6E"
22
+ renderTooltipContent={(title, data) => {
23
+ if (!data || data.length === 0) return {};
24
+ const item = data[0]?.data || data[0];
25
+ return {
26
+ title: t("Seedlings Height"),
27
+ subTitle: title,
28
+ items: [
29
+ {
30
+ label: t("Count"),
31
+ value: item?.value || 0,
32
+ },
33
+ ],
34
+ };
35
+ }}
36
+ />
37
+ </div>
38
+ </div>
39
+ </Widget>
40
+ );
41
+ };
42
+
43
+ export default SeedlingsHeight;
44
+
@@ -0,0 +1,86 @@
1
+ import React, { useMemo } from 'react';
2
+ import { StatCard } from '../../../../../../../../src/index.js';
3
+ import { calculateStatChange } from '../../../../../../utils/numbers.js';
4
+
5
+ const Stats = ({
6
+ survivalRate,
7
+ averageHeight,
8
+ averageDiameter,
9
+ t = (s) => s
10
+ }) => {
11
+ const survivalRateChange = useMemo(() => {
12
+ if (!survivalRate) return null;
13
+ return calculateStatChange(
14
+ {
15
+ current: Number(survivalRate.current) || 0,
16
+ previous: Number(survivalRate.previous) || 0,
17
+ },
18
+ {
19
+ tooltipText: t("In comparison to last period"),
20
+ format: 'absolute',
21
+ }
22
+ );
23
+ }, [survivalRate, t]);
24
+
25
+ const averageHeightChange = useMemo(() => {
26
+ if (!averageHeight) return null;
27
+ return calculateStatChange(
28
+ {
29
+ current: Number(averageHeight.current) || 0,
30
+ previous: Number(averageHeight.previous) || 0,
31
+ },
32
+ {
33
+ tooltipText: t("In comparison to last period"),
34
+ format: 'absolute',
35
+ }
36
+ );
37
+ }, [averageHeight, t]);
38
+
39
+ const averageDiameterChange = useMemo(() => {
40
+ if (!averageDiameter) return null;
41
+ return calculateStatChange(
42
+ {
43
+ current: Number(averageDiameter.current) || 0,
44
+ previous: Number(averageDiameter.previous) || 0,
45
+ },
46
+ {
47
+ tooltipText: t("In comparison to last period"),
48
+ format: 'absolute',
49
+ }
50
+ );
51
+ }, [averageDiameter, t]);
52
+
53
+ return (
54
+ <div style={{ display: "flex", gap: "24px", marginBottom: "24px" }}>
55
+ <section style={{ flex: 1 }}>
56
+ <StatCard
57
+ title={t("Survival Rate")}
58
+ value={survivalRate ? Number(survivalRate.current).toLocaleString() : "0"}
59
+ icon="EventCalendar"
60
+ change={survivalRateChange}
61
+ />
62
+ </section>
63
+
64
+ <section style={{ flex: 1 }}>
65
+ <StatCard
66
+ title={t("Average Height")}
67
+ value={averageHeight ? Number(averageHeight.current).toLocaleString() + " cm" : "0 cm"}
68
+ icon="ProjectLocation"
69
+ change={averageHeightChange}
70
+ />
71
+ </section>
72
+
73
+ <section style={{ flex: 1 }}>
74
+ <StatCard
75
+ title={t("Average Diameter")}
76
+ value={averageDiameter ? Number(averageDiameter.current).toLocaleString() + " mm" : "0 mm"}
77
+ icon="Activity"
78
+ change={averageDiameterChange}
79
+ />
80
+ </section>
81
+ </div>
82
+ );
83
+ };
84
+
85
+ export default Stats;
86
+
@@ -0,0 +1,73 @@
1
+ import React, { useMemo, useCallback } from 'react';
2
+ import { Widget, PieChart } from '../../../../../../../../src/index.js';
3
+ import { renderTooltipJsx } from '../../../../../../utils/tooltip.js';
4
+
5
+ const COLORS = ['#016C6E', '#F5C2AC', '#F0A888', '#DF571E', '#C04B19', '#9B3D14', '#7A2F0F'];
6
+
7
+ const VegetationHealth = ({
8
+ vegetationHealthChart,
9
+ t = (s) => s
10
+ }) => {
11
+ const pieData = useMemo(() => {
12
+ const data = vegetationHealthChart || [];
13
+ const total = data.reduce((sum, item) => sum + (Number(item?.value) || 0), 0);
14
+
15
+ return data.map((item, index) => ({
16
+ value: Number(item?.value) || 0,
17
+ percent: total > 0 ? (Number(item?.value) || 0) / total : 0,
18
+ color: COLORS[index % COLORS.length],
19
+ label: item?.type || '',
20
+ key: item?.type || `item-${index}`,
21
+ }));
22
+ }, [vegetationHealthChart]);
23
+
24
+ const isEmpty = useMemo(() => {
25
+ return !vegetationHealthChart || vegetationHealthChart.length === 0 ||
26
+ vegetationHealthChart.every(item => !item?.value || Number(item.value) === 0);
27
+ }, [vegetationHealthChart]);
28
+
29
+ const getTooltipChildren = useCallback(
30
+ (item) => {
31
+ if (isEmpty) {
32
+ return null;
33
+ }
34
+
35
+ return renderTooltipJsx({
36
+ title: t("Vegetation Health"),
37
+ items: [
38
+ {
39
+ color: item.color,
40
+ label: item.label || '',
41
+ value: `${item.value || 0}%`,
42
+ },
43
+ ],
44
+ });
45
+ },
46
+ [t, isEmpty]
47
+ );
48
+
49
+ return (
50
+ <Widget
51
+ title={t("Vegetation Health")}
52
+ className="with-border-header h-w-btn-header"
53
+ >
54
+ <div className="flex flex-1 flex-column justify-content-center">
55
+ <div className="flex justify-content-center w-full">
56
+ <PieChart
57
+ data={pieData}
58
+ isPie
59
+ isEmpty={isEmpty}
60
+ getTooltipChildren={getTooltipChildren}
61
+ mouseXOffset={10}
62
+ mouseYOffset={10}
63
+ changeOpacityOnHover={false}
64
+ doConstraints={false}
65
+ />
66
+ </div>
67
+ </div>
68
+ </Widget>
69
+ );
70
+ };
71
+
72
+ export default VegetationHealth;
73
+
@@ -0,0 +1,92 @@
1
+ import React, { useMemo } from 'react';
2
+ import { Widget } from '../../../../../../../../src/index.js';
3
+ import { useWidgetFetch } from '../../../../../../hooks/useWidgetFetch.js';
4
+ import VegetationHealth from './VegetationHealth.jsx';
5
+ import SeedlingsHeight from './SeedlingsHeight.jsx';
6
+ import PlantedSpecies from './PlantedSpecies.jsx';
7
+ import Stats from './Stats.jsx';
8
+
9
+ const MangroveGrowth = ({
10
+ id,
11
+ getSummaryDetail,
12
+ loading = false,
13
+ t = (s) => s
14
+ }) => {
15
+ const defaultConfig = useMemo(
16
+ () => ({
17
+ basepath: "events/monitoring-campaign",
18
+ url: `/summary/${id}/outcomes`,
19
+ stop: !id,
20
+ }),
21
+ [id],
22
+ );
23
+
24
+ const customGetData = useMemo(() => {
25
+ if (getSummaryDetail && id) {
26
+ return ({ url, params = {} }) => {
27
+ const match = url.match(/\/summary\/[^/]+\/(.+)/);
28
+ if (match) {
29
+ const [, type] = match;
30
+ return getSummaryDetail(id, type, params);
31
+ }
32
+ throw new Error(`Invalid URL format: ${url}`);
33
+ };
34
+ }
35
+ return undefined;
36
+ }, [getSummaryDetail, id]);
37
+
38
+ const { loading: outcomesLoading, data: outcomesData } = useWidgetFetch({
39
+ config: defaultConfig,
40
+ getData: customGetData
41
+ });
42
+
43
+ const {
44
+ survivalRate,
45
+ averageHeight,
46
+ averageDiameter,
47
+ vegetationHealthChart,
48
+ seedlingsHeightChart,
49
+ plantedSpeciesChart
50
+ } = outcomesData || {};
51
+
52
+ return (
53
+ <section>
54
+ <Widget
55
+ title={t("Mangrove Growth")}
56
+ loading={loading || outcomesLoading}
57
+ className="with-border-header h-w-btn-header"
58
+ >
59
+ <Stats
60
+ survivalRate={survivalRate}
61
+ averageHeight={averageHeight}
62
+ averageDiameter={averageDiameter}
63
+ t={t}
64
+ />
65
+
66
+ <div style={{ display: "flex", gap: "24px" }}>
67
+ <section style={{ flex: 1 }}>
68
+ <VegetationHealth
69
+ vegetationHealthChart={vegetationHealthChart}
70
+ t={t}
71
+ />
72
+ </section>
73
+ <section style={{ flex: 1 }}>
74
+ <SeedlingsHeight
75
+ seedlingsHeightChart={seedlingsHeightChart}
76
+ t={t}
77
+ />
78
+ </section>
79
+ <section style={{ flex: 1 }}>
80
+ <PlantedSpecies
81
+ plantedSpeciesChart={plantedSpeciesChart}
82
+ t={t}
83
+ />
84
+ </section>
85
+ </div>
86
+ </Widget>
87
+ </section>
88
+ );
89
+ };
90
+
91
+ export default MangroveGrowth;
92
+