datastake-daf 0.6.826 → 0.6.828
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 +1126 -1239
- package/dist/hooks/index.js +14 -12
- package/dist/pages/index.js +108 -77
- package/dist/services/index.js +5 -1
- package/package.json +1 -1
- package/src/@daf/core/components/Screens/Admin/AdminTables/EventsTable/helper.js +17 -21
- package/src/@daf/core/components/Screens/Admin/AdminTables/EventsTable/index.jsx +5 -3
- package/src/@daf/core/components/Screens/Admin/AdminTables/hook.js +0 -3
- package/src/@daf/core/components/Screens/Admin/AdminViews/index.jsx +2 -1
- package/src/@daf/hooks/useGetQueryParams.js +44 -25
- package/src/@daf/hooks/useWidgetFetch.js +1 -1
- package/src/@daf/pages/Dashboards/UserDashboard/components/MineSites/index.jsx +3 -1
- package/src/@daf/pages/Locations/MineSite/config.js +1 -1
- package/src/@daf/pages/Stakeholders/Operators/config.js +1 -1
- package/src/@daf/pages/Stakeholders/Workers/config.js +1 -1
- package/src/@daf/pages/Summary/Activities/PlantingCycle/components/CommunityParticipation/JobsTimeline/index.jsx +32 -9
- package/src/@daf/pages/Summary/Activities/PlantingCycle/components/CycleIndicators/HealthAndSafety/helper.js +48 -43
- package/src/@daf/pages/Summary/Activities/PlantingCycle/components/CycleIndicators/HealthAndSafety/index.jsx +17 -5
- package/src/@daf/pages/Summary/Activities/PlantingCycle/components/CycleOutcomes/PlantingActivitiesTimeline.jsx +12 -5
- package/src/@daf/pages/TablePage/hook.js +7 -2
- package/src/@daf/pages/View/index.jsx +1 -1
- package/src/@daf/services/LinkedSubjects.js +5 -1
|
@@ -20,21 +20,44 @@ const JobsTimeline = ({
|
|
|
20
20
|
? dayJobsTimeline
|
|
21
21
|
: (dayJobsTimeline?.jobsTimeline || dayJobsTimeline?.jobs || dayJobsTimeline?.timeline || []);
|
|
22
22
|
|
|
23
|
+
// const jobsTimelineData = useMemo(() => {
|
|
24
|
+
// // Always process data, even if empty, to generate default date range for x-axis
|
|
25
|
+
// const dataToProcess = (!jobsData || !Array.isArray(jobsData) || jobsData.length === 0)
|
|
26
|
+
// ? []
|
|
27
|
+
// : jobsData;
|
|
28
|
+
|
|
29
|
+
// // Process data without cumulative calculation (for jobs timeline)
|
|
30
|
+
// // Try to find value in total, count, jobs, or value fields
|
|
31
|
+
// return processChartDateData({
|
|
32
|
+
// mainData: dataToProcess,
|
|
33
|
+
// isCumulative: false,
|
|
34
|
+
// valueField: 'total', // Will fallback to count/jobs/value if total doesn't exist
|
|
35
|
+
// });
|
|
36
|
+
// }, [jobsData, processChartDateData]);
|
|
37
|
+
|
|
23
38
|
const jobsTimelineData = useMemo(() => {
|
|
24
|
-
//
|
|
25
|
-
const dataToProcess = (!jobsData || !Array.isArray(jobsData) || jobsData.length === 0)
|
|
26
|
-
? []
|
|
39
|
+
// Prepare data first
|
|
40
|
+
const dataToProcess = (!jobsData || !Array.isArray(jobsData) || jobsData.length === 0)
|
|
41
|
+
? []
|
|
27
42
|
: jobsData;
|
|
28
|
-
|
|
29
|
-
// Process data without cumulative calculation
|
|
30
|
-
|
|
31
|
-
return processChartDateData({
|
|
43
|
+
|
|
44
|
+
// Process data without cumulative calculation
|
|
45
|
+
const processedData = processChartDateData({
|
|
32
46
|
mainData: dataToProcess,
|
|
33
47
|
isCumulative: false,
|
|
34
|
-
valueField: 'total', //
|
|
48
|
+
valueField: 'total', // fallback handled inside processChartDateData
|
|
35
49
|
});
|
|
50
|
+
|
|
51
|
+
// Find last index with jobs > 0
|
|
52
|
+
let lastNonZeroIndex = processedData.length - 1;
|
|
53
|
+
while (lastNonZeroIndex >= 0 && (processedData[lastNonZeroIndex].jobs || 0) === 0) {
|
|
54
|
+
lastNonZeroIndex--;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Slice up to last period with data
|
|
58
|
+
return processedData.slice(0, lastNonZeroIndex + 1);
|
|
36
59
|
}, [jobsData, processChartDateData]);
|
|
37
|
-
|
|
60
|
+
|
|
38
61
|
const maxYValue = useMemo(() => {
|
|
39
62
|
if (!jobsTimelineData || jobsTimelineData.length === 0) {
|
|
40
63
|
return 100;
|
|
@@ -1,3 +1,28 @@
|
|
|
1
|
+
|
|
2
|
+
// Custom tooltip labels per field/value
|
|
3
|
+
const FIELD_TOOLTIP_LABELS = {
|
|
4
|
+
aidKitAccessible: {
|
|
5
|
+
compliant: "Available",
|
|
6
|
+
notCompliant: "Not available",
|
|
7
|
+
empty: "No data",
|
|
8
|
+
},
|
|
9
|
+
hsTrainingConfirmation: {
|
|
10
|
+
compliant: "Training delivered",
|
|
11
|
+
notCompliant: "No training",
|
|
12
|
+
empty: "No data",
|
|
13
|
+
},
|
|
14
|
+
duosFormed: {
|
|
15
|
+
compliant: "Duos formed",
|
|
16
|
+
notCompliant: "Not implemented",
|
|
17
|
+
empty: "No data",
|
|
18
|
+
},
|
|
19
|
+
presenceOfChildren: {
|
|
20
|
+
compliant: "None reported",
|
|
21
|
+
notCompliant: "Children present",
|
|
22
|
+
empty: "No data",
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
1
26
|
const HEALTH_SAFETY_COLORS = {
|
|
2
27
|
compliant: '#016C6E',
|
|
3
28
|
notCompliant: '#F97066',
|
|
@@ -11,11 +36,6 @@ const getIndicatorType = (value) => {
|
|
|
11
36
|
return "empty";
|
|
12
37
|
};
|
|
13
38
|
|
|
14
|
-
/**
|
|
15
|
-
* Gets health and safety distribution data from activity data
|
|
16
|
-
* @param {Object} activityData - Activity data object
|
|
17
|
-
* @returns {Object} Distribution object with compliant, notCompliant, and empty counts
|
|
18
|
-
*/
|
|
19
39
|
export const getHealthAndSafetyDistributionData = (activityData) => {
|
|
20
40
|
// Define health and safety indicator fields
|
|
21
41
|
const indicators = [
|
|
@@ -42,23 +62,12 @@ export const getHealthAndSafetyDistributionData = (activityData) => {
|
|
|
42
62
|
return distribution;
|
|
43
63
|
};
|
|
44
64
|
|
|
45
|
-
/**
|
|
46
|
-
* Checks if the health and safety distribution data is empty
|
|
47
|
-
* @param {Object} healthAndSafetyDistributionData - Distribution object
|
|
48
|
-
* @returns {boolean} True if all values are 0 or empty
|
|
49
|
-
*/
|
|
50
65
|
export const isHealthAndSafetyDistributionEmpty = (healthAndSafetyDistributionData) => {
|
|
51
66
|
return Object.values(healthAndSafetyDistributionData).every(val => !val || val === 0);
|
|
52
67
|
};
|
|
53
68
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
* @param {Object} healthAndSafetyDistributionData - Distribution object
|
|
57
|
-
* @param {Function} t - Translation function
|
|
58
|
-
* @returns {Array} Array of pie chart data points with value, percent, color, label, and key
|
|
59
|
-
*/
|
|
60
|
-
export const calculateHealthAndSafetyPieData = (healthAndSafetyDistributionData, t) => {
|
|
61
|
-
const total = Object.values(healthAndSafetyDistributionData).reduce((all, val) => all + (val || 0), 0);
|
|
69
|
+
export const calculateHealthAndSafetyPieData = (data, t, selectedField) => {
|
|
70
|
+
const total = Object.values(data).reduce((a, v) => a + (v || 0), 0);
|
|
62
71
|
|
|
63
72
|
const labels = {
|
|
64
73
|
compliant: t("Available"),
|
|
@@ -66,31 +75,27 @@ export const calculateHealthAndSafetyPieData = (healthAndSafetyDistributionData,
|
|
|
66
75
|
empty: t("Not answered"),
|
|
67
76
|
};
|
|
68
77
|
|
|
69
|
-
return Object.keys(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
key: key,
|
|
78
|
-
};
|
|
79
|
-
});
|
|
78
|
+
return Object.keys(data).map((key) => ({
|
|
79
|
+
value: data[key] || 0,
|
|
80
|
+
percent: total > 0 ? (data[key] || 0) / total : 0,
|
|
81
|
+
color: HEALTH_SAFETY_COLORS[key] || '#D9D9D9',
|
|
82
|
+
label: labels[key] || key,
|
|
83
|
+
key,
|
|
84
|
+
keyOfField: selectedField, // <-- ADD THIS
|
|
85
|
+
}));
|
|
80
86
|
};
|
|
81
87
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
export const getHealthAndSafetyTooltipChildren = (item, isEmpty, healthAndSafetyDistributionData, t, renderTooltipJsx, tooltipTitle = "Health and Safety") => {
|
|
88
|
+
|
|
89
|
+
export const getHealthAndSafetyTooltipChildren = (
|
|
90
|
+
item,
|
|
91
|
+
isEmpty,
|
|
92
|
+
healthAndSafetyDistributionData,
|
|
93
|
+
t,
|
|
94
|
+
renderTooltipJsx,
|
|
95
|
+
tooltipTitle = "Health and Safety",
|
|
96
|
+
selectedField
|
|
97
|
+
) => {
|
|
98
|
+
|
|
94
99
|
// If empty or no data, return null to display nothing
|
|
95
100
|
if (isEmpty || !Object.keys(healthAndSafetyDistributionData).length) {
|
|
96
101
|
return null;
|
|
@@ -104,10 +109,10 @@ export const getHealthAndSafetyTooltipChildren = (item, isEmpty, healthAndSafety
|
|
|
104
109
|
return null;
|
|
105
110
|
}
|
|
106
111
|
|
|
107
|
-
const labels = {
|
|
112
|
+
const labels = FIELD_TOOLTIP_LABELS[item?.keyOfField] || {
|
|
108
113
|
compliant: t("Available"),
|
|
109
114
|
notCompliant: t("Not available"),
|
|
110
|
-
empty: t("
|
|
115
|
+
empty: t("No data"),
|
|
111
116
|
};
|
|
112
117
|
|
|
113
118
|
// Filter items with values > 0
|
|
@@ -54,7 +54,6 @@ const HealthAndSafety = ({
|
|
|
54
54
|
getData: customGetData
|
|
55
55
|
});
|
|
56
56
|
|
|
57
|
-
// Process the fetched pie chart data
|
|
58
57
|
// The API returns data in format: [{count: 1, [field]: "null"}, {count: 1, [field]: "no"}, {count: 1, [field]: "yes"}]
|
|
59
58
|
const healthAndSafetyDistributionData = useMemo(() => {
|
|
60
59
|
if (!pieChartData) return { compliant: 0, notCompliant: 0, empty: 0 };
|
|
@@ -90,7 +89,10 @@ const HealthAndSafety = ({
|
|
|
90
89
|
}, [pieChartData, selectedField]);
|
|
91
90
|
|
|
92
91
|
const isEmpty = useMemo(() => isHealthAndSafetyDistributionEmpty(healthAndSafetyDistributionData), [healthAndSafetyDistributionData]);
|
|
93
|
-
const pieData = useMemo(() =>
|
|
92
|
+
const pieData = useMemo(() =>
|
|
93
|
+
calculateHealthAndSafetyPieData(healthAndSafetyDistributionData, t, selectedField),
|
|
94
|
+
[healthAndSafetyDistributionData, t, selectedField]);
|
|
95
|
+
|
|
94
96
|
|
|
95
97
|
// Get the label for the selected field to use as tooltip title
|
|
96
98
|
const selectedFieldLabel = useMemo(() => {
|
|
@@ -99,7 +101,16 @@ const HealthAndSafety = ({
|
|
|
99
101
|
}, [selectedField]);
|
|
100
102
|
|
|
101
103
|
const getTooltipChildren = useCallback(
|
|
102
|
-
(item) =>
|
|
104
|
+
(item) =>
|
|
105
|
+
getHealthAndSafetyTooltipChildren(
|
|
106
|
+
item,
|
|
107
|
+
isEmpty,
|
|
108
|
+
healthAndSafetyDistributionData,
|
|
109
|
+
t,
|
|
110
|
+
renderTooltipJsx,
|
|
111
|
+
selectedFieldLabel,
|
|
112
|
+
selectedField
|
|
113
|
+
),
|
|
103
114
|
[t, isEmpty, healthAndSafetyDistributionData, selectedFieldLabel],
|
|
104
115
|
);
|
|
105
116
|
|
|
@@ -110,8 +121,9 @@ const HealthAndSafety = ({
|
|
|
110
121
|
return (
|
|
111
122
|
<Widget
|
|
112
123
|
loading={loading || pieChartLoading}
|
|
113
|
-
title={<div>{t("Health
|
|
114
|
-
className="with-border-header h-w-btn-header
|
|
124
|
+
title={<div>{t("Operational Health & Safety")}</div>}
|
|
125
|
+
className="with-border-header h-w-btn-header"
|
|
126
|
+
description={t("Across all activities in this cycle.")}
|
|
115
127
|
addedHeader={
|
|
116
128
|
<>
|
|
117
129
|
<div className="flex-1" />
|
|
@@ -15,21 +15,28 @@ const PlantingActivitiesTimeline = ({
|
|
|
15
15
|
}) => {
|
|
16
16
|
const { timeFilter, setTimeFilter, formatDateAxis, processChartDateData } = useTimeFilter({ defaultFilter: 'monthly' });
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
const activitiesTimelineData = useMemo(() => {
|
|
20
20
|
const dataToProcess = (!activitiesTimelineChart || !Array.isArray(activitiesTimelineChart) || activitiesTimelineChart.length === 0)
|
|
21
21
|
? []
|
|
22
22
|
: activitiesTimelineChart;
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
// Process data without cumulative calculation (for activities timeline)
|
|
25
|
-
|
|
25
|
+
const processedData = processChartDateData({
|
|
26
26
|
mainData: dataToProcess,
|
|
27
27
|
isCumulative: false,
|
|
28
28
|
valueField: 'count',
|
|
29
29
|
});
|
|
30
|
+
|
|
31
|
+
// Remove trailing periods with 0 jobs (optional: remove all zero if you prefer)
|
|
32
|
+
let lastNonZeroIndex = processedData.length - 1;
|
|
33
|
+
while (lastNonZeroIndex >= 0 && (processedData[lastNonZeroIndex].jobs || 0) === 0) {
|
|
34
|
+
lastNonZeroIndex--;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return processedData.slice(0, lastNonZeroIndex + 1);
|
|
30
38
|
}, [activitiesTimelineChart, processChartDateData]);
|
|
31
|
-
|
|
32
|
-
// Calculate max value for Y-axis (default to 100 if all values are 0 or very small)
|
|
39
|
+
|
|
33
40
|
const maxActivitiesYValue = useMemo(() => {
|
|
34
41
|
if (!activitiesTimelineData || activitiesTimelineData.length === 0) {
|
|
35
42
|
return 100;
|
|
@@ -18,6 +18,11 @@ export const useFetchData = ({
|
|
|
18
18
|
subject,
|
|
19
19
|
}) => {
|
|
20
20
|
const { paginationQuery, searchParams, otherParams, sortBy, sortDir, } = useGetQueryParams({location});
|
|
21
|
+
|
|
22
|
+
const tab = useMemo(() => {
|
|
23
|
+
return activeTab;
|
|
24
|
+
}, [activeTab])
|
|
25
|
+
|
|
21
26
|
useEffect(() => {
|
|
22
27
|
const cleanSearchParams = Object.fromEntries(
|
|
23
28
|
Object.entries(searchParams).filter(([_, value]) => value != null && value !== '')
|
|
@@ -37,12 +42,12 @@ export const useFetchData = ({
|
|
|
37
42
|
pagination: paginationQuery,
|
|
38
43
|
...(Object.keys(otherParams).length > 0 && otherParams ),
|
|
39
44
|
...(Object.keys(cleanSearchParams).length > 0 && { search: cleanSearchParams }),
|
|
40
|
-
tab:
|
|
45
|
+
tab: tab,
|
|
41
46
|
sortBy: {
|
|
42
47
|
[sortBy || extendingSortKey || "updatedAt"]: sortDir ? (sortDir === "ascend" ? 1 : -1) : (extendingSortDir || -1),
|
|
43
48
|
},
|
|
44
49
|
}, subject)
|
|
45
|
-
}, [location.search,
|
|
50
|
+
}, [location.search, JSON.stringify(extendingFilters)]);
|
|
46
51
|
}
|
|
47
52
|
|
|
48
53
|
export const useTablePage = ({
|
|
@@ -7,14 +7,18 @@ export const getNamespace = (namespace) => {
|
|
|
7
7
|
let _namespace = namespace;
|
|
8
8
|
switch (namespace) {
|
|
9
9
|
case "locations":
|
|
10
|
+
case "location":
|
|
10
11
|
_namespace = "location";
|
|
11
12
|
break;
|
|
12
13
|
case "stakeholders":
|
|
14
|
+
case "stakeholder":
|
|
13
15
|
_namespace = "stakeholder";
|
|
14
16
|
break;
|
|
15
17
|
case "documents":
|
|
18
|
+
case "document":
|
|
16
19
|
_namespace = "document";
|
|
17
20
|
break;
|
|
21
|
+
case "event":
|
|
18
22
|
case "nashirikiEvent":
|
|
19
23
|
case "events":
|
|
20
24
|
_namespace = "event";
|
|
@@ -50,7 +54,7 @@ class LinkedSubjectsService extends BaseService {
|
|
|
50
54
|
|
|
51
55
|
getOne({ id, signal, namespace, sourceId, source, version }) {
|
|
52
56
|
return this.apiGet({
|
|
53
|
-
url: `/${namespace
|
|
57
|
+
url: `/${getNamespace(namespace)}/${id}`,
|
|
54
58
|
isApp: true,
|
|
55
59
|
signal,
|
|
56
60
|
params: { authorId: sourceId, source, version },
|