@eeacms/volto-arcgis-block 0.1.361 → 0.1.363

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,15 @@ 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.363](https://github.com/eea/volto-arcgis-block/compare/0.1.362...0.1.363) - 26 May 2025
8
+
9
+ ### [0.1.362](https://github.com/eea/volto-arcgis-block/compare/0.1.361...0.1.362) - 21 May 2025
10
+
11
+ #### :hammer_and_wrench: Others
12
+
13
+ - Merge pull request #956 from eea/develop [Unai Bolivar - [`b230060`](https://github.com/eea/volto-arcgis-block/commit/b230060ba6a428ced1b613f26c5dbc1f04cf5bee)]
14
+ - CLMS-286372 (bug): Fixed syntax errors and removed old commented code in MenuWidget and Area widget upload service. [Unai Bolivar - [`bea1116`](https://github.com/eea/volto-arcgis-block/commit/bea1116c14d09dd10f6da0a34e36f6796780645f)]
15
+ - CLMS-286372 (bug): Fixed issues with Area widget upload service. [Unai Bolivar - [`a66e6c6`](https://github.com/eea/volto-arcgis-block/commit/a66e6c69ef4d79dc265f4a17462a8f29df7aeee1)]
7
16
  ### [0.1.361](https://github.com/eea/volto-arcgis-block/compare/0.1.360...0.1.361) - 20 May 2025
8
17
 
9
18
  ### [0.1.360](https://github.com/eea/volto-arcgis-block/compare/0.1.359...0.1.360) - 19 May 2025
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-arcgis-block",
3
- "version": "0.1.361",
3
+ "version": "0.1.363",
4
4
  "description": "volto-arcgis-block: Volto add-on",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: CodeSyntax",
@@ -248,31 +248,71 @@ class AreaWidget extends React.Component {
248
248
  this.loadNutsService(e.target.value, [6, 7, 8]);
249
249
  this.nutsRadioButton(e.target.value);
250
250
  }
251
- // countriesHandler(e) {
252
- // this.loadCountriesService(e.target.value);
253
- // }
251
+
252
+ getNutsUrlChunks(nutsUrl) {
253
+ const [base, query] = nutsUrl.split('query?');
254
+ return {
255
+ baseUrl: base || '',
256
+ queryString: query || '',
257
+ };
258
+ }
259
+
260
+ getNutsParams(queryString) {
261
+ if (!queryString) return {};
262
+ return queryString.split('&').reduce((acc, pair) => {
263
+ const [key, value] = pair.split('=');
264
+ if (key && value) {
265
+ acc[key] = decodeURIComponent(value);
266
+ }
267
+ return acc;
268
+ }, {});
269
+ }
270
+
271
+ createDefinitionExpressionObject(params) {
272
+ if (!params || Object.keys(params).length === 0) return null;
273
+ return Object.entries(params)
274
+ .map(([k, v]) => {
275
+ if (typeof v === 'string' && v.includes(',')) {
276
+ const values = v.split(',').map((val) => `'${val.trim()}'`);
277
+ if (values.length > 2) {
278
+ return `${k} in (${values.join(', ')})`;
279
+ } else {
280
+ return values.map((val) => `${k}=${val}`).join(' OR ');
281
+ }
282
+ } else {
283
+ return `${k}='${v}'`;
284
+ }
285
+ })
286
+ .join(' AND ');
287
+ }
288
+
289
+ createFeatureLayer(id, baseUrl, level, definitionExpression) {
290
+ return new FeatureLayer({
291
+ id: id,
292
+ url: baseUrl,
293
+ layerId: level,
294
+ outFields: ['*'],
295
+ popupEnabled: false,
296
+ definitionExpression: definitionExpression,
297
+ });
298
+ }
254
299
 
255
300
  loadNutsService(id, levels) {
256
301
  this.clearWidget();
257
302
  document.querySelector('.esri-attribution__powered-by').style.display =
258
303
  'flex';
304
+ const { baseUrl, queryString } = this.getNutsUrlChunks(this.nutsUrl);
305
+ const params = this.getNutsParams(queryString);
306
+ const definitionExpression = this.createDefinitionExpressionObject(params);
259
307
  levels.forEach((level) => {
260
- var layer = new FeatureLayer({
261
- id: id,
262
- //url: this.props.urls.nutsHandler,
263
- url: this.nutsUrl,
264
- layerId: level,
265
- outFields: ['*'],
266
- popupEnabled: false,
267
- //definitionExpression: 'LEVL_CODE=' + level,
268
- });
269
-
270
- //this.removeFileUploadedLayer();
271
-
308
+ const layer = this.createFeatureLayer(
309
+ id,
310
+ baseUrl,
311
+ level,
312
+ definitionExpression,
313
+ );
272
314
  this.nutsGroupLayer.add(layer);
273
-
274
315
  let index = this.getHighestIndex();
275
-
276
316
  this.props.map.reorder(this.nutsGroupLayer, index + 1);
277
317
  });
278
318
  }
@@ -282,16 +322,12 @@ class AreaWidget extends React.Component {
282
322
  'flex';
283
323
  var layer = new FeatureLayer({
284
324
  id: id,
285
- //url: this.props.urls.outsideEu,
286
- url:
287
- 'https://land.discomap.eea.europa.eu/arcgis/rest/services/CLMS_Portal/World_countries_except_EU37/MapServer',
325
+ url: this.props.urls.outsideEu,
288
326
  layerId: 0,
289
327
  outFields: ['*'],
290
328
  popupEnabled: false,
291
329
  });
292
330
 
293
- //this.removeFileUploadedLayer();
294
-
295
331
  this.nutsGroupLayer.add(layer);
296
332
 
297
333
  let index = this.getHighestIndex();
@@ -318,10 +354,6 @@ class AreaWidget extends React.Component {
318
354
 
319
355
  const fileSize = e.target.files[0].size;
320
356
 
321
- //Get the file from the form
322
-
323
- const file = document.getElementById('uploadForm');
324
-
325
357
  //Get the file blob
326
358
 
327
359
  const fileBlob = e.target.files[0];
@@ -373,34 +405,26 @@ class AreaWidget extends React.Component {
373
405
  return;
374
406
  }
375
407
 
376
- switch (fileExtension) {
377
- case 'zip':
378
- this.generateFeatureCollection(fileName, file, 'shapefile');
379
- break;
380
- case 'geojson':
381
- this.generateFeatureCollection(fileName, file, 'geojson');
382
- break;
383
- case 'csv':
384
- //this.generateFeatureCollection(
385
- // fileName,
386
- // file,
387
- // 'csv',
388
- //);
389
- reader.readAsText(fileBlob);
390
- reader.onload = () => {
391
- this.handleCsv(reader.result);
392
- };
393
- break;
394
- default:
395
- break;
408
+ if (fileExtension === 'zip' || fileExtension === 'geojson') {
409
+ const formData = new FormData();
410
+ formData.append('file', fileBlob, fileName);
411
+ this.generateFeatureCollection(
412
+ fileName,
413
+ formData,
414
+ fileExtension === 'zip' ? 'shapefile' : 'geojson',
415
+ );
416
+ } else if (fileExtension === 'csv') {
417
+ reader.readAsText(fileBlob);
418
+ reader.onload = () => {
419
+ this.handleCsv(reader.result);
420
+ };
396
421
  }
397
- // setTimeout(() => {
422
+
398
423
  e.target.value = null;
399
- // }, 2000);
400
424
  this.props.uploadFileHandler(this.state.infoPopupType);
401
425
  };
402
426
 
403
- generateFeatureCollection(fileName, file, inputFormat) {
427
+ generateFeatureCollection(fileName, formData, inputFormat) {
404
428
  let name = fileName.split('.');
405
429
 
406
430
  // Chrome adds c:\fakepath to the value - we need to remove it
@@ -414,12 +438,12 @@ class AreaWidget extends React.Component {
414
438
  maxRecordCount: 1000,
415
439
  enforceInputFileSizeLimit: true,
416
440
  enforceOutputJsonSizeLimit: true,
441
+ // generalize features to 10 meters for better performance
442
+ generalize: true,
443
+ maxAllowableOffset: 10,
444
+ reducePrecision: true,
445
+ numberOfDigitsAfterDecimal: 0,
417
446
  };
418
- // generalize features to 10 meters for better performance
419
- params.generalize = true;
420
- params.maxAllowableOffset = 10;
421
- params.reducePrecision = true;
422
- params.numberOfDigitsAfterDecimal = 0;
423
447
 
424
448
  const myContent = {
425
449
  filetype: inputFormat,
@@ -429,7 +453,7 @@ class AreaWidget extends React.Component {
429
453
  // use the REST generate operation to generate a feature collection from the zipped shapefile
430
454
  request(this.uploadPortal + '/sharing/rest/content/features/generate', {
431
455
  query: myContent,
432
- body: file,
456
+ body: formData,
433
457
  responseType: 'json',
434
458
  })
435
459
  .then((response) => {
@@ -459,8 +483,6 @@ class AreaWidget extends React.Component {
459
483
 
460
484
  //Create a feature layer from the feature collection
461
485
  this.addFeatureCollectionToMap(featureCollection);
462
- } else {
463
- //console.error('Unexpected response structure:', response);
464
486
  }
465
487
  })
466
488
  .catch((error) => {
@@ -505,10 +527,9 @@ class AreaWidget extends React.Component {
505
527
  const layers = featureCollection.layers.map((layer) => {
506
528
  const graphics = layer.featureSet.features.map((feature) => {
507
529
  const polygonSymbol = {
508
- type: 'simple-fill', // autocasts as new SimpleFillSymbol()
530
+ type: 'simple-fill',
509
531
  color: [234, 168, 72, 0.8],
510
532
  outline: {
511
- // autocasts as new SimpleLineSymbol()
512
533
  color: '#000000',
513
534
  width: 0.1,
514
535
  },
@@ -557,9 +578,7 @@ class AreaWidget extends React.Component {
557
578
  //Add uploaded layer to the map and zoom to the extent
558
579
 
559
580
  this.props.view.graphics.addMany(sourceGraphics);
560
- this.props.view.goTo(sourceGraphics).catch((error) => {
561
- //console.error('From addFeatureCollectionToMap function', error);
562
- });
581
+ this.props.view.goTo(sourceGraphics).catch((error) => {});
563
582
 
564
583
  //Create a spatial reference object for the extent
565
584
 
@@ -633,13 +652,12 @@ class AreaWidget extends React.Component {
633
652
  // Set a simple renderer on the layer
634
653
 
635
654
  csvLayer.renderer = {
636
- type: 'simple', // autocasts as new SimpleRenderer()
655
+ type: 'simple',
637
656
  symbol: {
638
- type: 'simple-marker', // autocasts as new SimpleMarkerSymbol()
657
+ type: 'simple-marker',
639
658
  size: 6,
640
659
  color: 'black',
641
660
  outline: {
642
- // autocasts as new SimpleLineSymbol()
643
661
  width: 0.5,
644
662
  color: 'white',
645
663
  },
@@ -726,10 +744,9 @@ class AreaWidget extends React.Component {
726
744
  //Draw a graphic using the polyId polygon data as the geometry
727
745
 
728
746
  const polygonSymbol = {
729
- type: 'simple-fill', // autocasts as new SimpleFillSymbol()
747
+ type: 'simple-fill',
730
748
  color: [234, 168, 72, 0.8],
731
749
  outline: {
732
- // autocasts as new SimpleLineSymbol()
733
750
  color: '#000000',
734
751
  width: 0.1,
735
752
  },
@@ -751,13 +768,10 @@ class AreaWidget extends React.Component {
751
768
  //Add the polygon graphic to the map
752
769
 
753
770
  this.props.view.graphics.add(polygonGraphic);
754
- //this.props.map.add(this.fileUploadLayer);
755
771
 
756
772
  //Refresh the map view
757
773
 
758
- this.props.view.goTo(polygonGraphic).catch((error) => {
759
- //console.error('From handleCsv function', error);
760
- });
774
+ this.props.view.goTo(polygonGraphic).catch((error) => {});
761
775
 
762
776
  //Send the area to the parent component
763
777
 
@@ -792,7 +806,6 @@ class AreaWidget extends React.Component {
792
806
  infoPopupType: 'fileFormat',
793
807
  });
794
808
  this.props.uploadFileHandler(false);
795
- //console.error('Error: ', error);
796
809
  }
797
810
  }
798
811
 
@@ -895,9 +908,9 @@ class AreaWidget extends React.Component {
895
908
  );
896
909
  popupToUpdate.style.display = 'block';
897
910
  popupToUpdate.innerHTML =
898
- '<div class="drawRectanglePopup-content">' +
899
- '<span class="drawRectanglePopup-icon"><span class="esri-icon-cursor-marquee"></span></span>' +
900
- '<div class="drawRectanglePopup-text">' +
911
+ '<div className="drawRectanglePopup-content">' +
912
+ '<span className="drawRectanglePopup-icon"><span className="esri-icon-cursor-marquee"></span></span>' +
913
+ '<div className="drawRectanglePopup-text">' +
901
914
  '<a style="color: black; cursor: pointer" href="https://land.copernicus.eu/en/how-to-guides/how-to-download-spatial-data/how-to-download-m2m" target="_blank" rel="noreferrer">To download the full dataset consult the "How to download M2M" How to guide.</a>' +
902
915
  '</div>' +
903
916
  '</div>';
@@ -941,9 +954,9 @@ class AreaWidget extends React.Component {
941
954
  );
942
955
  popupToUpdate.style.display = 'block';
943
956
  popupToUpdate.innerHTML =
944
- '<div class="drawRectanglePopup-content">' +
945
- '<span class="drawRectanglePopup-icon"><span class="esri-icon-cursor-marquee"></span></span>' +
946
- '<div class="drawRectanglePopup-text">' +
957
+ '<div className="drawRectanglePopup-content">' +
958
+ '<span className="drawRectanglePopup-icon"><span className="esri-icon-cursor-marquee"></span></span>' +
959
+ '<div className="drawRectanglePopup-text">' +
947
960
  '<a style="color: black; cursor: pointer" href="https://land.copernicus.eu/en/how-to-guides/how-to-download-spatial-data/how-to-download-m2m" target="_blank" rel="noreferrer">To download the full dataset consult the "How to download M2M" How to guide.</a>' +
948
961
  '</div>' +
949
962
  '</div>';
@@ -987,9 +1000,9 @@ class AreaWidget extends React.Component {
987
1000
  if (this.props.download) {
988
1001
  let popup = document.querySelector('.drawRectanglePopup-block');
989
1002
  popup.innerHTML =
990
- '<div class="drawRectanglePopup-content">' +
991
- '<span class="drawRectanglePopup-icon"><span class="esri-icon-cursor-marquee"></span></span>' +
992
- '<div class="drawRectanglePopup-text">Select or draw an area of interest in the map to continue</div>' +
1003
+ '<div className="drawRectanglePopup-content">' +
1004
+ '<span className="drawRectanglePopup-icon"><span className="esri-icon-cursor-marquee"></span></span>' +
1005
+ '<div className="drawRectanglePopup-text">Select or draw an area of interest in the map to continue</div>' +
993
1006
  '</div>';
994
1007
  popup.style.display = 'block';
995
1008
  }
@@ -1143,9 +1156,9 @@ class AreaWidget extends React.Component {
1143
1156
  var popup = document.createElement('div');
1144
1157
  popup.className = 'drawRectanglePopup-block';
1145
1158
  popup.innerHTML =
1146
- '<div class="drawRectanglePopup-content">' +
1147
- '<span class="drawRectanglePopup-icon"><span class="esri-icon-cursor-marquee"></span></span>' +
1148
- '<div class="drawRectanglePopup-text">Select or draw an area of interest in the map to continue</div>' +
1159
+ '<div className="drawRectanglePopup-content">' +
1160
+ '<span className="drawRectanglePopup-icon"><span className="esri-icon-cursor-marquee"></span></span>' +
1161
+ '<div className="drawRectanglePopup-text">Select or draw an area of interest in the map to continue</div>' +
1149
1162
  '</div>';
1150
1163
  this.props.download && this.props.view.ui.add(popup, 'top-right');
1151
1164
  });
@@ -1373,7 +1386,7 @@ class AreaWidget extends React.Component {
1373
1386
  />
1374
1387
  <button
1375
1388
  aria-label="Search"
1376
- class="esri-button area-searchbutton"
1389
+ className="esri-button area-searchbutton"
1377
1390
  onClick={this.areaSearch.bind(this)}
1378
1391
  onKeyDown={(e) => {
1379
1392
  if (
@@ -1388,7 +1401,7 @@ class AreaWidget extends React.Component {
1388
1401
  }
1389
1402
  }}
1390
1403
  >
1391
- <span class="ccl-icon-zoom"></span>
1404
+ <span className="ccl-icon-zoom"></span>
1392
1405
  </button>
1393
1406
  <div className="no-result-message">No result found</div>
1394
1407
  </div>
@@ -1435,7 +1448,7 @@ class AreaWidget extends React.Component {
1435
1448
  </div>
1436
1449
  <div className="ccl-form">
1437
1450
  <form
1438
- enctype="multipart/form-data"
1451
+ encType="multipart/form-data"
1439
1452
  method="post"
1440
1453
  id="uploadForm"
1441
1454
  >
@@ -3060,15 +3060,15 @@ class MenuWidget extends React.Component {
3060
3060
 
3061
3061
  // Create node
3062
3062
  let template = `
3063
- <div class="esri-legend__layer">
3064
- <div class="esri-legend__layer-table esri-legend__layer-table--size-ramp" >
3065
- <div class="esri-legend__layer-caption">
3063
+ <div className="esri-legend__layer">
3064
+ <div className="esri-legend__layer-table esri-legend__layer-table--size-ramp" >
3065
+ <div className="esri-legend__layer-caption">
3066
3066
  ${title}
3067
3067
  </div>
3068
- <div class="esri-legend__layer-body">
3069
- <div class="esri-legend__layer-row">
3070
- <div class="esri-legend__layer-cell esri-legend__layer-cell--symbols" >
3071
- <div class="esri-legend__symbol">
3068
+ <div className="esri-legend__layer-body">
3069
+ <div className="esri-legend__layer-row">
3070
+ <div className="esri-legend__layer-cell esri-legend__layer-cell--symbols" >
3071
+ <div className="esri-legend__symbol">
3072
3072
  <img crossorigin="anonymous"
3073
3073
  alt=""
3074
3074
  src="${imageURL}"
@@ -3077,7 +3077,7 @@ class MenuWidget extends React.Component {
3077
3077
  </div>
3078
3078
  </div>
3079
3079
  <div
3080
- class="esri-legend__layer-cell esri-legend__layer-cell--info"
3080
+ className="esri-legend__layer-cell esri-legend__layer-cell--info"
3081
3081
  ></div>
3082
3082
  </div>
3083
3083
  </div>
@@ -3813,6 +3813,7 @@ class MenuWidget extends React.Component {
3813
3813
  <Popup
3814
3814
  trigger={<FontAwesomeIcon icon={this.visibleLayers[elem.id]} />}
3815
3815
  content={
3816
+ this.visibleLayers[elem.id] &&
3816
3817
  this.visibleLayers[elem.id][1] === 'eye'
3817
3818
  ? 'Hide layer'
3818
3819
  : 'Show layer'
@@ -3998,7 +3999,10 @@ class MenuWidget extends React.Component {
3998
3999
  }
3999
4000
  if (elem.id === layerId) {
4000
4001
  this.timeLayers[elem.id] = ['fas', 'stop'];
4001
- if (this.visibleLayers[elem.id][1] === 'eye-slash') {
4002
+ if (
4003
+ this.visibleLayers[elem.id] &&
4004
+ this.visibleLayers[elem.id][1] === 'eye-slash'
4005
+ ) {
4002
4006
  this.layers[elem.id].visible = true;
4003
4007
  this.visibleLayers[elem.id] = ['fas', 'eye'];
4004
4008
  }
@@ -5518,11 +5522,11 @@ class MenuWidget extends React.Component {
5518
5522
  >
5519
5523
  <div className="search-panel">
5520
5524
  <div className="menu-searchpanel">
5521
- <div class="search-input menu-search-input">
5525
+ <div className="search-input menu-search-input">
5522
5526
  <input
5523
5527
  type="text"
5524
5528
  id="menu-searchtext"
5525
- maxlength="200"
5529
+ maxLength="200"
5526
5530
  placeholder="Search products and datasets"
5527
5531
  onChange={() => this.openClearButton()}
5528
5532
  onKeyDown={(e) => {
@@ -5531,9 +5535,9 @@ class MenuWidget extends React.Component {
5531
5535
  }
5532
5536
  }}
5533
5537
  />
5534
- <div class="search-input-actions">
5538
+ <div className="search-input-actions">
5535
5539
  <button
5536
- class="ui basic icon button search-input-clear-icon-button clearsearch"
5540
+ className="ui basic icon button search-input-clear-icon-button clearsearch"
5537
5541
  onClick={() => this.clearMenuText()}
5538
5542
  onKeyDown={(e) => {
5539
5543
  if (
@@ -5551,10 +5555,10 @@ class MenuWidget extends React.Component {
5551
5555
  <svg
5552
5556
  xmlns="http://www.w3.org/2000/svg"
5553
5557
  viewBox="0 0 26 26"
5554
- class="icon"
5558
+ className="icon"
5555
5559
  >
5556
5560
  <path
5557
- fill-rule="evenodd"
5561
+ fillRule="evenodd"
5558
5562
  d="M27.899 9.515L26.485 8.101 18 16.586 9.514 8.101 8.1 9.515 16.586 18 8.1 26.486 9.514 27.9 18 19.414 26.485 27.9 27.899 26.486 19.414 18z"
5559
5563
  ></path>
5560
5564
  </svg>
@@ -5562,7 +5566,7 @@ class MenuWidget extends React.Component {
5562
5566
  </div>
5563
5567
  <button
5564
5568
  aria-label="Search"
5565
- class="button menu-search-button"
5569
+ className="button menu-search-button"
5566
5570
  onClick={() => this.menuSearch()}
5567
5571
  onKeyDown={(e) => {
5568
5572
  if (
@@ -5577,22 +5581,22 @@ class MenuWidget extends React.Component {
5577
5581
  }
5578
5582
  }}
5579
5583
  >
5580
- <span class="ccl-icon-zoom search-menu-icon"></span>
5584
+ <span className="ccl-icon-zoom search-menu-icon"></span>
5581
5585
  </button>
5582
5586
  </div>
5583
- <div class="filters-element filter-logo filters-header">
5584
- <div class="filters-title">
5587
+ <div className="filters-element filter-logo filters-header">
5588
+ <div className="filters-title">
5585
5589
  <svg
5586
5590
  xmlns="http://www.w3.org/2000/svg"
5587
5591
  viewBox="0 0 36 36"
5588
- class="icon ui"
5592
+ className="icon ui"
5589
5593
  >
5590
5594
  <path
5591
- fill-rule="evenodd"
5595
+ fillRule="evenodd"
5592
5596
  d="M5.0916,5.0002 L14.9996,19.3132 L14.9996,34.0002 L20.9996,29.5002 L20.9996,19.3132 L30.9086,5.0002 L5.0916,5.0002 Z M17.0006,18.6872 L8.9086,7.0002 L27.0916,7.0002 L19.0006,18.6872 L19.0006,28.5002 L17.0006,30.0002 L17.0006,18.6872 Z"
5593
5597
  ></path>
5594
5598
  </svg>
5595
- <span class="filters-title-bold">Filters</span>
5599
+ <span className="filters-title-bold">Filters</span>
5596
5600
  <div
5597
5601
  className="clear-filters"
5598
5602
  tabIndex="0"
@@ -5645,7 +5649,7 @@ class MenuWidget extends React.Component {
5645
5649
  Component
5646
5650
  <select
5647
5651
  id="select-component"
5648
- class="esri-select filter-select"
5652
+ className="esri-select filter-select"
5649
5653
  onBlur={() => {}}
5650
5654
  onChange={() => {
5651
5655
  this.loadProductFilters();
@@ -5657,7 +5661,7 @@ class MenuWidget extends React.Component {
5657
5661
  Product groups
5658
5662
  <select
5659
5663
  id="select-product"
5660
- class="esri-select filter-select"
5664
+ className="esri-select filter-select"
5661
5665
  onBlur={() => {}}
5662
5666
  onChange={() => {
5663
5667
  this.loadFamilyFilters();
@@ -5669,7 +5673,7 @@ class MenuWidget extends React.Component {
5669
5673
  Product sub-group
5670
5674
  <select
5671
5675
  id="select-family"
5672
- class="esri-select filter-select"
5676
+ className="esri-select filter-select"
5673
5677
  onBlur={() => {}}
5674
5678
  onChange={() => {
5675
5679
  this.menuSearch();