datastake-daf 0.6.758 → 0.6.760
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 +2355 -2056
- package/dist/constants/index.js +51 -1
- package/dist/layouts/index.js +476 -452
- package/dist/pages/index.js +881 -885
- package/dist/services/index.js +91 -0
- package/dist/utils/index.js +523 -456
- package/package.json +1 -1
- package/src/@daf/core/components/Dashboard/Map/Map.stories.js +8 -0
- package/src/@daf/core/components/Dashboard/Map/helper.js +134 -3
- package/src/@daf/core/components/Dashboard/Map/hook.js +4 -0
- package/src/@daf/core/components/Dashboard/Map/index.jsx +19 -0
- package/src/@daf/core/components/Dashboard/Map/storyConfig.js +2 -1
- package/src/@daf/core/components/Dashboard/Map/storyConfig6.js +69 -0
- package/src/@daf/core/components/Dashboard/Widget/ActivityIndicators/config.js +2 -5
- package/src/@daf/core/components/Dashboard/Widget/KeyIndicators/index.jsx +1 -1
- package/src/@daf/core/components/Graphs/components/BaseGraph.jsx +1 -1
- package/src/@daf/core/components/Icon/configs/SpacingHeight.js +8 -0
- package/src/@daf/core/components/Icon/configs/SpacingWidth.js +8 -0
- package/src/@daf/core/components/Icon/configs/index.js +5 -1
- package/src/@daf/core/components/Screens/FindInformation/index.js +2 -1
- package/src/@daf/core/components/Screens/Users/columns.js +0 -6
- package/src/@daf/core/components/Table/NavigationAction/index.jsx +24 -0
- package/src/@daf/hooks/useMapHelper.js +15 -1
- package/src/@daf/pages/Documents/columns.js +5 -22
- package/src/@daf/pages/Events/Activities/columns.js +7 -59
- package/src/@daf/pages/Events/Incidents/columns.js +7 -61
- package/src/@daf/pages/Events/columns.js +6 -47
- package/src/@daf/pages/Events/helper.js +14 -0
- package/src/@daf/pages/Locations/MineSite/columns.js +1 -8
- package/src/@daf/pages/Locations/columns.js +6 -32
- package/src/@daf/pages/Partners/index.jsx +11 -0
- package/src/@daf/pages/Stakeholders/Operators/columns.js +2 -8
- package/src/@daf/pages/Stakeholders/Workers/columns.js +10 -49
- package/src/@daf/pages/Stakeholders/columns.js +4 -25
- package/src/@daf/pages/Summary/Activities/Restoration/helper.js +133 -79
- package/src/@daf/pages/Summary/Activities/Restoration/index.jsx +57 -60
- package/src/@daf/pages/Summary/Minesite/components/LocationMap/index.js +0 -1
- package/src/@daf/services/PartnerService.js +76 -0
- package/src/@daf/utils/tags.js +26 -0
- package/src/@daf/utils/tooltip.js +5 -2
- package/src/constants/breadCrumbs.js +2 -0
- package/src/constants.js +2 -1
- package/src/index.js +1 -1
- package/src/services.js +2 -1
- package/src/utils.js +3 -1
|
@@ -1,16 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
// REGION: Photo/Image Extraction
|
|
3
|
-
// ============================================================================
|
|
1
|
+
import L from "leaflet";
|
|
4
2
|
|
|
5
|
-
/**
|
|
6
|
-
* Normalize URL by removing trailing colon if present
|
|
7
|
-
*/
|
|
8
3
|
const normalizeUrl = (url) => url?.endsWith(':') ? url.slice(0, -1) : url;
|
|
9
4
|
|
|
10
|
-
|
|
11
|
-
* Extract images from a photo document
|
|
12
|
-
* Handles both documents with pictures arrays and direct image objects
|
|
13
|
-
*/
|
|
5
|
+
|
|
14
6
|
export const extractFromPhotoDoc = (photoDoc, label, docIndex) => {
|
|
15
7
|
const photos = photoDoc?.pictures?.filter(p => p?.url) || (photoDoc?.url ? [photoDoc] : []);
|
|
16
8
|
|
|
@@ -20,13 +12,6 @@ export const extractFromPhotoDoc = (photoDoc, label, docIndex) => {
|
|
|
20
12
|
}));
|
|
21
13
|
};
|
|
22
14
|
|
|
23
|
-
/**
|
|
24
|
-
* Extract and process images from activity data
|
|
25
|
-
* Processes group photos and activity photos (start, during, end) into a flat array
|
|
26
|
-
*
|
|
27
|
-
* @param {Object} activityData - Activity data object containing photo arrays
|
|
28
|
-
* @returns {Array} - Flat array of image objects with src and alt properties
|
|
29
|
-
*/
|
|
30
15
|
export const getActivityImages = (activityData) => {
|
|
31
16
|
const photoArrays = [
|
|
32
17
|
{ data: activityData?.groupPhotos, label: 'Group Photo' },
|
|
@@ -43,17 +28,8 @@ export const getActivityImages = (activityData) => {
|
|
|
43
28
|
);
|
|
44
29
|
};
|
|
45
30
|
|
|
46
|
-
|
|
47
|
-
// REGION: Gender Distribution
|
|
48
|
-
// ============================================================================
|
|
49
|
-
|
|
50
|
-
// Gender distribution colors for pie chart
|
|
51
|
-
const GENDER_COLORS = ['#016C6E', '#00AEB1']; // Male (dark teal), Female (light teal)
|
|
31
|
+
const GENDER_COLORS = ['#016C6E', '#00AEB1'];
|
|
52
32
|
|
|
53
|
-
/**
|
|
54
|
-
* Get gender distribution data from activityData
|
|
55
|
-
* Maps genderDistributionMale and genderDistributionFemale to a structured object
|
|
56
|
-
*/
|
|
57
33
|
export const getGenderDistributionData = (activityData) => {
|
|
58
34
|
return {
|
|
59
35
|
Male: activityData?.genderDistributionMale || 0,
|
|
@@ -61,18 +37,11 @@ export const getGenderDistributionData = (activityData) => {
|
|
|
61
37
|
};
|
|
62
38
|
};
|
|
63
39
|
|
|
64
|
-
|
|
65
|
-
* Check if gender distribution is empty
|
|
66
|
-
* Returns true if all values are 0 or falsy
|
|
67
|
-
*/
|
|
40
|
+
|
|
68
41
|
export const isGenderDistributionEmpty = (genderDistributionData) => {
|
|
69
42
|
return Object.values(genderDistributionData).every(val => !val || val === 0);
|
|
70
43
|
};
|
|
71
44
|
|
|
72
|
-
/**
|
|
73
|
-
* Calculate pie chart data from gender distribution
|
|
74
|
-
* Computes percentages and assigns colors based on gender distribution values
|
|
75
|
-
*/
|
|
76
45
|
export const calculateGenderPieData = (genderDistributionData) => {
|
|
77
46
|
const total = Object.values(genderDistributionData).reduce((all, val) => all + (val || 0), 0);
|
|
78
47
|
|
|
@@ -89,10 +58,6 @@ export const calculateGenderPieData = (genderDistributionData) => {
|
|
|
89
58
|
});
|
|
90
59
|
};
|
|
91
60
|
|
|
92
|
-
/**
|
|
93
|
-
* Get tooltip children for gender distribution pie chart
|
|
94
|
-
* Generates tooltip content showing gender label and value
|
|
95
|
-
*/
|
|
96
61
|
export const getGenderTooltipChildren = (item, isEmpty, genderDistributionData, t, renderTooltipJsx) => {
|
|
97
62
|
if (isEmpty) {
|
|
98
63
|
if (!Object.keys(genderDistributionData).length) {
|
|
@@ -120,16 +85,6 @@ export const getGenderTooltipChildren = (item, isEmpty, genderDistributionData,
|
|
|
120
85
|
});
|
|
121
86
|
};
|
|
122
87
|
|
|
123
|
-
// ============================================================================
|
|
124
|
-
// REGION: Activity Indicators
|
|
125
|
-
// ============================================================================
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Maps activityData value to indicator type
|
|
129
|
-
* "yes" or true → "compliant"
|
|
130
|
-
* "no" or false → "notCompliant"
|
|
131
|
-
* null or undefined → "empty"
|
|
132
|
-
*/
|
|
133
88
|
export const getIndicatorType = (value) => {
|
|
134
89
|
if (value === "yes" || value === true) return "compliant";
|
|
135
90
|
if (value === "no" || value === false) return "notCompliant";
|
|
@@ -137,34 +92,7 @@ export const getIndicatorType = (value) => {
|
|
|
137
92
|
return "empty"; // default fallback
|
|
138
93
|
};
|
|
139
94
|
|
|
140
|
-
/**
|
|
141
|
-
* Special case: Children presence indicator configuration
|
|
142
|
-
* Children presence is compliant if answered 'no', not compliant if answered 'yes'
|
|
143
|
-
* Custom icons: "no" (compliant) → X icon with green badge, "yes" (notCompliant) → Check icon with red badge
|
|
144
|
-
*
|
|
145
|
-
* @param {string|boolean|null} value - The presenceOfChildren value from activityData
|
|
146
|
-
* @returns {Object} - Configuration object with type and optional statusIcon
|
|
147
|
-
*/
|
|
148
|
-
export const getChildrenPresenceConfig = (value) => {
|
|
149
|
-
if (value === "no" || value === false) {
|
|
150
|
-
return { type: "compliant", statusIcon: "Close" }; // X icon with green badge
|
|
151
|
-
}
|
|
152
|
-
if (value === "yes" || value === true) {
|
|
153
|
-
return { type: "notCompliant", statusIcon: "Check" }; // Check icon with red badge
|
|
154
|
-
}
|
|
155
|
-
return { type: "empty" }; // empty state
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Get activity indicators configuration from activityData
|
|
160
|
-
* Maps activityData fields to indicator config objects with icon, label, type, and optional statusIcon
|
|
161
|
-
*
|
|
162
|
-
* @param {Object} activityData - Activity data object
|
|
163
|
-
* @param {Function} t - Translation function
|
|
164
|
-
* @returns {Array} - Array of indicator config objects
|
|
165
|
-
*/
|
|
166
95
|
export const getActivityIndicatorsConfig = (activityData, t) => {
|
|
167
|
-
const childrenPresenceConfig = getChildrenPresenceConfig(activityData?.presenceOfChildren);
|
|
168
96
|
|
|
169
97
|
return [
|
|
170
98
|
{ icon: "Aid", label: t("Aid kit availability"), type: getIndicatorType(activityData?.aidKitAccessible) },
|
|
@@ -172,11 +100,137 @@ export const getActivityIndicatorsConfig = (activityData, t) => {
|
|
|
172
100
|
{ icon: "Users", label: t("Workers safe pairing"), type: getIndicatorType(activityData?.duosFormed) },
|
|
173
101
|
{
|
|
174
102
|
icon: "Bear",
|
|
175
|
-
label: t("
|
|
176
|
-
type:
|
|
177
|
-
...(childrenPresenceConfig.statusIcon && { statusIcon: childrenPresenceConfig.statusIcon })
|
|
103
|
+
label: t("No children"),
|
|
104
|
+
type: getIndicatorType(activityData?.presenceOfChildren),
|
|
178
105
|
},
|
|
179
106
|
{ icon: "Security", label: t("Security presence"), type: getIndicatorType(activityData?.focalPointPresent) },
|
|
180
107
|
{ icon: "UserCircle", label: t("Relay presence"), type: getIndicatorType(activityData?.relayPresent) },
|
|
181
108
|
];
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export const getMapDataFromActivity = (activityData, t) => {
|
|
112
|
+
|
|
113
|
+
const location = activityData?.location;
|
|
114
|
+
const perimeter = location?.perimeter;
|
|
115
|
+
|
|
116
|
+
const area = Array.isArray(perimeter) && perimeter.length > 0
|
|
117
|
+
? perimeter
|
|
118
|
+
.filter((coord) => Array.isArray(coord) && coord.length >= 2)
|
|
119
|
+
.map((coord) => {
|
|
120
|
+
const first = typeof coord[0] === 'number' ? coord[0] : parseFloat(coord[0]);
|
|
121
|
+
const second = typeof coord[1] === 'number' ? coord[1] : parseFloat(coord[1]);
|
|
122
|
+
|
|
123
|
+
if (isNaN(first) || isNaN(second) || !isFinite(first) || !isFinite(second)) {
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Try both formats and use Leaflet to validate
|
|
128
|
+
// First try as [lat, lng]
|
|
129
|
+
try {
|
|
130
|
+
const latLng1 = L.latLng(first, second);
|
|
131
|
+
if (latLng1.lat >= -90 && latLng1.lat <= 90 &&
|
|
132
|
+
latLng1.lng >= -180 && latLng1.lng <= 180) {
|
|
133
|
+
return [latLng1.lat, latLng1.lng];
|
|
134
|
+
}
|
|
135
|
+
} catch (e) {
|
|
136
|
+
// Not valid as [lat, lng], try swapping
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Try as [lng, lat] (GeoJSON format) - swap them
|
|
140
|
+
try {
|
|
141
|
+
const latLng2 = L.latLng(second, first);
|
|
142
|
+
if (latLng2.lat >= -90 && latLng2.lat <= 90 &&
|
|
143
|
+
latLng2.lng >= -180 && latLng2.lng <= 180) {
|
|
144
|
+
return [latLng2.lat, latLng2.lng];
|
|
145
|
+
}
|
|
146
|
+
} catch (e) {
|
|
147
|
+
// Invalid coordinates
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return null;
|
|
151
|
+
})
|
|
152
|
+
.filter((coord) => coord !== null)
|
|
153
|
+
: null;
|
|
154
|
+
|
|
155
|
+
// Don't return early - we need to check for markers even if there's no perimeter
|
|
156
|
+
|
|
157
|
+
const mapData = [];
|
|
158
|
+
const baseColor = '#15FFFFB2';
|
|
159
|
+
const locationName = location?.name || activityData?.name || t("Activity Location");
|
|
160
|
+
const datastakeId = location?.datastakeId || activityData?.datastakeId;
|
|
161
|
+
|
|
162
|
+
// Helper to validate coordinates
|
|
163
|
+
const isValidCoordinate = (coord) => {
|
|
164
|
+
const num = typeof coord === 'number' ? coord : parseFloat(coord);
|
|
165
|
+
return !isNaN(num) && isFinite(num);
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
// Entry 1: Perimeter polygon (independent - show if it exists)
|
|
169
|
+
if (area && area.length >= 3) {
|
|
170
|
+
mapData.push({
|
|
171
|
+
_id: {},
|
|
172
|
+
id: `${activityData?.id || activityData?.datastakeId || 'perimeter'}-perimeter`,
|
|
173
|
+
area: area,
|
|
174
|
+
color: baseColor,
|
|
175
|
+
// No gps property - this will display only the polygon without markers
|
|
176
|
+
name: locationName,
|
|
177
|
+
plotName: locationName,
|
|
178
|
+
territoryTitle: t("Associated Plot"),
|
|
179
|
+
subTitle: t("Activity Location"),
|
|
180
|
+
type: t("Activity Location"),
|
|
181
|
+
datastakeId: datastakeId,
|
|
182
|
+
sources: null,
|
|
183
|
+
link: null,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Entry 2: Arrival marker (independent - show if it exists)
|
|
188
|
+
const arrivalLat = activityData?.locationCheckArrival?.latitude;
|
|
189
|
+
const arrivalLng = activityData?.locationCheckArrival?.longitude;
|
|
190
|
+
if (isValidCoordinate(arrivalLat) && isValidCoordinate(arrivalLng)) {
|
|
191
|
+
mapData.push({
|
|
192
|
+
_id: {},
|
|
193
|
+
id: `${activityData?.id || activityData?.datastakeId || 'arrival'}-arrival`,
|
|
194
|
+
// Include area if it exists, so marker can show on top of polygon
|
|
195
|
+
area: area && area.length >= 3 ? area : null,
|
|
196
|
+
color: baseColor,
|
|
197
|
+
gps: {
|
|
198
|
+
latitude: typeof arrivalLat === 'number' ? arrivalLat : parseFloat(arrivalLat),
|
|
199
|
+
longitude: typeof arrivalLng === 'number' ? arrivalLng : parseFloat(arrivalLng),
|
|
200
|
+
},
|
|
201
|
+
name: t("Activity Start"),
|
|
202
|
+
plotName: locationName,
|
|
203
|
+
territoryTitle: t("Associated Plot"),
|
|
204
|
+
datastakeId: `${datastakeId}-arrival`,
|
|
205
|
+
sources: null,
|
|
206
|
+
link: null,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Entry 3: Departure marker (independent - show if it exists)
|
|
211
|
+
const departureLat = activityData?.locationCheckDeparture?.latitude;
|
|
212
|
+
const departureLng = activityData?.locationCheckDeparture?.longitude;
|
|
213
|
+
if (isValidCoordinate(departureLat) && isValidCoordinate(departureLng)) {
|
|
214
|
+
mapData.push({
|
|
215
|
+
_id: {},
|
|
216
|
+
id: `${activityData?.id || activityData?.datastakeId || 'departure'}-departure`,
|
|
217
|
+
// Include area if it exists, so marker can show on top of polygon
|
|
218
|
+
area: area && area.length >= 3 ? area : null,
|
|
219
|
+
color: baseColor,
|
|
220
|
+
gps: {
|
|
221
|
+
latitude: typeof departureLat === 'number' ? departureLat : parseFloat(departureLat),
|
|
222
|
+
longitude: typeof departureLng === 'number' ? departureLng : parseFloat(departureLng),
|
|
223
|
+
},
|
|
224
|
+
name: t("Activity End"),
|
|
225
|
+
plotName: locationName,
|
|
226
|
+
territoryTitle: t("Associated Plot"),
|
|
227
|
+
datastakeId: `${datastakeId}-departure`,
|
|
228
|
+
markerColor: "#FF7A45",
|
|
229
|
+
sources: null,
|
|
230
|
+
link: null,
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Return mapData even if empty - let the map component handle empty arrays
|
|
235
|
+
return mapData;
|
|
182
236
|
};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { useMemo, useCallback } from 'react';
|
|
2
2
|
import { DashboardLayout, Header, ImageCarousel, KeyIndicators, MineSiteMap, Widget, PieChart, ActivityIndicators } from '../../../../../../src/index.js'
|
|
3
3
|
import { getKeyIndicatorsRowConfig } from './config';
|
|
4
|
-
import { getActivityImages, getGenderDistributionData, isGenderDistributionEmpty, calculateGenderPieData, getGenderTooltipChildren, getActivityIndicatorsConfig } from './helper';
|
|
4
|
+
import { getActivityImages, getGenderDistributionData, isGenderDistributionEmpty, calculateGenderPieData, getGenderTooltipChildren, getActivityIndicatorsConfig, getMapDataFromActivity } from './helper';
|
|
5
5
|
import { renderTooltipJsx } from '../../../../../../src/utils';
|
|
6
|
+
import { convertDMS } from '../../../../../../src/helpers/Map';
|
|
6
7
|
import { useResizeContext } from '../../../../../../src/context';
|
|
8
|
+
import CustomIcon from '../../../../../../src/@daf/core/components/Icon/CustomIcon.jsx';
|
|
7
9
|
|
|
8
10
|
const RestorationActivitySummary = ({ activityData, supportText, onDownload, downloadDisabled, actionButtons, breadcrumbs, goBackTo, loading, t = () => { } }) => {
|
|
9
11
|
const { isCollapsed, isNestedSidebarCollapsed } = useResizeContext();
|
|
@@ -24,6 +26,9 @@ const RestorationActivitySummary = ({ activityData, supportText, onDownload, dow
|
|
|
24
26
|
[activityData, t]
|
|
25
27
|
);
|
|
26
28
|
|
|
29
|
+
// Map Data - transformed from activityData
|
|
30
|
+
const mapData = useMemo(() => getMapDataFromActivity(activityData, t), [activityData, t]);
|
|
31
|
+
|
|
27
32
|
return (
|
|
28
33
|
<DashboardLayout
|
|
29
34
|
header={
|
|
@@ -46,7 +51,7 @@ const RestorationActivitySummary = ({ activityData, supportText, onDownload, dow
|
|
|
46
51
|
<section>
|
|
47
52
|
<Widget
|
|
48
53
|
title={t("Activity Location")}
|
|
49
|
-
className="no-px no-pt-body no-p-body no-pb-body"
|
|
54
|
+
className="no-px h-w-btn-header no-pt-body no-p-body no-pb-body"
|
|
50
55
|
style={{ height: '100%', display: 'flex', flexDirection: 'column' }}
|
|
51
56
|
>
|
|
52
57
|
<div style={{ flex: 1, minHeight: 0 }}>
|
|
@@ -55,73 +60,65 @@ const RestorationActivitySummary = ({ activityData, supportText, onDownload, dow
|
|
|
55
60
|
t={t}
|
|
56
61
|
isSatellite={true}
|
|
57
62
|
app={"straatos"}
|
|
63
|
+
type={'location-territory'}
|
|
58
64
|
showSider={false}
|
|
59
65
|
user={null}
|
|
60
|
-
data={
|
|
61
|
-
|
|
62
|
-
_id: {},
|
|
63
|
-
id: "7f2aaed4-4b2e-406c-8e0a-6659c5c8367b",
|
|
64
|
-
color: "#6698E4",
|
|
65
|
-
parent: {
|
|
66
|
-
_id: {},
|
|
67
|
-
createdAt: "2024-06-13T14:51:55.296Z",
|
|
68
|
-
updatedAt: "2024-06-13T14:51:55.296Z",
|
|
69
|
-
id: "a5340bf1-2c7d-413f-a2a5-ccd7dc8f7a7c",
|
|
70
|
-
name: "New Mine",
|
|
71
|
-
authorId: "4e6066e9-00d8-423a-94ec-c7c9d3432fec",
|
|
72
|
-
collectId: "f8a2b6a9cc935ef3e5844427f49aade34e152eca",
|
|
73
|
-
country: "AL",
|
|
74
|
-
category: "mineSite",
|
|
75
|
-
datastakeId: "LOC-00000000141",
|
|
76
|
-
__v: 0,
|
|
77
|
-
},
|
|
78
|
-
administrativeLevel1: "6839cb26-5af4-44a3-b136-a0f0a0bcecc6",
|
|
79
|
-
administrativeLevel2: "f849835d-5640-4bee-ae98-9f1c810c1abe",
|
|
80
|
-
// "name": "New Mine",
|
|
81
|
-
country: "AL",
|
|
82
|
-
category: "mineSite",
|
|
83
|
-
authorId: "4e6066e9-00d8-423a-94ec-c7c9d3432fec",
|
|
84
|
-
gps: {
|
|
85
|
-
latitude: 7,
|
|
86
|
-
longitude: 1,
|
|
87
|
-
},
|
|
88
|
-
area: [
|
|
89
|
-
[6, 5],
|
|
90
|
-
[7, 1],
|
|
91
|
-
[9, 2],
|
|
92
|
-
],
|
|
93
|
-
associatedSubjects: [
|
|
94
|
-
{
|
|
95
|
-
entity: "Event",
|
|
96
|
-
_id: {},
|
|
97
|
-
nature: "",
|
|
98
|
-
},
|
|
99
|
-
],
|
|
100
|
-
published: false,
|
|
101
|
-
version: 1,
|
|
102
|
-
createdAt: "2024-06-13T14:51:55.296Z",
|
|
103
|
-
updatedAt: "2024-06-13T14:51:55.296Z",
|
|
104
|
-
name: "Name",
|
|
105
|
-
type: "Loc Type",
|
|
106
|
-
__v: 0,
|
|
107
|
-
datastakeId: "LOC-00000000141",
|
|
108
|
-
},
|
|
109
|
-
]}
|
|
110
|
-
// tooltipAsText: true,
|
|
66
|
+
data={mapData}
|
|
67
|
+
maxZoom={18}
|
|
111
68
|
primaryLink={true}
|
|
112
|
-
|
|
69
|
+
style={{ height: '100%', width: '100%' }}
|
|
70
|
+
renderTooltipForLocation={(data) => {
|
|
71
|
+
const coordinates = data.gps?.latitude && data.gps?.longitude
|
|
72
|
+
? convertDMS(data.gps.latitude, data.gps.longitude)
|
|
73
|
+
: null;
|
|
74
|
+
|
|
75
|
+
if (!coordinates) {
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const isActivityEnd = data.name === t("Activity End") || data.id?.includes('-departure');
|
|
80
|
+
const iconColor = isActivityEnd ? "#FF7A45" : "#016C6E";
|
|
81
|
+
|
|
82
|
+
return [
|
|
83
|
+
{
|
|
84
|
+
label: t("Coordinates"),
|
|
85
|
+
|
|
86
|
+
value: (
|
|
87
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '6px', flexWrap: 'nowrap' }}>
|
|
88
|
+
{/* Latitude icon (vertical) */}
|
|
89
|
+
<div style={{ display: 'flex', alignItems: 'center' }}>
|
|
90
|
+
<CustomIcon
|
|
91
|
+
name="SpacingHeight"
|
|
92
|
+
width={14}
|
|
93
|
+
height={14}
|
|
94
|
+
color={iconColor}
|
|
95
|
+
/>
|
|
96
|
+
<span style={{ fontWeight: 600, marginLeft: '4px' }}>{coordinates[0]}</span>
|
|
97
|
+
</div>
|
|
98
|
+
{/* Longitude icon (horizontal) */}
|
|
99
|
+
<div style={{ display: 'flex', alignItems: 'center' }}>
|
|
100
|
+
<CustomIcon
|
|
101
|
+
name="SpacingWidth"
|
|
102
|
+
width={14}
|
|
103
|
+
height={14}
|
|
104
|
+
color={iconColor}
|
|
105
|
+
/>
|
|
106
|
+
<span style={{ fontWeight: 600, marginLeft: '4px' }}>{coordinates[1]}</span>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
),
|
|
110
|
+
},
|
|
111
|
+
];
|
|
112
|
+
}}
|
|
113
|
+
renderTooltipForTerritory={(data) => {
|
|
113
114
|
return [
|
|
114
115
|
{
|
|
115
|
-
label: "Name",
|
|
116
|
-
value: "
|
|
116
|
+
label: t("Plot Name"),
|
|
117
|
+
value: data.plotName || data.name || "--",
|
|
117
118
|
},
|
|
118
119
|
];
|
|
119
120
|
}}
|
|
120
|
-
center={[13, -15]}
|
|
121
|
-
mapConfig={{ maxZoom: 18 }}
|
|
122
|
-
type={'territory'}
|
|
123
121
|
link={true}
|
|
124
|
-
onClickLink={() => { }}
|
|
125
122
|
/>
|
|
126
123
|
</div>
|
|
127
124
|
</Widget>
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React, { useMemo } from 'react'
|
|
2
2
|
import Widget from '../../../../../core/components/Dashboard/Widget/index.jsx'
|
|
3
3
|
import Map from '../../../../../core/components/Dashboard/Map/index.jsx'
|
|
4
|
-
import { getLinkValue } from '../../../../../../helpers/StringHelper.js'
|
|
5
4
|
|
|
6
5
|
const LocationMap = ({
|
|
7
6
|
selectedPartners = {},
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { BaseService } from "./BaseService.js";
|
|
2
|
+
import { createLazyService } from "./helpers/LazyService.js";
|
|
3
|
+
|
|
4
|
+
class PartnerService extends BaseService {
|
|
5
|
+
get(tab, filters) {
|
|
6
|
+
const { page, pageSize, search, searchParams, ...rest } = filters;
|
|
7
|
+
const params = {
|
|
8
|
+
filters: rest,
|
|
9
|
+
pagination: {
|
|
10
|
+
skip: page,
|
|
11
|
+
take: pageSize,
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
if (search && searchParams.length > 0) {
|
|
15
|
+
params.search = {
|
|
16
|
+
qs: search,
|
|
17
|
+
fields: searchParams,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return this.apiGet({
|
|
22
|
+
url: "/partner",
|
|
23
|
+
isApp: true,
|
|
24
|
+
params,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
create(data) {
|
|
29
|
+
return this.apiPost({
|
|
30
|
+
url: "/partner",
|
|
31
|
+
isApp: true,
|
|
32
|
+
data,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
accept(id) {
|
|
37
|
+
return this.apiPut({ url: `/partner/approve/${id}`, isApp: true });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
activate(id) {
|
|
41
|
+
return this.apiPut({ url: `/partner/activate/${id}`, isApp: true });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
decline(id) {
|
|
45
|
+
return this.apiPut({ url: `/partner/decline/${id}`, isApp: true });
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
suspend(id) {
|
|
49
|
+
return this.apiPut({ url: `/partner/suspend/${id}`, isApp: true });
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
block(id) {
|
|
53
|
+
return this.apiPut({ url: `/partner/block/${id}`, isApp: true });
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
resendInvite(id) {
|
|
57
|
+
return this.apiPut({ url: `/partner/resendInvite/${id}`, isApp: true });
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
getSubjectSources({ id, namespace = "stakeholder" }) {
|
|
61
|
+
return this.apiGet({
|
|
62
|
+
url: `/${namespace}/sources-for-subject/${id}`,
|
|
63
|
+
isApp: true,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
update(id, data) {
|
|
68
|
+
return this.apiPut({
|
|
69
|
+
url: `/partner/${id}`,
|
|
70
|
+
isApp: true,
|
|
71
|
+
data,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export default createLazyService(PartnerService);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Tag } from "antd";
|
|
2
|
+
|
|
3
|
+
export const renderStatusTag = ({ value, t = (s) => s }) => {
|
|
4
|
+
const width = 87;
|
|
5
|
+
|
|
6
|
+
switch (value) {
|
|
7
|
+
case "edited":
|
|
8
|
+
return (
|
|
9
|
+
<Tag color="yellow" style={{ width }} className="text-center">
|
|
10
|
+
{t("Edited")}
|
|
11
|
+
</Tag>
|
|
12
|
+
);
|
|
13
|
+
case "submitted":
|
|
14
|
+
return (
|
|
15
|
+
<Tag color="green" style={{ width }} className="text-center">
|
|
16
|
+
{t("Submitted")}
|
|
17
|
+
</Tag>
|
|
18
|
+
);
|
|
19
|
+
default:
|
|
20
|
+
return (
|
|
21
|
+
<Tag color="blue" style={{ width }} className="text-center">
|
|
22
|
+
{t("Private")}
|
|
23
|
+
</Tag>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
@@ -158,20 +158,23 @@ export const renderTooltipJsx = ({
|
|
|
158
158
|
<span className="daf-tooltip-name">{item.label}</span>
|
|
159
159
|
</Tooltip>
|
|
160
160
|
|
|
161
|
-
<Tooltip title={item.tooltipValue || item.value}>
|
|
161
|
+
<Tooltip title={item.tooltipValue || (typeof item.value === 'string' ? item.value : '')}>
|
|
162
162
|
<div
|
|
163
163
|
style={{
|
|
164
164
|
height: "20px",
|
|
165
165
|
display: "flex",
|
|
166
166
|
alignItems: "center",
|
|
167
|
+
gap: "4px",
|
|
167
168
|
}}
|
|
168
169
|
>
|
|
169
170
|
{item.tag ? (
|
|
170
171
|
<Tag color={item.tag} className="mr-none">
|
|
171
172
|
{item.value}
|
|
172
173
|
</Tag>
|
|
173
|
-
) : (
|
|
174
|
+
) : typeof item.value === 'string' || typeof item.value === 'number' ? (
|
|
174
175
|
<span className="daf-tooltip-value">{item.value}</span>
|
|
176
|
+
) : (
|
|
177
|
+
item.value
|
|
175
178
|
)}
|
|
176
179
|
</div>
|
|
177
180
|
</Tooltip>
|
package/src/constants.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { defaultBreadCrumbsLabels } from './constants/breadCrumbs.js';
|
|
1
|
+
export { defaultBreadCrumbsLabels } from './constants/breadCrumbs.js';
|
|
2
|
+
export { CREATE_DRAWER_WIDTH, CREATE_DRAWER_WIDTH_LARGE } from './helpers/Forms.js';
|
package/src/index.js
CHANGED
|
@@ -11,7 +11,7 @@ export { default as Pagination } from "./@daf/core/components/Table/Pagination/i
|
|
|
11
11
|
export { default as StickyTable } from "./@daf/core/components/Table/StickyTable/index.jsx";
|
|
12
12
|
export { default as TableFilters } from "./@daf/core/components/Table/TableFilters/index.jsx";
|
|
13
13
|
export { default as MoreOptions } from "./@daf/core/components/Table/MoreOptions/index.jsx";
|
|
14
|
-
|
|
14
|
+
export { default as NavigationAction } from "./@daf/core/components/Table/NavigationAction/index.jsx";
|
|
15
15
|
// Button
|
|
16
16
|
export { default as Button } from "./@daf/core/components/Button/index.jsx";
|
|
17
17
|
export { default as FilterButton } from "./@daf/core/components/Button/FilterButton/index.jsx";
|
package/src/services.js
CHANGED
|
@@ -17,4 +17,5 @@ export { default as UserService } from './@daf/services/UserService.js';
|
|
|
17
17
|
export { default as SourceService } from './@daf/services/SourceService.js';
|
|
18
18
|
export { default as DashboardService } from './@daf/services/DashboardService.js';
|
|
19
19
|
export { default as LinkedSubjectsService } from './@daf/services/LinkedSubjects.js';
|
|
20
|
-
export { default as OperatorService } from './@daf/services/OperatorService.js';
|
|
20
|
+
export { default as OperatorService } from './@daf/services/OperatorService.js';
|
|
21
|
+
export { default as PartnerService } from './@daf/services/PartnerService.js';
|
package/src/utils.js
CHANGED
|
@@ -60,4 +60,6 @@ export {
|
|
|
60
60
|
buildBreadcrumbs
|
|
61
61
|
} from './@daf/utils/adminConfigBuilders.js'
|
|
62
62
|
|
|
63
|
-
export { renderBreadCrumbs, buildBreadCrumbs as buildBreadCrumbsHelper } from './helpers/breadCrumbs.js'
|
|
63
|
+
export { renderBreadCrumbs, buildBreadCrumbs as buildBreadCrumbsHelper } from './helpers/breadCrumbs.js'
|
|
64
|
+
|
|
65
|
+
export { copyToClipboard } from './helpers/copyToClipboard.js'
|