datastake-daf 0.6.764 → 0.6.765

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.
@@ -10140,42 +10140,37 @@ const handleDataLinkGroupWithTableKeys = ({
10140
10140
  }
10141
10141
  };
10142
10142
 
10143
- const handleDataLinkWithTableKeys = _ref => {
10144
- var _inputConfig$meta, _inputConfig$meta3, _inputConfig$meta4, _inputConfig$meta5;
10145
- let {
10146
- inputConfig,
10147
- inputKey,
10148
- value,
10149
- level,
10150
- t,
10151
- rootForm,
10152
- allData,
10153
- user,
10154
- getApiBaseUrl = () => {},
10155
- getAppHeader = () => {},
10156
- app,
10157
- TreeNodeComponent
10158
- } = _ref;
10159
- if ((inputConfig === null || inputConfig === void 0 ? void 0 : inputConfig.type) !== 'dataLink' || !(inputConfig !== null && inputConfig !== void 0 && (_inputConfig$meta = inputConfig.meta) !== null && _inputConfig$meta !== void 0 && _inputConfig$meta.tableKeys)) {
10143
+ const handleDataLinkWithTableKeys = ({
10144
+ inputConfig,
10145
+ inputKey,
10146
+ value,
10147
+ level,
10148
+ t,
10149
+ rootForm,
10150
+ allData,
10151
+ user,
10152
+ getApiBaseUrl = () => {},
10153
+ getAppHeader = () => {},
10154
+ app,
10155
+ TreeNodeComponent
10156
+ }) => {
10157
+ if (inputConfig?.type !== 'dataLink' || !inputConfig?.meta?.tableKeys) {
10160
10158
  return null;
10161
10159
  }
10162
10160
  const tableKeys = inputConfig.meta.tableKeys;
10163
- const isAjaxModal = React.useMemo(() => {
10164
- var _inputConfig$meta2;
10165
- return !!(inputConfig !== null && inputConfig !== void 0 && (_inputConfig$meta2 = inputConfig.meta) !== null && _inputConfig$meta2 !== void 0 && _inputConfig$meta2.namespace);
10166
- }, [inputConfig]);
10161
+ const isAjaxModal = React.useMemo(() => !!inputConfig?.meta?.namespace, [inputConfig]);
10167
10162
  const ajaxModalValues = useAjaxModal$2({
10168
10163
  name: inputKey,
10169
10164
  user,
10170
- namespace: inputConfig === null || inputConfig === void 0 || (_inputConfig$meta3 = inputConfig.meta) === null || _inputConfig$meta3 === void 0 ? void 0 : _inputConfig$meta3.namespace,
10171
- skipFetch: inputConfig === null || inputConfig === void 0 || (_inputConfig$meta4 = inputConfig.meta) === null || _inputConfig$meta4 === void 0 ? void 0 : _inputConfig$meta4.skipFetch,
10165
+ namespace: inputConfig?.meta?.namespace,
10166
+ skipFetch: inputConfig?.meta?.skipFetch,
10172
10167
  isAjaxModal,
10173
- formScope: inputConfig === null || inputConfig === void 0 || (_inputConfig$meta5 = inputConfig.meta) === null || _inputConfig$meta5 === void 0 ? void 0 : _inputConfig$meta5.formScope,
10168
+ formScope: inputConfig?.meta?.formScope,
10174
10169
  APP: app,
10175
10170
  apiBaseUrl: getApiBaseUrl(),
10176
10171
  _getAppHeader: getAppHeader
10177
10172
  });
10178
- const dataLinkForm = ajaxModalValues === null || ajaxModalValues === void 0 ? void 0 : ajaxModalValues.form;
10173
+ const dataLinkForm = ajaxModalValues?.form;
10179
10174
  const createInputsAndValues = item => {
10180
10175
  const inputs = {};
10181
10176
  const values = {};
@@ -10188,20 +10183,19 @@ const handleDataLinkWithTableKeys = _ref => {
10188
10183
  };
10189
10184
  const isUploadFieldEmpty = (fieldKey, itemToCheck) => {
10190
10185
  if (uploadTypeFields.includes(fieldKey)) {
10191
- const itemValue = itemToCheck === null || itemToCheck === void 0 ? void 0 : itemToCheck[fieldKey];
10186
+ const itemValue = itemToCheck?.[fieldKey];
10192
10187
  return itemValue === undefined || itemValue === null || Array.isArray(itemValue) && itemValue.length === 0;
10193
10188
  }
10194
10189
  return false;
10195
10190
  };
10196
10191
  const processedTableKeys = processConditionalTableKeys(tableKeys, item);
10197
10192
  processedTableKeys.filter(tableKey => tableKey !== 'datastakeId').filter(tableKey => !isUploadFieldEmpty(tableKey, item)).forEach(tableKey => {
10198
- var _dataLinkForm$identif;
10199
- const formInputConfig = (dataLinkForm === null || dataLinkForm === void 0 ? void 0 : dataLinkForm[tableKey]) || (dataLinkForm === null || dataLinkForm === void 0 || (_dataLinkForm$identif = dataLinkForm['identification']) === null || _dataLinkForm$identif === void 0 ? void 0 : _dataLinkForm$identif[tableKey]);
10193
+ const formInputConfig = dataLinkForm?.[tableKey] || dataLinkForm?.['identification']?.[tableKey];
10200
10194
  if (formInputConfig) {
10201
- var _item$linking, _formInputConfig$meta, _formInputConfig$tabl;
10202
- inputs[tableKey] = _objectSpread2(_objectSpread2({}, formInputConfig), {}, {
10195
+ inputs[tableKey] = {
10196
+ ...formInputConfig,
10203
10197
  label: uploadTypeFields.includes(tableKey) ? uploadTypeLabels[tableKey] : formInputConfig.label || formInputConfig.tableLabel || tableKey
10204
- });
10198
+ };
10205
10199
  if (formInputConfig.label && typeof formInputConfig.label === 'object') {
10206
10200
  const dynamicLabelKeys = Object.keys(formInputConfig.label);
10207
10201
  let resolvedLabel = null;
@@ -10209,7 +10203,7 @@ const handleDataLinkWithTableKeys = _ref => {
10209
10203
  const parts = labelKey.split(' is ');
10210
10204
  if (parts.length === 2) {
10211
10205
  const [conditionKey, conditionValue] = parts;
10212
- if ((item === null || item === void 0 ? void 0 : item[conditionKey]) === conditionValue) {
10206
+ if (item?.[conditionKey] === conditionValue) {
10213
10207
  resolvedLabel = formInputConfig.label[labelKey];
10214
10208
  break;
10215
10209
  }
@@ -10217,17 +10211,16 @@ const handleDataLinkWithTableKeys = _ref => {
10217
10211
  }
10218
10212
  inputs[tableKey].label = resolvedLabel || Object.values(formInputConfig.label)[0] || (uploadTypeFields.includes(tableKey) ? uploadTypeLabels[tableKey] : tableKey);
10219
10213
  }
10220
- values[tableKey] = (item === null || item === void 0 || (_item$linking = item.linking) === null || _item$linking === void 0 || (_item$linking = _item$linking.SCL) === null || _item$linking === void 0 || (_item$linking = _item$linking[item === null || item === void 0 ? void 0 : item[tableKey]]) === null || _item$linking === void 0 ? void 0 : _item$linking.name) || item[formInputConfig === null || formInputConfig === void 0 || (_formInputConfig$meta = formInputConfig.meta) === null || _formInputConfig$meta === void 0 ? void 0 : _formInputConfig$meta.onNewSetValueKey] || (item === null || item === void 0 ? void 0 : item[formInputConfig === null || formInputConfig === void 0 || (_formInputConfig$tabl = formInputConfig.tableLabel) === null || _formInputConfig$tabl === void 0 ? void 0 : _formInputConfig$tabl.toLowerCase()]) || (item === null || item === void 0 ? void 0 : item[tableKey]);
10214
+ values[tableKey] = item?.linking?.SCL?.[item?.[tableKey]]?.name || item[formInputConfig?.meta?.onNewSetValueKey] || item?.[formInputConfig?.tableLabel?.toLowerCase()] || item?.[tableKey];
10221
10215
  } else {
10222
- var _item$linking2;
10223
10216
  inputs[tableKey] = {
10224
10217
  label: uploadTypeFields.includes(tableKey) ? uploadTypeLabels[tableKey] : tableKey,
10225
- type: inputConfig === null || inputConfig === void 0 ? void 0 : inputConfig.type
10218
+ type: inputConfig?.type
10226
10219
  };
10227
- values[tableKey] = (item === null || item === void 0 || (_item$linking2 = item.linking) === null || _item$linking2 === void 0 || (_item$linking2 = _item$linking2.SCL) === null || _item$linking2 === void 0 || (_item$linking2 = _item$linking2[item === null || item === void 0 ? void 0 : item[tableKey]]) === null || _item$linking2 === void 0 ? void 0 : _item$linking2.name) || (item === null || item === void 0 ? void 0 : item[tableKey]);
10220
+ values[tableKey] = item?.linking?.SCL?.[item?.[tableKey]]?.name || item?.[tableKey];
10228
10221
  }
10229
10222
  });
10230
- if (dataLinkForm !== null && dataLinkForm !== void 0 && dataLinkForm.identification && typeof dataLinkForm.identification === 'object') {
10223
+ if (dataLinkForm?.identification && typeof dataLinkForm.identification === 'object') {
10231
10224
  Object.keys(dataLinkForm.identification).filter(fieldKey => {
10232
10225
  if (uploadTypeFields.includes(fieldKey)) {
10233
10226
  return !isUploadFieldEmpty(fieldKey, item);
@@ -10237,11 +10230,11 @@ const handleDataLinkWithTableKeys = _ref => {
10237
10230
  const formInputConfig = dataLinkForm.identification[fieldKey];
10238
10231
  return formInputConfig && typeof formInputConfig === 'object' && !Array.isArray(formInputConfig);
10239
10232
  }).forEach(fieldKey => {
10240
- var _item$linking3, _formInputConfig$tabl2;
10241
10233
  const formInputConfig = dataLinkForm.identification[fieldKey];
10242
- inputs[fieldKey] = _objectSpread2(_objectSpread2({}, formInputConfig), {}, {
10234
+ inputs[fieldKey] = {
10235
+ ...formInputConfig,
10243
10236
  label: uploadTypeFields.includes(fieldKey) ? uploadTypeLabels[fieldKey] : formInputConfig.label || formInputConfig.tableLabel || fieldKey
10244
- });
10237
+ };
10245
10238
  if (formInputConfig.label && typeof formInputConfig.label === 'object') {
10246
10239
  const dynamicLabelKeys = Object.keys(formInputConfig.label);
10247
10240
  let resolvedLabel = null;
@@ -10249,7 +10242,7 @@ const handleDataLinkWithTableKeys = _ref => {
10249
10242
  const parts = labelKey.split(' is ');
10250
10243
  if (parts.length === 2) {
10251
10244
  const [conditionKey, conditionValue] = parts;
10252
- if ((item === null || item === void 0 ? void 0 : item[conditionKey]) === conditionValue) {
10245
+ if (item?.[conditionKey] === conditionValue) {
10253
10246
  resolvedLabel = formInputConfig.label[labelKey];
10254
10247
  break;
10255
10248
  }
@@ -10257,7 +10250,7 @@ const handleDataLinkWithTableKeys = _ref => {
10257
10250
  }
10258
10251
  inputs[fieldKey].label = resolvedLabel || Object.values(formInputConfig.label)[0] || (uploadTypeFields.includes(fieldKey) ? uploadTypeLabels[fieldKey] : fieldKey);
10259
10252
  }
10260
- values[fieldKey] = (item === null || item === void 0 || (_item$linking3 = item.linking) === null || _item$linking3 === void 0 || (_item$linking3 = _item$linking3.SCL) === null || _item$linking3 === void 0 || (_item$linking3 = _item$linking3[item === null || item === void 0 ? void 0 : item[fieldKey]]) === null || _item$linking3 === void 0 ? void 0 : _item$linking3.name) || (item === null || item === void 0 ? void 0 : item[formInputConfig === null || formInputConfig === void 0 || (_formInputConfig$tabl2 = formInputConfig.tableLabel) === null || _formInputConfig$tabl2 === void 0 ? void 0 : _formInputConfig$tabl2.toLowerCase()]) || (item === null || item === void 0 ? void 0 : item[fieldKey]);
10253
+ values[fieldKey] = item?.linking?.SCL?.[item?.[fieldKey]]?.name || item?.[formInputConfig?.tableLabel?.toLowerCase()] || item?.[fieldKey];
10261
10254
  });
10262
10255
  }
10263
10256
  return {
@@ -10267,7 +10260,7 @@ const handleDataLinkWithTableKeys = _ref => {
10267
10260
  };
10268
10261
  if (Array.isArray(value)) {
10269
10262
  return value.map((item, itemIndex) => {
10270
- const datastakeIdValue = item === null || item === void 0 ? void 0 : item.datastakeId;
10263
+ const datastakeIdValue = item?.datastakeId;
10271
10264
  const {
10272
10265
  inputs,
10273
10266
  values
@@ -10276,9 +10269,9 @@ const handleDataLinkWithTableKeys = _ref => {
10276
10269
  return null;
10277
10270
  }
10278
10271
  return /*#__PURE__*/jsxRuntime.jsx(TreeNodeComponent, {
10279
- nodeKey: datastakeIdValue || t("No ID ".concat(itemIndex + 1)),
10272
+ nodeKey: datastakeIdValue || t(`No ID ${itemIndex + 1}`),
10280
10273
  config: {
10281
- label: datastakeIdValue || t("No ID ".concat(itemIndex + 1)),
10274
+ label: datastakeIdValue || t(`No ID ${itemIndex + 1}`),
10282
10275
  type: 'custom-datalink',
10283
10276
  inputs: inputs
10284
10277
  },
@@ -10292,10 +10285,10 @@ const handleDataLinkWithTableKeys = _ref => {
10292
10285
  getApiBaseUrl: getApiBaseUrl,
10293
10286
  getAppHeader: getAppHeader,
10294
10287
  app: app
10295
- }, "".concat(inputKey, "-").concat(itemIndex));
10288
+ }, `${inputKey}-${itemIndex}`);
10296
10289
  });
10297
10290
  } else {
10298
- const datastakeIdValue = value === null || value === void 0 ? void 0 : value.datastakeId;
10291
+ const datastakeIdValue = value?.datastakeId;
10299
10292
  const {
10300
10293
  inputs,
10301
10294
  values
@@ -10320,7 +10313,7 @@ const handleDataLinkWithTableKeys = _ref => {
10320
10313
  getApiBaseUrl: getApiBaseUrl,
10321
10314
  getAppHeader: getAppHeader,
10322
10315
  app: app
10323
- }, "".concat(inputKey, "-single"));
10316
+ }, `${inputKey}-single`);
10324
10317
  }
10325
10318
  };
10326
10319
 
@@ -42327,7 +42327,7 @@ styled__default["default"].div`
42327
42327
  flex: 1;
42328
42328
  `;
42329
42329
 
42330
- const getKeyIndicatorsRowConfig = ({
42330
+ const getKeyIndicatorsRowConfig$1 = ({
42331
42331
  t,
42332
42332
  data = {}
42333
42333
  }) => [{
@@ -42355,8 +42355,8 @@ const getKeyIndicatorsRowConfig = ({
42355
42355
  })
42356
42356
  }, {
42357
42357
  label: t('Activity Participants'),
42358
- render: () => /*#__PURE__*/jsxRuntime.jsx("div", {
42359
- children: '0'
42358
+ render: () => /*#__PURE__*/jsxRuntime.jsxs("div", {
42359
+ children: [" ", data?.totalNumberOfParticipantsArrival || '0']
42360
42360
  })
42361
42361
  }, {
42362
42362
  label: t('Hectares Planted'),
@@ -42828,7 +42828,7 @@ const RestorationActivitySummary = ({
42828
42828
  isCollapsed,
42829
42829
  isNestedSidebarCollapsed
42830
42830
  } = useResizeContext();
42831
- const keyIndicatorsConfig = React.useMemo(() => getKeyIndicatorsRowConfig({
42831
+ const keyIndicatorsConfig = React.useMemo(() => getKeyIndicatorsRowConfig$1({
42832
42832
  t,
42833
42833
  data: activityData
42834
42834
  }), [t, activityData]);
@@ -43001,6 +43001,103 @@ const RestorationActivitySummary = ({
43001
43001
  });
43002
43002
  };
43003
43003
 
43004
+ const getKeyIndicatorsRowConfig = ({
43005
+ t,
43006
+ data = {}
43007
+ }) => [{
43008
+ label: t('Region'),
43009
+ render: () => {
43010
+ // const region = data?.region;
43011
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
43012
+ children: '-'
43013
+ });
43014
+ }
43015
+ }, {
43016
+ label: t('Associated Plots'),
43017
+ render: () => {
43018
+ // const plotsCount = data?.associatedPlotsCount || '0';
43019
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
43020
+ children: '0'
43021
+ });
43022
+ }
43023
+ }, {
43024
+ label: t('Implementation Partners'),
43025
+ render: () => {
43026
+ // const partnersCount = data?.partnersCount || '0';
43027
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
43028
+ children: '0'
43029
+ });
43030
+ }
43031
+ }, {
43032
+ label: t('Total Activities'),
43033
+ render: () => {
43034
+ // const activitiesCount = data?.activitiesCount || '0';
43035
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
43036
+ children: '0'
43037
+ });
43038
+ }
43039
+ }, {
43040
+ label: t('Information Sources'),
43041
+ render: () => {
43042
+ // const sourcesCount = data?.informationSourcesCount || '0';
43043
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
43044
+ children: '0'
43045
+ });
43046
+ }
43047
+ }];
43048
+
43049
+ const PlantingCycleSummary = ({
43050
+ activityData,
43051
+ supportText,
43052
+ onDownload,
43053
+ downloadDisabled,
43054
+ actionButtons,
43055
+ breadcrumbs,
43056
+ goBackTo,
43057
+ loading,
43058
+ t = () => {}
43059
+ }) => {
43060
+ const keyIndicatorsConfig = React.useMemo(() => getKeyIndicatorsRowConfig({
43061
+ t,
43062
+ data: {}
43063
+ }), [t]);
43064
+ return /*#__PURE__*/jsxRuntime.jsxs(DashboardLayout, {
43065
+ header: /*#__PURE__*/jsxRuntime.jsx(DAFHeader, {
43066
+ title: 'Planting Cycle Summary',
43067
+ supportText: supportText || '',
43068
+ onDownload: onDownload,
43069
+ downloadDisabled: downloadDisabled,
43070
+ actionButtons: actionButtons,
43071
+ breadcrumbs: breadcrumbs,
43072
+ goBackTo: goBackTo,
43073
+ loading: loading
43074
+ }),
43075
+ children: [/*#__PURE__*/jsxRuntime.jsx("section", {
43076
+ children: /*#__PURE__*/jsxRuntime.jsx(KeyIndicatorsWidget, {
43077
+ title: t("Key Information"),
43078
+ config: keyIndicatorsConfig,
43079
+ loading: loading
43080
+ })
43081
+ }), /*#__PURE__*/jsxRuntime.jsx("section", {
43082
+ children: /*#__PURE__*/jsxRuntime.jsx(Widget, {
43083
+ title: t("Planting Locations"),
43084
+ className: "no-px h-w-btn-header no-pt-body no-p-body no-pb-body",
43085
+ style: {
43086
+ height: '100%',
43087
+ display: 'flex',
43088
+ flexDirection: 'column'
43089
+ },
43090
+ children: /*#__PURE__*/jsxRuntime.jsx(Map$1, {
43091
+ loading: loading,
43092
+ t: t,
43093
+ isSatellite: true,
43094
+ data: []
43095
+ })
43096
+ })
43097
+ })]
43098
+ });
43099
+ };
43100
+
43004
43101
  const IconNodesConfig = {
43005
43102
  operator: {
43006
43103
  name: "Operators",
@@ -43481,6 +43578,7 @@ exports.MineSummary = MineSummary;
43481
43578
  exports.OperatorSummary = OperatorSummary;
43482
43579
  exports.OperatorsTable = OperatorsTable;
43483
43580
  exports.PartnersTable = PartnersTable;
43581
+ exports.PlantingCycleSummary = PlantingCycleSummary;
43484
43582
  exports.ProductionSitesTable = ProductionSitesTable;
43485
43583
  exports.RestorationActivitySummary = RestorationActivitySummary;
43486
43584
  exports.StakeholdersTable = StakeholdersTable;
@@ -0,0 +1,330 @@
1
+ /* Isolated Mapbox GL CSS - Scoped to prevent Leaflet conflicts */
2
+
3
+ /* Mapbox GL Core Styles - Scoped with .mapbox-gl-scope */
4
+ .mapbox-gl-scope .mapboxgl-map {
5
+ font: 12px/20px Helvetica Neue, Arial, Helvetica, sans-serif;
6
+ overflow: hidden;
7
+ position: relative;
8
+ -webkit-tap-highlight-color: rgb(0 0 0/0);
9
+ }
10
+
11
+ .mapbox-gl-scope .mapboxgl-canvas {
12
+ left: 0;
13
+ position: absolute;
14
+ top: 0;
15
+ }
16
+
17
+ .mapbox-gl-scope .mapboxgl-map:-webkit-full-screen {
18
+ height: 100%;
19
+ width: 100%;
20
+ }
21
+
22
+ .mapbox-gl-scope .mapboxgl-canary {
23
+ background-color: salmon;
24
+ }
25
+
26
+ .mapbox-gl-scope .mapboxgl-canvas-container.mapboxgl-interactive,
27
+ .mapbox-gl-scope .mapboxgl-ctrl-group button.mapboxgl-ctrl-compass {
28
+ cursor: grab;
29
+ -webkit-user-select: none;
30
+ user-select: none;
31
+ }
32
+
33
+ .mapbox-gl-scope .mapboxgl-canvas-container.mapboxgl-interactive.mapboxgl-track-pointer {
34
+ cursor: pointer;
35
+ }
36
+
37
+ .mapbox-gl-scope .mapboxgl-canvas-container.mapboxgl-interactive:active,
38
+ .mapbox-gl-scope .mapboxgl-ctrl-group button.mapboxgl-ctrl-compass:active {
39
+ cursor: grabbing;
40
+ }
41
+
42
+ .mapbox-gl-scope .mapboxgl-canvas-container.mapboxgl-touch-zoom-rotate,
43
+ .mapbox-gl-scope .mapboxgl-canvas-container.mapboxgl-touch-zoom-rotate .mapboxgl-canvas {
44
+ touch-action: pan-x pan-y;
45
+ }
46
+
47
+ .mapbox-gl-scope .mapboxgl-canvas-container.mapboxgl-touch-drag-pan,
48
+ .mapbox-gl-scope .mapboxgl-canvas-container.mapboxgl-touch-drag-pan .mapboxgl-canvas {
49
+ touch-action: pinch-zoom;
50
+ }
51
+
52
+ .mapbox-gl-scope .mapboxgl-canvas-container.mapboxgl-touch-zoom-rotate.mapboxgl-touch-drag-pan,
53
+ .mapbox-gl-scope .mapboxgl-canvas-container.mapboxgl-touch-zoom-rotate.mapboxgl-touch-drag-pan .mapboxgl-canvas {
54
+ touch-action: none;
55
+ }
56
+
57
+ /* Control positioning */
58
+ .mapbox-gl-scope .mapboxgl-ctrl-bottom,
59
+ .mapbox-gl-scope .mapboxgl-ctrl-bottom-left,
60
+ .mapbox-gl-scope .mapboxgl-ctrl-bottom-right,
61
+ .mapbox-gl-scope .mapboxgl-ctrl-left,
62
+ .mapbox-gl-scope .mapboxgl-ctrl-right,
63
+ .mapbox-gl-scope .mapboxgl-ctrl-top,
64
+ .mapbox-gl-scope .mapboxgl-ctrl-top-left,
65
+ .mapbox-gl-scope .mapboxgl-ctrl-top-right {
66
+ pointer-events: none;
67
+ position: absolute;
68
+ z-index: 2;
69
+ }
70
+
71
+ .mapbox-gl-scope .mapboxgl-ctrl-top-left {
72
+ left: 0;
73
+ top: 0;
74
+ }
75
+
76
+ .mapbox-gl-scope .mapboxgl-ctrl-top {
77
+ left: 50%;
78
+ top: 0;
79
+ transform: translateX(-50%);
80
+ }
81
+
82
+ .mapbox-gl-scope .mapboxgl-ctrl-top-right {
83
+ right: 0;
84
+ top: 0;
85
+ }
86
+
87
+ .mapbox-gl-scope .mapboxgl-ctrl-right {
88
+ right: 0;
89
+ top: 50%;
90
+ transform: translateY(-50%);
91
+ }
92
+
93
+ .mapbox-gl-scope .mapboxgl-ctrl-bottom-right {
94
+ bottom: 0;
95
+ right: 0;
96
+ }
97
+
98
+ .mapbox-gl-scope .mapboxgl-ctrl-bottom {
99
+ bottom: 0;
100
+ left: 50%;
101
+ transform: translateX(-50%);
102
+ }
103
+
104
+ .mapbox-gl-scope .mapboxgl-ctrl-bottom-left {
105
+ bottom: 0;
106
+ left: 0;
107
+ }
108
+
109
+ .mapbox-gl-scope .mapboxgl-ctrl-left {
110
+ left: 0;
111
+ top: 50%;
112
+ transform: translateY(-50%);
113
+ }
114
+
115
+ .mapbox-gl-scope .mapboxgl-ctrl {
116
+ clear: both;
117
+ pointer-events: auto;
118
+ transform: translate(0);
119
+ }
120
+
121
+ .mapbox-gl-scope .mapboxgl-ctrl-top-left .mapboxgl-ctrl {
122
+ float: left;
123
+ margin: 10px 0 0 10px;
124
+ }
125
+
126
+ .mapbox-gl-scope .mapboxgl-ctrl-top .mapboxgl-ctrl {
127
+ float: left;
128
+ margin: 10px 0;
129
+ }
130
+
131
+ .mapbox-gl-scope .mapboxgl-ctrl-top-right .mapboxgl-ctrl {
132
+ float: right;
133
+ margin: 10px 10px 0 0;
134
+ }
135
+
136
+ .mapbox-gl-scope .mapboxgl-ctrl-bottom-right .mapboxgl-ctrl,
137
+ .mapbox-gl-scope .mapboxgl-ctrl-right .mapboxgl-ctrl {
138
+ float: right;
139
+ margin: 0 10px 10px 0;
140
+ }
141
+
142
+ .mapbox-gl-scope .mapboxgl-ctrl-bottom .mapboxgl-ctrl {
143
+ float: left;
144
+ margin: 10px 0;
145
+ }
146
+
147
+ .mapbox-gl-scope .mapboxgl-ctrl-bottom-left .mapboxgl-ctrl,
148
+ .mapbox-gl-scope .mapboxgl-ctrl-left .mapboxgl-ctrl {
149
+ float: left;
150
+ margin: 0 0 10px 10px;
151
+ }
152
+
153
+ /* Control group styling */
154
+ .mapbox-gl-scope .mapboxgl-ctrl-group {
155
+ background: #fff;
156
+ border-radius: 4px;
157
+ }
158
+
159
+ .mapbox-gl-scope .mapboxgl-ctrl-group:not(:empty) {
160
+ box-shadow: 0 0 0 2px #0000001a;
161
+ }
162
+
163
+ .mapbox-gl-scope .mapboxgl-ctrl-group button {
164
+ background-color: initial;
165
+ border: 0;
166
+ box-sizing: border-box;
167
+ cursor: pointer;
168
+ display: block;
169
+ height: 29px;
170
+ outline: none;
171
+ overflow: hidden;
172
+ padding: 0;
173
+ width: 29px;
174
+ }
175
+
176
+ .mapbox-gl-scope .mapboxgl-ctrl-group button+button {
177
+ border-top: 1px solid #ddd;
178
+ }
179
+
180
+ .mapbox-gl-scope .mapboxgl-ctrl button .mapboxgl-ctrl-icon {
181
+ background-position: 50%;
182
+ background-repeat: no-repeat;
183
+ display: block;
184
+ height: 100%;
185
+ width: 100%;
186
+ }
187
+
188
+ .mapbox-gl-scope .mapboxgl-ctrl-attrib-button:focus,
189
+ .mapbox-gl-scope .mapboxgl-ctrl-group button:focus {
190
+ box-shadow: 0 0 2px 2px #0096ff;
191
+ }
192
+
193
+ .mapbox-gl-scope .mapboxgl-ctrl button:disabled {
194
+ cursor: not-allowed;
195
+ }
196
+
197
+ .mapbox-gl-scope .mapboxgl-ctrl button:disabled .mapboxgl-ctrl-icon {
198
+ opacity: .25;
199
+ }
200
+
201
+ .mapbox-gl-scope .mapboxgl-ctrl-group button:first-child {
202
+ border-radius: 4px 4px 0 0;
203
+ }
204
+
205
+ .mapbox-gl-scope .mapboxgl-ctrl-group button:last-child {
206
+ border-radius: 0 0 4px 4px;
207
+ }
208
+
209
+ .mapbox-gl-scope .mapboxgl-ctrl-group button:only-child {
210
+ border-radius: inherit;
211
+ }
212
+
213
+ .mapbox-gl-scope .mapboxgl-ctrl button:not(:disabled):hover {
214
+ background-color: #0000000d;
215
+ }
216
+
217
+ /* Marker styles */
218
+ .mapbox-gl-scope .mapboxgl-marker {
219
+ position: absolute;
220
+ z-index: 1;
221
+ }
222
+
223
+ .mapbox-gl-scope .mapboxgl-marker svg {
224
+ display: block;
225
+ }
226
+
227
+ /* Popup styles */
228
+ .mapbox-gl-scope .mapboxgl-popup {
229
+ position: absolute;
230
+ text-align: center;
231
+ margin-bottom: 20px;
232
+ }
233
+
234
+ .mapbox-gl-scope .mapboxgl-popup-content-wrapper {
235
+ padding: 1px;
236
+ text-align: left;
237
+ border-radius: 12px;
238
+ }
239
+
240
+ .mapbox-gl-scope .mapboxgl-popup-content {
241
+ margin: 13px 24px 13px 20px;
242
+ line-height: 1.3;
243
+ font-size: 13px;
244
+ min-height: 1px;
245
+ }
246
+
247
+ .mapbox-gl-scope .mapboxgl-popup-content p {
248
+ margin: 17px 0;
249
+ }
250
+
251
+ .mapbox-gl-scope .mapboxgl-popup-tip-container {
252
+ width: 40px;
253
+ height: 20px;
254
+ position: absolute;
255
+ left: 50%;
256
+ margin-top: -1px;
257
+ margin-left: -20px;
258
+ overflow: hidden;
259
+ pointer-events: none;
260
+ }
261
+
262
+ .mapbox-gl-scope .mapboxgl-popup-tip {
263
+ width: 17px;
264
+ height: 17px;
265
+ padding: 1px;
266
+ margin: -10px auto 0;
267
+ pointer-events: auto;
268
+ -webkit-transform: rotate(45deg);
269
+ -moz-transform: rotate(45deg);
270
+ -ms-transform: rotate(45deg);
271
+ transform: rotate(45deg);
272
+ }
273
+
274
+ .mapbox-gl-scope .mapboxgl-popup-content-wrapper,
275
+ .mapbox-gl-scope .mapboxgl-popup-tip {
276
+ background: white;
277
+ color: #333;
278
+ box-shadow: 0 3px 14px rgba(0, 0, 0, 0.4);
279
+ }
280
+
281
+ .mapbox-gl-scope .mapboxgl-popup-close-button {
282
+ position: absolute;
283
+ top: 0;
284
+ right: 0;
285
+ border: none;
286
+ text-align: center;
287
+ width: 24px;
288
+ height: 24px;
289
+ font: 16px/24px Tahoma, Verdana, sans-serif;
290
+ color: #757575;
291
+ text-decoration: none;
292
+ background: transparent;
293
+ }
294
+
295
+ .mapbox-gl-scope .mapboxgl-popup-close-button:hover,
296
+ .mapbox-gl-scope .mapboxgl-popup-close-button:focus {
297
+ color: #585858;
298
+ }
299
+
300
+ /* Attribution */
301
+ .mapbox-gl-scope .mapboxgl-ctrl-attribution {
302
+ background: #fff;
303
+ background: rgba(255, 255, 255, 0.8);
304
+ margin: 0;
305
+ }
306
+
307
+ .mapbox-gl-scope .mapboxgl-ctrl-attribution,
308
+ .mapbox-gl-scope .mapboxgl-ctrl-scale-line {
309
+ padding: 0 5px;
310
+ color: #333;
311
+ line-height: 1.4;
312
+ }
313
+
314
+ .mapbox-gl-scope .mapboxgl-ctrl-attribution a {
315
+ text-decoration: none;
316
+ }
317
+
318
+ .mapbox-gl-scope .mapboxgl-ctrl-attribution a:hover,
319
+ .mapbox-gl-scope .mapboxgl-ctrl-attribution a:focus {
320
+ text-decoration: underline;
321
+ }
322
+
323
+ /* Hide attribution by default */
324
+ .mapbox-gl-scope .mapboxgl-ctrl-attribution {
325
+ display: none !important;
326
+ }
327
+
328
+ .mapbox-gl-scope .mapboxgl-ctrl-logo {
329
+ display: none !important;
330
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "datastake-daf",
3
- "version": "0.6.764",
3
+ "version": "0.6.765",
4
4
  "dependencies": {
5
5
  "@ant-design/icons": "^5.2.5",
6
6
  "@antv/g2": "^5.1.1",
@@ -0,0 +1,40 @@
1
+ import React from "react";
2
+
3
+ export const getKeyIndicatorsRowConfig = ({ t, data = {} }) => [
4
+ {
5
+ label: t('Region'),
6
+ render: () => {
7
+ // const region = data?.region;
8
+ return <div>{ '-'}</div>;
9
+ }
10
+ },
11
+ {
12
+ label: t('Associated Plots'),
13
+ render: () => {
14
+ // const plotsCount = data?.associatedPlotsCount || '0';
15
+ return <div>{'0'}</div>
16
+ }
17
+ },
18
+ {
19
+ label: t('Implementation Partners'),
20
+ render: () => {
21
+ // const partnersCount = data?.partnersCount || '0';
22
+ return <div>{'0'}</div>
23
+ }
24
+ },
25
+ {
26
+ label: t('Total Activities'),
27
+ render: () => {
28
+ // const activitiesCount = data?.activitiesCount || '0';
29
+ return <div>{'0'}</div>
30
+ }
31
+ },
32
+ {
33
+ label: t('Information Sources'),
34
+ render: () => {
35
+ // const sourcesCount = data?.informationSourcesCount || '0';
36
+ return <div>{'0'}</div>
37
+ }
38
+ },
39
+ ];
40
+
@@ -0,0 +1,122 @@
1
+ import L from "leaflet";
2
+
3
+ export const getMapDataFromActivity = (activityData, t) => {
4
+ const location = activityData?.location;
5
+ const perimeter = location?.perimeter;
6
+
7
+ const area = Array.isArray(perimeter) && perimeter.length > 0
8
+ ? perimeter
9
+ .filter((coord) => Array.isArray(coord) && coord.length >= 2)
10
+ .map((coord) => {
11
+ const first = typeof coord[0] === 'number' ? coord[0] : parseFloat(coord[0]);
12
+ const second = typeof coord[1] === 'number' ? coord[1] : parseFloat(coord[1]);
13
+
14
+ if (isNaN(first) || isNaN(second) || !isFinite(first) || !isFinite(second)) {
15
+ return null;
16
+ }
17
+
18
+ // Try both formats and use Leaflet to validate
19
+ // First try as [lat, lng]
20
+ try {
21
+ const latLng1 = L.latLng(first, second);
22
+ if (latLng1.lat >= -90 && latLng1.lat <= 90 &&
23
+ latLng1.lng >= -180 && latLng1.lng <= 180) {
24
+ return [latLng1.lat, latLng1.lng];
25
+ }
26
+ } catch (e) {
27
+ // Not valid as [lat, lng], try swapping
28
+ }
29
+
30
+ // Try as [lng, lat] (GeoJSON format) - swap them
31
+ try {
32
+ const latLng2 = L.latLng(second, first);
33
+ if (latLng2.lat >= -90 && latLng2.lat <= 90 &&
34
+ latLng2.lng >= -180 && latLng2.lng <= 180) {
35
+ return [latLng2.lat, latLng2.lng];
36
+ }
37
+ } catch (e) {
38
+ // Invalid coordinates
39
+ }
40
+
41
+ return null;
42
+ })
43
+ .filter((coord) => coord !== null)
44
+ : null;
45
+
46
+ const mapData = [];
47
+ const baseColor = '#15FFFFB2';
48
+ const locationName = location?.name || activityData?.name || t("Activity Location");
49
+ const datastakeId = location?.datastakeId || activityData?.datastakeId;
50
+
51
+ // Helper to validate coordinates
52
+ const isValidCoordinate = (coord) => {
53
+ const num = typeof coord === 'number' ? coord : parseFloat(coord);
54
+ return !isNaN(num) && isFinite(num);
55
+ };
56
+
57
+ // Entry 1: Perimeter polygon (independent - show if it exists)
58
+ if (area && area.length >= 3) {
59
+ mapData.push({
60
+ _id: {},
61
+ id: `${activityData?.id || activityData?.datastakeId || 'perimeter'}-perimeter`,
62
+ area: area,
63
+ color: baseColor,
64
+ name: locationName,
65
+ plotName: locationName,
66
+ territoryTitle: t("Associated Plot"),
67
+ subTitle: t("Activity Location"),
68
+ type: t("Activity Location"),
69
+ datastakeId: datastakeId,
70
+ sources: null,
71
+ link: null,
72
+ });
73
+ }
74
+
75
+ // Entry 2: Arrival marker (independent - show if it exists)
76
+ const arrivalLat = activityData?.locationCheckArrival?.latitude;
77
+ const arrivalLng = activityData?.locationCheckArrival?.longitude;
78
+ if (isValidCoordinate(arrivalLat) && isValidCoordinate(arrivalLng)) {
79
+ mapData.push({
80
+ _id: {},
81
+ id: `${activityData?.id || activityData?.datastakeId || 'arrival'}-arrival`,
82
+ area: area && area.length >= 3 ? area : null,
83
+ color: baseColor,
84
+ gps: {
85
+ latitude: typeof arrivalLat === 'number' ? arrivalLat : parseFloat(arrivalLat),
86
+ longitude: typeof arrivalLng === 'number' ? arrivalLng : parseFloat(arrivalLng),
87
+ },
88
+ name: t("Activity Start"),
89
+ plotName: locationName,
90
+ territoryTitle: t("Associated Plot"),
91
+ datastakeId: `${datastakeId}-arrival`,
92
+ sources: null,
93
+ link: null,
94
+ });
95
+ }
96
+
97
+ // Entry 3: Departure marker (independent - show if it exists)
98
+ const departureLat = activityData?.locationCheckDeparture?.latitude;
99
+ const departureLng = activityData?.locationCheckDeparture?.longitude;
100
+ if (isValidCoordinate(departureLat) && isValidCoordinate(departureLng)) {
101
+ mapData.push({
102
+ _id: {},
103
+ id: `${activityData?.id || activityData?.datastakeId || 'departure'}-departure`,
104
+ area: area && area.length >= 3 ? area : null,
105
+ color: baseColor,
106
+ gps: {
107
+ latitude: typeof departureLat === 'number' ? departureLat : parseFloat(departureLat),
108
+ longitude: typeof departureLng === 'number' ? departureLng : parseFloat(departureLng),
109
+ },
110
+ name: t("Activity End"),
111
+ plotName: locationName,
112
+ territoryTitle: t("Associated Plot"),
113
+ datastakeId: `${datastakeId}-departure`,
114
+ markerColor: "#FF7A45",
115
+ sources: null,
116
+ link: null,
117
+ });
118
+ }
119
+
120
+ return mapData;
121
+ };
122
+
@@ -0,0 +1,46 @@
1
+ import { useMemo } from 'react';
2
+ import { DashboardLayout, Header, KeyIndicators, MineSiteMap, Widget } from '../../../../../../src/index.js'
3
+ import { getKeyIndicatorsRowConfig } from './config';
4
+
5
+ const PlantingCycleSummary = ({ activityData, supportText, onDownload, downloadDisabled, actionButtons, breadcrumbs, goBackTo, loading, t = () => { } }) => {
6
+ const keyIndicatorsConfig = useMemo(() => getKeyIndicatorsRowConfig({ t, data: {} }), [t]);
7
+
8
+ return (
9
+ <DashboardLayout
10
+ header={
11
+ <Header
12
+ title={'Planting Cycle Summary'}
13
+ supportText={supportText || ''}
14
+ onDownload={onDownload}
15
+ downloadDisabled={downloadDisabled}
16
+ actionButtons={actionButtons}
17
+ breadcrumbs={breadcrumbs}
18
+ goBackTo={goBackTo}
19
+ loading={loading}
20
+ />
21
+ }
22
+ >
23
+ <section>
24
+ <KeyIndicators title={t("Key Information")} config={keyIndicatorsConfig} loading={loading} />
25
+ </section>
26
+
27
+ <section>
28
+ <Widget
29
+ title={t("Planting Locations")}
30
+ className="no-px h-w-btn-header no-pt-body no-p-body no-pb-body"
31
+ style={{ height: '100%', display: 'flex', flexDirection: 'column' }}
32
+ >
33
+ <MineSiteMap
34
+ loading={loading}
35
+ t={t}
36
+ isSatellite
37
+ data={[]}
38
+ />
39
+ </Widget>
40
+ </section>
41
+ </DashboardLayout>
42
+ )
43
+ }
44
+
45
+ export default PlantingCycleSummary;
46
+
@@ -26,7 +26,7 @@ export const getKeyIndicatorsRowConfig = ({ t, data = {} }) => [
26
26
  },
27
27
  {
28
28
  label: t('Activity Participants'),
29
- render: () => <div>{'0'}</div>
29
+ render: () => <div> {data?.totalNumberOfParticipantsArrival || '0'}</div>
30
30
  },
31
31
  {
32
32
  label: t('Hectares Planted'),
package/src/pages.js CHANGED
@@ -17,4 +17,5 @@ export { default as PartnersTable } from './@daf/pages/Partners/index.jsx';
17
17
  // Summary
18
18
  export { default as OperatorSummary } from './@daf/pages/Summary/Operator/index.jsx';
19
19
  export { default as RestorationActivitySummary } from './@daf/pages/Summary/Activities/Restoration/index.jsx';
20
+ export { default as PlantingCycleSummary } from './@daf/pages/Summary/Activities/PlantingCycle/index.jsx';
20
21
  export { default as MineSummary } from './@daf/pages/Summary/Minesite/index.jsx';