@eeacms/volto-arcgis-block 0.1.468 → 0.1.470

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/CHANGELOG.md CHANGED
@@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. Dates are d
4
4
 
5
5
  Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6
6
 
7
+ ### [0.1.470](https://github.com/eea/volto-arcgis-block/compare/0.1.469...0.1.470) - 13 August 2026
8
+
9
+ ### [0.1.469](https://github.com/eea/volto-arcgis-block/compare/0.1.468...0.1.469) - 12 August 2026
10
+
11
+ #### :hammer_and_wrench: Others
12
+
13
+ - (chore): fix linting [Unai Bolivar - [`df6b223`](https://github.com/eea/volto-arcgis-block/commit/df6b223aa3b8b2e0bf098e191e210ec4022f059f)]
14
+ - (bug): dynamically pull time range from catalog for hi/lo res tile requests [Unai Bolivar - [`810b22d`](https://github.com/eea/volto-arcgis-block/commit/810b22d9b555fb18d9f8d5a810a5099f6ae29ab6)]
7
15
  ### [0.1.468](https://github.com/eea/volto-arcgis-block/compare/0.1.467...0.1.468) - 12 August 2026
8
16
 
9
17
  #### :rocket: New Features
@@ -17,6 +25,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
17
25
 
18
26
  #### :hammer_and_wrench: Others
19
27
 
28
+ - Merge pull request #1190 from eea/develop [Unai Bolivar - [`5d9e33f`](https://github.com/eea/volto-arcgis-block/commit/5d9e33f1470e6776920657aac835360aff91e47c)]
20
29
  - Merge pull request #1189 from eea/CLMS-304632-REFACTOR [Unai Bolivar - [`ffba286`](https://github.com/eea/volto-arcgis-block/commit/ffba286c6368fae6167ffedf3c89a18d74a31edd)]
21
30
  - (task): refactor dual layers support [Unai Bolivar - [`c13aaa0`](https://github.com/eea/volto-arcgis-block/commit/c13aaa089d91f476f1fa02e94673dc4d847704c9)]
22
31
  - (task): refactor dual layer support [Unai Bolivar - [`7c3a1cf`](https://github.com/eea/volto-arcgis-block/commit/7c3a1cfe18ed8be53b80fb2205b54cce90f0ad68)]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-arcgis-block",
3
- "version": "0.1.468",
3
+ "version": "0.1.470",
4
4
  "description": "volto-arcgis-block: Volto add-on",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: CodeSyntax",
@@ -952,7 +952,7 @@ class MenuWidget extends React.Component {
952
952
  }
953
953
  }
954
954
 
955
- supportDualLayers(layer, inheritedIndexLayer) {
955
+ supportDualLayers(layer, inheritedIndexLayer, datasetCollectionId) {
956
956
  const resolutionData = layer.resolution_data || {};
957
957
  const thresholdScale = Number(resolutionData.thresholdScale);
958
958
  const normalizeScaleValue = (scaleValue, fallbackValue = 0) => {
@@ -988,10 +988,85 @@ class MenuWidget extends React.Component {
988
988
  const CDSEProcessTileLayer = BaseTileLayer.createSubclass({
989
989
  properties: {
990
990
  collectionId: null,
991
+ catalogByoc: null,
991
992
  evalscript: null,
992
993
  processUrl: '/++api++/@proxyrunprocessapi',
993
994
  },
994
995
 
996
+ _resolveCatalogDateRange: function (options) {
997
+ const rawCollectionId = this.catalogByoc || '';
998
+ const normalizedCollectionId = String(rawCollectionId).replace(
999
+ /^byoc-/i,
1000
+ '',
1001
+ );
1002
+ if (!normalizedCollectionId) {
1003
+ return Promise.resolve(null);
1004
+ }
1005
+
1006
+ const cacheByCollection =
1007
+ this.constructor._catalogDateRangeCache ||
1008
+ (this.constructor._catalogDateRangeCache = {});
1009
+ const pendingByCollection =
1010
+ this.constructor._catalogDateRangePending ||
1011
+ (this.constructor._catalogDateRangePending = {});
1012
+
1013
+ if (cacheByCollection[normalizedCollectionId]) {
1014
+ return Promise.resolve(cacheByCollection[normalizedCollectionId]);
1015
+ }
1016
+ if (pendingByCollection[normalizedCollectionId]) {
1017
+ return pendingByCollection[normalizedCollectionId];
1018
+ }
1019
+
1020
+ const requestUrl =
1021
+ '/++api++/@get_catalogapi_dates?byoc=' +
1022
+ encodeURIComponent(normalizedCollectionId) +
1023
+ '&force_refresh=false';
1024
+
1025
+ pendingByCollection[normalizedCollectionId] = fetch(requestUrl, {
1026
+ headers: {
1027
+ Accept: 'application/json',
1028
+ },
1029
+ signal: options && options.signal,
1030
+ })
1031
+ .then((response) => {
1032
+ if (!response.ok) {
1033
+ return null;
1034
+ }
1035
+ return response.json();
1036
+ })
1037
+ .then((payload) => {
1038
+ const dates = Array.isArray(payload?.dates) ? payload.dates : [];
1039
+ const resolveTimeValue = (value, isStart) => {
1040
+ if (!value) {
1041
+ return null;
1042
+ }
1043
+ const stringValue = String(value);
1044
+ if (/^\d{4}-\d{2}-\d{2}$/.test(stringValue)) {
1045
+ return isStart
1046
+ ? `${stringValue}T00:00:00Z`
1047
+ : `${stringValue}T23:59:59Z`;
1048
+ }
1049
+ return stringValue;
1050
+ };
1051
+ const resolvedDateRange =
1052
+ dates.length > 0
1053
+ ? {
1054
+ from: resolveTimeValue(dates[0], true),
1055
+ to: resolveTimeValue(dates[dates.length - 1], false),
1056
+ }
1057
+ : null;
1058
+ cacheByCollection[normalizedCollectionId] = resolvedDateRange;
1059
+ delete pendingByCollection[normalizedCollectionId];
1060
+ return resolvedDateRange;
1061
+ })
1062
+ .catch(() => {
1063
+ delete pendingByCollection[normalizedCollectionId];
1064
+ return null;
1065
+ });
1066
+
1067
+ return pendingByCollection[normalizedCollectionId];
1068
+ },
1069
+
995
1070
  // Computes the tile bounding box in EPSG:3857 (without projections)
996
1071
  _tileToBBox3857: function (level, row, col) {
997
1072
  const tileInfo = this.tileInfo;
@@ -1024,81 +1099,94 @@ class MenuWidget extends React.Component {
1024
1099
  const width = this.tileInfo.size[0];
1025
1100
  const height = this.tileInfo.size[1];
1026
1101
 
1027
- const payload = {
1028
- input: {
1029
- bounds: {
1030
- bbox: [
1031
- bbox3857.west,
1032
- bbox3857.south,
1033
- bbox3857.east,
1034
- bbox3857.north,
1035
- ],
1036
- properties: {
1037
- crs: 'http://www.opengis.net/def/crs/EPSG/0/3857',
1038
- },
1039
- },
1040
- data: [
1041
- {
1042
- type: this.collectionId,
1043
- dataFilter: {
1044
- timeRange: {
1045
- from: '2021-01-01T00:00:00Z',
1046
- to: '2022-01-01T23:59:59Z',
1102
+ return this._resolveCatalogDateRange(options).then(
1103
+ (catalogDateRange) => {
1104
+ const resolvedTimeRangeFrom = catalogDateRange?.from || null;
1105
+ const resolvedTimeRangeTo = catalogDateRange?.to || null;
1106
+ const timeRange = {};
1107
+ if (resolvedTimeRangeFrom) {
1108
+ timeRange.from = resolvedTimeRangeFrom;
1109
+ }
1110
+ if (resolvedTimeRangeTo) {
1111
+ timeRange.to = resolvedTimeRangeTo;
1112
+ }
1113
+ const dataFilter = {};
1114
+ if (Object.keys(timeRange).length) {
1115
+ dataFilter.timeRange = timeRange;
1116
+ }
1117
+
1118
+ const payload = {
1119
+ input: {
1120
+ bounds: {
1121
+ bbox: [
1122
+ bbox3857.west,
1123
+ bbox3857.south,
1124
+ bbox3857.east,
1125
+ bbox3857.north,
1126
+ ],
1127
+ properties: {
1128
+ crs: 'http://www.opengis.net/def/crs/EPSG/0/3857',
1047
1129
  },
1048
1130
  },
1131
+ data: [
1132
+ {
1133
+ type: this.collectionId,
1134
+ ...(Object.keys(dataFilter).length ? { dataFilter } : {}),
1135
+ },
1136
+ ],
1049
1137
  },
1050
- ],
1051
- },
1052
- output: {
1053
- width: width,
1054
- height: height,
1055
- responses: [
1056
- {
1057
- identifier: 'default',
1058
- format: { type: 'image/png' },
1138
+ output: {
1139
+ width: width,
1140
+ height: height,
1141
+ responses: [
1142
+ {
1143
+ identifier: 'default',
1144
+ format: { type: 'image/png' },
1145
+ },
1146
+ ],
1059
1147
  },
1060
- ],
1061
- },
1062
- evalscript: this.evalscript,
1063
- };
1064
-
1065
- return fetch(this.processUrl, {
1066
- method: 'POST',
1067
- headers: {
1068
- 'Content-Type': 'application/json',
1069
- Accept: 'image/png',
1148
+ evalscript: this.evalscript,
1149
+ };
1150
+
1151
+ return fetch(this.processUrl, {
1152
+ method: 'POST',
1153
+ headers: {
1154
+ 'Content-Type': 'application/json',
1155
+ Accept: 'image/png',
1156
+ },
1157
+ body: JSON.stringify(payload),
1158
+ signal: options && options.signal,
1159
+ })
1160
+ .then((response) => {
1161
+ if (!response.ok) {
1162
+ throw new Error(
1163
+ `Process API error ${response.status}: ${response.statusText}`,
1164
+ );
1165
+ }
1166
+ return response.blob();
1167
+ })
1168
+ .then((blob) => {
1169
+ return new Promise((resolve, reject) => {
1170
+ const url = URL.createObjectURL(blob);
1171
+ const img = new Image();
1172
+ img.onload = () => {
1173
+ const canvas = document.createElement('canvas');
1174
+ canvas.width = width;
1175
+ canvas.height = height;
1176
+ const ctx = canvas.getContext('2d');
1177
+ ctx.drawImage(img, 0, 0, width, height);
1178
+ URL.revokeObjectURL(url);
1179
+ resolve(canvas);
1180
+ };
1181
+ img.onerror = (err) => {
1182
+ URL.revokeObjectURL(url);
1183
+ reject(err);
1184
+ };
1185
+ img.src = url;
1186
+ });
1187
+ });
1070
1188
  },
1071
- body: JSON.stringify(payload),
1072
- signal: options && options.signal,
1073
- })
1074
- .then((response) => {
1075
- if (!response.ok) {
1076
- throw new Error(
1077
- `Process API error ${response.status}: ${response.statusText}`,
1078
- );
1079
- }
1080
- return response.blob();
1081
- })
1082
- .then((blob) => {
1083
- return new Promise((resolve, reject) => {
1084
- const url = URL.createObjectURL(blob);
1085
- const img = new Image();
1086
- img.onload = () => {
1087
- const canvas = document.createElement('canvas');
1088
- canvas.width = width;
1089
- canvas.height = height;
1090
- const ctx = canvas.getContext('2d');
1091
- ctx.drawImage(img, 0, 0, width, height);
1092
- URL.revokeObjectURL(url);
1093
- resolve(canvas);
1094
- };
1095
- img.onerror = (err) => {
1096
- URL.revokeObjectURL(url);
1097
- reject(err);
1098
- };
1099
- img.src = url;
1100
- });
1101
- });
1189
+ );
1102
1190
  },
1103
1191
  });
1104
1192
  const tileInfo = {
@@ -1132,6 +1220,7 @@ class MenuWidget extends React.Component {
1132
1220
  new CDSEProcessTileLayer({
1133
1221
  ...sharedLayerProps,
1134
1222
  collectionId: lowResLayerData.collectionId,
1223
+ catalogByoc: datasetCollectionId || null,
1135
1224
  evalscript: lowResLayerData.evalscript,
1136
1225
  minScale: lowResLayerData.minScale,
1137
1226
  maxScale: lowResLayerData.maxScale,
@@ -1144,6 +1233,7 @@ class MenuWidget extends React.Component {
1144
1233
  new CDSEProcessTileLayer({
1145
1234
  ...sharedLayerProps,
1146
1235
  collectionId: highResLayerData.collectionId,
1236
+ catalogByoc: datasetCollectionId || null,
1147
1237
  evalscript: highResLayerData.evalscript,
1148
1238
  minScale: highResLayerData.minScale,
1149
1239
  maxScale: highResLayerData.maxScale,
@@ -2279,7 +2369,9 @@ class MenuWidget extends React.Component {
2279
2369
  layer.hasLowRes === true ||
2280
2370
  (layer.resolution_data?.lowRes && layer.resolution_data?.highRes)
2281
2371
  ) {
2282
- this.supportDualLayers(layer, inheritedIndexLayer);
2372
+ const datasetCollectionId =
2373
+ dataset_download_information?.items?.[0]?.byoc_collection || null;
2374
+ this.supportDualLayers(layer, inheritedIndexLayer, datasetCollectionId);
2283
2375
  } else if (viewService?.toLowerCase().includes('wms')) {
2284
2376
  viewService = viewService?.includes('?')
2285
2377
  ? viewService + '&'