@geogirafe/lib-geoportal 1.2.0-dev.2791536378 → 1.2.0-dev.2794025939

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.
@@ -546,6 +546,7 @@
546
546
  "themes-type-favorites": "Favoriten",
547
547
  "This instance of GeoGirafe cannot be used at the moment.": "Diese Instanz von GeoGirafe kann momentan nicht verwendet werden.",
548
548
  "This Text should be translated": "Dieser Text sollte übersetzt werden",
549
+ "This will export all the data for the layers": "Die folgenden Ebenen werden exportiert:",
549
550
  "Toggle all legends": "Alle Legenden umschalten",
550
551
  "Toggle legend": "Legende umschalten",
551
552
  "Tools": "Werkzeuge",
@@ -549,6 +549,7 @@
549
549
  "themes-type-favorites": "Favorite Themes",
550
550
  "This instance of GeoGirafe cannot be used at the moment.": "This instance of GeoGirafe cannot be used at the moment.",
551
551
  "This Text should be translated": "This Text should be translated",
552
+ "This will export all the data for the layers": "This will export all the data for the layers:",
552
553
  "Toggle all legends": "Toggle all legends",
553
554
  "Toggle legend": "Toggle legend",
554
555
  "Tools": "Tools",
@@ -546,6 +546,7 @@
546
546
  "themes-type-favorites": "Favoris",
547
547
  "This instance of GeoGirafe cannot be used at the moment.": "Cette instance de GeoGirafe ne peut pas être utilisée pour le moment.",
548
548
  "This Text should be translated": "Ce texte doit être traduit",
549
+ "This will export all the data for the layers": "Les couches suivantes vont être exportées:",
549
550
  "Toggle all legends": "Afficher / Masquer toutes les légendes",
550
551
  "Toggle legend": "Afficher / Masquer la légende",
551
552
  "Tools": "Outis",
@@ -546,6 +546,7 @@
546
546
  "themes-type-favorites": "Preferiti",
547
547
  "This instance of GeoGirafe cannot be used at the moment.": "Questa istanza di GeoGirafe non può essere utilizzata al momento.",
548
548
  "This Text should be translated": "Questo testo dovrebbe essere tradotto",
549
+ "This will export all the data for the layers": "I seguenti layer verranno esportati:",
549
550
  "Toggle all legends": "Attiva / Disattiva tutte le legende",
550
551
  "Toggle legend": "Attiva / Disattiva legenda",
551
552
  "Tools": "Strumenti",
@@ -16,6 +16,10 @@ declare class OfflineComponent extends GirafeHTMLElement {
16
16
  * Gets the list of all active WMTS layers
17
17
  */
18
18
  private getAllWmtsLayers;
19
+ /**
20
+ * layersList is a tree, walk recursively to find the active WMTS leaf
21
+ */
22
+ private getActiveWmtsLayersRecursive;
19
23
  progressCallback(progress: number): void;
20
24
  protected connectedCallback(): void;
21
25
  clearStores(): Promise<void>;
@@ -1,7 +1,9 @@
1
1
  import { html as uHtml } from 'uhtml';
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
  import GirafeHTMLElement from '../../base/GirafeHTMLElement.js';
4
+ import GroupLayer from '../../models/layers/grouplayer.js';
4
5
  import LayerWmts from '../../models/layers/layerwmts.js';
6
+ import ThemeLayer from '../../models/layers/themelayer.js';
5
7
  class OfflineComponent extends GirafeHTMLElement {
6
8
  templateUrl = null;
7
9
  styleUrls = null;
@@ -41,7 +43,8 @@ ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
41
43
  }
42
44
  exportData() {
43
45
  const allWmtsLayers = this.getAllWmtsLayers();
44
- const message = `This will export all the data for the layers [${allWmtsLayers.map((l) => l.name).join(', ')}].`;
46
+ const layersList = allWmtsLayers.map((l) => this.context.i18nManager.getTranslation(l.name)).join(', ');
47
+ const message = `${this.context.i18nManager.getTranslation('This will export all the data for the layers')} [${layersList}].`;
45
48
  if (confirm(message)) {
46
49
  this.downloadInProgress = true;
47
50
  this.downloadProgressValue = 0;
@@ -56,9 +59,26 @@ ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
56
59
  */
57
60
  getAllWmtsLayers() {
58
61
  const basemapLayers = this.context.stateManager.state.activeBasemaps?.flatMap((activeBasemap) => activeBasemap.layersList.filter((l) => l instanceof LayerWmts));
59
- const activeLayers = this.state.layers.layersList.filter((l) => l instanceof LayerWmts && l.active);
62
+ const activeLayers = this.getActiveWmtsLayersRecursive(this.state.layers.layersList);
60
63
  return [...basemapLayers, ...activeLayers];
61
64
  }
65
+ /**
66
+ * layersList is a tree, walk recursively to find the active WMTS leaf
67
+ */
68
+ getActiveWmtsLayersRecursive(layers) {
69
+ const activeWmtsLayers = [];
70
+ for (const layer of layers) {
71
+ if (layer instanceof LayerWmts) {
72
+ if (layer.active) {
73
+ activeWmtsLayers.push(layer);
74
+ }
75
+ }
76
+ else if (layer instanceof GroupLayer || layer instanceof ThemeLayer) {
77
+ activeWmtsLayers.push(...this.getActiveWmtsLayersRecursive(layer.children));
78
+ }
79
+ }
80
+ return activeWmtsLayers;
81
+ }
62
82
  progressCallback(progress) {
63
83
  if (progress === 100) {
64
84
  // Done.
@@ -20,7 +20,7 @@ class SelectionGridComponent extends GirafeResizableElement {
20
20
  </style><style>
21
21
  .tabulator{text-align:left;background-color:#888;border:1px solid #999;font-size:14px;position:relative;overflow:hidden;-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-ms-transform:translateZ(0);-o-transform:translateZ(0);transform:translateZ(0)}.tabulator[tabulator-layout=fitDataFill] .tabulator-tableholder .tabulator-table{min-width:100%}.tabulator[tabulator-layout=fitDataTable]{display:inline-block}.tabulator.tabulator-block-select,.tabulator.tabulator-ranges .tabulator-cell:not(.tabulator-editing){user-select:none}.tabulator .tabulator-header{box-sizing:border-box;color:#555;-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-o-user-select:none;white-space:nowrap;background-color:#e6e6e6;border-bottom:1px solid #999;outline:none;width:100%;font-weight:700;position:relative;overflow:hidden}.tabulator .tabulator-header.tabulator-header-hidden{display:none}.tabulator .tabulator-header .tabulator-header-contents{position:relative;overflow:hidden}.tabulator .tabulator-header .tabulator-header-contents .tabulator-headers{display:inline-block}.tabulator .tabulator-header .tabulator-col{box-sizing:border-box;text-align:left;vertical-align:bottom;background:#e6e6e6;border-right:1px solid #aaa;flex-direction:column;justify-content:flex-start;display:inline-flex;position:relative;overflow:hidden}.tabulator .tabulator-header .tabulator-col.tabulator-moving{pointer-events:none;background:#cdcdcd;border:1px solid #999;position:absolute}.tabulator .tabulator-header .tabulator-col.tabulator-range-highlight{color:#000;background-color:#d6d6d6}.tabulator .tabulator-header .tabulator-col.tabulator-range-selected{color:#fff;background-color:#3876ca}.tabulator .tabulator-header .tabulator-col .tabulator-col-content{box-sizing:border-box;padding:4px;position:relative}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-header-popup-button{padding:0 8px}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-header-popup-button:hover{cursor:pointer;opacity:.6}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title-holder{position:relative}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title{box-sizing:border-box;text-overflow:ellipsis;vertical-align:bottom;white-space:nowrap;width:100%;overflow:hidden}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title.tabulator-col-title-wrap{text-overflow:clip;white-space:normal}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title .tabulator-title-editor{box-sizing:border-box;background:#fff;border:1px solid #999;width:100%;padding:1px}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title .tabulator-header-popup-button+.tabulator-title-editor{width:calc(100% - 22px)}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter{align-items:center;display:flex;position:absolute;top:0;bottom:0;right:4px}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{border-bottom:6px solid #bbb;border-left:6px solid #0000;border-right:6px solid #0000;width:0;height:0}.tabulator .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols{border-top:1px solid #aaa;margin-right:-1px;display:flex;position:relative;overflow:hidden}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter{box-sizing:border-box;text-align:center;width:100%;margin-top:2px;position:relative}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter textarea{height:auto!important}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter svg{margin-top:3px}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter input::-ms-clear{width:0;height:0}.tabulator .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title{padding-right:25px}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable.tabulator-col-sorter-element:hover{cursor:pointer;background-color:#cdcdcd}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=none] .tabulator-col-content .tabulator-col-sorter{color:#bbb}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=none] .tabulator-col-content .tabulator-col-sorter.tabulator-col-sorter-element .tabulator-arrow:hover{cursor:pointer;border-bottom:6px solid #555}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=none] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{border-top:none;border-bottom:6px solid #bbb}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=ascending] .tabulator-col-content .tabulator-col-sorter{color:#666}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=ascending] .tabulator-col-content .tabulator-col-sorter.tabulator-col-sorter-element .tabulator-arrow:hover{cursor:pointer;border-bottom:6px solid #555}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=ascending] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{border-top:none;border-bottom:6px solid #666}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=descending] .tabulator-col-content .tabulator-col-sorter{color:#666}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=descending] .tabulator-col-content .tabulator-col-sorter.tabulator-col-sorter-element .tabulator-arrow:hover{cursor:pointer;border-top:6px solid #555}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=descending] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{color:#666;border-top:6px solid #666;border-bottom:none}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical .tabulator-col-content .tabulator-col-title{text-orientation:mixed;writing-mode:vertical-rl;justify-content:center;align-items:center;display:flex}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-col-vertical-flip .tabulator-col-title{transform:rotate(180deg)}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-col-title{padding-top:20px;padding-right:0}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable.tabulator-col-vertical-flip .tabulator-col-title{padding-bottom:20px;padding-right:0}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-col-sorter{justify-content:center;inset:4px 0 auto}.tabulator .tabulator-header .tabulator-frozen{z-index:11;position:sticky;left:0}.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-left{border-right:2px solid #aaa}.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-right{border-left:2px solid #aaa}.tabulator .tabulator-header .tabulator-calcs-holder{box-sizing:border-box;border-top:1px solid #aaa;border-bottom:1px solid #aaa;display:inline-block;background:#f3f3f3!important}.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row{background:#f3f3f3!important}.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle{display:none}.tabulator .tabulator-header .tabulator-frozen-rows-holder{padding-top:1em;display:inline-block}.tabulator .tabulator-header .tabulator-frozen-rows-holder:empty{display:none}.tabulator .tabulator-tableholder{-webkit-overflow-scrolling:touch;white-space:nowrap;width:100%;position:relative;overflow:auto}.tabulator .tabulator-tableholder:focus{outline:none}.tabulator .tabulator-tableholder .tabulator-placeholder{box-sizing:border-box;justify-content:center;align-items:center;width:100%;min-width:100%;display:flex}.tabulator .tabulator-tableholder .tabulator-placeholder[tabulator-render-mode=virtual]{min-height:100%}.tabulator .tabulator-tableholder .tabulator-placeholder .tabulator-placeholder-contents{color:#ccc;text-align:center;white-space:normal;padding:10px;font-size:20px;font-weight:700;display:inline-block}.tabulator .tabulator-tableholder .tabulator-table{color:#333;white-space:nowrap;background-color:#fff;display:inline-block;position:relative;overflow:visible}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs{font-weight:700;background:#e2e2e2!important}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-top{border-bottom:2px solid #aaa}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-bottom{border-top:2px solid #aaa}.tabulator .tabulator-tableholder .tabulator-range-overlay{pointer-events:none;z-index:10;position:absolute;inset:0}.tabulator .tabulator-tableholder .tabulator-range-overlay .tabulator-range{box-sizing:border-box;border:1px solid #2975dd;position:absolute}.tabulator .tabulator-tableholder .tabulator-range-overlay .tabulator-range.tabulator-range-active:after{content:"";background-color:#2975dd;border-radius:999px;width:6px;height:6px;position:absolute;bottom:-3px;right:-3px}.tabulator .tabulator-tableholder .tabulator-range-overlay .tabulator-range-cell-active{box-sizing:border-box;border:2px solid #2975dd;position:absolute}.tabulator .tabulator-footer{color:#555;-webkit-user-select:none;-moz-user-select:none;user-select:none;-khtml-user-select:none;-o-user-select:none;white-space:nowrap;background-color:#e6e6e6;border-top:1px solid #999;font-weight:700}.tabulator .tabulator-footer .tabulator-footer-contents{flex-direction:row;justify-content:space-between;align-items:center;padding:5px 10px;display:flex}.tabulator .tabulator-footer .tabulator-footer-contents:empty{display:none}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs{margin-top:-5px;overflow-x:auto}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab{border:1px solid #999;border-top:none;border-bottom-right-radius:5px;border-bottom-left-radius:5px;padding:5px;font-size:.9em;display:inline-block}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab:hover{cursor:pointer;opacity:.7}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab.tabulator-spreadsheet-tab-active{background:#fff}.tabulator .tabulator-footer .tabulator-calcs-holder{box-sizing:border-box;text-align:left;border-top:1px solid #aaa;border-bottom:1px solid #aaa;width:100%;overflow:hidden;background:#f3f3f3!important}.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row{display:inline-block;background:#f3f3f3!important}.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle{display:none}.tabulator .tabulator-footer .tabulator-calcs-holder:only-child{border-bottom:none;margin-bottom:-5px}.tabulator .tabulator-footer>*+.tabulator-page-counter{margin-left:10px}.tabulator .tabulator-footer .tabulator-page-counter{font-weight:400}.tabulator .tabulator-footer .tabulator-paginator{color:#555;font-family:inherit;font-size:inherit;font-weight:inherit;text-align:right;flex:1}.tabulator .tabulator-footer .tabulator-page-size{border:1px solid #aaa;border-radius:3px;margin:0 5px;padding:2px 5px;display:inline-block}.tabulator .tabulator-footer .tabulator-pages{margin:0 7px}.tabulator .tabulator-footer .tabulator-page{background:#fff3;border:1px solid #aaa;border-radius:3px;margin:0 2px;padding:2px 5px;display:inline-block}.tabulator .tabulator-footer .tabulator-page.active{color:#d00}.tabulator .tabulator-footer .tabulator-page:disabled{opacity:.5}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-footer .tabulator-page:not(disabled):hover{color:#fff;cursor:pointer;background:#0003}}.tabulator .tabulator-col-resize-handle{vertical-align:middle;z-index:11;width:6px;margin-left:-3px;margin-right:-3px;display:inline-block;position:relative}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-col-resize-handle:hover{cursor:ew-resize}}.tabulator .tabulator-col-resize-handle:last-of-type{width:3px;margin-right:0}.tabulator .tabulator-col-resize-guide{opacity:.5;background-color:#999;width:4px;height:100%;margin-left:-.5px;position:absolute;top:0}.tabulator .tabulator-row-resize-guide{opacity:.5;background-color:#999;width:100%;height:4px;margin-top:-.5px;position:absolute;left:0}.tabulator .tabulator-alert{text-align:center;z-index:100;background:#0006;align-items:center;width:100%;height:100%;display:flex;position:absolute;top:0;left:0}.tabulator .tabulator-alert .tabulator-alert-msg{background:#fff;border-radius:10px;margin:0 auto;padding:10px 20px;font-size:16px;font-weight:700;display:inline-block}.tabulator .tabulator-alert .tabulator-alert-msg.tabulator-alert-state-msg{color:#000;border:4px solid #333}.tabulator .tabulator-alert .tabulator-alert-msg.tabulator-alert-state-error{color:#590000;border:4px solid #d00}.tabulator-row{box-sizing:border-box;background-color:#fff;min-height:22px;position:relative}.tabulator-row.tabulator-row-even{background-color:#efefef}@media (hover:hover) and (pointer:fine){.tabulator-row.tabulator-selectable:hover{cursor:pointer;background-color:#bbb}}.tabulator-row.tabulator-selected{background-color:#9abcea}@media (hover:hover) and (pointer:fine){.tabulator-row.tabulator-selected:hover{cursor:pointer;background-color:#769bcc}}.tabulator-row.tabulator-row-moving{background:#fff;border:1px solid #000}.tabulator-row.tabulator-moving{pointer-events:none;z-index:15;border-top:1px solid #aaa;border-bottom:1px solid #aaa;position:absolute}.tabulator-row.tabulator-range-highlight .tabulator-cell.tabulator-range-row-header{color:#000;background-color:#d6d6d6}.tabulator-row.tabulator-range-highlight.tabulator-range-selected .tabulator-cell.tabulator-range-row-header,.tabulator-row.tabulator-range-selected .tabulator-cell.tabulator-range-row-header{color:#fff;background-color:#3876ca}.tabulator-row .tabulator-row-resize-handle{height:5px;position:absolute;bottom:0;left:0;right:0}.tabulator-row .tabulator-row-resize-handle.prev{top:0;bottom:auto}@media (hover:hover) and (pointer:fine){.tabulator-row .tabulator-row-resize-handle:hover{cursor:ns-resize}}.tabulator-row .tabulator-responsive-collapse{box-sizing:border-box;border-top:1px solid #aaa;border-bottom:1px solid #aaa;padding:5px}.tabulator-row .tabulator-responsive-collapse:empty{display:none}.tabulator-row .tabulator-responsive-collapse table{font-size:14px}.tabulator-row .tabulator-responsive-collapse table tr td{position:relative}.tabulator-row .tabulator-responsive-collapse table tr td:first-of-type{padding-right:10px}.tabulator-row .tabulator-cell{box-sizing:border-box;text-overflow:ellipsis;vertical-align:middle;white-space:nowrap;border-right:1px solid #aaa;outline:none;padding:4px;display:inline-block;position:relative;overflow:hidden}.tabulator-row .tabulator-cell.tabulator-row-header{background:#e6e6e6;border-bottom:1px solid #aaa;border-right:1px solid #999}.tabulator-row .tabulator-cell.tabulator-frozen{background-color:inherit;z-index:11;display:inline-block;position:sticky;left:0}.tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-left{border-right:2px solid #aaa}.tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-right{border-left:2px solid #aaa}.tabulator-row .tabulator-cell.tabulator-editing{border:1px solid #1d68cd;outline:none;padding:0}.tabulator-row .tabulator-cell.tabulator-editing input,.tabulator-row .tabulator-cell.tabulator-editing select{background:0 0;border:1px;outline:none}.tabulator-row .tabulator-cell.tabulator-validation-fail{border:1px solid #d00}.tabulator-row .tabulator-cell.tabulator-validation-fail input,.tabulator-row .tabulator-cell.tabulator-validation-fail select{color:#d00;background:0 0;border:1px}.tabulator-row .tabulator-cell.tabulator-row-handle{-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-o-user-select:none;justify-content:center;align-items:center;display:inline-flex}.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box{width:80%}.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box .tabulator-row-handle-bar{background:#666;width:100%;height:3px;margin-top:2px}.tabulator-row .tabulator-cell.tabulator-range-selected:not(.tabulator-range-only-cell-selected):not(.tabulator-range-row-header){background-color:#9abcea}.tabulator-row .tabulator-cell .tabulator-data-tree-branch-empty{width:7px;display:inline-block}.tabulator-row .tabulator-cell .tabulator-data-tree-branch{vertical-align:middle;border-bottom:2px solid #aaa;border-left:2px solid #aaa;border-bottom-left-radius:1px;width:7px;height:9px;margin-top:-9px;margin-right:5px;display:inline-block}.tabulator-row .tabulator-cell .tabulator-data-tree-control{vertical-align:middle;background:#0000001a;border:1px solid #333;border-radius:2px;justify-content:center;align-items:center;width:11px;height:11px;margin-right:5px;display:inline-flex;overflow:hidden}@media (hover:hover) and (pointer:fine){.tabulator-row .tabulator-cell .tabulator-data-tree-control:hover{cursor:pointer;background:#0003}}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse{background:0 0;width:1px;height:7px;display:inline-block;position:relative}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after{content:"";background:#333;width:7px;height:1px;position:absolute;top:3px;left:-3px}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand{background:#333;width:1px;height:7px;display:inline-block;position:relative}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand:after{content:"";background:#333;width:7px;height:1px;position:absolute;top:3px;left:-3px}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle{color:#fff;-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-o-user-select:none;background:#666;border-radius:20px;justify-content:center;align-items:center;width:15px;height:15px;font-size:1.1em;font-weight:700;display:inline-flex}@media (hover:hover) and (pointer:fine){.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle:hover{cursor:pointer;opacity:.7}}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-close{display:initial}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-open{display:none}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle svg{stroke:#fff}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle .tabulator-responsive-collapse-toggle-close{display:none}.tabulator-row .tabulator-cell .tabulator-traffic-light{border-radius:14px;width:14px;height:14px;display:inline-block}.tabulator-row.tabulator-group{box-sizing:border-box;background:#ccc;border-top:1px solid #999;border-bottom:1px solid #999;border-right:1px solid #aaa;min-width:100%;padding:5px 5px 5px 10px;font-weight:700}@media (hover:hover) and (pointer:fine){.tabulator-row.tabulator-group:hover{cursor:pointer;background-color:#0000001a}}.tabulator-row.tabulator-group.tabulator-group-visible .tabulator-arrow{border:6px solid #0000;border-top-color:#666;border-bottom:0;margin-right:10px}.tabulator-row.tabulator-group.tabulator-group-level-1{padding-left:30px}.tabulator-row.tabulator-group.tabulator-group-level-2{padding-left:50px}.tabulator-row.tabulator-group.tabulator-group-level-3{padding-left:70px}.tabulator-row.tabulator-group.tabulator-group-level-4{padding-left:90px}.tabulator-row.tabulator-group.tabulator-group-level-5{padding-left:110px}.tabulator-row.tabulator-group .tabulator-group-toggle{display:inline-block}.tabulator-row.tabulator-group .tabulator-arrow{vertical-align:middle;border:6px solid #0000;border-left-color:#666;border-right:0;width:0;height:0;margin-right:16px;display:inline-block}.tabulator-row.tabulator-group span{color:#d00;margin-left:10px}.tabulator-toggle{box-sizing:border-box;background:#dcdcdc;border:1px solid #ccc;flex-direction:row;display:flex}.tabulator-toggle.tabulator-toggle-on{background:#1c6cc2}.tabulator-toggle .tabulator-toggle-switch{box-sizing:border-box;background:#fff;border:1px solid #ccc}.tabulator-popup-container{-webkit-overflow-scrolling:touch;box-sizing:border-box;z-index:10000;background:#fff;border:1px solid #aaa;font-size:14px;display:inline-block;position:absolute;overflow-y:auto;box-shadow:0 0 5px #0003}.tabulator-popup{border-radius:3px;padding:5px}.tabulator-tooltip{box-shadow:none;pointer-events:none;border-radius:2px;max-width:min(500px,100%);padding:3px 5px;font-size:12px}.tabulator-menu .tabulator-menu-item{box-sizing:border-box;user-select:none;padding:5px 10px;position:relative}.tabulator-menu .tabulator-menu-item.tabulator-menu-item-disabled{opacity:.5}@media (hover:hover) and (pointer:fine){.tabulator-menu .tabulator-menu-item:not(.tabulator-menu-item-disabled):hover{cursor:pointer;background:#efefef}}.tabulator-menu .tabulator-menu-item.tabulator-menu-item-submenu{padding-right:25px}.tabulator-menu .tabulator-menu-item.tabulator-menu-item-submenu:after{content:"";vertical-align:top;border:1px solid #aaa;border-width:1px 1px 0 0;width:7px;height:7px;display:inline-block;position:absolute;top:calc(5px + .4em);right:10px;transform:rotate(45deg)}.tabulator-menu .tabulator-menu-separator{border-top:1px solid #aaa}.tabulator-edit-list{-webkit-overflow-scrolling:touch;max-height:200px;font-size:14px;overflow-y:auto}.tabulator-edit-list .tabulator-edit-list-item{color:#333;outline:none;padding:4px}.tabulator-edit-list .tabulator-edit-list-item.active{color:#fff;background:#1d68cd}.tabulator-edit-list .tabulator-edit-list-item.active.focused{outline:1px solid #ffffff80}.tabulator-edit-list .tabulator-edit-list-item.focused{outline:1px solid #1d68cd}@media (hover:hover) and (pointer:fine){.tabulator-edit-list .tabulator-edit-list-item:hover{color:#fff;cursor:pointer;background:#1d68cd}}.tabulator-edit-list .tabulator-edit-list-placeholder{color:#333;text-align:center;padding:4px}.tabulator-edit-list .tabulator-edit-list-group{color:#333;border-bottom:1px solid #aaa;padding:6px 4px 4px;font-weight:700}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-2,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-2{padding-left:12px}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-3,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-3{padding-left:20px}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-4,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-4{padding-left:28px}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-5,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-5{padding-left:36px}.tabulator.tabulator-ltr{direction:ltr}.tabulator.tabulator-rtl{text-align:initial;direction:rtl}.tabulator.tabulator-rtl .tabulator-header .tabulator-col{border-left:1px solid #aaa;border-right:initial;text-align:initial}.tabulator.tabulator-rtl .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols{margin-left:-1px;margin-right:0}.tabulator.tabulator-rtl .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title{padding-left:25px;padding-right:0}.tabulator.tabulator-rtl .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter{left:8px;right:auto}.tabulator.tabulator-rtl .tabulator-tableholder .tabulator-range-overlay .tabulator-range.tabulator-range-active:after{content:"";background-color:#2975dd;border-radius:999px;width:6px;height:6px;position:absolute;bottom:-3px;left:-3px;right:auto}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell{border-left:1px solid #aaa;border-right:initial}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell .tabulator-data-tree-branch{border-left:initial;border-right:2px solid #aaa;border-bottom-right-radius:1px;border-bottom-left-radius:0;margin-left:5px;margin-right:0}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell .tabulator-data-tree-control{margin-left:5px;margin-right:0}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-left{border-left:2px solid #aaa}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-right{border-right:2px solid #aaa}.tabulator.tabulator-rtl .tabulator-row .tabulator-col-resize-handle:last-of-type{width:3px;margin-left:0;margin-right:-3px}.tabulator.tabulator-rtl .tabulator-footer .tabulator-calcs-holder{text-align:initial}.tabulator-print-fullscreen{z-index:10000;position:absolute;inset:0}body.tabulator-print-fullscreen-hide>:not(.tabulator-print-fullscreen){display:none!important}.tabulator-print-table{border-collapse:collapse}.tabulator-print-table .tabulator-data-tree-branch{vertical-align:middle;border-bottom:2px solid #aaa;border-left:2px solid #aaa;border-bottom-left-radius:1px;width:7px;height:9px;margin-top:-9px;margin-right:5px;display:inline-block}.tabulator-print-table .tabulator-print-table-group{box-sizing:border-box;background:#ccc;border-top:1px solid #999;border-bottom:1px solid #999;border-right:1px solid #aaa;min-width:100%;padding:5px 5px 5px 10px;font-weight:700}@media (hover:hover) and (pointer:fine){.tabulator-print-table .tabulator-print-table-group:hover{cursor:pointer;background-color:#0000001a}}.tabulator-print-table .tabulator-print-table-group.tabulator-group-visible .tabulator-arrow{border:6px solid #0000;border-top-color:#666;border-bottom:0;margin-right:10px}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-1 td{padding-left:30px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-2 td{padding-left:50px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-3 td{padding-left:70px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-4 td{padding-left:90px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-5 td{padding-left:110px!important}.tabulator-print-table .tabulator-print-table-group .tabulator-group-toggle{display:inline-block}.tabulator-print-table .tabulator-print-table-group .tabulator-arrow{vertical-align:middle;border:6px solid #0000;border-left-color:#666;border-right:0;width:0;height:0;margin-right:16px;display:inline-block}.tabulator-print-table .tabulator-print-table-group span{color:#d00;margin-left:10px}.tabulator-print-table .tabulator-data-tree-control{vertical-align:middle;background:#0000001a;border:1px solid #333;border-radius:2px;justify-content:center;align-items:center;width:11px;height:11px;margin-right:5px;display:inline-flex;overflow:hidden}@media (hover:hover) and (pointer:fine){.tabulator-print-table .tabulator-data-tree-control:hover{cursor:pointer;background:#0003}}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-collapse{background:0 0;width:1px;height:7px;display:inline-block;position:relative}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after{content:"";background:#333;width:7px;height:1px;position:absolute;top:3px;left:-3px}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-expand{background:#333;width:1px;height:7px;display:inline-block;position:relative}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-expand:after{content:"";background:#333;width:7px;height:1px;position:absolute;top:3px;left:-3px}
22
22
  </style><style>
23
- :host,#panel{background:var(--bkg-color);height:16rem;min-height:10rem}#panel{inset:0;overflow:hidden}#gutter{background:var(--bkg-color);cursor:row-resize;width:100%;height:.4rem;position:absolute;top:0;left:0}#gutter:hover{background:var(--bkg-color-grad1)}#gutter:after{content:" ";background:var(--bkg-color-grad1);border-radius:1rem;width:4rem;height:.4rem;display:block;position:relative;left:calc(50% - 2rem)}#close{color:#777;background-color:var(--bkg-color);cursor:pointer;border:none;width:1rem;height:1rem;margin:.5rem;padding:0;line-height:1rem;position:absolute;top:6px;right:0}#close i:before{content:"uf00d"}#close:hover{color:#000;border-color:#000}#content{background:var(--bkg-color);flex-direction:column;margin:0 .5rem .5rem;padding:0;display:flex;position:absolute;inset:.5rem 0 0;overflow:hidden}#header{flex:0;justify-content:space-between;display:flex}.selection-panel{margin-right:.5rem;display:flex;& .gg-icon-button[disabled]{pointer-events:none;opacity:.5}& .gg-icon-button[disabled]:hover{background-color:#0000}& .label{align-self:center;padding-left:1rem}}.gg-tabs{margin:0}#grid{flex:1;overflow:hidden}.geo-type{margin-right:.5rem}::-webkit-scrollbar{width:8px}::-webkit-scrollbar-thumb{background:#999}.tiny-margin{margin:.1rem}.tabulator-col[aria-sort=none] .tabulator-col-sorter i{color:#999}.tabulator-col[aria-sort=asc] .tabulator-col-sorter i{color:red}.tabulator-col[aria-sort=desc] .tabulator-col-sorter i{color:red;transform:scaleY(-1)}#tabulator{background-color:var(--bkg-color)}#tabulator .tabulator-header .tabulator-col-content{background-color:var(--bkg-color);color:var(--text-color)}#tabulator .tabulator-header .tabulator-col,#tabulator .tabulator-header .tabulator-col-row-handle{white-space:normal}#tabulator .tabulator-tableholder .tabulator-table .tabulator-row{background-color:var(--bkg-color);color:var(--text-color)}#tabulator .tabulator-tableholder .tabulator-table .tabulator-row:nth-child(2n){background-color:var(--bkg-color-grad1)}#tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-selected{background-color:#9abcea}.tabulator{font-size:inherit!important}.tabulator-cell{text-wrap:pretty!important;height:fit-content!important}.tabulator-cell a{width:inherit;height:inherit}.tabulator-cell img{width:inherit;height:inherit;object-fit:scale-down;float:left;max-height:3rem;margin-right:.5rem}.tabulator-cell span{align-items:center;line-height:1.5rem;display:inline-flex;position:relative}.tabulator-cell span sup{position:absolute;top:-.3rem;right:-.5rem}@media (hover:hover) and (pointer:fine){#tabulator .tabulator-tableholder .tabulator-table{& .tabulator-row:hover{cursor:pointer;background-color:var(--bkg-color-grad2);&.tabulator-selected{background-color:#769bcc}}}}img.sort-icon{width:1rem;height:1rem;&.default{opacity:.5}&:hover{opacity:1}}
23
+ :host,#panel{background:var(--bkg-color);height:16rem;min-height:10rem}#panel{inset:0;overflow:hidden}#gutter{background:var(--bkg-color);cursor:row-resize;width:100%;height:.4rem;position:absolute;top:0;left:0}#gutter:hover{background:var(--bkg-color-grad1)}#gutter:after{content:" ";background:var(--bkg-color-grad1);border-radius:1rem;width:4rem;height:.4rem;display:block;position:relative;left:calc(50% - 2rem)}#close{color:#777;background-color:var(--bkg-color);cursor:pointer;border:none;width:1rem;height:1rem;margin:.5rem;padding:0;line-height:1rem;position:absolute;top:6px;right:0}#close i:before{content:"uf00d"}#close:hover{color:#000;border-color:#000}#content{background:var(--bkg-color);flex-direction:column;margin:0 .5rem .5rem;padding:0;display:flex;position:absolute;inset:.5rem 0 0;overflow:hidden}#header{flex:0;justify-content:space-between;display:flex}.selection-panel{max-height:calc(var(--app-standard-height) / 1.2);margin-right:.5rem;display:flex;& .gg-icon-button[disabled]{pointer-events:none;opacity:.5}& .gg-icon-button[disabled]:hover{background-color:#0000}& .label{color:var(--text-color);align-self:center;padding-left:1rem}}.gg-tabs{margin:0}#grid{flex:1;overflow:hidden}.geo-type{margin-right:.5rem}::-webkit-scrollbar{width:8px}::-webkit-scrollbar-thumb{background:#999}.tiny-margin{margin:.1rem}.tabulator-col[aria-sort=none] .tabulator-col-sorter i{color:#999}.tabulator-col[aria-sort=asc] .tabulator-col-sorter i{color:red}.tabulator-col[aria-sort=desc] .tabulator-col-sorter i{color:red;transform:scaleY(-1)}#tabulator{background-color:var(--bkg-color)}#tabulator .tabulator-header .tabulator-col-content{background-color:var(--bkg-color);color:var(--text-color)}#tabulator .tabulator-header .tabulator-col,#tabulator .tabulator-header .tabulator-col-row-handle{white-space:normal}#tabulator .tabulator-tableholder .tabulator-table .tabulator-row{background-color:var(--bkg-color);color:var(--text-color)}#tabulator .tabulator-tableholder .tabulator-table .tabulator-row:nth-child(2n){background-color:var(--bkg-color-grad1)}#tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-selected{background-color:#9abcea}.tabulator{font-size:inherit!important}.tabulator-cell{text-wrap:pretty!important;height:fit-content!important}.tabulator-cell a{width:inherit;height:inherit}.tabulator-cell img{width:inherit;height:inherit;object-fit:scale-down;float:left;max-height:3rem;margin-right:.5rem}.tabulator-cell span{align-items:center;line-height:1.5rem;display:inline-flex;position:relative}.tabulator-cell span sup{position:absolute;top:-.3rem;right:-.5rem}@media (hover:hover) and (pointer:fine){#tabulator .tabulator-tableholder .tabulator-table{& .tabulator-row:hover{cursor:pointer;background-color:var(--bkg-color-grad2);&.tabulator-selected{background-color:#769bcc}}}}img.sort-icon{width:1rem;height:1rem;&.default{opacity:.5}&:hover{opacity:1}}
24
24
  </style>
25
25
  <style>${this.customStyle}</style>
26
26
  <div id="panel"><div id="content"><div id="header"><div class="gg-tabs">${this.getTabHeaders().map((th) => uHtml ` <button id="${th.id}" i18n="${th.text}" class="${th.active ? 'gg-tab active' : 'gg-tab'}" .active="${th.active}" onclick="${() => this.displayGrid(th.id, true)}"></button> `)}</div><div class="selection-panel"><span class="label" i18n="Selection"></span> <button class="gg-icon-button gg-medium" onclick="${() => this.selectAll()}" tip="Select all"><img alt="select all icon" src="icons/select-all-on.svg"></button> <button class="gg-icon-button gg-medium" onclick="${() => this.selectNone()}" tip="Select none"><img alt="select none icon" src="icons/select-all-off.svg"></button> <button class="gg-icon-button gg-medium" onclick="${() => this.invertSelection()}" tip="Invert selection"><img alt="invert selection icon" src="icons/select-invert.svg"></button><girafe-get-directions></girafe-get-directions><button class="${this.resultsSelected ? 'gg-icon-button gg-medium' : 'gg-icon-button gg-medium disabled'}" ?disabled="${!this.resultsSelected}" onclick="${() => this.zoomToSelection()}" tip="Zoom to"><img alt="zoom to selection icon" src="icons/zoom-to-selection.svg"></button> <button class="${this.resultsSelected ? 'gg-icon-button gg-medium' : 'gg-icon-button gg-medium disabled'}" ?disabled="${!this.resultsSelected}" onclick="${() => this.generateCSV()}" tip="Generate CSV"><img alt="download csv icon" src="icons/arrow-download.svg"></button> <button class="gg-icon-button gg-medium" onclick="${() => this.closePanel()}" tip="Clear results and close Panel"><img alt="close-icon" src="icons/close.svg"></button></div></div><div id="tabulator"></div></div><div id="gutter"></div></div>
@@ -81,6 +81,7 @@
81
81
  .selection-panel {
82
82
  margin-right: 0.5rem;
83
83
  display: flex;
84
+ max-height: calc(var(--app-standard-height) / 1.2);
84
85
 
85
86
  .gg-icon-button[disabled] {
86
87
  pointer-events: none;
@@ -91,6 +92,7 @@
91
92
  }
92
93
 
93
94
  .label {
95
+ color: var(--text-color);
94
96
  align-self: center;
95
97
  padding-left: 1rem;
96
98
  }
@@ -26,5 +26,5 @@ export default class SelectionPanelMobile extends GirafeHTMLElement {
26
26
  * Return the name of the WMS query layer of a given feature
27
27
  * (using FeatureToGridDataById.getUserFeatureType directly from the template)
28
28
  */
29
- static getFeatureLayerName(feature: Feature): string;
29
+ getFeatureLayerName(feature: Feature): string;
30
30
  }
@@ -27,7 +27,7 @@ export default class SelectionPanelMobile extends GirafeHTMLElement {
27
27
  .full-width-height{width:100%;height:100%}.container{scroll-snap-type:x mandatory;scrollbar-width:none;-ms-overflow-style:none;width:100%;height:calc(100% - 60px - env(safe-area-inset-bottom) / 2);grid-auto-columns:100%;grid-auto-flow:column;gap:10px;display:grid;overflow-x:auto}.container::-webkit-scrollbar{display:none}.single-feature{scroll-snap-align:center;box-sizing:border-box;background-color:#ffffff61;border:1px solid #277aff3f;border-radius:10px;width:100%;padding:15px;position:relative;overflow-y:scroll}.pagination{width:100%;height:60px;margin-bottom:calc(env(safe-area-inset-bottom) / 2);border-radius:20px;position:relative}.nav-bt{width:fit-content;height:fit-content;margin:auto;top:0;bottom:0}.nav-bt>img{width:40px;height:40px}.previous-bt{position:absolute;left:70px}.next-bt{position:absolute;right:70px}.next-fast-bt{position:absolute;right:0}.previous-fast-bt{position:absolute;left:0}.next-fast-bt>img,.previous-fast-bt>img{width:50px;height:50px}.nav-indicator{text-align:center;color:#606368;font-size:2em;font-weight:600}.nav-center-wrapper{align-items:center;width:fit-content;height:fit-content;margin:auto;display:flex;position:absolute;inset:0}.feature-property-key-value{margin-bottom:1.5em;font-size:1.3em}.feature-property-key{color:#a9a9a9;font-weight:900}.layer-name{color:#277aff;text-align:center;background-color:#277aff29;border-radius:5px;width:100%;margin-bottom:1.5em;padding:.5em 0;font-size:1.5em}.layer-icon{filter:brightness(10);height:25px;margin-bottom:-6px;margin-right:5px}.feature-property-value{overflow-x:hidden;text-overflow:ellipsis!important}
28
28
  </style>
29
29
  <style>${this.customStyle}</style>
30
- <div class="full-width-height" style="${this.state.interface.swipeupPanelContent === 'features' ? '' : 'display: none;'}"><div class="container">${this.state.selection.selectedFeatures.filter((feature) => feature !== undefined).map((feature) => uHtml `<div class="single-feature"><div class="layer-name"><img class="layer-icon" alt="layer icon" src="icons/themes.svg"> <span i18n="${SelectionPanelMobile.getFeatureLayerName(feature)}"></span></div>${Object.entries(feature.getProperties()).filter((keyValue) => typeof keyValue[1] === "boolean" || typeof keyValue[1] === "string" || typeof keyValue[1] === "number").map((keyValue) => uHtml `<div class="feature-property-key-value"><div class="feature-property-key" i18n="${keyValue[0]}"></div><div class="feature-property-value" i18n="${getLinkFriendlyString(keyValue[1])}"></div></div>`)}<div class="feature-property-key-value"><div class="feature-property-key" i18n="Geometry type"></div><div class="feature-property-value">${feature.getGeometry()?.getType()}</div></div></div>`)}</div><div class="pagination"><div class="nav-bt previous-fast-bt" onpointerup="${() => this.touchChangeSlide(-20)}" style="${this.currentIndex <= 0 ? 'opacity: 0.3' : ''}"><img alt="Fast previous button" src="icons/arrow_left.svg"></div><div class="nav-bt previous-bt" onpointerup="${() => this.touchChangeSlide(-1)}" style="${this.currentIndex <= 0 ? 'opacity: 0.3' : ''}"><img alt="Previous button" src="icons/arrow_left.svg"></div><div class="nav-bt next-bt" onpointerup="${() => this.touchChangeSlide(1)}" style="${this.currentIndex >= (this.state.selection.selectedFeatures.length - 1) ? 'opacity: 0.3' : ''}"><img alt="Fast next button" src="icons/arrow_right.svg"></div><div class="nav-bt next-fast-bt" onpointerup="${() => this.touchChangeSlide(20)}" style="${this.currentIndex >= (this.state.selection.selectedFeatures.length - 1) ? 'opacity: 0.3' : ''}"><img alt="Fast next button" src="icons/arrow_right.svg"></div><div class="nav-center-wrapper"><div class="nav-indicator">${`${this.currentIndex + 1}/${this.state.selection.selectedFeatures.length}`}</div><girafe-get-directions></girafe-get-directions></div></div></div>
30
+ <div class="full-width-height" style="${this.state.interface.swipeupPanelContent === 'features' ? '' : 'display: none;'}"><div class="container">${this.state.selection.selectedFeatures.filter((feature) => feature !== undefined).map((feature) => uHtml `<div class="single-feature"><div class="layer-name"><img class="layer-icon" alt="layer icon" src="icons/themes.svg"> <span i18n="${this.getFeatureLayerName(feature)}"></span></div>${Object.entries(feature.getProperties()).filter((keyValue) => typeof keyValue[1] === "boolean" || typeof keyValue[1] === "string" || typeof keyValue[1] === "number").map((keyValue) => uHtml `<div class="feature-property-key-value"><div class="feature-property-key" i18n="${keyValue[0]}"></div><div class="feature-property-value" i18n="${getLinkFriendlyString(keyValue[1])}"></div></div>`)}<div class="feature-property-key-value"><div class="feature-property-key" i18n="Geometry type"></div><div class="feature-property-value">${feature.getGeometry()?.getType()}</div></div></div>`)}</div><div class="pagination"><div class="nav-bt previous-fast-bt" onpointerup="${() => this.touchChangeSlide(-20)}" style="${this.currentIndex <= 0 ? 'opacity: 0.3' : ''}"><img alt="Fast previous button" src="icons/arrow_left.svg"></div><div class="nav-bt previous-bt" onpointerup="${() => this.touchChangeSlide(-1)}" style="${this.currentIndex <= 0 ? 'opacity: 0.3' : ''}"><img alt="Previous button" src="icons/arrow_left.svg"></div><div class="nav-bt next-bt" onpointerup="${() => this.touchChangeSlide(1)}" style="${this.currentIndex >= (this.state.selection.selectedFeatures.length - 1) ? 'opacity: 0.3' : ''}"><img alt="Fast next button" src="icons/arrow_right.svg"></div><div class="nav-bt next-fast-bt" onpointerup="${() => this.touchChangeSlide(20)}" style="${this.currentIndex >= (this.state.selection.selectedFeatures.length - 1) ? 'opacity: 0.3' : ''}"><img alt="Fast next button" src="icons/arrow_right.svg"></div><div class="nav-center-wrapper"><div class="nav-indicator">${`${this.currentIndex + 1}/${this.state.selection.selectedFeatures.length}`}</div><girafe-get-directions></girafe-get-directions></div></div></div>
31
31
  ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
32
32
  };
33
33
  currentIndex = 0;
@@ -138,7 +138,7 @@ ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
138
138
  * Return the name of the WMS query layer of a given feature
139
139
  * (using FeatureToGridDataById.getUserFeatureType directly from the template)
140
140
  */
141
- static getFeatureLayerName(feature) {
142
- return FeatureToGridDataById.getUserFeatureType(feature);
141
+ getFeatureLayerName(feature) {
142
+ return FeatureToGridDataById.getUserFeatureType(feature, this.context);
143
143
  }
144
144
  }
package/models/gmf.d.ts CHANGED
@@ -45,7 +45,7 @@ export interface GMFTreeItem {
45
45
  mixed?: boolean;
46
46
  ogcServer?: string;
47
47
  children?: GMFTreeItem[];
48
- type?: 'OSM' | 'WMS' | 'WMTS' | 'VectorTiles' | 'COG' | 'XYZ';
48
+ type?: 'OSM' | 'WMS' | 'WMTS' | 'VectorTiles' | 'COG' | 'XYZ' | 'GeoJSON';
49
49
  url?: string;
50
50
  style?: string;
51
51
  source?: string;
@@ -43,9 +43,14 @@ class GroupLayer extends BaseLayer {
43
43
  clonedObject.timeRestriction = this.timeRestriction;
44
44
  // Clone children
45
45
  for (const child of this.children) {
46
- const clonedChild = child.clone();
47
- clonedChild.parent = clonedObject;
48
- clonedObject.children.push(clonedChild);
46
+ try {
47
+ const clonedChild = child.clone();
48
+ clonedChild.parent = clonedObject;
49
+ clonedObject.children.push(clonedChild);
50
+ }
51
+ catch {
52
+ console.warn(`Cloning child ${child.name} of group ${this.name} isn't supported`);
53
+ }
49
54
  }
50
55
  return clonedObject;
51
56
  }
@@ -10,7 +10,11 @@ declare class LayerLocalFile extends Layer implements ILayerWithLegend {
10
10
  isLegendExpanded: boolean;
11
11
  wasLegendExpanded: boolean;
12
12
  extent: Extent;
13
- constructor(file: File, features: Feature<Geometry>[], extent: Extent, locale: string);
13
+ private readonly file;
14
+ private readonly locale;
15
+ constructor(id: number, order: number, file: File, features: Feature<Geometry>[], extent: Extent, locale: string, options?: {
16
+ isDefaultChecked?: boolean;
17
+ });
14
18
  clone(): LayerLocalFile;
15
19
  }
16
20
  export default LayerLocalFile;
@@ -13,16 +13,27 @@ class LayerLocalFile extends Layer {
13
13
  isLegendExpanded;
14
14
  wasLegendExpanded;
15
15
  extent;
16
- constructor(file, features, extent, locale) {
17
- super(0, file.name, 0, { isDefaultChecked: true });
16
+ file;
17
+ locale;
18
+ constructor(id, order, file, features, extent, locale, options) {
19
+ super(id, file.name, order, { isDefaultChecked: options?.isDefaultChecked ?? true });
18
20
  this._features = features;
19
21
  this.extent = extent;
22
+ this.file = file;
23
+ this.locale = locale;
20
24
  this.lastModifiedDate = new Date(file.lastModified).toLocaleDateString(locale);
21
25
  this.isLegendExpanded = true;
22
26
  this.wasLegendExpanded = false;
23
27
  }
24
28
  clone() {
25
- throw new Error('Cannot clone layer for local file.');
29
+ const clonedObject = new LayerLocalFile(this.id, this.order, this.file, this._features, this.extent, this.locale, {
30
+ isDefaultChecked: this.isDefaultChecked
31
+ });
32
+ clonedObject.activeState = this.activeState;
33
+ clonedObject.opacity = this.opacity;
34
+ clonedObject.isLegendExpanded = this.isLegendExpanded;
35
+ clonedObject.wasLegendExpanded = this.wasLegendExpanded;
36
+ return clonedObject;
26
37
  }
27
38
  }
28
39
  export default LayerLocalFile;
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "name": "GeoGirafe PSC",
6
6
  "url": "https://doc.geogirafe.org"
7
7
  },
8
- "version": "1.2.0-dev.2791536378",
8
+ "version": "1.2.0-dev.2794025939",
9
9
  "type": "module",
10
10
  "engines": {
11
11
  "node": ">=20.19.0"
@@ -1 +1 @@
1
- {"version":"1.2.0-dev.2791536378", "build":"2791536378", "date":"26/08/2026"}
1
+ {"version":"1.2.0-dev.2794025939", "build":"2794025939", "date":"26/08/2026"}
@@ -65,5 +65,9 @@ export default class FeatureToGridDataById {
65
65
  * @static
66
66
  */
67
67
  private static findEmptyColumnIndexOf;
68
- static getUserFeatureType(feature: OlFeature): string;
68
+ /**
69
+ * Returns the feature type extracted from the feature's WFS-style id
70
+ * falls back to the name of the LayerLocalFile.
71
+ */
72
+ static getUserFeatureType(feature: OlFeature, context?: IGirafeContext): string;
69
73
  }
@@ -33,7 +33,7 @@ export default class FeatureToGridDataById {
33
33
  * @private
34
34
  */
35
35
  addFeatureToGridDataById(gridDataById, feature) {
36
- const featureType = FeatureToGridDataById.getUserFeatureType(feature);
36
+ const featureType = FeatureToGridDataById.getUserFeatureType(feature, this.context);
37
37
  let notOlProperties = removeUnwantedOlParams(feature, this.options.keepGeomProperty);
38
38
  if (!Object.keys(notOlProperties).length) {
39
39
  // Don't keep feature without properties.
@@ -115,7 +115,16 @@ export default class FeatureToGridDataById {
115
115
  });
116
116
  return emptyColumnIndexes;
117
117
  }
118
- static getUserFeatureType(feature) {
119
- return WfsManager.extractFeatureTypeFromId(feature);
118
+ /**
119
+ * Returns the feature type extracted from the feature's WFS-style id
120
+ * falls back to the name of the LayerLocalFile.
121
+ */
122
+ static getUserFeatureType(feature, context) {
123
+ const featureType = WfsManager.extractFeatureTypeFromId(feature);
124
+ if (featureType !== WfsManager.UnknownFeatureType) {
125
+ return featureType;
126
+ }
127
+ const localFileLayer = context?.localFileManager.getLayerForFeature(feature);
128
+ return localFileLayer?.name ?? featureType;
120
129
  }
121
130
  }
@@ -11,6 +11,7 @@ declare class LocalFileManager extends GirafeSingleton {
11
11
  private readonly supportedFileFormats;
12
12
  private readonly supportedFileExtensions;
13
13
  private activeLayers;
14
+ private readonly featureLayerMap;
14
15
  constructor(context: IGirafeContext);
15
16
  initializeSingleton(): void;
16
17
  private registerEvents;
@@ -21,6 +22,7 @@ declare class LocalFileManager extends GirafeSingleton {
21
22
  private splitIntoSimpleGeometries;
22
23
  private handleUnsupportedFiles;
23
24
  private validateAndCompleteFeatures;
25
+ private buildFeatureStyle;
24
26
  addLayer(layerFile: LayerLocalFile): void;
25
27
  getLayer(layerFile: LayerLocalFile): VectorLayer<VectorSource<Feature<Geometry, {
26
28
  [x: string]: any;
@@ -29,6 +31,10 @@ declare class LocalFileManager extends GirafeSingleton {
29
31
  }>> | null;
30
32
  removeLayer(layerFile: LayerLocalFile): void;
31
33
  layerExists(layer: LayerLocalFile): boolean;
34
+ /**
35
+ * Returns the LayerLocalFile a given feature belongs to
36
+ */
37
+ getLayerForFeature(feature: Feature<Geometry>): LayerLocalFile | undefined;
32
38
  selectFeatures(extent: number[]): void;
33
39
  changeOpacity(layer: LayerLocalFile): void;
34
40
  }
@@ -5,6 +5,7 @@ import DragAndDrop from 'ol/interaction/DragAndDrop.js';
5
5
  import { GPX, GeoJSON, IGC, KML, TopoJSON } from 'ol/format.js';
6
6
  import { Vector as VectorLayer } from 'ol/layer.js';
7
7
  import { Vector as VectorSource } from 'ol/source.js';
8
+ import { Circle, Fill, Stroke, Style } from 'ol/style.js';
8
9
  import LayerLocalFile from '../../models/layers/layerlocalfile.js';
9
10
  import { extend, intersects } from 'ol/extent.js';
10
11
  import { applyFeaturesToSelection } from '../utils/utils.js';
@@ -16,6 +17,9 @@ class LocalFileManager extends GirafeSingleton {
16
17
  supportedFileFormats = [GPX, GeoJSON, IGC, new KML({ extractStyles: true }), TopoJSON];
17
18
  supportedFileExtensions = ['gpx', 'geojson', 'igc', 'kml', 'topojson', 'json'];
18
19
  activeLayers = {};
20
+ // Keeps track of which LayerLocalFile a given feature belongs to, so its layer name can be
21
+ // used as a display fallback when the feature has no WFS-style id
22
+ featureLayerMap = new WeakMap();
19
23
  constructor(context) {
20
24
  super(context);
21
25
  this.map = this.context.mapManager.getMap();
@@ -75,7 +79,7 @@ class LocalFileManager extends GirafeSingleton {
75
79
  window.gAlert(msg, title);
76
80
  return;
77
81
  }
78
- const layer = new LayerLocalFile(localFile, acceptableFeatures.features, acceptableFeatures.globalExtent, this.context.configManager.Config.general.locale);
82
+ const layer = new LayerLocalFile(0, 0, localFile, acceptableFeatures.features, acceptableFeatures.globalExtent, this.context.configManager.Config.general.locale);
79
83
  if (features && features.length > acceptableFeatures.features.length) {
80
84
  // Some features are outer extent
81
85
  layer.hasError = true;
@@ -167,15 +171,29 @@ class LocalFileManager extends GirafeSingleton {
167
171
  globalExtent: globalExtent
168
172
  };
169
173
  }
174
+ buildFeatureStyle() {
175
+ const drawingConfig = this.context.configManager.Config.drawing;
176
+ return new Style({
177
+ fill: new Fill({ color: drawingConfig.defaultFillColor }),
178
+ stroke: new Stroke({ color: drawingConfig.defaultStrokeColor, width: drawingConfig.defaultStrokeWidth }),
179
+ image: new Circle({
180
+ radius: 10,
181
+ fill: new Fill({ color: drawingConfig.defaultFillColor }),
182
+ stroke: new Stroke({ color: drawingConfig.defaultStrokeColor, width: drawingConfig.defaultStrokeWidth })
183
+ })
184
+ });
185
+ }
170
186
  addLayer(layerFile) {
171
187
  const vectorSource = new VectorSource({
172
188
  features: layerFile._features
173
189
  });
174
190
  const olayer = new VectorLayer({
175
- source: vectorSource
191
+ source: vectorSource,
192
+ style: this.buildFeatureStyle()
176
193
  });
177
194
  this.map.addLayer(olayer);
178
195
  this.activeLayers[layerFile.treeItemId] = { layerFile: layerFile, olayer: olayer };
196
+ layerFile._features.forEach((feature) => this.featureLayerMap.set(feature, layerFile));
179
197
  }
180
198
  getLayer(layerFile) {
181
199
  if (this.layerExists(layerFile)) {
@@ -188,6 +206,7 @@ class LocalFileManager extends GirafeSingleton {
188
206
  const olayer = this.activeLayers[layerFile.treeItemId].olayer;
189
207
  delete this.activeLayers[layerFile.treeItemId];
190
208
  this.map.removeLayer(olayer);
209
+ layerFile._features.forEach((feature) => this.featureLayerMap.delete(feature));
191
210
  }
192
211
  else {
193
212
  throw new Error('Cannot remove this layer: it does not exist');
@@ -196,6 +215,12 @@ class LocalFileManager extends GirafeSingleton {
196
215
  layerExists(layer) {
197
216
  return layer.treeItemId in this.activeLayers;
198
217
  }
218
+ /**
219
+ * Returns the LayerLocalFile a given feature belongs to
220
+ */
221
+ getLayerForFeature(feature) {
222
+ return this.featureLayerMap.get(feature);
223
+ }
199
224
  selectFeatures(extent) {
200
225
  for (const activeLayer of Object.values(this.activeLayers)) {
201
226
  const features = activeLayer.olayer.getSource()?.getFeaturesInExtent(extent);
@@ -35,6 +35,11 @@ declare class ThemesManager extends GirafeSingleton {
35
35
  */
36
36
  private prepareThemeLayer;
37
37
  private createGroup;
38
+ /**
39
+ * Reads a GeoJSON file referenced directly by url in the themes.json (elem.url)
40
+ * Not supported by GMF backend.
41
+ */
42
+ private createGeoJsonLayer;
38
43
  private createWmsLayer;
39
44
  private createWmtsLayer;
40
45
  private createVectorTilesLayer;
@@ -1,5 +1,7 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  import { v4 as uuidv4 } from 'uuid';
3
+ import { GeoJSON } from 'ol/format.js';
4
+ import { createEmpty, extend } from 'ol/extent.js';
3
5
  import GirafeSingleton from '../../base/GirafeSingleton.js';
4
6
  import Basemap from '../../models/basemaps/basemap.js';
5
7
  import GroupLayer from '../../models/layers/grouplayer.js';
@@ -9,6 +11,7 @@ import LayerWmts from '../../models/layers/layerwmts.js';
9
11
  import LayerWms from '../../models/layers/layerwms.js';
10
12
  import LayerCog from '../../models/layers/layercog.js';
11
13
  import LayerXYZ from '../../models/layers/layerxyz.js';
14
+ import LayerLocalFile from '../../models/layers/layerlocalfile.js';
12
15
  import ServerOgc from '../../models/serverogc.js';
13
16
  import ThemeLayer from '../../models/layers/themelayer.js';
14
17
  import BasemapEmpty from '../../models/basemaps/basemapempty.js';
@@ -97,8 +100,8 @@ class ThemesManager extends GirafeSingleton {
97
100
  const response = await fetch(this.context.configManager.Config.themes.url);
98
101
  const content = await response.json();
99
102
  this.state.ogcServers = this.prepareOgcServers(content['ogcServers']);
100
- this.state.basemaps = this.prepareBasemaps(content['background_layers']);
101
- const themesAndFunctionalities = this.prepareThemes(content['themes']);
103
+ this.state.basemaps = await this.prepareBasemaps(content['background_layers']);
104
+ const themesAndFunctionalities = await this.prepareThemes(content['themes']);
102
105
  this.state.themes._allThemes = themesAndFunctionalities.themes;
103
106
  this.state.themes._allFunctionalities = themesAndFunctionalities.themesFunctionalities;
104
107
  this.context.customThemesManager.loadCustomThemes();
@@ -160,7 +163,7 @@ class ThemesManager extends GirafeSingleton {
160
163
  }
161
164
  }
162
165
  }
163
- prepareBasemaps(basemapJson) {
166
+ async prepareBasemaps(basemapJson) {
164
167
  const basemaps = {};
165
168
  if (this.context.configManager.Config.basemaps.emptyBasemap) {
166
169
  const basemapEmpty = new BasemapEmpty();
@@ -174,12 +177,12 @@ class ThemesManager extends GirafeSingleton {
174
177
  const basemapSwisstopoVectorTiles = new BasemapSwisstopoVectorTiles();
175
178
  basemaps[basemapSwisstopoVectorTiles.id] = basemapSwisstopoVectorTiles;
176
179
  }
177
- this.addBasemapsFromConfig(basemapJson, basemaps);
180
+ await this.addBasemapsFromConfig(basemapJson, basemaps);
178
181
  this.applyOpacityToBasemaps(basemaps);
179
182
  return basemaps;
180
183
  }
181
- addBasemapsFromConfig(basemapsJson, basemaps) {
182
- basemapsJson.forEach((elem) => {
184
+ async addBasemapsFromConfig(basemapsJson, basemaps) {
185
+ for (const elem of basemapsJson) {
183
186
  // Create basemap
184
187
  const basemap = new Basemap(elem);
185
188
  basemaps[basemap.id] = basemap;
@@ -187,21 +190,21 @@ class ThemesManager extends GirafeSingleton {
187
190
  const order = { value: 0 };
188
191
  if (elem.children) {
189
192
  // Multiple layers
190
- elem.children.forEach((child) => {
191
- const layer = this.prepareThemeLayer(child, null, order);
193
+ for (const child of elem.children) {
194
+ const layer = await this.prepareThemeLayer(child, null, order);
192
195
  if (layer) {
193
196
  basemap.layersList.push(layer);
194
197
  }
195
- });
198
+ }
196
199
  }
197
200
  else {
198
201
  // Only one layer in this basemap
199
- const layer = this.prepareThemeLayer(elem, null, order);
202
+ const layer = await this.prepareThemeLayer(elem, null, order);
200
203
  if (layer) {
201
204
  basemap.layersList.push(layer);
202
205
  }
203
206
  }
204
- });
207
+ }
205
208
  }
206
209
  applyOpacityToBasemaps(basemaps) {
207
210
  for (const basemap of Object.values(basemaps)) {
@@ -226,25 +229,25 @@ class ThemesManager extends GirafeSingleton {
226
229
  }
227
230
  }
228
231
  }
229
- prepareThemes(themesJson) {
232
+ async prepareThemes(themesJson) {
230
233
  const themes = {};
231
234
  const order = { value: 0 };
232
235
  const themesFunctionalities = {};
233
- themesJson.forEach((themeJson, index) => {
236
+ for (const [index, themeJson] of themesJson.entries()) {
234
237
  if (!themeJson.icon.startsWith('http') && this.context.configManager.Config.themes.imagesUrlPrefix) {
235
238
  themeJson.icon = this.context.configManager.Config.themes.imagesUrlPrefix + themeJson.icon;
236
239
  }
237
240
  themesFunctionalities[themeJson.id] = themeJson['functionalities'];
238
241
  const theme = new ThemeLayer(themeJson['id'], themeJson['name'], index, themeJson['icon'], themeJson['metadata']);
239
- themeJson.children.forEach((layerJson) => {
240
- const layer = this.prepareThemeLayer(layerJson, null, order);
242
+ for (const layerJson of themeJson.children) {
243
+ const layer = await this.prepareThemeLayer(layerJson, null, order);
241
244
  if (layer) {
242
245
  layer.parent = theme;
243
246
  theme.children.push(layer);
244
247
  }
245
- });
248
+ }
246
249
  themes[index] = theme;
247
- });
250
+ }
248
251
  return { themes, themesFunctionalities };
249
252
  }
250
253
  /**
@@ -254,7 +257,7 @@ class ThemesManager extends GirafeSingleton {
254
257
  * @param order the order in the layer list
255
258
  * @returns the created girafe layer
256
259
  */
257
- prepareThemeLayer(elem, parentServer, order) {
260
+ async prepareThemeLayer(elem, parentServer, order) {
258
261
  // If a server is defined on this node, we use it.
259
262
  // Otherwise, we use the server of the parent
260
263
  const ogcServerName = elem.ogcServer ? elem.ogcServer : parentServer;
@@ -285,15 +288,19 @@ class ThemesManager extends GirafeSingleton {
285
288
  layer = new LayerXYZ(elem.id, elem.name, order.value, elem.url, elem);
286
289
  break;
287
290
  }
291
+ case 'GeoJSON': {
292
+ layer = await this.createGeoJsonLayer(elem, order);
293
+ break;
294
+ }
288
295
  default: {
289
296
  // Group
290
- layer = this.createGroup(elem, order, ogcServerName);
297
+ layer = await this.createGroup(elem, order, ogcServerName);
291
298
  }
292
299
  }
293
300
  order.value = order.value + 1;
294
301
  return layer;
295
302
  }
296
- createGroup(elem, order, ogcServerName) {
303
+ async createGroup(elem, order, ogcServerName) {
297
304
  const options = {
298
305
  isDefaultChecked: elem.metadata?.isChecked,
299
306
  metadataUrl: elem.metadata?.metadataUrl,
@@ -314,7 +321,7 @@ class ThemesManager extends GirafeSingleton {
314
321
  if (options.time) {
315
322
  child.time = { ...options.time };
316
323
  }
317
- const childLayer = this.prepareThemeLayer(child, ogcServerName, order);
324
+ const childLayer = await this.prepareThemeLayer(child, ogcServerName, order);
318
325
  if (childLayer) {
319
326
  childLayer.parent = group;
320
327
  group.children.push(childLayer);
@@ -323,6 +330,40 @@ class ThemesManager extends GirafeSingleton {
323
330
  }
324
331
  return group;
325
332
  }
333
+ /**
334
+ * Reads a GeoJSON file referenced directly by url in the themes.json (elem.url)
335
+ * Not supported by GMF backend.
336
+ */
337
+ async createGeoJsonLayer(elem, order) {
338
+ if (!elem.url) {
339
+ this.context.errorManager.pushMessage(uuidv4(), `GeoJSON-Layer ${elem.name} (id=${elem.id}) is invalid and cannot be created: missing url.`, 'error');
340
+ return null;
341
+ }
342
+ try {
343
+ const response = await fetch(elem.url);
344
+ const text = await response.text();
345
+ const features = new GeoJSON().readFeatures(text, {
346
+ featureProjection: this.state.projection
347
+ });
348
+ const extent = createEmpty();
349
+ for (const feature of features) {
350
+ const geometry = feature.getGeometry();
351
+ if (geometry) {
352
+ extend(extent, geometry.getExtent());
353
+ }
354
+ }
355
+ const lastModifiedHeader = response.headers.get('Last-Modified');
356
+ const lastModified = lastModifiedHeader ? new Date(lastModifiedHeader).getTime() : Date.now();
357
+ const fileName = elem.url.split('/').pop() || elem.name;
358
+ const file = new File([text], fileName, { type: 'application/geo+json', lastModified });
359
+ return new LayerLocalFile(elem.id, order.value, file, features, extent, this.context.configManager.Config.general.locale, { isDefaultChecked: elem.metadata?.isChecked });
360
+ }
361
+ catch (error) {
362
+ this.context.errorManager.pushMessage(uuidv4(), `GeoJSON-Layer ${elem.name} (id=${elem.id}) could not be loaded from ${elem.url}.`, 'error');
363
+ console.error(error);
364
+ return null;
365
+ }
366
+ }
326
367
  createWmsLayer(ogcServerName, elem, order) {
327
368
  if (ogcServerName) {
328
369
  const ogcServer = this.state.ogcServers[ogcServerName];