@geogirafe/lib-geoportal
Version:
GeoGirafe is a flexible application to build online geoportals.
205 lines (204 loc) • 7.75 kB
JavaScript
// SPDX-License-Identifier: Apache-2.0
import GirafeHTMLElement from '../../../base/GirafeHTMLElement.js';
import { isTimeAwareLayer } from '../../../models/layers/timeawarelayer.js';
import { isSnappableLayer } from '../../../models/layers/snappablelayer.js';
import tippy from 'tippy.js';
import TimeRestrictionComponent from '../../timerestriction/component.js';
import LayerWms from '../../../models/layers/layerwms.js';
import Layer from '../../../models/layers/layer.js';
export default class TreeViewElement extends GirafeHTMLElement {
dragManager;
layer;
dragButton;
container;
header;
constructor(layer, name) {
super(name);
this.layer = layer;
}
connectedCallback() {
super.connectedCallback();
this.dragManager = this.context.dragManager;
}
render() {
super.render();
this.dragButton = this.shadow.getElementById('drag-button');
this.container = this.shadow.getElementById('container');
this.header = this.shadow.querySelector('header');
super.girafeTranslate();
this.initializeDrag();
if (isTimeAwareLayer(this.layer)) {
this.createTimeRestrictionTooltip(this.layer);
}
this.subscribe(/layers\.layersList\..*\.isHighlighted/, (_oldValue, newValue, layer) => {
if (newValue && layer === this.layer) {
this.highlight();
}
});
}
highlight() {
this.header.scrollIntoView({
behavior: 'smooth',
block: 'nearest'
});
this.header.classList.add('highlight');
setTimeout(() => {
this.header.classList.remove('highlight');
this.layer.isHighlighted = false;
}, 3000);
}
refreshRender(layer) {
if (this.state.treeview.renderEnabled && (!layer || layer === this.layer)) {
// Is called without param, call refresh
// Else, call refresh only if the layer in param is the current one
super.refreshRender();
super.girafeTranslate();
if (this.layer.isHighlighted) {
this.highlight();
}
}
}
showMetadata() {
window.gOpenWindow(this.layer.name, this.layer.metadataUrl);
}
initializeDrag() {
if (!this.layer.isDraggable) {
return;
}
this.dragButton.draggable = true;
this.dragButton.ondragstart = (e) => this.dragStart(e);
this.dragButton.ondragend = (e) => this.dragEnd(e);
this.ondragenter = (e) => this.dragEnter(e);
this.ondragleave = (e) => this.dragLeave(e);
}
dragStart(event) {
this.dragManager.dragStart(this.layer);
event.dataTransfer.setDragImage(this, this.offsetWidth, 0);
}
dragEnd(_event) {
this.dragManager.dragEnd();
}
dragEnter(_event) {
if (this.dragManager.dragEnter(this.layer)) {
this.setDragStyle();
}
}
dragLeave(_event) {
if (this.dragManager.dragLeave(this.layer)) {
this.setDragStyle();
}
}
setDragStyle() {
if (this.dragManager.dragAfter) {
this.container.classList.remove('dragBefore');
this.container.classList.add('dragAfter');
}
else if (this.dragManager.dragBefore) {
this.container.classList.remove('dragAfter');
this.container.classList.add('dragBefore');
}
else {
this.container.classList.remove('dragAfter');
this.container.classList.remove('dragBefore');
}
}
getButtonClass(button) {
const buttonClasses = 'gg-icon-button gg-small gg-opacity tool';
const activeButtonClasses = buttonClasses + ' active';
switch (button) {
case 'swipedLeft':
if (this.layer.isSwipeable && !this.layer.inactive && this.layer instanceof Layer) {
return this.layer.swiped === 'left' ? activeButtonClasses : buttonClasses;
}
return 'hidden';
case 'swipedRight':
if (this.layer.isSwipeable && !this.layer.inactive && this.layer instanceof Layer) {
return this.layer.swiped === 'right' ? activeButtonClasses : buttonClasses;
}
return 'hidden';
case 'opacity':
if (!this.layer.inactive && this.layer instanceof Layer) {
return this.layer.opacity < 1 ? activeButtonClasses : buttonClasses;
}
return 'hidden';
case 'filter':
if (!this.layer.inactive && this.layer instanceof LayerWms && this.layer.queryable) {
if (this.layer.hasFilter) {
// Hide the filter icon if it's not a simple filter (advanced filter icon will be shown instead)
return this.layer.filter.isSimpleFilter() ? activeButtonClasses : 'hidden';
}
// No filter applied yet
return buttonClasses;
}
return 'hidden';
case 'advanced-filter':
if (!this.layer.inactive &&
this.layer instanceof LayerWms &&
this.layer.hasFilter &&
this.layer.filter.isAdvancedFilter()) {
return activeButtonClasses;
}
return 'hidden';
case 'timeRestriction':
if (!this.layer.inactive && isTimeAwareLayer(this.layer)) {
return this.layer.hasTimeRestriction ? activeButtonClasses : buttonClasses;
}
return 'hidden';
case 'snappable':
if (!this.layer.inactive && isSnappableLayer(this.layer)) {
return this.layer.snapActive ? activeButtonClasses : buttonClasses;
}
return 'hidden';
case 'draggable':
if (this.layer.isDraggable) {
return 'gg-icon-button gg-small gg-grab gg-opacity tool';
}
return 'hidden';
case 'removable':
if (this.layer.isRemovable) {
return 'gg-icon-button gg-small remove gg-opacity tool';
}
else {
return 'hidden';
}
default:
throw Error('Unsupported type: ' + button);
}
}
createTimeRestrictionTooltip(layer) {
const el = this.shadow.getElementById('timeRestriction');
if (!el)
return;
tippy(el, {
trigger: 'click',
arrow: true,
interactive: true,
theme: 'light',
placement: 'bottom',
appendTo: document.body,
content: (_reference) => {
return new TimeRestrictionComponent(layer);
}
});
}
removeFromParent() {
TreeViewElement.removeLayerFromParent(this.layer, this.state);
}
static removeLayerFromParent(layer, state) {
if (layer.parent) {
const index = layer.parent.children.indexOf(layer);
if (index >= 0) {
layer.parent.children.splice(index, 1);
}
if (layer.parent.children.length === 0) {
TreeViewElement.removeLayerFromParent(layer.parent, state);
}
}
else {
const index = state.layers.layersList.indexOf(layer);
if (index >= 0) {
state.layers.layersList.splice(index, 1);
}
}
}
}