datastake-daf 0.6.745 → 0.6.747
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/build/favicon.ico +0 -0
- package/build/logo192.png +0 -0
- package/build/logo512.png +0 -0
- package/build/manifest.json +25 -0
- package/build/robots.txt +3 -0
- package/dist/components/index.js +71 -7
- package/dist/hooks/index.js +2 -2
- package/dist/pages/index.css +1 -0
- package/dist/pages/index.js +5924 -32
- package/dist/services/index.js +23 -1
- package/package.json +1 -1
- package/src/@daf/core/components/Dashboard/Widget/ImageCarousel/index.jsx +75 -54
- package/src/@daf/core/components/Dashboard/Widget/ImageCarousel/style.js +44 -0
- package/src/@daf/core/components/Screens/TableScreen/TablePageWithTabs/index.jsx +128 -0
- package/src/@daf/{pages/pages → core/components/TableScreen}/TablePageWithTabs/index.jsx +3 -3
- package/src/@daf/hooks/useSources.js +1 -1
- package/src/@daf/pages/Documents/index.jsx +1 -1
- package/src/@daf/pages/Events/Activities/index.jsx +1 -1
- package/src/@daf/pages/Events/Incidents/index.jsx +1 -1
- package/src/@daf/pages/Events/index.jsx +1 -1
- package/src/@daf/pages/Locations/MineSite/index.jsx +1 -1
- package/src/@daf/pages/Locations/index.jsx +1 -1
- package/src/@daf/pages/Stakeholders/Operators/index.jsx +1 -1
- package/src/@daf/pages/Stakeholders/Workers/index.jsx +1 -1
- package/src/@daf/pages/Stakeholders/index.jsx +1 -1
- package/src/@daf/pages/Summary/Activities/Restoration/config.js +36 -0
- package/src/@daf/pages/Summary/Activities/Restoration/helper.js +98 -0
- package/src/@daf/pages/Summary/Activities/Restoration/index.jsx +178 -0
- package/src/@daf/pages/Summary/Minesite/components/LocationMap/index.js +61 -0
- package/src/@daf/pages/Summary/Minesite/components/MineSiteDetails/config.js +77 -0
- package/src/@daf/pages/Summary/Minesite/components/MineSiteDetails/index.js +47 -0
- package/src/@daf/pages/Summary/Minesite/components/StakeholderMapping/config.js +26 -0
- package/src/@daf/pages/Summary/Minesite/components/StakeholderMapping/helper.js +64 -0
- package/src/@daf/pages/Summary/Minesite/components/StakeholderMapping/index.js +56 -0
- package/src/@daf/pages/Summary/Minesite/index.jsx +162 -0
- package/src/@daf/pages/Summary/Operator/components/Governance/config.js +26 -0
- package/src/@daf/pages/Summary/Operator/components/Governance/helper.js +61 -0
- package/src/@daf/pages/Summary/Operator/components/Governance/index.js +55 -0
- package/src/@daf/pages/Summary/Operator/components/KeyInformation/config.js +84 -0
- package/src/@daf/pages/Summary/Operator/components/KeyInformation/index.js +46 -0
- package/src/@daf/pages/Summary/Operator/components/TradeRelationships/config.js +40 -0
- package/src/@daf/pages/Summary/Operator/components/TradeRelationships/helper.js +98 -0
- package/src/@daf/pages/Summary/Operator/components/TradeRelationships/hook.js +160 -0
- package/src/@daf/pages/Summary/Operator/components/TradeRelationships/index.js +83 -0
- package/src/@daf/pages/Summary/Operator/hook.js +176 -0
- package/src/@daf/pages/Summary/Operator/index.jsx +170 -0
- package/src/@daf/pages/Summary/components/InformationAvailability/components/Contributions/index.js +36 -0
- package/src/@daf/pages/Summary/components/InformationAvailability/components/InformationCompleteness/index.js +58 -0
- package/src/@daf/pages/Summary/components/InformationAvailability/index.js +42 -0
- package/src/@daf/pages/Summary/hook.js +188 -0
- package/src/@daf/services/OperatorService.js +16 -0
- package/src/@daf/services/SourceService.js +1 -1
- package/src/helpers/StringHelper.js +7 -0
- package/src/pages.js +6 -4
- package/src/@daf/pages/Events/Incidents2/columns.js +0 -176
- package/src/@daf/pages/Events/Incidents2/config.js +0 -170
- package/src/@daf/pages/Events/Incidents2/create.jsx +0 -104
- package/src/@daf/pages/Events/Incidents2/index.jsx +0 -156
- /package/src/@daf/pages/{dashboards → Dashboards}/SupplyChain/components/ChartsContainer/components/GenderDistribution/config.js +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/SupplyChain/components/ChartsContainer/components/GenderDistribution/index.js +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/SupplyChain/components/ChartsContainer/components/Identification/hook.js +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/SupplyChain/components/ChartsContainer/components/Identification/index.js +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/SupplyChain/components/ChartsContainer/components/Locations/config.js +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/SupplyChain/components/ChartsContainer/components/Locations/index.js +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/SupplyChain/components/ChartsContainer/index.js +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/SupplyChain/components/KeyIndicators/config.js +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/SupplyChain/components/KeyIndicators/index.js +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/SupplyChain/components/SupplyChainMap/index.js +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/SupplyChain/components/TradeRelationships/index.js +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/SupplyChain/config.js +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/SupplyChain/index.jsx +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/UserDashboard/components/AccumulationGraph/hook.js +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/UserDashboard/components/AccumulationGraph/index.jsx +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/UserDashboard/components/ContributionsGraph/helper.js +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/UserDashboard/components/ContributionsGraph/hook.js +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/UserDashboard/components/ContributionsGraph/index.jsx +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/UserDashboard/components/CustomSegment/index.jsx +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/UserDashboard/components/DataChainOfCustody/index.jsx +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/UserDashboard/components/DataCompilation/index.jsx +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/UserDashboard/components/DataConsilidation/index.jsx +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/UserDashboard/components/KeyIndicators/config.js +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/UserDashboard/components/KeyIndicators/index.jsx +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/UserDashboard/components/MineSites/config.js +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/UserDashboard/components/MineSites/helper.js +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/UserDashboard/components/MineSites/index.jsx +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/UserDashboard/components/Triangulation/config.js +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/UserDashboard/components/Triangulation/hook.js +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/UserDashboard/components/Triangulation/index.jsx +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/UserDashboard/config.js +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/UserDashboard/index.jsx +0 -0
- /package/src/@daf/pages/{dashboards → Dashboards}/helper.js +0 -0
package/dist/services/index.js
CHANGED
|
@@ -1188,7 +1188,7 @@ class SourceService extends BaseService {
|
|
|
1188
1188
|
id
|
|
1189
1189
|
}) {
|
|
1190
1190
|
return this.apiGet({
|
|
1191
|
-
url: `/${type}/sources
|
|
1191
|
+
url: `/${type}/sources/${id}`
|
|
1192
1192
|
});
|
|
1193
1193
|
}
|
|
1194
1194
|
}
|
|
@@ -1435,8 +1435,30 @@ var LinkedSubjects = createLazyService(LinkedSubjectsService);
|
|
|
1435
1435
|
|
|
1436
1436
|
class OperatorService extends BaseService {
|
|
1437
1437
|
get(params) {
|
|
1438
|
+
const {
|
|
1439
|
+
datastakeId,
|
|
1440
|
+
...rest
|
|
1441
|
+
} = params;
|
|
1442
|
+
if (datastakeId) {
|
|
1443
|
+
return this.apiGet({
|
|
1444
|
+
url: `/stakeholder/${datastakeId}`,
|
|
1445
|
+
params: {
|
|
1446
|
+
...rest
|
|
1447
|
+
},
|
|
1448
|
+
isApp: true
|
|
1449
|
+
});
|
|
1450
|
+
}
|
|
1438
1451
|
return this.apiGet({
|
|
1439
1452
|
url: "/stakeholder",
|
|
1453
|
+
params: {
|
|
1454
|
+
...rest
|
|
1455
|
+
},
|
|
1456
|
+
isApp: true
|
|
1457
|
+
});
|
|
1458
|
+
}
|
|
1459
|
+
getOne(id, params) {
|
|
1460
|
+
return this.apiGet({
|
|
1461
|
+
url: `/stakeholder/${id}`,
|
|
1440
1462
|
params,
|
|
1441
1463
|
isApp: true
|
|
1442
1464
|
});
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import React, { useState, useRef } from "react";
|
|
2
2
|
import CarouselWidget from "../CarouselWidget/index.jsx";
|
|
3
|
-
import { Image, Carousel } from "antd";
|
|
3
|
+
import { Image, Carousel, Empty } from "antd";
|
|
4
4
|
import { LeftOutlined, RightOutlined } from "@ant-design/icons";
|
|
5
5
|
import CustomArrowButton from "./components/CustomArrowButton/index.js";
|
|
6
|
-
import { StyledCarouselWrapper } from "./style.js";
|
|
6
|
+
import { StyledCarouselWrapper, EmptyStateContainer } from "./style.js";
|
|
7
7
|
import PropTypes from "prop-types";
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -45,6 +45,8 @@ import PropTypes from "prop-types";
|
|
|
45
45
|
* @param {string} [props.arrowIconColor="#666"] - Default color of arrow icons
|
|
46
46
|
* @param {string} [props.arrowHoverIconColor="#1890ff"] - Color of arrow icons on hover
|
|
47
47
|
* @param {boolean} [props.customArrows=false] - Whether to show custom navigation arrows
|
|
48
|
+
* @param {ReactNode} [props.emptyLogo] - Custom logo/icon for empty state (defaults to Ant Design simple empty icon)
|
|
49
|
+
* @param {string|ReactNode} [props.emptyText="No Image"] - Custom text for empty state
|
|
48
50
|
* @param {Object} [props.rest] - Additional props passed to the underlying CarouselWidget component
|
|
49
51
|
*
|
|
50
52
|
* @features
|
|
@@ -74,6 +76,8 @@ function ImageCarousel({
|
|
|
74
76
|
arrowIconColor = "#666",
|
|
75
77
|
arrowHoverIconColor = "#1890ff",
|
|
76
78
|
customArrows = false,
|
|
79
|
+
emptyLogo = Empty.PRESENTED_IMAGE_SIMPLE,
|
|
80
|
+
emptyText = "No Image",
|
|
77
81
|
...rest
|
|
78
82
|
}) {
|
|
79
83
|
const [previewVisible, setPreviewVisible] = useState(false);
|
|
@@ -92,7 +96,11 @@ function ImageCarousel({
|
|
|
92
96
|
carouselRef.current?.next();
|
|
93
97
|
};
|
|
94
98
|
|
|
95
|
-
|
|
99
|
+
// Check if images array is empty or has no valid images
|
|
100
|
+
const hasImages = images && images.length > 0 && images.some(image => {
|
|
101
|
+
const imageSrc = typeof image === "string" ? image : image?.src;
|
|
102
|
+
return imageSrc && imageSrc.trim().length > 0;
|
|
103
|
+
});
|
|
96
104
|
return (
|
|
97
105
|
<>
|
|
98
106
|
<StyledCarouselWrapper
|
|
@@ -108,38 +116,47 @@ function ImageCarousel({
|
|
|
108
116
|
infinite
|
|
109
117
|
dots={false}
|
|
110
118
|
>
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
119
|
+
{hasImages ? (
|
|
120
|
+
<Carousel ref={carouselRef} afterChange={handleCarouselChange} arrows={false} {...rest} infinite>
|
|
121
|
+
{images.map((image, index) => {
|
|
122
|
+
const imageSrc = typeof image === "string" ? image : image.src;
|
|
123
|
+
const imageAlt =
|
|
124
|
+
typeof image === "string"
|
|
125
|
+
? `${title} - Image ${index + 1}`
|
|
126
|
+
: image.alt;
|
|
118
127
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
128
|
+
return (
|
|
129
|
+
<div key={imageSrc}>
|
|
130
|
+
<div className="image-container">
|
|
131
|
+
<Image
|
|
132
|
+
src={imageSrc}
|
|
133
|
+
alt={imageAlt}
|
|
134
|
+
fallback={fallback}
|
|
135
|
+
loading="lazy"
|
|
136
|
+
preview={{
|
|
137
|
+
visible: false,
|
|
138
|
+
}}
|
|
139
|
+
onClick={() => {
|
|
140
|
+
setCurrent(index);
|
|
141
|
+
setPreviewVisible(true);
|
|
142
|
+
}}
|
|
143
|
+
/>
|
|
144
|
+
</div>
|
|
145
|
+
</div>
|
|
146
|
+
);
|
|
147
|
+
})}
|
|
148
|
+
</Carousel>
|
|
149
|
+
) : (
|
|
150
|
+
<EmptyStateContainer height={height}>
|
|
151
|
+
<Empty
|
|
152
|
+
image={emptyLogo || Empty.PRESENTED_IMAGE_SIMPLE}
|
|
153
|
+
description={<span style={{ color: '#8C8C8C' }}>{emptyText}</span>}
|
|
154
|
+
/>
|
|
155
|
+
</EmptyStateContainer>
|
|
156
|
+
)}
|
|
140
157
|
</CarouselWidget>
|
|
141
158
|
|
|
142
|
-
{customArrows &&
|
|
159
|
+
{customArrows && hasImages && images.length > 1 && (
|
|
143
160
|
<>
|
|
144
161
|
<CustomArrowButton
|
|
145
162
|
icon={<LeftOutlined />}
|
|
@@ -158,29 +175,31 @@ function ImageCarousel({
|
|
|
158
175
|
)}
|
|
159
176
|
</StyledCarouselWrapper>
|
|
160
177
|
|
|
161
|
-
|
|
162
|
-
<
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
178
|
+
{hasImages && (
|
|
179
|
+
<div style={{ display: "none" }}>
|
|
180
|
+
<Image.PreviewGroup
|
|
181
|
+
preview={{
|
|
182
|
+
visible: previewVisible,
|
|
183
|
+
current,
|
|
184
|
+
onVisibleChange: (vis) => setPreviewVisible(vis),
|
|
185
|
+
onChange: (idx) => {
|
|
186
|
+
setCurrent(idx);
|
|
187
|
+
carouselRef.current?.goTo(idx);
|
|
188
|
+
},
|
|
189
|
+
}}
|
|
190
|
+
>
|
|
191
|
+
{images.map((image, index) => {
|
|
192
|
+
const imageSrc = typeof image === "string" ? image : image.src;
|
|
193
|
+
const imageAlt =
|
|
194
|
+
typeof image === "string"
|
|
195
|
+
? `${title} - Image ${index + 1}`
|
|
196
|
+
: image.alt;
|
|
179
197
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
198
|
+
return <Image key={imageSrc} src={imageSrc} alt={imageAlt} />;
|
|
199
|
+
})}
|
|
200
|
+
</Image.PreviewGroup>
|
|
201
|
+
</div>
|
|
202
|
+
)}
|
|
184
203
|
</>
|
|
185
204
|
);
|
|
186
205
|
}
|
|
@@ -195,6 +214,8 @@ ImageCarousel.propTypes = {
|
|
|
195
214
|
arrowIconColor: PropTypes.string,
|
|
196
215
|
arrowHoverIconColor: PropTypes.string,
|
|
197
216
|
customArrows: PropTypes.bool,
|
|
217
|
+
emptyLogo: PropTypes.node,
|
|
218
|
+
emptyText: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
|
198
219
|
};
|
|
199
220
|
|
|
200
221
|
export default ImageCarousel;
|
|
@@ -42,4 +42,48 @@ export const StyledCarouselWrapper = styled.div`
|
|
|
42
42
|
margin-bottom: -3px !important;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
`;
|
|
46
|
+
|
|
47
|
+
export const EmptyStateContainer = styled.div`
|
|
48
|
+
width: 100%;
|
|
49
|
+
height: ${props => props.height || 400}px;
|
|
50
|
+
display: flex;
|
|
51
|
+
align-items: center;
|
|
52
|
+
justify-content: center;
|
|
53
|
+
background-color: #ffffff;
|
|
54
|
+
border-radius: 6px;
|
|
55
|
+
position: relative;
|
|
56
|
+
|
|
57
|
+
.ant-empty {
|
|
58
|
+
margin: 0;
|
|
59
|
+
display: flex;
|
|
60
|
+
flex-direction: column;
|
|
61
|
+
align-items: center;
|
|
62
|
+
justify-content: center;
|
|
63
|
+
height: 100%;
|
|
64
|
+
width: 100%;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.ant-empty-image {
|
|
68
|
+
margin-bottom: 16px;
|
|
69
|
+
display: flex;
|
|
70
|
+
align-items: center;
|
|
71
|
+
justify-content: center;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.ant-empty-description {
|
|
75
|
+
text-align: center;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
&::after {
|
|
79
|
+
content: '';
|
|
80
|
+
position: absolute;
|
|
81
|
+
bottom: 8px;
|
|
82
|
+
left: 50%;
|
|
83
|
+
transform: translateX(-50%);
|
|
84
|
+
width: 40px;
|
|
85
|
+
height: 2px;
|
|
86
|
+
background-color: #722ed1;
|
|
87
|
+
border-radius: 1px;
|
|
88
|
+
}
|
|
45
89
|
`;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import React, { useState, useEffect, useRef } from 'react'
|
|
2
|
+
import { Tabs, Drawer } from 'antd'
|
|
3
|
+
import Header from '../../../Header/index.jsx'
|
|
4
|
+
import BaseScreen from '../../BaseScreen/index.jsx'
|
|
5
|
+
import { CREATE_DRAWER_WIDTH } from '../../../../../../helpers/Forms.js'
|
|
6
|
+
import DrawerHeader from '../../../Header/DrawerHeader/index.jsx'
|
|
7
|
+
|
|
8
|
+
const TablePageWithTabs = ({
|
|
9
|
+
t= () => {},
|
|
10
|
+
title,
|
|
11
|
+
breadCrumbs,
|
|
12
|
+
location,
|
|
13
|
+
loading = false,
|
|
14
|
+
goTo = () => {},
|
|
15
|
+
defaultActiveTab = "own",
|
|
16
|
+
checkboxConfig = {},
|
|
17
|
+
columns = [],
|
|
18
|
+
data = {},
|
|
19
|
+
APP,
|
|
20
|
+
getApiBaseUrl = () => {},
|
|
21
|
+
selectOptions = {},
|
|
22
|
+
selectFiltersConfig = {},
|
|
23
|
+
getRedirectLink = () => {},
|
|
24
|
+
filtersConfig = {},
|
|
25
|
+
isMobile,
|
|
26
|
+
view,
|
|
27
|
+
getActiveTab = () => {},
|
|
28
|
+
onDownload = () => {},
|
|
29
|
+
downloadDisabled = false,
|
|
30
|
+
drawerTitle = "",
|
|
31
|
+
onCreateModalClose = () => {},
|
|
32
|
+
children
|
|
33
|
+
}) => {
|
|
34
|
+
const params = new URLSearchParams(location?.search);
|
|
35
|
+
const [activeTab, setActiveTab] = useState(params.get("tab") || defaultActiveTab);
|
|
36
|
+
const [openCreateModal, setOpenCreateModal] = useState(params.has("create"));
|
|
37
|
+
|
|
38
|
+
const getActiveTabRef = useRef(getActiveTab);
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
getActiveTabRef.current = getActiveTab;
|
|
41
|
+
}, [getActiveTab]);
|
|
42
|
+
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
getActiveTabRef.current(activeTab);
|
|
45
|
+
}, [activeTab]);
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<div className="semibold form-input-output daf-create-view">
|
|
49
|
+
<Header
|
|
50
|
+
title={t(title)}
|
|
51
|
+
breadcrumbs={breadCrumbs}
|
|
52
|
+
actionButtons={[
|
|
53
|
+
{
|
|
54
|
+
type: "primary",
|
|
55
|
+
onClick: () => setOpenCreateModal(true),
|
|
56
|
+
tooltip: t("New"),
|
|
57
|
+
icon: "Add",
|
|
58
|
+
},
|
|
59
|
+
]}
|
|
60
|
+
onDownload={onDownload}
|
|
61
|
+
downloadDisabled={downloadDisabled}
|
|
62
|
+
/>
|
|
63
|
+
<Tabs
|
|
64
|
+
items={[
|
|
65
|
+
{ label: t("All Data"), key: "all" },
|
|
66
|
+
{ label: t("Own Data"), key: "own" },
|
|
67
|
+
{ label: t("Partners"), key: "shared" },
|
|
68
|
+
]}
|
|
69
|
+
defaultActiveKey={activeTab}
|
|
70
|
+
activeKey={activeTab}
|
|
71
|
+
onChange={(val) => {
|
|
72
|
+
if (loading) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
setActiveTab(val);
|
|
77
|
+
|
|
78
|
+
const newParams = new URLSearchParams(location?.search);
|
|
79
|
+
newParams.set("tab", val);
|
|
80
|
+
goTo(`${location.pathname}?${newParams.toString()}`);
|
|
81
|
+
}}
|
|
82
|
+
className="view-page-tabs mt-3"
|
|
83
|
+
/>
|
|
84
|
+
<BaseScreen
|
|
85
|
+
t={t}
|
|
86
|
+
checkboxConfig={checkboxConfig}
|
|
87
|
+
defaultTableFilters={{}}
|
|
88
|
+
columns={columns}
|
|
89
|
+
data={data}
|
|
90
|
+
loading={loading}
|
|
91
|
+
location={location}
|
|
92
|
+
goTo={goTo}
|
|
93
|
+
APP={APP}
|
|
94
|
+
getApiBaseUrl={getApiBaseUrl}
|
|
95
|
+
selectOptions={selectOptions}
|
|
96
|
+
selectFilters={selectFiltersConfig}
|
|
97
|
+
view={view}
|
|
98
|
+
getRedirectLink={getRedirectLink}
|
|
99
|
+
defaultUrlParams={{}}
|
|
100
|
+
module={APP}
|
|
101
|
+
filtersConfig={filtersConfig}
|
|
102
|
+
isMobile={isMobile}
|
|
103
|
+
/>
|
|
104
|
+
{openCreateModal && (
|
|
105
|
+
<Drawer
|
|
106
|
+
destroyOnHidden
|
|
107
|
+
title={
|
|
108
|
+
<DrawerHeader
|
|
109
|
+
title={t(drawerTitle)}
|
|
110
|
+
/>
|
|
111
|
+
}
|
|
112
|
+
open={openCreateModal}
|
|
113
|
+
onClose={() => setOpenCreateModal(false)}
|
|
114
|
+
width={CREATE_DRAWER_WIDTH}
|
|
115
|
+
bodyStyle={{ padding: 0 }}
|
|
116
|
+
>
|
|
117
|
+
{typeof children === 'function'
|
|
118
|
+
? children({ onDrawerClose: () => setOpenCreateModal(false) })
|
|
119
|
+
: children
|
|
120
|
+
}
|
|
121
|
+
</Drawer>
|
|
122
|
+
)}
|
|
123
|
+
|
|
124
|
+
</div>
|
|
125
|
+
)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export default TablePageWithTabs
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import React, { useState, useEffect, useRef } from 'react'
|
|
2
2
|
import { Tabs, Drawer } from 'antd'
|
|
3
|
-
import Header from '../../../
|
|
4
|
-
import BaseScreen from '
|
|
3
|
+
import Header from '../../../Header/index.jsx'
|
|
4
|
+
import BaseScreen from '../../BaseScreen/index.jsx'
|
|
5
5
|
import { CREATE_DRAWER_WIDTH } from '../../../../helpers/Forms.js'
|
|
6
|
-
import DrawerHeader from '../../../
|
|
6
|
+
import DrawerHeader from '../../../Header/DrawerHeader/index.jsx'
|
|
7
7
|
|
|
8
8
|
const TablePageWithTabs = ({
|
|
9
9
|
t= () => {},
|
|
@@ -82,7 +82,7 @@ export default function useSource({ user = {}, t = () => {}, getData = () => {},
|
|
|
82
82
|
|
|
83
83
|
export const useSources = ({type, id, user, t = () => {}}) => {
|
|
84
84
|
function getData(params) {
|
|
85
|
-
if(id) {
|
|
85
|
+
if(id !== undefined && id !== null) {
|
|
86
86
|
return SourceService.getSources({type, id});
|
|
87
87
|
} else {
|
|
88
88
|
return SourceService.get(null, params);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useMemo, useState, useEffect, useCallback } from 'react'
|
|
2
|
-
import TablePageWithTabs from '
|
|
2
|
+
import TablePageWithTabs from '../../core/components/Screens/TableScreen/TablePageWithTabs/index.jsx'
|
|
3
3
|
import { getColumns } from './columns.js';
|
|
4
4
|
import { checkboxConfig, getFiltersConfig, filtersConfig, getFilterOptions } from './config.js';
|
|
5
5
|
import { useGetQueryParams } from '../../hooks/useGetQueryParams.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useMemo, useState, useEffect, useCallback } from 'react'
|
|
2
|
-
import TablePageWithTabs from '
|
|
2
|
+
import TablePageWithTabs from '../../../core/components/Screens/TableScreen/TablePageWithTabs/index.jsx'
|
|
3
3
|
import { getColumns } from './columns.js';
|
|
4
4
|
import { checkboxConfig, getFiltersConfig, filtersConfig, getFilterOptions } from './config.js';
|
|
5
5
|
import { useGetQueryParams } from '../../../hooks/useGetQueryParams.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useMemo, useState, useEffect, useCallback } from 'react'
|
|
2
|
-
import TablePageWithTabs from '
|
|
2
|
+
import TablePageWithTabs from '../../../core/components/Screens/TableScreen/TablePageWithTabs/index.jsx'
|
|
3
3
|
import { getColumns } from './columns.js';
|
|
4
4
|
import { checkboxConfig, getFiltersConfig, filtersConfig, getFilterOptions } from './config.js';
|
|
5
5
|
import { useGetQueryParams } from '../../../hooks/useGetQueryParams.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useMemo, useState, useEffect, useCallback } from 'react'
|
|
2
|
-
import TablePageWithTabs from '
|
|
2
|
+
import TablePageWithTabs from '../../core/components/Screens/TableScreen/TablePageWithTabs/index.jsx'
|
|
3
3
|
import { getColumns } from './columns.js';
|
|
4
4
|
import { checkboxConfig, getFiltersConfig, filtersConfig, getFilterOptions } from './config.js';
|
|
5
5
|
import { useGetQueryParams } from '../../hooks/useGetQueryParams.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useMemo, useState, useEffect, useCallback } from 'react'
|
|
2
|
-
import TablePageWithTabs from '
|
|
2
|
+
import TablePageWithTabs from '../../../core/components/Screens/TableScreen/TablePageWithTabs/index.jsx'
|
|
3
3
|
import { getColumns } from './columns.js';
|
|
4
4
|
import { checkboxConfig, getFiltersConfig, filtersConfig, getFilterOptions } from './config.js';
|
|
5
5
|
import { useGetQueryParams } from '../../../hooks/useGetQueryParams.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useMemo, useState, useEffect, useCallback } from 'react'
|
|
2
|
-
import TablePageWithTabs from '
|
|
2
|
+
import TablePageWithTabs from '../../core/components/Screens/TableScreen/TablePageWithTabs/index.jsx'
|
|
3
3
|
import { getColumns } from './columns.js';
|
|
4
4
|
import { checkboxConfig, getFiltersConfig, filtersConfig, getFilterOptions } from './config.js';
|
|
5
5
|
import { useGetQueryParams } from '../../hooks/useGetQueryParams.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useMemo, useState, useEffect, useCallback } from 'react'
|
|
2
|
-
import TablePageWithTabs from '
|
|
2
|
+
import TablePageWithTabs from '../../../core/components/Screens/TableScreen/TablePageWithTabs/index.jsx'
|
|
3
3
|
import { getColumns } from './columns.js';
|
|
4
4
|
import { checkboxConfig, getFiltersConfig, filtersConfig, getFilterOptions } from './config.js';
|
|
5
5
|
import { useGetQueryParams } from '../../../hooks/useGetQueryParams.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useMemo, useState, useEffect, useCallback } from 'react'
|
|
2
|
-
import TablePageWithTabs from '
|
|
2
|
+
import TablePageWithTabs from '../../../core/components/Screens/TableScreen/TablePageWithTabs/index.jsx'
|
|
3
3
|
import { getColumns } from './columns.js';
|
|
4
4
|
import { checkboxConfig, getFiltersConfig, filtersConfig, getFilterOptions } from './config.js';
|
|
5
5
|
import { useGetQueryParams } from '../../../hooks/useGetQueryParams.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useMemo, useState, useEffect, useCallback } from 'react'
|
|
2
|
-
import TablePageWithTabs from '
|
|
2
|
+
import TablePageWithTabs from '../../core/components/Screens/TableScreen/TablePageWithTabs/index.jsx'
|
|
3
3
|
import { getColumns } from './columns.js';
|
|
4
4
|
import { checkboxConfig, getFiltersConfig, filtersConfig, getFilterOptions } from './config.js';
|
|
5
5
|
import { useGetQueryParams } from '../../hooks/useGetQueryParams.js';
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
export const getKeyIndicatorsRowConfig = ({ t, data = {} }) => [
|
|
4
|
+
|
|
5
|
+
{
|
|
6
|
+
label: t('Primary Data Collection'),
|
|
7
|
+
render: () => {
|
|
8
|
+
let displayValue = '-';
|
|
9
|
+
|
|
10
|
+
if (data?.origin?.[0]?.name === 'straatos') {
|
|
11
|
+
displayValue = data?.author?.name || '-';
|
|
12
|
+
} else if (data?.formCompleterType === 'localRelay') {
|
|
13
|
+
displayValue = 'Relay (Allcot Senegal)';
|
|
14
|
+
} else if (data?.formCompleterType === 'technicalPartner') {
|
|
15
|
+
displayValue = data?.technicalPartner?.name || '-';
|
|
16
|
+
} else {
|
|
17
|
+
displayValue = data?.author?.name || '-';
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return <div className="flex">{displayValue}</div>;
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
label: t('Implementation Partner'),
|
|
25
|
+
render: () => <div>{data?.technicalPartner?.name || '-'}</div>
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
label: t('Activity Participants'),
|
|
29
|
+
render: () => <div>{'0'}</div>
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
label: t('Hectares Planted'),
|
|
33
|
+
render: () => <div>{data?.hectaresPlanted || '0 ha'}</div>
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
];
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// REGION: Photo/Image Extraction
|
|
3
|
+
// ============================================================================
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Extract images from a photo document
|
|
7
|
+
* Handles both documents with pictures arrays and direct image objects
|
|
8
|
+
*/
|
|
9
|
+
export const extractFromPhotoDoc = (photoDoc, label, docIndex) => {
|
|
10
|
+
const photos = photoDoc?.pictures?.filter(p => p?.url) || (photoDoc?.url ? [photoDoc] : []);
|
|
11
|
+
|
|
12
|
+
return photos.map((photo, photoIndex) => ({
|
|
13
|
+
src: normalizeUrl(photo.url),
|
|
14
|
+
alt: photo.name || photo.alt || `${label} - Image ${docIndex + 1}-${photoIndex + 1}`
|
|
15
|
+
}));
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Normalize URL by removing trailing colon if present
|
|
20
|
+
*/
|
|
21
|
+
const normalizeUrl = (url) => url?.endsWith(':') ? url.slice(0, -1) : url;
|
|
22
|
+
|
|
23
|
+
// ============================================================================
|
|
24
|
+
// REGION: Gender Distribution
|
|
25
|
+
// ============================================================================
|
|
26
|
+
|
|
27
|
+
// Gender distribution colors for pie chart
|
|
28
|
+
const GENDER_COLORS = ['#016C6E', '#00AEB1']; // Male (dark teal), Female (light teal)
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Get gender distribution data from activityData
|
|
32
|
+
* Maps genderDistributionMale and genderDistributionFemale to a structured object
|
|
33
|
+
*/
|
|
34
|
+
export const getGenderDistributionData = (activityData) => {
|
|
35
|
+
return {
|
|
36
|
+
Male: activityData?.genderDistributionMale || 0,
|
|
37
|
+
Female: activityData?.genderDistributionFemale || 0,
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Check if gender distribution is empty
|
|
43
|
+
* Returns true if all values are 0 or falsy
|
|
44
|
+
*/
|
|
45
|
+
export const isGenderDistributionEmpty = (genderDistributionData) => {
|
|
46
|
+
return Object.values(genderDistributionData).every(val => !val || val === 0);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Calculate pie chart data from gender distribution
|
|
51
|
+
* Computes percentages and assigns colors based on gender distribution values
|
|
52
|
+
*/
|
|
53
|
+
export const calculateGenderPieData = (genderDistributionData) => {
|
|
54
|
+
const total = Object.values(genderDistributionData).reduce((all, val) => all + (val || 0), 0);
|
|
55
|
+
|
|
56
|
+
return Object.keys(genderDistributionData).map((key, index) => {
|
|
57
|
+
const color = GENDER_COLORS[index % GENDER_COLORS.length];
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
value: genderDistributionData[key] || 0,
|
|
61
|
+
percent: total > 0 ? (genderDistributionData[key] || 0) / total : 0,
|
|
62
|
+
color: color,
|
|
63
|
+
label: key,
|
|
64
|
+
key: key,
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Get tooltip children for gender distribution pie chart
|
|
71
|
+
* Generates tooltip content showing gender label and value
|
|
72
|
+
*/
|
|
73
|
+
export const getGenderTooltipChildren = (item, isEmpty, genderDistributionData, t, renderTooltipJsx) => {
|
|
74
|
+
if (isEmpty) {
|
|
75
|
+
if (!Object.keys(genderDistributionData).length) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return renderTooltipJsx({
|
|
80
|
+
title: t("Gender"),
|
|
81
|
+
items: Object.keys(genderDistributionData).map((k) => ({
|
|
82
|
+
label: k,
|
|
83
|
+
value: 0,
|
|
84
|
+
})),
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return renderTooltipJsx({
|
|
89
|
+
title: t("Gender"),
|
|
90
|
+
items: [
|
|
91
|
+
{
|
|
92
|
+
color: item.color,
|
|
93
|
+
label: t(item.label),
|
|
94
|
+
value: `${item.value || 0}`,
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
});
|
|
98
|
+
};
|