@geogirafe/lib-geoportal 1.2.0-dev.2646908874 → 1.2.0-dev.2657510436

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -245,6 +245,7 @@ From:
245
245
  - https://www.svgrepo.com/svg/310167/thumb-like
246
246
  - https://www.svgrepo.com/svg/310166/thumb-dislike
247
247
  - https://www.svgrepo.com/svg/309871/photo-filter
248
+ - https://www.svgrepo.com/svg/309651/full-screen-zoom
248
249
 
249
250
 
250
251
  The MIT License (MIT)
@@ -220,6 +220,8 @@
220
220
  "Freehand line": "Freihandlinie",
221
221
  "Freehand polygon": "Freihandpolygon",
222
222
  "freeze-column": "Spalte fixieren",
223
+ "fullscreen-off": "Vollbildmodus verlassen",
224
+ "fullscreen-on": "Vollbildmodus aktivieren",
223
225
  "Generate and copy code": "Code generieren und kopieren",
224
226
  "Generate and copy link": "Link generieren und kopieren",
225
227
  "Generate CSV": "CSV generieren",
@@ -351,6 +353,7 @@
351
353
  "onboarding-treeview-filter-selection-title": "Layer filtern",
352
354
  "Only WMTS layers are saved": "Nur WMTS-Layer werden gespeichert",
353
355
  "Open advanced filter tool": "Erweiterte Filter öffnen",
356
+ "open-buttonbar-menu": "Menü öffnen",
354
357
  "OpenStreetMap": "OpenStreetMap",
355
358
  "Operator": "Operator",
356
359
  "or": "oder",
@@ -222,6 +222,8 @@
222
222
  "Freehand line": "Freehand line",
223
223
  "Freehand polygon": "Freehand polygon",
224
224
  "freeze-column": "Freeze column",
225
+ "fullscreen-off": "Exit full screen",
226
+ "fullscreen-on": "Enter full screen",
225
227
  "Generate and copy code": "Generate and copy code",
226
228
  "Generate and copy link": "Generate and copy link",
227
229
  "Generate CSV": "Generate CSV",
@@ -353,6 +355,7 @@
353
355
  "onboarding-treeview-filter-selection-title": "Filter layer",
354
356
  "Only WMTS layers are saved": "Only WMTS layers are saved",
355
357
  "Open advanced filter tool": "Open advanced filter tool",
358
+ "open-buttonbar-menu": "Open Menu",
356
359
  "OpenStreetMap": "OpenStreetMap",
357
360
  "Operator": "Operator",
358
361
  "or": "or",
@@ -220,6 +220,8 @@
220
220
  "Freehand line": "Ligne à main levée",
221
221
  "Freehand polygon": "Polygone à main levée",
222
222
  "freeze-column": "Figer la colonne",
223
+ "fullscreen-off": "Quitter le plein écran",
224
+ "fullscreen-on": "Passer en plein écran",
223
225
  "Generate and copy code": "Générer et copier le code",
224
226
  "Generate and copy link": "Générer et copier le lien",
225
227
  "Generate CSV": "Générer CSV",
@@ -351,6 +353,7 @@
351
353
  "onboarding-treeview-filter-selection-title": "Filtrer les couches",
352
354
  "Only WMTS layers are saved": "Seules les couches WMTS sont sauvegardées",
353
355
  "Open advanced filter tool": "Ouvrir l'outil de filtre avancé",
356
+ "open-buttonbar-menu": "Ouvrir le menu",
354
357
  "OpenStreetMap": "OpenStreetMap",
355
358
  "Operator": "Opérateur",
356
359
  "or": "ou",
@@ -220,6 +220,8 @@
220
220
  "Freehand line": "Linea a mano libera",
221
221
  "Freehand polygon": "Poligono a mano libera",
222
222
  "freeze-column": "Blocca colonna",
223
+ "fullscreen-off": "Esci dalla modalità schermo intero",
224
+ "fullscreen-on": "Attiva la modalità schermo intero",
223
225
  "Generate and copy code": "Genera e copia il codice",
224
226
  "Generate and copy link": "Genera e copia il link",
225
227
  "Generate CSV": "Genera CSV",
@@ -351,6 +353,7 @@
351
353
  "onboarding-treeview-filter-selection-title": "Filtra i livelli",
352
354
  "Only WMTS layers are saved": "Solo i layer WMTS vengono salvati",
353
355
  "Open advanced filter tool": "Apri lo strumento di filtro avanzato",
356
+ "open-buttonbar-menu": "Apri menu",
354
357
  "OpenStreetMap": "OpenStreetMap",
355
358
  "Operator": "Operatore",
356
359
  "or": "oppure",
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="800" height="800" viewBox="0 0 24 24"><title>ic_fluent_full_screen_zoom_24_regular</title><path fill="#212121" fill-rule="nonzero" d="M16.25 15.5h4a.75.75 0 0 1 .102 1.493L20.25 17H17v3.25a.75.75 0 0 1-1.493.102l-.007-.102v-4a.75.75 0 0 1 .648-.743zh4zm-12.5 0h4a.75.75 0 0 1 .743.648l.007.102v4a.75.75 0 0 1-1.493.102L7 20.25V17H3.75a.75.75 0 0 1-.102-1.493zh4zm4-12.5a.75.75 0 0 1 .743.648l.007.102v4a.75.75 0 0 1-.648.743L7.75 8.5h-4a.75.75 0 0 1-.102-1.493L3.75 7H7V3.75A.75.75 0 0 1 7.75 3m8.5 0a.75.75 0 0 1 .743.648L17 3.75V7h3.25a.75.75 0 0 1 .102 1.493l-.102.007h-4a.75.75 0 0 1-.743-.648L15.5 7.75v-4a.75.75 0 0 1 .75-.75"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="800" height="800" viewBox="0 0 24 24"><title>ic_fluent_full_screen_zoom_24_regular</title><path fill="none" fill-rule="evenodd" d="M3 20.25v-4a.75.75 0 0 1 1.493-.102l.007.102v3.25h3.25a.75.75 0 0 1 .102 1.493L7.75 21h-4a.75.75 0 0 1-.743-.648zv-4zm0-12.5v-4a.75.75 0 0 1 .648-.743L3.75 3h4a.75.75 0 0 1 .102 1.493L7.75 4.5H4.5v3.25a.75.75 0 0 1-1.493.102zv-4zm12.5-4a.75.75 0 0 1 .648-.743L16.25 3h4a.75.75 0 0 1 .743.648L21 3.75v4a.75.75 0 0 1-1.493.102L19.5 7.75V4.5h-3.25a.75.75 0 0 1-.75-.75m0 16.5a.75.75 0 0 1 .648-.743l.102-.007h3.25v-3.25a.75.75 0 0 1 1.493-.102l.007.102v4a.75.75 0 0 1-.648.743L20.25 21h-4a.75.75 0 0 1-.75-.75" style="fill:#212121;fill-rule:nonzero"/></svg>
@@ -12,6 +12,8 @@ declare abstract class GirafeHTMLElement extends HTMLElement {
12
12
  private timeoutId?;
13
13
  protected rendered: boolean;
14
14
  protected feedbackTemplateHtml?: string;
15
+ private fullscreenModeActive;
16
+ private displayBeforeFullscreen;
15
17
  private readonly callbacks;
16
18
  private readonly unsafeCache;
17
19
  private _context?;
@@ -90,6 +92,25 @@ declare abstract class GirafeHTMLElement extends HTMLElement {
90
92
  * Show the component (display: block).
91
93
  */
92
94
  protected show(): void;
95
+ /**
96
+ * Whether this Component must stay visible when the App is in Fullscreen Mode.
97
+ * Controlled by the "fullscreen" attribute (default: false).
98
+ */
99
+ protected get isFullscreenComponent(): boolean;
100
+ /**
101
+ * Apply a display value to the Host Element, taking the Fullscreen Mode into account.
102
+ * In Fullscreen Mode, components that are not flagged with fullscreen="true" are forced
103
+ * hidden, but their intended display value is remembered so it can be restored when
104
+ * leaving Fullscreen Mode.
105
+ */
106
+ private setHostDisplay;
107
+ /**
108
+ * Handler for Changes of <code>interface.fullscreenMode</code>.
109
+ * Components flagged with fullscreen="true" are always visible and left untouched.
110
+ * Other Components are hidden when entering Fullscreen Mode and restored to their
111
+ * previous visibility when leaving it.
112
+ */
113
+ private onFullscreenModeChanged;
93
114
  /**
94
115
  * Subscribes with <callback> to the state changes made on <path>
95
116
  */
@@ -9,6 +9,8 @@ class GirafeHTMLElement extends HTMLElement {
9
9
  timeoutId;
10
10
  rendered = false;
11
11
  feedbackTemplateHtml;
12
+ fullscreenModeActive = false;
13
+ displayBeforeFullscreen = null;
12
14
  callbacks = [];
13
15
  unsafeCache = new Map();
14
16
  _context;
@@ -198,7 +200,7 @@ class GirafeHTMLElement extends HTMLElement {
198
200
  * Hide the component (display: none).
199
201
  */
200
202
  hide() {
201
- this.style.display = 'none';
203
+ this.setHostDisplay('none');
202
204
  this.unregisterInteractionListeners();
203
205
  }
204
206
  /**
@@ -206,7 +208,54 @@ class GirafeHTMLElement extends HTMLElement {
206
208
  */
207
209
  show() {
208
210
  if (this.displayStyle) {
209
- this.style.display = this.displayStyle;
211
+ this.setHostDisplay(this.displayStyle);
212
+ }
213
+ }
214
+ /**
215
+ * Whether this Component must stay visible when the App is in Fullscreen Mode.
216
+ * Controlled by the "fullscreen" attribute (default: false).
217
+ */
218
+ get isFullscreenComponent() {
219
+ return this.getAttribute('fullscreen') === 'true';
220
+ }
221
+ /**
222
+ * Apply a display value to the Host Element, taking the Fullscreen Mode into account.
223
+ * In Fullscreen Mode, components that are not flagged with fullscreen="true" are forced
224
+ * hidden, but their intended display value is remembered so it can be restored when
225
+ * leaving Fullscreen Mode.
226
+ */
227
+ setHostDisplay(display) {
228
+ if (this.fullscreenModeActive && !this.isFullscreenComponent) {
229
+ this.displayBeforeFullscreen = display;
230
+ this.style.display = 'none';
231
+ }
232
+ else {
233
+ this.style.display = display;
234
+ }
235
+ }
236
+ /**
237
+ * Handler for Changes of <code>interface.fullscreenMode</code>.
238
+ * Components flagged with fullscreen="true" are always visible and left untouched.
239
+ * Other Components are hidden when entering Fullscreen Mode and restored to their
240
+ * previous visibility when leaving it.
241
+ */
242
+ onFullscreenModeChanged(fullscreenMode) {
243
+ if (fullscreenMode === this.fullscreenModeActive) {
244
+ return;
245
+ }
246
+ this.fullscreenModeActive = fullscreenMode;
247
+ if (this.isFullscreenComponent) {
248
+ return;
249
+ }
250
+ if (fullscreenMode) {
251
+ // Entering Fullscreen Mode: remember the current visibility and hide the component.
252
+ this.displayBeforeFullscreen = this.style.display;
253
+ this.style.display = 'none';
254
+ }
255
+ else if (this.displayBeforeFullscreen !== null) {
256
+ // Leaving Fullscreen Mode: restore the visibility the component had before.
257
+ this.style.display = this.displayBeforeFullscreen;
258
+ this.displayBeforeFullscreen = null;
210
259
  }
211
260
  }
212
261
  subscribe(path, callback) {
@@ -230,6 +279,7 @@ class GirafeHTMLElement extends HTMLElement {
230
279
  this.context.componentManager.registerComponent(this);
231
280
  this.subscribe('language', () => this.girafeTranslate());
232
281
  this.subscribe('oauth.userInfo', () => this.userInfoChanged());
282
+ this.subscribe('interface.fullscreenMode', (_oldValue, newValue) => this.onFullscreenModeChanged(newValue));
233
283
  }
234
284
  /**
235
285
  * When the component is disconnected from the DOM
@@ -79,11 +79,24 @@ export default class MapComponent extends GirafeHTMLElement {
79
79
  focusFeature: FocusFeature;
80
80
  mapTargetResizeObserver: ResizeObserver;
81
81
  constructor();
82
+ /**
83
+ * The Map needs to be displayed in Fullscreen Mode.
84
+ */
85
+ protected get isFullscreenComponent(): boolean;
82
86
  resetAllSwipedLayers(layers: BaseLayer[]): void;
83
87
  registerEvents(): void;
84
88
  locateUser(): void;
85
89
  getCurrentLocation(): void;
86
90
  disableLocateUser: () => void;
91
+ /**
92
+ * Toggles the application fullscreen mode.
93
+ * The button is displayed over the map, like the geolocation button.
94
+ */
95
+ toggleFullscreen(): void;
96
+ /**
97
+ * Shows the matching fullscreen button (enter or exit) depending on the current mode.
98
+ */
99
+ private updateFullscreenButton;
87
100
  readonly updateGeolocation: (position: GeolocationPosition) => void;
88
101
  render(): void;
89
102
  listenOpenLayersEvents(): void;
@@ -53,10 +53,10 @@ export default class MapComponent extends GirafeHTMLElement {
53
53
  </style><style>
54
54
  .hidden{display:none!important}.gg-rotate90{transform:rotate(90deg)}.gg-rotate180{transform:rotate(180deg)}.gg-rotate270{transform:rotate(270deg)}img{filter:var(--svg-filter)}img.legend-image{filter:var(--svg-map-filter);background:var(--svg-legend-bkg)}div{scrollbar-width:thin}a,a:visited{color:var(--link-color)}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes spin-wait{0%{transform:rotate(0)}7%{transform:rotate(360deg)}to{transform:rotate(360deg)}}.gg-spin{animation-name:spin;animation-duration:2s;animation-timing-function:linear;animation-iteration-count:infinite}.gg-spin-wait{animation-name:spin-wait;animation-duration:10s;animation-timing-function:linear;animation-iteration-count:infinite}::-webkit-scrollbar{width:5px}::-webkit-scrollbar-thumb{background:#999}button,input,select,textarea{font:inherit}.gg-button,.gg-select,.gg-input,.gg-textarea{background-color:var(--bkg-color);color:var(--text-color);border:var(--app-standard-border);box-sizing:border-box;cursor:pointer;border-radius:3px;outline:0;margin:0;padding:0 0 0 .5rem;display:inline-block}.gg-label{background-color:var(--bkg-color);color:var(--text-color);border:none;align-items:center;margin:0;padding:0;display:flex}.gg-button,.gg-select,.gg-input,.gg-label{min-height:calc(var(--app-standard-height) / 1.5)}.gg-textarea{max-height:initial;resize:vertical;height:6rem;padding:.5rem;line-height:1.3rem}.gg-input{cursor:text}.gg-checkbox{accent-color:var(--text-color);width:1.2rem}.gg-range{accent-color:var(--text-color)}.gg-button{padding:0 .5rem}.gg-button.active{border:solid 1px var(--text-color-grad1);background-color:var(--bkg-color-grad2)}.gg-button:disabled{background-color:var(--bkg-color-grad1);color:var(--text-color-grad2);cursor:not-allowed;border:none}.gg-button:disabled img{filter:opacity(.6)}.gg-input:disabled,.gg-select:disabled,.gg-textarea:disabled{background-color:var(--bkg-color-grad1);color:var(--text-color-grad2);cursor:not-allowed}.gg-button>img{vertical-align:middle}.gg-icon-button{color:var(--text-color);cursor:pointer;background-color:#0000;border:none;flex-direction:column;justify-content:center;align-items:center;padding:0;display:flex}.gg-icon{justify-content:center;align-items:center;display:flex}.gg-big,.gg-big-withtext{min-width:var(--app-standard-height);min-height:var(--app-standard-height);max-height:var(--app-standard-height)}.gg-big img,.gg-big-withtext img{width:calc(var(--app-standard-height) - 1.5rem);margin:0}.gg-big-withtext span{font-variant:small-caps;padding:0 1rem;font-size:.9rem}.gg-medium,.gg-medium-withtext{min-width:calc(var(--app-standard-height) / 1.2);min-height:calc(var(--app-standard-height) / 1.2);max-height:calc(var(--app-standard-height) / 1.2);flex-direction:row}.gg-medium img{width:calc(var(--app-standard-height) / 2.4);margin:0}.gg-medium-withtext img{width:calc(var(--app-standard-height) / 2.4);margin-left:.5rem}.gg-medium-withtext span{padding:0 1rem 0 .5rem;font-size:.9rem}.gg-small,.gg-small-withtext{min-width:calc(var(--app-standard-height) / 2);min-height:calc(var(--app-standard-height) / 2);max-height:calc(var(--app-standard-height) / 2);flex-direction:row}.gg-small img{width:calc(var(--app-standard-height) / 3);margin:0}.gg-small-withtext img{width:calc(var(--app-standard-height) / 3);margin-left:.5rem}.gg-small-withtext span{padding:0 .5rem 0 .3rem;font-size:.9rem}.gg-button:hover:not(:disabled),.gg-select:hover:not(:disabled),.gg-input:hover:not(:disabled),.gg-textarea:hover:not(:disabled),.gg-icon-button:hover:not(:disabled){background-color:var(--bkg-color-grad1)}.gg-opacity{opacity:.5}.gg-opacity:hover{opacity:1;background-color:#0000}.gg-tabs{cursor:pointer;grid-auto-flow:column;padding-bottom:1rem;font-size:1rem;display:grid}.gg-tab{border:none;border-bottom:var(--app-standard-border);cursor:pointer;color:var(--text-color);background:0 0;padding:.5rem}.gg-tab.active{border-bottom:solid 1px var(--text-color)}.girafe-button-big,.girafe-button-large,.girafe-button-small,.girafe-button-tiny{color:var(--text-color);background-color:#0000;border:none;flex-direction:column;display:flex}.girafe-button-big:hover,.girafe-button-large:hover,.girafe-button-small:hover,.girafe-button-tiny:hover{background-color:var(--bkg-color-grad1);cursor:pointer}.girafe-button-big.dark,.girafe-button-large.dark,.girafe-button-small.dark,.girafe-button-tiny.dark{background-color:var(--bkg-color);filter:invert()}.girafe-button-big{width:var(--app-standard-height);height:var(--app-standard-height);align-items:center;padding:1rem}.girafe-button-big img{overflow:hidden}.girafe-button-large{flex-direction:row}.girafe-button-large img{height:2rem;margin:.3rem}.girafe-button-large span{height:2rem;margin:.3rem;line-height:2rem}.girafe-button-small{min-width:calc(var(--app-standard-height) / 2);height:calc(var(--app-standard-height) / 2);align-items:center;padding:.5rem}.girafe-button-small img{overflow:hidden}.girafe-button-small span{text-align:left;text-overflow:ellipsis;width:100%;overflow:hidden}.girafe-button-tiny{align-items:center;width:1rem;height:1rem;padding:0}.girafe-button-tiny img{overflow:hidden}.girafe-onboarding-theme{background-color:var(--bkg-color)!important;color:var(--text-color)!important}.girafe-onboarding-theme button{background-color:var(--bkg-color)!important;color:var(--text-color)!important;text-shadow:none!important}.girafe-onboarding-theme button.driver-popover-close-btn{z-index:10000}
55
55
  </style><style>
56
- #container,#ol-map{background-color:var(--bkg-color);width:100%;height:100%;position:relative}#ol-map.darkmap canvas{filter:invert()hue-rotate(180deg)}.hidden{display:none}.center{text-align:center;margin:10px;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.loading span{color:var(--text-color);margin-top:1rem;font-weight:600;display:block}.loading span.quote{font-style:italic;font-weight:300}#cs-map{background-color:var(--bkg-color);border-left:3px solid #444;height:100%;display:none;position:absolute;overflow:hidden}.ol-control{background-color:#0000;border:none;box-shadow:0 1px 4px #0000004d;right:2rem!important;left:unset!important}.ol-zoom{top:2rem!important}.mobile-map .ol-zoom{display:none!important}.ol-rotate{top:9.3rem!important}.ol-location{top:7rem!important}.img-location,.img-disable-location{width:55%;height:auto}.ol-zoom-in,.ol-zoom-out,.btn-location,.btn-disable-location,.ol-rotate-reset{cursor:pointer;background-color:var(--bkg-color)!important;width:2rem!important;height:2rem!important;color:var(--text-color)!important;font-size:1.2rem!important}.ol-scale-line{bottom:.5rem!important;right:1rem!important;left:unset!important}#swiper{width:100%;height:0;margin:0;display:none;position:absolute;top:50%}input[type=range]{-webkit-appearance:none;width:100%}input[type=range]::-webkit-slider-runnable-track{height:0}input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;background:var(--bkg-color);cursor:ew-resize;border:2px solid #444;width:6px;height:0;margin-top:-1000px;padding-top:1000px;padding-bottom:1000px}input[type=range]::-moz-range-thumb{background:var(--bkg-color);cursor:ew-resize;border:2px solid #444;width:3px;height:0;padding-top:1000px;padding-bottom:1000px}.close-swiper{--button-size:2rem;transform:translateX(calc(-1 * var(--button-size) / 2));width:var(--button-size);height:var(--button-size);background-color:var(--bkg-color);color:var(--text-color);cursor:pointer;border-width:1px;border-radius:4px;display:none;position:absolute;top:0}.close-swiper:hover,.close-swiper:focus{outline:1px solid var(--text-color);color:var(--text-color-grad1)}.ol-viewport .tooltip{color:#fff;opacity:.7;white-space:nowrap;background:#00000080;border-radius:0;padding:.32rem .62rem;position:relative}@media screen and (hover:none){.ol-zoom,.ol-rotate,.ol-location{display:none!important}}.contextmenu{background-color:var(--bkg-color);color:var(--text-color);border:1px solid #ccc;box-shadow:1px 3px 4px #0006;& .hidden{display:none}& .menu-entry{cursor:pointer;padding:10px}& .menu-entry:hover{background-color:var(--bkg-color-grad1)}& .menu-entry[aria-disabled=true]{pointer-events:none;color:var(--text-color-grad1)}}
56
+ #container,#ol-map{background-color:var(--bkg-color);width:100%;height:100%;position:relative}#ol-map.darkmap canvas{filter:invert()hue-rotate(180deg)}.hidden{display:none}.center{text-align:center;margin:10px;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.loading span{color:var(--text-color);margin-top:1rem;font-weight:600;display:block}.loading span.quote{font-style:italic;font-weight:300}#cs-map{background-color:var(--bkg-color);border-left:3px solid #444;height:100%;display:none;position:absolute;overflow:hidden}.ol-control{background-color:#0000;border:none;box-shadow:0 1px 4px #0000004d;right:2rem!important;left:unset!important}.ol-zoom{top:2rem!important}.mobile-map .ol-zoom{display:none!important}.ol-rotate{top:11.6rem!important}.ol-fullscreen{top:7rem!important}.ol-location{top:9.3rem!important}.img-location,.img-disable-location,.img-fullscreen{width:55%;height:auto}.ol-zoom-in,.ol-zoom-out,.btn-location,.btn-disable-location,.btn-fullscreen,.btn-exit-fullscreen,.ol-rotate-reset{cursor:pointer;background-color:var(--bkg-color)!important;width:2rem!important;height:2rem!important;color:var(--text-color)!important;font-size:1.2rem!important}.ol-scale-line{bottom:.5rem!important;right:1rem!important;left:unset!important}#swiper{width:100%;height:0;margin:0;display:none;position:absolute;top:50%}input[type=range]{-webkit-appearance:none;width:100%}input[type=range]::-webkit-slider-runnable-track{height:0}input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;background:var(--bkg-color);cursor:ew-resize;border:2px solid #444;width:6px;height:0;margin-top:-1000px;padding-top:1000px;padding-bottom:1000px}input[type=range]::-moz-range-thumb{background:var(--bkg-color);cursor:ew-resize;border:2px solid #444;width:3px;height:0;padding-top:1000px;padding-bottom:1000px}.close-swiper{--button-size:2rem;transform:translateX(calc(-1 * var(--button-size) / 2));width:var(--button-size);height:var(--button-size);background-color:var(--bkg-color);color:var(--text-color);cursor:pointer;border-width:1px;border-radius:4px;display:none;position:absolute;top:0}.close-swiper:hover,.close-swiper:focus{outline:1px solid var(--text-color);color:var(--text-color-grad1)}.ol-viewport .tooltip{color:#fff;opacity:.7;white-space:nowrap;background:#00000080;border-radius:0;padding:.32rem .62rem;position:relative}@media screen and (hover:none){.ol-zoom,.ol-rotate,.ol-location,.ol-fullscreen{display:none!important}}.contextmenu{background-color:var(--bkg-color);color:var(--text-color);border:1px solid #ccc;box-shadow:1px 3px 4px #0006;& .hidden{display:none}& .menu-entry{cursor:pointer;padding:10px}& .menu-entry:hover{background-color:var(--bkg-color-grad1)}& .menu-entry[aria-disabled=true]{pointer-events:none;color:var(--text-color-grad1)}}
57
57
  </style>
58
58
  <style>${this.customStyle}</style>
59
- <div id="container"><div id="ol-map" class="${this.onMobile ? 'mobile-map' : ''}"></div><div class="${this.onMobile ? 'hidden' : 'ol-location ol-unselectable ol-control'}"><button onclick="${() => this.locateUser()}" class="btn-location" tip="Locate user"><img class="img-location" alt="location-icon" src="icons/adjust.svg"></button> <button id="disable-location" onclick="${() => this.disableLocateUser()}" tip="Disable locate user" class="btn-disable-location hidden"><img class="img-disable-location" alt="disable-location-icon" src="icons/adjust-disable.svg"></button></div><div id="cs-map"><div class="${this.loading ? 'loading center' : 'loading hidden'}"><img alt="loading-icon" src="icons/loading.svg" class="gg-spin"> <span i18n="Loading cesium...">Loading cesium...</span> <span class="quote" i18n="cesium-loading-quote">Please be patient, like a giraffe reaching for the tastiest leaves.</span></div></div><input id="swiper" type="range" min="0" max="1000" step="1"> <button tip="Hide Swiper" id="close-swiper" class="close-swiper">×</button></div>
59
+ <div id="container"><div id="ol-map" class="${this.onMobile ? 'mobile-map' : ''}"></div><div class="${this.onMobile ? 'hidden' : 'ol-fullscreen ol-unselectable ol-control'}"><button id="fullscreen-enter-button" onclick="${() => this.toggleFullscreen()}" tip="fullscreen-on" class="btn-fullscreen"><img class="img-fullscreen" alt="fullscreen-icon" src="icons/fullscreen.svg"></button> <button id="fullscreen-exit-button" onclick="${() => this.toggleFullscreen()}" tip="fullscreen-off" class="btn-exit-fullscreen hidden"><img class="img-fullscreen" alt="fullscreen-exit-icon" src="icons/fullscreen-exit.svg"></button></div><div class="${this.onMobile ? 'hidden' : 'ol-location ol-unselectable ol-control'}"><button onclick="${() => this.locateUser()}" class="btn-location" tip="Locate user"><img class="img-location" alt="location-icon" src="icons/adjust.svg"></button> <button id="disable-location" onclick="${() => this.disableLocateUser()}" tip="Disable locate user" class="btn-disable-location hidden"><img class="img-disable-location" alt="disable-location-icon" src="icons/adjust-disable.svg"></button></div><div id="cs-map"><div class="${this.loading ? 'loading center' : 'loading hidden'}"><img alt="loading-icon" src="icons/loading.svg" class="gg-spin"> <span i18n="Loading cesium...">Loading cesium...</span> <span class="quote" i18n="cesium-loading-quote">Please be patient, like a giraffe reaching for the tastiest leaves.</span></div></div><input id="swiper" type="range" min="0" max="1000" step="1"> <button tip="Hide Swiper" id="close-swiper" class="close-swiper">×</button></div>
60
60
  ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
61
61
  };
62
62
  olMap;
@@ -127,6 +127,12 @@ ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
127
127
  constructor() {
128
128
  super('map');
129
129
  }
130
+ /**
131
+ * The Map needs to be displayed in Fullscreen Mode.
132
+ */
133
+ get isFullscreenComponent() {
134
+ return true;
135
+ }
130
136
  resetAllSwipedLayers(layers) {
131
137
  for (const layer of layers) {
132
138
  if (layer instanceof Layer) {
@@ -150,6 +156,7 @@ ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
150
156
  this.subscribe(/activeBasemaps\.\d\.opacity/, (_oldOpacity, _newOpacity, basemap) => this.onChangeBasemapOpacity(basemap));
151
157
  this.subscribe('projection', (oldProjection, newProjection) => this.onChangeProjection(oldProjection, newProjection));
152
158
  this.subscribe('interface.darkMapMode', () => this.onChangeDarkMode());
159
+ this.subscribe('interface.fullscreenMode', (_oldValue, newValue) => this.updateFullscreenButton(newValue));
153
160
  this.subscribe('selection.selectionParameters', (_, newParams) => this.onSelectFeatures(newParams));
154
161
  this.subscribe('selection.selectedFeatures', (_oldFeatures, newFeatures) => this.onFeaturesSelected(newFeatures));
155
162
  this.subscribe('selection.selectedFeaturesType', (_oldFeaturesType, newFeaturesType) => this.onFeaturesTypeChanged(newFeaturesType));
@@ -245,6 +252,20 @@ ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
245
252
  this.geolocationSource.clear();
246
253
  this.shadow.getElementById('disable-location')?.classList.add('hidden');
247
254
  };
255
+ /**
256
+ * Toggles the application fullscreen mode.
257
+ * The button is displayed over the map, like the geolocation button.
258
+ */
259
+ toggleFullscreen() {
260
+ this.state.interface.fullscreenMode = !this.state.interface.fullscreenMode;
261
+ }
262
+ /**
263
+ * Shows the matching fullscreen button (enter or exit) depending on the current mode.
264
+ */
265
+ updateFullscreenButton(fullscreen) {
266
+ this.shadow.getElementById('fullscreen-enter-button')?.classList.toggle('hidden', fullscreen);
267
+ this.shadow.getElementById('fullscreen-exit-button')?.classList.toggle('hidden', !fullscreen);
268
+ }
248
269
  updateGeolocation = (position) => {
249
270
  const coords = position.coords;
250
271
  const longitude = coords.longitude;
@@ -61,15 +61,23 @@
61
61
  }
62
62
 
63
63
  .ol-rotate {
64
- top: 9.3rem !important;
64
+ top: 11.6rem !important;
65
65
  }
66
66
 
67
- .ol-location {
67
+ /* Inserted between the zoom controls (top: 2rem) and the geolocation button. */
68
+ .ol-fullscreen {
68
69
  top: 7rem !important;
69
70
  }
70
71
 
72
+ /* Shifted down to leave room for the fullscreen button (top: 7rem),
73
+ which is inserted between the zoom controls and the geolocation button. */
74
+ .ol-location {
75
+ top: 9.3rem !important;
76
+ }
77
+
71
78
  .img-location,
72
- .img-disable-location {
79
+ .img-disable-location,
80
+ .img-fullscreen {
73
81
  width: 55%;
74
82
  height: auto;
75
83
  }
@@ -78,6 +86,8 @@
78
86
  .ol-zoom-out,
79
87
  .btn-location,
80
88
  .btn-disable-location,
89
+ .btn-fullscreen,
90
+ .btn-exit-fullscreen,
81
91
  .ol-rotate-reset {
82
92
  width: 2rem !important;
83
93
  height: 2rem !important;
@@ -169,7 +179,8 @@ input[type='range']::-moz-range-thumb {
169
179
  @media screen and (hover: none) {
170
180
  .ol-zoom,
171
181
  .ol-rotate,
172
- .ol-location {
182
+ .ol-location,
183
+ .ol-fullscreen {
173
184
  display: none !important;
174
185
  }
175
186
  }
@@ -19,6 +19,10 @@ declare class SelectionGridComponent extends GirafeResizableElement {
19
19
  currentTabId: string;
20
20
  resultsSelected: boolean;
21
21
  constructor();
22
+ /**
23
+ * We want the Results of a Selection/Query to be shown either in the Grid. So we ignore the Fullscree Mode
24
+ */
25
+ protected get isFullscreenComponent(): boolean;
22
26
  protected connectedCallback(): void;
23
27
  /**
24
28
  * Render the component regarding its visibility.
@@ -37,6 +37,12 @@ ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
37
37
  constructor() {
38
38
  super('selectiongrid');
39
39
  }
40
+ /**
41
+ * We want the Results of a Selection/Query to be shown either in the Grid. So we ignore the Fullscree Mode
42
+ */
43
+ get isFullscreenComponent() {
44
+ return true;
45
+ }
40
46
  connectedCallback() {
41
47
  super.connectedCallback();
42
48
  this.csvManager = new CsvManager(this.context);
@@ -39,6 +39,10 @@ declare class SelectionWindowComponent extends GirafeDraggableElement {
39
39
  private columnAliasHelper;
40
40
  showDirectionsProviderDropdown: boolean;
41
41
  constructor();
42
+ /**
43
+ * We want the Results of a Selection/Query to be shown either in the Window. So we ignore the Fullscree Mode
44
+ */
45
+ protected get isFullscreenComponent(): boolean;
42
46
  protected connectedCallback(): void;
43
47
  /**
44
48
  * Render the component regarding its visibility.
@@ -50,6 +50,12 @@ ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
50
50
  constructor() {
51
51
  super('selectionwindow');
52
52
  }
53
+ /**
54
+ * We want the Results of a Selection/Query to be shown either in the Window. So we ignore the Fullscree Mode
55
+ */
56
+ get isFullscreenComponent() {
57
+ return true;
58
+ }
53
59
  connectedCallback() {
54
60
  super.connectedCallback();
55
61
  this.csvManager = new CsvManager(this.context);
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.2646908874",
8
+ "version": "1.2.0-dev.2657510436",
9
9
  "type": "module",
10
10
  "engines": {
11
11
  "node": ">=20.19.0"
package/styles/index.css CHANGED
@@ -14,14 +14,14 @@ header {
14
14
  position: fixed;
15
15
  top: 0;
16
16
  left: 0;
17
- right: 0;
17
+ right: calc(var(--app-standard-height) - 0px);
18
18
  display: flex;
19
19
  flex-direction: row;
20
20
  align-items: center;
21
21
  border-bottom: var(--app-standard-border);
22
22
  background: var(--bkg-color);
23
23
  height: var(--app-standard-height);
24
- z-index: 100;
24
+ z-index: 101;
25
25
  justify-content: space-between;
26
26
  }
27
27
 
@@ -50,19 +50,82 @@ girafe-search {
50
50
  display: flex;
51
51
  flex-direction: column;
52
52
  position: fixed;
53
- top: var(--app-standard-height);
53
+ top: 0;
54
54
  right: 0;
55
- height: calc(100% - var(--app-standard-height));
55
+ height: 100%;
56
56
  width: var(--app-standard-height);
57
57
  background-color: var(--bkg-color);
58
58
  border-left: var(--app-standard-border);
59
- z-index: 1000;
59
+ z-index: 100;
60
60
  }
61
61
 
62
62
  #buttonbar .filler {
63
63
  flex-grow: 1;
64
64
  }
65
65
 
66
+ #buttonbar-toggle {
67
+ display: none;
68
+ }
69
+
70
+ #buttonbar-grid {
71
+ display: contents;
72
+ }
73
+
74
+ /* Small screens */
75
+ @media (max-height: 700px) {
76
+ #buttonbar {
77
+ position: absolute;
78
+ bottom: 0.75rem;
79
+ z-index: 20;
80
+ display: flex;
81
+ flex-direction: column;
82
+ align-items: flex-end;
83
+ gap: 0.5rem;
84
+ }
85
+
86
+ #buttonbar-toggle {
87
+ display: inline-flex;
88
+ }
89
+
90
+ #buttonbar-grid {
91
+ display: none;
92
+ }
93
+
94
+ #buttonbar.open #buttonbar-grid {
95
+ display: grid;
96
+ grid-template-columns: repeat(2, auto);
97
+ gap: 0.5rem;
98
+ padding: 0.5rem;
99
+ margin-right: 0.75rem;
100
+ border-radius: 0.5rem;
101
+ background-color: var(--bkg-color);
102
+ box-shadow: var(--bx-shdw);
103
+ }
104
+
105
+ #buttonbar.open .filler {
106
+ display: none;
107
+ }
108
+ }
109
+
110
+ /* Slightly smaller screens: use 3 columns */
111
+ @media (max-height: 500px) {
112
+ #buttonbar.open #buttonbar-grid {
113
+ grid-template-columns: repeat(3, auto);
114
+ }
115
+ }
116
+
117
+ /* Full Screen Mode: Hide most of the Apps Components */
118
+ girafe-app.fullscreen-mode header,
119
+ girafe-app.fullscreen-mode footer,
120
+ girafe-app.fullscreen-mode #buttonbar {
121
+ display: none;
122
+ }
123
+
124
+ girafe-app.fullscreen-mode #content {
125
+ top: 0;
126
+ right: 0;
127
+ }
128
+
66
129
  #content {
67
130
  position: absolute;
68
131
  display: flex;
@@ -125,7 +125,6 @@
125
125
  <girafe-news-button plugin="config:news"></girafe-news-button>
126
126
  <girafe-oauth></girafe-oauth>
127
127
  <girafe-add-bookmark></girafe-add-bookmark>
128
- <girafe-video-record></girafe-video-record>
129
128
  </header>
130
129
 
131
130
  <girafe-help></girafe-help>
@@ -186,134 +185,155 @@
186
185
 
187
186
  <div id="buttonbar">
188
187
  <button
189
- tip="drawing-panel"
190
- slot="menu-content"
188
+ id="buttonbar-toggle"
191
189
  class="gg-icon-button gg-big"
192
- onclick="
193
- document.geogirafe.state.interface.drawingPanelVisible =
194
- !document.geogirafe.state.interface.drawingPanelVisible
195
- ">
196
- <img alt="draw-icon" src="icons/draw.svg" />
197
- </button>
198
- <button
199
- tip="selection-tool-panel"
200
- slot="menu-content"
201
- class="gg-icon-button gg-big"
202
- onclick="
203
- document.geogirafe.state.interface.selectionToolPanelVisible =
204
- !document.geogirafe.state.interface.selectionToolPanelVisible
205
- ">
206
- <img alt="draw-icon" src="icons/select.svg" />
207
- </button>
208
- <button
209
- tip="external-entry"
210
- slot="menu-content"
211
- class="gg-icon-button gg-big"
212
- onclick="
213
- document.geogirafe.state.interface.extLayerPanelVisible =
214
- !document.geogirafe.state.interface.extLayerPanelVisible
215
- ">
216
- <img alt="ext-icon" src="icons/external-entry.svg" />
217
- </button>
218
- <button
219
- tip="print-panel"
220
- slot="menu-content"
221
- class="gg-icon-button gg-big"
222
- plugin="config:print"
223
- onclick="
224
- document.geogirafe.state.interface.printPanelVisible = !document.geogirafe.state.interface.printPanelVisible
225
- ">
226
- <img alt="print-icon" src="icons/print.svg" />
227
- </button>
228
- <button
229
- tip="lidar-panel"
230
- slot="menu-content"
231
- class="gg-icon-button gg-big"
232
- plugin="config:lidar"
233
- onclick="
234
- document.geogirafe.state.interface.crossSectionPanelVisible =
235
- !document.geogirafe.state.interface.crossSectionPanelVisible
236
- ">
237
- <img alt="cross-section-icon" src="icons/cross-section.svg" />
238
- </button>
239
- <button
240
- tip="advanced-filter-panel"
241
- slot="menu-content"
242
- class="gg-icon-button gg-big"
243
- onclick="
244
- document.geogirafe.state.interface.advancedFilterPanelVisible =
245
- !document.geogirafe.state.interface.advancedFilterPanelVisible
246
- ">
247
- <img alt="advanced-filter-icon" src="icons/advanced-filter.svg" />
248
- </button>
249
- <button
250
- tip="edit-panel"
251
- slot="menu-content"
252
- class="gg-icon-button gg-big"
253
- onclick="
254
- document.geogirafe.state.interface.editPanelVisible = !document.geogirafe.state.interface.editPanelVisible
255
- ">
256
- <img alt="edit-icon" src="icons/edit.svg" />
257
- </button>
258
- <button
259
- tip="share-panel"
260
- slot="menu-content"
261
- class="gg-icon-button gg-big"
262
- plugin="config:share"
263
- onclick="
264
- document.geogirafe.state.interface.sharePanelVisible = !document.geogirafe.state.interface.sharePanelVisible
265
- ">
266
- <img alt="share-icon" src="icons/share.svg" />
267
- </button>
268
- <button
269
- tip="layout-panel"
270
- class="gg-icon-button gg-big"
271
- plugin="config:map3d"
272
- onclick="
273
- document.geogirafe.state.interface.layoutPanelVisible =
274
- !document.geogirafe.state.interface.layoutPanelVisible
275
- ">
276
- <img alt="layout-icon" src="icons/layout.svg" />
277
- </button>
278
- <button
279
- tip="contact-panel"
280
- class="gg-icon-button gg-big"
281
- plugin="config:contact"
282
- onclick="
283
- document.geogirafe.state.interface.contactPanelVisible =
284
- !document.geogirafe.state.interface.contactPanelVisible
285
- ">
286
- <img alt="layout-icon" src="icons/mail.svg" />
287
- </button>
288
- <button tip="infra3d" class="gg-icon-button gg-big" plugin="plugin_infra3d" onclick="alert('infra3d')">
289
- <img alt="help-icon" src="icons/infra3d.svg" />
190
+ type="button"
191
+ tip="open-buttonbar-menu"
192
+ aria-expanded="false"
193
+ onclick="this.parentNode.classList.toggle('open')">
194
+ <img alt="" src="icons/menu.svg" />
290
195
  </button>
291
196
 
292
- <div class="filler"></div>
197
+ <div
198
+ id="buttonbar-grid"
199
+ role="menubar"
200
+ tabindex="0"
201
+ onclick="this.parentNode.classList.toggle('open')"
202
+ onkeyup="this.parentNode.classList.toggle('open')">
203
+ <girafe-video-record></girafe-video-record>
204
+ <button
205
+ tip="drawing-panel"
206
+ slot="menu-content"
207
+ class="gg-icon-button gg-big"
208
+ onclick="
209
+ document.geogirafe.state.interface.drawingPanelVisible =
210
+ !document.geogirafe.state.interface.drawingPanelVisible
211
+ ">
212
+ <img alt="draw-icon" src="icons/draw.svg" />
213
+ </button>
214
+ <button
215
+ tip="selection-tool-panel"
216
+ slot="menu-content"
217
+ class="gg-icon-button gg-big"
218
+ onclick="
219
+ document.geogirafe.state.interface.selectionToolPanelVisible =
220
+ !document.geogirafe.state.interface.selectionToolPanelVisible
221
+ ">
222
+ <img alt="draw-icon" src="icons/select.svg" />
223
+ </button>
224
+ <button
225
+ tip="external-entry"
226
+ slot="menu-content"
227
+ class="gg-icon-button gg-big"
228
+ onclick="
229
+ document.geogirafe.state.interface.extLayerPanelVisible =
230
+ !document.geogirafe.state.interface.extLayerPanelVisible
231
+ ">
232
+ <img alt="ext-icon" src="icons/external-entry.svg" />
233
+ </button>
234
+ <button
235
+ tip="print-panel"
236
+ slot="menu-content"
237
+ class="gg-icon-button gg-big"
238
+ plugin="config:print"
239
+ onclick="
240
+ document.geogirafe.state.interface.printPanelVisible =
241
+ !document.geogirafe.state.interface.printPanelVisible
242
+ ">
243
+ <img alt="print-icon" src="icons/print.svg" />
244
+ </button>
245
+ <button
246
+ tip="lidar-panel"
247
+ slot="menu-content"
248
+ class="gg-icon-button gg-big"
249
+ plugin="config:lidar"
250
+ onclick="
251
+ document.geogirafe.state.interface.crossSectionPanelVisible =
252
+ !document.geogirafe.state.interface.crossSectionPanelVisible
253
+ ">
254
+ <img alt="cross-section-icon" src="icons/cross-section.svg" />
255
+ </button>
256
+ <button
257
+ tip="advanced-filter-panel"
258
+ slot="menu-content"
259
+ class="gg-icon-button gg-big"
260
+ onclick="
261
+ document.geogirafe.state.interface.advancedFilterPanelVisible =
262
+ !document.geogirafe.state.interface.advancedFilterPanelVisible
263
+ ">
264
+ <img alt="advanced-filter-icon" src="icons/advanced-filter.svg" />
265
+ </button>
266
+ <button
267
+ tip="edit-panel"
268
+ slot="menu-content"
269
+ class="gg-icon-button gg-big"
270
+ onclick="
271
+ document.geogirafe.state.interface.editPanelVisible = !document.geogirafe.state.interface.editPanelVisible
272
+ ">
273
+ <img alt="edit-icon" src="icons/edit.svg" />
274
+ </button>
275
+ <button
276
+ tip="share-panel"
277
+ slot="menu-content"
278
+ class="gg-icon-button gg-big"
279
+ plugin="config:share"
280
+ onclick="
281
+ document.geogirafe.state.interface.sharePanelVisible =
282
+ !document.geogirafe.state.interface.sharePanelVisible
283
+ ">
284
+ <img alt="share-icon" src="icons/share.svg" />
285
+ </button>
286
+ <button
287
+ tip="layout-panel"
288
+ class="gg-icon-button gg-big"
289
+ plugin="config:map3d"
290
+ onclick="
291
+ document.geogirafe.state.interface.layoutPanelVisible =
292
+ !document.geogirafe.state.interface.layoutPanelVisible
293
+ ">
294
+ <img alt="layout-icon" src="icons/layout.svg" />
295
+ </button>
296
+ <button
297
+ tip="contact-panel"
298
+ class="gg-icon-button gg-big"
299
+ plugin="config:contact"
300
+ onclick="
301
+ document.geogirafe.state.interface.contactPanelVisible =
302
+ !document.geogirafe.state.interface.contactPanelVisible
303
+ ">
304
+ <img alt="layout-icon" src="icons/mail.svg" />
305
+ </button>
306
+ <button tip="infra3d" class="gg-icon-button gg-big" plugin="plugin_infra3d" onclick="alert('infra3d')">
307
+ <img alt="help-icon" src="icons/infra3d.svg" />
308
+ </button>
293
309
 
294
- <button
295
- tip="help"
296
- class="gg-icon-button gg-big"
297
- onclick="document.geogirafe.state.interface.helpVisible = true">
298
- <img alt="help-icon" src="icons/help.svg" />
299
- </button>
300
- <button
301
- tip="about-panel"
302
- class="gg-icon-button gg-big"
303
- onclick="
304
- document.geogirafe.state.interface.aboutPanelVisible = !document.geogirafe.state.interface.aboutPanelVisible
305
- ">
306
- <img alt="info-icon" src="icons/info.svg" />
307
- </button>
308
- <button
309
- tip="user-preferences-panel"
310
- class="gg-icon-button gg-big"
311
- onclick="
312
- document.geogirafe.state.interface.userPreferencesPanelVisible =
313
- !document.geogirafe.state.interface.userPreferencesPanelVisible
314
- ">
315
- <img alt="user-preferences-icon" src="icons/config.svg" />
316
- </button>
310
+ <div class="filler"></div>
311
+
312
+ <button
313
+ tip="help"
314
+ class="gg-icon-button gg-big"
315
+ onclick="document.geogirafe.state.interface.helpVisible = true">
316
+ <img alt="help-icon" src="icons/help.svg" />
317
+ </button>
318
+ <button
319
+ tip="about-panel"
320
+ class="gg-icon-button gg-big"
321
+ onclick="
322
+ document.geogirafe.state.interface.aboutPanelVisible =
323
+ !document.geogirafe.state.interface.aboutPanelVisible
324
+ ">
325
+ <img alt="info-icon" src="icons/info.svg" />
326
+ </button>
327
+ <button
328
+ tip="user-preferences-panel"
329
+ class="gg-icon-button gg-big"
330
+ onclick="
331
+ document.geogirafe.state.interface.userPreferencesPanelVisible =
332
+ !document.geogirafe.state.interface.userPreferencesPanelVisible
333
+ ">
334
+ <img alt="user-preferences-icon" src="icons/config.svg" />
335
+ </button>
336
+ </div>
317
337
  </div>
318
338
  </girafe-app>
319
339
  </body>
@@ -1 +1 @@
1
- {"version":"1.2.0-dev.2646908874", "build":"2646908874", "date":"02/07/2026"}
1
+ {"version":"1.2.0-dev.2657510436", "build":"2657510436", "date":"07/07/2026"}
@@ -7,6 +7,10 @@ export default class GeoGirafeAppComponent extends GirafeHTMLElement {
7
7
  private resolveReady;
8
8
  constructor();
9
9
  getContext(): IGirafeContext;
10
+ /**
11
+ * This one needs to be displayed in Fullscreen Mode. Otherwise the User will see nothing at all ;)
12
+ */
13
+ protected get isFullscreenComponent(): boolean;
10
14
  protected connectedCallback(): void;
11
15
  getInheritedContext(): IGirafeContext;
12
16
  isReady(): Promise<void>;
@@ -18,8 +18,19 @@ export default class GeoGirafeAppComponent extends GirafeHTMLElement {
18
18
  getContext() {
19
19
  return this.context;
20
20
  }
21
+ /**
22
+ * This one needs to be displayed in Fullscreen Mode. Otherwise the User will see nothing at all ;)
23
+ */
24
+ get isFullscreenComponent() {
25
+ return true;
26
+ }
21
27
  connectedCallback() {
22
28
  super.connectedCallback();
29
+ // Reflect the fullscreen mode as a class on the app root, so that plain
30
+ // layout elements (header, footer, button bar) can be hidden via CSS.
31
+ this.subscribe('interface.fullscreenMode', (_oldValue, newValue) => {
32
+ this.classList.toggle('fullscreen-mode', newValue);
33
+ });
23
34
  this.initialize().then(() => {
24
35
  // App is ready
25
36
  this.resolveReady();
@@ -21,6 +21,7 @@ export default class GraphicalInterface {
21
21
  searchComponentVisible: boolean;
22
22
  basemapComponentVisible: boolean;
23
23
  darkMapMode: boolean;
24
+ fullscreenMode: boolean;
24
25
  selectionToolPanelVisible: boolean;
25
26
  darkFrontendMode: boolean;
26
27
  swipeupPanelMode: SwipeupPanelMode;
@@ -21,6 +21,7 @@ export default class GraphicalInterface {
21
21
  searchComponentVisible = true;
22
22
  basemapComponentVisible = true;
23
23
  darkMapMode = false;
24
+ fullscreenMode = false;
24
25
  selectionToolPanelVisible = false;
25
26
  // TODO: remove of adjust this when the component UserDataManager is monted on mobile UI
26
27
  darkFrontendMode = systemIsInDarkMode() ?? false;