datastake-daf 0.6.747 → 0.6.748

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.
@@ -218,6 +218,10 @@ import userIcon from "./userIcon";
218
218
  import partnerIcon from "./partnerIcon";
219
219
  import LifeCycle from "./LifeCycle";
220
220
  import EventCalendar from "./EventCalendar";
221
+ import Aid from "./Aid";
222
+ import Bear from "./Bear";
223
+ import Security from "./Security";
224
+ import Minus from "./Minus";
221
225
 
222
226
  const config = {
223
227
  AppAdmin,
@@ -440,6 +444,10 @@ const config = {
440
444
  partnerIcon,
441
445
  LifeCycle,
442
446
  EventCalendar,
447
+ Aid,
448
+ Bear,
449
+ Security,
450
+ Minus,
443
451
  };
444
452
 
445
453
  export default config;
@@ -2,6 +2,11 @@
2
2
  // REGION: Photo/Image Extraction
3
3
  // ============================================================================
4
4
 
5
+ /**
6
+ * Normalize URL by removing trailing colon if present
7
+ */
8
+ const normalizeUrl = (url) => url?.endsWith(':') ? url.slice(0, -1) : url;
9
+
5
10
  /**
6
11
  * Extract images from a photo document
7
12
  * Handles both documents with pictures arrays and direct image objects
@@ -16,9 +21,27 @@ export const extractFromPhotoDoc = (photoDoc, label, docIndex) => {
16
21
  };
17
22
 
18
23
  /**
19
- * Normalize URL by removing trailing colon if present
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
20
29
  */
21
- const normalizeUrl = (url) => url?.endsWith(':') ? url.slice(0, -1) : url;
30
+ export const getActivityImages = (activityData) => {
31
+ const photoArrays = [
32
+ { data: activityData?.groupPhotos, label: 'Group Photo' },
33
+ { data: activityData?.photosStartActivity, label: 'Start of Activity' },
34
+ { data: activityData?.photosDuringActivity, label: 'During Activity' },
35
+ { data: activityData?.photosEndActivity, label: 'End of Activity' }
36
+ ];
37
+
38
+ return photoArrays
39
+ .flatMap(({ data, label }) =>
40
+ Array.isArray(data)
41
+ ? data.flatMap((photoDoc, index) => extractFromPhotoDoc(photoDoc, label, index))
42
+ : []
43
+ );
44
+ };
22
45
 
23
46
  // ============================================================================
24
47
  // REGION: Gender Distribution
@@ -95,4 +118,65 @@ export const getGenderTooltipChildren = (item, isEmpty, genderDistributionData,
95
118
  },
96
119
  ],
97
120
  });
121
+ };
122
+
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
+ export const getIndicatorType = (value) => {
134
+ if (value === "yes" || value === true) return "compliant";
135
+ if (value === "no" || value === false) return "notCompliant";
136
+ if (value === null || value === undefined) return "empty";
137
+ return "empty"; // default fallback
138
+ };
139
+
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
+ export const getActivityIndicatorsConfig = (activityData, t) => {
167
+ const childrenPresenceConfig = getChildrenPresenceConfig(activityData?.presenceOfChildren);
168
+
169
+ return [
170
+ { icon: "Aid", label: t("Aid kit availability"), type: getIndicatorType(activityData?.aidKitAccessible) },
171
+ { icon: "MineOperators", label: t("H&S training delivery"), type: getIndicatorType(activityData?.hsTrainingConfirmation) },
172
+ { icon: "Users", label: t("Workers safe pairing"), type: getIndicatorType(activityData?.duosFormed) },
173
+ {
174
+ icon: "Bear",
175
+ label: t("Children presence"),
176
+ type: childrenPresenceConfig.type,
177
+ ...(childrenPresenceConfig.statusIcon && { statusIcon: childrenPresenceConfig.statusIcon })
178
+ },
179
+ { icon: "Security", label: t("Security presence"), type: getIndicatorType(activityData?.focalPointPresent) },
180
+ { icon: "UserCircle", label: t("Relay presence"), type: getIndicatorType(activityData?.relayPresent) },
181
+ ];
98
182
  };
@@ -1,29 +1,14 @@
1
1
  import { useMemo, useCallback } from 'react';
2
- import { DashboardLayout, Header, ImageCarousel, KeyIndicators, MineSiteMap, Widget, PieChart } from '../../../../../../src/index.js'
2
+ import { DashboardLayout, Header, ImageCarousel, KeyIndicators, MineSiteMap, Widget, PieChart, ActivityIndicators } from '../../../../../../src/index.js'
3
3
  import { getKeyIndicatorsRowConfig } from './config';
4
- import { extractFromPhotoDoc, getGenderDistributionData, isGenderDistributionEmpty, calculateGenderPieData, getGenderTooltipChildren } from './helper';
4
+ import { getActivityImages, getGenderDistributionData, isGenderDistributionEmpty, calculateGenderPieData, getGenderTooltipChildren, getActivityIndicatorsConfig } from './helper';
5
5
  import { renderTooltipJsx } from '../../../../../../src/utils';
6
6
  import { useResizeContext } from '../../../../../../src/context';
7
7
 
8
8
  const RestorationActivitySummary = ({ activityData, supportText, onDownload, downloadDisabled, actionButtons, breadcrumbs, goBackTo, loading, t = () => { } }) => {
9
9
  const { isCollapsed, isNestedSidebarCollapsed } = useResizeContext();
10
10
  const keyIndicatorsConfig = useMemo(() => getKeyIndicatorsRowConfig({ t, data: activityData }), [t, activityData]);
11
- const images = useMemo(() => {
12
-
13
- const photoArrays = [
14
- { data: activityData?.groupPhotos, label: 'Group Photo' },
15
- { data: activityData?.photosStartActivity, label: 'Start of Activity' },
16
- { data: activityData?.photosDuringActivity, label: 'During Activity' },
17
- { data: activityData?.photosEndActivity, label: 'End of Activity' }
18
- ];
19
-
20
- return photoArrays
21
- .flatMap(({ data, label }) =>
22
- Array.isArray(data)
23
- ? data.flatMap((photoDoc, index) => extractFromPhotoDoc(photoDoc, label, index))
24
- : []
25
- );
26
- }, [activityData]);
11
+ const images = useMemo(() => getActivityImages(activityData), [activityData]);
27
12
  const genderDistributionData = useMemo(() => getGenderDistributionData(activityData), [activityData]);
28
13
  const isEmpty = useMemo(() => isGenderDistributionEmpty(genderDistributionData), [genderDistributionData]);
29
14
  const pieData = useMemo(() => calculateGenderPieData(genderDistributionData), [genderDistributionData]);
@@ -32,6 +17,13 @@ const RestorationActivitySummary = ({ activityData, supportText, onDownload, dow
32
17
  (item) => getGenderTooltipChildren(item, isEmpty, genderDistributionData, t, renderTooltipJsx),
33
18
  [t, isEmpty, genderDistributionData],
34
19
  );
20
+
21
+ // Activity Indicators Config - mapped from activityData
22
+ const activityIndicatorsConfig = useMemo(() =>
23
+ getActivityIndicatorsConfig(activityData, t),
24
+ [activityData, t]
25
+ );
26
+
35
27
  return (
36
28
  <DashboardLayout
37
29
  header={
@@ -54,7 +46,7 @@ const RestorationActivitySummary = ({ activityData, supportText, onDownload, dow
54
46
  <section>
55
47
  <Widget
56
48
  title={t("Activity Location")}
57
- className="no-px no-pb-body"
49
+ className="no-px no-pt-body no-p-body no-pb-body"
58
50
  style={{ height: '100%', display: 'flex', flexDirection: 'column' }}
59
51
  >
60
52
  <div style={{ flex: 1, minHeight: 0 }}>
@@ -135,6 +127,15 @@ const RestorationActivitySummary = ({ activityData, supportText, onDownload, dow
135
127
  </Widget>
136
128
  </section>
137
129
 
130
+ <section>
131
+ <ActivityIndicators
132
+ config={activityIndicatorsConfig}
133
+ loading={loading}
134
+ title={t("Activity Indicators")}
135
+ className="small-content"
136
+ />
137
+ </section>
138
+
138
139
  <section>
139
140
  <div style={{ maxWidth: "70%", width: "calc(100% - 405px)" }}>
140
141
  <ImageCarousel
package/src/index.js CHANGED
@@ -57,6 +57,7 @@ export { default as WidgetImage } from "./@daf/core/components/Dashboard/Widget/
57
57
  export { default as FlowWidget } from "./@daf/core/components/Dashboard/Widget/FlowWidgets/index.jsx";
58
58
  export { default as ActionWidget } from "./@daf/core/components/Dashboard/Widget/ActionWidget/index.jsx";
59
59
  export { default as KeyIndicators } from "./@daf/core/components/Dashboard/Widget/KeyIndicators/index.jsx";
60
+ export { default as ActivityIndicators } from "./@daf/core/components/Dashboard/Widget/ActivityIndicators/index.jsx";
60
61
  export { default as WidgetLoader } from "./@daf/core/components/Dashboard/Widget/WidgetLoader/index.jsx";
61
62
  export { default as TooltipIcon } from "./@daf/core/components/Icon/TooltipIcon.jsx";
62
63
  export { default as MineSiteMap } from "./@daf/core/components/Dashboard/Map/index.jsx";