qwc2 2025.10.14 → 2025.10.16

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.
Files changed (38) hide show
  1. package/components/IdentifyViewer.js +404 -314
  2. package/components/MapSelection.js +1 -1
  3. package/components/map3d/Map3D.js +1 -1
  4. package/components/style/App.css +4 -0
  5. package/components/style/AttributeTableWidget.css +1 -0
  6. package/components/style/IdentifyViewer.css +51 -80
  7. package/components/widgets/NavBar.js +2 -2
  8. package/components/widgets/style/NavBar.css +0 -1
  9. package/icons/eye-slash.svg +138 -0
  10. package/icons/pin.svg +41 -0
  11. package/icons/unpin.svg +41 -0
  12. package/package.json +1 -1
  13. package/plugins/HeightProfile.js +7 -2
  14. package/plugins/Identify.js +5 -4
  15. package/static/translations/bg-BG.json +3 -1
  16. package/static/translations/ca-ES.json +3 -1
  17. package/static/translations/cs-CZ.json +2 -0
  18. package/static/translations/de-CH.json +4 -2
  19. package/static/translations/de-DE.json +4 -2
  20. package/static/translations/en-US.json +3 -1
  21. package/static/translations/es-ES.json +2 -0
  22. package/static/translations/fi-FI.json +2 -0
  23. package/static/translations/fr-FR.json +3 -1
  24. package/static/translations/hu-HU.json +2 -0
  25. package/static/translations/it-IT.json +3 -1
  26. package/static/translations/ja-JP.json +3 -1
  27. package/static/translations/nl-NL.json +2 -0
  28. package/static/translations/no-NO.json +2 -0
  29. package/static/translations/pl-PL.json +2 -0
  30. package/static/translations/pt-BR.json +2 -0
  31. package/static/translations/pt-PT.json +2 -0
  32. package/static/translations/ro-RO.json +2 -0
  33. package/static/translations/ru-RU.json +2 -0
  34. package/static/translations/sv-SE.json +2 -0
  35. package/static/translations/tr-TR.json +2 -0
  36. package/static/translations/tsconfig.json +2 -0
  37. package/static/translations/uk-UA.json +2 -0
  38. package/utils/MiscUtils.js +53 -0
@@ -52,9 +52,10 @@ import CoordinatesUtils from '../utils/CoordinatesUtils';
52
52
  import LayerUtils from '../utils/LayerUtils';
53
53
  import LocaleUtils from '../utils/LocaleUtils';
54
54
  import MapUtils from '../utils/MapUtils';
55
- import MiscUtils from '../utils/MiscUtils';
55
+ import MiscUtils, { ToggleSet } from '../utils/MiscUtils';
56
56
  import VectorLayerUtils from '../utils/VectorLayerUtils';
57
57
  import Icon from './Icon';
58
+ import NavBar from './widgets/NavBar';
58
59
  import Spinner from './widgets/Spinner';
59
60
  import './style/IdentifyViewer.css';
60
61
  var EXCLUDE_PROPS = ['featurereport', 'displayfield', 'layername', 'layertitle', 'layerinfo', 'attribnames', 'clickPos', 'displayname', 'bbox'];
@@ -321,46 +322,52 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
321
322
  _classCallCheck(this, IdentifyViewer);
322
323
  _this = _callSuper(this, IdentifyViewer, [props]);
323
324
  _defineProperty(_this, "state", {
324
- expanded: {},
325
- expandedResults: {},
325
+ collapsedLayers: new ToggleSet(),
326
+ expandedResults: new ToggleSet(),
327
+ pinnedResults: new ToggleSet(),
326
328
  resultTree: {},
327
329
  reports: {},
328
330
  currentResult: null,
329
- currentLayer: null,
331
+ settingsMenu: false,
330
332
  exportFormat: 'geojson',
331
333
  selectedAggregatedReport: "",
332
334
  generatingReport: false,
333
- selectedLayer: ''
335
+ selectedLayer: '',
336
+ compareEnabled: false,
337
+ currentPage: 0
338
+ });
339
+ _defineProperty(_this, "getCurrentResultFeature", function () {
340
+ var _this$state$resultTre, _this$state$resultTre2, _this$state$resultTre3, _this$state$currentRe;
341
+ return (_this$state$resultTre = (_this$state$resultTre2 = _this.state.resultTree[(_this$state$currentRe = _this.state.currentResult) === null || _this$state$currentRe === void 0 ? void 0 : _this$state$currentRe.layerid]) === null || _this$state$resultTre2 === void 0 || (_this$state$resultTre3 = _this$state$resultTre2.find) === null || _this$state$resultTre3 === void 0 ? void 0 : _this$state$resultTre3.call(_this$state$resultTre2, function (feature) {
342
+ return feature.id === _this.state.currentResult.featureid;
343
+ })) !== null && _this$state$resultTre !== void 0 ? _this$state$resultTre : null;
334
344
  });
335
345
  _defineProperty(_this, "updateResultTree", function () {
336
346
  var layers = Object.keys(_this.props.identifyResults);
337
347
  var currentResult = null;
338
- var currentLayer = null;
339
348
  if (layers.length === 1 && _this.props.identifyResults[layers[0]].length === 1) {
340
- currentLayer = layers[0];
341
- currentResult = _this.props.identifyResults[layers[0]][0];
349
+ currentResult = {
350
+ layerid: layers[0],
351
+ featureid: _this.props.identifyResults[layers[0]][0].id
352
+ };
342
353
  }
343
354
  _this.setState({
344
355
  resultTree: clone(_this.props.identifyResults),
345
356
  currentResult: currentResult,
346
- currentLayer: currentLayer,
347
357
  reports: LayerUtils.collectFeatureReports(_this.props.layers)
348
358
  });
349
359
  });
350
- _defineProperty(_this, "setHighlightedResults", function (results, resultTree) {
351
- if (!results && _this.props.highlightAllResults) {
352
- var selectedLayer = _this.state.selectedLayer || '';
353
- results = Object.keys(resultTree).reduce(function (res, layer) {
354
- var layerData = resultTree[selectedLayer || layer];
355
- return res.concat(layerData.map(function (result) {
356
- return _objectSpread(_objectSpread({}, result), {}, {
357
- id: "".concat(selectedLayer || layer, ".").concat(result.id)
358
- });
359
- }));
360
- }, []);
360
+ _defineProperty(_this, "setHighlightedFeatures", function (features) {
361
+ var paginated = _this.props.resultDisplayMode === 'paginated';
362
+ if (!features && (_this.props.highlightAllResults || paginated)) {
363
+ var resultTree = _this.state.selectedLayer !== '' ? _defineProperty({}, _this.state.selectedLayer, _this.state.resultTree[_this.state.selectedLayer]) : _this.state.resultTree;
364
+ features = Object.values(resultTree).flat();
365
+ if (paginated) {
366
+ features = [features[_this.state.currentPage]];
367
+ }
361
368
  }
362
- results = (results || []).filter(function (result) {
363
- return result.type.toLowerCase() === "feature";
369
+ features = (features || []).filter(function (feature) {
370
+ return feature.type.toLowerCase() === "feature";
364
371
  }).map(function (feature) {
365
372
  var newFeature = _objectSpread(_objectSpread({}, feature), {}, {
366
373
  properties: {}
@@ -370,79 +377,50 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
370
377
  delete newFeature.styleOptions;
371
378
  return newFeature;
372
379
  });
373
- if (!isEmpty(results)) {
380
+ if (!isEmpty(features)) {
374
381
  var layer = {
375
382
  id: "__identifyviewerhighlight",
376
383
  role: LayerRole.SELECTION
377
384
  };
378
- _this.props.addLayerFeatures(layer, results, true);
385
+ _this.props.addLayerFeatures(layer, features, true);
379
386
  } else {
380
387
  _this.props.removeLayer("__identifyviewerhighlight");
381
388
  }
382
389
  });
383
- _defineProperty(_this, "getExpandedClass", function (path, deflt) {
384
- var expanded = _this.state.expanded[path] !== undefined ? _this.state.expanded[path] : deflt;
385
- return expanded ? "identify-layer-expandable identify-layer-expanded" : "identify-layer-expandable";
386
- });
387
- _defineProperty(_this, "toggleExpanded", function (path, deflt) {
388
- var newstate = _this.state.expanded[path] !== undefined ? !_this.state.expanded[path] : !deflt;
389
- var diff = {};
390
- diff[path] = newstate;
391
- if (_this.state.currentLayer === path && !newstate) {
392
- _this.setState(function (state) {
393
- return _objectSpread(_objectSpread({}, state), {}, {
394
- expanded: _objectSpread(_objectSpread({}, state.expanded), diff),
395
- currentResult: null,
396
- currentLayer: null
397
- });
398
- });
399
- } else {
400
- _this.setState(function (state) {
401
- return _objectSpread(_objectSpread({}, state), {}, {
402
- expanded: _objectSpread(_objectSpread({}, state.expanded), diff)
403
- });
404
- });
405
- }
406
- });
407
- _defineProperty(_this, "setCurrentResult", function (layer, result) {
408
- if (_this.state.currentResult === result) {
409
- _this.setState({
410
- currentResult: null,
411
- currentLayer: null
412
- });
413
- } else {
414
- _this.setState({
415
- currentResult: result,
416
- currentLayer: layer
417
- });
418
- _this.scrollIntoView = true;
419
- }
420
- });
421
- _defineProperty(_this, "removeResultLayer", function (layer) {
390
+ _defineProperty(_this, "removeResultLayer", function (layerid) {
422
391
  _this.setState(function (state) {
392
+ var _state$currentResult;
423
393
  var newResultTree = _objectSpread({}, state.resultTree);
424
- delete newResultTree[layer];
425
- _this.setState({
394
+ delete newResultTree[layerid];
395
+ return {
426
396
  resultTree: newResultTree,
427
- currentResult: state.currentLayer === layer ? null : state.currentResult,
428
- currentLayer: state.currentLayer === layer ? null : state.currentLayer
429
- });
397
+ collapsedLayers: state.collapsedLayers["delete"](layerid),
398
+ currentResult: ((_state$currentResult = state.currentResult) === null || _state$currentResult === void 0 ? void 0 : _state$currentResult.layerid) === layerid ? null : state.currentResult
399
+ };
430
400
  });
431
401
  });
432
- _defineProperty(_this, "removeResult", function (layer, result) {
402
+ _defineProperty(_this, "removeResult", function (layerid, feature) {
433
403
  _this.setState(function (state) {
404
+ var _state$currentResult2;
434
405
  var newResultTree = _objectSpread({}, state.resultTree);
435
- newResultTree[layer] = state.resultTree[layer].filter(function (item) {
436
- return item !== result;
406
+ var collapsedLayers = state.collapsedLayers;
407
+ newResultTree[layerid] = state.resultTree[layerid].filter(function (item) {
408
+ return item !== feature;
437
409
  });
438
- if (isEmpty(newResultTree[layer])) {
439
- delete newResultTree[layer];
410
+ if (isEmpty(newResultTree[layerid])) {
411
+ delete newResultTree[layerid];
412
+ collapsedLayers["delete"](layerid);
440
413
  }
441
- var selectedLayer = isEmpty(newResultTree[layer]) ? '' : state.selectedLayer;
414
+ var selectedLayer = isEmpty(newResultTree[layerid]) ? '' : state.selectedLayer;
415
+ var pinnedResults = state.pinnedResults["delete"](layerid + "$" + feature.id);
442
416
  return {
443
417
  resultTree: newResultTree,
444
- currentResult: state.currentResult === result ? null : state.currentResult,
445
- selectedLayer: selectedLayer
418
+ currentResult: ((_state$currentResult2 = state.currentResult) === null || _state$currentResult2 === void 0 ? void 0 : _state$currentResult2.featureid) === feature.id ? null : state.currentResult,
419
+ selectedLayer: selectedLayer,
420
+ pinnedResults: pinnedResults,
421
+ expandedResults: state.expandedResults["delete"](layerid + "$" + feature.id),
422
+ collapsedLayers: collapsedLayers,
423
+ compareEnabled: state.compareEnabled && pinnedResults.size > 1
446
424
  };
447
425
  });
448
426
  });
@@ -469,10 +447,10 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
469
447
  });
470
448
  if (exporter) {
471
449
  if (!_this.props.exportGeometry) {
472
- json = Object.entries(json).reduce(function (res, _ref13) {
473
- var _ref14 = _slicedToArray(_ref13, 2),
474
- layerId = _ref14[0],
475
- features = _ref14[1];
450
+ json = Object.entries(json).reduce(function (res, _ref14) {
451
+ var _ref15 = _slicedToArray(_ref14, 2),
452
+ layerId = _ref15[0],
453
+ features = _ref15[1];
476
454
  return _objectSpread(_objectSpread({}, res), {}, _defineProperty({}, layerId, features.map(function (feature) {
477
455
  return omit(feature, ['geometry']);
478
456
  })));
@@ -489,138 +467,179 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
489
467
  });
490
468
  }
491
469
  });
492
- _defineProperty(_this, "renderLayer", function (layer) {
493
- var results = _this.state.resultTree[layer];
494
- if (results.length === 0) {
495
- return null;
496
- }
470
+ _defineProperty(_this, "renderResultTree", function () {
471
+ var exportEnabled = _this.props.enableExport === true || !isEmpty(_this.props.enableExport);
497
472
  return /*#__PURE__*/React.createElement("div", {
498
- className: _this.getExpandedClass(layer, true),
499
- key: layer
500
- }, /*#__PURE__*/React.createElement("div", {
501
- className: "identify-result-entry",
502
- onMouseEnter: function onMouseEnter() {
503
- return _this.setHighlightedResults(results, _this.state.resultTree);
473
+ className: "identify-results-tree",
474
+ key: "results-container",
475
+ ref: function ref(el) {
476
+ _this.resultsTreeRef = el;
504
477
  },
505
- onMouseLeave: function onMouseLeave() {
506
- return _this.setHighlightedResults(_this.state.currentResult === null ? null : [_this.state.currentResult], _this.state.resultTree);
507
- }
508
- }, /*#__PURE__*/React.createElement("span", {
509
- className: "clickable",
510
- onClick: function onClick() {
511
- return _this.toggleExpanded(layer, true);
478
+ style: {
479
+ maxHeight: _this.state.currentResult ? '10em' : 'initial'
512
480
  }
513
- }, /*#__PURE__*/React.createElement("b", null, results[0].layertitle)), /*#__PURE__*/React.createElement(Icon, {
514
- className: "identify-remove-result",
515
- icon: "minus-sign",
516
- onClick: function onClick() {
517
- return _this.removeResultLayer(layer);
518
- }
519
- }), _this.props.enableExport === true || !isEmpty(_this.props.enableExport) ? /*#__PURE__*/React.createElement(Icon, {
520
- className: "identify-export-result",
521
- icon: "export",
522
- onClick: function onClick() {
523
- return _this.exportResultLayer(layer);
481
+ }, Object.entries(_this.state.resultTree).map(function (_ref16) {
482
+ var _ref17 = _slicedToArray(_ref16, 2),
483
+ layerid = _ref17[0],
484
+ features = _ref17[1];
485
+ if (features.length === 0) {
486
+ return null;
524
487
  }
525
- }) : null), /*#__PURE__*/React.createElement("div", {
526
- className: "identify-layer-entries"
527
- }, results.map(function (result) {
528
- return _this.renderResult(layer, result);
529
- })));
488
+ return /*#__PURE__*/React.createElement("div", {
489
+ key: layerid
490
+ }, /*#__PURE__*/React.createElement("div", {
491
+ className: "identify-results-tree-entry",
492
+ onMouseEnter: function onMouseEnter() {
493
+ return _this.setHighlightedFeatures(features);
494
+ },
495
+ onMouseLeave: function onMouseLeave() {
496
+ return _this.setHighlightedFeatures(_this.state.currentResult ? [_this.getCurrentResultFeature()] : null);
497
+ }
498
+ }, /*#__PURE__*/React.createElement("span", {
499
+ onClick: function onClick() {
500
+ return _this.toggleExpanded(layerid);
501
+ }
502
+ }, /*#__PURE__*/React.createElement(Icon, {
503
+ icon: _this.state.collapsedLayers.has(layerid) ? "expand" : "collapse"
504
+ }), " ", features[0].layertitle), exportEnabled ? /*#__PURE__*/React.createElement(Icon, {
505
+ className: "identify-export-result",
506
+ icon: "export",
507
+ onClick: function onClick() {
508
+ return _this.exportResultLayer(layerid);
509
+ }
510
+ }) : null, /*#__PURE__*/React.createElement(Icon, {
511
+ className: "identify-remove-result",
512
+ icon: "trash",
513
+ onClick: function onClick() {
514
+ return _this.removeResultLayer(layerid);
515
+ }
516
+ })), _this.state.collapsedLayers.has(layerid) ? null : /*#__PURE__*/React.createElement("div", {
517
+ className: "identify-results-tree-entries"
518
+ }, features.map(function (feature) {
519
+ var _this$state$currentRe2, _this$state$currentRe3;
520
+ // this.renderResult(layername, result)
521
+ var ref = _this.state.currentResult === feature && _this.scrollIntoView ? function (el) {
522
+ _this.currentResultElRef = el;
523
+ } : null;
524
+ var active = ((_this$state$currentRe2 = _this.state.currentResult) === null || _this$state$currentRe2 === void 0 ? void 0 : _this$state$currentRe2.featureid) === feature.id && ((_this$state$currentRe3 = _this.state.currentResult) === null || _this$state$currentRe3 === void 0 ? void 0 : _this$state$currentRe3.layerid) === layerid;
525
+ return /*#__PURE__*/React.createElement("div", {
526
+ className: "identify-results-tree-entry",
527
+ key: feature.id,
528
+ onMouseEnter: function onMouseEnter() {
529
+ return _this.setHighlightedFeatures([feature]);
530
+ },
531
+ onMouseLeave: function onMouseLeave() {
532
+ return _this.setHighlightedFeatures(_this.state.currentResult ? [_this.getCurrentResultFeature()] : null);
533
+ }
534
+ }, /*#__PURE__*/React.createElement("span", {
535
+ className: active ? "identify-results-tree-entry-active" : "",
536
+ onClick: function onClick() {
537
+ return _this.setCurrentResult(layerid, feature.id);
538
+ },
539
+ ref: ref
540
+ }, feature.displayname, _this.state.pinnedResults.has(layerid + "$" + feature.id) ? /*#__PURE__*/React.createElement(Icon, {
541
+ icon: "pin"
542
+ }) : null), exportEnabled ? /*#__PURE__*/React.createElement(Icon, {
543
+ className: "identify-export-result",
544
+ icon: "export",
545
+ onClick: function onClick() {
546
+ return _this.exportResult(layerid, feature);
547
+ }
548
+ }) : null, /*#__PURE__*/React.createElement(Icon, {
549
+ className: "identify-remove-result",
550
+ icon: "trash",
551
+ onClick: function onClick() {
552
+ return _this.removeResult(layerid, feature);
553
+ }
554
+ }));
555
+ })));
556
+ }));
530
557
  });
531
- _defineProperty(_this, "renderResult", function (layer, result) {
532
- var ref = _this.state.currentResult === result && _this.scrollIntoView ? function (el) {
533
- _this.currentResultElRef = el;
534
- } : null;
535
- return /*#__PURE__*/React.createElement("div", {
536
- className: "identify-result-entry",
537
- key: result.id,
538
- onMouseEnter: function onMouseEnter() {
539
- return _this.setHighlightedResults([result], _this.state.resultTree);
540
- },
541
- onMouseLeave: function onMouseLeave() {
542
- return _this.setHighlightedResults(_this.state.currentResult === null ? null : [_this.state.currentResult], _this.state.resultTree);
543
- }
544
- }, /*#__PURE__*/React.createElement("span", {
545
- className: _this.state.currentResult === result ? "active clickable" : "clickable",
546
- onClick: function onClick() {
547
- return _this.setCurrentResult(layer, result);
548
- },
549
- ref: ref
550
- }, result.displayname), /*#__PURE__*/React.createElement(Icon, {
551
- className: "identify-remove-result",
552
- icon: "minus-sign",
553
- onClick: function onClick() {
554
- return _this.removeResult(layer, result);
555
- }
556
- }), _this.props.enableExport === true || !isEmpty(_this.props.enableExport) ? /*#__PURE__*/React.createElement(Icon, {
557
- className: "identify-export-result",
558
- icon: "export",
559
- onClick: function onClick() {
560
- return _this.exportResult(layer, result);
561
- }
562
- }) : null);
558
+ _defineProperty(_this, "toggleExpanded", function (layerid) {
559
+ _this.setState(function (state) {
560
+ var _state$currentResult3;
561
+ return {
562
+ collapsedLayers: state.collapsedLayers.toggle(layerid),
563
+ currentResult: ((_state$currentResult3 = state.currentResult) === null || _state$currentResult3 === void 0 ? void 0 : _state$currentResult3.layerid) === layerid ? null : state.currentResult
564
+ };
565
+ });
566
+ });
567
+ _defineProperty(_this, "setCurrentResult", function (layerid, featureid) {
568
+ var _this$state$currentRe4, _this$state$currentRe5;
569
+ if (((_this$state$currentRe4 = _this.state.currentResult) === null || _this$state$currentRe4 === void 0 ? void 0 : _this$state$currentRe4.layerid) === layerid && ((_this$state$currentRe5 = _this.state.currentResult) === null || _this$state$currentRe5 === void 0 ? void 0 : _this$state$currentRe5.featureid) === featureid) {
570
+ _this.setState({
571
+ currentResult: null
572
+ });
573
+ } else {
574
+ _this.setState({
575
+ currentResult: {
576
+ layerid: layerid,
577
+ featureid: featureid
578
+ }
579
+ });
580
+ _this.scrollIntoView = true;
581
+ }
563
582
  });
564
- _defineProperty(_this, "renderResultAttributes", function (layer, result, resultClass) {
565
- if (!result) {
583
+ _defineProperty(_this, "renderResultAttributes", function (layerid, feature, resultClass) {
584
+ if (!feature) {
566
585
  return null;
567
586
  }
568
587
  var resultbox = null;
569
588
  var extraattribs = null;
570
589
  var inlineExtaAttribs = false;
571
- var featureReports = _this.state.reports[layer] || [];
572
- if (result.featureReport) {
590
+ var featureReports = _this.state.reports[layerid] || [];
591
+ if (feature.featureReport) {
573
592
  featureReports.push({
574
- title: result.layertitle,
575
- template: result.featureReport
593
+ title: feature.layertitle,
594
+ template: feature.featureReport
576
595
  });
577
596
  }
578
- if (result.type === "text") {
597
+ if (feature.type === "text") {
579
598
  resultbox = /*#__PURE__*/React.createElement("pre", {
580
599
  className: "identify-result-box"
581
- }, result.text);
582
- } else if (result.type === "html") {
600
+ }, feature.text);
601
+ } else if (feature.type === "html") {
583
602
  resultbox = /*#__PURE__*/React.createElement("iframe", {
584
603
  className: "identify-result-box",
585
604
  onLoad: function onLoad(ev) {
586
- return _this.setIframeContent(ev.target, result.text);
605
+ return _this.setIframeContent(ev.target, feature.text);
587
606
  },
588
607
  ref: function ref(el) {
589
- return _this.pollIframe(el, result.text);
608
+ return _this.pollIframe(el, feature.text);
590
609
  }
591
610
  });
592
- } else if (result.properties.htmlContent) {
593
- if (result.properties.htmlContentInline) {
611
+ } else if (feature.properties.htmlContent) {
612
+ if (feature.properties.htmlContentInline) {
594
613
  resultbox = /*#__PURE__*/React.createElement("div", {
595
614
  className: "identify-result-box"
596
- }, _this.parsedContent(result.properties.htmlContent));
615
+ }, _this.parsedContent(feature.properties.htmlContent));
597
616
  } else {
598
617
  resultbox = /*#__PURE__*/React.createElement("iframe", {
599
618
  className: "identify-result-box",
600
619
  onLoad: function onLoad(ev) {
601
- return _this.setIframeContent(ev.target, result.properties.htmlContent);
620
+ return _this.setIframeContent(ev.target, feature.properties.htmlContent);
602
621
  },
603
622
  ref: function ref(el) {
604
- return _this.pollIframe(el, result.properties.htmlContent);
623
+ return _this.pollIframe(el, feature.properties.htmlContent);
605
624
  }
606
625
  });
607
626
  }
608
627
  } else {
609
628
  var _rows;
610
629
  inlineExtaAttribs = true;
611
- var properties = Object.keys(result.properties) || [];
630
+ var properties = Object.keys(feature.properties) || [];
612
631
  var rows = [];
613
- if (properties.length === 1 && result.properties.maptip) {
632
+ if (properties.length === 1 && feature.properties.maptip) {
614
633
  rows = properties.map(function (attrib) {
615
634
  return /*#__PURE__*/React.createElement("tr", {
616
635
  key: attrib
617
636
  }, /*#__PURE__*/React.createElement("td", {
618
637
  className: "identify-attr-value"
619
- }, _this.attribValue(result.properties[attrib], attrib, layer, result)));
638
+ }, _this.attribValue(feature.properties[attrib], attrib, layerid, feature)));
620
639
  });
621
640
  } else {
622
641
  rows = properties.map(function (attrib) {
623
- if (_this.props.theme.skipEmptyFeatureAttributes && (result.properties[attrib] === "" || result.properties[attrib] === null || result.properties[attrib] === "NULL")) {
642
+ if (_this.props.theme.skipEmptyFeatureAttributes && (feature.properties[attrib] === "" || feature.properties[attrib] === null || feature.properties[attrib] === "NULL")) {
624
643
  return null;
625
644
  }
626
645
  return /*#__PURE__*/React.createElement("tr", {
@@ -629,10 +648,10 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
629
648
  className: "identify-attr-title " + _this.props.longAttributesDisplay
630
649
  }, /*#__PURE__*/React.createElement("i", null, attrib)), /*#__PURE__*/React.createElement("td", {
631
650
  className: "identify-attr-value " + _this.props.longAttributesDisplay
632
- }, _this.attribValue(result.properties[attrib], attrib, layer, result)));
651
+ }, _this.attribValue(feature.properties[attrib], attrib, layerid, feature)));
633
652
  });
634
653
  }
635
- (_rows = rows).push.apply(_rows, _toConsumableArray(_this.computeExtraAttributes(layer, result)));
654
+ (_rows = rows).push.apply(_rows, _toConsumableArray(_this.computeExtraAttributes(layerid, feature)));
636
655
  featureReports.forEach(function (report, idx) {
637
656
  rows.push(/*#__PURE__*/React.createElement("tr", {
638
657
  key: "__featurereport" + idx
@@ -641,7 +660,7 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
641
660
  }, /*#__PURE__*/React.createElement("i", null, LocaleUtils.tr("identify.featureReport") + ": " + report.title)), /*#__PURE__*/React.createElement("td", {
642
661
  className: "identify-attr-value " + _this.props.longAttributesDisplay
643
662
  }, /*#__PURE__*/React.createElement("a", {
644
- href: _this.getFeatureReportUrl(report, result)
663
+ href: _this.getFeatureReportUrl(report, feature)
645
664
  }, LocaleUtils.tr("identify.link")))));
646
665
  });
647
666
  if (isEmpty(rows)) {
@@ -655,12 +674,12 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
655
674
  className: "attribute-list"
656
675
  }, /*#__PURE__*/React.createElement("tbody", null, rows)));
657
676
  }
658
- if (!inlineExtaAttribs && (_this.props.attributeCalculator || !isEmpty(_this.state.reports[layer]))) {
677
+ if (!inlineExtaAttribs && (_this.props.attributeCalculator || !isEmpty(_this.state.reports[layerid]))) {
659
678
  extraattribs = /*#__PURE__*/React.createElement("div", {
660
679
  className: "identify-result-box"
661
680
  }, /*#__PURE__*/React.createElement("table", {
662
681
  className: "attribute-list"
663
- }, /*#__PURE__*/React.createElement("tbody", null, _this.computeExtraAttributes(layer, result), featureReports.map(function (report, idx) {
682
+ }, /*#__PURE__*/React.createElement("tbody", null, _this.computeExtraAttributes(layerid, feature), featureReports.map(function (report, idx) {
664
683
  return /*#__PURE__*/React.createElement("tr", {
665
684
  key: "report" + idx
666
685
  }, /*#__PURE__*/React.createElement("td", {
@@ -668,26 +687,27 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
668
687
  }, /*#__PURE__*/React.createElement("i", null, LocaleUtils.tr("identify.featureReport") + ": " + report.title)), /*#__PURE__*/React.createElement("td", {
669
688
  className: "identify-attr-value " + _this.props.longAttributesDisplay
670
689
  }, /*#__PURE__*/React.createElement("a", {
671
- href: _this.getFeatureReportUrl(report, result),
690
+ href: _this.getFeatureReportUrl(report, feature),
672
691
  rel: "noreferrer",
673
692
  target: "_blank"
674
693
  }, LocaleUtils.tr("identify.link"))));
675
694
  }))));
676
695
  }
677
696
  var zoomToFeatureButton = null;
678
- if (result.bbox && result.crs) {
697
+ if (feature.bbox && feature.crs) {
679
698
  zoomToFeatureButton = /*#__PURE__*/React.createElement(Icon, {
680
699
  icon: "zoom",
681
700
  onClick: function onClick() {
682
- return _this.zoomToResult(result);
701
+ return _this.zoomToResult(feature);
683
702
  }
684
703
  });
685
704
  }
686
- var key = result + ":" + result.id;
687
- var expanded = _this.state.expandedResults[key];
705
+ var key = layerid + "$" + feature.id;
706
+ var expanded = _this.state.expandedResults.has(key);
707
+ var pinned = _this.state.pinnedResults.has(key);
688
708
  return /*#__PURE__*/React.createElement("div", {
689
709
  className: resultClass,
690
- key: "results-attributes"
710
+ key: key
691
711
  }, /*#__PURE__*/React.createElement("div", {
692
712
  className: "identify-result-title"
693
713
  }, _this.props.collapsible ? /*#__PURE__*/React.createElement(Icon, {
@@ -695,24 +715,167 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
695
715
  onClick: function onClick() {
696
716
  return _this.setState(function (state) {
697
717
  return {
698
- expandedResults: _objectSpread(_objectSpread({}, state.expandedResults), {}, _defineProperty({}, key, !expanded))
718
+ expandedResults: state.expandedResults.toggle(key)
699
719
  };
700
720
  });
701
721
  }
702
- }) : null, /*#__PURE__*/React.createElement("span", null, (_this.props.showLayerTitles ? result.layertitle + ": " : "") + result.displayname), zoomToFeatureButton, /*#__PURE__*/React.createElement(Icon, {
722
+ }) : null, _this.props.enableCompare ? /*#__PURE__*/React.createElement(Icon, {
723
+ icon: pinned ? "unpin" : "pin",
724
+ onClick: function onClick() {
725
+ return _this.togglePinnedResult(key);
726
+ }
727
+ }) : null, /*#__PURE__*/React.createElement("span", null, (_this.props.showLayerTitles ? feature.layertitle + ": " : "") + feature.displayname), zoomToFeatureButton, /*#__PURE__*/React.createElement(Icon, {
703
728
  icon: "info-sign",
704
729
  onClick: function onClick() {
705
- return _this.showLayerInfo(layer);
730
+ return _this.showLayerInfo(layerid);
706
731
  }
707
732
  }), /*#__PURE__*/React.createElement(Icon, {
708
733
  icon: "trash",
709
734
  onClick: function onClick() {
710
- return _this.removeResult(layer, result);
735
+ return _this.removeResult(layerid, feature);
711
736
  }
712
737
  })), _this.props.collapsible && !expanded ? null : /*#__PURE__*/React.createElement("div", {
713
738
  className: "identify-result-container"
714
739
  }, resultbox, extraattribs));
715
740
  });
741
+ _defineProperty(_this, "togglePinnedResult", function (key) {
742
+ _this.setState(function (state) {
743
+ var pinnedResults = state.pinnedResults.toggle(key);
744
+ return {
745
+ pinnedResults: pinnedResults,
746
+ compareEnabled: pinnedResults.size > 1
747
+ };
748
+ });
749
+ });
750
+ _defineProperty(_this, "renderToolbar", function (resultCount) {
751
+ var toggleButton = function toggleButton(key, icon) {
752
+ return /*#__PURE__*/React.createElement("button", {
753
+ className: "button" + (_this.state[key] ? " pressed" : ""),
754
+ onClick: function onClick() {
755
+ return _this.setState(function (state) {
756
+ return _defineProperty({}, key, !state[key]);
757
+ });
758
+ }
759
+ }, /*#__PURE__*/React.createElement(Icon, {
760
+ icon: icon
761
+ }));
762
+ };
763
+ var infoLabel = null;
764
+ if (_this.state.compareEnabled) {
765
+ infoLabel = /*#__PURE__*/React.createElement("span", null, LocaleUtils.tr("identify.comparing", _this.state.pinnedResults.size()));
766
+ } else if (_this.props.resultDisplayMode !== 'paginated') {
767
+ infoLabel = /*#__PURE__*/React.createElement("span", null, LocaleUtils.tr("identify.featurecount", resultCount));
768
+ }
769
+ return /*#__PURE__*/React.createElement("div", {
770
+ className: "identify-toolbar"
771
+ }, toggleButton("settingsMenu", "cog"), _this.state.settingsMenu ? _this.renderSettingsMenu() : null, _this.state.pinnedResults.size() > 1 ? toggleButton("compareEnabled", "compare") : null, /*#__PURE__*/React.createElement("span", {
772
+ className: "identify-toolbar-spacer"
773
+ }), infoLabel, /*#__PURE__*/React.createElement("span", {
774
+ className: "identify-toolbar-spacer"
775
+ }), _this.props.resultDisplayMode === 'paginated' ? /*#__PURE__*/React.createElement(NavBar, {
776
+ currentPage: _this.state.currentPage,
777
+ nPages: resultCount,
778
+ pageChanged: function pageChanged(page) {
779
+ return _this.setState({
780
+ currentPage: page
781
+ });
782
+ },
783
+ pageSizes: [1]
784
+ }) : null);
785
+ });
786
+ _defineProperty(_this, "renderSettingsMenu", function () {
787
+ var _exporters$_this$stat;
788
+ var exporters = Object.fromEntries(_this.getExporters().map(function (exporter) {
789
+ return [exporter.id, exporter];
790
+ }));
791
+ var enabledExporters = Array.isArray(_this.props.enableExport) ? _this.props.enableExport : Object.keys(exporters);
792
+ var clipboardExportDisabled = ((_exporters$_this$stat = exporters[_this.state.exportFormat]) === null || _exporters$_this$stat === void 0 ? void 0 : _exporters$_this$stat.allowClipboard) !== true;
793
+ var exportEnabled = _this.props.enableExport === true || !isEmpty(_this.props.enableExport);
794
+ var reportsEnabled = _this.props.enableAggregatedReports && Object.keys(_this.state.reports).length > 0;
795
+ return /*#__PURE__*/React.createElement("div", {
796
+ className: "identify-settings-menu"
797
+ }, /*#__PURE__*/React.createElement("table", null, /*#__PURE__*/React.createElement("tbody", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, LocaleUtils.tr("identify.results"), ":"), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("div", {
798
+ className: "controlgroup"
799
+ }, /*#__PURE__*/React.createElement("select", {
800
+ className: "controlgroup-expanditem",
801
+ onChange: function onChange(e) {
802
+ return _this.setState({
803
+ selectedLayer: e.target.value
804
+ });
805
+ }
806
+ }, /*#__PURE__*/React.createElement("option", {
807
+ value: ""
808
+ }, LocaleUtils.tr("identify.layerall")), Object.keys(_this.state.resultTree).filter(function (key) {
809
+ return _this.state.resultTree[key].length;
810
+ }).map(function (layer) {
811
+ return /*#__PURE__*/React.createElement("option", {
812
+ key: layer,
813
+ value: layer
814
+ }, _this.state.resultTree[layer][0].layertitle);
815
+ }))))), exportEnabled ? /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, LocaleUtils.tr("identify.export"), ":"), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("div", {
816
+ className: "controlgroup"
817
+ }, /*#__PURE__*/React.createElement("select", {
818
+ className: "controlgroup-expanditem",
819
+ onChange: function onChange(ev) {
820
+ return _this.setState({
821
+ exportFormat: ev.target.value
822
+ });
823
+ },
824
+ value: _this.state.exportFormat
825
+ }, enabledExporters.map(function (id) {
826
+ var _exporters$id$title;
827
+ return /*#__PURE__*/React.createElement("option", {
828
+ key: id,
829
+ value: id
830
+ }, (_exporters$id$title = exporters[id].title) !== null && _exporters$id$title !== void 0 ? _exporters$id$title : LocaleUtils.tr(exporters[id].titleMsgId));
831
+ })), /*#__PURE__*/React.createElement("button", {
832
+ className: "button",
833
+ onClick: function onClick() {
834
+ return _this.exportResults();
835
+ },
836
+ title: LocaleUtils.tr("identify.download")
837
+ }, /*#__PURE__*/React.createElement(Icon, {
838
+ icon: "export"
839
+ })), /*#__PURE__*/React.createElement("button", {
840
+ className: "button",
841
+ disabled: clipboardExportDisabled,
842
+ onClick: function onClick() {
843
+ return _this.exportResults(true);
844
+ },
845
+ title: LocaleUtils.tr("identify.clipboard")
846
+ }, /*#__PURE__*/React.createElement(Icon, {
847
+ icon: "copy"
848
+ }))))) : null, reportsEnabled ? /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, LocaleUtils.tr("identify.aggregatedreport"), ":"), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("div", {
849
+ className: "controlgroup"
850
+ }, /*#__PURE__*/React.createElement("select", {
851
+ className: "controlgroup-expanditem",
852
+ onChange: function onChange(ev) {
853
+ return _this.setState({
854
+ selectedAggregatedReport: ev.target.value
855
+ });
856
+ },
857
+ value: _this.state.selectedAggregatedReport
858
+ }, /*#__PURE__*/React.createElement("option", {
859
+ disabled: true,
860
+ value: ""
861
+ }, LocaleUtils.tr("identify.selectreport")), Object.entries(_this.state.reports).map(function (_ref19) {
862
+ var _ref20 = _slicedToArray(_ref19, 2),
863
+ layername = _ref20[0],
864
+ reports = _ref20[1];
865
+ return reports.map(function (report, idx) {
866
+ return /*#__PURE__*/React.createElement("option", {
867
+ key: layername + "::" + idx,
868
+ value: layername + "::" + idx
869
+ }, report.title);
870
+ });
871
+ })), /*#__PURE__*/React.createElement("button", {
872
+ className: "button",
873
+ disabled: !_this.state.selectedAggregatedReport || _this.state.generatingReport,
874
+ onClick: _this.downloadAggregatedReport
875
+ }, _this.state.generatingReport ? /*#__PURE__*/React.createElement(Spinner, null) : /*#__PURE__*/React.createElement(Icon, {
876
+ icon: "report"
877
+ }))))) : null)));
878
+ });
716
879
  _defineProperty(_this, "computeExtraAttributes", function (layer, result) {
717
880
  var _window$qwc;
718
881
  var rows = [];
@@ -925,6 +1088,7 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
925
1088
  _this.props.changeLayerProperty(layer.id, "visibility", true, path);
926
1089
  }
927
1090
  });
1091
+ _this.resultsTreeRef = null;
928
1092
  _this.currentResultElRef = null;
929
1093
  _this.scrollIntoView = false;
930
1094
  _this.state.exportFormat = !Array.isArray(props.enableExport) ? 'geojson' : props.enableExport[0];
@@ -942,15 +1106,24 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
942
1106
  if (this.props.identifyResults !== prevProps.identifyResults) {
943
1107
  this.updateResultTree();
944
1108
  }
945
- if (prevState.currentResult !== this.state.currentResult || prevState.resultTree !== this.state.resultTree) {
946
- this.setHighlightedResults(this.state.currentResult === null ? null : [this.state.currentResult], this.state.resultTree);
1109
+ if (prevState.currentResult !== this.state.currentResult || prevState.resultTree !== this.state.resultTree || this.state.currentPage !== prevState.currentPage) {
1110
+ this.setHighlightedFeatures(this.state.currentResult ? [this.getCurrentResultFeature()] : null);
947
1111
  }
948
1112
  // Scroll to selected result
949
- if (this.state.currentResult && this.state.currentResult !== prevState.currentResult && this.currentResultElRef && this.scrollIntoView) {
950
- this.currentResultElRef.parentNode.scrollTop = this.currentResultElRef.offsetTop - this.currentResultElRef.parentNode.offsetTop;
1113
+ if (this.state.currentResult && this.state.currentResult !== prevState.currentResult && this.resultsTreeRef && this.currentResultElRef && this.scrollIntoView) {
1114
+ this.resultsTreeRef.scrollTop = this.currentResultElRef.offsetTop - 10;
951
1115
  this.scrollIntoView = false;
952
1116
  this.currentResultElRef = null;
953
1117
  }
1118
+ // Ensure currentPage is in range
1119
+ if (this.state.resultTree !== prevState.resultTree || this.state.selectedLayer !== prevState.selectedLayer) {
1120
+ var count = Object.values(this.state.selectedLayer !== '' ? _defineProperty({}, this.state.selectedLayer, this.state.resultTree[this.state.selectedLayer]) : this.state.resultTree).flat().length;
1121
+ this.setState(function (state) {
1122
+ return {
1123
+ currentPage: Math.max(0, Math.min(state.currentPage, count - 1))
1124
+ };
1125
+ });
1126
+ }
954
1127
  }
955
1128
  }, {
956
1129
  key: "componentWillUnmount",
@@ -960,151 +1133,67 @@ var IdentifyViewer = /*#__PURE__*/function (_React$Component) {
960
1133
  }, {
961
1134
  key: "render",
962
1135
  value: function render() {
963
- var _this2 = this,
964
- _exporters$this$state;
965
- var tree = this.props.displayResultTree;
1136
+ var _this2 = this;
966
1137
  var body = null;
967
- if (tree) {
968
- var contents = Object.keys(this.state.resultTree).map(function (layer) {
969
- return _this2.renderLayer(layer);
1138
+ var resultTree = this.state.selectedLayer !== '' ? _defineProperty({}, this.state.selectedLayer, this.state.resultTree[this.state.selectedLayer]) : this.state.resultTree;
1139
+ var flatResults = Object.entries(resultTree).map(function (_ref23) {
1140
+ var _ref24 = _slicedToArray(_ref23, 2),
1141
+ layerid = _ref24[0],
1142
+ features = _ref24[1];
1143
+ return features.map(function (feature) {
1144
+ return [layerid, feature];
970
1145
  });
971
- var attributes = this.renderResultAttributes(this.state.currentLayer, this.state.currentResult, 'identify-result-tree-frame');
972
- var resultsContainerStyle = {
973
- maxHeight: attributes ? '10em' : 'initial'
974
- };
975
- body = [/*#__PURE__*/React.createElement("div", {
976
- className: "identify-results-container",
977
- key: "results-container",
978
- style: resultsContainerStyle
979
- }, contents), attributes];
980
- } else {
1146
+ }).flat();
1147
+ if (this.state.compareEnabled) {
1148
+ body = /*#__PURE__*/React.createElement("div", {
1149
+ className: "identify-compare-results"
1150
+ }, this.state.pinnedResults.entries().map(function (key) {
1151
+ var _key$split = key.split("$"),
1152
+ _key$split2 = _slicedToArray(_key$split, 2),
1153
+ layerid = _key$split2[0],
1154
+ featureid = _key$split2[1];
1155
+ var feature = _this2.state.resultTree[layerid].find(function (f) {
1156
+ return f.id === featureid;
1157
+ });
1158
+ return _this2.renderResultAttributes(layerid, feature, "identify-result-frame");
1159
+ }));
1160
+ } else if (this.props.resultDisplayMode === 'tree') {
1161
+ var _this$state$currentRe6;
1162
+ body = [this.renderResultTree(), this.renderResultAttributes((_this$state$currentRe6 = this.state.currentResult) === null || _this$state$currentRe6 === void 0 ? void 0 : _this$state$currentRe6.layerid, this.getCurrentResultFeature(), 'identify-result-tree-frame')];
1163
+ } else if (this.props.resultDisplayMode === 'flat') {
981
1164
  body = /*#__PURE__*/React.createElement("div", {
982
1165
  className: "identify-flat-results-list"
983
- }, this.props.showLayerSelector ? /*#__PURE__*/React.createElement("div", {
984
- className: "identify-selectbox"
985
- }, /*#__PURE__*/React.createElement("select", {
986
- className: "identify-layer-select",
987
- onChange: function onChange(e) {
988
- var selectedLayer = e.target.value;
989
- _this2.setState({
990
- selectedLayer: selectedLayer
991
- });
992
- }
993
- }, /*#__PURE__*/React.createElement("option", {
994
- value: ""
995
- }, LocaleUtils.tr("identify.layerall")), Object.keys(this.state.resultTree).filter(function (key) {
996
- return _this2.state.resultTree[key].length;
997
- }).map(function (layer) {
998
- return /*#__PURE__*/React.createElement("option", {
999
- key: layer,
1000
- value: layer
1001
- }, _this2.state.resultTree[layer][0].layertitle);
1002
- })), /*#__PURE__*/React.createElement("span", {
1003
- className: "identify-buttonbox-spacer"
1004
- }), /*#__PURE__*/React.createElement("span", null, LocaleUtils.tr("identify.featurecount"), ": ", Object.values(this.state.selectedLayer !== '' ? this.state.resultTree[this.state.selectedLayer] : this.state.resultTree).flat().length)) : null, Object.keys(this.state.selectedLayer !== '' ? _defineProperty({}, this.state.selectedLayer, this.state.resultTree[this.state.selectedLayer]) : this.state.resultTree).map(function (layer) {
1005
- var layerResults = _this2.state.resultTree[layer];
1006
- return layerResults.map(function (result) {
1007
- var resultClass = _this2.state.currentResult === result ? 'identify-result-frame-highlighted' : 'identify-result-frame-normal';
1166
+ }, Object.entries(resultTree).map(function (_ref25) {
1167
+ var _ref26 = _slicedToArray(_ref25, 2),
1168
+ layerid = _ref26[0],
1169
+ features = _ref26[1];
1170
+ return features.map(function (feature) {
1008
1171
  return /*#__PURE__*/React.createElement("div", {
1009
- key: result.id,
1172
+ key: layerid + "$" + feature.id,
1010
1173
  onMouseEnter: function onMouseEnter() {
1011
- return _this2.setState({
1012
- currentResult: result,
1013
- currentLayer: layer
1014
- });
1174
+ return _this2.setHighlightedFeatures([feature]);
1015
1175
  },
1016
1176
  onMouseLeave: function onMouseLeave() {
1017
- return _this2.setState({
1018
- currentResult: null,
1019
- currentLayer: null
1020
- });
1177
+ return _this2.setHighlightedFeatures(null);
1021
1178
  }
1022
- }, _this2.renderResultAttributes(layer, result, resultClass));
1179
+ }, _this2.renderResultAttributes(layerid, feature, 'identify-result-frame'));
1023
1180
  });
1024
1181
  }));
1182
+ } else if (this.props.resultDisplayMode === 'paginated' && this.state.currentPage < flatResults.length) {
1183
+ var _flatResults$this$sta = _slicedToArray(flatResults[this.state.currentPage], 2),
1184
+ layerid = _flatResults$this$sta[0],
1185
+ feature = _flatResults$this$sta[1];
1186
+ body = /*#__PURE__*/React.createElement("div", {
1187
+ className: "identify-flat-results-list"
1188
+ }, this.renderResultAttributes(layerid, feature, 'identify-result-frame'));
1025
1189
  }
1026
1190
  // "el.style.background='inherit'": HACK to trigger an additional repaint, since Safari/Chrome on iOS render the element cut off the first time
1027
- var exporters = Object.fromEntries(this.getExporters().map(function (exporter) {
1028
- return [exporter.id, exporter];
1029
- }));
1030
- var enabledExporters = Array.isArray(this.props.enableExport) ? this.props.enableExport : Object.keys(exporters);
1031
- var clipboardExportDisabled = ((_exporters$this$state = exporters[this.state.exportFormat]) === null || _exporters$this$state === void 0 ? void 0 : _exporters$this$state.allowClipboard) !== true;
1032
1191
  return /*#__PURE__*/React.createElement("div", {
1033
1192
  className: "identify-body",
1034
1193
  ref: function ref(el) {
1035
1194
  if (el) el.style.background = 'inherit';
1036
1195
  }
1037
- }, body, this.props.enableExport === true || !isEmpty(this.props.enableExport) ? /*#__PURE__*/React.createElement("div", {
1038
- className: "identify-buttonbox"
1039
- }, /*#__PURE__*/React.createElement("span", {
1040
- className: "identify-buttonbox-spacer"
1041
- }), /*#__PURE__*/React.createElement("span", null, LocaleUtils.tr("identify.export"), ":\xA0"), /*#__PURE__*/React.createElement("div", {
1042
- className: "controlgroup"
1043
- }, /*#__PURE__*/React.createElement("select", {
1044
- className: "combo identify-export-format",
1045
- onChange: function onChange(ev) {
1046
- return _this2.setState({
1047
- exportFormat: ev.target.value
1048
- });
1049
- },
1050
- value: this.state.exportFormat
1051
- }, enabledExporters.map(function (id) {
1052
- var _exporters$id$title;
1053
- return /*#__PURE__*/React.createElement("option", {
1054
- key: id,
1055
- value: id
1056
- }, (_exporters$id$title = exporters[id].title) !== null && _exporters$id$title !== void 0 ? _exporters$id$title : LocaleUtils.tr(exporters[id].titleMsgId));
1057
- })), /*#__PURE__*/React.createElement("button", {
1058
- className: "button",
1059
- onClick: function onClick() {
1060
- return _this2.exportResults();
1061
- },
1062
- title: LocaleUtils.tr("identify.download")
1063
- }, /*#__PURE__*/React.createElement(Icon, {
1064
- icon: "export"
1065
- })), /*#__PURE__*/React.createElement("button", {
1066
- className: "button",
1067
- disabled: clipboardExportDisabled,
1068
- onClick: function onClick() {
1069
- return _this2.exportResults(true);
1070
- },
1071
- title: LocaleUtils.tr("identify.clipboard")
1072
- }, /*#__PURE__*/React.createElement(Icon, {
1073
- icon: "copy"
1074
- })))) : null, this.props.enableAggregatedReports && Object.keys(this.state.reports).length > 0 ? /*#__PURE__*/React.createElement("div", {
1075
- className: "identify-buttonbox"
1076
- }, /*#__PURE__*/React.createElement("span", {
1077
- className: "identify-buttonbox-spacer"
1078
- }), /*#__PURE__*/React.createElement("span", null, LocaleUtils.tr("identify.aggregatedreport"), ":\xA0"), /*#__PURE__*/React.createElement("div", {
1079
- className: "controlgroup"
1080
- }, /*#__PURE__*/React.createElement("select", {
1081
- className: "combo identify-export-format",
1082
- onChange: function onChange(ev) {
1083
- return _this2.setState({
1084
- selectedAggregatedReport: ev.target.value
1085
- });
1086
- },
1087
- value: this.state.selectedAggregatedReport
1088
- }, /*#__PURE__*/React.createElement("option", {
1089
- disabled: true,
1090
- value: ""
1091
- }, LocaleUtils.tr("identify.selectreport")), Object.entries(this.state.reports).map(function (_ref16) {
1092
- var _ref17 = _slicedToArray(_ref16, 2),
1093
- layername = _ref17[0],
1094
- reports = _ref17[1];
1095
- return reports.map(function (report, idx) {
1096
- return /*#__PURE__*/React.createElement("option", {
1097
- key: layername + "::" + idx,
1098
- value: layername + "::" + idx
1099
- }, report.title);
1100
- });
1101
- })), /*#__PURE__*/React.createElement("button", {
1102
- className: "button",
1103
- disabled: !this.state.selectedAggregatedReport || this.state.generatingReport,
1104
- onClick: this.downloadAggregatedReport
1105
- }, this.state.generatingReport ? /*#__PURE__*/React.createElement(Spinner, null) : /*#__PURE__*/React.createElement(Icon, {
1106
- icon: "report"
1107
- })))) : null);
1196
+ }, body, flatResults.length > 0 ? this.renderToolbar(flatResults.length) : null);
1108
1197
  }
1109
1198
  }]);
1110
1199
  }(React.Component);
@@ -1115,8 +1204,8 @@ _defineProperty(IdentifyViewer, "propTypes", {
1115
1204
  changeLayerProperty: PropTypes.func,
1116
1205
  collapsible: PropTypes.bool,
1117
1206
  customExporters: PropTypes.array,
1118
- displayResultTree: PropTypes.bool,
1119
1207
  enableAggregatedReports: PropTypes.bool,
1208
+ enableCompare: PropTypes.bool,
1120
1209
  enableExport: PropTypes.oneOfType([PropTypes.bool, PropTypes.array]),
1121
1210
  exportGeometry: PropTypes.bool,
1122
1211
  highlightAllResults: PropTypes.bool,
@@ -1128,6 +1217,7 @@ _defineProperty(IdentifyViewer, "propTypes", {
1128
1217
  openExternalUrl: PropTypes.func,
1129
1218
  removeLayer: PropTypes.func,
1130
1219
  replaceImageUrls: PropTypes.bool,
1220
+ resultDisplayMode: PropTypes.string,
1131
1221
  setActiveLayerInfo: PropTypes.func,
1132
1222
  showLayerSelector: PropTypes.bool,
1133
1223
  showLayerTitles: PropTypes.bool,
@@ -1137,7 +1227,6 @@ _defineProperty(IdentifyViewer, "propTypes", {
1137
1227
  _defineProperty(IdentifyViewer, "defaultProps", {
1138
1228
  longAttributesDisplay: 'ellipsis',
1139
1229
  customExporters: [],
1140
- displayResultTree: true,
1141
1230
  attributeCalculator: function attributeCalculator(/* layer, feature */) {
1142
1231
  return [];
1143
1232
  },
@@ -1145,6 +1234,7 @@ _defineProperty(IdentifyViewer, "defaultProps", {
1145
1234
  return value;
1146
1235
  },
1147
1236
  enableAggregatedReports: true,
1237
+ resultDisplayMode: 'flat',
1148
1238
  showLayerTitles: true,
1149
1239
  showLayerSelector: true,
1150
1240
  highlightAllResults: true