From b92695dd7fbb38ee3e0b02561910eb630d7a0f1c Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Wed, 6 Mar 2024 14:27:57 +0100 Subject: [PATCH 01/44] wip: first shot on merging data browser and features browser --- umap/static/umap/base.css | 7 + umap/static/umap/img/24-white.svg | 4 +- umap/static/umap/img/24.svg | 7 +- umap/static/umap/img/source/24-white.svg | 8 +- umap/static/umap/img/source/24.svg | 13 +- umap/static/umap/js/modules/browser.js | 74 ++++++--- umap/static/umap/js/modules/orderable.js | 84 ++++++++++ umap/static/umap/js/modules/schema.js | 5 + umap/static/umap/js/umap.controls.js | 200 ++++------------------- umap/static/umap/js/umap.core.js | 88 ---------- umap/static/umap/js/umap.forms.js | 3 - umap/static/umap/js/umap.js | 55 ++++--- umap/static/umap/js/umap.layer.js | 2 - umap/static/umap/map.css | 88 +++++----- 14 files changed, 268 insertions(+), 370 deletions(-) create mode 100644 umap/static/umap/js/modules/orderable.js diff --git a/umap/static/umap/base.css b/umap/static/umap/base.css index 119ff4ba..ccbda217 100644 --- a/umap/static/umap/base.css +++ b/umap/static/umap/base.css @@ -975,6 +975,13 @@ input:invalid { right: 0; visibility: visible; } + #umap-ui-container.condensed { + margin-top: 10px; + margin-right: 10px; + max-height: 300px; + width: 390px; + border-radius: 10px; + } } @media all and (orientation:portrait) { #umap-ui-container { diff --git a/umap/static/umap/img/24-white.svg b/umap/static/umap/img/24-white.svg index 3ee202b4..ac571991 100644 --- a/umap/static/umap/img/24-white.svg +++ b/umap/static/umap/img/24-white.svg @@ -33,7 +33,6 @@ - @@ -58,5 +57,8 @@ + + + diff --git a/umap/static/umap/img/24.svg b/umap/static/umap/img/24.svg index 6d760791..b4b8f678 100644 --- a/umap/static/umap/img/24.svg +++ b/umap/static/umap/img/24.svg @@ -12,10 +12,6 @@ 0 1 - - - - @@ -86,5 +82,8 @@ + + + diff --git a/umap/static/umap/img/source/24-white.svg b/umap/static/umap/img/source/24-white.svg index baa2be5c..149eb62e 100644 --- a/umap/static/umap/img/source/24-white.svg +++ b/umap/static/umap/img/source/24-white.svg @@ -1,8 +1,8 @@ - - + + @@ -54,7 +54,6 @@ - @@ -79,5 +78,8 @@ + + + diff --git a/umap/static/umap/img/source/24.svg b/umap/static/umap/img/source/24.svg index ab7c400e..432831c0 100644 --- a/umap/static/umap/img/source/24.svg +++ b/umap/static/umap/img/source/24.svg @@ -1,9 +1,9 @@ - - - + + + @@ -32,10 +32,6 @@ 0 1 - - - - @@ -106,5 +102,8 @@ + + + diff --git a/umap/static/umap/js/modules/browser.js b/umap/static/umap/js/modules/browser.js index 80c7f358..474183b1 100644 --- a/umap/static/umap/js/modules/browser.js +++ b/umap/static/umap/js/modules/browser.js @@ -1,10 +1,13 @@ -// Uses `L._`` from Leaflet.i18n which we cannot import as a module yet import { DomUtil, DomEvent } from '../../vendors/leaflet/leaflet-src.esm.js' +import Orderable from './orderable.js' +import {translate} from './i18n.js' export default class Browser { constructor(map) { this.map = map this.map.on('moveend', this.onMoveEnd, this) + this.map.on('edit:enabled', this.onEnableEdit, this) + this.map.on('edit:disabled', this.onDisableEdit, this) this.options = { filter: '', inBbox: false, @@ -24,9 +27,9 @@ export default class Browser { symbol = feature._getIconUrl ? U.Icon.prototype.formatUrl(feature._getIconUrl(), feature) : null - zoom_to.title = L._('Bring feature to center') - edit.title = L._('Edit this feature') - del.title = L._('Delete this feature') + zoom_to.title = translate('Bring feature to center') + edit.title = translate('Edit this feature') + del.title = translate('Delete this feature') title.textContent = feature.getDisplayName() || '—' const bgcolor = feature.getDynamicOption('color') colorBox.style.backgroundColor = bgcolor @@ -69,18 +72,20 @@ export default class Browser { } addDataLayer(datalayer, parent) { - const container = DomUtil.create('div', datalayer.getHidableClass(), parent), - headline = DomUtil.create('h5', '', container), - counter = DomUtil.create('span', 'datalayer-counter', headline) + const container = DomUtil.create( + 'div', + `orderable ${datalayer.getHidableClass()}`, + parent + ), + headline = DomUtil.create('h5', '', container) container.id = this.datalayerId(datalayer) - datalayer.renderToolbox(headline) - DomUtil.add('span', '', headline, datalayer.options.name) const ul = DomUtil.create('ul', '', container) this.updateDatalayer(datalayer) datalayer.on('datachanged', this.onDataLayerChanged, this) this.map.ui.once('panel:closed', () => { datalayer.off('datachanged', this.onDataLayerChanged, this) }) + container.dataset.id = L.stamp(datalayer) } updateDatalayer(datalayer) { @@ -90,16 +95,22 @@ export default class Browser { // Panel is not open if (!parent) return DomUtil.classIf(parent, 'off', !datalayer.isVisible()) - const container = parent.querySelector('ul'), - counter = parent.querySelector('.datalayer-counter') + const container = parent.querySelector('ul') + const headline = parent.querySelector('h5') + const toggleList = () => parent.classList.toggle('show-list') + headline.innerHTML = '' + const toggle = DomUtil.create('i', 'datalayer-toggle-list', headline) + DomEvent.on(toggle, 'click', toggleList) + datalayer.renderToolbox(headline) + const name = DomUtil.create('span', 'datalayer-name', headline) + DomEvent.on(name, 'click', toggleList) container.innerHTML = '' datalayer.eachFeature((feature) => this.addFeature(feature, container)) let total = datalayer.count(), current = container.querySelectorAll('li').length, count = total == current ? total : `${current}/${total}` - counter.textContent = count - counter.title = L._('Features in this layer: {count}', { count: count }) + name.textContent = `${datalayer.options.name} (${count})` } onFormChange() { @@ -127,19 +138,14 @@ export default class Browser { // https://github.com/Leaflet/Leaflet/pull/9052 DomEvent.disableClickPropagation(container) - const title = DomUtil.add( - 'h3', - 'umap-browse-title', - container, - this.map.getOption('name') - ) + const title = DomUtil.add('h3', 'umap-browse-title', container, translate('Browse data')) const formContainer = DomUtil.create('div', '', container) const dataContainer = DomUtil.create('div', 'umap-browse-features', container) const fields = [ - ['options.filter', { handler: 'Input', placeholder: L._('Filter') }], - ['options.inBbox', { handler: 'Switch', label: L._('Current map view') }], + ['options.filter', { handler: 'Input', placeholder: translate('Filter') }], + ['options.inBbox', { handler: 'Switch', label: translate('Current map view') }], ] const builder = new U.FormBuilder(this, fields, { makeDirty: false, @@ -150,10 +156,36 @@ export default class Browser { this.map.ui.openPanel({ data: { html: container }, actions: [this.map._aboutLink()], + className: 'condensed' }) this.map.eachBrowsableDataLayer((datalayer) => { this.addDataLayer(datalayer, dataContainer) }) + // After datalayers have been added. + const orderable = new Orderable(dataContainer, L.bind(this.onReorder, this)) + } + + onReorder(src, dst, initialIndex, finalIndex) { + const layer = this.map.datalayers[src.dataset.id], + other = this.map.datalayers[dst.dataset.id], + minIndex = Math.min(layer.getRank(), other.getRank()), + maxIndex = Math.max(layer.getRank(), other.getRank()) + if (finalIndex === 0) layer.bringToTop() + else if (finalIndex > initialIndex) layer.insertBefore(other) + else layer.insertAfter(other) + this.map.eachDataLayerReverse((datalayer) => { + if (datalayer.getRank() >= minIndex && datalayer.getRank() <= maxIndex) + datalayer.isDirty = true + }) + this.map.indexDatalayers() + } + + onEnableEdit () { + this.map.ui._panel.classList.add('dark') + } + + onDisableEdit () { + this.map.ui._panel.classList.remove('dark') } } diff --git a/umap/static/umap/js/modules/orderable.js b/umap/static/umap/js/modules/orderable.js new file mode 100644 index 00000000..76334581 --- /dev/null +++ b/umap/static/umap/js/modules/orderable.js @@ -0,0 +1,84 @@ +import { DomEvent } from '../../vendors/leaflet/leaflet-src.esm.js' + +export default class Orderable { + constructor(parent, onDrop, selector = '.orderable') { + this.parent = parent + this.onCommit = onDrop + this.src = null + this.dst = null + this.els = this.parent.querySelectorAll(selector) + for (let i = 0; i < this.els.length; i++) this.makeDraggable(this.els[i]) + } + + makeDraggable(node) { + node.draggable = true + DomEvent.on(node, 'dragstart', this.onDragStart, this) + DomEvent.on(node, 'dragenter', this.onDragEnter, this) + DomEvent.on(node, 'dragover', this.onDragOver, this) + DomEvent.on(node, 'dragleave', this.onDragLeave, this) + DomEvent.on(node, 'drop', this.onDrop, this) + DomEvent.on(node, 'dragend', this.onDragEnd, this) + } + + nodeIndex(node) { + return Array.prototype.indexOf.call(this.parent.children, node) + } + + findTarget(node) { + while (node) { + if (this.nodeIndex(node) !== -1) return node + node = node.parentNode + } + } + + onDragStart(e) { + // e.target is the source node. + const realSrc = document.elementFromPoint(e.clientX, e.clientY); + // Only allow drag from the handle + if (!realSrc.classList.contains('drag-handle')) { + e.preventDefault() + return + } + this.src = e.target + this.initialIndex = this.nodeIndex(this.src) + this.src.classList.add('ordering') + e.dataTransfer.effectAllowed = 'move' + e.dataTransfer.setData('text/html', this.src.innerHTML) + } + + onDragOver(e) { + DomEvent.stop(e) + if (e.preventDefault) e.preventDefault() // Necessary. Allows us to drop. + e.dataTransfer.dropEffect = 'move' + return false + } + + onDragEnter(e) { + DomEvent.stop(e) + // e.target is the current hover target. + const dst = this.findTarget(e.target) + if (!dst || dst === this.src) return + this.dst = dst + const targetIndex = this.nodeIndex(this.dst), + srcIndex = this.nodeIndex(this.src) + if (targetIndex > srcIndex) this.parent.insertBefore(this.dst, this.src) + else this.parent.insertBefore(this.src, this.dst) + } + + onDragLeave(e) { + // e.target is previous target element. + } + + onDrop(e) { + // e.target is current target element. + if (e.stopPropagation) e.stopPropagation() // Stops the browser from redirecting. + if (!this.dst) return + this.onCommit(this.src, this.dst, this.initialIndex, this.nodeIndex(this.src)) + return false + } + + onDragEnd(e) { + // e.target is the source node. + this.src.classList.remove('ordering') + } +} diff --git a/umap/static/umap/js/modules/schema.js b/umap/static/umap/js/modules/schema.js index aec0d450..05728a94 100644 --- a/umap/static/umap/js/modules/schema.js +++ b/umap/static/umap/js/modules/schema.js @@ -372,6 +372,11 @@ export const SCHEMA = { impacts: ['ui'], label: translate('Allow scroll wheel zoom?'), }, + captionControl: { + type: Boolean, + label: translate('Display the caption control'), + default: true, + }, searchControl: { type: Boolean, impacts: ['ui'], diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js index c6e5e38c..d461c3a1 100644 --- a/umap/static/umap/js/umap.controls.js +++ b/umap/static/umap/js/umap.controls.js @@ -53,17 +53,6 @@ U.ChangeTileLayerAction = U.BaseAction.extend({ }, }) -U.ManageDatalayersAction = U.BaseAction.extend({ - options: { - className: 'dark manage-datalayers', - tooltip: L._('Manage layers'), - }, - - addHooks: function () { - this.map.manageDatalayers() - }, -}) - U.UpdateExtentAction = U.BaseAction.extend({ options: { className: 'update-map-extent dark', @@ -488,174 +477,48 @@ U.PermanentCreditsControl = L.Control.extend({ }, }) -U.DataLayersControl = L.Control.extend({ - options: { - position: 'topleft', - }, - - labels: { - zoomToLayer: L._('Zoom to layer extent'), - toggleLayer: L._('Show/hide layer'), - editLayer: L._('Edit'), - }, - +L.Control.Button = L.Control.extend({ initialize: function (map, options) { this.map = map L.Control.prototype.initialize.call(this, options) }, - _initLayout: function (map) { - const container = (this._container = L.DomUtil.create( - 'div', - 'leaflet-control-browse umap-control' - )), - actions = L.DomUtil.create('div', 'umap-browse-actions', container) - this._datalayers_container = L.DomUtil.create( - 'ul', - 'umap-browse-datalayers', - actions - ) - - L.DomUtil.createButton( - 'umap-browse-link', - actions, - L._('Browse data'), - map.openBrowser, - map - ) - - const toggleButton = L.DomUtil.createButton( - 'umap-browse-toggle', + onAdd: function (map) { + const container = L.DomUtil.create('div', `${this.options.className} umap-control`) + const button = L.DomUtil.createButton( + '', container, - L._('See data layers') + this.options.title, + this.onClick, + this ) - L.DomEvent.on(toggleButton, 'click', L.DomEvent.stop) - - map.whenReady(function () { - this.update() - }, this) - - if (L.Browser.pointer) { - L.DomEvent.disableClickPropagation(container) - L.DomEvent.on(container, 'wheel', L.DomEvent.stopPropagation) - L.DomEvent.on(container, 'MozMousePixelScroll', L.DomEvent.stopPropagation) - } - if (!L.Browser.touch) { - L.DomEvent.on( - container, - { - mouseenter: this.expand, - mouseleave: this.collapse, - }, - this - ) - } else { - L.DomEvent.on(container, 'click', L.DomEvent.stopPropagation) - L.DomEvent.on(toggleButton, 'click', L.DomEvent.stop).on( - toggleButton, - 'click', - this.expand, - this - ) - map.on('click', this.collapse, this) - } - + L.DomEvent.on(button, 'dblclick', L.DomEvent.stopPropagation) return container }, +}) - onAdd: function (map) { - if (!this._container) this._initLayout(map) - if (map.options.datalayersControl === 'expanded') this.expand() - return this._container +U.DataLayersControl = L.Control.Button.extend({ + options: { + position: 'topright', + className: 'leaflet-control-browse', + title: L._('Show datalayers'), }, - onRemove: function (map) { - this.collapse() + onClick: function () { + this.map.openBrowser() + }, +}) + +U.CaptionControl = L.Control.Button.extend({ + options: { + position: 'topright', + className: 'leaflet-control-caption', + title: L._('About'), }, - update: function () { - if (this._datalayers_container && this._map) { - this._datalayers_container.innerHTML = '' - this.map.eachDataLayerReverse(function (datalayer) { - this.addDataLayer(this._datalayers_container, datalayer) - }, this) - } - }, - - expand: function () { - L.DomUtil.addClass(this._container, 'expanded') - }, - - collapse: function () { - if (this.map.options.datalayersControl === 'expanded') return - L.DomUtil.removeClass(this._container, 'expanded') - }, - - addDataLayer: function (container, datalayer, draggable) { - const datalayerLi = L.DomUtil.create('li', '', container) - if (draggable) - L.DomUtil.element( - 'i', - { className: 'drag-handle', title: L._('Drag to reorder') }, - datalayerLi - ) - datalayer.renderToolbox(datalayerLi) - const title = L.DomUtil.add( - 'span', - 'layer-title', - datalayerLi, - datalayer.options.name - ) - - datalayerLi.id = `browse_data_toggle_${L.stamp(datalayer)}` - L.DomUtil.classIf(datalayerLi, 'off', !datalayer.isVisible()) - - title.textContent = datalayer.options.name - }, - - newDataLayer: function () { - const datalayer = this.map.createDataLayer({}) - datalayer.edit() - }, - - openPanel: function () { - if (!this.map.editEnabled) return - const container = L.DomUtil.create('ul', 'umap-browse-datalayers') - const title = L.DomUtil.create('h3', '', container) - title.textContent = L._('Manage layers') - this.map.eachDataLayerReverse(function (datalayer) { - this.addDataLayer(container, datalayer, true) - }, this) - const orderable = new U.Orderable(container) - orderable.on( - 'drop', - function (e) { - const layer = this.map.datalayers[e.src.dataset.id], - other = this.map.datalayers[e.dst.dataset.id], - minIndex = Math.min(layer.getRank(), other.getRank()), - maxIndex = Math.max(layer.getRank(), other.getRank()) - if (e.finalIndex === 0) layer.bringToTop() - else if (e.finalIndex > e.initialIndex) layer.insertBefore(other) - else layer.insertAfter(other) - this.map.eachDataLayerReverse((datalayer) => { - if (datalayer.getRank() >= minIndex && datalayer.getRank() <= maxIndex) - datalayer.isDirty = true - }) - this.map.indexDatalayers() - }, - this - ) - - const bar = L.DomUtil.create('div', 'button-bar', container) - L.DomUtil.createButton( - 'show-on-edit block add-datalayer button', - bar, - L._('Add a layer'), - this.newDataLayer, - this - ) - - this.map.ui.openPanel({ data: { html: container }, className: 'dark' }) + onClick: function () { + if (this.map.editEnabled) this.map.editCaption() + else this.map.displayCaption() }, }) @@ -667,6 +530,11 @@ U.DataLayer.include({ }, renderToolbox: function (container) { + L.DomUtil.element( + 'i', + { className: 'drag-handle', title: L._('Drag to reorder') }, + container + ) const toggle = L.DomUtil.create('i', 'layer-toggle', container), zoomTo = L.DomUtil.create('i', 'layer-zoom_to', container), edit = L.DomUtil.create('i', 'layer-edit show-on-edit', container), @@ -698,7 +566,6 @@ U.DataLayer.include({ L.DomEvent.on(zoomTo, 'click', this.zoomTo, this) L.DomUtil.addClass(container, this.getHidableClass()) L.DomUtil.classIf(container, 'off', !this.isVisible()) - container.dataset.id = L.stamp(this) }, getHidableElements: function () { @@ -748,7 +615,6 @@ const ControlsMixin = { 'locate', 'measure', 'editinosm', - 'datalayers', 'star', 'tilelayers', ], diff --git a/umap/static/umap/js/umap.core.js b/umap/static/umap/js/umap.core.js index 2c8da683..474287dd 100644 --- a/umap/static/umap/js/umap.core.js +++ b/umap/static/umap/js/umap.core.js @@ -531,94 +531,6 @@ U.Help = L.Class.extend({ ), }) -U.Orderable = L.Evented.extend({ - options: { - selector: 'li', - color: '#374E75', - }, - - initialize: function (parent, options) { - L.Util.setOptions(this, options) - this.parent = parent - this.src = null - this.dst = null - this.els = this.parent.querySelectorAll(this.options.selector) - for (let i = 0; i < this.els.length; i++) this.makeDraggable(this.els[i]) - }, - - makeDraggable: function (node) { - node.draggable = true - L.DomEvent.on(node, 'dragstart', this.onDragStart, this) - L.DomEvent.on(node, 'dragenter', this.onDragEnter, this) - L.DomEvent.on(node, 'dragover', this.onDragOver, this) - L.DomEvent.on(node, 'dragleave', this.onDragLeave, this) - L.DomEvent.on(node, 'drop', this.onDrop, this) - L.DomEvent.on(node, 'dragend', this.onDragEnd, this) - }, - - nodeIndex: function (node) { - return Array.prototype.indexOf.call(this.parent.children, node) - }, - - findTarget: function (node) { - while (node) { - if (this.nodeIndex(node) !== -1) return node - node = node.parentNode - } - }, - - onDragStart: function (e) { - // e.target is the source node. - this.src = e.target - this.initialIndex = this.nodeIndex(this.src) - this.srcBackgroundColor = this.src.style.backgroundColor - this.src.style.backgroundColor = this.options.color - e.dataTransfer.effectAllowed = 'move' - e.dataTransfer.setData('text/html', this.src.innerHTML) - }, - - onDragOver: function (e) { - L.DomEvent.stop(e) - if (e.preventDefault) e.preventDefault() // Necessary. Allows us to drop. - e.dataTransfer.dropEffect = 'move' - return false - }, - - onDragEnter: function (e) { - L.DomEvent.stop(e) - // e.target is the current hover target. - const dst = this.findTarget(e.target) - if (!dst || dst === this.src) return - this.dst = dst - const targetIndex = this.nodeIndex(this.dst), - srcIndex = this.nodeIndex(this.src) - if (targetIndex > srcIndex) this.parent.insertBefore(this.dst, this.src) - else this.parent.insertBefore(this.src, this.dst) - }, - - onDragLeave: function (e) { - // e.target is previous target element. - }, - - onDrop: function (e) { - // e.target is current target element. - if (e.stopPropagation) e.stopPropagation() // Stops the browser from redirecting. - if (!this.dst) return - this.fire('drop', { - src: this.src, - initialIndex: this.initialIndex, - finalIndex: this.nodeIndex(this.src), - dst: this.dst, - }) - return false - }, - - onDragEnd: function (e) { - // e.target is the source node. - this.src.style.backgroundColor = this.srcBackgroundColor - }, -}) - L.LatLng.prototype.isValid = function () { return ( isFinite(this.lat) && diff --git a/umap/static/umap/js/umap.forms.js b/umap/static/umap/js/umap.forms.js index 624cb8a2..acd10c61 100644 --- a/umap/static/umap/js/umap.forms.js +++ b/umap/static/umap/js/umap.forms.js @@ -1009,9 +1009,6 @@ U.FormBuilder = L.FormBuilder.extend({ case 'iconUrl': schema.handler = 'IconUrl' break - case 'datalayersControl': - schema.handler = 'DataLayersControl' - break case 'licence': schema.handler = 'LicenceChooser' break diff --git a/umap/static/umap/js/umap.js b/umap/static/umap/js/umap.js index 132b773e..5159e6d0 100644 --- a/umap/static/umap/js/umap.js +++ b/umap/static/umap/js/umap.js @@ -140,6 +140,9 @@ U.Map = L.Map.extend({ } delete this.options.displayDataBrowserOnLoad } + if (this.options.datalayersControl === 'expanded') { + this.options.onLoadPanel = 'databrowser' + } this.ui.on( 'panel:closed', @@ -302,7 +305,7 @@ U.Map = L.Map.extend({ // Specific case for datalayersControl // which accepts "expanded" value, on top of true/false/null if (L.Util.queryString('datalayersControl') === 'expanded') { - L.Util.setFromQueryString(options, 'datalayersControl') + options.datalayersControl = 'expanded' } }, @@ -326,7 +329,6 @@ U.Map = L.Map.extend({ const editActions = [ U.ImportAction, U.EditPropertiesAction, - U.ManageDatalayersAction, U.ChangeTileLayerAction, U.UpdateExtentAction, U.UpdatePermsAction, @@ -338,6 +340,7 @@ U.Map = L.Map.extend({ zoomOutTitle: L._('Zoom out'), }) this._controls.datalayers = new U.DataLayersControl(this) + this._controls.caption = new U.CaptionControl(this) this._controls.locate = new U.Locate(this, { strings: { title: L._('Center map on your location'), @@ -427,6 +430,8 @@ U.Map = L.Map.extend({ L.DomUtil.addClass(control._container, 'display-on-more') else L.DomUtil.removeClass(control._container, 'display-on-more') } + if (this.getOption('datalayersControl')) this._controls.datalayers.addTo(this) + if (this.getOption('captionControl')) this._controls.caption.addTo(this) if (this.getOption('permanentCredit')) this._controls.permanentCredit.addTo(this) if (this.getOption('moreControl')) this._controls.more.addTo(this) if (this.getOption('scaleControl')) this._controls.scale.addTo(this) @@ -460,7 +465,6 @@ U.Map = L.Map.extend({ if (!pane.dataset || !pane.dataset.id) continue this.datalayers_index.push(this.datalayers[pane.dataset.id]) } - this.updateDatalayersControl() }, ensurePanesOrder: function () { @@ -489,10 +493,6 @@ U.Map = L.Map.extend({ return this }, - updateDatalayersControl: function () { - if (this._controls.datalayers) this._controls.datalayers.update() - }, - backupOptions: function () { this._backupOptions = L.extend({}, this.options) this._backupOptions.tilelayer = L.extend({}, this.options.tilelayer) @@ -951,7 +951,6 @@ U.Map = L.Map.extend({ }) this.ensurePanesOrder() this.dirty_datalayers = [] - this.updateDatalayersControl() this.initTileLayers() this.isDirty = false }, @@ -1157,6 +1156,7 @@ U.Map = L.Map.extend({ UIFields.push(`options.${this.HIDDABLE_CONTROLS[i]}Control`) } UIFields = UIFields.concat([ + 'options.datalayersControl', 'options.moreControl', 'options.scrollWheelZoom', 'options.miniMap', @@ -1459,19 +1459,6 @@ U.Map = L.Map.extend({ slideshow.appendChild(slideshowBuilder.build()) }, - _editCredits: function (container) { - const credits = L.DomUtil.createFieldset(container, L._('Credits')) - const creditsFields = [ - 'options.licence', - 'options.shortCredit', - 'options.longCredit', - 'options.permanentCredit', - 'options.permanentCreditBackground', - ] - const creditsBuilder = new U.FormBuilder(this, creditsFields) - credits.appendChild(creditsBuilder.build()) - }, - _advancedActions: function (container) { const advancedActions = L.DomUtil.createFieldset(container, L._('Advanced actions')) const advancedButtons = L.DomUtil.create('div', 'button-bar half', advancedActions) @@ -1514,18 +1501,39 @@ U.Map = L.Map.extend({ ) }, - edit: function () { + editCaption: function () { if (!this.editEnabled) return if (this.options.editMode !== 'advanced') return const container = L.DomUtil.create('div', 'umap-edit-container'), metadataFields = ['options.name', 'options.description'], title = L.DomUtil.create('h3', '', container) - title.textContent = L._('Edit map properties') + title.textContent = L._('Edit map details') const builder = new U.FormBuilder(this, metadataFields, { className: 'map-metadata', }) const form = builder.build() container.appendChild(form) + + const credits = L.DomUtil.createFieldset(container, L._('Credits')) + const creditsFields = [ + 'options.licence', + 'options.shortCredit', + 'options.longCredit', + 'options.permanentCredit', + 'options.permanentCreditBackground', + ] + const creditsBuilder = new U.FormBuilder(this, creditsFields) + credits.appendChild(creditsBuilder.build()) + this.ui.openPanel({ data: { html: container }, className: 'dark' }) + + }, + + edit: function () { + if (!this.editEnabled) return + if (this.options.editMode !== 'advanced') return + const container = L.DomUtil.create('div', 'umap-edit-container') + title = L.DomUtil.create('h3', '', container) + title.textContent = L._('Edit map properties') this._editControls(container) this._editShapeProperties(container) this._editDefaultProperties(container) @@ -1534,7 +1542,6 @@ U.Map = L.Map.extend({ this._editOverlay(container) this._editBounds(container) this._editSlideshow(container) - this._editCredits(container) this._advancedActions(container) this.ui.openPanel({ data: { html: container }, className: 'dark' }) diff --git a/umap/static/umap/js/umap.layer.js b/umap/static/umap/js/umap.layer.js index 21ae6189..56d36383 100644 --- a/umap/static/umap/js/umap.layer.js +++ b/umap/static/umap/js/umap.layer.js @@ -845,7 +845,6 @@ U.DataLayer = L.Evented.extend({ if (L.Util.indexOf(this.map.datalayers_index, this) === -1) this.map.datalayers_index.push(this) } - this.map.updateDatalayersControl() }, _dataUrl: function () { @@ -1153,7 +1152,6 @@ U.DataLayer = L.Evented.extend({ delete this.map.datalayers[L.stamp(this)] this.map.datalayers_index.splice(this.getRank(), 1) this.parentPane.removeChild(this.pane) - this.map.updateDatalayersControl() this.fire('erase') this._leaflet_events_bk = this._leaflet_events this.map.off('moveend', this.onMoveEnd, this) diff --git a/umap/static/umap/map.css b/umap/static/umap/map.css index f6a643a6..b74f89b0 100644 --- a/umap/static/umap/map.css +++ b/umap/static/umap/map.css @@ -841,23 +841,21 @@ ul.photon-autocomplete { /* Datalayers Control */ /* ********************************* */ -.leaflet-control-browse .umap-browse-toggle { +.leaflet-control-caption [type="button"], +.leaflet-control-browse [type="button"] { background-image: url('./img/24.svg'); - width: 36px; - height: 36px; - background-position: -36px -72px; + width: 40px; + height: 40px; + background-position: -34px -70px; background-size: 180px; } -.leaflet-control-browse .umap-browse-actions { - background-color: #fff; - padding: 10px; - display: none; - line-height: 24px; - border-radius: 2px; +.leaflet-control-caption [type="button"] { + background-position: -70px -70px; } -.leaflet-control-browse .umap-browse-datalayers { - max-height: 15em; - overflow-y: auto; +.umap-edit-enabled .leaflet-control-caption [type="button"], +.umap-edit-enabled .leaflet-control-browse [type="button"] { + background-image: url('./img/24-white.svg'); + background-color: var(--color-darkGray); } .search-result-tools i, .leaflet-inplace-toolbar a, @@ -876,11 +874,20 @@ ul.photon-autocomplete { .dark .umap-browse-datalayers i { background-image: url('./img/16-white.svg'); } -.umap-browse-datalayers li[draggable] .drag-handle { - float: right; +.umap-browse-features ul { + display: none; +} +.show-list ul { + display: initial; +} +[draggable] .drag-handle { + display: none; +} +.umap-edit-enabled [draggable] .drag-handle { background-position: -72px -72px; margin-right: 5px; cursor: move; + display: initial; } .leaflet-inplace-toolbar a { background-image: url('./img/16-white.svg'); @@ -892,9 +899,6 @@ ul.photon-autocomplete { .leaflet-inplace-toolbar a:hover { background-color: #353c3e!important; } -.leaflet-control-browse .umap-browse-datalayers .off i { - cursor: inherit; -} .layer-toggle { background-position: -49px -31px; } @@ -958,8 +962,7 @@ ul.photon-autocomplete { .umap-extract-shape-from-multi{ background-position: -119px 2px; } -.umap-browse-features .feature-title, -.leaflet-control-browse .umap-browse-actions .layer-title { +.umap-browse-features .feature-title { width: inherit; cursor: inherit; padding-left: 6px; @@ -968,32 +971,7 @@ ul.photon-autocomplete { font-size: 12px; cursor: pointer; } -.leaflet-control-browse .umap-browse-actions .off .layer-title { - color: rgb(179, 179, 179); -} -.leaflet-control-browse.expanded > a, -.leaflet-control-browse.expanded > button { - display: none; -} -.leaflet-control-browse.expanded .umap-browse-actions { - display: block; -} -.leaflet-control-browse .umap-browse-link { - background-image: none; - background-color: rgb(68, 68, 68); - color: white; - display: block; - height: 24px; - line-height: 24px; - margin-top: 14px; - padding: 0 5px; - text-align: right; - min-width: 160px; - width: 100%; - border-radius: 2px; -} -a.add-datalayer:before, -.leaflet-control-browse .umap-browse-link:before { +a.add-datalayer:before { background-image: url('./img/16.svg'); background-repeat: no-repeat; background-position: -45px -96px; @@ -1006,8 +984,7 @@ a.add-datalayer:before, a.add-datalayer:before { background-position: -20px -20px; } -a.add-datalayer:hover, -.leaflet-control-browse .umap-browse-link:hover { +a.add-datalayer:hover { background-color: rgb(99, 99, 99); } .umap-browse-data .off .feature { @@ -1031,9 +1008,13 @@ a.add-datalayer:hover, padding-left: 5px; height: 30px; line-height: 30px; - background-color: #eeeee0; + background-color: var(--color-lightGray); color: #666; } +.dark .umap-browse-features h5 { + background-color: initial; + color: white; +} .umap-browse-features h5 span { margin-left: 10px; } @@ -1095,9 +1076,16 @@ a.add-datalayer:hover, font-size: 0.9em; margin-bottom: 14px; } -.datalayer-counter { +.datalayer-toggle-list { float: right; margin-right: 5px; + background-position: -145px -70px; +} +.show-list .datalayer-toggle-list { + background-position: -145px -45px; +} +.datalayer-name { + cursor: pointer; } From 5b78d6f0ffd892dc014cd6137bb5ac74d4ca308e Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Wed, 6 Mar 2024 19:58:20 +0100 Subject: [PATCH 02/44] wip: refactor browser related CSS --- umap/static/umap/base.css | 55 +- umap/static/umap/img/16-white.svg | 2 + umap/static/umap/img/16.svg | 2 + umap/static/umap/img/source/16-white.svg | 1098 ++++------------------ umap/static/umap/img/source/16.svg | 4 +- umap/static/umap/js/modules/browser.js | 15 +- umap/static/umap/js/umap.controls.js | 4 +- umap/static/umap/js/umap.ui.js | 2 +- umap/static/umap/map.css | 269 +++--- 9 files changed, 345 insertions(+), 1106 deletions(-) diff --git a/umap/static/umap/base.css b/umap/static/umap/base.css index ccbda217..844ae097 100644 --- a/umap/static/umap/base.css +++ b/umap/static/umap/base.css @@ -547,7 +547,6 @@ i.info { .umap-layer-properties-container, .umap-browse-data, .umap-facet-search, -.umap-browse-datalayers, .umap-tilelayer-switcher-container { padding: 0 10px; } @@ -678,13 +677,13 @@ input[type=hidden].blur + [type="button"] { .leaflet-ui-container { overflow-x: hidden; } -#umap-ui-container { +#umap-panel { /* Added for playwright to consider the element as non visible */ /* as being out of the visible viewport is not enough */ visibility: hidden; position: absolute; bottom: 0; - padding: 0 10px; + padding: 10px; border-left: 1px solid var(--color-lightGray); overflow-x: auto; z-index: 1010; @@ -692,23 +691,19 @@ input[type=hidden].blur + [type="button"] { opacity: 0.98; cursor: initial; } -#umap-ui-container.login-panel { - position: fixed; /* Should not scroll when used in content pages (like home page) */ - z-index: 1011; /* Above a map panel if any */ -} -#umap-ui-container.dark { +#umap-panel.dark { border-left: 1px solid #222; background-color: var(--color-darkGray); color: #efefef; } -#umap-ui-container.fullwidth { +#umap-panel.fullwidth { width: 100%; right: -100%; z-index: 10000; padding-left: 0; padding-right: 0; } -.umap-caption-bar-enabled #umap-ui-container { +.umap-caption-bar-enabled #umap-panel { bottom: 46px; } .leaflet-top, @@ -718,25 +713,25 @@ input[type=hidden].blur + [type="button"] { .umap-ui .leaflet-right { right: 400px; } -#umap-ui-container, +#umap-panel, #umap-alert-container, #umap-tooltip-container { -moz-box-sizing:border-box; -webkit-box-sizing:border-box; box-sizing: border-box; } -#umap-ui-container .umap-popup-content img { +#umap-panel .umap-popup-content img { /* See https://github.com/Leaflet/Leaflet/commit/61d746818b99d362108545c151a27f09d60960ee#commitcomment-6061847 */ max-width: 99% !important; } -#umap-ui-container .umap-popup-content { +#umap-panel .umap-popup-content { max-height: inherit; } -#umap-ui-container .body { +#umap-panel .body { clear: both; height: calc(100% - 54px); /* Minus size of toolbox */ } -#umap-ui-container .toolbox { +#umap-panel .toolbox { padding: 5px 10px; overflow: hidden; display: flex; @@ -745,7 +740,7 @@ input[type=hidden].blur + [type="button"] { justify-content: flex-start; gap: 5px; } -#umap-ui-container .toolbox li { +#umap-panel .toolbox li { color: #2e3436; line-height: 32px; cursor: pointer; @@ -755,15 +750,15 @@ input[type=hidden].blur + [type="button"] { border: 1px solid #b6b6b3; border-radius: 2px; } -#umap-ui-container.dark .toolbox li { +#umap-panel.dark .toolbox li { color: #d3dfeb; border: 1px solid #202425; } -#umap-ui-container .toolbox li:hover { +#umap-panel .toolbox li:hover { color: #2e3436; background-color: #d4d4d2; } -#umap-ui-container.dark .toolbox li:hover { +#umap-panel.dark .toolbox li:hover { color: #eeeeec; background-color: #353c3e; } @@ -897,6 +892,7 @@ input:invalid { /* *********** */ /* Close link */ /* *********** */ +.umap-resize-icon, .umap-close-icon { background-repeat: no-repeat; background-image: url('./img/16.svg'); @@ -905,6 +901,10 @@ input:invalid { padding: 0 10px; vertical-align: middle; } +.umap-resize-icon { + background-position: -76px -150px; +} +.dark .umap-resize-icon, .dark .umap-close-icon { background-image: url('./img/16-white.svg'); } @@ -963,35 +963,36 @@ input:invalid { /* Mobile */ /* *********** */ @media all and (orientation:landscape) { - .umap-edit-enabled #umap-ui-container { + .umap-edit-enabled #umap-panel { top: 46px; } - #umap-ui-container { + #umap-panel { width: 400px; right: -400px; top: 0; } - .umap-ui #umap-ui-container { + .umap-ui #umap-panel { right: 0; visibility: visible; } - #umap-ui-container.condensed { + #umap-panel.condensed { margin-top: 10px; margin-right: 10px; - max-height: 300px; + max-height: 500px; + bottom: initial; width: 390px; - border-radius: 10px; + border-radius: 5px; } } @media all and (orientation:portrait) { - #umap-ui-container { + #umap-panel { height: 50%; max-height: 400px; width: 100%; bottom: 0; right: -100%; } - .umap-ui #umap-ui-container { + .umap-ui #umap-panel { right: 0; visibility: visible; } diff --git a/umap/static/umap/img/16-white.svg b/umap/static/umap/img/16-white.svg index 7a42f5bf..022e413f 100644 --- a/umap/static/umap/img/16-white.svg +++ b/umap/static/umap/img/16-white.svg @@ -186,5 +186,7 @@ + + diff --git a/umap/static/umap/img/16.svg b/umap/static/umap/img/16.svg index 10d76ca4..e046e342 100644 --- a/umap/static/umap/img/16.svg +++ b/umap/static/umap/img/16.svg @@ -178,5 +178,7 @@ + + diff --git a/umap/static/umap/img/source/16-white.svg b/umap/static/umap/img/source/16-white.svg index 81bf9d91..11ab2c03 100644 --- a/umap/static/umap/img/source/16-white.svg +++ b/umap/static/umap/img/source/16-white.svg @@ -1,980 +1,214 @@ - - - - + + + + - - + + - - + + - - + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - + - + image/svg+xml - + - -   - - - - + +   + + + + - - - - - - - - - - -   - - + + + + + + + + + + +   + + - - - - - - + + + + + + - - - - - - - + + + + + + + - - - - - - - - + + + + + + + + - - + + - - - + + + - - - - + + + + - - - + + + - - - - + + + + - - + + - - - - + + + + - - + + - - - - + + + + - - + + - - - - + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + - - - + + + - - - - + + + + - - - - - + + + + + - - - + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - + + + diff --git a/umap/static/umap/img/source/16.svg b/umap/static/umap/img/source/16.svg index a3df2236..16569742 100644 --- a/umap/static/umap/img/source/16.svg +++ b/umap/static/umap/img/source/16.svg @@ -10,7 +10,7 @@ - + @@ -197,5 +197,7 @@ + + diff --git a/umap/static/umap/js/modules/browser.js b/umap/static/umap/js/modules/browser.js index 474183b1..288b7a35 100644 --- a/umap/static/umap/js/modules/browser.js +++ b/umap/static/umap/js/modules/browser.js @@ -72,9 +72,10 @@ export default class Browser { } addDataLayer(datalayer, parent) { + let className = `orderable datalayer ${datalayer.getHidableClass()}` const container = DomUtil.create( 'div', - `orderable ${datalayer.getHidableClass()}`, + className, parent ), headline = DomUtil.create('h5', '', container) @@ -133,15 +134,14 @@ export default class Browser { open() { // Get once but use it for each feature later this.filterKeys = this.map.getFilterKeys() - const container = DomUtil.create('div', 'umap-browse-data') + const container = DomUtil.create('div') // HOTFIX. Remove when this is released: // https://github.com/Leaflet/Leaflet/pull/9052 DomEvent.disableClickPropagation(container) - const title = DomUtil.add('h3', 'umap-browse-title', container, translate('Browse data')) - + const title = DomUtil.add('h3', '', container, translate('Browse data')) const formContainer = DomUtil.create('div', '', container) - const dataContainer = DomUtil.create('div', 'umap-browse-features', container) + const dataContainer = DomUtil.create('div', '', container) const fields = [ ['options.filter', { handler: 'Input', placeholder: translate('Filter') }], @@ -153,10 +153,11 @@ export default class Browser { }) formContainer.appendChild(builder.build()) + let className = 'umap-browser' + if (this.map.editEnabled) className += ' dark' this.map.ui.openPanel({ data: { html: container }, - actions: [this.map._aboutLink()], - className: 'condensed' + className: className }) this.map.eachBrowsableDataLayer((datalayer) => { diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js index d461c3a1..31732576 100644 --- a/umap/static/umap/js/umap.controls.js +++ b/umap/static/umap/js/umap.controls.js @@ -500,7 +500,7 @@ L.Control.Button = L.Control.extend({ U.DataLayersControl = L.Control.Button.extend({ options: { position: 'topright', - className: 'leaflet-control-browse', + className: 'umap-control-browse', title: L._('Show datalayers'), }, @@ -512,7 +512,7 @@ U.DataLayersControl = L.Control.Button.extend({ U.CaptionControl = L.Control.Button.extend({ options: { position: 'topright', - className: 'leaflet-control-caption', + className: 'umap-control-caption', title: L._('About'), }, diff --git a/umap/static/umap/js/umap.ui.js b/umap/static/umap/js/umap.ui.js index 7434b38f..06f9d0dd 100644 --- a/umap/static/umap/js/umap.ui.js +++ b/umap/static/umap/js/umap.ui.js @@ -14,7 +14,7 @@ U.UI = L.Evented.extend({ L.DomEvent.on(this.container, 'wheel', L.DomEvent.stopPropagation) L.DomEvent.on(this.container, 'MozMousePixelScroll', L.DomEvent.stopPropagation) this._panel = L.DomUtil.create('div', '', this.container) - this._panel.id = 'umap-ui-container' + this._panel.id = 'umap-panel' this._alert = L.DomUtil.create('div', 'with-transition', this.container) this._alert.id = 'umap-alert-container' this._tooltip = L.DomUtil.create('div', '', this.container) diff --git a/umap/static/umap/map.css b/umap/static/umap/map.css index b74f89b0..7d39e2d4 100644 --- a/umap/static/umap/map.css +++ b/umap/static/umap/map.css @@ -317,7 +317,6 @@ ul.photon-autocomplete { background-position: -36px -72px; } .permissions-panel h3:before, -.umap-browse-datalayers h3:before, .umap-edit-container h3:before, .umap-feature-properties:before, .umap-layer-properties-container h3:before, @@ -836,59 +835,6 @@ ul.photon-autocomplete { } - -/* ********************************* */ -/* Datalayers Control */ -/* ********************************* */ - -.leaflet-control-caption [type="button"], -.leaflet-control-browse [type="button"] { - background-image: url('./img/24.svg'); - width: 40px; - height: 40px; - background-position: -34px -70px; - background-size: 180px; -} -.leaflet-control-caption [type="button"] { - background-position: -70px -70px; -} -.umap-edit-enabled .leaflet-control-caption [type="button"], -.umap-edit-enabled .leaflet-control-browse [type="button"] { - background-image: url('./img/24-white.svg'); - background-color: var(--color-darkGray); -} -.search-result-tools i, -.leaflet-inplace-toolbar a, -.umap-browse-features i, -.umap-caption i, -.umap-browse-datalayers i { - background-repeat: no-repeat; - background-image: url('./img/16.svg'); - display: inline; - padding: 0 10px; - cursor: pointer; - height: 24px; - line-height: 24px; - vertical-align: middle; -} -.dark .umap-browse-datalayers i { - background-image: url('./img/16-white.svg'); -} -.umap-browse-features ul { - display: none; -} -.show-list ul { - display: initial; -} -[draggable] .drag-handle { - display: none; -} -.umap-edit-enabled [draggable] .drag-handle { - background-position: -72px -72px; - margin-right: 5px; - cursor: move; - display: initial; -} .leaflet-inplace-toolbar a { background-image: url('./img/16-white.svg'); background-color: var(--color-darkGray)!important; @@ -962,12 +908,12 @@ ul.photon-autocomplete { .umap-extract-shape-from-multi{ background-position: -119px 2px; } -.umap-browse-features .feature-title { +.umap-browser .feature-title { width: inherit; cursor: inherit; padding-left: 6px; } -.umap-browse-features .feature-title { +.umap-browser .feature-title { font-size: 12px; cursor: pointer; } @@ -987,79 +933,6 @@ a.add-datalayer:before { a.add-datalayer:hover { background-color: rgb(99, 99, 99); } -.umap-browse-data .off .feature { - display: none; -} - - -/* ********************************* */ -/* Features browser panel */ -/* ********************************* */ - -.umap-facet-search .formbox, -.umap-browse-features > div { - border: 1px solid #d3d3d3; - margin-bottom: 14px; - border-radius: 2px; -} -.umap-browse-features h5, .umap-facet-search h5 { - margin-bottom: 0; - overflow: hidden; - padding-left: 5px; - height: 30px; - line-height: 30px; - background-color: var(--color-lightGray); - color: #666; -} -.dark .umap-browse-features h5 { - background-color: initial; - color: white; -} -.umap-browse-features h5 span { - margin-left: 10px; -} -.umap-browse-features li, .umap-facet-search li { - padding: 2px 0; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -.umap-facet-search li:nth-child(even), -.umap-browse-features li:nth-child(even) { - background-color: #f8f8f3; -} -.umap-browse-features .feature-color { - box-shadow: 0 0 2px 0 black inset; - cursor: inherit; - -moz-box-sizing:border-box; - -webkit-box-sizing:border-box; - box-sizing: border-box; - background: none; - display: inline-block; - padding: 0; - width: 24px; - text-align: center; - margin-left: 5px; -} -.umap-browse-features .feature-color img { - width: 24px; -} -.umap-browse-features .feature-color span { - font-style: normal; - font-weight: bold; -} -.umap-browse-features .polygon .feature-color, -.umap-browse-features .polyline .feature-color { - box-shadow: 0 0 2px 0 black inset; - background-image: url('./img/24.svg'); - background-size: 500%; -} -.umap-browse-features .polyline .feature-color { - background-position: -72px -23px; -} -.umap-browse-features .polygon .feature-color { - background-position: -48px -25px; -} .show-on-edit { display: none!important; } @@ -1072,16 +945,140 @@ a.add-datalayer:hover { .umap-edit-enabled .show-on-edit.block { display: block!important; } -.umap-browse-description { - font-size: 0.9em; - margin-bottom: 14px; + + +/* ********************************* */ +/* Browser panel */ +/* ********************************* */ +.umap-control-caption [type="button"], +.umap-control-browse [type="button"] { + background-image: url('./img/24.svg'); + width: 40px; + height: 40px; + background-position: -34px -70px; + background-size: 180px; } -.datalayer-toggle-list { +.umap-control-caption [type="button"] { + background-position: -70px -70px; +} +.umap-edit-enabled .umap-control-caption [type="button"], +.umap-edit-enabled .umap-control-browse [type="button"] { + background-image: url('./img/24-white.svg'); + background-color: var(--color-darkGray); +} +.search-result-tools i, +.leaflet-inplace-toolbar a, +.umap-browser i, +.umap-caption i { + background-repeat: no-repeat; + background-image: url('./img/16.svg'); + display: inline; + padding: 0 10px; + cursor: pointer; + height: 24px; + line-height: 24px; + vertical-align: middle; +} +.umap-browser.dark .datalayer i { + background-image: url('./img/16-white.svg'); +} +.umap-browser ul { + display: none; +} +.show-list ul { + display: block; +} +i.drag-handle { + display: none; + background-position: -72px -73px; + cursor: move; + margin-right: 10px; +} +.umap-edit-enabled [draggable] .drag-handle { + display: inline-block; +} + +.umap-browser .off .feature { + display: none; +} +.umap-facet-search .formbox, +.umap-browser .datalayer { + margin-bottom: 2px; + border-radius: 2px; +} +.umap-browser .datalayer ul { + border: 1px solid #d3d3d3; +} +.umap-browser.dark .datalayer ul { + border: 1px solid #2c3233; +} +.umap-browser h5, .umap-facet-search h5 { + margin-bottom: 0; + overflow: hidden; + padding-left: 5px; + height: 30px; + line-height: 30px; + background-color: var(--color-lightGray); + color: #666; +} +.umap-browser.dark h5 { + background-color: #2c3233; + color: white; +} +.umap-browser h5 span { + margin-left: 10px; +} +.umap-browser li, .umap-facet-search li { + padding: 2px 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.umap-facet-search li:nth-child(even), +.umap-browser .datalayer li:nth-child(even) { + background-color: #efefef; +} +.umap-browser.dark .datalayer li:nth-child(even) { + background-color: #2c3233; +} +.umap-browser .datalayer i.feature-color { + box-shadow: 0 0 2px 0 black inset; + cursor: inherit; + -moz-box-sizing:border-box; + -webkit-box-sizing:border-box; + box-sizing: border-box; + background: none; + display: inline-block; + padding: 0; + width: 24px; + text-align: center; + margin-left: 5px; +} +.umap-browser .datalayer .feature-color img { + width: 24px; +} +.umap-browser .datalayer .feature-color span { + font-style: normal; + font-weight: bold; +} +.umap-browser .polygon .feature-color, +.umap-browser .polyline .feature-color { + box-shadow: 0 0 2px 0 black inset; + background-image: url('./img/24.svg'); + background-size: 500%; +} +.umap-browser .polyline .feature-color { + background-position: -72px -23px; +} +.umap-browser .polygon .feature-color { + background-position: -48px -25px; +} +.umap-browser .datalayer-toggle-list { float: right; margin-right: 5px; background-position: -145px -70px; } -.show-list .datalayer-toggle-list { +.umap-browser .show-list .datalayer-toggle-list { background-position: -145px -45px; } .datalayer-name { @@ -1092,11 +1089,11 @@ a.add-datalayer:hover { /* ********************************* */ /* Table Editor */ /* ********************************* */ -#umap-ui-container.umap-table-editor { +#umap-panel.umap-table-editor { padding-left: 0; padding-right: 0; } -#umap-ui-container.umap-table-editor .toolbox li { +#umap-panel.umap-table-editor .toolbox li { float: left; } From 41e7b34813d9bfebeb01dd16553b8751e13f27b9 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Wed, 6 Mar 2024 20:00:07 +0100 Subject: [PATCH 03/44] wip: allow to open browser in condensed mode --- umap/static/umap/js/modules/browser.js | 1 + umap/static/umap/js/modules/schema.js | 1 + umap/static/umap/js/umap.js | 26 +++++++++++++++----------- umap/static/umap/js/umap.ui.js | 3 ++- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/umap/static/umap/js/modules/browser.js b/umap/static/umap/js/modules/browser.js index 288b7a35..1e80b695 100644 --- a/umap/static/umap/js/modules/browser.js +++ b/umap/static/umap/js/modules/browser.js @@ -73,6 +73,7 @@ export default class Browser { addDataLayer(datalayer, parent) { let className = `orderable datalayer ${datalayer.getHidableClass()}` + if (this.map.ui.PANEL_MODE !== 'condensed') className += ' show-list' const container = DomUtil.create( 'div', className, diff --git a/umap/static/umap/js/modules/schema.js b/umap/static/umap/js/modules/schema.js index 05728a94..97f3d777 100644 --- a/umap/static/umap/js/modules/schema.js +++ b/umap/static/umap/js/modules/schema.js @@ -273,6 +273,7 @@ export const SCHEMA = { ['none', translate('None')], ['caption', translate('Caption')], ['databrowser', translate('Data browser')], + ['datalayers', translate('Layers')], ['facet', translate('Facet search')], ], default: 'none', diff --git a/umap/static/umap/js/umap.js b/umap/static/umap/js/umap.js index 5159e6d0..16691541 100644 --- a/umap/static/umap/js/umap.js +++ b/umap/static/umap/js/umap.js @@ -141,7 +141,7 @@ U.Map = L.Map.extend({ delete this.options.displayDataBrowserOnLoad } if (this.options.datalayersControl === 'expanded') { - this.options.onLoadPanel = 'databrowser' + this.options.onLoadPanel = 'datalayers' } this.ui.on( @@ -214,14 +214,19 @@ U.Map = L.Map.extend({ } this.initShortcuts() this.onceDataLoaded(function () { - if (L.Util.queryString('share')) this.share.open() - else if (this.options.onLoadPanel === 'databrowser') this.openBrowser() - else if (this.options.onLoadPanel === 'caption') this.displayCaption() - else if ( - this.options.onLoadPanel === 'facet' || - this.options.onLoadPanel === 'datafilters' - ) + if (L.Util.queryString('share')) { + this.share.open() + } else if (this.options.onLoadPanel === 'databrowser') { + this.openBrowser() + } else if (this.options.onLoadPanel === 'datalayers') { + this.ui.PANEL_MODE = 'condensed' + this.openBrowser() + } else if (this.options.onLoadPanel === 'caption') { + this.ui.PANEL_MODE = 'condensed' + this.displayCaption() + } else if (['facet', 'datafilters'].includes(this.options.onLoadPanel)) { this.openFacet() + } const slug = L.Util.queryString('feature') if (slug && this.features_index[slug]) this.features_index[slug].view() if (L.Util.queryString('edit')) { @@ -305,7 +310,7 @@ U.Map = L.Map.extend({ // Specific case for datalayersControl // which accepts "expanded" value, on top of true/false/null if (L.Util.queryString('datalayersControl') === 'expanded') { - options.datalayersControl = 'expanded' + options.onLoadPanel = 'datalayers' } }, @@ -1525,14 +1530,13 @@ U.Map = L.Map.extend({ const creditsBuilder = new U.FormBuilder(this, creditsFields) credits.appendChild(creditsBuilder.build()) this.ui.openPanel({ data: { html: container }, className: 'dark' }) - }, edit: function () { if (!this.editEnabled) return if (this.options.editMode !== 'advanced') return const container = L.DomUtil.create('div', 'umap-edit-container') - title = L.DomUtil.create('h3', '', container) + const title = L.DomUtil.create('h3', '', container) title.textContent = L._('Edit map properties') this._editControls(container) this._editShapeProperties(container) diff --git a/umap/static/umap/js/umap.ui.js b/umap/static/umap/js/umap.ui.js index 06f9d0dd..eccc32eb 100644 --- a/umap/static/umap/js/umap.ui.js +++ b/umap/static/umap/js/umap.ui.js @@ -5,6 +5,7 @@ U.UI = L.Evented.extend({ ALERTS: Array(), ALERT_ID: null, TOOLTIP_ID: null, + PANEL_MODE: 'expanded', initialize: function (parent) { this.parent = parent @@ -22,7 +23,7 @@ U.UI = L.Evented.extend({ }, resetPanelClassName: function () { - this._panel.className = 'with-transition' + this._panel.className = `with-transition ${this.PANEL_MODE}` }, openPanel: function (e) { From 9e3984fdcb4c2ccab9d3299f53d8f802a7ade5ad Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Wed, 6 Mar 2024 20:01:04 +0100 Subject: [PATCH 04/44] wip: do not change panel color if it's not browser Ugly way to do, but for now I haven't found a better option --- umap/static/umap/js/modules/browser.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/umap/static/umap/js/modules/browser.js b/umap/static/umap/js/modules/browser.js index 1e80b695..a2230ad6 100644 --- a/umap/static/umap/js/modules/browser.js +++ b/umap/static/umap/js/modules/browser.js @@ -122,9 +122,12 @@ export default class Browser { }) } + isOpen () { + return !!document.querySelector('.umap-browser') + } + onMoveEnd() { - const isBrowserOpen = !!document.querySelector('.umap-browse-data') - if (!isBrowserOpen) return + if (!this.isOpen()) return const isListDynamic = this.options.inBbox this.map.eachBrowsableDataLayer((datalayer) => { if (!isListDynamic && !datalayer.hasDynamicData()) return @@ -184,10 +187,12 @@ export default class Browser { } onEnableEdit () { + if (!this.isOpen()) return this.map.ui._panel.classList.add('dark') } onDisableEdit () { + if (!this.isOpen()) return this.map.ui._panel.classList.remove('dark') } } From af203d7b90ebfb11df5379b8bb695822bc4f83de Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Wed, 6 Mar 2024 20:02:23 +0100 Subject: [PATCH 05/44] wip: remove extra actions from browser/facets --- umap/static/umap/js/umap.controls.js | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js index 31732576..04933087 100644 --- a/umap/static/umap/js/umap.controls.js +++ b/umap/static/umap/js/umap.controls.js @@ -757,21 +757,7 @@ const ControlsMixin = { `, urls ) - const browser = L.DomUtil.create('li', '') - L.DomUtil.create('i', 'umap-icon-16 umap-list', browser) - const labelBrowser = L.DomUtil.create('span', '', browser) - labelBrowser.textContent = labelBrowser.title = L._('Browse data') - L.DomEvent.on(browser, 'click', this.openBrowser, this) - const actions = [browser] - if (this.options.facetKey) { - const filter = L.DomUtil.create('li', '') - L.DomUtil.create('i', 'umap-icon-16 umap-add', filter) - const labelFilter = L.DomUtil.create('span', '', filter) - labelFilter.textContent = labelFilter.title = L._('Facet search') - L.DomEvent.on(filter, 'click', this.openFacet, this) - actions.push(filter) - } - this.ui.openPanel({ data: { html: container }, actions: actions }) + this.ui.openPanel({ data: { html: container } }) }, renderEditToolbar: function () { From 56e6b20087b11f6861f7f10ca20681d9423cc900 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Wed, 6 Mar 2024 20:02:38 +0100 Subject: [PATCH 06/44] wip: add resize button in panel --- umap/static/umap/js/umap.ui.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/umap/static/umap/js/umap.ui.js b/umap/static/umap/js/umap.ui.js index eccc32eb..89ee90d0 100644 --- a/umap/static/umap/js/umap.ui.js +++ b/umap/static/umap/js/umap.ui.js @@ -41,6 +41,10 @@ U.UI = L.Evented.extend({ L.DomUtil.add('i', 'umap-close-icon', closeLink) const label = L.DomUtil.create('span', '', closeLink) label.title = label.textContent = L._('Close') + const resizeLink = L.DomUtil.create('li', 'umap-resize-link', actionsContainer) + L.DomUtil.add('i', 'umap-resize-icon', resizeLink) + const resizeLabel = L.DomUtil.create('span', '', resizeLink) + resizeLabel.title = resizeLabel.textContent = L._('Toggle size') if (e.actions) { for (let i = 0; i < e.actions.length; i++) { actionsContainer.appendChild(e.actions[i]) @@ -62,6 +66,11 @@ U.UI = L.Evented.extend({ L.DomUtil.addClass(this.parent, 'umap-ui') } L.DomEvent.on(closeLink, 'click', this.closePanel, this) + L.DomEvent.on(resizeLink, 'click', this.resizePanel, this) + }, + + resizePanel: function () { + this._panel.classList.toggle('condensed') }, closePanel: function () { From 8524cc785fabac0ab26fee326cc2b65336619328 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Fri, 8 Mar 2024 18:17:20 +0100 Subject: [PATCH 07/44] chore: fix tests --- umap/static/umap/content.css | 10 +- umap/static/umap/js/modules/browser.js | 18 +- umap/static/umap/js/umap.controls.js | 2 +- umap/static/umap/locale/am_ET.js | 2 +- umap/static/umap/locale/am_ET.json | 2 +- umap/static/umap/locale/ar.js | 2 +- umap/static/umap/locale/ar.json | 2 +- umap/static/umap/locale/ast.js | 2 +- umap/static/umap/locale/ast.json | 2 +- umap/static/umap/locale/bg.js | 2 +- umap/static/umap/locale/bg.json | 2 +- umap/static/umap/locale/br.js | 2 +- umap/static/umap/locale/br.json | 2 +- umap/static/umap/locale/ca.js | 2 +- umap/static/umap/locale/ca.json | 2 +- umap/static/umap/locale/cs_CZ.js | 2 +- umap/static/umap/locale/cs_CZ.json | 2 +- umap/static/umap/locale/da.js | 2 +- umap/static/umap/locale/da.json | 2 +- umap/static/umap/locale/de.js | 2 +- umap/static/umap/locale/de.json | 2 +- umap/static/umap/locale/el.js | 2 +- umap/static/umap/locale/el.json | 2 +- umap/static/umap/locale/en.js | 2 +- umap/static/umap/locale/en.json | 2 +- umap/static/umap/locale/en_US.json | 2 +- umap/static/umap/locale/es.js | 2 +- umap/static/umap/locale/es.json | 2 +- umap/static/umap/locale/et.js | 2 +- umap/static/umap/locale/et.json | 2 +- umap/static/umap/locale/eu.js | 2 +- umap/static/umap/locale/eu.json | 2 +- umap/static/umap/locale/fa_IR.js | 2 +- umap/static/umap/locale/fa_IR.json | 2 +- umap/static/umap/locale/fi.js | 2 +- umap/static/umap/locale/fi.json | 2 +- umap/static/umap/locale/fr.js | 2 +- umap/static/umap/locale/fr.json | 2 +- umap/static/umap/locale/gl.js | 2 +- umap/static/umap/locale/gl.json | 2 +- umap/static/umap/locale/he.js | 2 +- umap/static/umap/locale/he.json | 2 +- umap/static/umap/locale/hr.js | 2 +- umap/static/umap/locale/hr.json | 2 +- umap/static/umap/locale/hu.js | 2 +- umap/static/umap/locale/hu.json | 2 +- umap/static/umap/locale/id.js | 2 +- umap/static/umap/locale/id.json | 2 +- umap/static/umap/locale/is.js | 2 +- umap/static/umap/locale/is.json | 2 +- umap/static/umap/locale/it.js | 2 +- umap/static/umap/locale/it.json | 2 +- umap/static/umap/locale/ja.js | 2 +- umap/static/umap/locale/ja.json | 2 +- umap/static/umap/locale/ko.js | 2 +- umap/static/umap/locale/ko.json | 2 +- umap/static/umap/locale/lt.js | 2 +- umap/static/umap/locale/lt.json | 2 +- umap/static/umap/locale/ms.js | 2 +- umap/static/umap/locale/ms.json | 2 +- umap/static/umap/locale/nl.js | 2 +- umap/static/umap/locale/nl.json | 2 +- umap/static/umap/locale/no.js | 2 +- umap/static/umap/locale/no.json | 2 +- umap/static/umap/locale/pl.js | 2 +- umap/static/umap/locale/pl.json | 2 +- umap/static/umap/locale/pl_PL.json | 2 +- umap/static/umap/locale/pt.js | 2 +- umap/static/umap/locale/pt.json | 2 +- umap/static/umap/locale/pt_BR.js | 2 +- umap/static/umap/locale/pt_BR.json | 2 +- umap/static/umap/locale/pt_PT.js | 2 +- umap/static/umap/locale/pt_PT.json | 2 +- umap/static/umap/locale/ro.js | 2 +- umap/static/umap/locale/ro.json | 2 +- umap/static/umap/locale/ru.js | 2 +- umap/static/umap/locale/ru.json | 2 +- umap/static/umap/locale/si.js | 2 +- umap/static/umap/locale/si.json | 2 +- umap/static/umap/locale/sk_SK.js | 2 +- umap/static/umap/locale/sk_SK.json | 2 +- umap/static/umap/locale/sl.js | 2 +- umap/static/umap/locale/sl.json | 2 +- umap/static/umap/locale/sr.js | 2 +- umap/static/umap/locale/sr.json | 2 +- umap/static/umap/locale/sv.js | 2 +- umap/static/umap/locale/sv.json | 2 +- umap/static/umap/locale/th_TH.js | 2 +- umap/static/umap/locale/th_TH.json | 2 +- umap/static/umap/locale/tr.js | 2 +- umap/static/umap/locale/tr.json | 2 +- umap/static/umap/locale/uk_UA.js | 2 +- umap/static/umap/locale/uk_UA.json | 2 +- umap/static/umap/locale/vi.js | 2 +- umap/static/umap/locale/vi.json | 2 +- umap/static/umap/locale/vi_VN.json | 2 +- umap/static/umap/locale/zh.js | 2 +- umap/static/umap/locale/zh.json | 2 +- umap/static/umap/locale/zh_CN.json | 2 +- umap/static/umap/locale/zh_TW.Big5.json | 2 +- umap/static/umap/locale/zh_TW.js | 2 +- umap/static/umap/locale/zh_TW.json | 2 +- umap/static/umap/test/DataLayer.js | 463 ++++++++++++++++++ umap/static/umap/test/TableEditor.js | 104 ++++ .../integration/test_anonymous_owned_map.py | 2 +- umap/tests/integration/test_browser.py | 31 +- umap/tests/integration/test_edit_datalayer.py | 5 +- umap/tests/integration/test_import.py | 12 +- umap/tests/integration/test_map.py | 33 +- umap/tests/integration/test_owned_map.py | 2 +- umap/tests/integration/test_picto.py | 4 +- umap/tests/integration/test_querystring.py | 21 +- umap/tests/integration/test_statics.py | 3 +- 113 files changed, 737 insertions(+), 171 deletions(-) create mode 100644 umap/static/umap/test/DataLayer.js create mode 100644 umap/static/umap/test/TableEditor.js diff --git a/umap/static/umap/content.css b/umap/static/umap/content.css index f7b032e3..f1ebe99a 100644 --- a/umap/static/umap/content.css +++ b/umap/static/umap/content.css @@ -17,19 +17,19 @@ input:-moz-placeholder, :-moz-placeholder { color: #a5a5a5; } -#umap-ui-container textarea { +#umap-panel textarea { height: 100px; margin-bottom: 14px; } -#umap-ui-container select { +#umap-panel select { margin-bottom: 10px; } -#umap-ui-container.warning .button { +#umap-panel.warning .button { background-color: #c60f13; border: 1px solid #7f0a0c; } -#umap-ui-container.warning .button:hover { +#umap-panel.warning .button:hover { background-color: #970b0e; } @@ -194,7 +194,7 @@ h2.tabs a:hover { color: #efefef; text-decoration: underline; } -body.content #umap-ui-container { +body.content #umap-panel { background-color: #fff; } diff --git a/umap/static/umap/js/modules/browser.js b/umap/static/umap/js/modules/browser.js index a2230ad6..5e2d38ba 100644 --- a/umap/static/umap/js/modules/browser.js +++ b/umap/static/umap/js/modules/browser.js @@ -105,6 +105,7 @@ export default class Browser { DomEvent.on(toggle, 'click', toggleList) datalayer.renderToolbox(headline) const name = DomUtil.create('span', 'datalayer-name', headline) + name.textContent = datalayer.options.name DomEvent.on(name, 'click', toggleList) container.innerHTML = '' datalayer.eachFeature((feature) => this.addFeature(feature, container)) @@ -112,7 +113,9 @@ export default class Browser { let total = datalayer.count(), current = container.querySelectorAll('li').length, count = total == current ? total : `${current}/${total}` - name.textContent = `${datalayer.options.name} (${count})` + const counter = DomUtil.create('span', 'datalayer-counter', headline) + counter.textContent = `(${count})` + counter.title = translate(`Features in this layer: ${count}`) } onFormChange() { @@ -167,10 +170,23 @@ export default class Browser { this.map.eachBrowsableDataLayer((datalayer) => { this.addDataLayer(datalayer, dataContainer) }) + L.DomUtil.createButton( + 'show-on-edit block add-datalayer button', + container, + L._('Add a layer'), + this.newDataLayer, + this + ) // After datalayers have been added. const orderable = new Orderable(dataContainer, L.bind(this.onReorder, this)) } + newDataLayer () { + const datalayer = this.map.createDataLayer({}) + datalayer.edit() + } + + onReorder(src, dst, initialIndex, finalIndex) { const layer = this.map.datalayers[src.dataset.id], other = this.map.datalayers[dst.dataset.id], diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js index 04933087..52370364 100644 --- a/umap/static/umap/js/umap.controls.js +++ b/umap/static/umap/js/umap.controls.js @@ -501,7 +501,7 @@ U.DataLayersControl = L.Control.Button.extend({ options: { position: 'topright', className: 'umap-control-browse', - title: L._('Show datalayers'), + title: L._('See layers'), }, onClick: function () { diff --git a/umap/static/umap/locale/am_ET.js b/umap/static/umap/locale/am_ET.js index 1e4ac541..d485ad4d 100644 --- a/umap/static/umap/locale/am_ET.js +++ b/umap/static/umap/locale/am_ET.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Save this location as new feature", "Search location": "Search location", "See all": "ሁሉንም ተመልከት", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "ሙሉውን ስክሪን ተመልከት", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…", "Shape properties": "Shape properties", diff --git a/umap/static/umap/locale/am_ET.json b/umap/static/umap/locale/am_ET.json index e6d37037..3471a9af 100644 --- a/umap/static/umap/locale/am_ET.json +++ b/umap/static/umap/locale/am_ET.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "ሁሉንም ተመልከት", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "ሙሉውን ስክሪን ተመልከት", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/ar.js b/umap/static/umap/locale/ar.js index 48dea06a..40a3cb1e 100644 --- a/umap/static/umap/locale/ar.js +++ b/umap/static/umap/locale/ar.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Save this location as new feature", "Search location": "Search location", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "See full screen", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…", "Shape properties": "Shape properties", diff --git a/umap/static/umap/locale/ar.json b/umap/static/umap/locale/ar.json index 8aab7a9a..8fa1b0f0 100644 --- a/umap/static/umap/locale/ar.json +++ b/umap/static/umap/locale/ar.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "See full screen", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/ast.js b/umap/static/umap/locale/ast.js index c699e893..d9d8696e 100644 --- a/umap/static/umap/locale/ast.js +++ b/umap/static/umap/locale/ast.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Save this location as new feature", "Search location": "Search location", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "See full screen", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…", "Shape properties": "Shape properties", diff --git a/umap/static/umap/locale/ast.json b/umap/static/umap/locale/ast.json index f4ecf491..a56ffc3e 100644 --- a/umap/static/umap/locale/ast.json +++ b/umap/static/umap/locale/ast.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "See full screen", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/bg.js b/umap/static/umap/locale/bg.js index ef1f2b04..f62c2032 100644 --- a/umap/static/umap/locale/bg.js +++ b/umap/static/umap/locale/bg.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Save this location as new feature", "Search location": "Search location", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "Виж на цял екран", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…", "Shape properties": "Shape properties", diff --git a/umap/static/umap/locale/bg.json b/umap/static/umap/locale/bg.json index 56b09a16..eea3e742 100644 --- a/umap/static/umap/locale/bg.json +++ b/umap/static/umap/locale/bg.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "Виж на цял екран", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/br.js b/umap/static/umap/locale/br.js index 7dd93668..4d63bb5a 100644 --- a/umap/static/umap/locale/br.js +++ b/umap/static/umap/locale/br.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Enrollañ al lec'h-mañ evel un elfenn nevez", "Search location": "Klask ul lec'h", "See all": "Gwelet pep tra", - "See data layers": "Diskouez ar gwiskadoù", + "See layers": "Diskouez ar gwiskadoù", "See full screen": "Gwelet e skramm a-bezh", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Diweredekaat evit kuzhat ar gwiskad-mañ ouzh an diaporama, ar merdeer roadennoù...", "Shape properties": "Perzhioù ar furm", diff --git a/umap/static/umap/locale/br.json b/umap/static/umap/locale/br.json index 7e882ebf..550c4908 100644 --- a/umap/static/umap/locale/br.json +++ b/umap/static/umap/locale/br.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Liamm aozañ kuzh eilet er golver!", "Secret edit link:": "Liamm aozañ kuzh:", "See all": "Gwelet pep tra", - "See data layers": "Diskouez ar gwiskadoù", + "See layers": "Diskouez ar gwiskadoù", "See full screen": "Gwelet e skramm a-bezh", "See on OpenStreetMap": "Gwelet war OpenStreetMap", "Select data": "Diuzañ ar roadennoù", diff --git a/umap/static/umap/locale/ca.js b/umap/static/umap/locale/ca.js index 5e9b4d40..07962d70 100644 --- a/umap/static/umap/locale/ca.js +++ b/umap/static/umap/locale/ca.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Save this location as new feature", "Search location": "Search location", "See all": "See all", - "See data layers": "Mostra les capes de dades", + "See layers": "Mostra les capes de dades", "See full screen": "Mostra-ho a pantalla completa", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…", "Shape properties": "Shape properties", diff --git a/umap/static/umap/locale/ca.json b/umap/static/umap/locale/ca.json index b9a32777..5c826dfd 100644 --- a/umap/static/umap/locale/ca.json +++ b/umap/static/umap/locale/ca.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "L'enllaç secret s'ha copiat al porta-retalls!", "Secret edit link:": "Secret edit link:", "See all": "See all", - "See data layers": "Mostra les capes de dades", + "See layers": "Mostra les capes de dades", "See full screen": "Mostra-ho a pantalla completa", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/cs_CZ.js b/umap/static/umap/locale/cs_CZ.js index 9edef54d..9a52a7ed 100644 --- a/umap/static/umap/locale/cs_CZ.js +++ b/umap/static/umap/locale/cs_CZ.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Uložit tuto pozici jako nový objekt", "Search location": "Vyhledat místo na mapě", "See all": "Zobraz vše", - "See data layers": "Zobrazit datové vrstvy", + "See layers": "Zobrazit datové vrstvy", "See full screen": "Na celou obrazovku", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Nastavte na false pro ukrytí této vrstvy z prezentace, prohlížeče dat, vyskakovací navigace...", "Shape properties": "Vlastností tvaru", diff --git a/umap/static/umap/locale/cs_CZ.json b/umap/static/umap/locale/cs_CZ.json index 9a6319af..9bcab004 100644 --- a/umap/static/umap/locale/cs_CZ.json +++ b/umap/static/umap/locale/cs_CZ.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Tajný odkaz na úpravy do schránky!", "Secret edit link:": "Tajný odkaz na úpravy:", "See all": "Zobraz vše", - "See data layers": "Zobrazit datové vrstvy", + "See layers": "Zobrazit datové vrstvy", "See full screen": "Na celou obrazovku", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/da.js b/umap/static/umap/locale/da.js index e100b104..ecb7e897 100644 --- a/umap/static/umap/locale/da.js +++ b/umap/static/umap/locale/da.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Gem denne placering som et nyt objekt", "Search location": "Søg efter placering", "See all": "Se alle", - "See data layers": "Se datalag", + "See layers": "Se datalag", "See full screen": "Se i fuld skærm", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Sæt den til false, for at skjule dette lag fra slideshowet, databrowseren, popupnavigeringen…", "Shape properties": "Figuregenskaber", diff --git a/umap/static/umap/locale/da.json b/umap/static/umap/locale/da.json index 50bb257b..6447d0ab 100644 --- a/umap/static/umap/locale/da.json +++ b/umap/static/umap/locale/da.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "Se alle", - "See data layers": "Se datalag", + "See layers": "Se datalag", "See full screen": "Se i fuld skærm", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/de.js b/umap/static/umap/locale/de.js index 563e1c28..35e738c8 100644 --- a/umap/static/umap/locale/de.js +++ b/umap/static/umap/locale/de.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Diesen Ort als neues Element speichern", "Search location": "Ort suchen", "See all": "Alle anzeigen", - "See data layers": "Datenebenen ansehen", + "See layers": "Datenebenen ansehen", "See full screen": "Vollbildanzeige", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Setze es auf Nein, um diese Ebene in der Diashow, im Datenbrowser, in der Popup-Navigation,... auszublenden.", "Shape properties": "Formeigenschaften", diff --git a/umap/static/umap/locale/de.json b/umap/static/umap/locale/de.json index ffe8e431..73dceb87 100644 --- a/umap/static/umap/locale/de.json +++ b/umap/static/umap/locale/de.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Geheimer Link zum Bearbeiten der Karte in die Zwischenablage kopiert!", "Secret edit link:": "Secret edit link:", "See all": "Alle anzeigen", - "See data layers": "Datenebenen ansehen", + "See layers": "Datenebenen ansehen", "See full screen": "Vollbildanzeige", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Wähle Daten aus", diff --git a/umap/static/umap/locale/el.js b/umap/static/umap/locale/el.js index 229adedc..c5f584a0 100644 --- a/umap/static/umap/locale/el.js +++ b/umap/static/umap/locale/el.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Αποθήκευση αυτής της τοποθεσίας ως νέο στοιχείο", "Search location": "Αναζήτηση τοποθεσίας", "See all": "Εμφάνιση όλων", - "See data layers": "Εμφάνιση επιπέδων δεδομένων", + "See layers": "Εμφάνιση επιπέδων δεδομένων", "See full screen": "Εμφάνιση πλήρους οθόνης", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Απενεργοποίηση εάν επιθυμείτε την απόκρυψη του επιπέδου κατά την προβολή των διαφανειών, την περιήγηση δεδομένων, την αναδυόμενη πλοήγηση...", "Shape properties": "Ιδιότητες σχήματος", diff --git a/umap/static/umap/locale/el.json b/umap/static/umap/locale/el.json index ccb7b510..6187b312 100644 --- a/umap/static/umap/locale/el.json +++ b/umap/static/umap/locale/el.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Ο μυστικός σύνδεσμος επεξεργασίας αντιγράφηκε στο πρόχειρο!", "Secret edit link:": "Μυστικός σύνδεσμος επεξεργασίας:", "See all": "Εμφάνιση όλων", - "See data layers": "Εμφάνιση επιπέδων δεδομένων", + "See layers": "Εμφάνιση επιπέδων δεδομένων", "See full screen": "Εμφάνιση πλήρους οθόνης", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Επιλογή δεδομένων", diff --git a/umap/static/umap/locale/en.js b/umap/static/umap/locale/en.js index 12f0550e..9a733eba 100644 --- a/umap/static/umap/locale/en.js +++ b/umap/static/umap/locale/en.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Save this location as new feature", "Search location": "Search location", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "See full screen", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…", "Shape properties": "Shape properties", diff --git a/umap/static/umap/locale/en.json b/umap/static/umap/locale/en.json index 0408bfda..887f80f0 100644 --- a/umap/static/umap/locale/en.json +++ b/umap/static/umap/locale/en.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "See full screen", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/en_US.json b/umap/static/umap/locale/en_US.json index 791f4d62..325760c0 100644 --- a/umap/static/umap/locale/en_US.json +++ b/umap/static/umap/locale/en_US.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "See full screen", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/es.js b/umap/static/umap/locale/es.js index 59bb67f1..4146e929 100644 --- a/umap/static/umap/locale/es.js +++ b/umap/static/umap/locale/es.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Guardar esta ubicación como nuevo elemento", "Search location": "Buscar ubicación", "See all": "Ver todo", - "See data layers": "Ver capas de datos", + "See layers": "Ver capas de datos", "See full screen": "Ver pantalla completa", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Establecer en falso para ocultar esta capa de la presentación de diapositivas, el navegador de datos, la navegación emergente...", "Shape properties": "Propiedades de la figura", diff --git a/umap/static/umap/locale/es.json b/umap/static/umap/locale/es.json index 13d6c661..0fd3cfb5 100644 --- a/umap/static/umap/locale/es.json +++ b/umap/static/umap/locale/es.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Enlace de edición secreto copiado en el portapapeles", "Secret edit link:": "Enlace secreto de edición:", "See all": "Ver todo", - "See data layers": "Ver capas de datos", + "See layers": "Ver capas de datos", "See full screen": "Ver pantalla completa", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/et.js b/umap/static/umap/locale/et.js index d203ca25..049c5035 100644 --- a/umap/static/umap/locale/et.js +++ b/umap/static/umap/locale/et.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Salvesta see asukoht uue elemendina", "Search location": "Asukoha otsing", "See all": "Näita kõiki", - "See data layers": "Näita andmekihte", + "See layers": "Näita andmekihte", "See full screen": "Täisekraanvaade", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…", "Shape properties": "Kujundi omadused", diff --git a/umap/static/umap/locale/et.json b/umap/static/umap/locale/et.json index 506e259b..c4d5c43a 100644 --- a/umap/static/umap/locale/et.json +++ b/umap/static/umap/locale/et.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "Näita kõiki", - "See data layers": "Näita andmekihte", + "See layers": "Näita andmekihte", "See full screen": "Täisekraanvaade", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/eu.js b/umap/static/umap/locale/eu.js index 181f875b..53af4d7d 100644 --- a/umap/static/umap/locale/eu.js +++ b/umap/static/umap/locale/eu.js @@ -250,7 +250,7 @@ const locale = { "Search location": "Search location", "Secret edit link is:
{link}": "Secret edit link is:
{link}", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "See full screen", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…", "Shape properties": "Shape properties", diff --git a/umap/static/umap/locale/eu.json b/umap/static/umap/locale/eu.json index d7249e9c..6e23663f 100644 --- a/umap/static/umap/locale/eu.json +++ b/umap/static/umap/locale/eu.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "See full screen", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/fa_IR.js b/umap/static/umap/locale/fa_IR.js index 523b9629..cd439757 100644 --- a/umap/static/umap/locale/fa_IR.js +++ b/umap/static/umap/locale/fa_IR.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "این مکان را به عنوان ویژگی جدید ذخیره کنید", "Search location": "مکان را جستجو کنید", "See all": "همه را ببین", - "See data layers": "لایه های داده را مشاهده کنید", + "See layers": "لایه های داده را مشاهده کنید", "See full screen": "تمام صفحه را مشاهده کنید", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "آن را روی غلط/false تنظیم کنید تا این لایه از نمایش اسلاید، مرورگر داده، ناوبری بازشو پنهان شود…", "Shape properties": "ویژگی های شکل", diff --git a/umap/static/umap/locale/fa_IR.json b/umap/static/umap/locale/fa_IR.json index 8349127e..34ba25f5 100644 --- a/umap/static/umap/locale/fa_IR.json +++ b/umap/static/umap/locale/fa_IR.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "همه را ببین", - "See data layers": "لایه های داده را مشاهده کنید", + "See layers": "لایه های داده را مشاهده کنید", "See full screen": "تمام صفحه را مشاهده کنید", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "داده‌ها را انتخاب کنید", diff --git a/umap/static/umap/locale/fi.js b/umap/static/umap/locale/fi.js index 5e32675f..65097279 100644 --- a/umap/static/umap/locale/fi.js +++ b/umap/static/umap/locale/fi.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Save this location as new feature", "Search location": "Search location", "See all": "Näytä kaikki", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "Katso koko näytöllä", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…", "Shape properties": "Piirteen ominaisuudet", diff --git a/umap/static/umap/locale/fi.json b/umap/static/umap/locale/fi.json index de07f287..04201181 100644 --- a/umap/static/umap/locale/fi.json +++ b/umap/static/umap/locale/fi.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "Näytä kaikki", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "Katso koko näytöllä", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/fr.js b/umap/static/umap/locale/fr.js index 5e982bf0..8e417048 100644 --- a/umap/static/umap/locale/fr.js +++ b/umap/static/umap/locale/fr.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Enregistrer ce lieu comme élément de la carte", "Search location": "Chercher un lieu", "See all": "Tout voir", - "See data layers": "Voir les calques", + "See layers": "Voir les calques", "See full screen": "Voir en plein écran", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Désactiver pour masquer ce calque du diaporama, du navigateur de données…", "Shape properties": "Propriétés de la forme", diff --git a/umap/static/umap/locale/fr.json b/umap/static/umap/locale/fr.json index f81f84d6..7cc4f476 100644 --- a/umap/static/umap/locale/fr.json +++ b/umap/static/umap/locale/fr.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Lien d'édition secret copié dans le presse-papier!", "Secret edit link:": "Lien d'édition secret :", "See all": "Tout voir", - "See data layers": "Voir les calques", + "See layers": "Voir les calques", "See full screen": "Voir en plein écran", "See on OpenStreetMap": "Voir sur OpenStreetMap", "Select data": "Sélectionner les données", diff --git a/umap/static/umap/locale/gl.js b/umap/static/umap/locale/gl.js index 8768547e..0d50af20 100644 --- a/umap/static/umap/locale/gl.js +++ b/umap/static/umap/locale/gl.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Gardar esta ubicación coma novo elemento", "Search location": "Procurar localización", "See all": "Ollar todo", - "See data layers": "Ollar capas de datos", + "See layers": "Ollar capas de datos", "See full screen": "Ollar pantalla completa", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Axústeo a falso para agochar esta capa da presentación ('slideshow'), o navegador de datos, a navegación da xanela emerxente...", "Shape properties": "Propiedades da forma", diff --git a/umap/static/umap/locale/gl.json b/umap/static/umap/locale/gl.json index b2131706..26ab558c 100644 --- a/umap/static/umap/locale/gl.json +++ b/umap/static/umap/locale/gl.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "Ollar todo", - "See data layers": "Ollar capas de datos", + "See layers": "Ollar capas de datos", "See full screen": "Ollar pantalla completa", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/he.js b/umap/static/umap/locale/he.js index a1342212..2b7e5f28 100644 --- a/umap/static/umap/locale/he.js +++ b/umap/static/umap/locale/he.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "לשמור את המיקום הזה כתכונה חדשה", "Search location": "חיפוש מיקום", "See all": "להציג הכול", - "See data layers": "להציג שכבות נתונים", + "See layers": "להציג שכבות נתונים", "See full screen": "הצגת מסך מלא", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "יש להגדיר לשקר כדי להסתיר את השכבה הזאת מהמצגת, דפדפן הנתונים, הניווט המוקפץ…", "Shape properties": "מאפייני צורה", diff --git a/umap/static/umap/locale/he.json b/umap/static/umap/locale/he.json index 1b73c8d1..65cf7b27 100644 --- a/umap/static/umap/locale/he.json +++ b/umap/static/umap/locale/he.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "להציג הכול", - "See data layers": "להציג שכבות נתונים", + "See layers": "להציג שכבות נתונים", "See full screen": "הצגת מסך מלא", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/hr.js b/umap/static/umap/locale/hr.js index e9c21345..60397c5f 100644 --- a/umap/static/umap/locale/hr.js +++ b/umap/static/umap/locale/hr.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Save this location as new feature", "Search location": "Search location", "See all": "See all", - "See data layers": "Prikaži unesene podatke", + "See layers": "Prikaži unesene podatke", "See full screen": "See full screen", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…", "Shape properties": "Shape properties", diff --git a/umap/static/umap/locale/hr.json b/umap/static/umap/locale/hr.json index 0848beeb..132f1762 100644 --- a/umap/static/umap/locale/hr.json +++ b/umap/static/umap/locale/hr.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "See all", - "See data layers": "Prikaži unesene podatke", + "See layers": "Prikaži unesene podatke", "See full screen": "See full screen", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/hu.js b/umap/static/umap/locale/hu.js index ac1dc189..1455c457 100644 --- a/umap/static/umap/locale/hu.js +++ b/umap/static/umap/locale/hu.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "E hely mentése új objektumként", "Search location": "Hely keresése", "See all": "Összes megtekintése", - "See data layers": "Adatrétegek megtekintése", + "See layers": "Adatrétegek megtekintése", "See full screen": "Teljes képernyős nézet megtekintése", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Állítsa hamisra, hogy elrejtse ezt a réteget a diavetítésből, az adatböngészőből, az előugró navigációból stb.", "Shape properties": "Alakzat tulajdonságai", diff --git a/umap/static/umap/locale/hu.json b/umap/static/umap/locale/hu.json index fa4e9175..5e9cc04f 100644 --- a/umap/static/umap/locale/hu.json +++ b/umap/static/umap/locale/hu.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Titkos szerkesztési link a vágólapra másolva.", "Secret edit link:": "Titkos szerkesztési link:", "See all": "Összes megtekintése", - "See data layers": "Adatrétegek megtekintése", + "See layers": "Adatrétegek megtekintése", "See full screen": "Teljes képernyős nézet megtekintése", "See on OpenStreetMap": "Megtekintés az OpenStreetMapen", "Select data": "Select data", diff --git a/umap/static/umap/locale/id.js b/umap/static/umap/locale/id.js index d0afe1b2..aa41140b 100644 --- a/umap/static/umap/locale/id.js +++ b/umap/static/umap/locale/id.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Save this location as new feature", "Search location": "Search location", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "See full screen", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…", "Shape properties": "Shape properties", diff --git a/umap/static/umap/locale/id.json b/umap/static/umap/locale/id.json index f4ecf491..a56ffc3e 100644 --- a/umap/static/umap/locale/id.json +++ b/umap/static/umap/locale/id.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "See full screen", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/is.js b/umap/static/umap/locale/is.js index 5cd7c287..fd048107 100644 --- a/umap/static/umap/locale/is.js +++ b/umap/static/umap/locale/is.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Vista þessa staðsetningu sem nýja fitju", "Search location": "Leita að staðsetningu", "See all": "Sjá allt", - "See data layers": "Skoða gagnalög", + "See layers": "Skoða gagnalög", "See full screen": "Fylla skjáinn", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Settu þetta sem ósatt til að fela þetta lag úr skyggnusýningu, gagnavafranum, sprettleiðsögn…", "Shape properties": "Eiginleikar lögunar", diff --git a/umap/static/umap/locale/is.json b/umap/static/umap/locale/is.json index 7e450fdc..16fe4f8b 100644 --- a/umap/static/umap/locale/is.json +++ b/umap/static/umap/locale/is.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "Sjá allt", - "See data layers": "Skoða gagnalög", + "See layers": "Skoða gagnalög", "See full screen": "Fylla skjáinn", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/it.js b/umap/static/umap/locale/it.js index b5c412ca..241aee5c 100644 --- a/umap/static/umap/locale/it.js +++ b/umap/static/umap/locale/it.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Salva questa posizione come nuovo oggetto", "Search location": "Cerca un luogo", "See all": "Vedi tutto", - "See data layers": "Vedi i layer di dati", + "See layers": "Vedi i layer di dati", "See full screen": "Visualizza a schermo intero", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Impostalo su false per nascondere questo layer dalla presentazione, dal browser dati, dalla navigazione popup...", "Shape properties": "Proprietà della geometria", diff --git a/umap/static/umap/locale/it.json b/umap/static/umap/locale/it.json index 23ba696d..02ead191 100644 --- a/umap/static/umap/locale/it.json +++ b/umap/static/umap/locale/it.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Link della modifica segreta copiato in memoria!", "Secret edit link:": "Link segreto per editare:", "See all": "Vedi tutto", - "See data layers": "Vedi i layer di dati", + "See layers": "Vedi i layer di dati", "See full screen": "Visualizza a schermo intero", "See on OpenStreetMap": "Vedi su OpenStreetMap", "Select data": "Seleziona i dati", diff --git a/umap/static/umap/locale/ja.js b/umap/static/umap/locale/ja.js index d5315762..de7029ba 100644 --- a/umap/static/umap/locale/ja.js +++ b/umap/static/umap/locale/ja.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "この場所を新しい地物として保存", "Search location": "地名で検索", "See all": "すべて表示", - "See data layers": "データレイヤを見る", + "See layers": "データレイヤを見る", "See full screen": "フルスクリーン表示", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…", "Shape properties": "シェイプ表示プロパティ", diff --git a/umap/static/umap/locale/ja.json b/umap/static/umap/locale/ja.json index 8c51c6f5..a4d191ce 100644 --- a/umap/static/umap/locale/ja.json +++ b/umap/static/umap/locale/ja.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "すべて表示", - "See data layers": "データレイヤを見る", + "See layers": "データレイヤを見る", "See full screen": "フルスクリーン表示", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/ko.js b/umap/static/umap/locale/ko.js index 27daa6e9..e0205c98 100644 --- a/umap/static/umap/locale/ko.js +++ b/umap/static/umap/locale/ko.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Save this location as new feature", "Search location": "Search location", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "See full screen", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…", "Shape properties": "Shape properties", diff --git a/umap/static/umap/locale/ko.json b/umap/static/umap/locale/ko.json index 7d9560be..9d54844e 100644 --- a/umap/static/umap/locale/ko.json +++ b/umap/static/umap/locale/ko.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "See full screen", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/lt.js b/umap/static/umap/locale/lt.js index b0c1598a..f7cd4ffb 100644 --- a/umap/static/umap/locale/lt.js +++ b/umap/static/umap/locale/lt.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Save this location as new feature", "Search location": "Search location", "See all": "Išsaugoti viską", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "Peržiūrėti per visą ekraną", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…", "Shape properties": "Shape properties", diff --git a/umap/static/umap/locale/lt.json b/umap/static/umap/locale/lt.json index 1cc773fb..72b42502 100644 --- a/umap/static/umap/locale/lt.json +++ b/umap/static/umap/locale/lt.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "Išsaugoti viską", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "Peržiūrėti per visą ekraną", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/ms.js b/umap/static/umap/locale/ms.js index 016003b5..275b5d37 100644 --- a/umap/static/umap/locale/ms.js +++ b/umap/static/umap/locale/ms.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Simpan kedudukan ini sebagai sifat baharu", "Search location": "Kedudukan carian", "See all": "Lihat semua", - "See data layers": "Lihat lapisan data", + "See layers": "Lihat lapisan data", "See full screen": "Lihat skrin penuh", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Tetapkan ke 'false' untuk menyembunyikan lapisan ini daripada persembahan slaid, pelayar data, navigasi timbul…", "Shape properties": "Ciri-ciri bentuk", diff --git a/umap/static/umap/locale/ms.json b/umap/static/umap/locale/ms.json index 9862de03..76452778 100644 --- a/umap/static/umap/locale/ms.json +++ b/umap/static/umap/locale/ms.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Pautan suntingan rahsia telah disalin ke papan keratan!", "Secret edit link:": "Pautan suntingan rahsia:", "See all": "Lihat semua", - "See data layers": "Lihat lapisan data", + "See layers": "Lihat lapisan data", "See full screen": "Lihat skrin penuh", "See on OpenStreetMap": "Lihat di OpenStreetMap", "Select data": "Pilih data", diff --git a/umap/static/umap/locale/nl.js b/umap/static/umap/locale/nl.js index a4f90caa..c106c4c7 100644 --- a/umap/static/umap/locale/nl.js +++ b/umap/static/umap/locale/nl.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Sla deze locatie op als nieuw object", "Search location": "Zoek locatie", "See all": "Toon alles", - "See data layers": "Bekijk datalagen", + "See layers": "Bekijk datalagen", "See full screen": "Op volledig scherm weergeven", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Zet op onwaar ('false') om deze laag te verbergen in de slideshow, data verkenner, popup navigatie, ...", "Shape properties": "Eigenschappen van de vorm", diff --git a/umap/static/umap/locale/nl.json b/umap/static/umap/locale/nl.json index f7c907e6..1ee3e247 100644 --- a/umap/static/umap/locale/nl.json +++ b/umap/static/umap/locale/nl.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Geheime editeer-link is gekopieerd naar het klembord!", "Secret edit link:": "Geheime editeer-link", "See all": "Toon alles", - "See data layers": "Bekijk datalagen", + "See layers": "Bekijk datalagen", "See full screen": "Op volledig scherm weergeven", "See on OpenStreetMap": "Bekijk op OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/no.js b/umap/static/umap/locale/no.js index 97580d49..d77fc4c5 100644 --- a/umap/static/umap/locale/no.js +++ b/umap/static/umap/locale/no.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Save this location as new feature", "Search location": "Search location", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "See full screen", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…", "Shape properties": "Shape properties", diff --git a/umap/static/umap/locale/no.json b/umap/static/umap/locale/no.json index a29e9870..c5a949d0 100644 --- a/umap/static/umap/locale/no.json +++ b/umap/static/umap/locale/no.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "See full screen", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/pl.js b/umap/static/umap/locale/pl.js index 3bf808d6..ace9d589 100644 --- a/umap/static/umap/locale/pl.js +++ b/umap/static/umap/locale/pl.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Zapisz to miejsce jako nowy obiekt", "Search location": "Znajdź miejsce", "See all": "Pokaż wszystko", - "See data layers": "Zobacz wszystkie warstwy danych", + "See layers": "Zobacz wszystkie warstwy danych", "See full screen": "Pełny ekran", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Ustaw „OFF”, żeby ukryć tę warstwę z pokazu slajdów, przeglądarki danych i okienek nawigacji.", "Shape properties": "Właściwości kształtu", diff --git a/umap/static/umap/locale/pl.json b/umap/static/umap/locale/pl.json index 102348ae..89963c08 100644 --- a/umap/static/umap/locale/pl.json +++ b/umap/static/umap/locale/pl.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Tajny odnośnik do edycji skopiowany do schowka!", "Secret edit link:": "Sekretny odnośnik edycji:", "See all": "Pokaż wszystko", - "See data layers": "Zobacz wszystkie warstwy danych", + "See layers": "Zobacz wszystkie warstwy danych", "See full screen": "Pełny ekran", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/pl_PL.json b/umap/static/umap/locale/pl_PL.json index f4ecf491..a56ffc3e 100644 --- a/umap/static/umap/locale/pl_PL.json +++ b/umap/static/umap/locale/pl_PL.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "See full screen", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/pt.js b/umap/static/umap/locale/pt.js index d19039f7..7336be93 100644 --- a/umap/static/umap/locale/pt.js +++ b/umap/static/umap/locale/pt.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Gravar esta localização como novo elemento", "Search location": "Procurar localização", "See all": "Ver tudo", - "See data layers": "Ver camadas de dados", + "See layers": "Ver camadas de dados", "See full screen": "Ver em ecrã total", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Defina como falso para ocultar esta camada da apresentação de slides, o navegador de dados e da navegação do popup…", "Shape properties": "Propriedades de formas geométricas", diff --git a/umap/static/umap/locale/pt.json b/umap/static/umap/locale/pt.json index 9acabd19..afabf49b 100644 --- a/umap/static/umap/locale/pt.json +++ b/umap/static/umap/locale/pt.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "Ver tudo", - "See data layers": "Ver camadas de dados", + "See layers": "Ver camadas de dados", "See full screen": "Ver em ecrã total", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/pt_BR.js b/umap/static/umap/locale/pt_BR.js index 74a2d201..b135758c 100644 --- a/umap/static/umap/locale/pt_BR.js +++ b/umap/static/umap/locale/pt_BR.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Gravar esta localização como novo elemento", "Search location": "Procurar localização", "See all": "Ver tudo", - "See data layers": "Ver camadas de dados", + "See layers": "Ver camadas de dados", "See full screen": "Ver em ecrã total", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Defina como falso para ocultar esta camada da apresentação de slides, o navegador de dados e da navegação do popup…", "Shape properties": "Propriedades de formas geométricas", diff --git a/umap/static/umap/locale/pt_BR.json b/umap/static/umap/locale/pt_BR.json index b2946e84..54dcb9dd 100644 --- a/umap/static/umap/locale/pt_BR.json +++ b/umap/static/umap/locale/pt_BR.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "Ver tudo", - "See data layers": "Ver camadas de dados", + "See layers": "Ver camadas de dados", "See full screen": "Ver em ecrã total", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/pt_PT.js b/umap/static/umap/locale/pt_PT.js index 550b49f1..e5ec7c09 100644 --- a/umap/static/umap/locale/pt_PT.js +++ b/umap/static/umap/locale/pt_PT.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Gravar esta localização como novo elemento", "Search location": "Procurar localização", "See all": "Ver tudo", - "See data layers": "Ver camadas de dados", + "See layers": "Ver camadas de dados", "See full screen": "Ver em ecrã total", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Defina como falso para ocultar esta camada da apresentação de slides, o navegador de dados e da navegação do popup…", "Shape properties": "Propriedades de formas geométricas", diff --git a/umap/static/umap/locale/pt_PT.json b/umap/static/umap/locale/pt_PT.json index 6657b780..79e8441c 100644 --- a/umap/static/umap/locale/pt_PT.json +++ b/umap/static/umap/locale/pt_PT.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "Ver tudo", - "See data layers": "Ver camadas de dados", + "See layers": "Ver camadas de dados", "See full screen": "Ver em ecrã total", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/ro.js b/umap/static/umap/locale/ro.js index b509ed07..dc111e1d 100644 --- a/umap/static/umap/locale/ro.js +++ b/umap/static/umap/locale/ro.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Save this location as new feature", "Search location": "Căutați locația", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "See full screen", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…", "Shape properties": "Shape properties", diff --git a/umap/static/umap/locale/ro.json b/umap/static/umap/locale/ro.json index 11214613..f41ea864 100644 --- a/umap/static/umap/locale/ro.json +++ b/umap/static/umap/locale/ro.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "See full screen", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/ru.js b/umap/static/umap/locale/ru.js index 0de09d4c..22308a35 100644 --- a/umap/static/umap/locale/ru.js +++ b/umap/static/umap/locale/ru.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Сохранить это местоположение как новый объект", "Search location": "Поиск местоположения", "See all": "Посмотреть все", - "See data layers": "Посмотреть слои данных", + "See layers": "Посмотреть слои данных", "See full screen": "Смотреть в полноэкранном режиме", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Сбросьте, чтобы скрыть слой из слайдшоу, просмотра данных и всплывающей навигации...", "Shape properties": "Свойства фигуры", diff --git a/umap/static/umap/locale/ru.json b/umap/static/umap/locale/ru.json index 1907527c..83a9acc7 100644 --- a/umap/static/umap/locale/ru.json +++ b/umap/static/umap/locale/ru.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "Посмотреть все", - "See data layers": "Посмотреть слои данных", + "See layers": "Посмотреть слои данных", "See full screen": "Смотреть в полноэкранном режиме", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/si.js b/umap/static/umap/locale/si.js index 2cad7095..30f7de11 100644 --- a/umap/static/umap/locale/si.js +++ b/umap/static/umap/locale/si.js @@ -244,7 +244,7 @@ const locale = { "Search a place name": "Search a place name", "Search location": "Search location", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "See full screen", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…", "Shape properties": "Shape properties", diff --git a/umap/static/umap/locale/si.json b/umap/static/umap/locale/si.json index 4d166927..2c71f08a 100644 --- a/umap/static/umap/locale/si.json +++ b/umap/static/umap/locale/si.json @@ -244,7 +244,7 @@ "Search a place name": "Search a place name", "Search location": "Search location", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "See full screen", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…", "Shape properties": "Shape properties", diff --git a/umap/static/umap/locale/sk_SK.js b/umap/static/umap/locale/sk_SK.js index e397d132..1cf13978 100644 --- a/umap/static/umap/locale/sk_SK.js +++ b/umap/static/umap/locale/sk_SK.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Uložiť túto polohu ako nový objekt", "Search location": "Vyhľadať polohu", "See all": "Zobraziť všetko", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "Na celú obrazovku", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…", "Shape properties": "Vlastnosti tvaru", diff --git a/umap/static/umap/locale/sk_SK.json b/umap/static/umap/locale/sk_SK.json index 65be3387..2b61f0ba 100644 --- a/umap/static/umap/locale/sk_SK.json +++ b/umap/static/umap/locale/sk_SK.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "Zobraziť všetko", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "Na celú obrazovku", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/sl.js b/umap/static/umap/locale/sl.js index 969a5eb6..d8a66709 100644 --- a/umap/static/umap/locale/sl.js +++ b/umap/static/umap/locale/sl.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Shrani mesto kot nov predmet", "Search location": "Preišči mesto", "See all": "Pokaži vse", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "Pokaži v celozaslonskem načinu", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Neizbrana možnost skrije plast med predstavitvijo, v pregledovalniku podatkov, ...", "Shape properties": "Lastnosti oblike", diff --git a/umap/static/umap/locale/sl.json b/umap/static/umap/locale/sl.json index d4292a19..d656c296 100644 --- a/umap/static/umap/locale/sl.json +++ b/umap/static/umap/locale/sl.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "Pokaži vse", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "Pokaži v celozaslonskem načinu", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/sr.js b/umap/static/umap/locale/sr.js index 0164bd5b..94f22696 100644 --- a/umap/static/umap/locale/sr.js +++ b/umap/static/umap/locale/sr.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Сачувај локацију као нови елемент", "Search location": "Претражи локацију", "See all": "Види све", - "See data layers": "Прикажи унесене податке", + "See layers": "Прикажи унесене податке", "See full screen": "Увећана слика", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…", "Shape properties": "Својства облика", diff --git a/umap/static/umap/locale/sr.json b/umap/static/umap/locale/sr.json index 7d48ddc7..15597ee7 100644 --- a/umap/static/umap/locale/sr.json +++ b/umap/static/umap/locale/sr.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "Види све", - "See data layers": "Прикажи унесене податке", + "See layers": "Прикажи унесене податке", "See full screen": "Увећана слика", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/sv.js b/umap/static/umap/locale/sv.js index 3e3589ab..cc0bac97 100644 --- a/umap/static/umap/locale/sv.js +++ b/umap/static/umap/locale/sv.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Spara denna plats som nytt kartobjekt", "Search location": "Sök plats", "See all": "Se alla", - "See data layers": "Visa datalager", + "See layers": "Visa datalager", "See full screen": "Öppna i fullskärm", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Slå av för att dölja lagret från bilspelsvisning, databläddrare, popup-navigering etc", "Shape properties": "Formategenskaper", diff --git a/umap/static/umap/locale/sv.json b/umap/static/umap/locale/sv.json index 5d8b2727..d347f9be 100644 --- a/umap/static/umap/locale/sv.json +++ b/umap/static/umap/locale/sv.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Hemlig redigeringslänk kopierad till klippbordet", "Secret edit link:": "Secret edit link:", "See all": "Se alla", - "See data layers": "Visa datalager", + "See layers": "Visa datalager", "See full screen": "Öppna i fullskärm", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/th_TH.js b/umap/static/umap/locale/th_TH.js index 65caf03d..31da42e8 100644 --- a/umap/static/umap/locale/th_TH.js +++ b/umap/static/umap/locale/th_TH.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Save this location as new feature", "Search location": "Search location", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "See full screen", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…", "Shape properties": "Shape properties", diff --git a/umap/static/umap/locale/th_TH.json b/umap/static/umap/locale/th_TH.json index f4ecf491..a56ffc3e 100644 --- a/umap/static/umap/locale/th_TH.json +++ b/umap/static/umap/locale/th_TH.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "See full screen", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/tr.js b/umap/static/umap/locale/tr.js index 520c314e..b57b24b8 100644 --- a/umap/static/umap/locale/tr.js +++ b/umap/static/umap/locale/tr.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Bu konumu yeni özellik olarak kaydet", "Search location": "Konum ara", "See all": "Hepsini gör", - "See data layers": "Veri katmanlarını gör", + "See layers": "Veri katmanlarını gör", "See full screen": "Tam ekranda gör", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Bu katmanı slayt gösterisinden, veri tarayıcısından, pop-up gezinmeden gizlemek için yanlış olarak ayarlayın ...", "Shape properties": "Şekil özellikleri", diff --git a/umap/static/umap/locale/tr.json b/umap/static/umap/locale/tr.json index 2d9ce685..009c96d2 100644 --- a/umap/static/umap/locale/tr.json +++ b/umap/static/umap/locale/tr.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "Hepsini gör", - "See data layers": "Veri katmanlarını gör", + "See layers": "Veri katmanlarını gör", "See full screen": "Tam ekranda gör", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/uk_UA.js b/umap/static/umap/locale/uk_UA.js index d6333823..3e4ab0e4 100644 --- a/umap/static/umap/locale/uk_UA.js +++ b/umap/static/umap/locale/uk_UA.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Зберегти місце розташування як новий об’єкт", "Search location": "Пошук місця", "See all": "Переглянути усе", - "See data layers": "Подивитися шари даних", + "See layers": "Подивитися шари даних", "See full screen": "Дивитися в повноекранному режимі", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Встановіть false, щоб приховати шар в слайдшоу, в перегляді даних та навігації…", "Shape properties": "Параметри полігона", diff --git a/umap/static/umap/locale/uk_UA.json b/umap/static/umap/locale/uk_UA.json index aabca3e7..2d4a9308 100644 --- a/umap/static/umap/locale/uk_UA.json +++ b/umap/static/umap/locale/uk_UA.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "Переглянути усе", - "See data layers": "Подивитися шари даних", + "See layers": "Подивитися шари даних", "See full screen": "Дивитися в повноекранному режимі", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/vi.js b/umap/static/umap/locale/vi.js index 9b9a900d..ee56a392 100644 --- a/umap/static/umap/locale/vi.js +++ b/umap/static/umap/locale/vi.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Save this location as new feature", "Search location": "Search location", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "See full screen", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…", "Shape properties": "Shape properties", diff --git a/umap/static/umap/locale/vi.json b/umap/static/umap/locale/vi.json index 20415efb..6c95ff9f 100644 --- a/umap/static/umap/locale/vi.json +++ b/umap/static/umap/locale/vi.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "See full screen", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/vi_VN.json b/umap/static/umap/locale/vi_VN.json index f4ecf491..a56ffc3e 100644 --- a/umap/static/umap/locale/vi_VN.json +++ b/umap/static/umap/locale/vi_VN.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "See full screen", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/zh.js b/umap/static/umap/locale/zh.js index 39e9f406..f4a9cb31 100644 --- a/umap/static/umap/locale/zh.js +++ b/umap/static/umap/locale/zh.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "Save this location as new feature", "Search location": "Search location", "See all": "查看全部", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "全屏", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…", "Shape properties": "Shape properties", diff --git a/umap/static/umap/locale/zh.json b/umap/static/umap/locale/zh.json index 8bb0be18..b2078d4f 100644 --- a/umap/static/umap/locale/zh.json +++ b/umap/static/umap/locale/zh.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "查看全部", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "全屏", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/zh_CN.json b/umap/static/umap/locale/zh_CN.json index f4ecf491..a56ffc3e 100644 --- a/umap/static/umap/locale/zh_CN.json +++ b/umap/static/umap/locale/zh_CN.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "See full screen", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/zh_TW.Big5.json b/umap/static/umap/locale/zh_TW.Big5.json index f4ecf491..a56ffc3e 100644 --- a/umap/static/umap/locale/zh_TW.Big5.json +++ b/umap/static/umap/locale/zh_TW.Big5.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "Secret edit link copied to clipboard!", "Secret edit link:": "Secret edit link:", "See all": "See all", - "See data layers": "See data layers", + "See layers": "See layers", "See full screen": "See full screen", "See on OpenStreetMap": "See on OpenStreetMap", "Select data": "Select data", diff --git a/umap/static/umap/locale/zh_TW.js b/umap/static/umap/locale/zh_TW.js index 24ce97ca..ae115824 100644 --- a/umap/static/umap/locale/zh_TW.js +++ b/umap/static/umap/locale/zh_TW.js @@ -230,7 +230,7 @@ const locale = { "Save this location as new feature": "將地點存為新的圖徵", "Search location": "搜尋地點", "See all": "觀看完整內容", - "See data layers": "檢視資料圖層", + "See layers": "檢視資料圖層", "See full screen": "觀看全螢幕", "Set it to false to hide this layer from the slideshow, the data browser, the popup navigation…": "設定為假時,在幻燈片時、資料檢視器和彈出式導航中可將此圖層隱藏...", "Shape properties": "形狀屬性", diff --git a/umap/static/umap/locale/zh_TW.json b/umap/static/umap/locale/zh_TW.json index 76d8996a..1e518b71 100644 --- a/umap/static/umap/locale/zh_TW.json +++ b/umap/static/umap/locale/zh_TW.json @@ -335,7 +335,7 @@ "Secret edit link copied to clipboard!": "複製私密編輯連結到剪貼簿!", "Secret edit link:": "祕密編輯連結:", "See all": "觀看完整內容", - "See data layers": "檢視資料圖層", + "See layers": "檢視資料圖層", "See full screen": "觀看全螢幕", "See on OpenStreetMap": "在開放街圖檢視", "Select data": "Select data", diff --git a/umap/static/umap/test/DataLayer.js b/umap/static/umap/test/DataLayer.js new file mode 100644 index 00000000..93cf8a09 --- /dev/null +++ b/umap/static/umap/test/DataLayer.js @@ -0,0 +1,463 @@ +describe('U.DataLayer', () => { + let path = '/map/99/datalayer/update/62/', + map, + datalayer + + before(async () => { + fetchMock.mock(/\/datalayer\/62\/\?.*/, JSON.stringify(RESPONSES.datalayer62_GET)) + fetchMock.sticky('/map/99/update/settings/', { id: 99 }) + this.options = { + umap_id: 99, + } + MAP = map = initMap({ umap_id: 99 }) + const datalayer_options = defaultDatalayerData() + await map.initDataLayers([datalayer_options]) + datalayer = map.getDataLayerByUmapId(62) + enableEdit() + }) + after(() => { + fetchMock.restore() + resetMap() + }) + + describe('#init()', () => { + it('should be added in datalayers index', () => { + assert.notEqual(map.datalayers_index.indexOf(datalayer), -1) + }) + }) + + describe('#edit()', () => { + var editButton, form, input, forceButton + + it('row in control should be active', () => { + assert.notOk( + qs('.leaflet-control-browse #browse_data_toggle_' + L.stamp(datalayer) + '.off') + ) + }) + + it('should have edit button', () => { + editButton = qs('#browse_data_toggle_' + L.stamp(datalayer) + ' .layer-edit') + assert.ok(editButton) + }) + + it('should have toggle visibility element', () => { + assert.ok(qs('.leaflet-control-browse i.layer-toggle')) + }) + + it('should exist only one datalayer', () => { + assert.equal(qsa('.leaflet-control-browse i.layer-toggle').length, 1) + }) + + it('should build a form on edit button click', () => { + happen.click(editButton) + form = qs('form.umap-form') + input = qs('form.umap-form input[name="name"]') + assert.ok(form) + assert.ok(input) + }) + + it('should update name on input change', () => { + var new_name = 'This is a new name' + input.value = new_name + happen.once(input, { type: 'input' }) + assert.equal(datalayer.options.name, new_name) + }) + + it('should have made datalayer dirty', () => { + assert.ok(datalayer.isDirty) + assert.notEqual(map.dirty_datalayers.indexOf(datalayer), -1) + }) + + it('should have made Map dirty', () => { + assert.ok(map.isDirty) + }) + + it('should call datalayer.save on save button click', (done) => { + const postDatalayer = fetchMock.post(path, () => { + return defaultDatalayerData() + }) + clickSave() + window.setTimeout(() => { + assert(fetchMock.called(path)) + done() + }, 500) + }) + + it('should show alert if server respond 412', (done) => { + cleanAlert() + fetchMock.restore() + fetchMock.post(path, 412) + happen.click(editButton) + input = qs('form.umap-form input[name="name"]') + input.value = 'a new name' + happen.once(input, { type: 'input' }) + clickSave() + window.setTimeout(() => { + assert(L.DomUtil.hasClass(map._container, 'umap-alert')) + assert.notEqual(map.dirty_datalayers.indexOf(datalayer), -1) + const forceButton = qs('#umap-alert-container .umap-action') + assert.ok(forceButton) + done() + }, 500) + }) + + it('should save anyway on force save button click', (done) => { + const forceButton = qs('#umap-alert-container .umap-action') + fetchMock.restore() + fetchMock.post(path, defaultDatalayerData) + happen.click(forceButton) + window.setTimeout(() => { + assert.notOk(qs('#umap-alert-container .umap-action')) + assert(fetchMock.called(path)) + assert.equal(map.dirty_datalayers.indexOf(datalayer), -1) + done() + }, 500) + }) + }) + + describe('#save() new', () => { + let newLayerButton, form, input, newDatalayer, editButton, manageButton + + it('should have a manage datalayers action', () => { + enableEdit() + manageButton = qs('.manage-datalayers') + assert.ok(manageButton) + happen.click(manageButton) + }) + + it('should have a new layer button', () => { + newLayerButton = qs('#umap-panel .add-datalayer') + assert.ok(newLayerButton) + }) + + it('should build a form on new layer button click', () => { + happen.click(newLayerButton) + form = qs('form.umap-form') + input = qs('form.umap-form input[name="name"]') + assert.ok(form) + assert.ok(input) + }) + + it('should have an empty name', () => { + assert.notOk(input.value) + }) + + it('should have created a new datalayer', () => { + assert.equal(map.datalayers_index.length, 2) + newDatalayer = map.datalayers_index[1] + }) + + it('should have made Map dirty', () => { + assert.ok(map.isDirty) + }) + + it('should update name on input change', () => { + var new_name = 'This is a new name' + input.value = new_name + happen.once(input, { type: 'input' }) + assert.equal(newDatalayer.options.name, new_name) + }) + + it('should set umap_id on save callback', async () => { + assert.notOk(newDatalayer.umap_id) + fetchMock.post('/map/99/datalayer/create/', defaultDatalayerData({ id: 63 })) + clickSave() + return new Promise((resolve) => { + window.setTimeout(() => { + assert.equal(newDatalayer.umap_id, 63) + resolve() + }, 1000) + }) + }) + + it('should have unset map dirty', () => { + assert.notOk(map.isDirty) + }) + + it('should have edit button', () => { + editButton = qs('#browse_data_toggle_' + L.stamp(newDatalayer) + ' .layer-edit') + assert.ok(editButton) + }) + + it('should call update if we edit again', async () => { + happen.click(editButton) + assert.notOk(map.isDirty) + input = qs('form.umap-form input[name="name"]') + input.value = "a new name again but we don't care which" + happen.once(input, { type: 'input' }) + assert.ok(map.isDirty) + var response = () => { + return defaultDatalayerData({ pk: 63 }) + } + var spy = sinon.spy(response) + fetchMock.post('/map/99/datalayer/update/63/', spy) + return new Promise((resolve) => { + clickSave() + window.setTimeout(() => { + assert.ok(spy.calledOnce) + resolve() + }, 1000) + }) + }) + }) + + describe('#iconClassChange()', () => { + it('should change icon class', () => { + happen.click(qs('[data-id="' + datalayer._leaflet_id + '"] .layer-edit')) + changeSelectValue( + qs('form#datalayer-advanced-properties select[name=iconClass]'), + 'Circle' + ) + assert.notOk(qs('div.umap-div-icon')) + assert.ok(qs('div.umap-circle-icon')) + happen.click( + qs('form#datalayer-advanced-properties .umap-field-iconClass .undefine') + ) + assert.notOk(qs('div.umap-circle-icon')) + assert.ok(qs('div.umap-div-icon')) + clickCancel() + }) + }) + + describe('#show/hide', () => { + it('should hide features on hide', () => { + assert.ok(qs('div.umap-div-icon')) + assert.ok(qs('path[fill="none"]')) + datalayer.hide() + assert.notOk(qs('div.umap-div-icon')) + assert.notOk(qs('path[fill="none"]')) + }) + + it('should show features on show', () => { + assert.notOk(qs('div.umap-div-icon')) + assert.notOk(qs('path[fill="none"]')) + datalayer.show() + assert.ok(qs('div.umap-div-icon')) + assert.ok(qs('path[fill="none"]')) + }) + }) + + describe('#clone()', () => { + it('should clone everything but the id and the name', () => { + enableEdit() + var clone = datalayer.clone() + assert.notOk(clone.umap_id) + assert.notEqual(clone.options.name, datalayer.name) + assert.ok(clone.options.name) + assert.equal(clone.options.color, datalayer.options.color) + assert.equal(clone.options.stroke, datalayer.options.stroke) + clone._delete() + clickSave() + }) + }) + + describe('#restore()', () => { + var oldConfirm, + newConfirm = () => { + return true + } + + before(() => { + oldConfirm = window.confirm + window.confirm = newConfirm + }) + after(() => { + window.confirm = oldConfirm + }) + + it('should restore everything', (done) => { + enableEdit() + var geojson = L.Util.CopyJSON(RESPONSES.datalayer62_GET) + geojson.features.push({ + geometry: { + type: 'Point', + coordinates: [-1.274658203125, 50.57634993749885], + }, + type: 'Feature', + id: 1807, + properties: { _umap_options: {}, name: 'new point from restore' }, + }) + geojson._umap_options.color = 'Chocolate' + fetchMock.get('/datalayer/62/olderversion.geojson', geojson) + sinon.spy(window, 'confirm') + datalayer.restore('olderversion.geojson') + window.setTimeout(() => { + assert(window.confirm.calledOnce) + window.confirm.restore() + assert.equal(datalayer.umap_id, 62) + assert.ok(datalayer.isDirty) + assert.equal(datalayer._index.length, 4) + assert.ok(qs('path[fill="Chocolate"]')) + done() + }, 1000) + }) + + it('should revert anything on cancel click', () => { + clickCancel() + assert.equal(datalayer._index.length, 3) + assert.notOk(qs('path[fill="Chocolate"]')) + }) + }) + + describe('#smart-options()', () => { + let poly, marker + before(() => { + datalayer.eachLayer(function (layer) { + if (!poly && layer instanceof L.Polygon) { + poly = layer + } + if (!marker && layer instanceof L.Marker) { + marker = layer + } + }) + }) + + it('should parse color variable', () => { + let icon = qs('div.umap-div-icon .icon_container') + poly.properties.mycolor = 'DarkGoldenRod' + marker.properties.mycolor = 'DarkRed' + marker.properties._umap_options.color = undefined + assert.notOk(qs('path[fill="DarkGoldenRod"]')) + assert.equal(icon.style.backgroundColor, 'olivedrab') + datalayer.options.color = '{mycolor}' + datalayer.options.fillColor = '{mycolor}' + datalayer.indexProperties(poly) + datalayer.indexProperties(marker) + datalayer.redraw() + icon = qs('div.umap-div-icon .icon_container') + assert.equal(icon.style.backgroundColor, 'darkred') + assert.ok(qs('path[fill="DarkGoldenRod"]')) + }) + }) + + describe('#facet-search()', () => { + before(async () => { + fetchMock.get(/\/datalayer\/63\/\?.*/, RESPONSES.datalayer63_GET) + map.options.facetKey = 'name' + await map.initDataLayers([RESPONSES.datalayer63_GET._umap_options]) + }) + it('should not impact non browsable layer', () => { + assert.ok(qs('path[fill="SteelBlue"]')) + }) + it('should allow advanced filter', () => { + map.openFacet() + assert.ok(qs('div.umap-facet-search')) + // This one if from the normal datalayer + // it's name is "test", so it should be hidden + // by the filter + assert.ok(qs('path[fill="none"]')) + happen.click(qs('input[data-value="name poly"]')) + assert.notOk(qs('path[fill="none"]')) + // This one comes from a non browsable layer + // so it should not be affected by the filter + assert.ok(qs('path[fill="SteelBlue"]')) + happen.click(qs('input[data-value="name poly"]')) // Undo + }) + it('should allow to control facet label', () => { + map.options.facetKey = 'name|Nom' + map.openFacet() + assert.ok(qs('div.umap-facet-search h5')) + assert.equal(qs('div.umap-facet-search h5').textContent, 'Nom') + }) + }) + describe('#zoomEnd', () => { + it('should honour the fromZoom option', () => { + map.setZoom(6, { animate: false }) + assert.ok(qs('path[fill="none"]')) + datalayer.options.fromZoom = 6 + map.setZoom(5, { animate: false }) + assert.notOk(qs('path[fill="none"]')) + map.setZoom(6, { animate: false }) + assert.ok(qs('path[fill="none"]')) + }) + + it('should honour the toZoom option', () => { + map.setZoom(6, { animate: false }) + assert.ok(qs('path[fill="none"]')) + datalayer.options.toZoom = 6 + map.setZoom(7, { animate: false }) + assert.notOk(qs('path[fill="none"]')) + map.setZoom(6, { animate: false }) + assert.ok(qs('path[fill="none"]')) + }) + }) + + describe('#displayOnLoad', () => { + before(() => { + fetchMock.get(/\/datalayer\/64\/\?.*/, RESPONSES.datalayer64_GET) + }) + + beforeEach(async () => { + await map.initDataLayers([RESPONSES.datalayer64_GET._umap_options]) + datalayer = map.getDataLayerByUmapId(64) + map.setZoom(10, { animate: false }) + }) + + afterEach(() => { + datalayer._delete() + }) + + it('should not display layer at load', () => { + assert.notOk(qs('path[fill="AliceBlue"]')) + }) + + it('should display on click', (done) => { + happen.click(qs(`[data-id='${L.stamp(datalayer)}'] .layer-toggle`)) + window.setTimeout(() => { + assert.ok(qs('path[fill="AliceBlue"]')) + done() + }, 500) + }) + + it('should not display on zoom', (done) => { + map.setZoom(9, { animate: false }) + window.setTimeout(() => { + assert.notOk(qs('path[fill="AliceBlue"]')) + done() + }, 500) + }) + }) + + describe('#delete()', () => { + let deleteLink, + deletePath = '/map/99/datalayer/delete/62/' + before(() => { + datalayer = map.getDataLayerByUmapId(62) + }) + + it('should have a delete link in update form', () => { + enableEdit() + happen.click(qs('#browse_data_toggle_' + L.stamp(datalayer) + ' .layer-edit')) + deleteLink = qs('button.delete_datalayer_button') + assert.ok(deleteLink) + }) + + it('should delete features on datalayer delete', () => { + happen.click(deleteLink) + assert.notOk(qs('div.icon_container')) + }) + + it('should have set map dirty', () => { + assert.ok(map.isDirty) + }) + + it('should delete layer control row on delete', () => { + assert.notOk( + qs('.leaflet-control-browse #browse_data_toggle_' + L.stamp(datalayer)) + ) + }) + + it('should be removed from map.datalayers_index', () => { + assert.equal(map.datalayers_index.indexOf(datalayer), -1) + }) + + it('should be removed from map.datalayers', () => { + assert.notOk(map.datalayers[L.stamp(datalayer)]) + }) + + it('should be visible again on edit cancel', () => { + clickCancel() + assert.ok(qs('div.icon_container')) + }) + }) +}) diff --git a/umap/static/umap/test/TableEditor.js b/umap/static/umap/test/TableEditor.js new file mode 100644 index 00000000..52f82898 --- /dev/null +++ b/umap/static/umap/test/TableEditor.js @@ -0,0 +1,104 @@ +describe('L.TableEditor', () => { + let path = '/map/99/datalayer/edit/62/', + datalayer + + before(async () => { + await fetchMock.mock( + /\/datalayer\/62\/\?.*/, + JSON.stringify(RESPONSES.datalayer62_GET) + ) + this.options = { + umap_id: 99, + } + map = initMap({ umap_id: 99 }) + const datalayer_options = defaultDatalayerData() + await map.initDataLayers([datalayer_options]) + datalayer = map.getDataLayerByUmapId(62) + enableEdit() + }) + after(() => { + fetchMock.restore() + clickCancel() + resetMap() + }) + + describe('#open()', () => { + var button + + it('should exist table click on edit mode', () => { + button = qs( + '#browse_data_toggle_' + L.stamp(datalayer) + ' .layer-table-edit' + ) + expect(button).to.be.ok + }) + + it('should open table button click', () => { + happen.click(button) + expect(qs('#umap-panel div.table')).to.be.ok + expect(qsa('#umap-panel div.table form').length).to.eql(3) // One per feature. + expect(qsa('#umap-panel div.table input').length).to.eql(3) // One per feature and per property. + }) + }) + describe('#properties()', () => { + var feature + + before(() => { + var firstIndex = datalayer._index[0] + feature = datalayer._layers[firstIndex] + }) + + it('should create new property column', () => { + var newPrompt = () => { + return 'newprop' + } + var oldPrompt = window.prompt + window.prompt = newPrompt + var button = qs('#umap-panel .add-property') + expect(button).to.be.ok + happen.click(button) + expect(qsa('#umap-panel div.table input').length).to.eql(6) // One per feature and per property. + window.prompt = oldPrompt + }) + + it('should populate feature property on fill', () => { + var input = qs( + 'form#umap-feature-properties_' + L.stamp(feature) + ' input[name=newprop]' + ) + changeInputValue(input, 'the value') + expect(feature.properties.newprop).to.eql('the value') + }) + + it('should update property name on update click', () => { + var newPrompt = () => { + return 'newname' + } + var oldPrompt = window.prompt + window.prompt = newPrompt + var button = qs('#umap-panel div.thead div.tcell:last-of-type .umap-edit') + expect(button).to.be.ok + happen.click(button) + expect(qsa('#umap-panel div.table input').length).to.eql(6) + expect(feature.properties.newprop).to.be.undefined + expect(feature.properties.newname).to.eql('the value') + window.prompt = oldPrompt + }) + + it('should update property on delete click', () => { + var oldConfirm, + newConfirm = () => { + return true + } + oldConfirm = window.confirm + window.confirm = newConfirm + var button = qs( + '#umap-panel div.thead div.tcell:last-of-type .umap-delete' + ) + expect(button).to.be.ok + happen.click(button) + FEATURE = feature + expect(qsa('#umap-panel div.table input').length).to.eql(3) + expect(feature.properties.newname).to.be.undefined + window.confirm = oldConfirm + }) + }) +}) diff --git a/umap/tests/integration/test_anonymous_owned_map.py b/umap/tests/integration/test_anonymous_owned_map.py index 89c590d7..2bb94f3b 100644 --- a/umap/tests/integration/test_anonymous_owned_map.py +++ b/umap/tests/integration/test_anonymous_owned_map.py @@ -131,7 +131,7 @@ def test_anonymous_can_add_marker_on_editable_layer( def test_can_change_perms_after_create(tilelayer, live_server, page): page.goto(f"{live_server.url}/en/map/new") # Create a layer - page.get_by_title("Manage layers").click() + page.get_by_title("See layers").click() page.get_by_role("button", name="Add a layer").click() page.locator("input[name=name]").fill("Layer 1") save = page.get_by_role("button", name="Save") diff --git a/umap/tests/integration/test_browser.py b/umap/tests/integration/test_browser.py index 41d89584..2912f932 100644 --- a/umap/tests/integration/test_browser.py +++ b/umap/tests/integration/test_browser.py @@ -63,7 +63,7 @@ def bootstrap(map, live_server): def test_data_browser_should_be_open(live_server, page, bootstrap, map): page.goto(f"{live_server.url}{map.get_absolute_url()}") - el = page.locator(".umap-browse-data") + el = page.locator(".umap-browser") expect(el).to_be_visible() expect(page.get_by_text("one point in france")).to_be_visible() expect(page.get_by_text("one line in new zeland")).to_be_visible() @@ -81,7 +81,7 @@ def test_data_browser_should_be_filterable(live_server, page, bootstrap, map): expect(filter_).to_be_visible() filter_.type("poly") expect(page.get_by_title("Features in this layer: 1/3")).to_be_visible() - expect(page.get_by_title("Features in this layer: 1/3")).to_have_text("1/3") + expect(page.get_by_title("Features in this layer: 1/3")).to_have_text("(1/3)") expect(page.get_by_text("one point in france")).to_be_hidden() expect(page.get_by_text("one line in new zeland")).to_be_hidden() expect(page.get_by_text("one polygon in greenland")).to_be_visible() @@ -159,7 +159,7 @@ def test_data_browser_bbox_filter_should_be_persistent( el = page.get_by_text("Current map view") expect(el).to_be_visible() el.click() - browser = page.locator("#umap-ui-container") + browser = page.locator("#umap-panel") expect(browser.get_by_text("one point in france")).to_be_visible() expect(browser.get_by_text("one line in new zeland")).to_be_hidden() expect(browser.get_by_text("one polygon in greenland")).to_be_hidden() @@ -171,8 +171,7 @@ def test_data_browser_bbox_filter_should_be_persistent( expect(browser.get_by_text("one point in france")).to_be_hidden() expect(browser.get_by_text("one line in new zeland")).to_be_hidden() expect(browser.get_by_text("one polygon in greenland")).to_be_hidden() - page.get_by_title("See data layers").click() - page.get_by_role("button", name="Browse data").click() + page.get_by_title("See layers").click() expect(browser.get_by_text("one point in france")).to_be_visible() expect(browser.get_by_text("one line in new zeland")).to_be_hidden() expect(browser.get_by_text("one polygon in greenland")).to_be_hidden() @@ -185,7 +184,7 @@ def test_data_browser_bbox_filtered_is_clickable(live_server, page, bootstrap, m el = page.get_by_text("Current map view") expect(el).to_be_visible() el.click() - browser = page.locator("#umap-ui-container") + browser = page.locator("#umap-panel") expect(browser.get_by_text("one point in france")).to_be_visible() expect(browser.get_by_text("one line in new zeland")).to_be_hidden() expect(browser.get_by_text("one polygon in greenland")).to_be_hidden() @@ -217,18 +216,6 @@ def test_data_browser_with_variable_in_name(live_server, page, bootstrap, map): expect(page.get_by_text("one polygon in greenland (polygon)")).to_be_visible() -def test_can_open_databrowser_from_layers_list(live_server, map, page, bootstrap): - page.goto(f"{live_server.url}{map.get_absolute_url()}") - page.get_by_title("See data layers").click() - page.get_by_role("button", name="Browse data").click() - browser = page.locator(".umap-browse-data") - expect(browser).to_be_visible() - expect(browser.get_by_text("test datalayer")).to_be_visible() - expect(browser.get_by_text("one point in france")).to_be_visible() - expect(browser.get_by_text("one line in new zeland")).to_be_visible() - expect(browser.get_by_text("one polygon in greenland")).to_be_visible() - - def test_should_sort_features_in_natural_order(live_server, map, page): map.settings["properties"]["onLoadPanel"] = "databrowser" map.save() @@ -238,7 +225,7 @@ def test_should_sort_features_in_natural_order(live_server, map, page): datalayer_data["features"][2]["properties"]["name"] = "100. a line" DataLayerFactory(map=map, data=datalayer_data) page.goto(f"{live_server.url}{map.get_absolute_url()}") - features = page.locator(".umap-browse-data li") + features = page.locator(".umap-browser .datalayer li") expect(features).to_have_count(3) expect(features.nth(0)).to_have_text("1. a poly") expect(features.nth(1)).to_have_text("9. a marker") @@ -249,7 +236,7 @@ def test_should_redraw_list_on_feature_delete(live_server, openmap, page, bootst page.goto(f"{live_server.url}{openmap.get_absolute_url()}") # Enable edit page.get_by_role("button", name="Edit").click() - buttons = page.locator(".umap-browse-data li .feature-delete") + buttons = page.locator(".umap-browser .datalayer li .feature-delete") expect(buttons).to_have_count(3) page.on("dialog", lambda dialog: dialog.accept()) buttons.nth(0).click() @@ -265,7 +252,7 @@ def test_should_show_header_for_display_on_load_false( datalayer.settings["name"] = "This layer is not loaded" datalayer.save() page.goto(f"{live_server.url}{map.get_absolute_url()}") - browser = page.locator(".umap-browse-data") + browser = page.locator(".umap-browser") expect(browser).to_be_visible() expect(browser.get_by_text("This layer is not loaded")).to_be_visible() @@ -279,7 +266,7 @@ def test_should_use_color_variable(live_server, map, page): datalayer_data["features"][2]["properties"]["mycolor"] = "DarkGreen" DataLayerFactory(map=map, data=datalayer_data) page.goto(f"{live_server.url}{map.get_absolute_url()}") - features = page.locator(".umap-browse-data li .feature-color") + features = page.locator(".umap-browser .datalayer li .feature-color") expect(features).to_have_count(3) # DarkGreen expect(features.nth(0)).to_have_css("background-color", "rgb(0, 100, 0)") diff --git a/umap/tests/integration/test_edit_datalayer.py b/umap/tests/integration/test_edit_datalayer.py index 2671cdf1..f0d4e50a 100644 --- a/umap/tests/integration/test_edit_datalayer.py +++ b/umap/tests/integration/test_edit_datalayer.py @@ -12,16 +12,15 @@ def test_should_have_fieldset_for_layer_type_properties(page, live_server, tilel page.goto(f"{live_server.url}/en/map/new/") # Open DataLayers list - button = page.get_by_title("Manage Layers") + button = page.get_by_title("See layers") expect(button).to_be_visible() button.click() # Create a layer - page.get_by_title("Manage layers").click() page.get_by_role("button", name="Add a layer").click() page.locator("input[name=name]").fill("Layer 1") - select = page.locator("#umap-ui-container .umap-field-type select") + select = page.locator("#umap-panel .umap-field-type select") expect(select).to_be_visible() choropleth_header = page.get_by_text("Choropleth: settings") diff --git a/umap/tests/integration/test_import.py b/umap/tests/integration/test_import.py index 7c278342..e780750c 100644 --- a/umap/tests/integration/test_import.py +++ b/umap/tests/integration/test_import.py @@ -24,10 +24,6 @@ def test_umap_import_from_file(live_server, tilelayer, page): button = page.get_by_role("button", name="Import", exact=True) expect(button).to_be_visible() button.click() - layers = page.locator(".umap-browse-datalayers li") - expect(layers).to_have_count(2) - nonloaded = page.locator(".umap-browse-datalayers li.off") - expect(nonloaded).to_have_count(1) assert file_input.input_value() # Close the import panel page.keyboard.press("Escape") @@ -35,6 +31,11 @@ def test_umap_import_from_file(live_server, tilelayer, page): expect(page.locator(".umap-main-edit-toolbox .map-name")).to_have_text( "Carte sans nom" ) + page.get_by_title("See layers").click() + layers = page.locator(".umap-browser .datalayer") + expect(layers).to_have_count(2) + nonloaded = page.locator(".umap-browser .datalayer.off") + expect(nonloaded).to_have_count(1) def test_umap_import_from_textarea(live_server, tilelayer, page, settings): @@ -67,7 +68,7 @@ def test_umap_import_from_textarea(live_server, tilelayer, page, settings): def test_import_geojson_from_textarea(tilelayer, live_server, page): page.goto(f"{live_server.url}/map/new/") - layers = page.locator(".umap-browse-datalayers li") + layers = page.locator(".umap-browser .datalayer") markers = page.locator(".leaflet-marker-icon") paths = page.locator("path") expect(markers).to_have_count(0) @@ -84,6 +85,7 @@ def test_import_geojson_from_textarea(tilelayer, live_server, page): expect(button).to_be_visible() button.click() # A layer has been created + page.get_by_title("See layers").click() expect(layers).to_have_count(1) expect(markers).to_have_count(2) expect(paths).to_have_count(3) diff --git a/umap/tests/integration/test_map.py b/umap/tests/integration/test_map.py index f0178883..90b691bc 100644 --- a/umap/tests/integration/test_map.py +++ b/umap/tests/integration/test_map.py @@ -42,10 +42,10 @@ def test_default_view_without_datalayer_should_use_default_center( ): datalayer.settings["displayOnLoad"] = False datalayer.save() - page.goto(f"{live_server.url}{map.get_absolute_url()}") + page.goto(f"{live_server.url}{map.get_absolute_url()}?onLoadPanel=datalayers") # Hash is defined, so map is initialized expect(page).to_have_url(re.compile(r".*#7/48\..+/13\..+")) - layers = page.locator(".umap-browse-datalayers li") + layers = page.locator(".umap-browser .datalayer h5") expect(layers).to_have_count(1) @@ -56,10 +56,10 @@ def test_default_view_latest_without_datalayer_should_use_default_center( datalayer.save() map.settings["properties"]["defaultView"] = "latest" map.save() - page.goto(f"{live_server.url}{map.get_absolute_url()}") + page.goto(f"{live_server.url}{map.get_absolute_url()}?onLoadPanel=datalayers") # Hash is defined, so map is initialized expect(page).to_have_url(re.compile(r".*#7/48\..+/13\..+")) - layers = page.locator(".umap-browse-datalayers li") + layers = page.locator(".umap-browser .datalayer h5") expect(layers).to_have_count(1) @@ -70,20 +70,20 @@ def test_default_view_data_without_datalayer_should_use_default_center( datalayer.save() map.settings["properties"]["defaultView"] = "data" map.save() - page.goto(f"{live_server.url}{map.get_absolute_url()}") + page.goto(f"{live_server.url}{map.get_absolute_url()}?onLoadPanel=datalayers") # Hash is defined, so map is initialized expect(page).to_have_url(re.compile(r".*#7/48\..+/13\..+")) - layers = page.locator(".umap-browse-datalayers li") + layers = page.locator(".umap-browser .datalayer h5") expect(layers).to_have_count(1) def test_default_view_latest_with_marker(map, live_server, datalayer, page): map.settings["properties"]["defaultView"] = "latest" map.save() - page.goto(f"{live_server.url}{map.get_absolute_url()}") + page.goto(f"{live_server.url}{map.get_absolute_url()}?onLoadPanel=datalayers") # Hash is defined, so map is initialized expect(page).to_have_url(re.compile(r".*#7/48\..+/14\..+")) - layers = page.locator(".umap-browse-datalayers li") + layers = page.locator(".umap-browser .datalayer h5") expect(layers).to_have_count(1) @@ -109,9 +109,9 @@ def test_default_view_latest_with_line(map, live_server, page): DataLayerFactory(map=map, data=data) map.settings["properties"]["defaultView"] = "latest" map.save() - page.goto(f"{live_server.url}{map.get_absolute_url()}") + page.goto(f"{live_server.url}{map.get_absolute_url()}?onLoadPanel=datalayers") expect(page).to_have_url(re.compile(r".*#8/48\..+/2\..+")) - layers = page.locator(".umap-browse-datalayers li") + layers = page.locator(".umap-browser .datalayer h5") expect(layers).to_have_count(1) @@ -140,9 +140,9 @@ def test_default_view_latest_with_polygon(map, live_server, page): DataLayerFactory(map=map, data=data) map.settings["properties"]["defaultView"] = "latest" map.save() - page.goto(f"{live_server.url}{map.get_absolute_url()}") + page.goto(f"{live_server.url}{map.get_absolute_url()}?onLoadPanel=datalayers") expect(page).to_have_url(re.compile(r".*#8/48\..+/2\..+")) - layers = page.locator(".umap-browse-datalayers li") + layers = page.locator(".umap-browser .datalayer h5") expect(layers).to_have_count(1) @@ -168,10 +168,10 @@ def test_remote_layer_should_not_be_used_as_datalayer_for_created_features( } datalayer.save() page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit") - toggle = page.get_by_role("button", name="See data layers") + toggle = page.get_by_role("button", name="See layers") expect(toggle).to_be_visible() toggle.click() - layers = page.locator(".umap-browse-datalayers li") + layers = page.locator(".umap-browser .datalayer h5") expect(layers).to_have_count(1) map_el = page.locator("#map") add_marker = page.get_by_title("Draw a marker") @@ -183,6 +183,7 @@ def test_remote_layer_should_not_be_used_as_datalayer_for_created_features( expect(marker).to_have_count(1) # A new datalayer has been created to host this created feature # given the remote one cannot accept new features + page.get_by_title("See layers").click() expect(layers).to_have_count(2) @@ -195,9 +196,9 @@ def test_can_hide_datalayer_from_caption(openmap, live_server, datalayer, page): toggle.click() layers = page.locator(".umap-caption .datalayer-legend") expect(layers).to_have_count(1) - found = page.locator("#umap-ui-container").get_by_text(datalayer.name) + found = page.locator("#umap-panel").get_by_text(datalayer.name) expect(found).to_be_visible() - hidden = page.locator("#umap-ui-container").get_by_text(other.name) + hidden = page.locator("#umap-panel").get_by_text(other.name) expect(hidden).to_be_hidden() diff --git a/umap/tests/integration/test_owned_map.py b/umap/tests/integration/test_owned_map.py index f753baba..4013fe86 100644 --- a/umap/tests/integration/test_owned_map.py +++ b/umap/tests/integration/test_owned_map.py @@ -186,7 +186,7 @@ def test_can_change_perms_after_create(tilelayer, live_server, login, user): page = login(user) page.goto(f"{live_server.url}/en/map/new") # Create a layer - page.get_by_title("Manage layers").click() + page.get_by_title("See layers").click() page.get_by_role("button", name="Add a layer").click() page.locator("input[name=name]").fill("Layer 1") save = page.get_by_role("button", name="Save") diff --git a/umap/tests/integration/test_picto.py b/umap/tests/integration/test_picto.py index 33a2c214..192f28e4 100644 --- a/umap/tests/integration/test_picto.py +++ b/umap/tests/integration/test_picto.py @@ -171,7 +171,7 @@ def test_can_use_remote_url_as_picto(openmap, live_server, page, pictos): input_el.blur() expect(marker).to_have_attribute("src", "https://foo.bar/img.jpg") # Now close and reopen the form, it should still be the URL tab - close = page.locator("#umap-ui-container .toolbox").get_by_title("Close") + close = page.locator("#umap-panel .toolbox").get_by_title("Close") expect(close).to_be_visible() close.click() edit_settings.click() @@ -210,7 +210,7 @@ def test_can_use_char_as_picto(openmap, live_server, page, pictos): expect(marker).to_have_count(1) expect(marker).to_have_text("♩") # Now close and reopen the form, it should still be the URL tab - close = page.locator("#umap-ui-container .toolbox").get_by_title("Close") + close = page.locator("#umap-panel .toolbox").get_by_title("Close") expect(close).to_be_visible() close.click() edit_settings.click() diff --git a/umap/tests/integration/test_querystring.py b/umap/tests/integration/test_querystring.py index 92962ded..1393a89b 100644 --- a/umap/tests/integration/test_querystring.py +++ b/umap/tests/integration/test_querystring.py @@ -15,30 +15,23 @@ def test_scale_control(map, live_server, datalayer, page): def test_datalayers_control(map, live_server, datalayer, page): - control = page.locator(".umap-browse-toggle") - box = page.locator(".umap-browse-datalayers") - more = page.get_by_title("More controls") + control = page.locator(".umap-control-browse") + browser = page.locator(".umap-browser") page.goto(f"{live_server.url}{map.get_absolute_url()}") expect(control).to_be_visible() - expect(box).to_be_hidden() + expect(browser).to_be_hidden() page.goto(f"{live_server.url}{map.get_absolute_url()}?datalayersControl=true") expect(control).to_be_visible() - expect(box).to_be_hidden() + expect(browser).to_be_hidden() page.goto(f"{live_server.url}{map.get_absolute_url()}?datalayersControl=null") expect(control).to_be_hidden() - expect(more).to_be_visible() - more.click() - expect(control).to_be_visible() - expect(box).to_be_hidden() + expect(browser).to_be_hidden() page.goto(f"{live_server.url}{map.get_absolute_url()}?datalayersControl=false") expect(control).to_be_hidden() - expect(more).to_be_visible() - more.click() - expect(control).to_be_hidden() - expect(box).to_be_hidden() + expect(browser).to_be_hidden() page.goto(f"{live_server.url}{map.get_absolute_url()}?datalayersControl=expanded") expect(control).to_be_hidden() - expect(box).to_be_visible() + expect(browser).to_be_visible() def test_can_deactivate_wheel_from_query_string(map, live_server, page): diff --git a/umap/tests/integration/test_statics.py b/umap/tests/integration/test_statics.py index f1aa9306..3b92fb7d 100644 --- a/umap/tests/integration/test_statics.py +++ b/umap/tests/integration/test_statics.py @@ -42,5 +42,6 @@ def test_javascript_have_been_loaded( # Should be in French, so hashed locale file has been loaded correctly button = page.get_by_text("Voir les calques") expect(button).to_be_visible() - layers = page.locator(".umap-browse-datalayers li") + button.click() + layers = page.locator(".umap-browser .datalayer") expect(layers).to_have_count(1) From 87f611d0b505434bb02e7a7d0f2490edadb622d6 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Tue, 12 Mar 2024 09:50:10 +0100 Subject: [PATCH 08/44] chore: refactore panel header/toolbox --- umap/static/umap/base.css | 34 ++++++++++-------------- umap/static/umap/img/16-white.svg | 6 +++-- umap/static/umap/img/16.svg | 5 ++-- umap/static/umap/img/source/16-white.svg | 8 +++--- umap/static/umap/img/source/16.svg | 7 ++--- umap/static/umap/js/umap.controls.js | 13 ++------- umap/static/umap/js/umap.popup.js | 4 +-- umap/static/umap/js/umap.ui.js | 6 ++--- umap/static/umap/map.css | 26 ++++++++---------- umap/tests/integration/test_browser.py | 2 +- 10 files changed, 48 insertions(+), 63 deletions(-) diff --git a/umap/static/umap/base.css b/umap/static/umap/base.css index 844ae097..5c64232d 100644 --- a/umap/static/umap/base.css +++ b/umap/static/umap/base.css @@ -683,7 +683,6 @@ input[type=hidden].blur + [type="button"] { visibility: hidden; position: absolute; bottom: 0; - padding: 10px; border-left: 1px solid var(--color-lightGray); overflow-x: auto; z-index: 1010; @@ -729,7 +728,8 @@ input[type=hidden].blur + [type="button"] { } #umap-panel .body { clear: both; - height: calc(100% - 54px); /* Minus size of toolbox */ + height: calc(100% - 32px); /* Minus size of toolbox */ + padding: 10px; } #umap-panel .toolbox { padding: 5px 10px; @@ -739,27 +739,30 @@ input[type=hidden].blur + [type="button"] { font-size: 10px; justify-content: flex-start; gap: 5px; + background-color: var(--color-lightGray); + border-bottom: 1px solid #bbb; + line-height: 2.2em; +} +#umap-panel.dark .toolbox { + background-color: var(--color-darkGray); + border-bottom: 1px solid #232729; } #umap-panel .toolbox li { - color: #2e3436; - line-height: 32px; cursor: pointer; - float: right; display: inline; - padding: 0 7px; + padding: 0 2px; border: 1px solid #b6b6b3; border-radius: 2px; } +#umap-panel.dark .toolbox #umap-panel.dark .toolbox li { color: #d3dfeb; border: 1px solid #202425; } #umap-panel .toolbox li:hover { - color: #2e3436; background-color: #d4d4d2; } #umap-panel.dark .toolbox li:hover { - color: #eeeeec; background-color: #353c3e; } .dark input, .dark textarea { @@ -896,28 +899,19 @@ input:invalid { .umap-close-icon { background-repeat: no-repeat; background-image: url('./img/16.svg'); - background-position: -28px -6px; + background-position: -26px -6px; display: inline; padding: 0 10px; vertical-align: middle; + line-height: 24px; } .umap-resize-icon { - background-position: -76px -150px; + background-position: -74px -150px; } .dark .umap-resize-icon, .dark .umap-close-icon { background-image: url('./img/16-white.svg'); } -.dark .umap-close-link { - border: 1px solid #202425; - color: #eeeeec; - padding: 0 7px; - line-height: 32px; - background-color: var(--color-darkGray); -} -.dark .umap-close-link:hover { - background-color: #2e3436; -} #umap-alert-container .umap-close-link { color: #fff; float: right; diff --git a/umap/static/umap/img/16-white.svg b/umap/static/umap/img/16-white.svg index 022e413f..d3c2c6bd 100644 --- a/umap/static/umap/img/16-white.svg +++ b/umap/static/umap/img/16-white.svg @@ -186,7 +186,9 @@ - - + + + + diff --git a/umap/static/umap/img/16.svg b/umap/static/umap/img/16.svg index e046e342..0367ddfd 100644 --- a/umap/static/umap/img/16.svg +++ b/umap/static/umap/img/16.svg @@ -178,7 +178,8 @@ - - + + + diff --git a/umap/static/umap/img/source/16-white.svg b/umap/static/umap/img/source/16-white.svg index 11ab2c03..c8dddfeb 100644 --- a/umap/static/umap/img/source/16-white.svg +++ b/umap/static/umap/img/source/16-white.svg @@ -16,7 +16,7 @@ - + @@ -208,7 +208,9 @@ - - + + + + diff --git a/umap/static/umap/img/source/16.svg b/umap/static/umap/img/source/16.svg index 16569742..54925b08 100644 --- a/umap/static/umap/img/source/16.svg +++ b/umap/static/umap/img/source/16.svg @@ -10,7 +10,7 @@ - + @@ -197,7 +197,8 @@ - - + + + diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js index 52370364..c4f1bd6d 100644 --- a/umap/static/umap/js/umap.controls.js +++ b/umap/static/umap/js/umap.controls.js @@ -532,7 +532,7 @@ U.DataLayer.include({ renderToolbox: function (container) { L.DomUtil.element( 'i', - { className: 'drag-handle', title: L._('Drag to reorder') }, + { className: 'drag-handle show-on-edit', title: L._('Drag to reorder') }, container ) const toggle = L.DomUtil.create('i', 'layer-toggle', container), @@ -667,16 +667,7 @@ const ControlsMixin = { }) container.appendChild(builder.build()) - this.ui.openPanel({ data: { html: container }, actions: [this._aboutLink()] }) - }, - - _aboutLink: function () { - const link = L.DomUtil.create('li', '') - L.DomUtil.create('i', 'umap-icon-16 umap-caption', link) - const label = L.DomUtil.create('span', '', link) - label.textContent = label.title = L._('About') - L.DomEvent.on(link, 'click', this.displayCaption, this) - return link + this.ui.openPanel({ data: { html: container } }) }, displayCaption: function () { diff --git a/umap/static/umap/js/umap.popup.js b/umap/static/umap/js/umap.popup.js index e4354985..e070cef6 100644 --- a/umap/static/umap/js/umap.popup.js +++ b/umap/static/umap/js/umap.popup.js @@ -56,9 +56,9 @@ U.Popup.Panel = U.Popup.extend({ allButton: function () { const button = L.DomUtil.create('li', '') - L.DomUtil.create('i', 'umap-icon-16 umap-list', button) + L.DomUtil.create('i', 'umap-icon-16 umap-back', button) const label = L.DomUtil.create('span', '', button) - label.textContent = label.title = L._('See all') + button.title = L._('See all') // Fixme: remove me when this is merged and released // https://github.com/Leaflet/Leaflet/pull/9052 L.DomEvent.disableClickPropagation(button) diff --git a/umap/static/umap/js/umap.ui.js b/umap/static/umap/js/umap.ui.js index 89ee90d0..0e61caa1 100644 --- a/umap/static/umap/js/umap.ui.js +++ b/umap/static/umap/js/umap.ui.js @@ -39,12 +39,10 @@ U.UI = L.Evented.extend({ else body.innerHTML = e.data.html const closeLink = L.DomUtil.create('li', 'umap-close-link', actionsContainer) L.DomUtil.add('i', 'umap-close-icon', closeLink) - const label = L.DomUtil.create('span', '', closeLink) - label.title = label.textContent = L._('Close') + closeLink.title = L._('Close') const resizeLink = L.DomUtil.create('li', 'umap-resize-link', actionsContainer) L.DomUtil.add('i', 'umap-resize-icon', resizeLink) - const resizeLabel = L.DomUtil.create('span', '', resizeLink) - resizeLabel.title = resizeLabel.textContent = L._('Toggle size') + resizeLink.title = L._('Toggle size') if (e.actions) { for (let i = 0; i < e.actions.length; i++) { actionsContainer.appendChild(e.actions[i]) diff --git a/umap/static/umap/map.css b/umap/static/umap/map.css index 7d39e2d4..a2d41ddd 100644 --- a/umap/static/umap/map.css +++ b/umap/static/umap/map.css @@ -835,16 +835,9 @@ ul.photon-autocomplete { } -.leaflet-inplace-toolbar a { - background-image: url('./img/16-white.svg'); - background-color: var(--color-darkGray)!important; -} .leaflet-toolbar-tip { background-color: var(--color-darkGray); } -.leaflet-inplace-toolbar a:hover { - background-color: #353c3e!important; -} .layer-toggle { background-position: -49px -31px; } @@ -989,14 +982,10 @@ a.add-datalayer:hover { display: block; } i.drag-handle { - display: none; background-position: -72px -73px; cursor: move; margin-right: 10px; } -.umap-edit-enabled [draggable] .drag-handle { - display: inline-block; -} .umap-browser .off .feature { display: none; @@ -1093,9 +1082,6 @@ i.drag-handle { padding-left: 0; padding-right: 0; } -#umap-panel.umap-table-editor .toolbox li { - float: left; -} .umap-table-editor .umap-close-link { right: auto; @@ -1171,11 +1157,14 @@ i.drag-handle { vertical-align: middle; } .umap-add { - background-position: -28px -27px; + background-position: -27px -27px; } .umap-list { background-position: -28px -99px; } +.umap-back { + background-position: -122px -144px; +} .umap-list-white { background-position: -92px -168px; } @@ -1726,6 +1715,13 @@ span.popup-icon { .leaflet-inplace-toolbar { z-index: 10000!important; } +.leaflet-inplace-toolbar a { + background-image: url('./img/16-white.svg'); + background-color: var(--color-darkGray)!important; +} +.leaflet-inplace-toolbar a:hover { + background-color: #353c3e!important; +} .leaflet-touch .leaflet-control-layers, .leaflet-touch .leaflet-bar { border-width: 1px; } diff --git a/umap/tests/integration/test_browser.py b/umap/tests/integration/test_browser.py index 2912f932..5241a548 100644 --- a/umap/tests/integration/test_browser.py +++ b/umap/tests/integration/test_browser.py @@ -164,7 +164,7 @@ def test_data_browser_bbox_filter_should_be_persistent( expect(browser.get_by_text("one line in new zeland")).to_be_hidden() expect(browser.get_by_text("one polygon in greenland")).to_be_hidden() # Close and reopen the browser to make sure this settings is persistent - close = browser.get_by_text("Close") + close = browser.get_by_title("Close") close.click() expect(browser).to_be_hidden() sleep(0.5) From 86956c4563062c45ce4654b52a5e9f6f043622d9 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Tue, 12 Mar 2024 11:06:33 +0100 Subject: [PATCH 09/44] chore: use umap-icon-16 CSS class in panel toolbox --- umap/static/umap/js/modules/browser.js | 32 +++++++++++++++--------- umap/static/umap/js/umap.controls.js | 12 ++++----- umap/static/umap/js/umap.ui.js | 4 +-- umap/static/umap/map.css | 34 ++++++-------------------- 4 files changed, 36 insertions(+), 46 deletions(-) diff --git a/umap/static/umap/js/modules/browser.js b/umap/static/umap/js/modules/browser.js index 5e2d38ba..5f93a22a 100644 --- a/umap/static/umap/js/modules/browser.js +++ b/umap/static/umap/js/modules/browser.js @@ -19,10 +19,10 @@ export default class Browser { if (filter && !feature.matchFilter(filter, this.filterKeys)) return if (this.options.inBbox && !feature.isOnScreen(this.bounds)) return const feature_li = DomUtil.create('li', `${feature.getClassName()} feature`), - zoom_to = DomUtil.create('i', 'feature-zoom_to', feature_li), - edit = DomUtil.create('i', 'show-on-edit feature-edit', feature_li), - del = DomUtil.create('i', 'show-on-edit feature-delete', feature_li), - colorBox = DomUtil.create('i', 'feature-color', feature_li), + zoom_to = DomUtil.create('i', 'umap-icon-16 feature-zoom_to', feature_li), + edit = DomUtil.create('i', 'umap-icon-16 show-on-edit feature-edit', feature_li), + del = DomUtil.create('i', 'umap-icon-16 show-on-edit feature-delete', feature_li), + colorBox = DomUtil.create('i', 'umap-icon-16 feature-color', feature_li), title = DomUtil.create('span', 'feature-title', feature_li), symbol = feature._getIconUrl ? U.Icon.prototype.formatUrl(feature._getIconUrl(), feature) @@ -160,23 +160,31 @@ export default class Browser { }) formContainer.appendChild(builder.build()) + const addButton = L.DomUtil.create('li', 'add-datalayer show-on-edit') + L.DomUtil.create('i', 'umap-icon-16 umap-add', addButton) + const label = L.DomUtil.create('span', '', addButton) + label.textContent = label.title = L._('Add a layer') + const addProperty = function () { + const newName = prompt(L._('Please enter the name of the property')) + if (!newName || !this.validateName(newName)) return + this.datalayer.indexProperty(newName) + this.edit() + } + L.DomEvent.on(addButton, 'click', this.newDataLayer, this) + + let className = 'umap-browser' if (this.map.editEnabled) className += ' dark' this.map.ui.openPanel({ data: { html: container }, - className: className + className: className, + actions: [addButton] }) this.map.eachBrowsableDataLayer((datalayer) => { this.addDataLayer(datalayer, dataContainer) }) - L.DomUtil.createButton( - 'show-on-edit block add-datalayer button', - container, - L._('Add a layer'), - this.newDataLayer, - this - ) + // After datalayers have been added. const orderable = new Orderable(dataContainer, L.bind(this.onReorder, this)) } diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js index c4f1bd6d..c2d5d905 100644 --- a/umap/static/umap/js/umap.controls.js +++ b/umap/static/umap/js/umap.controls.js @@ -532,14 +532,14 @@ U.DataLayer.include({ renderToolbox: function (container) { L.DomUtil.element( 'i', - { className: 'drag-handle show-on-edit', title: L._('Drag to reorder') }, + { className: 'umap-icon-16 drag-handle show-on-edit', title: L._('Drag to reorder') }, container ) - const toggle = L.DomUtil.create('i', 'layer-toggle', container), - zoomTo = L.DomUtil.create('i', 'layer-zoom_to', container), - edit = L.DomUtil.create('i', 'layer-edit show-on-edit', container), - table = L.DomUtil.create('i', 'layer-table-edit show-on-edit', container), - remove = L.DomUtil.create('i', 'layer-delete show-on-edit', container) + const toggle = L.DomUtil.create('i', 'umap-icon-16 layer-toggle', container), + zoomTo = L.DomUtil.create('i', 'umap-icon-16 layer-zoom_to', container), + edit = L.DomUtil.create('i', 'umap-icon-16 layer-edit show-on-edit', container), + table = L.DomUtil.create('i', 'umap-icon-16 layer-table-edit show-on-edit', container), + remove = L.DomUtil.create('i', 'umap-icon-16 layer-delete show-on-edit', container) zoomTo.title = L._('Zoom to layer extent') toggle.title = L._('Show/hide layer') edit.title = L._('Edit') diff --git a/umap/static/umap/js/umap.ui.js b/umap/static/umap/js/umap.ui.js index 0e61caa1..ad881fde 100644 --- a/umap/static/umap/js/umap.ui.js +++ b/umap/static/umap/js/umap.ui.js @@ -38,10 +38,10 @@ U.UI = L.Evented.extend({ body.appendChild(e.data.html) else body.innerHTML = e.data.html const closeLink = L.DomUtil.create('li', 'umap-close-link', actionsContainer) - L.DomUtil.add('i', 'umap-close-icon', closeLink) + L.DomUtil.add('i', 'umap-icon-16 umap-close-icon', closeLink) closeLink.title = L._('Close') const resizeLink = L.DomUtil.create('li', 'umap-resize-link', actionsContainer) - L.DomUtil.add('i', 'umap-resize-icon', resizeLink) + L.DomUtil.add('i', 'umap-icon-16 umap-resize-icon', resizeLink) resizeLink.title = L._('Toggle size') if (e.actions) { for (let i = 0; i < e.actions.length; i++) { diff --git a/umap/static/umap/map.css b/umap/static/umap/map.css index a2d41ddd..7d478fb8 100644 --- a/umap/static/umap/map.css +++ b/umap/static/umap/map.css @@ -910,22 +910,6 @@ ul.photon-autocomplete { font-size: 12px; cursor: pointer; } -a.add-datalayer:before { - background-image: url('./img/16.svg'); - background-repeat: no-repeat; - background-position: -45px -96px; - width: 24px; - height: 24px; - content: " "; - display: block; - float: left; -} -a.add-datalayer:before { - background-position: -20px -20px; -} -a.add-datalayer:hover { - background-color: rgb(99, 99, 99); -} .show-on-edit { display: none!important; } @@ -960,9 +944,7 @@ a.add-datalayer:hover { background-color: var(--color-darkGray); } .search-result-tools i, -.leaflet-inplace-toolbar a, -.umap-browser i, -.umap-caption i { +.leaflet-inplace-toolbar a { background-repeat: no-repeat; background-image: url('./img/16.svg'); display: inline; @@ -1083,10 +1065,6 @@ i.drag-handle { padding-right: 0; } -.umap-table-editor .umap-close-link { - right: auto; - left: 20px; -} .umap-table-editor .table { display: table; width: 100%; @@ -1151,13 +1129,17 @@ i.drag-handle { .umap-icon-16 { background-repeat: no-repeat; background-image: url('./img/16.svg'); - display: inline-block; - height: 20px; + display: inline; + height: 24px; + line-height: 24px; padding: 0 10px; vertical-align: middle; } +.dark .umap-icon-16 { + background-image: url('./img/16-white.svg'); +} .umap-add { - background-position: -27px -27px; + background-position: -26px -30px; } .umap-list { background-position: -28px -99px; From a018b8863f8a3b1ef15edc9982e7c5309ead4504 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Tue, 12 Mar 2024 11:32:05 +0100 Subject: [PATCH 10/44] chore: refactor browser back button --- umap/static/umap/img/16-white.svg | 1 + umap/static/umap/img/source/16-white.svg | 3 ++- umap/static/umap/js/modules/browser.js | 13 +++++++++++++ umap/static/umap/js/umap.features.js | 6 +++++- umap/static/umap/js/umap.layer.js | 6 +++++- umap/static/umap/js/umap.popup.js | 14 +------------- umap/static/umap/js/umap.tableeditor.js | 2 +- umap/static/umap/map.css | 6 +++--- 8 files changed, 31 insertions(+), 20 deletions(-) diff --git a/umap/static/umap/img/16-white.svg b/umap/static/umap/img/16-white.svg index d3c2c6bd..1de49bb5 100644 --- a/umap/static/umap/img/16-white.svg +++ b/umap/static/umap/img/16-white.svg @@ -190,5 +190,6 @@ + diff --git a/umap/static/umap/img/source/16-white.svg b/umap/static/umap/img/source/16-white.svg index c8dddfeb..11dabbaf 100644 --- a/umap/static/umap/img/source/16-white.svg +++ b/umap/static/umap/img/source/16-white.svg @@ -16,7 +16,7 @@ - + @@ -212,5 +212,6 @@ + diff --git a/umap/static/umap/js/modules/browser.js b/umap/static/umap/js/modules/browser.js index 5f93a22a..63f0f86d 100644 --- a/umap/static/umap/js/modules/browser.js +++ b/umap/static/umap/js/modules/browser.js @@ -219,4 +219,17 @@ export default class Browser { if (!this.isOpen()) return this.map.ui._panel.classList.remove('dark') } + + static backButton (map) { + const button = L.DomUtil.create('li', '') + L.DomUtil.create('i', 'umap-icon-16 umap-back', button) + const label = L.DomUtil.create('span', '', button) + button.title = L._('Back to browser') + // Fixme: remove me when this is merged and released + // https://github.com/Leaflet/Leaflet/pull/9052 + L.DomEvent.disableClickPropagation(button) + L.DomEvent.on(button, 'click', map.openBrowser, map) + return button + } + } diff --git a/umap/static/umap/js/umap.features.js b/umap/static/umap/js/umap.features.js index e38595ad..58a27e41 100644 --- a/umap/static/umap/js/umap.features.js +++ b/umap/static/umap/js/umap.features.js @@ -137,7 +137,11 @@ U.FeatureMixin = { this.appendEditFieldsets(container) const advancedActions = L.DomUtil.createFieldset(container, L._('Advanced actions')) this.getAdvancedEditActions(advancedActions) - this.map.ui.openPanel({ data: { html: container }, className: 'dark' }) + this.map.ui.openPanel({ + data: { html: container }, + className: 'dark', + actions: [U.Browser.backButton(this.map)], + }) this.map.editedFeature = this if (!this.isOnScreen()) this.zoomTo(e) }, diff --git a/umap/static/umap/js/umap.layer.js b/umap/static/umap/js/umap.layer.js index 56d36383..7012b2d2 100644 --- a/umap/static/umap/js/umap.layer.js +++ b/umap/static/umap/js/umap.layer.js @@ -1379,7 +1379,11 @@ U.DataLayer = L.Evented.extend({ '_blank' ) } - this.map.ui.openPanel({ data: { html: container }, className: 'dark' }) + this.map.ui.openPanel({ + data: { html: container }, + className: 'dark', + actions: [U.Browser.backButton(this.map)], + }) }, getOwnOption: function (option) { diff --git a/umap/static/umap/js/umap.popup.js b/umap/static/umap/js/umap.popup.js index e070cef6..ced6b1d0 100644 --- a/umap/static/umap/js/umap.popup.js +++ b/umap/static/umap/js/umap.popup.js @@ -54,22 +54,10 @@ U.Popup.Panel = U.Popup.extend({ zoomAnimation: false, }, - allButton: function () { - const button = L.DomUtil.create('li', '') - L.DomUtil.create('i', 'umap-icon-16 umap-back', button) - const label = L.DomUtil.create('span', '', button) - button.title = L._('See all') - // Fixme: remove me when this is merged and released - // https://github.com/Leaflet/Leaflet/pull/9052 - L.DomEvent.disableClickPropagation(button) - L.DomEvent.on(button, 'click', this.feature.map.openBrowser, this.feature.map) - return button - }, - onAdd: function (map) { map.ui.openPanel({ data: { html: this._content }, - actions: [this.allButton()], + actions: [U.Browser.backButton(map)], }) // fire events as in base class Popup.js:onAdd diff --git a/umap/static/umap/js/umap.tableeditor.js b/umap/static/umap/js/umap.tableeditor.js index 19cafbed..2c0a9bf4 100644 --- a/umap/static/umap/js/umap.tableeditor.js +++ b/umap/static/umap/js/umap.tableeditor.js @@ -113,7 +113,7 @@ U.TableEditor = L.Class.extend({ this.datalayer.map.ui.openPanel({ data: { html: this.table }, className: 'umap-table-editor fullwidth dark', - actions: [addButton], + actions: [addButton, U.Browser.backButton(this.datalayer.map)], }) this.datalayer.map.fire('dataload', { id: id }) }, diff --git a/umap/static/umap/map.css b/umap/static/umap/map.css index 7d478fb8..648b684c 100644 --- a/umap/static/umap/map.css +++ b/umap/static/umap/map.css @@ -954,8 +954,8 @@ ul.photon-autocomplete { line-height: 24px; vertical-align: middle; } -.umap-browser.dark .datalayer i { - background-image: url('./img/16-white.svg'); +.umap-browser .datalayer i { + cursor: pointer; } .umap-browser ul { display: none; @@ -1145,7 +1145,7 @@ i.drag-handle { background-position: -28px -99px; } .umap-back { - background-position: -122px -144px; + background-position: -122px -150px; } .umap-list-white { background-position: -92px -168px; From 2147e5a612216468c5a5ade7c7a0d74d4cbc0492 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Tue, 12 Mar 2024 17:08:23 +0100 Subject: [PATCH 11/44] chore: add missing umap-icon-16 class in browser toggle button --- umap/static/umap/js/modules/browser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/umap/static/umap/js/modules/browser.js b/umap/static/umap/js/modules/browser.js index 63f0f86d..bbb6cda4 100644 --- a/umap/static/umap/js/modules/browser.js +++ b/umap/static/umap/js/modules/browser.js @@ -101,7 +101,7 @@ export default class Browser { const headline = parent.querySelector('h5') const toggleList = () => parent.classList.toggle('show-list') headline.innerHTML = '' - const toggle = DomUtil.create('i', 'datalayer-toggle-list', headline) + const toggle = DomUtil.create('i', 'umap-icon-16 datalayer-toggle-list', headline) DomEvent.on(toggle, 'click', toggleList) datalayer.renderToolbox(headline) const name = DomUtil.create('span', 'datalayer-name', headline) From a360ca0e130b6383b572e9e02bc6b3d2ab61f319 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Tue, 12 Mar 2024 17:08:51 +0100 Subject: [PATCH 12/44] chore: make browser expanded/condensed mode persistent --- umap/static/umap/js/umap.ui.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/umap/static/umap/js/umap.ui.js b/umap/static/umap/js/umap.ui.js index ad881fde..ceaca6a2 100644 --- a/umap/static/umap/js/umap.ui.js +++ b/umap/static/umap/js/umap.ui.js @@ -68,7 +68,15 @@ U.UI = L.Evented.extend({ }, resizePanel: function () { - this._panel.classList.toggle('condensed') + if (this.PANEL_MODE === 'expanded') { + this.PANEL_MODE = 'condensed' + this._panel.classList.remove('expanded') + this._panel.classList.add('condensed') + } else { + this.PANEL_MODE = 'expanded' + this._panel.classList.remove('condensed') + this._panel.classList.add('expanded') + } }, closePanel: function () { From e4ecb1a84700b2f300f1a0c909ff9282ab9e55cb Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Tue, 12 Mar 2024 22:37:50 +0100 Subject: [PATCH 13/44] chore: fix test This action is managed in the header panel, thus it's not a button. We may make all header actions proper buttons, but maybe in another PR ? --- umap/tests/integration/test_anonymous_owned_map.py | 2 +- umap/tests/integration/test_edit_datalayer.py | 2 +- umap/tests/integration/test_owned_map.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/umap/tests/integration/test_anonymous_owned_map.py b/umap/tests/integration/test_anonymous_owned_map.py index 2bb94f3b..119547eb 100644 --- a/umap/tests/integration/test_anonymous_owned_map.py +++ b/umap/tests/integration/test_anonymous_owned_map.py @@ -132,7 +132,7 @@ def test_can_change_perms_after_create(tilelayer, live_server, page): page.goto(f"{live_server.url}/en/map/new") # Create a layer page.get_by_title("See layers").click() - page.get_by_role("button", name="Add a layer").click() + page.get_by_title("Add a layer").click() page.locator("input[name=name]").fill("Layer 1") save = page.get_by_role("button", name="Save") expect(save).to_be_visible() diff --git a/umap/tests/integration/test_edit_datalayer.py b/umap/tests/integration/test_edit_datalayer.py index f0d4e50a..824a8327 100644 --- a/umap/tests/integration/test_edit_datalayer.py +++ b/umap/tests/integration/test_edit_datalayer.py @@ -17,7 +17,7 @@ def test_should_have_fieldset_for_layer_type_properties(page, live_server, tilel button.click() # Create a layer - page.get_by_role("button", name="Add a layer").click() + page.get_by_title("Add a layer").click() page.locator("input[name=name]").fill("Layer 1") select = page.locator("#umap-panel .umap-field-type select") diff --git a/umap/tests/integration/test_owned_map.py b/umap/tests/integration/test_owned_map.py index 4013fe86..31ea9087 100644 --- a/umap/tests/integration/test_owned_map.py +++ b/umap/tests/integration/test_owned_map.py @@ -187,7 +187,7 @@ def test_can_change_perms_after_create(tilelayer, live_server, login, user): page.goto(f"{live_server.url}/en/map/new") # Create a layer page.get_by_title("See layers").click() - page.get_by_role("button", name="Add a layer").click() + page.get_by_title("Add a layer").click() page.locator("input[name=name]").fill("Layer 1") save = page.get_by_role("button", name="Save") expect(save).to_be_visible() From 2a2f38e3cd506af48a1e460556fc3eea04decc44 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Wed, 13 Mar 2024 11:42:51 +0100 Subject: [PATCH 14/44] chore: change edit button order --- umap/static/umap/base.css | 7 ++- umap/static/umap/img/24-white.svg | 4 +- umap/static/umap/img/source/24-white.svg | 6 +-- umap/static/umap/js/umap.controls.js | 44 +++++++++++++------ umap/static/umap/js/umap.js | 13 +++--- umap/static/umap/map.css | 24 +++++----- .../integration/test_anonymous_owned_map.py | 4 +- umap/tests/integration/test_owned_map.py | 10 ++--- umap/tests/integration/test_picto.py | 6 +-- 9 files changed, 72 insertions(+), 46 deletions(-) diff --git a/umap/static/umap/base.css b/umap/static/umap/base.css index 5c64232d..8283cb54 100644 --- a/umap/static/umap/base.css +++ b/umap/static/umap/base.css @@ -274,11 +274,13 @@ input[type="file"] + .error { margin-top: 0; } .fieldset { - border: 1px solid #222; margin-bottom: 5px; border-top-left-radius: 4px; border-top-right-radius: 4px; } +.dark .fieldset { + border: 1px solid #222; +} .fieldset .fields { visibility: hidden; opacity: 0; @@ -296,7 +298,7 @@ input[type="file"] + .error { text-align: left; display: block; cursor: pointer; - background-color: #eee; + background-color: var(--color-lightGray); height: 30px; line-height: 30px; margin: 0; @@ -976,6 +978,7 @@ input:invalid { bottom: initial; width: 390px; border-radius: 5px; + border: 1px solid var(--color-lightGray); } } @media all and (orientation:portrait) { diff --git a/umap/static/umap/img/24-white.svg b/umap/static/umap/img/24-white.svg index ac571991..b1792024 100644 --- a/umap/static/umap/img/24-white.svg +++ b/umap/static/umap/img/24-white.svg @@ -57,8 +57,8 @@ - - + + diff --git a/umap/static/umap/img/source/24-white.svg b/umap/static/umap/img/source/24-white.svg index 149eb62e..80d9b3e6 100644 --- a/umap/static/umap/img/source/24-white.svg +++ b/umap/static/umap/img/source/24-white.svg @@ -2,7 +2,7 @@ - + @@ -78,8 +78,8 @@ - - + + diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js index c2d5d905..5eafc43c 100644 --- a/umap/static/umap/js/umap.controls.js +++ b/umap/static/umap/js/umap.controls.js @@ -29,11 +29,23 @@ U.ImportAction = U.BaseAction.extend({ }, }) +U.EditCaptionAction = U.BaseAction.extend({ + options: { + helpMenu: true, + className: 'umap-control-caption dark', + tooltip: L._('Edit map name and caption'), + }, + + addHooks: function () { + this.map.editCaption() + }, +}) + U.EditPropertiesAction = U.BaseAction.extend({ options: { helpMenu: true, className: 'update-map-settings dark', - tooltip: L._('Edit map properties'), + tooltip: L._('Map advanced properties'), }, addHooks: function () { @@ -268,12 +280,8 @@ U.ContinueLineAction = U.BaseVertexAction.extend({ }) // Leaflet.Toolbar doesn't allow twice same toolbar class… -U.SettingsToolbar = L.Toolbar.Control.extend({ - addTo: function (map) { - if (map.options.editMode !== 'advanced') return - L.Toolbar.Control.prototype.addTo.call(this, map) - }, -}) +U.ImportToolbar = L.Toolbar.Control.extend({}) +U.SettingsToolbar = L.Toolbar.Control.extend({}) U.DrawToolbar = L.Toolbar.Control.extend({ initialize: function (options) { L.Toolbar.Control.prototype.initialize.call(this, options) @@ -512,13 +520,12 @@ U.DataLayersControl = L.Control.Button.extend({ U.CaptionControl = L.Control.Button.extend({ options: { position: 'topright', - className: 'umap-control-caption', + className: 'umap-control-caption hide-on-edit', title: L._('About'), }, onClick: function () { - if (this.map.editEnabled) this.map.editCaption() - else this.map.displayCaption() + this.map.displayCaption() }, }) @@ -532,14 +539,25 @@ U.DataLayer.include({ renderToolbox: function (container) { L.DomUtil.element( 'i', - { className: 'umap-icon-16 drag-handle show-on-edit', title: L._('Drag to reorder') }, + { + className: 'umap-icon-16 drag-handle show-on-edit', + title: L._('Drag to reorder'), + }, container ) const toggle = L.DomUtil.create('i', 'umap-icon-16 layer-toggle', container), zoomTo = L.DomUtil.create('i', 'umap-icon-16 layer-zoom_to', container), edit = L.DomUtil.create('i', 'umap-icon-16 layer-edit show-on-edit', container), - table = L.DomUtil.create('i', 'umap-icon-16 layer-table-edit show-on-edit', container), - remove = L.DomUtil.create('i', 'umap-icon-16 layer-delete show-on-edit', container) + table = L.DomUtil.create( + 'i', + 'umap-icon-16 layer-table-edit show-on-edit', + container + ), + remove = L.DomUtil.create( + 'i', + 'umap-icon-16 layer-delete show-on-edit', + container + ) zoomTo.title = L._('Zoom to layer extent') toggle.title = L._('Show/hide layer') edit.title = L._('Edit') diff --git a/umap/static/umap/js/umap.js b/umap/static/umap/js/umap.js index 16691541..b1738135 100644 --- a/umap/static/umap/js/umap.js +++ b/umap/static/umap/js/umap.js @@ -329,16 +329,19 @@ U.Map = L.Map.extend({ if (this.hasEditMode() && !this.options.noControl) { new U.EditControl(this).addTo(this) - new U.DrawToolbar({ map: this }).addTo(this) - const editActions = [ - U.ImportAction, + U.EditCaptionAction, U.EditPropertiesAction, U.ChangeTileLayerAction, U.UpdateExtentAction, U.UpdatePermsAction, ] - new U.SettingsToolbar({ actions: editActions }).addTo(this) + if (this.options.editMode === 'advanced') { + new U.SettingsToolbar({ actions: editActions }).addTo(this) + new U.ImportToolbar({ actions: [U.ImportAction] }).addTo(this) + } + + new U.DrawToolbar({ map: this }).addTo(this) } this._controls.zoom = new L.Control.Zoom({ zoomInTitle: L._('Zoom in'), @@ -1537,7 +1540,7 @@ U.Map = L.Map.extend({ if (this.options.editMode !== 'advanced') return const container = L.DomUtil.create('div', 'umap-edit-container') const title = L.DomUtil.create('h3', '', container) - title.textContent = L._('Edit map properties') + title.textContent = L._('Map advanced properties') this._editControls(container) this._editShapeProperties(container) this._editDefaultProperties(container) diff --git a/umap/static/umap/map.css b/umap/static/umap/map.css index 648b684c..672392ce 100644 --- a/umap/static/umap/map.css +++ b/umap/static/umap/map.css @@ -287,8 +287,8 @@ ul.photon-autocomplete { .leaflet-control-toolbar > li > .leaflet-toolbar-icon, .umap-toolbar a, .umap-toolbar a:hover { - height: 40px; - width: 40px; + height: 36px; + width: 36px; display: none; margin-top: 0; vertical-align: top; @@ -922,21 +922,20 @@ ul.photon-autocomplete { .umap-edit-enabled .show-on-edit.block { display: block!important; } +.umap-edit-enabled .hide-on-edit { + display: none!important; +} /* ********************************* */ /* Browser panel */ /* ********************************* */ -.umap-control-caption [type="button"], .umap-control-browse [type="button"] { - background-image: url('./img/24.svg'); - width: 40px; - height: 40px; - background-position: -34px -70px; - background-size: 180px; + background-position: -36px -72px; } +a.umap-control-caption, .umap-control-caption [type="button"] { - background-position: -70px -70px; + background-position: -72px -72px; } .umap-edit-enabled .umap-control-caption [type="button"], .umap-edit-enabled .umap-control-browse [type="button"] { @@ -981,7 +980,7 @@ i.drag-handle { border: 1px solid #d3d3d3; } .umap-browser.dark .datalayer ul { - border: 1px solid #2c3233; + border: 1px solid #232729; } .umap-browser h5, .umap-facet-search h5 { margin-bottom: 0; @@ -993,7 +992,7 @@ i.drag-handle { color: #666; } .umap-browser.dark h5 { - background-color: #2c3233; + background-color: #232729; color: white; } .umap-browser h5 span { @@ -1025,6 +1024,9 @@ i.drag-handle { text-align: center; margin-left: 5px; } +.umap-browser.dark .datalayer i.feature-color { + box-shadow: 0 0 2px 0 #999 inset; +} .umap-browser .datalayer .feature-color img { width: 24px; } diff --git a/umap/tests/integration/test_anonymous_owned_map.py b/umap/tests/integration/test_anonymous_owned_map.py index 119547eb..70b90972 100644 --- a/umap/tests/integration/test_anonymous_owned_map.py +++ b/umap/tests/integration/test_anonymous_owned_map.py @@ -34,7 +34,7 @@ def test_map_load_with_owner(anonymap, live_server, owner_session): expect(save).to_be_visible() add_marker = owner_session.get_by_title("Draw a marker") expect(add_marker).to_be_visible() - edit_settings = owner_session.get_by_title("Edit map properties") + edit_settings = owner_session.get_by_title("Map advanced properties") expect(edit_settings).to_be_visible() edit_permissions = owner_session.get_by_title("Update permissions and editors") expect(edit_permissions).to_be_visible() @@ -65,7 +65,7 @@ def test_map_load_with_anonymous_but_editable_layer( expect(save).to_be_visible() add_marker = page.get_by_title("Draw a marker") expect(add_marker).to_be_visible() - edit_settings = page.get_by_title("Edit map properties") + edit_settings = page.get_by_title("Map advanced properties") expect(edit_settings).to_be_hidden() edit_permissions = page.get_by_title("Update permissions and editors") expect(edit_permissions).to_be_hidden() diff --git a/umap/tests/integration/test_owned_map.py b/umap/tests/integration/test_owned_map.py index 31ea9087..e30b3ba6 100644 --- a/umap/tests/integration/test_owned_map.py +++ b/umap/tests/integration/test_owned_map.py @@ -22,7 +22,7 @@ def test_map_update_with_owner(map, live_server, login): expect(save).to_be_visible() add_marker = page.get_by_title("Draw a marker") expect(add_marker).to_be_visible() - edit_settings = page.get_by_title("Edit map properties") + edit_settings = page.get_by_title("Map advanced properties") expect(edit_settings).to_be_visible() edit_permissions = page.get_by_title("Update permissions and editors") expect(edit_permissions).to_be_visible() @@ -49,7 +49,7 @@ def test_map_update_with_anonymous_but_editable_datalayer( enable.click() add_marker = page.get_by_title("Draw a marker") expect(add_marker).to_be_visible() - edit_settings = page.get_by_title("Edit map properties") + edit_settings = page.get_by_title("Map advanced properties") expect(edit_settings).to_be_hidden() edit_permissions = page.get_by_title("Update permissions and editors") expect(edit_permissions).to_be_hidden() @@ -97,7 +97,7 @@ def test_map_update_with_editor(map, live_server, login, user): expect(save).to_be_visible() add_marker = page.get_by_title("Draw a marker") expect(add_marker).to_be_visible() - edit_settings = page.get_by_title("Edit map properties") + edit_settings = page.get_by_title("Map advanced properties") expect(edit_settings).to_be_visible() edit_permissions = page.get_by_title("Update permissions and editors") expect(edit_permissions).to_be_visible() @@ -126,7 +126,7 @@ def test_permissions_form_with_editor(map, datalayer, live_server, login, user): def test_owner_has_delete_map_button(map, live_server, login): page = login(map.owner) page.goto(f"{live_server.url}{map.get_absolute_url()}?edit") - settings = page.get_by_title("Edit map properties") + settings = page.get_by_title("Map advanced properties") expect(settings).to_be_visible() settings.click() advanced = page.get_by_text("Advanced actions") @@ -154,7 +154,7 @@ def test_editor_do_not_have_delete_map_button(map, live_server, login, user): map.save() page = login(user) page.goto(f"{live_server.url}{map.get_absolute_url()}?edit") - settings = page.get_by_title("Edit map properties") + settings = page.get_by_title("Map advanced properties") expect(settings).to_be_visible() settings.click() advanced = page.get_by_text("Advanced actions") diff --git a/umap/tests/integration/test_picto.py b/umap/tests/integration/test_picto.py index 192f28e4..808a9d04 100644 --- a/umap/tests/integration/test_picto.py +++ b/umap/tests/integration/test_picto.py @@ -44,7 +44,7 @@ def test_can_change_picto_at_map_level(openmap, live_server, page, pictos): expect(marker).to_have_count(1) # Should have default img expect(marker).to_have_attribute("src", "/static/umap/img/marker.svg") - edit_settings = page.get_by_title("Edit map properties") + edit_settings = page.get_by_title("Map advanced properties") expect(edit_settings).to_be_visible() edit_settings.click() shape_settings = page.get_by_text("Default shape properties") @@ -152,7 +152,7 @@ def test_can_use_remote_url_as_picto(openmap, live_server, page, pictos): expect(marker).to_have_count(1) # Should have default img expect(marker).to_have_attribute("src", "/static/umap/img/marker.svg") - edit_settings = page.get_by_title("Edit map properties") + edit_settings = page.get_by_title("Map advanced properties") expect(edit_settings).to_be_visible() edit_settings.click() shape_settings = page.get_by_text("Default shape properties") @@ -191,7 +191,7 @@ def test_can_use_char_as_picto(openmap, live_server, page, pictos): marker = page.locator(".umap-div-icon span") # Should have default img, so not a span expect(marker).to_have_count(0) - edit_settings = page.get_by_title("Edit map properties") + edit_settings = page.get_by_title("Map advanced properties") expect(edit_settings).to_be_visible() edit_settings.click() shape_settings = page.get_by_text("Default shape properties") From a516cbd2a35cc0ebd3899b036835fc4e8998643f Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Wed, 13 Mar 2024 19:02:46 +0100 Subject: [PATCH 15/44] chore: panel in condensed mode by default --- umap/static/umap/js/umap.ui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/umap/static/umap/js/umap.ui.js b/umap/static/umap/js/umap.ui.js index ceaca6a2..8c54e5aa 100644 --- a/umap/static/umap/js/umap.ui.js +++ b/umap/static/umap/js/umap.ui.js @@ -5,7 +5,7 @@ U.UI = L.Evented.extend({ ALERTS: Array(), ALERT_ID: null, TOOLTIP_ID: null, - PANEL_MODE: 'expanded', + PANEL_MODE: 'condensed', initialize: function (parent) { this.parent = parent From 1e2d990a3ab3bd30b66b8bed347db80aa0a1ff09 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Thu, 14 Mar 2024 20:22:57 +0100 Subject: [PATCH 16/44] chore: start moving icon related CSS rules to a dedicated file --- umap/static/umap/base.css | 17 ---- umap/static/umap/content.css | 12 +-- umap/static/umap/css/icon.css | 95 ++++++++++++++++++++ umap/static/umap/img/16-white.svg | 5 +- umap/static/umap/img/16.svg | 5 +- umap/static/umap/img/24.svg | 4 +- umap/static/umap/img/source/16-white.svg | 7 +- umap/static/umap/img/source/16.svg | 9 +- umap/static/umap/img/source/24.svg | 6 +- umap/static/umap/js/modules/browser.js | 12 +-- umap/static/umap/js/umap.controls.js | 36 ++------ umap/static/umap/js/umap.core.js | 11 +++ umap/static/umap/js/umap.features.js | 7 +- umap/static/umap/js/umap.importer.js | 2 +- umap/static/umap/js/umap.js | 7 +- umap/static/umap/js/umap.layer.js | 2 +- umap/static/umap/js/umap.permissions.js | 7 +- umap/static/umap/js/umap.share.js | 5 +- umap/static/umap/js/umap.tableeditor.js | 2 +- umap/static/umap/map.css | 107 ----------------------- umap/static/umap/test/TableEditor.js | 2 +- umap/templates/umap/css.html | 1 + 22 files changed, 158 insertions(+), 203 deletions(-) create mode 100644 umap/static/umap/css/icon.css diff --git a/umap/static/umap/base.css b/umap/static/umap/base.css index 8283cb54..09cb6be0 100644 --- a/umap/static/umap/base.css +++ b/umap/static/umap/base.css @@ -897,23 +897,6 @@ input:invalid { /* *********** */ /* Close link */ /* *********** */ -.umap-resize-icon, -.umap-close-icon { - background-repeat: no-repeat; - background-image: url('./img/16.svg'); - background-position: -26px -6px; - display: inline; - padding: 0 10px; - vertical-align: middle; - line-height: 24px; -} -.umap-resize-icon { - background-position: -74px -150px; -} -.dark .umap-resize-icon, -.dark .umap-close-icon { - background-image: url('./img/16-white.svg'); -} #umap-alert-container .umap-close-link { color: #fff; float: right; diff --git a/umap/static/umap/content.css b/umap/static/umap/content.css index f1ebe99a..17bb390c 100644 --- a/umap/static/umap/content.css +++ b/umap/static/umap/content.css @@ -357,22 +357,22 @@ ul.umap-autocomplete { width: 36px; margin: 3px; } -.icon-view { +.content .icon-view { background-image: url('./img/icon-view.svg'); } -.icon-share { +.content .icon-share { background-image: url('./img/icon-share.svg'); } -.icon-edit { +.content .icon-edit { background-image: url('./img/icon-edit.svg'); } -.icon-download { +.content .icon-download { background-image: url('./img/icon-download.svg'); } -.icon-duplicate { +.content .icon-duplicate { background-image: url('./img/icon-duplicate.svg'); } -.icon-delete { +.content .icon-delete { background-image: url('./img/icon-delete.svg'); } .table-header { diff --git a/umap/static/umap/css/icon.css b/umap/static/umap/css/icon.css new file mode 100644 index 00000000..87257be2 --- /dev/null +++ b/umap/static/umap/css/icon.css @@ -0,0 +1,95 @@ +.icon { + background-repeat: no-repeat; + display: inline-block; + padding: 0 10px; + vertical-align: middle; +} +.icon-16 { + background-image: url('../img/16.svg'); + height: 24px; + line-height: 24px; +} +.icon + span { + margin-left: 10px; +} +.dark .icon-16 { + background-image: url('../img/16-white.svg'); +} +.icon-add { + background-position: -26px -30px; +} +.icon-back { + background-position: -122px -144px; +} +.icon-caption { + background-position: -98px -24px; +} +.icon-close { + background-position: -26px 0px; +} +.icon-delete { + background-position: -121px -49px; +} +.icon-drag { + background-position: -72px -73px; + cursor: move; + margin-right: 10px; +} +.icon-eye { + background-position: -49px -26px; +} +.icon-edit { + background-position: -51px -49px; +} +.icon-key { + background-position: -144px -121px; +} +.icon-layers { + background-position: -96px -120px; +} +.icon-list { + background-position: -28px -99px; +} +.icon-marker { + background-position: -72px -120px; +} +.icon-polygon { + background-position: -24px -119px; +} +.icon-polyline { + background-position: 0 -119px; +} +.icon-resize { + background-position: -74px -145px; +} +.icon-search { + background-position: -27px -120px; +} +.icon-settings { + background-position: -27px -93px; +} +.icon-share { + background-position: 0px -120px; +} +.icon-table { + background-position: -50px -1px; +} +.readonly .icon-table, +.off .icon-table { + background-position: -74px -1px; +} +.remotelayer .icon-table { + display: none !important; +} +.icon-tilelayer { + background-position: -98px -141px; +} +.icon-upload { + background-position: -144px -97px; +} +.icon-zoom { + background-position: -1px -49px; +} +.off .icon-zoom { + background-position: -25px -54px; +} diff --git a/umap/static/umap/img/16-white.svg b/umap/static/umap/img/16-white.svg index 1de49bb5..88eb6924 100644 --- a/umap/static/umap/img/16-white.svg +++ b/umap/static/umap/img/16-white.svg @@ -186,10 +186,7 @@ - - - - + diff --git a/umap/static/umap/img/16.svg b/umap/static/umap/img/16.svg index 0367ddfd..bc8233a7 100644 --- a/umap/static/umap/img/16.svg +++ b/umap/static/umap/img/16.svg @@ -178,8 +178,9 @@ - - + + + diff --git a/umap/static/umap/img/24.svg b/umap/static/umap/img/24.svg index b4b8f678..a4fc8d62 100644 --- a/umap/static/umap/img/24.svg +++ b/umap/static/umap/img/24.svg @@ -82,8 +82,8 @@ - - + + diff --git a/umap/static/umap/img/source/16-white.svg b/umap/static/umap/img/source/16-white.svg index 11dabbaf..943a252c 100644 --- a/umap/static/umap/img/source/16-white.svg +++ b/umap/static/umap/img/source/16-white.svg @@ -16,7 +16,7 @@ - + @@ -208,10 +208,7 @@ - - - - + diff --git a/umap/static/umap/img/source/16.svg b/umap/static/umap/img/source/16.svg index 54925b08..ed3d4715 100644 --- a/umap/static/umap/img/source/16.svg +++ b/umap/static/umap/img/source/16.svg @@ -10,7 +10,7 @@ - + @@ -197,8 +197,11 @@ - - + + + + + diff --git a/umap/static/umap/img/source/24.svg b/umap/static/umap/img/source/24.svg index 432831c0..0d463125 100644 --- a/umap/static/umap/img/source/24.svg +++ b/umap/static/umap/img/source/24.svg @@ -2,7 +2,7 @@ - + @@ -102,8 +102,8 @@ - - + + diff --git a/umap/static/umap/js/modules/browser.js b/umap/static/umap/js/modules/browser.js index bbb6cda4..50cc4b11 100644 --- a/umap/static/umap/js/modules/browser.js +++ b/umap/static/umap/js/modules/browser.js @@ -19,10 +19,10 @@ export default class Browser { if (filter && !feature.matchFilter(filter, this.filterKeys)) return if (this.options.inBbox && !feature.isOnScreen(this.bounds)) return const feature_li = DomUtil.create('li', `${feature.getClassName()} feature`), - zoom_to = DomUtil.create('i', 'umap-icon-16 feature-zoom_to', feature_li), - edit = DomUtil.create('i', 'umap-icon-16 show-on-edit feature-edit', feature_li), - del = DomUtil.create('i', 'umap-icon-16 show-on-edit feature-delete', feature_li), - colorBox = DomUtil.create('i', 'umap-icon-16 feature-color', feature_li), + zoom_to = DomUtil.create('i', 'icon icon-16 icon-zoom', feature_li), + edit = DomUtil.create('i', 'icon icon-16 show-on-edit icon-edit', feature_li), + del = DomUtil.create('i', 'icon icon-16 show-on-edit icon-delete', feature_li), + colorBox = DomUtil.create('i', 'icon icon-16 feature-color', feature_li), title = DomUtil.create('span', 'feature-title', feature_li), symbol = feature._getIconUrl ? U.Icon.prototype.formatUrl(feature._getIconUrl(), feature) @@ -101,7 +101,7 @@ export default class Browser { const headline = parent.querySelector('h5') const toggleList = () => parent.classList.toggle('show-list') headline.innerHTML = '' - const toggle = DomUtil.create('i', 'umap-icon-16 datalayer-toggle-list', headline) + const toggle = DomUtil.create('i', 'icon icon-16 datalayer-toggle-list', headline) DomEvent.on(toggle, 'click', toggleList) datalayer.renderToolbox(headline) const name = DomUtil.create('span', 'datalayer-name', headline) @@ -146,7 +146,7 @@ export default class Browser { // https://github.com/Leaflet/Leaflet/pull/9052 DomEvent.disableClickPropagation(container) - const title = DomUtil.add('h3', '', container, translate('Browse data')) + DomUtil.createTitle(container, translate('Browse data'), 'layers') const formContainer = DomUtil.create('div', '', container) const dataContainer = DomUtil.create('div', '', container) diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js index 5eafc43c..10c65b14 100644 --- a/umap/static/umap/js/umap.controls.js +++ b/umap/static/umap/js/umap.controls.js @@ -537,27 +537,11 @@ U.DataLayer.include({ }, renderToolbox: function (container) { - L.DomUtil.element( - 'i', - { - className: 'umap-icon-16 drag-handle show-on-edit', - title: L._('Drag to reorder'), - }, - container - ) - const toggle = L.DomUtil.create('i', 'umap-icon-16 layer-toggle', container), - zoomTo = L.DomUtil.create('i', 'umap-icon-16 layer-zoom_to', container), - edit = L.DomUtil.create('i', 'umap-icon-16 layer-edit show-on-edit', container), - table = L.DomUtil.create( - 'i', - 'umap-icon-16 layer-table-edit show-on-edit', - container - ), - remove = L.DomUtil.create( - 'i', - 'umap-icon-16 layer-delete show-on-edit', - container - ) + const toggle = L.DomUtil.create('i', 'icon icon-16 icon-eye', container), + zoomTo = L.DomUtil.create('i', 'icon icon-16 icon-zoom', container), + edit = L.DomUtil.create('i', 'icon icon-16 icon-edit show-on-edit', container), + table = L.DomUtil.create('i', 'icon icon-16 icon-table show-on-edit', container), + remove = L.DomUtil.create('i', 'icon icon-16 icon-delete show-on-edit', container) zoomTo.title = L._('Zoom to layer extent') toggle.title = L._('Show/hide layer') edit.title = L._('Edit') @@ -690,8 +674,7 @@ const ControlsMixin = { displayCaption: function () { const container = L.DomUtil.create('div', 'umap-caption') - let title = L.DomUtil.create('h3', '', container) - title.textContent = this.options.name + L.DomUtil.createTitle(container, this.options.name, 'caption') this.permissions.addOwnerLink('h5', container) if (this.options.description) { const description = L.DomUtil.create('div', 'umap-map-description', container) @@ -985,8 +968,7 @@ U.TileLayerChooser = L.Control.extend({ openSwitcher: function (options) { const container = L.DomUtil.create('div', 'umap-tilelayer-switcher-container') - const title = L.DomUtil.create('h3', '', container) - title.textContent = L._('Change tilelayers') + L.DomUtil.createTitle(container, L._('Change tilelayers'), 'tilelayer') this._tilelayers_container = L.DomUtil.create('ul', '', container) this.buildList(options) this.map.ui.openPanel({ @@ -1179,8 +1161,8 @@ U.Search = L.PhotonSearch.extend({ formatResult: function (feature, el) { const self = this const tools = L.DomUtil.create('span', 'search-result-tools', el), - zoom = L.DomUtil.create('i', 'feature-zoom_to', tools), - edit = L.DomUtil.create('i', 'feature-edit show-on-edit', tools) + zoom = L.DomUtil.create('i', 'icon icon-16 icon-zoom', tools), + edit = L.DomUtil.create('i', 'icon icon-16 icon-edit show-on-edit', tools) zoom.title = L._('Zoom to this place') edit.title = L._('Save this location as new feature') // We need to use "mousedown" because Leaflet.Photon listen to mousedown diff --git a/umap/static/umap/js/umap.core.js b/umap/static/umap/js/umap.core.js index 474287dd..c451879f 100644 --- a/umap/static/umap/js/umap.core.js +++ b/umap/static/umap/js/umap.core.js @@ -117,6 +117,17 @@ L.DomUtil.createLink = (className, container, content, url, target, title) => { return el } +L.DomUtil.createIcon = (parent, name) => { + L.DomUtil.create('i', `icon icon-16 icon-${name}`, parent) +} + +L.DomUtil.createTitle = (parent, text, icon, tag = 'h3') => { + const title = L.DomUtil.create(tag, '', parent) + L.DomUtil.createIcon(title, icon) + L.DomUtil.add('span', '', title, text) + return title +} + L.DomUtil.createCopiableInput = (parent, label, value) => { const wrapper = L.DomUtil.add('div', 'copiable-input', parent) const labelEl = L.DomUtil.add('label', '', wrapper, label) diff --git a/umap/static/umap/js/umap.features.js b/umap/static/umap/js/umap.features.js index 58a27e41..517f321c 100644 --- a/umap/static/umap/js/umap.features.js +++ b/umap/static/umap/js/umap.features.js @@ -96,12 +96,7 @@ U.FeatureMixin = { edit: function (e) { if (!this.map.editEnabled || this.isReadOnly()) return const container = L.DomUtil.create('div', 'umap-feature-container') - L.DomUtil.add( - 'h3', - `umap-feature-properties ${this.getClassName()}`, - container, - L._('Feature properties') - ) + L.DomUtil.createTitle(container, L._('Feature properties'), this.getClassName()) let builder = new U.FormBuilder( this, diff --git a/umap/static/umap/js/umap.importer.js b/umap/static/umap/js/umap.importer.js index 0f1a1fdb..0400cd1c 100644 --- a/umap/static/umap/js/umap.importer.js +++ b/umap/static/umap/js/umap.importer.js @@ -7,7 +7,7 @@ U.Importer = L.Class.extend({ build: function () { this.container = L.DomUtil.create('div', 'umap-upload') - this.title = L.DomUtil.add('h3', '', this.container, L._('Import data')) + this.title = L.DomUtil.createTitle(this.container, L._('Import data'), 'upload') this.presetBox = L.DomUtil.create('div', 'formbox', this.container) this.presetSelect = L.DomUtil.create('select', '', this.presetBox) this.fileBox = L.DomUtil.create('div', 'formbox', this.container) diff --git a/umap/static/umap/js/umap.js b/umap/static/umap/js/umap.js index b1738135..a1b9ef54 100644 --- a/umap/static/umap/js/umap.js +++ b/umap/static/umap/js/umap.js @@ -1532,15 +1532,14 @@ U.Map = L.Map.extend({ ] const creditsBuilder = new U.FormBuilder(this, creditsFields) credits.appendChild(creditsBuilder.build()) - this.ui.openPanel({ data: { html: container }, className: 'dark' }) + this.editPanel.open({ data: { html: container } }) }, edit: function () { if (!this.editEnabled) return if (this.options.editMode !== 'advanced') return - const container = L.DomUtil.create('div', 'umap-edit-container') - const title = L.DomUtil.create('h3', '', container) - title.textContent = L._('Map advanced properties') + const container = L.DomUtil.create('div') + L.DomUtil.createTitle(container, L._('Map advanced properties'), 'settings') this._editControls(container) this._editShapeProperties(container) this._editDefaultProperties(container) diff --git a/umap/static/umap/js/umap.layer.js b/umap/static/umap/js/umap.layer.js index 7012b2d2..1ebc39e0 100644 --- a/umap/static/umap/js/umap.layer.js +++ b/umap/static/umap/js/umap.layer.js @@ -1211,7 +1211,7 @@ U.DataLayer = L.Evented.extend({ }, ], ] - const title = L.DomUtil.add('h3', '', container, L._('Layer properties')) + L.DomUtil.createTitle(container, L._('Layer properties'), 'layers') let builder = new U.FormBuilder(this, metadataFields, { callback: function (e) { if (e.helper.field === 'options.type') { diff --git a/umap/static/umap/js/umap.permissions.js b/umap/static/umap/js/umap.permissions.js index 9d01f668..6200a694 100644 --- a/umap/static/umap/js/umap.permissions.js +++ b/umap/static/umap/js/umap.permissions.js @@ -57,9 +57,9 @@ U.MapPermissions = L.Class.extend({ content: L._('Please save the map first'), level: 'info', }) - const container = L.DomUtil.create('div', 'permissions-panel'), - fields = [], - title = L.DomUtil.create('h3', '', container) + const container = L.DomUtil.create('div', 'permissions-panel') + const fields = [] + L.DomUtil.createTitle(container, L._('Update permissions'), 'key') if (this.isAnonymousMap()) { if (this.options.anonymous_edit_url) { const helpText = `${L._('Secret edit link:')}
${this.options.anonymous_edit_url @@ -103,7 +103,6 @@ U.MapPermissions = L.Class.extend({ { handler: 'ManageEditors', label: L._("Map's editors") }, ]) } - title.textContent = L._('Update permissions') const builder = new U.FormBuilder(this, fields) const form = builder.build() container.appendChild(form) diff --git a/umap/static/umap/js/umap.share.js b/umap/static/umap/js/umap.share.js index 3284df76..88a2d033 100644 --- a/umap/static/umap/js/umap.share.js +++ b/umap/static/umap/js/umap.share.js @@ -44,9 +44,8 @@ U.Share = L.Class.extend({ }, build: function () { - this.container = L.DomUtil.create('div', 'umap-share') - this.title = L.DomUtil.create('h3', '', this.container) - this.title.textContent = L._('Share and download') + this.container = L.DomUtil.create('div', '') + this.title = L.DomUtil.createTitle(this.container, L._('Share and download'), 'share') L.DomUtil.createCopiableInput( this.container, diff --git a/umap/static/umap/js/umap.tableeditor.js b/umap/static/umap/js/umap.tableeditor.js index 2c0a9bf4..d59fa704 100644 --- a/umap/static/umap/js/umap.tableeditor.js +++ b/umap/static/umap/js/umap.tableeditor.js @@ -100,7 +100,7 @@ U.TableEditor = L.Class.extend({ this.body.innerHTML = '' this.datalayer.eachLayer(this.renderRow, this) const addButton = L.DomUtil.create('li', 'add-property') - L.DomUtil.create('i', 'umap-icon-16 umap-add', addButton) + L.DomUtil.create('i', 'icon icon-16 icon-add', addButton) const label = L.DomUtil.create('span', '', addButton) label.textContent = label.title = L._('Add a new property') const addProperty = function () { diff --git a/umap/static/umap/map.css b/umap/static/umap/map.css index 672392ce..051e6844 100644 --- a/umap/static/umap/map.css +++ b/umap/static/umap/map.css @@ -316,58 +316,6 @@ ul.photon-autocomplete { .manage-datalayers { background-position: -36px -72px; } -.permissions-panel h3:before, -.umap-edit-container h3:before, -.umap-feature-properties:before, -.umap-layer-properties-container h3:before, -.umap-search h3:before, -.umap-share h3:before, -.umap-tilelayer-switcher-container h3:before, -.umap-upload h3:before { - height: 24px; - width: 24px; - background-repeat: no-repeat; - background-image: url('./img/16-white.svg'); - background-size: auto auto; - background-position: -98px -117px; - content: " "; - vertical-align: bottom; - display: inline-block; -} -.umap-edit-container h3:before { - background-position: -27px -93px; -} -.permissions-panel h3:before { - background-position: -144px -117px; -} -.umap-upload h3:before { - background-position: -144px -93px; -} -.umap-search h3:before { - background-image: url('./img/16.svg'); - background-position: -27px -117px; -} -.umap-share h3:before { - background-image: url('./img/16.svg'); - background-position: -4px -119px; -} -.dark .umap-tilelayer-switcher-container h3:before { - background-image: url('./img/16-white.svg'); - background-position: -98px -141px; -} -.umap-tilelayer-switcher-container h3:before { - background-image: url('./img/16.svg'); - background-position: -98px -141px; -} -.umap-feature-properties.marker:before { - background-position: -72px -117px; -} -.umap-feature-properties.polyline:before { - background-position: 0 -117px; -} -.umap-feature-properties.polygon:before { - background-position: -24px -117px; -} .umap-toolbar .update-map-permissions, .update-map-permissions { background-position: -36px -36px; @@ -844,15 +792,6 @@ ul.photon-autocomplete { .off .layer-toggle { background-position: -73px -31px; } -.feature-zoom_to { - background-position: -1px -54px; -} -.layer-zoom_to { - background-position: -1px -54px; -} -.layer-table-edit { - background-position: -50px -1px; -} .feature-delete, .layer-delete { background-position: -122px -49px; @@ -864,17 +803,10 @@ ul.photon-autocomplete { .umap-toggle-edit { background-position: -44px -48px; } -.readonly .layer-table-edit, -.off .layer-table-edit { - background-position: -74px -1px; -} .readonly .layer-edit, .off .layer-edit { background-position: -50px -73px; } -.off .layer-zoom_to { - background-position: -25px -54px; -} .readonly .layer-delete, .off .layer-delete { background-position: -122px -121px; @@ -962,11 +894,6 @@ a.umap-control-caption, .show-list ul { display: block; } -i.drag-handle { - background-position: -72px -73px; - cursor: move; - margin-right: 10px; -} .umap-browser .off .feature { display: none; @@ -1121,40 +1048,6 @@ i.drag-handle { .umap-table-editor .thead .tcell:hover span { display: none; } -.remotelayer .layer-table-edit { - display: none !important; -} - -/* ********************************* */ -/* Icons */ -/* ********************************* */ -.umap-icon-16 { - background-repeat: no-repeat; - background-image: url('./img/16.svg'); - display: inline; - height: 24px; - line-height: 24px; - padding: 0 10px; - vertical-align: middle; -} -.dark .umap-icon-16 { - background-image: url('./img/16-white.svg'); -} -.umap-add { - background-position: -26px -30px; -} -.umap-list { - background-position: -28px -99px; -} -.umap-back { - background-position: -122px -150px; -} -.umap-list-white { - background-position: -92px -168px; -} -.umap-caption { - background-position: -99px -28px; -} /* ********************************* */ /* Tilelayer switcher */ diff --git a/umap/static/umap/test/TableEditor.js b/umap/static/umap/test/TableEditor.js index 52f82898..88d828bb 100644 --- a/umap/static/umap/test/TableEditor.js +++ b/umap/static/umap/test/TableEditor.js @@ -27,7 +27,7 @@ describe('L.TableEditor', () => { it('should exist table click on edit mode', () => { button = qs( - '#browse_data_toggle_' + L.stamp(datalayer) + ' .layer-table-edit' + '#browse_data_toggle_' + L.stamp(datalayer) + ' .icon-table' ) expect(button).to.be.ok }) diff --git a/umap/templates/umap/css.html b/umap/templates/umap/css.html index 8c1af26d..623d1e6d 100644 --- a/umap/templates/umap/css.html +++ b/umap/templates/umap/css.html @@ -23,6 +23,7 @@ href="{% static 'umap/vendors/iconlayers/iconLayers.css' %}" /> + From c4e86c4ab94ff9e62b06c270414a458ac86b9652 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Thu, 14 Mar 2024 20:29:28 +0100 Subject: [PATCH 17/44] wip: move panel to a dedicated module --- umap/static/umap/base.css | 41 -------- umap/static/umap/css/panel.css | 120 ++++++++++++++++++++++++ umap/static/umap/js/modules/browser.js | 78 ++------------- umap/static/umap/js/modules/global.js | 5 + umap/static/umap/js/modules/panel.js | 81 ++++++++++++++++ umap/static/umap/js/umap.controls.js | 93 ++++++++++++++---- umap/static/umap/js/umap.features.js | 6 +- umap/static/umap/js/umap.importer.js | 2 +- umap/static/umap/js/umap.js | 23 ++--- umap/static/umap/js/umap.layer.js | 3 +- umap/static/umap/js/umap.permissions.js | 2 +- umap/static/umap/js/umap.popup.js | 4 +- umap/static/umap/js/umap.share.js | 2 +- umap/static/umap/js/umap.ui.js | 67 ------------- umap/static/umap/map.css | 7 +- umap/templates/umap/css.html | 1 + 16 files changed, 311 insertions(+), 224 deletions(-) create mode 100644 umap/static/umap/css/panel.css create mode 100644 umap/static/umap/js/modules/panel.js diff --git a/umap/static/umap/base.css b/umap/static/umap/base.css index 09cb6be0..995f95b7 100644 --- a/umap/static/umap/base.css +++ b/umap/static/umap/base.css @@ -544,7 +544,6 @@ i.info { .permissions-panel, .umap-upload, .umap-share, -.umap-edit-container, .umap-datalayer-container, .umap-layer-properties-container, .umap-browse-data, @@ -711,9 +710,6 @@ input[type=hidden].blur + [type="button"] { .leaflet-right { transition: all .7s; } -.umap-ui .leaflet-right { - right: 400px; -} #umap-panel, #umap-alert-container, #umap-tooltip-container { @@ -941,44 +937,7 @@ input:invalid { /* *********** */ /* Mobile */ /* *********** */ -@media all and (orientation:landscape) { - .umap-edit-enabled #umap-panel { - top: 46px; - } - #umap-panel { - width: 400px; - right: -400px; - top: 0; - } - .umap-ui #umap-panel { - right: 0; - visibility: visible; - } - #umap-panel.condensed { - margin-top: 10px; - margin-right: 10px; - max-height: 500px; - bottom: initial; - width: 390px; - border-radius: 5px; - border: 1px solid var(--color-lightGray); - } -} @media all and (orientation:portrait) { - #umap-panel { - height: 50%; - max-height: 400px; - width: 100%; - bottom: 0; - right: -100%; - } - .umap-ui #umap-panel { - right: 0; - visibility: visible; - } - .umap-ui .leaflet-right { - right: 0; - } #umap-alert-container { width: 100%; left: 0; diff --git a/umap/static/umap/css/panel.css b/umap/static/umap/css/panel.css new file mode 100644 index 00000000..c84c6ef9 --- /dev/null +++ b/umap/static/umap/css/panel.css @@ -0,0 +1,120 @@ +.panel { + /* Added for playwright to consider the element as non visible */ + /* as being out of the visible viewport is not enough */ + visibility: hidden; + position: absolute; + bottom: 20px; + overflow-x: auto; + z-index: 1010; + background-color: #fff; + opacity: 0.98; + cursor: initial; + border-radius: 5px; + border: 1px solid var(--color-lightGray); +} +.panel.dark { + border-left: 1px solid #222; + background-color: var(--color-darkGray); + color: #efefef; +} +.panel.fullwidth { + width: 100%; + right: -100%; + z-index: 10000; + padding-left: 0; + padding-right: 0; +} +.umap-caption-bar-enabled .panel { + bottom: 46px; +} +.panel { + -moz-box-sizing:border-box; + -webkit-box-sizing:border-box; + box-sizing: border-box; +} +.panel .umap-popup-content img { + /* See https://github.com/Leaflet/Leaflet/commit/61d746818b99d362108545c151a27f09d60960ee#commitcomment-6061847 */ + max-width: 99% !important; +} +.panel .umap-popup-content { + max-height: inherit; +} +.panel .body { + clear: both; + height: calc(100% - 32px); /* Minus size of toolbox */ + padding: 10px; +} +.panel .toolbox { + padding: 5px 10px; + overflow: hidden; + display: flex; + flex-direction: row-reverse; + font-size: 10px; + justify-content: flex-start; + gap: 5px; + line-height: 2.2em; +} +.panel.dark .toolbox { + background-color: var(--color-darkGray); + border-bottom: 1px solid #232729; +} +.panel .toolbox li { + cursor: pointer; + display: inline; + padding: 0 2px; + border: 1px solid #b6b6b3; + border-radius: 2px; +} +.panel.dark .toolbox +.panel.dark .toolbox li { + color: #d3dfeb; + border: 1px solid #202425; +} +.panel .toolbox li:hover { + background-color: #d4d4d2; +} +.panel.dark .toolbox li:hover { + background-color: #353c3e; +} +@media all and (orientation:landscape) { + .panel { + top: 0; + margin-top: 10px; + width: 390px; + } + .panel.condensed { + max-height: 500px; + bottom: initial; + } + .panel.right { + margin-right: 10px; + right: -400px; + } + .panel.left { + left: -400px; + } + .panel.left.on { + left: 60px; + visibility: visible; + } + .panel.right.on { + right: 40px; + visibility: visible; + } + .umap-edit-enabled .panel { + top: 46px; + } +} +@media all and (orientation:portrait) { + .panel { + height: 50%; + max-height: 400px; + width: 100%; + bottom: 0; + right: -100%; + } + .panel.on { + right: 0; + visibility: visible; + } +} diff --git a/umap/static/umap/js/modules/browser.js b/umap/static/umap/js/modules/browser.js index 50cc4b11..fe1bc092 100644 --- a/umap/static/umap/js/modules/browser.js +++ b/umap/static/umap/js/modules/browser.js @@ -1,13 +1,10 @@ import { DomUtil, DomEvent } from '../../vendors/leaflet/leaflet-src.esm.js' -import Orderable from './orderable.js' -import {translate} from './i18n.js' +import { translate } from './i18n.js' export default class Browser { constructor(map) { this.map = map this.map.on('moveend', this.onMoveEnd, this) - this.map.on('edit:enabled', this.onEnableEdit, this) - this.map.on('edit:disabled', this.onDisableEdit, this) this.options = { filter: '', inBbox: false, @@ -72,13 +69,9 @@ export default class Browser { } addDataLayer(datalayer, parent) { - let className = `orderable datalayer ${datalayer.getHidableClass()}` - if (this.map.ui.PANEL_MODE !== 'condensed') className += ' show-list' - const container = DomUtil.create( - 'div', - className, - parent - ), + let className = `datalayer ${datalayer.getHidableClass()}` + if (this.map.panel.MODE !== 'condensed') className += ' show-list' + const container = DomUtil.create('div', className, parent), headline = DomUtil.create('h5', '', container) container.id = this.datalayerId(datalayer) const ul = DomUtil.create('ul', '', container) @@ -87,7 +80,6 @@ export default class Browser { this.map.ui.once('panel:closed', () => { datalayer.off('datachanged', this.onDataLayerChanged, this) }) - container.dataset.id = L.stamp(datalayer) } updateDatalayer(datalayer) { @@ -125,7 +117,7 @@ export default class Browser { }) } - isOpen () { + isOpen() { return !!document.querySelector('.umap-browser') } @@ -160,70 +152,19 @@ export default class Browser { }) formContainer.appendChild(builder.build()) - const addButton = L.DomUtil.create('li', 'add-datalayer show-on-edit') - L.DomUtil.create('i', 'umap-icon-16 umap-add', addButton) - const label = L.DomUtil.create('span', '', addButton) - label.textContent = label.title = L._('Add a layer') - const addProperty = function () { - const newName = prompt(L._('Please enter the name of the property')) - if (!newName || !this.validateName(newName)) return - this.datalayer.indexProperty(newName) - this.edit() - } - L.DomEvent.on(addButton, 'click', this.newDataLayer, this) - - - let className = 'umap-browser' - if (this.map.editEnabled) className += ' dark' - this.map.ui.openPanel({ + this.map.panel.open({ data: { html: container }, - className: className, - actions: [addButton] + className: 'umap-browser', }) this.map.eachBrowsableDataLayer((datalayer) => { this.addDataLayer(datalayer, dataContainer) }) - - // After datalayers have been added. - const orderable = new Orderable(dataContainer, L.bind(this.onReorder, this)) } - newDataLayer () { - const datalayer = this.map.createDataLayer({}) - datalayer.edit() - } - - - onReorder(src, dst, initialIndex, finalIndex) { - const layer = this.map.datalayers[src.dataset.id], - other = this.map.datalayers[dst.dataset.id], - minIndex = Math.min(layer.getRank(), other.getRank()), - maxIndex = Math.max(layer.getRank(), other.getRank()) - if (finalIndex === 0) layer.bringToTop() - else if (finalIndex > initialIndex) layer.insertBefore(other) - else layer.insertAfter(other) - this.map.eachDataLayerReverse((datalayer) => { - if (datalayer.getRank() >= minIndex && datalayer.getRank() <= maxIndex) - datalayer.isDirty = true - }) - this.map.indexDatalayers() - } - - onEnableEdit () { - if (!this.isOpen()) return - this.map.ui._panel.classList.add('dark') - } - - onDisableEdit () { - if (!this.isOpen()) return - this.map.ui._panel.classList.remove('dark') - } - - static backButton (map) { + static backButton(map) { const button = L.DomUtil.create('li', '') - L.DomUtil.create('i', 'umap-icon-16 umap-back', button) - const label = L.DomUtil.create('span', '', button) + L.DomUtil.create('i', 'icon icon-16 icon-back', button) button.title = L._('Back to browser') // Fixme: remove me when this is merged and released // https://github.com/Leaflet/Leaflet/pull/9052 @@ -231,5 +172,4 @@ export default class Browser { L.DomEvent.on(button, 'click', map.openBrowser, map) return button } - } diff --git a/umap/static/umap/js/modules/global.js b/umap/static/umap/js/modules/global.js index c432771e..708d9a15 100644 --- a/umap/static/umap/js/modules/global.js +++ b/umap/static/umap/js/modules/global.js @@ -1,8 +1,10 @@ import URLs from './urls.js' import Browser from './browser.js' +import { Panel, EditPanel } from './panel.js' import * as Utils from './utils.js' import { SCHEMA } from './schema.js' import { Request, ServerRequest, RequestError, HTTPError, NOKError } from './request.js' +import Orderable from './orderable.js' // Import modules and export them to the global scope. // For the not yet module-compatible JS out there. @@ -15,6 +17,9 @@ window.U = { HTTPError, NOKError, Browser, + Panel, + EditPanel, Utils, SCHEMA, + Orderable, } diff --git a/umap/static/umap/js/modules/panel.js b/umap/static/umap/js/modules/panel.js new file mode 100644 index 00000000..0e94f0c7 --- /dev/null +++ b/umap/static/umap/js/modules/panel.js @@ -0,0 +1,81 @@ +export class Panel { + MODE = 'condensed' + CLASSNAME = 'left' + + constructor(parent) { + this.parent = parent + this.container = L.DomUtil.create('div', '', this.parent) + L.DomEvent.disableClickPropagation(this.container) + L.DomEvent.on(this.container, 'contextmenu', L.DomEvent.stopPropagation) // Do not activate our custom context menu. + L.DomEvent.on(this.container, 'wheel', L.DomEvent.stopPropagation) + L.DomEvent.on(this.container, 'MozMousePixelScroll', L.DomEvent.stopPropagation) + } + + resetClassName() { + this.container.className = `with-transition panel ${this.CLASSNAME} ${this.MODE}` + } + + open(e) { + //this.fire('panel:open') + // We reset all because we can't know which class has been added + // by previous ui processes... + this.resetClassName() + this.container.innerHTML = '' + const actionsContainer = L.DomUtil.create('ul', 'toolbox', this.container) + const body = L.DomUtil.create('div', 'body', this.container) + if (e.data.html.nodeType && e.data.html.nodeType === 1) + body.appendChild(e.data.html) + else body.innerHTML = e.data.html + const closeLink = L.DomUtil.create('li', 'umap-close-link', actionsContainer) + L.DomUtil.add('i', 'icon icon-16 icon-close', closeLink) + closeLink.title = L._('Close') + const resizeLink = L.DomUtil.create('li', 'umap-resize-link', actionsContainer) + L.DomUtil.add('i', 'icon icon-16 icon-resize', resizeLink) + resizeLink.title = L._('Toggle size') + if (e.actions) { + for (let i = 0; i < e.actions.length; i++) { + actionsContainer.appendChild(e.actions[i]) + } + } + if (e.className) L.DomUtil.addClass(this.container, e.className) + if (L.DomUtil.hasClass(this.container, 'on')) { + // Already open. + //this.fire('panel:ready') + } else { + L.DomEvent.once( + this.container, + 'transitionend', + function (e) { + //this.fire('panel:ready') + }, + this + ) + L.DomUtil.addClass(this.container, 'on') + } + L.DomEvent.on(closeLink, 'click', this.close, this) + L.DomEvent.on(resizeLink, 'click', this.resize, this) + } + + resize() { + if (this.MODE === 'expanded') { + this.MODE = 'condensed' + this.container.classList.remove('expanded') + this.container.classList.add('condensed') + } else { + this.MODE = 'expanded' + this.container.classList.remove('condensed') + this.container.classList.add('expanded') + } + } + + close() { + if (L.DomUtil.hasClass(this.container, 'on')) { + L.DomUtil.removeClass(this.container, 'on') + //this.fire('panel:closed') + } + } +} + +export class EditPanel extends Panel { + CLASSNAME = 'right dark' +} diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js index 10c65b14..f7bd5b48 100644 --- a/umap/static/umap/js/umap.controls.js +++ b/umap/static/umap/js/umap.controls.js @@ -29,6 +29,18 @@ U.ImportAction = U.BaseAction.extend({ }, }) +U.EditLayersAction = U.BaseAction.extend({ + options: { + helpMenu: true, + className: 'umap-control-browse dark', + tooltip: L._('See layers'), + }, + + addHooks: function () { + this.map.editDatalayers() + }, +}) + U.EditCaptionAction = U.BaseAction.extend({ options: { helpMenu: true, @@ -280,7 +292,6 @@ U.ContinueLineAction = U.BaseVertexAction.extend({ }) // Leaflet.Toolbar doesn't allow twice same toolbar class… -U.ImportToolbar = L.Toolbar.Control.extend({}) U.SettingsToolbar = L.Toolbar.Control.extend({}) U.DrawToolbar = L.Toolbar.Control.extend({ initialize: function (options) { @@ -316,6 +327,7 @@ U.DrawToolbar = L.Toolbar.Control.extend({ }, }) + U.DropControl = L.Class.extend({ initialize: function (map) { this.map = map @@ -507,7 +519,7 @@ L.Control.Button = L.Control.extend({ U.DataLayersControl = L.Control.Button.extend({ options: { - position: 'topright', + position: 'topleft', className: 'umap-control-browse', title: L._('See layers'), }, @@ -519,8 +531,8 @@ U.DataLayersControl = L.Control.Button.extend({ U.CaptionControl = L.Control.Button.extend({ options: { - position: 'topright', - className: 'umap-control-caption hide-on-edit', + position: 'topleft', + className: 'umap-control-caption', title: L._('About'), }, @@ -614,6 +626,8 @@ const ControlsMixin = { 'search', 'fullscreen', 'embed', + 'datalayers', + 'caption', 'locate', 'measure', 'editinosm', @@ -669,7 +683,7 @@ const ControlsMixin = { }) container.appendChild(builder.build()) - this.ui.openPanel({ data: { html: container } }) + this.panel.open({ data: { html: container } }) }, displayCaption: function () { @@ -749,7 +763,7 @@ const ControlsMixin = { `, urls ) - this.ui.openPanel({ data: { html: container } }) + this.panel.open({ data: { html: container } }) }, renderEditToolbar: function () { @@ -899,6 +913,49 @@ const ControlsMixin = { this ) }, + + editDatalayers: function () { + if (!this.editEnabled) return + const container = L.DomUtil.create('div') + L.DomUtil.createTitle(container, L._('Manage layers'), 'layers') + const ul = L.DomUtil.create('ul', '', container) + this.eachDataLayerReverse((datalayer) => { + const row = L.DomUtil.create('li', 'orderable', ul) + const dragHandle = L.DomUtil.create('i', 'icon icon-16 icon-drag', row) + dragHandle.title = L._('Drag to reorder') + datalayer.renderToolbox(row) + const title = L.DomUtil.add('span', '', row, datalayer.options.name) + L.DomUtil.classIf(row, 'off', !datalayer.isVisible()) + title.textContent = datalayer.options.name + row.dataset.id = L.stamp(datalayer) + }) + const onReorder = (src, dst, initialIndex, finalIndex) => { + const layer = this.datalayers[src.dataset.id], + other = this.datalayers[dst.dataset.id], + minIndex = Math.min(layer.getRank(), other.getRank()), + maxIndex = Math.max(layer.getRank(), other.getRank()) + if (finalIndex === 0) layer.bringToTop() + else if (finalIndex > initialIndex) layer.insertBefore(other) + else layer.insertAfter(other) + this.eachDataLayerReverse((datalayer) => { + if (datalayer.getRank() >= minIndex && datalayer.getRank() <= maxIndex) + datalayer.isDirty = true + }) + this.indexDatalayers() + } + const orderable = new U.Orderable(ul, onReorder) + + const bar = L.DomUtil.create('div', 'button-bar', container) + L.DomUtil.createButton( + 'show-on-edit block add-datalayer button', + bar, + L._('Add a layer'), + this.newDataLayer, + this + ) + + this.editPanel.open({ data: { html: container } }) + }, } /* Used in view mode to define the current tilelayer */ @@ -971,7 +1028,7 @@ U.TileLayerChooser = L.Control.extend({ L.DomUtil.createTitle(container, L._('Change tilelayers'), 'tilelayer') this._tilelayers_container = L.DomUtil.create('ul', '', container) this.buildList(options) - this.map.ui.openPanel({ + this.map.editPanel.open({ data: { html: container }, className: options.className, }) @@ -1201,6 +1258,7 @@ U.SearchControl = L.Control.extend({ }, onAdd: function (map) { + this.map = map const container = L.DomUtil.create('div', 'leaflet-control-search umap-control') L.DomEvent.disableClickPropagation(container) L.DomUtil.createButton( @@ -1209,38 +1267,37 @@ U.SearchControl = L.Control.extend({ L._('Search location'), (e) => { L.DomEvent.stop(e) - this.openPanel(map) + this.open() }, this ) return container }, - openPanel: function (map) { + open: function () { const options = { limit: 10, noResultLabel: L._('No results'), } - if (map.options.photonUrl) options.url = map.options.photonUrl - const container = L.DomUtil.create('div', 'umap-search') + if (this.map.options.photonUrl) options.url = this.map.options.photonUrl + const container = L.DomUtil.create('div', '') - const title = L.DomUtil.create('h3', '', container) - title.textContent = L._('Search location') + L.DomUtil.createTitle(container, L._('Search location'), 'search') const input = L.DomUtil.create('input', 'photon-input', container) const resultsContainer = L.DomUtil.create('div', 'photon-autocomplete', container) - this.search = new U.Search(map, input, options) + this.search = new U.Search(this.map, input, options) const id = Math.random() this.search.on('ajax:send', () => { - map.fire('dataloading', { id: id }) + this.map.fire('dataloading', { id: id }) }) this.search.on('ajax:return', () => { - map.fire('dataload', { id: id }) + this.map.fire('dataload', { id: id }) }) this.search.resultsContainer = resultsContainer - map.ui.once('panel:ready', () => { + this.map.ui.once('panel:ready', () => { input.focus() }) - map.ui.openPanel({ data: { html: container } }) + this.map.panel.open({ data: { html: container } }) }, }) diff --git a/umap/static/umap/js/umap.features.js b/umap/static/umap/js/umap.features.js index 517f321c..34087abb 100644 --- a/umap/static/umap/js/umap.features.js +++ b/umap/static/umap/js/umap.features.js @@ -132,11 +132,7 @@ U.FeatureMixin = { this.appendEditFieldsets(container) const advancedActions = L.DomUtil.createFieldset(container, L._('Advanced actions')) this.getAdvancedEditActions(advancedActions) - this.map.ui.openPanel({ - data: { html: container }, - className: 'dark', - actions: [U.Browser.backButton(this.map)], - }) + this.map.editPanel.open({ data: { html: container } }) this.map.editedFeature = this if (!this.isOnScreen()) this.zoomTo(e) }, diff --git a/umap/static/umap/js/umap.importer.js b/umap/static/umap/js/umap.importer.js index 0400cd1c..d3e85df7 100644 --- a/umap/static/umap/js/umap.importer.js +++ b/umap/static/umap/js/umap.importer.js @@ -117,7 +117,7 @@ U.Importer = L.Class.extend({ open: function () { if (!this.container) this.build() - this.map.ui.openPanel({ data: { html: this.container }, className: 'dark' }) + this.map.editPanel.open({ data: { html: this.container } }) }, openFiles: function () { diff --git a/umap/static/umap/js/umap.js b/umap/static/umap/js/umap.js index a1b9ef54..60b13208 100644 --- a/umap/static/umap/js/umap.js +++ b/umap/static/umap/js/umap.js @@ -56,6 +56,8 @@ U.Map = L.Map.extend({ if (geojson.geometry) this.options.center = this.latLng(geojson.geometry) this.urls = new U.URLs(this.options.urls) + this.panel = new U.Panel(this._container) + if (this.hasEditMode()) this.editPanel = new U.EditPanel(this._container) this.ui = new U.UI(this._container) this.ui.on('dataloading', (e) => this.fire('dataloading', e)) this.ui.on('dataload', (e) => this.fire('dataload', e)) @@ -330,15 +332,16 @@ U.Map = L.Map.extend({ new U.EditControl(this).addTo(this) const editActions = [ + U.EditLayersAction, U.EditCaptionAction, U.EditPropertiesAction, U.ChangeTileLayerAction, U.UpdateExtentAction, U.UpdatePermsAction, + U.ImportAction, ] if (this.options.editMode === 'advanced') { new U.SettingsToolbar({ actions: editActions }).addTo(this) - new U.ImportToolbar({ actions: [U.ImportAction] }).addTo(this) } new U.DrawToolbar({ map: this }).addTo(this) @@ -438,8 +441,6 @@ U.Map = L.Map.extend({ L.DomUtil.addClass(control._container, 'display-on-more') else L.DomUtil.removeClass(control._container, 'display-on-more') } - if (this.getOption('datalayersControl')) this._controls.datalayers.addTo(this) - if (this.getOption('captionControl')) this._controls.caption.addTo(this) if (this.getOption('permanentCredit')) this._controls.permanentCredit.addTo(this) if (this.getOption('moreControl')) this._controls.more.addTo(this) if (this.getOption('scaleControl')) this._controls.scale.addTo(this) @@ -775,6 +776,11 @@ U.Map = L.Map.extend({ return new U.DataLayer(this, datalayer) }, + newDataLayer: function () { + const datalayer = this.createDataLayer({}) + datalayer.edit() + }, + getDefaultOption: function (option) { return U.SCHEMA[option] && U.SCHEMA[option].default }, @@ -812,10 +818,6 @@ U.Map = L.Map.extend({ }) }, - manageDatalayers: function () { - if (this._controls.datalayers) this._controls.datalayers.openPanel() - }, - toGeoJSON: function () { let features = [] this.eachDataLayer((datalayer) => { @@ -1061,7 +1063,7 @@ U.Map = L.Map.extend({ else window.location = data.url alert.content = data.info || alert.content this.once('saved', () => this.ui.alert(alert)) - this.ui.closePanel() + this.editPanel.close() this.permissions.save() } }, @@ -1164,7 +1166,6 @@ U.Map = L.Map.extend({ UIFields.push(`options.${this.HIDDABLE_CONTROLS[i]}Control`) } UIFields = UIFields.concat([ - 'options.datalayersControl', 'options.moreControl', 'options.scrollWheelZoom', 'options.miniMap', @@ -1550,7 +1551,7 @@ U.Map = L.Map.extend({ this._editSlideshow(container) this._advancedActions(container) - this.ui.openPanel({ data: { html: container }, className: 'dark' }) + this.editPanel.open({ data: { html: container }, className: 'dark' }) }, enableEdit: function () { @@ -1822,7 +1823,7 @@ U.Map = L.Map.extend({ }, search: function () { - if (this._controls.search) this._controls.search.openPanel(this) + if (this._controls.search) this._controls.search.open() }, getFilterKeys: function () { diff --git a/umap/static/umap/js/umap.layer.js b/umap/static/umap/js/umap.layer.js index 1ebc39e0..93c088ce 100644 --- a/umap/static/umap/js/umap.layer.js +++ b/umap/static/umap/js/umap.layer.js @@ -1379,9 +1379,8 @@ U.DataLayer = L.Evented.extend({ '_blank' ) } - this.map.ui.openPanel({ + this.map.editPanel.open({ data: { html: container }, - className: 'dark', actions: [U.Browser.backButton(this.map)], }) }, diff --git a/umap/static/umap/js/umap.permissions.js b/umap/static/umap/js/umap.permissions.js index 6200a694..871e88fe 100644 --- a/umap/static/umap/js/umap.permissions.js +++ b/umap/static/umap/js/umap.permissions.js @@ -126,7 +126,7 @@ U.MapPermissions = L.Class.extend({ this.map.eachDataLayer((datalayer) => { datalayer.permissions.edit(container) }) - this.map.ui.openPanel({ data: { html: container }, className: 'dark' }) + this.map.editPanel.open({ data: { html: container }, className: 'dark' }) }, attach: async function () { diff --git a/umap/static/umap/js/umap.popup.js b/umap/static/umap/js/umap.popup.js index ced6b1d0..5416a7ea 100644 --- a/umap/static/umap/js/umap.popup.js +++ b/umap/static/umap/js/umap.popup.js @@ -55,7 +55,7 @@ U.Popup.Panel = U.Popup.extend({ }, onAdd: function (map) { - map.ui.openPanel({ + map.panel.open({ data: { html: this._content }, actions: [U.Browser.backButton(map)], }) @@ -71,7 +71,7 @@ U.Popup.Panel = U.Popup.extend({ }, onRemove: function (map) { - map.ui.closePanel() + map.panel.close() // fire events as in base class Popup.js:onRemove map.fire('popupclose', { popup: this }) diff --git a/umap/static/umap/js/umap.share.js b/umap/static/umap/js/umap.share.js index 88a2d033..a4c0a65c 100644 --- a/umap/static/umap/js/umap.share.js +++ b/umap/static/umap/js/umap.share.js @@ -155,7 +155,7 @@ U.Share = L.Class.extend({ open: function () { if (!this.container) this.build() - this.map.ui.openPanel({ data: { html: this.container } }) + this.map.panel.open({ data: { html: this.container } }) }, format: function (mode) { diff --git a/umap/static/umap/js/umap.ui.js b/umap/static/umap/js/umap.ui.js index 8c54e5aa..4f238244 100644 --- a/umap/static/umap/js/umap.ui.js +++ b/umap/static/umap/js/umap.ui.js @@ -5,7 +5,6 @@ U.UI = L.Evented.extend({ ALERTS: Array(), ALERT_ID: null, TOOLTIP_ID: null, - PANEL_MODE: 'condensed', initialize: function (parent) { this.parent = parent @@ -14,78 +13,12 @@ U.UI = L.Evented.extend({ L.DomEvent.on(this.container, 'contextmenu', L.DomEvent.stopPropagation) // Do not activate our custom context menu. L.DomEvent.on(this.container, 'wheel', L.DomEvent.stopPropagation) L.DomEvent.on(this.container, 'MozMousePixelScroll', L.DomEvent.stopPropagation) - this._panel = L.DomUtil.create('div', '', this.container) - this._panel.id = 'umap-panel' this._alert = L.DomUtil.create('div', 'with-transition', this.container) this._alert.id = 'umap-alert-container' this._tooltip = L.DomUtil.create('div', '', this.container) this._tooltip.id = 'umap-tooltip-container' }, - resetPanelClassName: function () { - this._panel.className = `with-transition ${this.PANEL_MODE}` - }, - - openPanel: function (e) { - this.fire('panel:open') - // We reset all because we can't know which class has been added - // by previous ui processes... - this.resetPanelClassName() - this._panel.innerHTML = '' - const actionsContainer = L.DomUtil.create('ul', 'toolbox', this._panel) - const body = L.DomUtil.create('div', 'body', this._panel) - if (e.data.html.nodeType && e.data.html.nodeType === 1) - body.appendChild(e.data.html) - else body.innerHTML = e.data.html - const closeLink = L.DomUtil.create('li', 'umap-close-link', actionsContainer) - L.DomUtil.add('i', 'umap-icon-16 umap-close-icon', closeLink) - closeLink.title = L._('Close') - const resizeLink = L.DomUtil.create('li', 'umap-resize-link', actionsContainer) - L.DomUtil.add('i', 'umap-icon-16 umap-resize-icon', resizeLink) - resizeLink.title = L._('Toggle size') - if (e.actions) { - for (let i = 0; i < e.actions.length; i++) { - actionsContainer.appendChild(e.actions[i]) - } - } - if (e.className) L.DomUtil.addClass(this._panel, e.className) - if (L.DomUtil.hasClass(this.parent, 'umap-ui')) { - // Already open. - this.fire('panel:ready') - } else { - L.DomEvent.once( - this._panel, - 'transitionend', - function (e) { - this.fire('panel:ready') - }, - this - ) - L.DomUtil.addClass(this.parent, 'umap-ui') - } - L.DomEvent.on(closeLink, 'click', this.closePanel, this) - L.DomEvent.on(resizeLink, 'click', this.resizePanel, this) - }, - - resizePanel: function () { - if (this.PANEL_MODE === 'expanded') { - this.PANEL_MODE = 'condensed' - this._panel.classList.remove('expanded') - this._panel.classList.add('condensed') - } else { - this.PANEL_MODE = 'expanded' - this._panel.classList.remove('condensed') - this._panel.classList.add('expanded') - } - }, - - closePanel: function () { - if (L.DomUtil.hasClass(this.parent, 'umap-ui')) { - L.DomUtil.removeClass(this.parent, 'umap-ui') - this.fire('panel:closed') - } - }, - alert: function (e) { if (L.DomUtil.hasClass(this.parent, 'umap-alert')) this.ALERTS.push(e) else this.popAlert(e) diff --git a/umap/static/umap/map.css b/umap/static/umap/map.css index 051e6844..86640d3c 100644 --- a/umap/static/umap/map.css +++ b/umap/static/umap/map.css @@ -862,6 +862,7 @@ ul.photon-autocomplete { /* ********************************* */ /* Browser panel */ /* ********************************* */ +a.umap-control-browse, .umap-control-browse [type="button"] { background-position: -36px -72px; } @@ -869,12 +870,6 @@ a.umap-control-caption, .umap-control-caption [type="button"] { background-position: -72px -72px; } -.umap-edit-enabled .umap-control-caption [type="button"], -.umap-edit-enabled .umap-control-browse [type="button"] { - background-image: url('./img/24-white.svg'); - background-color: var(--color-darkGray); -} -.search-result-tools i, .leaflet-inplace-toolbar a { background-repeat: no-repeat; background-image: url('./img/16.svg'); diff --git a/umap/templates/umap/css.html b/umap/templates/umap/css.html index 623d1e6d..c121ccd1 100644 --- a/umap/templates/umap/css.html +++ b/umap/templates/umap/css.html @@ -28,4 +28,5 @@ + From 3bc57a8512da548d4612bffda9facfdf35d1ed95 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Thu, 14 Mar 2024 20:41:47 +0100 Subject: [PATCH 18/44] chore: refactor simple button controls --- umap/static/umap/js/umap.controls.js | 77 ++++++++++++---------------- 1 file changed, 33 insertions(+), 44 deletions(-) diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js index f7bd5b48..8daa7e29 100644 --- a/umap/static/umap/js/umap.controls.js +++ b/umap/static/umap/js/umap.controls.js @@ -407,26 +407,6 @@ U.EditControl = L.Control.extend({ }, }) -/* Share control */ -L.Control.Embed = L.Control.extend({ - options: { - position: 'topleft', - }, - - onAdd: function (map) { - const container = L.DomUtil.create('div', 'leaflet-control-embed umap-control') - const shareButton = L.DomUtil.createButton( - '', - container, - L._('Share and download'), - map.share.open, - map.share - ) - L.DomEvent.on(shareButton, 'dblclick', L.DomEvent.stopPropagation) - return container - }, -}) - U.MoreControls = L.Control.extend({ options: { position: 'topleft', @@ -503,8 +483,12 @@ L.Control.Button = L.Control.extend({ L.Control.prototype.initialize.call(this, options) }, + getClassName: function () { + return this.options.className + }, + onAdd: function (map) { - const container = L.DomUtil.create('div', `${this.options.className} umap-control`) + const container = L.DomUtil.create('div', `${this.getClassName()} umap-control`) const button = L.DomUtil.createButton( '', container, @@ -541,6 +525,34 @@ U.CaptionControl = L.Control.Button.extend({ }, }) +U.StarControl = L.Control.Button.extend({ + options: { + position: 'topleft', + title: L._('Star this map'), + }, + + getClassName: function () { + const status = this.map.options.starred ? ' starred' : '' + return `leaflet-control-star umap-control${status}` + }, + + onClick: function () { + this.map.star() + }, +}) + +L.Control.Embed = L.Control.Button.extend({ + options: { + position: 'topleft', + title: L._('Share and download'), + className: 'leaflet-control-embed umap-control', + }, + + onClick: function () { + this.map.share.open() + }, +}) + U.DataLayer.include({ renderLegend: function (container) { if (this.layer.renderLegend) return this.layer.renderLegend(container) @@ -1111,29 +1123,6 @@ U.AttributionControl = L.Control.Attribution.extend({ }, }) -U.StarControl = L.Control.extend({ - options: { - position: 'topleft', - }, - - onAdd: function (map) { - const status = map.options.starred ? ' starred' : '' - const container = L.DomUtil.create( - 'div', - `leaflet-control-star umap-control${status}` - ) - const starMapButton = L.DomUtil.createButton( - '', - container, - L._('Star this map'), - map.star, - map - ) - L.DomEvent.on(starMapButton, 'dblclick', L.DomEvent.stopPropagation) - return container - }, -}) - /* * Take control over L.Control.Locate to be able to * call start() before adding the control (and thus the button) to the map. From 0b175d1a56e4fcaf239078085728fdae8016583b Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Fri, 15 Mar 2024 11:29:59 +0100 Subject: [PATCH 19/44] chore: use icon buttons where possible --- umap/static/umap/base.css | 5 +- umap/static/umap/css/icon.css | 20 ++++++-- umap/static/umap/js/modules/browser.js | 21 ++++---- umap/static/umap/js/umap.controls.js | 67 ++++++++++++++++--------- umap/static/umap/js/umap.core.js | 20 ++++++-- umap/static/umap/js/umap.importer.js | 6 ++- umap/static/umap/js/umap.js | 2 +- umap/static/umap/js/umap.layer.js | 2 +- umap/static/umap/js/umap.permissions.js | 2 +- umap/static/umap/js/umap.share.js | 6 ++- 10 files changed, 102 insertions(+), 49 deletions(-) diff --git a/umap/static/umap/base.css b/umap/static/umap/base.css index 995f95b7..456b3063 100644 --- a/umap/static/umap/base.css +++ b/umap/static/umap/base.css @@ -21,6 +21,9 @@ a { text-decoration: none; color: SeaGreen; } +button { + cursor: pointer; +} hr { clear: both; width: 100%; @@ -530,7 +533,7 @@ i.info { background-position: -150px -78px; } .umap-delete:before { - background-position: -40px -8px; + background-position: -32px -8px; } .umap-edit:before { background-position: -6px -6px; diff --git a/umap/static/umap/css/icon.css b/umap/static/umap/css/icon.css index 87257be2..39778ee1 100644 --- a/umap/static/umap/css/icon.css +++ b/umap/static/umap/css/icon.css @@ -1,8 +1,12 @@ +/* Applied on i and button elements */ .icon { background-repeat: no-repeat; display: inline-block; padding: 0 10px; vertical-align: middle; + /* Reste default style, in case we apply this class on a button element */ + border: none; + background-color: initial; } .icon-16 { background-image: url('../img/16.svg'); @@ -16,7 +20,7 @@ background-image: url('../img/16-white.svg'); } .icon-add { - background-position: -26px -30px; + background-position: -26px -24px; } .icon-back { background-position: -122px -144px; @@ -30,17 +34,27 @@ .icon-delete { background-position: -121px -49px; } +.readonly .icon-delete, +.off .icon-delete { + background-position: -121px -122px; +} .icon-drag { background-position: -72px -73px; cursor: move; - margin-right: 10px; + float: right; } .icon-eye { background-position: -49px -26px; } +.off .icon-eye { + background-position: -73px -26px; +} .icon-edit { background-position: -51px -49px; } +.off .icon-edit { + background-position: -51px -73px; +} .icon-key { background-position: -144px -121px; } @@ -91,5 +105,5 @@ background-position: -1px -49px; } .off .icon-zoom { - background-position: -25px -54px; + background-position: -25px -49px; } diff --git a/umap/static/umap/js/modules/browser.js b/umap/static/umap/js/modules/browser.js index fe1bc092..59fe52e4 100644 --- a/umap/static/umap/js/modules/browser.js +++ b/umap/static/umap/js/modules/browser.js @@ -15,18 +15,15 @@ export default class Browser { const filter = this.options.filter if (filter && !feature.matchFilter(filter, this.filterKeys)) return if (this.options.inBbox && !feature.isOnScreen(this.bounds)) return - const feature_li = DomUtil.create('li', `${feature.getClassName()} feature`), - zoom_to = DomUtil.create('i', 'icon icon-16 icon-zoom', feature_li), - edit = DomUtil.create('i', 'icon icon-16 show-on-edit icon-edit', feature_li), - del = DomUtil.create('i', 'icon icon-16 show-on-edit icon-delete', feature_li), - colorBox = DomUtil.create('i', 'icon icon-16 feature-color', feature_li), - title = DomUtil.create('span', 'feature-title', feature_li), - symbol = feature._getIconUrl + const row = DomUtil.create('li', `${feature.getClassName()} feature`) + const zoom_to = DomUtil.createButtonIcon(row, 'icon-zoom', translate('Bring feature to center')) + const edit = DomUtil.createButtonIcon(row, 'show-on-edit icon-edit', translate('Edit this feature')) + const del = DomUtil.createButtonIcon(row, 'show-on-edit icon-delete', translate('Delete this feature')) + const colorBox = DomUtil.create('i', 'icon icon-16 feature-color', row) + const title = DomUtil.create('span', 'feature-title', row) + const symbol = feature._getIconUrl ? U.Icon.prototype.formatUrl(feature._getIconUrl(), feature) : null - zoom_to.title = translate('Bring feature to center') - edit.title = translate('Edit this feature') - del.title = translate('Delete this feature') title.textContent = feature.getDisplayName() || '—' const bgcolor = feature.getDynamicOption('color') colorBox.style.backgroundColor = bgcolor @@ -56,8 +53,8 @@ export default class Browser { DomEvent.on(del, 'click', feature.confirmDelete, feature) // HOTFIX. Remove when this is released: // https://github.com/Leaflet/Leaflet/pull/9052 - DomEvent.disableClickPropagation(feature_li) - parent.appendChild(feature_li) + DomEvent.disableClickPropagation(row) + parent.appendChild(row) } datalayerId(datalayer) { diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js index 8daa7e29..45ce42e3 100644 --- a/umap/static/umap/js/umap.controls.js +++ b/umap/static/umap/js/umap.controls.js @@ -561,16 +561,31 @@ U.DataLayer.include({ }, renderToolbox: function (container) { - const toggle = L.DomUtil.create('i', 'icon icon-16 icon-eye', container), - zoomTo = L.DomUtil.create('i', 'icon icon-16 icon-zoom', container), - edit = L.DomUtil.create('i', 'icon icon-16 icon-edit show-on-edit', container), - table = L.DomUtil.create('i', 'icon icon-16 icon-table show-on-edit', container), - remove = L.DomUtil.create('i', 'icon icon-16 icon-delete show-on-edit', container) - zoomTo.title = L._('Zoom to layer extent') - toggle.title = L._('Show/hide layer') - edit.title = L._('Edit') - table.title = L._('Edit properties in a table') - remove.title = L._('Delete layer') + const toggle = L.DomUtil.createButtonIcon( + container, + 'icon-eye', + L._('Show/hide layer') + ) + const zoomTo = L.DomUtil.createButtonIcon( + container, + 'icon-zoom', + L._('Zoom to layer extent') + ) + const edit = L.DomUtil.createButtonIcon( + container, + 'icon-edit show-on-edit', + L._('Edit') + ) + const table = L.DomUtil.createButtonIcon( + container, + 'icon-table show-on-edit', + L._('Edit properties in a table') + ) + const remove = L.DomUtil.createButtonIcon( + container, + 'icon-delete show-on-edit', + L._('Delete layer') + ) if (this.isReadOnly()) { L.DomUtil.addClass(container, 'readonly') } else { @@ -700,7 +715,7 @@ const ControlsMixin = { displayCaption: function () { const container = L.DomUtil.create('div', 'umap-caption') - L.DomUtil.createTitle(container, this.options.name, 'caption') + L.DomUtil.createTitle(container, this.options.name, 'icon-caption') this.permissions.addOwnerLink('h5', container) if (this.options.description) { const description = L.DomUtil.create('div', 'umap-map-description', container) @@ -929,12 +944,11 @@ const ControlsMixin = { editDatalayers: function () { if (!this.editEnabled) return const container = L.DomUtil.create('div') - L.DomUtil.createTitle(container, L._('Manage layers'), 'layers') + L.DomUtil.createTitle(container, L._('Manage layers'), 'icon-layers') const ul = L.DomUtil.create('ul', '', container) this.eachDataLayerReverse((datalayer) => { const row = L.DomUtil.create('li', 'orderable', ul) - const dragHandle = L.DomUtil.create('i', 'icon icon-16 icon-drag', row) - dragHandle.title = L._('Drag to reorder') + L.DomUtil.createIcon(row, 'icon-drag', L._('Drag to reorder')) datalayer.renderToolbox(row) const title = L.DomUtil.add('span', '', row, datalayer.options.name) L.DomUtil.classIf(row, 'off', !datalayer.isVisible()) @@ -1037,7 +1051,7 @@ U.TileLayerChooser = L.Control.extend({ openSwitcher: function (options) { const container = L.DomUtil.create('div', 'umap-tilelayer-switcher-container') - L.DomUtil.createTitle(container, L._('Change tilelayers'), 'tilelayer') + L.DomUtil.createTitle(container, L._('Change tilelayers'), 'icon-tilelayer') this._tilelayers_container = L.DomUtil.create('ul', '', container) this.buildList(options) this.map.editPanel.open({ @@ -1205,21 +1219,26 @@ U.Search = L.PhotonSearch.extend({ }, formatResult: function (feature, el) { - const self = this - const tools = L.DomUtil.create('span', 'search-result-tools', el), - zoom = L.DomUtil.create('i', 'icon icon-16 icon-zoom', tools), - edit = L.DomUtil.create('i', 'icon icon-16 icon-edit show-on-edit', tools) - zoom.title = L._('Zoom to this place') - edit.title = L._('Save this location as new feature') + const tools = L.DomUtil.create('span', 'search-result-tools', el) + const zoom = L.DomUtil.createButtonIcon( + tools, + 'icon-zoom', + L._('Zoom to this place') + ) + const edit = L.DomUtil.createButtonIcon( + tools, + 'icon-edit', + L._('Save this location as new feature') + ) // We need to use "mousedown" because Leaflet.Photon listen to mousedown // on el. L.DomEvent.on(zoom, 'mousedown', (e) => { L.DomEvent.stop(e) - self.zoomToFeature(feature) + this.zoomToFeature(feature) }) L.DomEvent.on(edit, 'mousedown', (e) => { L.DomEvent.stop(e) - const datalayer = self.map.defaultEditDataLayer() + const datalayer = this.map.defaultEditDataLayer() const layer = datalayer.geojsonToFeatures(feature) layer.isDirty = true layer.edit() @@ -1271,7 +1290,7 @@ U.SearchControl = L.Control.extend({ if (this.map.options.photonUrl) options.url = this.map.options.photonUrl const container = L.DomUtil.create('div', '') - L.DomUtil.createTitle(container, L._('Search location'), 'search') + L.DomUtil.createTitle(container, L._('Search location'), 'icon-search') const input = L.DomUtil.create('input', 'photon-input', container) const resultsContainer = L.DomUtil.create('div', 'photon-autocomplete', container) this.search = new U.Search(this.map, input, options) diff --git a/umap/static/umap/js/umap.core.js b/umap/static/umap/js/umap.core.js index c451879f..e3794e82 100644 --- a/umap/static/umap/js/umap.core.js +++ b/umap/static/umap/js/umap.core.js @@ -117,13 +117,25 @@ L.DomUtil.createLink = (className, container, content, url, target, title) => { return el } -L.DomUtil.createIcon = (parent, name) => { - L.DomUtil.create('i', `icon icon-16 icon-${name}`, parent) +L.DomUtil.createIcon = (parent, className, title, size = 16) => { + return L.DomUtil.element( + 'i', + { className: `icon icon-${size} ${className}`, title: title }, + parent + ) } -L.DomUtil.createTitle = (parent, text, icon, tag = 'h3') => { +L.DomUtil.createButtonIcon = (parent, className, title, size = 16) => { + return L.DomUtil.element( + 'button', + { className: `icon icon-${size} ${className}`, title: title }, + parent + ) +} + +L.DomUtil.createTitle = (parent, text, className, tag = 'h3') => { const title = L.DomUtil.create(tag, '', parent) - L.DomUtil.createIcon(title, icon) + L.DomUtil.createIcon(title, className) L.DomUtil.add('span', '', title, text) return title } diff --git a/umap/static/umap/js/umap.importer.js b/umap/static/umap/js/umap.importer.js index d3e85df7..ff5237b1 100644 --- a/umap/static/umap/js/umap.importer.js +++ b/umap/static/umap/js/umap.importer.js @@ -7,7 +7,11 @@ U.Importer = L.Class.extend({ build: function () { this.container = L.DomUtil.create('div', 'umap-upload') - this.title = L.DomUtil.createTitle(this.container, L._('Import data'), 'upload') + this.title = L.DomUtil.createTitle( + this.container, + L._('Import data'), + 'icon-upload' + ) this.presetBox = L.DomUtil.create('div', 'formbox', this.container) this.presetSelect = L.DomUtil.create('select', '', this.presetBox) this.fileBox = L.DomUtil.create('div', 'formbox', this.container) diff --git a/umap/static/umap/js/umap.js b/umap/static/umap/js/umap.js index 60b13208..a8c37e7b 100644 --- a/umap/static/umap/js/umap.js +++ b/umap/static/umap/js/umap.js @@ -1540,7 +1540,7 @@ U.Map = L.Map.extend({ if (!this.editEnabled) return if (this.options.editMode !== 'advanced') return const container = L.DomUtil.create('div') - L.DomUtil.createTitle(container, L._('Map advanced properties'), 'settings') + L.DomUtil.createTitle(container, L._('Map advanced properties'), 'icon-settings') this._editControls(container) this._editShapeProperties(container) this._editDefaultProperties(container) diff --git a/umap/static/umap/js/umap.layer.js b/umap/static/umap/js/umap.layer.js index 93c088ce..dad7a770 100644 --- a/umap/static/umap/js/umap.layer.js +++ b/umap/static/umap/js/umap.layer.js @@ -1211,7 +1211,7 @@ U.DataLayer = L.Evented.extend({ }, ], ] - L.DomUtil.createTitle(container, L._('Layer properties'), 'layers') + L.DomUtil.createTitle(container, L._('Layer properties'), 'icon-layers') let builder = new U.FormBuilder(this, metadataFields, { callback: function (e) { if (e.helper.field === 'options.type') { diff --git a/umap/static/umap/js/umap.permissions.js b/umap/static/umap/js/umap.permissions.js index 871e88fe..00a25bd2 100644 --- a/umap/static/umap/js/umap.permissions.js +++ b/umap/static/umap/js/umap.permissions.js @@ -59,7 +59,7 @@ U.MapPermissions = L.Class.extend({ }) const container = L.DomUtil.create('div', 'permissions-panel') const fields = [] - L.DomUtil.createTitle(container, L._('Update permissions'), 'key') + L.DomUtil.createTitle(container, L._('Update permissions'), 'icon-key') if (this.isAnonymousMap()) { if (this.options.anonymous_edit_url) { const helpText = `${L._('Secret edit link:')}
${this.options.anonymous_edit_url diff --git a/umap/static/umap/js/umap.share.js b/umap/static/umap/js/umap.share.js index a4c0a65c..54befdb8 100644 --- a/umap/static/umap/js/umap.share.js +++ b/umap/static/umap/js/umap.share.js @@ -45,7 +45,11 @@ U.Share = L.Class.extend({ build: function () { this.container = L.DomUtil.create('div', '') - this.title = L.DomUtil.createTitle(this.container, L._('Share and download'), 'share') + this.title = L.DomUtil.createTitle( + this.container, + L._('Share and download'), + 'icon-share' + ) L.DomUtil.createCopiableInput( this.container, From 849b194d4fa3504b5bb22e70adf7f6371aa2c1cf Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Fri, 15 Mar 2024 11:34:09 +0100 Subject: [PATCH 20/44] chore: use a specific panel class for table view --- umap/static/umap/css/panel.css | 33 +++++++++++++++++++------ umap/static/umap/js/modules/global.js | 3 ++- umap/static/umap/js/modules/panel.js | 5 ++++ umap/static/umap/js/umap.js | 5 +++- umap/static/umap/js/umap.tableeditor.js | 6 ++--- umap/static/umap/map.css | 8 +++--- 6 files changed, 42 insertions(+), 18 deletions(-) diff --git a/umap/static/umap/css/panel.css b/umap/static/umap/css/panel.css index c84c6ef9..58116c08 100644 --- a/umap/static/umap/css/panel.css +++ b/umap/static/umap/css/panel.css @@ -3,7 +3,7 @@ /* as being out of the visible viewport is not enough */ visibility: hidden; position: absolute; - bottom: 20px; + bottom: 10px; overflow-x: auto; z-index: 1010; background-color: #fff; @@ -17,12 +17,15 @@ background-color: var(--color-darkGray); color: #efefef; } -.panel.fullwidth { - width: 100%; +.panel.full { + width: initial; right: -100%; z-index: 10000; - padding-left: 0; - padding-right: 0; +} +.panel.full.on { + visibility: visible; + right: 10px; + left: 10px; } .umap-caption-bar-enabled .panel { bottom: 46px; @@ -43,6 +46,7 @@ clear: both; height: calc(100% - 32px); /* Minus size of toolbox */ padding: 10px; + padding-top: 32px; } .panel .toolbox { padding: 5px 10px; @@ -53,10 +57,14 @@ justify-content: flex-start; gap: 5px; line-height: 2.2em; + background-color: #fff; + position: fixed; } .panel.dark .toolbox { background-color: var(--color-darkGray); - border-bottom: 1px solid #232729; +} +.panel.full .toolbox { + width: calc(100% - 112px); } .panel .toolbox li { cursor: pointer; @@ -80,7 +88,11 @@ .panel { top: 0; margin-top: 10px; - width: 390px; + width: 400px; + } + .panel .toolbox { + /* It overflows otherwise, dunno why */ + width: 398px; } .panel.condensed { max-height: 500px; @@ -113,8 +125,15 @@ bottom: 0; right: -100%; } + .panel.left { + left: -100%; + } + .panel .toolbox { + width: 100%; + } .panel.on { right: 0; + left: 0; visibility: visible; } } diff --git a/umap/static/umap/js/modules/global.js b/umap/static/umap/js/modules/global.js index 708d9a15..7d07ba2f 100644 --- a/umap/static/umap/js/modules/global.js +++ b/umap/static/umap/js/modules/global.js @@ -1,6 +1,6 @@ import URLs from './urls.js' import Browser from './browser.js' -import { Panel, EditPanel } from './panel.js' +import { Panel, EditPanel, FullPanel } from './panel.js' import * as Utils from './utils.js' import { SCHEMA } from './schema.js' import { Request, ServerRequest, RequestError, HTTPError, NOKError } from './request.js' @@ -19,6 +19,7 @@ window.U = { Browser, Panel, EditPanel, + FullPanel, Utils, SCHEMA, Orderable, diff --git a/umap/static/umap/js/modules/panel.js b/umap/static/umap/js/modules/panel.js index 0e94f0c7..3e612b74 100644 --- a/umap/static/umap/js/modules/panel.js +++ b/umap/static/umap/js/modules/panel.js @@ -79,3 +79,8 @@ export class Panel { export class EditPanel extends Panel { CLASSNAME = 'right dark' } + +export class FullPanel extends Panel { + CLASSNAME = 'full dark' + MODE = 'expanded' +} diff --git a/umap/static/umap/js/umap.js b/umap/static/umap/js/umap.js index a8c37e7b..5b3e663b 100644 --- a/umap/static/umap/js/umap.js +++ b/umap/static/umap/js/umap.js @@ -57,7 +57,10 @@ U.Map = L.Map.extend({ this.urls = new U.URLs(this.options.urls) this.panel = new U.Panel(this._container) - if (this.hasEditMode()) this.editPanel = new U.EditPanel(this._container) + if (this.hasEditMode()) { + this.editPanel = new U.EditPanel(this._container) + this.fullPanel = new U.FullPanel(this._container) + } this.ui = new U.UI(this._container) this.ui.on('dataloading', (e) => this.fire('dataloading', e)) this.ui.on('dataload', (e) => this.fire('dataload', e)) diff --git a/umap/static/umap/js/umap.tableeditor.js b/umap/static/umap/js/umap.tableeditor.js index d59fa704..d856ecdf 100644 --- a/umap/static/umap/js/umap.tableeditor.js +++ b/umap/static/umap/js/umap.tableeditor.js @@ -94,7 +94,6 @@ U.TableEditor = L.Class.extend({ edit: function () { const id = 'tableeditor:edit' - this.datalayer.map.fire('dataloading', { id: id }) this.compileProperties() this.renderHeaders() this.body.innerHTML = '' @@ -110,11 +109,10 @@ U.TableEditor = L.Class.extend({ this.edit() } L.DomEvent.on(addButton, 'click', addProperty, this) - this.datalayer.map.ui.openPanel({ + this.datalayer.map.fullPanel.open({ data: { html: this.table }, - className: 'umap-table-editor fullwidth dark', + className: 'umap-table-editor', actions: [addButton, U.Browser.backButton(this.datalayer.map)], }) - this.datalayer.map.fire('dataload', { id: id }) }, }) diff --git a/umap/static/umap/map.css b/umap/static/umap/map.css index 86640d3c..c173f49e 100644 --- a/umap/static/umap/map.css +++ b/umap/static/umap/map.css @@ -911,7 +911,9 @@ a.umap-control-caption, height: 30px; line-height: 30px; background-color: var(--color-lightGray); - color: #666; +} +.umap-browser .off h5 { + color: #b3b3b3; } .umap-browser.dark h5 { background-color: #232729; @@ -984,10 +986,6 @@ a.umap-control-caption, /* ********************************* */ /* Table Editor */ /* ********************************* */ -#umap-panel.umap-table-editor { - padding-left: 0; - padding-right: 0; -} .umap-table-editor .table { display: table; From e3ff769ab98dc7cef2bf3b1cc62e0df953426678 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Fri, 15 Mar 2024 11:34:42 +0100 Subject: [PATCH 21/44] chore: import modules in panel.js --- umap/static/umap/js/modules/panel.js | 54 ++++++++++++++-------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/umap/static/umap/js/modules/panel.js b/umap/static/umap/js/modules/panel.js index 3e612b74..7839f7f0 100644 --- a/umap/static/umap/js/modules/panel.js +++ b/umap/static/umap/js/modules/panel.js @@ -1,48 +1,46 @@ +import { DomUtil, DomEvent } from '../../vendors/leaflet/leaflet-src.esm.js' +import { translate } from './i18n.js' + export class Panel { MODE = 'condensed' CLASSNAME = 'left' + constructor(parent) { this.parent = parent - this.container = L.DomUtil.create('div', '', this.parent) - L.DomEvent.disableClickPropagation(this.container) - L.DomEvent.on(this.container, 'contextmenu', L.DomEvent.stopPropagation) // Do not activate our custom context menu. - L.DomEvent.on(this.container, 'wheel', L.DomEvent.stopPropagation) - L.DomEvent.on(this.container, 'MozMousePixelScroll', L.DomEvent.stopPropagation) - } - - resetClassName() { - this.container.className = `with-transition panel ${this.CLASSNAME} ${this.MODE}` + this.container = DomUtil.create('div', '', this.parent) + DomEvent.disableClickPropagation(this.container) + DomEvent.on(this.container, 'contextmenu', DomEvent.stopPropagation) // Do not activate our custom context menu. + DomEvent.on(this.container, 'wheel', DomEvent.stopPropagation) + DomEvent.on(this.container, 'MozMousePixelScroll', DomEvent.stopPropagation) } open(e) { //this.fire('panel:open') - // We reset all because we can't know which class has been added - // by previous ui processes... - this.resetClassName() + this.container.className = `with-transition panel ${this.CLASSNAME} ${this.MODE}` this.container.innerHTML = '' - const actionsContainer = L.DomUtil.create('ul', 'toolbox', this.container) - const body = L.DomUtil.create('div', 'body', this.container) + const actionsContainer = DomUtil.create('ul', 'toolbox', this.container) + const body = DomUtil.create('div', 'body', this.container) if (e.data.html.nodeType && e.data.html.nodeType === 1) body.appendChild(e.data.html) else body.innerHTML = e.data.html - const closeLink = L.DomUtil.create('li', 'umap-close-link', actionsContainer) - L.DomUtil.add('i', 'icon icon-16 icon-close', closeLink) - closeLink.title = L._('Close') - const resizeLink = L.DomUtil.create('li', 'umap-resize-link', actionsContainer) - L.DomUtil.add('i', 'icon icon-16 icon-resize', resizeLink) - resizeLink.title = L._('Toggle size') + const closeLink = DomUtil.create('li', 'umap-close-link', actionsContainer) + DomUtil.add('i', 'icon icon-16 icon-close', closeLink) + closeLink.title = translate('Close') + const resizeLink = DomUtil.create('li', 'umap-resize-link', actionsContainer) + DomUtil.add('i', 'icon icon-16 icon-resize', resizeLink) + resizeLink.title = translate('Toggle size') if (e.actions) { for (let i = 0; i < e.actions.length; i++) { actionsContainer.appendChild(e.actions[i]) } } - if (e.className) L.DomUtil.addClass(this.container, e.className) - if (L.DomUtil.hasClass(this.container, 'on')) { + if (e.className) DomUtil.addClass(body, e.className) + if (DomUtil.hasClass(this.container, 'on')) { // Already open. //this.fire('panel:ready') } else { - L.DomEvent.once( + DomEvent.once( this.container, 'transitionend', function (e) { @@ -50,10 +48,10 @@ export class Panel { }, this ) - L.DomUtil.addClass(this.container, 'on') + DomUtil.addClass(this.container, 'on') } - L.DomEvent.on(closeLink, 'click', this.close, this) - L.DomEvent.on(resizeLink, 'click', this.resize, this) + DomEvent.on(closeLink, 'click', this.close, this) + DomEvent.on(resizeLink, 'click', this.resize, this) } resize() { @@ -69,8 +67,8 @@ export class Panel { } close() { - if (L.DomUtil.hasClass(this.container, 'on')) { - L.DomUtil.removeClass(this.container, 'on') + if (DomUtil.hasClass(this.container, 'on')) { + DomUtil.removeClass(this.container, 'on') //this.fire('panel:closed') } } From 44bae50c85c3680a225e68d02fc82cc94c98a221 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Fri, 15 Mar 2024 11:35:42 +0100 Subject: [PATCH 22/44] chore: remove remaining openPanel/closePanel calls --- umap/static/umap/js/umap.controls.js | 7 ++----- umap/static/umap/js/umap.js | 3 ++- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js index 45ce42e3..e1710f3e 100644 --- a/umap/static/umap/js/umap.controls.js +++ b/umap/static/umap/js/umap.controls.js @@ -598,7 +598,7 @@ U.DataLayer.include({ if (!this.isVisible()) return if (!confirm(L._('Are you sure you want to delete this layer?'))) return this._delete() - this.map.ui.closePanel() + this.map.editPanel.close() }, this ) @@ -898,10 +898,7 @@ const ControlsMixin = { 'leaflet-control-edit-disable', rightContainer, L.DomUtil.add('span', '', null, L._('View')), - function (e) { - this.disableEdit(e) - this.ui.closePanel() - }, + this.disableEdit, this ) L.DomEvent.on( diff --git a/umap/static/umap/js/umap.js b/umap/static/umap/js/umap.js index 5b3e663b..0ff863d5 100644 --- a/umap/static/umap/js/umap.js +++ b/umap/static/umap/js/umap.js @@ -541,7 +541,6 @@ U.Map = L.Map.extend({ } else if (key === U.Keys.E && modifierKey && this.editEnabled && !this.isDirty) { L.DomEvent.stop(e) this.disableEdit() - this.ui.closePanel() } if (key === U.Keys.S && modifierKey) { L.DomEvent.stop(e) @@ -1571,6 +1570,8 @@ U.Map = L.Map.extend({ this.editedFeature = null this.editEnabled = false this.fire('edit:disabled') + this.editPanel.close() + this.fullPanel.close() }, hasEditMode: function () { From 7fd2f0ded9ed4ebbc9976a5d18acf2d441f7e12e Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Fri, 15 Mar 2024 11:36:07 +0100 Subject: [PATCH 23/44] chore: fix drag class --- umap/static/umap/js/modules/orderable.js | 2 +- umap/static/umap/js/umap.controls.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/umap/static/umap/js/modules/orderable.js b/umap/static/umap/js/modules/orderable.js index 76334581..850d0304 100644 --- a/umap/static/umap/js/modules/orderable.js +++ b/umap/static/umap/js/modules/orderable.js @@ -35,7 +35,7 @@ export default class Orderable { // e.target is the source node. const realSrc = document.elementFromPoint(e.clientX, e.clientY); // Only allow drag from the handle - if (!realSrc.classList.contains('drag-handle')) { + if (!realSrc.classList.contains('icon-drag')) { e.preventDefault() return } diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js index e1710f3e..b16d6fe3 100644 --- a/umap/static/umap/js/umap.controls.js +++ b/umap/static/umap/js/umap.controls.js @@ -327,7 +327,6 @@ U.DrawToolbar = L.Toolbar.Control.extend({ }, }) - U.DropControl = L.Class.extend({ initialize: function (map) { this.map = map From 581f7134fd5ec3e5821e1454a23ccd940c60db67 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Fri, 15 Mar 2024 14:28:20 +0100 Subject: [PATCH 24/44] chore: fix integration tests --- umap/static/umap/js/modules/panel.js | 27 +++++++------------ umap/static/umap/js/modules/request.js | 1 - umap/static/umap/js/umap.controls.js | 4 +-- umap/static/umap/js/umap.features.js | 14 +++++----- umap/static/umap/js/umap.forms.js | 2 +- umap/static/umap/js/umap.importer.js | 6 +++-- umap/static/umap/js/umap.js | 17 +++++++----- umap/static/umap/js/umap.layer.js | 2 +- umap/static/umap/js/umap.permissions.js | 2 +- umap/static/umap/test/DataLayer.js | 2 +- umap/static/umap/test/TableEditor.js | 18 ++++++------- .../integration/test_anonymous_owned_map.py | 7 ++--- umap/tests/integration/test_browser.py | 10 +++---- umap/tests/integration/test_edit_datalayer.py | 6 ++--- umap/tests/integration/test_import.py | 8 +++--- umap/tests/integration/test_map.py | 6 ++--- umap/tests/integration/test_owned_map.py | 2 +- umap/tests/integration/test_picto.py | 4 +-- umap/tests/integration/test_querystring.py | 3 ++- 19 files changed, 71 insertions(+), 70 deletions(-) diff --git a/umap/static/umap/js/modules/panel.js b/umap/static/umap/js/modules/panel.js index 7839f7f0..4268a527 100644 --- a/umap/static/umap/js/modules/panel.js +++ b/umap/static/umap/js/modules/panel.js @@ -5,7 +5,6 @@ export class Panel { MODE = 'condensed' CLASSNAME = 'left' - constructor(parent) { this.parent = parent this.container = DomUtil.create('div', '', this.parent) @@ -16,7 +15,6 @@ export class Panel { } open(e) { - //this.fire('panel:open') this.container.className = `with-transition panel ${this.CLASSNAME} ${this.MODE}` this.container.innerHTML = '' const actionsContainer = DomUtil.create('ul', 'toolbox', this.container) @@ -36,22 +34,18 @@ export class Panel { } } if (e.className) DomUtil.addClass(body, e.className) - if (DomUtil.hasClass(this.container, 'on')) { - // Already open. - //this.fire('panel:ready') - } else { - DomEvent.once( - this.container, - 'transitionend', - function (e) { - //this.fire('panel:ready') - }, - this - ) - DomUtil.addClass(this.container, 'on') - } + const promise = new Promise((resolve, reject) => { + if (DomUtil.hasClass(this.container, 'on')) { + // Already open. + resolve() + } else { + DomEvent.once(this.container, 'transitionend', resolve) + DomUtil.addClass(this.container, 'on') + } + }) DomEvent.on(closeLink, 'click', this.close, this) DomEvent.on(resizeLink, 'click', this.resize, this) + return promise } resize() { @@ -69,7 +63,6 @@ export class Panel { close() { if (DomUtil.hasClass(this.container, 'on')) { DomUtil.removeClass(this.container, 'on') - //this.fire('panel:closed') } } } diff --git a/umap/static/umap/js/modules/request.js b/umap/static/umap/js/modules/request.js index d21759ed..a12d5b76 100644 --- a/umap/static/umap/js/modules/request.js +++ b/umap/static/umap/js/modules/request.js @@ -128,7 +128,6 @@ export class ServerRequest extends Request { const data = await response.json() if (data.info) { this.ui.alert({ content: data.info, level: 'info' }) - this.ui.closePanel() } else if (data.error) { this.ui.alert({ content: data.error, level: 'error' }) return this._onError(new Error(data.error)) diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js index b16d6fe3..0b2b4204 100644 --- a/umap/static/umap/js/umap.controls.js +++ b/umap/static/umap/js/umap.controls.js @@ -33,7 +33,7 @@ U.EditLayersAction = U.BaseAction.extend({ options: { helpMenu: true, className: 'umap-control-browse dark', - tooltip: L._('See layers'), + tooltip: L._('Manage layers'), }, addHooks: function () { @@ -1252,7 +1252,7 @@ U.Search = L.PhotonSearch.extend({ onSelected: function (feature) { this.zoomToFeature(feature) - this.map.ui.closePanel() + this.map.panel.close() }, }) diff --git a/umap/static/umap/js/umap.features.js b/umap/static/umap/js/umap.features.js index 34087abb..e5c86887 100644 --- a/umap/static/umap/js/umap.features.js +++ b/umap/static/umap/js/umap.features.js @@ -126,13 +126,13 @@ U.FeatureMixin = { callback: this._redraw, // In case we have dynamic options… }) container.appendChild(builder.build()) - this.map.ui.once('panel:ready', () => { - builder.helpers['properties.name'].input.focus() - }) this.appendEditFieldsets(container) const advancedActions = L.DomUtil.createFieldset(container, L._('Advanced actions')) this.getAdvancedEditActions(advancedActions) - this.map.editPanel.open({ data: { html: container } }) + const onLoad = this.map.editPanel.open({ data: { html: container } }) + onLoad.then(() => { + builder.helpers['properties.name'].input.focus() + }) this.map.editedFeature = this if (!this.isOnScreen()) this.zoomTo(e) }, @@ -144,7 +144,7 @@ U.FeatureMixin = { L._('Delete'), function (e) { L.DomEvent.stop(e) - if (this.confirmDelete()) this.map.ui.closePanel() + if (this.confirmDelete()) this.map.editPanel.close() }, this ) @@ -462,7 +462,7 @@ U.FeatureMixin = { this.parentClass.prototype.onRemove.call(this, map) if (this.map.editedFeature === this) { this.endEdit() - this.map.ui.closePanel() + this.map.editPanel.close() } }, @@ -754,7 +754,7 @@ U.PathMixin = { if (this.map.editEnabled) { if (this.editEnabled()) { this.endEdit() - this.map.ui.closePanel() + this.map.editPanel.close() } else { this.edit(e) } diff --git a/umap/static/umap/js/umap.forms.js b/umap/static/umap/js/umap.forms.js index acd10c61..f29460fd 100644 --- a/umap/static/umap/js/umap.forms.js +++ b/umap/static/umap/js/umap.forms.js @@ -1036,6 +1036,6 @@ U.FormBuilder = L.FormBuilder.extend({ }, finish: function () { - this.map.ui.closePanel() + this.map.editPanel.close() }, }) diff --git a/umap/static/umap/js/umap.importer.js b/umap/static/umap/js/umap.importer.js index ff5237b1..ec1aea09 100644 --- a/umap/static/umap/js/umap.importer.js +++ b/umap/static/umap/js/umap.importer.js @@ -20,7 +20,6 @@ U.Importer = L.Class.extend({ { type: 'file', multiple: 'multiple', autofocus: true }, this.fileBox ) - this.map.ui.once('panel:closed', () => (this.fileInput.value = null)) this.urlInput = L.DomUtil.element( 'input', { type: 'text', placeholder: L._('Provide an URL here') }, @@ -121,7 +120,10 @@ U.Importer = L.Class.extend({ open: function () { if (!this.container) this.build() - this.map.editPanel.open({ data: { html: this.container } }) + const onLoad = this.map.editPanel.open({ data: { html: this.container } }) + onLoad.then(() => { + this.fileInput.value = null + }) }, openFiles: function () { diff --git a/umap/static/umap/js/umap.js b/umap/static/umap/js/umap.js index 0ff863d5..997acd13 100644 --- a/umap/static/umap/js/umap.js +++ b/umap/static/umap/js/umap.js @@ -222,12 +222,13 @@ U.Map = L.Map.extend({ if (L.Util.queryString('share')) { this.share.open() } else if (this.options.onLoadPanel === 'databrowser') { + this.panel.MODE = 'expanded' this.openBrowser() } else if (this.options.onLoadPanel === 'datalayers') { - this.ui.PANEL_MODE = 'condensed' + this.panel.MODE = 'condensed' this.openBrowser() } else if (this.options.onLoadPanel === 'caption') { - this.ui.PANEL_MODE = 'condensed' + this.panel.MODE = 'condensed' this.displayCaption() } else if (['facet', 'datafilters'].includes(this.options.onLoadPanel)) { this.openFacet() @@ -528,8 +529,13 @@ U.Map = L.Map.extend({ L.DomEvent.stop(e) this.search() } else if (e.keyCode === U.Keys.ESC) { - if (this.help.visible()) this.help.hide() - else this.ui.closePanel() + if (this.help.visible()) { + this.help.hide() + } else { + this.panel.close() + this.editPanel.close() + this.fullPanel.close() + } } if (!this.hasEditMode()) return @@ -1629,8 +1635,7 @@ U.Map = L.Map.extend({ askForReset: function (e) { if (!confirm(L._('Are you sure you want to cancel your changes?'))) return this.reset() - this.disableEdit(e) - this.ui.closePanel() + this.disableEdit() }, startMarker: function () { diff --git a/umap/static/umap/js/umap.layer.js b/umap/static/umap/js/umap.layer.js index dad7a770..53861317 100644 --- a/umap/static/umap/js/umap.layer.js +++ b/umap/static/umap/js/umap.layer.js @@ -1347,7 +1347,7 @@ U.DataLayer = L.Evented.extend({ L._('Delete'), function () { this._delete() - this.map.ui.closePanel() + this.map.editPanel.close() }, this ) diff --git a/umap/static/umap/js/umap.permissions.js b/umap/static/umap/js/umap.permissions.js index 00a25bd2..cd6aa214 100644 --- a/umap/static/umap/js/umap.permissions.js +++ b/umap/static/umap/js/umap.permissions.js @@ -137,7 +137,7 @@ U.MapPermissions = L.Class.extend({ content: L._('Map has been attached to your account'), level: 'info', }) - this.map.ui.closePanel() + this.map.editPanel.close() } }, diff --git a/umap/static/umap/test/DataLayer.js b/umap/static/umap/test/DataLayer.js index 93cf8a09..26ba7d61 100644 --- a/umap/static/umap/test/DataLayer.js +++ b/umap/static/umap/test/DataLayer.js @@ -126,7 +126,7 @@ describe('U.DataLayer', () => { }) it('should have a new layer button', () => { - newLayerButton = qs('#umap-panel .add-datalayer') + newLayerButton = qs('.panel.right.on .add-datalayer') assert.ok(newLayerButton) }) diff --git a/umap/static/umap/test/TableEditor.js b/umap/static/umap/test/TableEditor.js index 88d828bb..ef53362b 100644 --- a/umap/static/umap/test/TableEditor.js +++ b/umap/static/umap/test/TableEditor.js @@ -34,9 +34,9 @@ describe('L.TableEditor', () => { it('should open table button click', () => { happen.click(button) - expect(qs('#umap-panel div.table')).to.be.ok - expect(qsa('#umap-panel div.table form').length).to.eql(3) // One per feature. - expect(qsa('#umap-panel div.table input').length).to.eql(3) // One per feature and per property. + expect(qs('.panel.full.on div.table')).to.be.ok + expect(qsa('.panel.full.on div.table form').length).to.eql(3) // One per feature. + expect(qsa('.panel.full.on div.table input').length).to.eql(3) // One per feature and per property. }) }) describe('#properties()', () => { @@ -53,10 +53,10 @@ describe('L.TableEditor', () => { } var oldPrompt = window.prompt window.prompt = newPrompt - var button = qs('#umap-panel .add-property') + var button = qs('.panel.full.on .add-property') expect(button).to.be.ok happen.click(button) - expect(qsa('#umap-panel div.table input').length).to.eql(6) // One per feature and per property. + expect(qsa('.panel.full.on div.table input').length).to.eql(6) // One per feature and per property. window.prompt = oldPrompt }) @@ -74,10 +74,10 @@ describe('L.TableEditor', () => { } var oldPrompt = window.prompt window.prompt = newPrompt - var button = qs('#umap-panel div.thead div.tcell:last-of-type .umap-edit') + var button = qs('.panel.full.on div.thead div.tcell:last-of-type .umap-edit') expect(button).to.be.ok happen.click(button) - expect(qsa('#umap-panel div.table input').length).to.eql(6) + expect(qsa('.panel.full.on div.table input').length).to.eql(6) expect(feature.properties.newprop).to.be.undefined expect(feature.properties.newname).to.eql('the value') window.prompt = oldPrompt @@ -91,12 +91,12 @@ describe('L.TableEditor', () => { oldConfirm = window.confirm window.confirm = newConfirm var button = qs( - '#umap-panel div.thead div.tcell:last-of-type .umap-delete' + '.panel.full.on div.thead div.tcell:last-of-type .umap-delete' ) expect(button).to.be.ok happen.click(button) FEATURE = feature - expect(qsa('#umap-panel div.table input').length).to.eql(3) + expect(qsa('.panel.full.on div.table input').length).to.eql(3) expect(feature.properties.newname).to.be.undefined window.confirm = oldConfirm }) diff --git a/umap/tests/integration/test_anonymous_owned_map.py b/umap/tests/integration/test_anonymous_owned_map.py index 70b90972..ad14dc72 100644 --- a/umap/tests/integration/test_anonymous_owned_map.py +++ b/umap/tests/integration/test_anonymous_owned_map.py @@ -114,12 +114,13 @@ def test_anonymous_can_add_marker_on_editable_layer( marker = page.locator(".leaflet-marker-icon") map_el = page.locator("#map") expect(marker).to_have_count(2) - expect(map_el).not_to_have_class(re.compile("umap-ui")) + panel = page.locator('.panel.right.on') + expect(panel).to_be_hidden() add_marker.click() map_el.click(position={"x": 100, "y": 100}) expect(marker).to_have_count(3) # Edit panel is open - expect(map_el).to_have_class(re.compile("umap-ui")) + expect(panel).to_be_visible() datalayer_select = page.locator("select[name='datalayer']") expect(datalayer_select).to_be_visible() options = page.locator("select[name='datalayer'] option") @@ -131,7 +132,7 @@ def test_anonymous_can_add_marker_on_editable_layer( def test_can_change_perms_after_create(tilelayer, live_server, page): page.goto(f"{live_server.url}/en/map/new") # Create a layer - page.get_by_title("See layers").click() + page.get_by_title("Manage layers").click() page.get_by_title("Add a layer").click() page.locator("input[name=name]").fill("Layer 1") save = page.get_by_role("button", name="Save") diff --git a/umap/tests/integration/test_browser.py b/umap/tests/integration/test_browser.py index 5241a548..11a31460 100644 --- a/umap/tests/integration/test_browser.py +++ b/umap/tests/integration/test_browser.py @@ -159,7 +159,7 @@ def test_data_browser_bbox_filter_should_be_persistent( el = page.get_by_text("Current map view") expect(el).to_be_visible() el.click() - browser = page.locator("#umap-panel") + browser = page.locator(".panel.left.on") expect(browser.get_by_text("one point in france")).to_be_visible() expect(browser.get_by_text("one line in new zeland")).to_be_hidden() expect(browser.get_by_text("one polygon in greenland")).to_be_hidden() @@ -184,7 +184,7 @@ def test_data_browser_bbox_filtered_is_clickable(live_server, page, bootstrap, m el = page.get_by_text("Current map view") expect(el).to_be_visible() el.click() - browser = page.locator("#umap-panel") + browser = page.locator(".panel.left.on") expect(browser.get_by_text("one point in france")).to_be_visible() expect(browser.get_by_text("one line in new zeland")).to_be_hidden() expect(browser.get_by_text("one polygon in greenland")).to_be_hidden() @@ -236,7 +236,7 @@ def test_should_redraw_list_on_feature_delete(live_server, openmap, page, bootst page.goto(f"{live_server.url}{openmap.get_absolute_url()}") # Enable edit page.get_by_role("button", name="Edit").click() - buttons = page.locator(".umap-browser .datalayer li .feature-delete") + buttons = page.locator(".umap-browser .datalayer li .icon-delete") expect(buttons).to_have_count(3) page.on("dialog", lambda dialog: dialog.accept()) buttons.nth(0).click() @@ -282,7 +282,7 @@ def test_should_allow_to_toggle_datalayer_visibility(live_server, map, page, boo paths = page.locator(".leaflet-overlay-pane path") expect(markers).to_have_count(1) expect(paths).to_have_count(2) - toggle = page.locator("#umap-ui-container").get_by_title("Show/hide layer") + toggle = page.locator(".umap-browser").get_by_title("Show/hide layer") toggle.click() expect(markers).to_have_count(0) expect(paths).to_have_count(0) @@ -290,7 +290,7 @@ def test_should_allow_to_toggle_datalayer_visibility(live_server, map, page, boo def test_should_have_edit_buttons_in_edit_mode(live_server, openmap, page, bootstrap): page.goto(f"{live_server.url}{openmap.get_absolute_url()}") - browser = page.locator("#umap-ui-container") + browser = page.locator(".umap-browser") edit_layer = browser.get_by_title("Edit", exact=True) in_table = browser.get_by_title("Edit properties in a table") delete_layer = browser.get_by_title("Delete layer") diff --git a/umap/tests/integration/test_edit_datalayer.py b/umap/tests/integration/test_edit_datalayer.py index 824a8327..14242126 100644 --- a/umap/tests/integration/test_edit_datalayer.py +++ b/umap/tests/integration/test_edit_datalayer.py @@ -12,15 +12,13 @@ def test_should_have_fieldset_for_layer_type_properties(page, live_server, tilel page.goto(f"{live_server.url}/en/map/new/") # Open DataLayers list - button = page.get_by_title("See layers") - expect(button).to_be_visible() - button.click() + page.get_by_title("Manage layers").click() # Create a layer page.get_by_title("Add a layer").click() page.locator("input[name=name]").fill("Layer 1") - select = page.locator("#umap-panel .umap-field-type select") + select = page.locator(".panel.on .umap-field-type select") expect(select).to_be_visible() choropleth_header = page.get_by_text("Choropleth: settings") diff --git a/umap/tests/integration/test_import.py b/umap/tests/integration/test_import.py index e780750c..32fb378a 100644 --- a/umap/tests/integration/test_import.py +++ b/umap/tests/integration/test_import.py @@ -1,5 +1,6 @@ import json import re +from time import sleep from pathlib import Path import pytest @@ -12,9 +13,7 @@ pytestmark = pytest.mark.django_db def test_umap_import_from_file(live_server, tilelayer, page): page.goto(f"{live_server.url}/map/new/") - button = page.get_by_title("Import data") - expect(button).to_be_visible() - button.click() + page.get_by_title("Import data").click() file_input = page.locator("input[type='file']") with page.expect_file_chooser() as fc_info: file_input.click() @@ -27,6 +26,9 @@ def test_umap_import_from_file(live_server, tilelayer, page): assert file_input.input_value() # Close the import panel page.keyboard.press("Escape") + # Reopen + page.get_by_title("Import data").click() + sleep(1) # Wait for CSS transition to happen assert not file_input.input_value() expect(page.locator(".umap-main-edit-toolbox .map-name")).to_have_text( "Carte sans nom" diff --git a/umap/tests/integration/test_map.py b/umap/tests/integration/test_map.py index 90b691bc..8ede6547 100644 --- a/umap/tests/integration/test_map.py +++ b/umap/tests/integration/test_map.py @@ -179,7 +179,7 @@ def test_remote_layer_should_not_be_used_as_datalayer_for_created_features( marker = page.locator(".leaflet-marker-icon") expect(marker).to_have_count(0) add_marker.click() - map_el.click(position={"x": 100, "y": 100}) + map_el.click(position={"x": 500, "y": 100}) expect(marker).to_have_count(1) # A new datalayer has been created to host this created feature # given the remote one cannot accept new features @@ -196,9 +196,9 @@ def test_can_hide_datalayer_from_caption(openmap, live_server, datalayer, page): toggle.click() layers = page.locator(".umap-caption .datalayer-legend") expect(layers).to_have_count(1) - found = page.locator("#umap-panel").get_by_text(datalayer.name) + found = page.locator(".panel.left.on").get_by_text(datalayer.name) expect(found).to_be_visible() - hidden = page.locator("#umap-panel").get_by_text(other.name) + hidden = page.locator(".panel.left.on").get_by_text(other.name) expect(hidden).to_be_hidden() diff --git a/umap/tests/integration/test_owned_map.py b/umap/tests/integration/test_owned_map.py index e30b3ba6..7071e556 100644 --- a/umap/tests/integration/test_owned_map.py +++ b/umap/tests/integration/test_owned_map.py @@ -186,7 +186,7 @@ def test_can_change_perms_after_create(tilelayer, live_server, login, user): page = login(user) page.goto(f"{live_server.url}/en/map/new") # Create a layer - page.get_by_title("See layers").click() + page.get_by_title("Manage layers").click() page.get_by_title("Add a layer").click() page.locator("input[name=name]").fill("Layer 1") save = page.get_by_role("button", name="Save") diff --git a/umap/tests/integration/test_picto.py b/umap/tests/integration/test_picto.py index 808a9d04..b8541f8b 100644 --- a/umap/tests/integration/test_picto.py +++ b/umap/tests/integration/test_picto.py @@ -171,7 +171,7 @@ def test_can_use_remote_url_as_picto(openmap, live_server, page, pictos): input_el.blur() expect(marker).to_have_attribute("src", "https://foo.bar/img.jpg") # Now close and reopen the form, it should still be the URL tab - close = page.locator("#umap-panel .toolbox").get_by_title("Close") + close = page.locator(".panel.right.on .toolbox").get_by_title("Close") expect(close).to_be_visible() close.click() edit_settings.click() @@ -210,7 +210,7 @@ def test_can_use_char_as_picto(openmap, live_server, page, pictos): expect(marker).to_have_count(1) expect(marker).to_have_text("♩") # Now close and reopen the form, it should still be the URL tab - close = page.locator("#umap-panel .toolbox").get_by_title("Close") + close = page.locator(".panel.right.on .toolbox").get_by_title("Close") expect(close).to_be_visible() close.click() edit_settings.click() diff --git a/umap/tests/integration/test_querystring.py b/umap/tests/integration/test_querystring.py index 1393a89b..d4199e90 100644 --- a/umap/tests/integration/test_querystring.py +++ b/umap/tests/integration/test_querystring.py @@ -29,8 +29,9 @@ def test_datalayers_control(map, live_server, datalayer, page): page.goto(f"{live_server.url}{map.get_absolute_url()}?datalayersControl=false") expect(control).to_be_hidden() expect(browser).to_be_hidden() + # Retrocompat page.goto(f"{live_server.url}{map.get_absolute_url()}?datalayersControl=expanded") - expect(control).to_be_hidden() + expect(control).to_be_visible() expect(browser).to_be_visible() From 46016cb10b541d3692c84db3a181473b3738164b Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Fri, 15 Mar 2024 17:04:01 +0100 Subject: [PATCH 25/44] chore: replace panel:xxx events --- umap/static/umap/css/icon.css | 2 +- umap/static/umap/js/modules/browser.js | 22 ++++++++++----------- umap/static/umap/js/modules/panel.js | 16 +++++++-------- umap/static/umap/js/umap.controls.js | 5 +---- umap/static/umap/js/umap.js | 27 +++++++++----------------- umap/static/umap/js/umap.layer.js | 5 +++++ umap/static/umap/map.css | 6 +++--- 7 files changed, 36 insertions(+), 47 deletions(-) diff --git a/umap/static/umap/css/icon.css b/umap/static/umap/css/icon.css index 39778ee1..07f0dd1e 100644 --- a/umap/static/umap/css/icon.css +++ b/umap/static/umap/css/icon.css @@ -80,7 +80,7 @@ background-position: -27px -120px; } .icon-settings { - background-position: -27px -93px; + background-position: -23px -97px; } .icon-share { background-position: 0px -120px; diff --git a/umap/static/umap/js/modules/browser.js b/umap/static/umap/js/modules/browser.js index 59fe52e4..ddddfaf5 100644 --- a/umap/static/umap/js/modules/browser.js +++ b/umap/static/umap/js/modules/browser.js @@ -61,10 +61,6 @@ export default class Browser { return `browse_data_datalayer_${L.stamp(datalayer)}` } - onDataLayerChanged(e) { - this.updateDatalayer(e.target) - } - addDataLayer(datalayer, parent) { let className = `datalayer ${datalayer.getHidableClass()}` if (this.map.panel.MODE !== 'condensed') className += ' show-list' @@ -73,10 +69,6 @@ export default class Browser { container.id = this.datalayerId(datalayer) const ul = DomUtil.create('ul', '', container) this.updateDatalayer(datalayer) - datalayer.on('datachanged', this.onDataLayerChanged, this) - this.map.ui.once('panel:closed', () => { - datalayer.off('datachanged', this.onDataLayerChanged, this) - }) } updateDatalayer(datalayer) { @@ -127,6 +119,14 @@ export default class Browser { }) } + update() { + if (!this.isOpen()) return + this.dataContainer.innerHTML = '' + this.map.eachBrowsableDataLayer((datalayer) => { + this.addDataLayer(datalayer, this.dataContainer) + }) + } + open() { // Get once but use it for each feature later this.filterKeys = this.map.getFilterKeys() @@ -137,7 +137,7 @@ export default class Browser { DomUtil.createTitle(container, translate('Browse data'), 'layers') const formContainer = DomUtil.create('div', '', container) - const dataContainer = DomUtil.create('div', '', container) + this.dataContainer = DomUtil.create('div', '', container) const fields = [ ['options.filter', { handler: 'Input', placeholder: translate('Filter') }], @@ -154,9 +154,7 @@ export default class Browser { className: 'umap-browser', }) - this.map.eachBrowsableDataLayer((datalayer) => { - this.addDataLayer(datalayer, dataContainer) - }) + this.update() } static backButton(map) { diff --git a/umap/static/umap/js/modules/panel.js b/umap/static/umap/js/modules/panel.js index 4268a527..b83d703d 100644 --- a/umap/static/umap/js/modules/panel.js +++ b/umap/static/umap/js/modules/panel.js @@ -5,8 +5,9 @@ export class Panel { MODE = 'condensed' CLASSNAME = 'left' - constructor(parent) { - this.parent = parent + constructor(map) { + this.parent = map._container + this.map = map this.container = DomUtil.create('div', '', this.parent) DomEvent.disableClickPropagation(this.container) DomEvent.on(this.container, 'contextmenu', DomEvent.stopPropagation) // Do not activate our custom context menu. @@ -35,13 +36,8 @@ export class Panel { } if (e.className) DomUtil.addClass(body, e.className) const promise = new Promise((resolve, reject) => { - if (DomUtil.hasClass(this.container, 'on')) { - // Already open. - resolve() - } else { - DomEvent.once(this.container, 'transitionend', resolve) - DomUtil.addClass(this.container, 'on') - } + DomUtil.addClass(this.container, 'on') + resolve() }) DomEvent.on(closeLink, 'click', this.close, this) DomEvent.on(resizeLink, 'click', this.resize, this) @@ -63,6 +59,8 @@ export class Panel { close() { if (DomUtil.hasClass(this.container, 'on')) { DomUtil.removeClass(this.container, 'on') + this.map.invalidateSize({ pan: false }) + this.map.editedFeature = null } } } diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js index 0b2b4204..405c32ef 100644 --- a/umap/static/umap/js/umap.controls.js +++ b/umap/static/umap/js/umap.controls.js @@ -1298,10 +1298,7 @@ U.SearchControl = L.Control.extend({ this.map.fire('dataload', { id: id }) }) this.search.resultsContainer = resultsContainer - this.map.ui.once('panel:ready', () => { - input.focus() - }) - this.map.panel.open({ data: { html: container } }) + this.map.panel.open({ data: { html: container } }).then(input.focus) }, }) diff --git a/umap/static/umap/js/umap.js b/umap/static/umap/js/umap.js index 997acd13..89e0d1a6 100644 --- a/umap/static/umap/js/umap.js +++ b/umap/static/umap/js/umap.js @@ -56,10 +56,10 @@ U.Map = L.Map.extend({ if (geojson.geometry) this.options.center = this.latLng(geojson.geometry) this.urls = new U.URLs(this.options.urls) - this.panel = new U.Panel(this._container) + this.panel = new U.Panel(this) if (this.hasEditMode()) { - this.editPanel = new U.EditPanel(this._container) - this.fullPanel = new U.FullPanel(this._container) + this.editPanel = new U.EditPanel(this) + this.fullPanel = new U.FullPanel(this) } this.ui = new U.UI(this._container) this.ui.on('dataloading', (e) => this.fire('dataloading', e)) @@ -149,14 +149,6 @@ U.Map = L.Map.extend({ this.options.onLoadPanel = 'datalayers' } - this.ui.on( - 'panel:closed', - function () { - this.invalidateSize({ pan: false }) - }, - this - ) - let isDirty = false // self status try { Object.defineProperty(this, 'isDirty', { @@ -208,13 +200,6 @@ U.Map = L.Map.extend({ this.initCaptionBar() if (this.hasEditMode()) { this.editTools = new U.Editable(this) - this.ui.on( - 'panel:closed panel:open', - function () { - this.editedFeature = null - }, - this - ) this.renderEditToolbar() } this.initShortcuts() @@ -478,6 +463,11 @@ U.Map = L.Map.extend({ if (!pane.dataset || !pane.dataset.id) continue this.datalayers_index.push(this.datalayers[pane.dataset.id]) } + this.onDataLayersChanged() + }, + + onDataLayersChanged: function () { + if (this.browser) this.browser.update() }, ensurePanesOrder: function () { @@ -971,6 +961,7 @@ U.Map = L.Map.extend({ this.dirty_datalayers = [] this.initTileLayers() this.isDirty = false + this.onDataLayersChanged() }, checkDirty: function () { diff --git a/umap/static/umap/js/umap.layer.js b/umap/static/umap/js/umap.layer.js index 53861317..c10c3bea 100644 --- a/umap/static/umap/js/umap.layer.js +++ b/umap/static/umap/js/umap.layer.js @@ -594,6 +594,7 @@ U.DataLayer = L.Evented.extend({ // Automatically, others will be shown manually, and thus will // be in the "forced visibility" mode if (this.autoLoaded()) this.map.on('zoomend', this.onZoomEnd, this) + this.on('datachanged', this.map.onDataLayersChanged, this.map) }, render: function (fields, builder) { @@ -845,6 +846,7 @@ U.DataLayer = L.Evented.extend({ if (L.Util.indexOf(this.map.datalayers_index, this) === -1) this.map.datalayers_index.push(this) } + this.map.onDataLayersChanged() }, _dataUrl: function () { @@ -1152,6 +1154,8 @@ U.DataLayer = L.Evented.extend({ delete this.map.datalayers[L.stamp(this)] this.map.datalayers_index.splice(this.getRank(), 1) this.parentPane.removeChild(this.pane) + this.map.onDataLayersChanged() + this.off('datachanged', this.map.onDataLayersChanged, this.map) this.fire('erase') this._leaflet_events_bk = this._leaflet_events this.map.off('moveend', this.onMoveEnd, this) @@ -1214,6 +1218,7 @@ U.DataLayer = L.Evented.extend({ L.DomUtil.createTitle(container, L._('Layer properties'), 'icon-layers') let builder = new U.FormBuilder(this, metadataFields, { callback: function (e) { + this.map.onDataLayersChanged() if (e.helper.field === 'options.type') { this.edit() } diff --git a/umap/static/umap/map.css b/umap/static/umap/map.css index c173f49e..00a0da91 100644 --- a/umap/static/umap/map.css +++ b/umap/static/umap/map.css @@ -660,7 +660,7 @@ ul.photon-autocomplete { display: inline-block; /* Prevents underline on hover. */ } .umap-edit-enabled .leaflet-top { - top: 48px; + top: 46px; } .umap-caption-bar-enabled .umap-caption-bar { display: block; @@ -935,7 +935,7 @@ a.umap-control-caption, .umap-browser.dark .datalayer li:nth-child(even) { background-color: #2c3233; } -.umap-browser .datalayer i.feature-color { +.umap-browser .datalayer .feature-color { box-shadow: 0 0 2px 0 black inset; cursor: inherit; -moz-box-sizing:border-box; @@ -948,7 +948,7 @@ a.umap-control-caption, text-align: center; margin-left: 5px; } -.umap-browser.dark .datalayer i.feature-color { +.umap-browser.dark .datalayer .feature-color { box-shadow: 0 0 2px 0 #999 inset; } .umap-browser .datalayer .feature-color img { From c5e3dfb95c7e87e033ea9be00a7f7a5c369cb3d1 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Fri, 15 Mar 2024 17:19:56 +0100 Subject: [PATCH 26/44] chore: fix JS syntax to be compatible with browser >= 2020 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Safari only supports public field since 2021… --- umap/static/umap/js/modules/panel.js | 25 +++++++++++++++---------- umap/static/umap/js/umap.js | 6 +++--- umap/tests/integration/test_import.py | 2 +- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/umap/static/umap/js/modules/panel.js b/umap/static/umap/js/modules/panel.js index b83d703d..d2ea1918 100644 --- a/umap/static/umap/js/modules/panel.js +++ b/umap/static/umap/js/modules/panel.js @@ -2,13 +2,12 @@ import { DomUtil, DomEvent } from '../../vendors/leaflet/leaflet-src.esm.js' import { translate } from './i18n.js' export class Panel { - MODE = 'condensed' - CLASSNAME = 'left' - constructor(map) { this.parent = map._container this.map = map this.container = DomUtil.create('div', '', this.parent) + this.mode = 'condensed' + this.classname = 'left' DomEvent.disableClickPropagation(this.container) DomEvent.on(this.container, 'contextmenu', DomEvent.stopPropagation) // Do not activate our custom context menu. DomEvent.on(this.container, 'wheel', DomEvent.stopPropagation) @@ -16,7 +15,7 @@ export class Panel { } open(e) { - this.container.className = `with-transition panel ${this.CLASSNAME} ${this.MODE}` + this.container.className = `with-transition panel ${this.classname} ${this.mode}` this.container.innerHTML = '' const actionsContainer = DomUtil.create('ul', 'toolbox', this.container) const body = DomUtil.create('div', 'body', this.container) @@ -45,12 +44,12 @@ export class Panel { } resize() { - if (this.MODE === 'expanded') { - this.MODE = 'condensed' + if (this.mode === 'expanded') { + this.mode = 'condensed' this.container.classList.remove('expanded') this.container.classList.add('condensed') } else { - this.MODE = 'expanded' + this.mode = 'expanded' this.container.classList.remove('condensed') this.container.classList.add('expanded') } @@ -66,10 +65,16 @@ export class Panel { } export class EditPanel extends Panel { - CLASSNAME = 'right dark' + constructor(map) { + super(map) + this.classname = 'right dark' + } } export class FullPanel extends Panel { - CLASSNAME = 'full dark' - MODE = 'expanded' + constructor(map) { + super(map) + this.classname = 'full dark' + this.mode = 'expanded' + } } diff --git a/umap/static/umap/js/umap.js b/umap/static/umap/js/umap.js index 89e0d1a6..7c6d8394 100644 --- a/umap/static/umap/js/umap.js +++ b/umap/static/umap/js/umap.js @@ -207,13 +207,13 @@ U.Map = L.Map.extend({ if (L.Util.queryString('share')) { this.share.open() } else if (this.options.onLoadPanel === 'databrowser') { - this.panel.MODE = 'expanded' + this.panel.mode = 'expanded' this.openBrowser() } else if (this.options.onLoadPanel === 'datalayers') { - this.panel.MODE = 'condensed' + this.panel.mode = 'condensed' this.openBrowser() } else if (this.options.onLoadPanel === 'caption') { - this.panel.MODE = 'condensed' + this.panel.mode = 'condensed' this.displayCaption() } else if (['facet', 'datafilters'].includes(this.options.onLoadPanel)) { this.openFacet() diff --git a/umap/tests/integration/test_import.py b/umap/tests/integration/test_import.py index 32fb378a..a50c7a1a 100644 --- a/umap/tests/integration/test_import.py +++ b/umap/tests/integration/test_import.py @@ -1,7 +1,7 @@ import json import re -from time import sleep from pathlib import Path +from time import sleep import pytest from playwright.sync_api import expect From 11cd61ff843fcedf062e1ce8182b0b7415af5ef1 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Fri, 15 Mar 2024 17:22:07 +0100 Subject: [PATCH 27/44] chore: remove useless back button from table editor --- umap/static/umap/js/umap.tableeditor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/umap/static/umap/js/umap.tableeditor.js b/umap/static/umap/js/umap.tableeditor.js index d856ecdf..d84e55ea 100644 --- a/umap/static/umap/js/umap.tableeditor.js +++ b/umap/static/umap/js/umap.tableeditor.js @@ -112,7 +112,7 @@ U.TableEditor = L.Class.extend({ this.datalayer.map.fullPanel.open({ data: { html: this.table }, className: 'umap-table-editor', - actions: [addButton, U.Browser.backButton(this.datalayer.map)], + actions: [addButton], }) }, }) From 737292ca768a01b04d4381654de68c747e00e981 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Fri, 15 Mar 2024 17:30:35 +0100 Subject: [PATCH 28/44] chore: remove unused CSS --- umap/static/umap/base.css | 100 ++++---------------------------------- 1 file changed, 9 insertions(+), 91 deletions(-) diff --git a/umap/static/umap/base.css b/umap/static/umap/base.css index 456b3063..b6dd76b9 100644 --- a/umap/static/umap/base.css +++ b/umap/static/umap/base.css @@ -276,6 +276,15 @@ input + .error { input[type="file"] + .error { margin-top: 0; } +input:invalid { + border-color: red; + background-color: darkred; +} +.dark input, .dark textarea { + background-color: #232729; + border-color: #1b1f20; + color: #efefef; +} .fieldset { margin-bottom: 5px; border-top-left-radius: 4px; @@ -681,101 +690,10 @@ input[type=hidden].blur + [type="button"] { .leaflet-ui-container { overflow-x: hidden; } -#umap-panel { - /* Added for playwright to consider the element as non visible */ - /* as being out of the visible viewport is not enough */ - visibility: hidden; - position: absolute; - bottom: 0; - border-left: 1px solid var(--color-lightGray); - overflow-x: auto; - z-index: 1010; - background-color: #fff; - opacity: 0.98; - cursor: initial; -} -#umap-panel.dark { - border-left: 1px solid #222; - background-color: var(--color-darkGray); - color: #efefef; -} -#umap-panel.fullwidth { - width: 100%; - right: -100%; - z-index: 10000; - padding-left: 0; - padding-right: 0; -} -.umap-caption-bar-enabled #umap-panel { - bottom: 46px; -} .leaflet-top, .leaflet-right { transition: all .7s; } -#umap-panel, -#umap-alert-container, -#umap-tooltip-container { - -moz-box-sizing:border-box; - -webkit-box-sizing:border-box; - box-sizing: border-box; -} -#umap-panel .umap-popup-content img { - /* See https://github.com/Leaflet/Leaflet/commit/61d746818b99d362108545c151a27f09d60960ee#commitcomment-6061847 */ - max-width: 99% !important; -} -#umap-panel .umap-popup-content { - max-height: inherit; -} -#umap-panel .body { - clear: both; - height: calc(100% - 32px); /* Minus size of toolbox */ - padding: 10px; -} -#umap-panel .toolbox { - padding: 5px 10px; - overflow: hidden; - display: flex; - flex-direction: row-reverse; - font-size: 10px; - justify-content: flex-start; - gap: 5px; - background-color: var(--color-lightGray); - border-bottom: 1px solid #bbb; - line-height: 2.2em; -} -#umap-panel.dark .toolbox { - background-color: var(--color-darkGray); - border-bottom: 1px solid #232729; -} -#umap-panel .toolbox li { - cursor: pointer; - display: inline; - padding: 0 2px; - border: 1px solid #b6b6b3; - border-radius: 2px; -} -#umap-panel.dark .toolbox -#umap-panel.dark .toolbox li { - color: #d3dfeb; - border: 1px solid #202425; -} -#umap-panel .toolbox li:hover { - background-color: #d4d4d2; -} -#umap-panel.dark .toolbox li:hover { - background-color: #353c3e; -} -.dark input, .dark textarea { - background-color: #232729; - border-color: #1b1f20; - /*box-shadow: inset 0 0 0 1px #215d9c;*/ - color: #efefef; -} -input:invalid { - border-color: red; - background-color: darkred; -} /* *********** */ From fa6919280449aa5a7ff836db4aaddc1e353f5eb9 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Fri, 15 Mar 2024 17:41:50 +0100 Subject: [PATCH 29/44] chore: add min-height for textarea --- umap/static/umap/base.css | 2 ++ umap/static/umap/content.css | 19 ------------------- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/umap/static/umap/base.css b/umap/static/umap/base.css index b6dd76b9..5c3993e5 100644 --- a/umap/static/umap/base.css +++ b/umap/static/umap/base.css @@ -163,6 +163,8 @@ input[type="checkbox"] { textarea { height: inherit; padding: 7px; + min-height: 15rem; + min-height: 6rlh; } select { border: 1px solid #222; diff --git a/umap/static/umap/content.css b/umap/static/umap/content.css index 17bb390c..8e8de671 100644 --- a/umap/static/umap/content.css +++ b/umap/static/umap/content.css @@ -17,22 +17,6 @@ input:-moz-placeholder, :-moz-placeholder { color: #a5a5a5; } -#umap-panel textarea { - height: 100px; - margin-bottom: 14px; -} -#umap-panel select { - margin-bottom: 10px; -} - -#umap-panel.warning .button { - background-color: #c60f13; - border: 1px solid #7f0a0c; -} -#umap-panel.warning .button:hover { - background-color: #970b0e; -} - /* **************** */ /* Login icons */ @@ -194,9 +178,6 @@ h2.tabs a:hover { color: #efefef; text-decoration: underline; } -body.content #umap-panel { - background-color: #fff; -} /* **************************** */ From 70cca268e8ba65604d78101b63da189a7dca7b00 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Fri, 15 Mar 2024 17:45:40 +0100 Subject: [PATCH 30/44] chore: fix icons in the dashboard --- umap/static/umap/content.css | 1 + 1 file changed, 1 insertion(+) diff --git a/umap/static/umap/content.css b/umap/static/umap/content.css index 8e8de671..bab0a051 100644 --- a/umap/static/umap/content.css +++ b/umap/static/umap/content.css @@ -337,6 +337,7 @@ ul.umap-autocomplete { height: 36px; width: 36px; margin: 3px; + background-position: initial; } .content .icon-view { background-image: url('./img/icon-view.svg'); From 2c248ea1240d4501237722d6e038dbe1d4625985 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Fri, 15 Mar 2024 17:47:58 +0100 Subject: [PATCH 31/44] chore: panel.MODE has been renamed to panel.mode --- umap/static/umap/js/modules/browser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/umap/static/umap/js/modules/browser.js b/umap/static/umap/js/modules/browser.js index ddddfaf5..f4a12184 100644 --- a/umap/static/umap/js/modules/browser.js +++ b/umap/static/umap/js/modules/browser.js @@ -63,7 +63,7 @@ export default class Browser { addDataLayer(datalayer, parent) { let className = `datalayer ${datalayer.getHidableClass()}` - if (this.map.panel.MODE !== 'condensed') className += ' show-list' + if (this.map.panel.mode !== 'condensed') className += ' show-list' const container = DomUtil.create('div', className, parent), headline = DomUtil.create('h5', '', container) container.id = this.datalayerId(datalayer) From c9acb22d6445fc7c78190c6374ccaa1322541a18 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Fri, 15 Mar 2024 18:00:30 +0100 Subject: [PATCH 32/44] chore: remove calls to L. from browser.js --- umap/static/umap/js/modules/browser.js | 59 +++++++++++++------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/umap/static/umap/js/modules/browser.js b/umap/static/umap/js/modules/browser.js index f4a12184..b61ff293 100644 --- a/umap/static/umap/js/modules/browser.js +++ b/umap/static/umap/js/modules/browser.js @@ -1,4 +1,4 @@ -import { DomUtil, DomEvent } from '../../vendors/leaflet/leaflet-src.esm.js' +import { DomUtil, DomEvent, stamp } from '../../vendors/leaflet/leaflet-src.esm.js' import { translate } from './i18n.js' export default class Browser { @@ -16,14 +16,26 @@ export default class Browser { if (filter && !feature.matchFilter(filter, this.filterKeys)) return if (this.options.inBbox && !feature.isOnScreen(this.bounds)) return const row = DomUtil.create('li', `${feature.getClassName()} feature`) - const zoom_to = DomUtil.createButtonIcon(row, 'icon-zoom', translate('Bring feature to center')) - const edit = DomUtil.createButtonIcon(row, 'show-on-edit icon-edit', translate('Edit this feature')) - const del = DomUtil.createButtonIcon(row, 'show-on-edit icon-delete', translate('Delete this feature')) + const zoom_to = DomUtil.createButtonIcon( + row, + 'icon-zoom', + translate('Bring feature to center') + ) + const edit = DomUtil.createButtonIcon( + row, + 'show-on-edit icon-edit', + translate('Edit this feature') + ) + const del = DomUtil.createButtonIcon( + row, + 'show-on-edit icon-delete', + translate('Delete this feature') + ) const colorBox = DomUtil.create('i', 'icon icon-16 feature-color', row) const title = DomUtil.create('span', 'feature-title', row) const symbol = feature._getIconUrl - ? U.Icon.prototype.formatUrl(feature._getIconUrl(), feature) - : null + ? U.Icon.prototype.formatUrl(feature._getIconUrl(), feature) + : null title.textContent = feature.getDisplayName() || '—' const bgcolor = feature.getDynamicOption('color') colorBox.style.backgroundColor = bgcolor @@ -31,24 +43,11 @@ export default class Browser { const icon = U.Icon.makeIconElement(symbol, colorBox) U.Icon.setIconContrast(icon, colorBox, symbol, bgcolor) } - DomEvent.on( - zoom_to, - 'click', - function (e) { - e.callback = L.bind(this.view, this) - this.zoomTo(e) - }, - feature - ) - DomEvent.on( - title, - 'click', - function (e) { - e.callback = L.bind(this.view, this) - this.zoomTo(e) - }, - feature - ) + const viewFeature = (e) => { + feature.zoomTo({...e, callback: feature.view}) + } + DomEvent.on(zoom_to, 'click', viewFeature) + DomEvent.on(title, 'click', viewFeature) DomEvent.on(edit, 'click', feature.edit, feature) DomEvent.on(del, 'click', feature.confirmDelete, feature) // HOTFIX. Remove when this is released: @@ -58,7 +57,7 @@ export default class Browser { } datalayerId(datalayer) { - return `browse_data_datalayer_${L.stamp(datalayer)}` + return `browse_data_datalayer_${stamp(datalayer)}` } addDataLayer(datalayer, parent) { @@ -158,13 +157,13 @@ export default class Browser { } static backButton(map) { - const button = L.DomUtil.create('li', '') - L.DomUtil.create('i', 'icon icon-16 icon-back', button) - button.title = L._('Back to browser') + const button = DomUtil.create('li', '') + DomUtil.create('i', 'icon icon-16 icon-back', button) + button.title = translate('Back to browser') // Fixme: remove me when this is merged and released // https://github.com/Leaflet/Leaflet/pull/9052 - L.DomEvent.disableClickPropagation(button) - L.DomEvent.on(button, 'click', map.openBrowser, map) + DomEvent.disableClickPropagation(button) + DomEvent.on(button, 'click', map.openBrowser, map) return button } } From 2f3d579079a41efa837a36e951496e2dbdc29a4e Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Fri, 15 Mar 2024 18:10:50 +0100 Subject: [PATCH 33/44] chore: make captionControl nullable in schema.js So it can be configured to appears in the "More" button --- umap/static/umap/js/modules/schema.js | 1 + 1 file changed, 1 insertion(+) diff --git a/umap/static/umap/js/modules/schema.js b/umap/static/umap/js/modules/schema.js index 97f3d777..e733739b 100644 --- a/umap/static/umap/js/modules/schema.js +++ b/umap/static/umap/js/modules/schema.js @@ -375,6 +375,7 @@ export const SCHEMA = { }, captionControl: { type: Boolean, + nullable: true, label: translate('Display the caption control'), default: true, }, From 8279ae8a62fd7c2404926da9908b6b8bc66c0a6e Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Fri, 15 Mar 2024 18:26:17 +0100 Subject: [PATCH 34/44] chore: put back order of edit buttons We'll certainly change them later, but for now let's create useless noise for users --- umap/static/umap/js/umap.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/umap/static/umap/js/umap.js b/umap/static/umap/js/umap.js index 7c6d8394..c2f31f67 100644 --- a/umap/static/umap/js/umap.js +++ b/umap/static/umap/js/umap.js @@ -320,10 +320,11 @@ U.Map = L.Map.extend({ if (this.hasEditMode() && !this.options.noControl) { new U.EditControl(this).addTo(this) + new U.DrawToolbar({ map: this }).addTo(this) const editActions = [ - U.EditLayersAction, U.EditCaptionAction, U.EditPropertiesAction, + U.EditLayersAction, U.ChangeTileLayerAction, U.UpdateExtentAction, U.UpdatePermsAction, @@ -333,7 +334,6 @@ U.Map = L.Map.extend({ new U.SettingsToolbar({ actions: editActions }).addTo(this) } - new U.DrawToolbar({ map: this }).addTo(this) } this._controls.zoom = new L.Control.Zoom({ zoomInTitle: L._('Zoom in'), From cd01e4085f2181aadb4f88db65da070c66f05d42 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Fri, 15 Mar 2024 18:26:49 +0100 Subject: [PATCH 35/44] chore: better align icon and title in panels --- umap/static/umap/css/panel.css | 3 +++ umap/static/umap/img/16.svg | 9 ++++++--- umap/static/umap/img/source/16.svg | 3 ++- umap/static/umap/js/modules/browser.js | 2 +- umap/static/umap/js/umap.core.js | 2 +- 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/umap/static/umap/css/panel.css b/umap/static/umap/css/panel.css index 58116c08..967f5d60 100644 --- a/umap/static/umap/css/panel.css +++ b/umap/static/umap/css/panel.css @@ -84,6 +84,9 @@ .panel.dark .toolbox li:hover { background-color: #353c3e; } +.panel h3 { + line-height: 3; +} @media all and (orientation:landscape) { .panel { top: 0; diff --git a/umap/static/umap/img/16.svg b/umap/static/umap/img/16.svg index bc8233a7..54d14015 100644 --- a/umap/static/umap/img/16.svg +++ b/umap/static/umap/img/16.svg @@ -179,8 +179,11 @@ - - - + + + + + + diff --git a/umap/static/umap/img/source/16.svg b/umap/static/umap/img/source/16.svg index ed3d4715..48b69f61 100644 --- a/umap/static/umap/img/source/16.svg +++ b/umap/static/umap/img/source/16.svg @@ -10,7 +10,7 @@ - + @@ -203,5 +203,6 @@ + diff --git a/umap/static/umap/js/modules/browser.js b/umap/static/umap/js/modules/browser.js index b61ff293..a916c997 100644 --- a/umap/static/umap/js/modules/browser.js +++ b/umap/static/umap/js/modules/browser.js @@ -134,7 +134,7 @@ export default class Browser { // https://github.com/Leaflet/Leaflet/pull/9052 DomEvent.disableClickPropagation(container) - DomUtil.createTitle(container, translate('Browse data'), 'layers') + DomUtil.createTitle(container, translate('Browse data'), 'icon-layers') const formContainer = DomUtil.create('div', '', container) this.dataContainer = DomUtil.create('div', '', container) diff --git a/umap/static/umap/js/umap.core.js b/umap/static/umap/js/umap.core.js index e3794e82..dac89bba 100644 --- a/umap/static/umap/js/umap.core.js +++ b/umap/static/umap/js/umap.core.js @@ -128,7 +128,7 @@ L.DomUtil.createIcon = (parent, className, title, size = 16) => { L.DomUtil.createButtonIcon = (parent, className, title, size = 16) => { return L.DomUtil.element( 'button', - { className: `icon icon-${size} ${className}`, title: title }, + { className: `icon icon-${size} ${className}`, title: title || '' }, parent ) } From 2f1a85144e67f0a0101fb5afe43d08755c61daf9 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Fri, 15 Mar 2024 18:39:06 +0100 Subject: [PATCH 36/44] chore: make panel toolbox sticky instead of fixed No need to deal with width, that way. --- umap/static/umap/css/panel.css | 13 ++----------- umap/static/umap/js/umap.core.js | 2 +- umap/static/umap/js/umap.tableeditor.js | 2 +- 3 files changed, 4 insertions(+), 13 deletions(-) diff --git a/umap/static/umap/css/panel.css b/umap/static/umap/css/panel.css index 967f5d60..d3bed4bc 100644 --- a/umap/static/umap/css/panel.css +++ b/umap/static/umap/css/panel.css @@ -58,14 +58,12 @@ gap: 5px; line-height: 2.2em; background-color: #fff; - position: fixed; + position: sticky; + top: 0; } .panel.dark .toolbox { background-color: var(--color-darkGray); } -.panel.full .toolbox { - width: calc(100% - 112px); -} .panel .toolbox li { cursor: pointer; display: inline; @@ -93,10 +91,6 @@ margin-top: 10px; width: 400px; } - .panel .toolbox { - /* It overflows otherwise, dunno why */ - width: 398px; - } .panel.condensed { max-height: 500px; bottom: initial; @@ -131,9 +125,6 @@ .panel.left { left: -100%; } - .panel .toolbox { - width: 100%; - } .panel.on { right: 0; left: 0; diff --git a/umap/static/umap/js/umap.core.js b/umap/static/umap/js/umap.core.js index dac89bba..c4c2c5e4 100644 --- a/umap/static/umap/js/umap.core.js +++ b/umap/static/umap/js/umap.core.js @@ -120,7 +120,7 @@ L.DomUtil.createLink = (className, container, content, url, target, title) => { L.DomUtil.createIcon = (parent, className, title, size = 16) => { return L.DomUtil.element( 'i', - { className: `icon icon-${size} ${className}`, title: title }, + { className: `icon icon-${size} ${className}`, title: title || '' }, parent ) } diff --git a/umap/static/umap/js/umap.tableeditor.js b/umap/static/umap/js/umap.tableeditor.js index d84e55ea..c5bbaa6c 100644 --- a/umap/static/umap/js/umap.tableeditor.js +++ b/umap/static/umap/js/umap.tableeditor.js @@ -99,7 +99,7 @@ U.TableEditor = L.Class.extend({ this.body.innerHTML = '' this.datalayer.eachLayer(this.renderRow, this) const addButton = L.DomUtil.create('li', 'add-property') - L.DomUtil.create('i', 'icon icon-16 icon-add', addButton) + L.DomUtil.createIcon(addButton, 'icon-add') const label = L.DomUtil.create('span', '', addButton) label.textContent = label.title = L._('Add a new property') const addProperty = function () { From 211a86f27cc1a1c1051400397e247fdc8bbfbb26 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Fri, 15 Mar 2024 19:11:38 +0100 Subject: [PATCH 37/44] chore: lint --- umap/tests/integration/test_anonymous_owned_map.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/umap/tests/integration/test_anonymous_owned_map.py b/umap/tests/integration/test_anonymous_owned_map.py index ad14dc72..74f3f0e7 100644 --- a/umap/tests/integration/test_anonymous_owned_map.py +++ b/umap/tests/integration/test_anonymous_owned_map.py @@ -114,7 +114,7 @@ def test_anonymous_can_add_marker_on_editable_layer( marker = page.locator(".leaflet-marker-icon") map_el = page.locator("#map") expect(marker).to_have_count(2) - panel = page.locator('.panel.right.on') + panel = page.locator(".panel.right.on") expect(panel).to_be_hidden() add_marker.click() map_el.click(position={"x": 100, "y": 100}) From 573a33df5afe3e2550e06688bb243d05eb632aa7 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Fri, 15 Mar 2024 21:41:11 +0100 Subject: [PATCH 38/44] chore: use CSS vars for panel --- umap/static/umap/css/panel.css | 40 +++++++++++++------------ umap/static/umap/js/modules/panel.js | 2 +- umap/static/umap/map.css | 44 ++++++++++++++-------------- umap/static/umap/vars.css | 8 +++++ 4 files changed, 52 insertions(+), 42 deletions(-) diff --git a/umap/static/umap/css/panel.css b/umap/static/umap/css/panel.css index d3bed4bc..71d17d3e 100644 --- a/umap/static/umap/css/panel.css +++ b/umap/static/umap/css/panel.css @@ -3,7 +3,7 @@ /* as being out of the visible viewport is not enough */ visibility: hidden; position: absolute; - bottom: 10px; + bottom: var(--panel-gutter); overflow-x: auto; z-index: 1010; background-color: #fff; @@ -20,19 +20,20 @@ .panel.full { width: initial; right: -100%; - z-index: 10000; + z-index: 1030; } .panel.full.on { visibility: visible; - right: 10px; - left: 10px; + right: var(--panel-gutter); + left: var(--panel-gutter); + top: var(--header-height); + height: initial; + max-height: initial; } .umap-caption-bar-enabled .panel { - bottom: 46px; + bottom: var(--footer-height); } .panel { - -moz-box-sizing:border-box; - -webkit-box-sizing:border-box; box-sizing: border-box; } .panel .umap-popup-content img { @@ -43,10 +44,8 @@ max-height: inherit; } .panel .body { - clear: both; - height: calc(100% - 32px); /* Minus size of toolbox */ - padding: 10px; - padding-top: 32px; + height: calc(100% - var(--panel-header-height)); /* Minus size of toolbox */ + padding: var(--panel-gutter); } .panel .toolbox { padding: 5px 10px; @@ -60,6 +59,7 @@ background-color: #fff; position: sticky; top: 0; + height: var(--panel-header-height); } .panel.dark .toolbox { background-color: var(--color-darkGray); @@ -88,30 +88,29 @@ @media all and (orientation:landscape) { .panel { top: 0; - margin-top: 10px; - width: 400px; + margin-top: var(--panel-gutter); + width: var(--panel-width); } .panel.condensed { max-height: 500px; bottom: initial; } .panel.right { - margin-right: 10px; - right: -400px; + right: calc(0px - var(--panel-width)); } .panel.left { - left: -400px; + left: calc(0px - var(--panel-width)); } .panel.left.on { - left: 60px; + left: calc(var(--panel-gutter) * 2 + var(--control-size)); visibility: visible; } .panel.right.on { - right: 40px; + right: calc(var(--panel-gutter) * 2 + var(--control-size)); visibility: visible; } .umap-edit-enabled .panel { - top: 46px; + top: var(--header-height); } } @media all and (orientation:portrait) { @@ -130,4 +129,7 @@ left: 0; visibility: visible; } + .panel li.umap-resize-link { + display: none; + } } diff --git a/umap/static/umap/js/modules/panel.js b/umap/static/umap/js/modules/panel.js index d2ea1918..8d95fcda 100644 --- a/umap/static/umap/js/modules/panel.js +++ b/umap/static/umap/js/modules/panel.js @@ -3,7 +3,7 @@ import { translate } from './i18n.js' export class Panel { constructor(map) { - this.parent = map._container + this.parent = map._controlContainer this.map = map this.container = DomUtil.create('div', '', this.parent) this.mode = 'condensed' diff --git a/umap/static/umap/map.css b/umap/static/umap/map.css index 00a0da91..3ff54116 100644 --- a/umap/static/umap/map.css +++ b/umap/static/umap/map.css @@ -32,13 +32,13 @@ } .leaflet-control-fullscreen a:hover, .leaflet-control-fullscreen a { - height: 36px; - width: 36px; + height: var(--control-size); + width: var(--control-size); background-size: 36px 68px; } .leaflet-touch .leaflet-control-fullscreen a { - height: 36px; - width: 36px; + height: var(--control-size); + width: var(--control-size); background-position: 0px 0px; } .leaflet-touch.leaflet-fullscreen-on .leaflet-control-fullscreen a, @@ -52,9 +52,9 @@ background-position: 50% 50%; background-repeat: no-repeat; display: block; - height: 36px; - width: 36px; - line-height: 36px; + height: var(--control-size); + width: var(--control-size); + line-height: var(--control-size); background-image: url('./img/24.svg'); text-indent: -9999px; margin-bottom: 0; @@ -144,8 +144,8 @@ color: #fff; background-image: none; border-radius: 20px; - height: 36px; - line-height: 36px; + height: var(--control-size); + line-height: var(--control-size); display: block; } .leaflet-control-toolbar .leaflet-toolbar-icon.dark:hover, @@ -287,8 +287,8 @@ ul.photon-autocomplete { .leaflet-control-toolbar > li > .leaflet-toolbar-icon, .umap-toolbar a, .umap-toolbar a:hover { - height: 36px; - width: 36px; + height: var(--control-size); + width: var(--control-size); display: none; margin-top: 0; vertical-align: top; @@ -435,8 +435,8 @@ ul.photon-autocomplete { clear: both; } .umap-edit-actions li { - height: 36px; - line-height: 36px; + height: var(--control-size); + line-height: var(--control-size); cursor: pointer; margin-bottom: 5px; border-radius: 2px; @@ -446,8 +446,8 @@ ul.photon-autocomplete { background-image: url('./img/24-white.svg'); background-repeat: no-repeat; display: table-cell; - width: 36px; - height: 36px; + width: var(--control-size); + height: var(--control-size); } .umap-edit-actions li span { display: table-cell; @@ -575,7 +575,7 @@ ul.photon-autocomplete { background-color: var(--color-darkGray); padding: 0 10px; text-align: left; - line-height: 36px; + line-height: var(--control-size); cursor: auto; border-bottom: 1px solid #222; z-index: 1000; @@ -1503,9 +1503,9 @@ span.popup-icon { /* *************************** */ .leaflet-control-zoom a, .leaflet-control-zoom a:hover { - height: 36px; - width: 36px; - line-height: 36px; + height: var(--control-size); + width: var(--control-size); + line-height: var(--control-size); } .leaflet-container .leaflet-control-zoom { margin-left: 10px; @@ -1596,9 +1596,9 @@ span.popup-icon { border-width: 1px; } .leaflet-touch .leaflet-bar a { - width: 36px; - height: 36px; - line-height: 34px; + width: var(--control-size); + height: var(--control-size); + line-height: var(--control-size); } /* Links are blue by default */ .leaflet-container a { diff --git a/umap/static/umap/vars.css b/umap/static/umap/vars.css index c72a52ac..962c9eef 100644 --- a/umap/static/umap/vars.css +++ b/umap/static/umap/vars.css @@ -10,4 +10,12 @@ --button-primary-color: var(--color-darkBlue); --button-neutral-background: var(--color-lightGray); --button-neutral-color: var(--color-darkGray); + + /* Sizes and spaces */ + --panel-gutter: 10px; + --panel-header-height: 36px; + --panel-width: 400px; + --header-height: 46px; + --footer-height: 46px; + --control-size: 36px; } From e615e0926a1563747f4ecaec04557458ccf78512 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Mon, 15 Apr 2024 11:59:06 +0200 Subject: [PATCH 39/44] chore: fix tests --- umap/tests/integration/test_choropleth.py | 2 +- umap/tests/integration/test_datalayer.py | 14 ++++---- umap/tests/integration/test_edit_datalayer.py | 26 +++++++------- umap/tests/integration/test_edit_map.py | 2 +- umap/tests/integration/test_edit_marker.py | 4 +-- umap/tests/integration/test_edit_polygon.py | 4 +-- umap/tests/integration/test_import.py | 36 ++++++++++++------- umap/tests/integration/test_owned_map.py | 8 ++--- umap/tests/integration/test_tableeditor.py | 6 +--- 9 files changed, 55 insertions(+), 47 deletions(-) diff --git a/umap/tests/integration/test_choropleth.py b/umap/tests/integration/test_choropleth.py index baed5e71..e896dba1 100644 --- a/umap/tests/integration/test_choropleth.py +++ b/umap/tests/integration/test_choropleth.py @@ -49,7 +49,7 @@ def test_basic_choropleth_map_with_custom_brewer(openmap, live_server, page): # Now change brewer from UI page.get_by_role("button", name="Edit").click() page.get_by_role("link", name="Manage layers").click() - page.locator("#umap-ui-container").get_by_title("Edit", exact=True).click() + page.locator(".panel").get_by_title("Edit", exact=True).click() page.get_by_role("heading", name="Choropleth: settings").click() page.locator('select[name="brewer"]').select_option("Greens") diff --git a/umap/tests/integration/test_datalayer.py b/umap/tests/integration/test_datalayer.py index da4ec622..ed3ffc52 100644 --- a/umap/tests/integration/test_datalayer.py +++ b/umap/tests/integration/test_datalayer.py @@ -20,14 +20,14 @@ def set_options(datalayer, **options): def test_honour_displayOnLoad_false(map, live_server, datalayer, page): set_options(datalayer, displayOnLoad=False) - page.goto(f"{live_server.url}{map.get_absolute_url()}") + page.goto(f"{live_server.url}{map.get_absolute_url()}?onLoadPanel=datalayers") expect(page.locator(".leaflet-marker-icon")).to_be_hidden() - layers = page.locator(".umap-browse-datalayers li") + layers = page.locator(".umap-browser .datalayer") markers = page.locator(".leaflet-marker-icon") - layers_off = page.locator(".umap-browse-datalayers li.off") + layers_off = page.locator(".umap-browser .datalayer.off") expect(layers).to_have_count(1) expect(layers_off).to_have_count(1) - page.get_by_role("button", name="See data layers").click() + page.get_by_role("button", name="See layers").click() page.get_by_label("Zoom in").click() expect(markers).to_be_hidden() page.get_by_title("Show/hide layer").click() @@ -109,10 +109,12 @@ def test_should_honour_color_variable(live_server, map, page): def test_datalayers_in_query_string(live_server, datalayer, map, page): + map.settings["properties"]["onLoadPanel"] = "datalayers" + map.save() with_old_id = DataLayerFactory(old_id=134, map=map, name="with old id") set_options(with_old_id, name="with old id") - visible = page.locator(".leaflet-control-browse li:not(.off) span") - hidden = page.locator(".leaflet-control-browse li.off span") + visible = page.locator(".umap-browser .datalayer:not(.off) .datalayer-name") + hidden = page.locator(".umap-browser .datalayer.off .datalayer-name") page.goto(f"{live_server.url}{map.get_absolute_url()}") expect(visible).to_have_count(2) expect(hidden).to_have_count(0) diff --git a/umap/tests/integration/test_edit_datalayer.py b/umap/tests/integration/test_edit_datalayer.py index 14242126..ecfba705 100644 --- a/umap/tests/integration/test_edit_datalayer.py +++ b/umap/tests/integration/test_edit_datalayer.py @@ -54,32 +54,32 @@ def test_cancel_deleting_datalayer_should_restore( live_server, openmap, datalayer, page ): page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit") - layers = page.locator(".umap-browse-datalayers li") + page.get_by_title("See layers").click() + layers = page.locator(".umap-browser .datalayer") markers = page.locator(".leaflet-marker-icon") expect(layers).to_have_count(1) expect(markers).to_have_count(1) page.get_by_role("link", name="Manage layers").click() page.once("dialog", lambda dialog: dialog.accept()) - page.locator("#umap-ui-container").get_by_title("Delete layer").click() + page.locator(".panel.right").get_by_title("Delete layer").click() expect(markers).to_have_count(0) - page.get_by_role("button", name="See data layers").click() + page.get_by_role("button", name="See layers").click() expect(page.get_by_text("test datalayer")).to_be_hidden() page.once("dialog", lambda dialog: dialog.accept()) page.get_by_role("button", name="Cancel edits").click() expect(markers).to_have_count(1) - expect( - page.locator(".leaflet-control-browse").get_by_text("test datalayer") - ).to_be_visible() + expect(page.locator(".umap-browser").get_by_text("test datalayer")).to_be_visible() def test_can_clone_datalayer(live_server, openmap, login, datalayer, page): page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit") - layers = page.locator(".umap-browse-datalayers li") + page.get_by_title("See layers").click() + layers = page.locator(".umap-browser .datalayer") markers = page.locator(".leaflet-marker-icon") expect(layers).to_have_count(1) expect(markers).to_have_count(1) page.get_by_role("link", name="Manage layers").click() - page.locator("#umap-ui-container").get_by_title("Edit", exact=True).click() + page.locator(".panel.right").get_by_title("Edit", exact=True).click() page.get_by_role("heading", name="Advanced actions").click() page.get_by_role("button", name="Clone").click() expect(layers).to_have_count(2) @@ -103,7 +103,7 @@ def test_can_change_icon_class(live_server, openmap, page): expect(page.locator(".umap-div-icon")).to_be_visible() page.get_by_role("link", name="Manage layers").click() expect(page.locator(".umap-circle-icon")).to_be_hidden() - page.locator("#umap-ui-container").get_by_title("Edit", exact=True).click() + page.locator(".panel.right").get_by_title("Edit", exact=True).click() page.get_by_role("heading", name="Shape properties").click() page.locator(".umap-field-iconClass a.define").click() page.get_by_text("Circle").click() @@ -116,12 +116,12 @@ def test_can_change_name(live_server, openmap, page, datalayer): f"{live_server.url}{openmap.get_absolute_url()}?edit&datalayersControl=expanded" ) page.get_by_role("link", name="Manage layers").click() - page.locator("#umap-ui-container").get_by_title("Edit", exact=True).click() + page.locator(".panel.right").get_by_title("Edit", exact=True).click() expect(page.locator(".umap-is-dirty")).to_be_hidden() page.locator('input[name="name"]').click() page.locator('input[name="name"]').press("Control+a") page.locator('input[name="name"]').fill("new name") - expect(page.locator(".leaflet-control-browse li span")).to_contain_text("new name") + expect(page.locator(".umap-browser .datalayer")).to_contain_text("new name") expect(page.locator(".umap-is-dirty")).to_be_visible() with page.expect_response(re.compile(".*/datalayer/update/.*")): page.get_by_role("button", name="Save").click() @@ -147,7 +147,7 @@ def test_can_create_new_datalayer(live_server, openmap, page, datalayer): expect(page.locator(".umap-is-dirty")).to_be_hidden() # Edit again, it should not create a new datalayer page.get_by_role("link", name="Manage layers").click() - page.locator("#umap-ui-container").get_by_title("Edit", exact=True).first.click() + page.locator(".panel.right").get_by_title("Edit", exact=True).first.click() page.locator('input[name="name"]').click() page.locator('input[name="name"]').fill("my new layer with a new name") expect(page.get_by_text("my new layer with a new name")).to_be_visible() @@ -171,7 +171,7 @@ def test_can_restore_version(live_server, openmap, page, datalayer): page.get_by_role("button", name="Save").click() expect(marker).to_have_class(re.compile(".*umap-div-icon.*")) page.get_by_role("link", name="Manage layers").click() - page.locator("#umap-ui-container").get_by_title("Edit", exact=True).click() + page.locator(".panel.right").get_by_title("Edit", exact=True).click() page.get_by_role("heading", name="Versions").click() page.once("dialog", lambda dialog: dialog.accept()) page.get_by_role("button", name="Restore this version").last.click() diff --git a/umap/tests/integration/test_edit_map.py b/umap/tests/integration/test_edit_map.py index e0d80309..3d1738de 100644 --- a/umap/tests/integration/test_edit_map.py +++ b/umap/tests/integration/test_edit_map.py @@ -10,7 +10,7 @@ from ..base import DataLayerFactory def test_can_edit_name(page, live_server, tilelayer): page.goto(f"{live_server.url}/en/map/new/") - page.get_by_title("Edit map properties").click() + page.get_by_title("Edit map name and caption").click() name_input = page.locator('.map-metadata input[name="name"]') expect(name_input).to_be_visible() name_input.click() diff --git a/umap/tests/integration/test_edit_marker.py b/umap/tests/integration/test_edit_marker.py index df53ffc5..fb3b2d1a 100644 --- a/umap/tests/integration/test_edit_marker.py +++ b/umap/tests/integration/test_edit_marker.py @@ -44,7 +44,7 @@ def test_marker_style_should_have_precedence(live_server, openmap, page, bootstr # Change colour at layer level page.get_by_role("link", name="Manage layers").click() - page.locator("#umap-ui-container").get_by_title("Edit", exact=True).click() + page.locator(".panel").get_by_title("Edit", exact=True).click() page.get_by_role("heading", name="Shape properties").click() page.locator(".umap-field-color .define").click() expect(page.locator(".leaflet-marker-icon .icon_container")).to_have_css( @@ -66,7 +66,7 @@ def test_marker_style_should_have_precedence(live_server, openmap, page, bootstr # Now change again at layer level again, it should not change the marker color page.get_by_role("link", name="Manage layers").click() - page.locator("#umap-ui-container").get_by_title("Edit", exact=True).click() + page.locator(".panel").get_by_title("Edit", exact=True).click() page.get_by_role("heading", name="Shape properties").click() page.locator(".umap-field-color input").click() page.get_by_title("DarkViolet").first.click() diff --git a/umap/tests/integration/test_edit_polygon.py b/umap/tests/integration/test_edit_polygon.py index c34ad65b..b812e181 100644 --- a/umap/tests/integration/test_edit_polygon.py +++ b/umap/tests/integration/test_edit_polygon.py @@ -58,7 +58,7 @@ def test_marker_style_should_have_precedence(live_server, openmap, page, bootstr # Change colour at layer level page.get_by_role("link", name="Manage layers").click() - page.locator("#umap-ui-container").get_by_title("Edit", exact=True).click() + page.locator(".panel").get_by_title("Edit", exact=True).click() page.get_by_role("heading", name="Shape properties").click() page.locator(".umap-field-color .define").click() expect(page.locator(".leaflet-overlay-pane path[fill='DarkBlue']")).to_have_count(1) @@ -76,7 +76,7 @@ def test_marker_style_should_have_precedence(live_server, openmap, page, bootstr # Now change again at layer level again, it should not change the marker color page.get_by_role("link", name="Manage layers").click() - page.locator("#umap-ui-container").get_by_title("Edit", exact=True).click() + page.locator(".panel").get_by_title("Edit", exact=True).click() page.get_by_role("heading", name="Shape properties").click() page.locator(".umap-field-color input").click() page.get_by_title("DarkViolet").first.click() diff --git a/umap/tests/integration/test_import.py b/umap/tests/integration/test_import.py index a50c7a1a..684eae04 100644 --- a/umap/tests/integration/test_import.py +++ b/umap/tests/integration/test_import.py @@ -43,18 +43,18 @@ def test_umap_import_from_file(live_server, tilelayer, page): def test_umap_import_from_textarea(live_server, tilelayer, page, settings): settings.UMAP_ALLOW_ANONYMOUS = True page.goto(f"{live_server.url}/map/new/") + page.get_by_role("button", name="See layers").click() page.get_by_title("Import data").click() textarea = page.locator(".umap-upload textarea") path = Path(__file__).parent.parent / "fixtures/test_upload_data.umap" textarea.fill(path.read_text()) page.locator('select[name="format"]').select_option("umap") page.get_by_role("button", name="Import", exact=True).click() - layers = page.locator(".umap-browse-datalayers li") + layers = page.locator(".umap-browser .datalayer") expect(layers).to_have_count(2) expect(page.locator(".umap-main-edit-toolbox .map-name")).to_have_text( "Imported map" ) - page.get_by_role("button", name="See data layers").click() expect(page.get_by_text("Tunnels")).to_be_visible() expect(page.get_by_text("Cities")).to_be_visible() expect(page.locator(".leaflet-control-minimap")).to_be_visible() @@ -70,6 +70,7 @@ def test_umap_import_from_textarea(live_server, tilelayer, page, settings): def test_import_geojson_from_textarea(tilelayer, live_server, page): page.goto(f"{live_server.url}/map/new/") + page.get_by_title("See layers").click() layers = page.locator(".umap-browser .datalayer") markers = page.locator(".leaflet-marker-icon") paths = page.locator("path") @@ -87,7 +88,6 @@ def test_import_geojson_from_textarea(tilelayer, live_server, page): expect(button).to_be_visible() button.click() # A layer has been created - page.get_by_title("See layers").click() expect(layers).to_have_count(1) expect(markers).to_have_count(2) expect(paths).to_have_count(3) @@ -95,7 +95,8 @@ def test_import_geojson_from_textarea(tilelayer, live_server, page): def test_import_kml_from_textarea(tilelayer, live_server, page): page.goto(f"{live_server.url}/map/new/") - layers = page.locator(".umap-browse-datalayers li") + page.get_by_title("See layers").click() + layers = page.locator(".umap-browser .datalayer") markers = page.locator(".leaflet-marker-icon") paths = page.locator("path") expect(markers).to_have_count(0) @@ -119,7 +120,8 @@ def test_import_kml_from_textarea(tilelayer, live_server, page): def test_import_gpx_from_textarea(tilelayer, live_server, page): page.goto(f"{live_server.url}/map/new/") - layers = page.locator(".umap-browse-datalayers li") + page.get_by_title("See layers").click() + layers = page.locator(".umap-browser .datalayer") markers = page.locator(".leaflet-marker-icon") paths = page.locator("path") expect(markers).to_have_count(0) @@ -143,7 +145,8 @@ def test_import_gpx_from_textarea(tilelayer, live_server, page): def test_import_osm_from_textarea(tilelayer, live_server, page): page.goto(f"{live_server.url}/map/new/") - layers = page.locator(".umap-browse-datalayers li") + page.get_by_title("See layers").click() + layers = page.locator(".umap-browser .datalayer") markers = page.locator(".leaflet-marker-icon") expect(markers).to_have_count(0) expect(layers).to_have_count(0) @@ -162,7 +165,8 @@ def test_import_osm_from_textarea(tilelayer, live_server, page): def test_import_csv_from_textarea(tilelayer, live_server, page): page.goto(f"{live_server.url}/map/new/") - layers = page.locator(".umap-browse-datalayers li") + page.get_by_title("See layers").click() + layers = page.locator(".umap-browser .datalayer") markers = page.locator(".leaflet-marker-icon") expect(markers).to_have_count(0) expect(layers).to_have_count(0) @@ -181,7 +185,8 @@ def test_import_csv_from_textarea(tilelayer, live_server, page): def test_can_import_in_existing_datalayer(live_server, datalayer, page, openmap): page.goto(f"{live_server.url}{openmap.get_absolute_url()}") - layers = page.locator(".umap-browse-datalayers li") + page.get_by_title("See layers").click() + layers = page.locator(".umap-browser .datalayer") markers = page.locator(".leaflet-marker-icon") expect(markers).to_have_count(1) expect(layers).to_have_count(1) @@ -199,7 +204,8 @@ def test_can_import_in_existing_datalayer(live_server, datalayer, page, openmap) def test_can_replace_datalayer_data(live_server, datalayer, page, openmap): page.goto(f"{live_server.url}{openmap.get_absolute_url()}") - layers = page.locator(".umap-browse-datalayers li") + page.get_by_title("See layers").click() + layers = page.locator(".umap-browser .datalayer") markers = page.locator(".leaflet-marker-icon") expect(markers).to_have_count(1) expect(layers).to_have_count(1) @@ -218,7 +224,8 @@ def test_can_replace_datalayer_data(live_server, datalayer, page, openmap): def test_can_import_in_new_datalayer(live_server, datalayer, page, openmap): page.goto(f"{live_server.url}{openmap.get_absolute_url()}") - layers = page.locator(".umap-browse-datalayers li") + page.get_by_title("See layers").click() + layers = page.locator(".umap-browser .datalayer") markers = page.locator(".leaflet-marker-icon") expect(markers).to_have_count(1) expect(layers).to_have_count(1) @@ -321,7 +328,8 @@ def test_import_geometry_collection(live_server, page, tilelayer): ], } page.goto(f"{live_server.url}/map/new/") - layers = page.locator(".umap-browse-datalayers li") + page.get_by_title("See layers").click() + layers = page.locator(".umap-browser .datalayer") markers = page.locator(".leaflet-marker-icon") paths = page.locator("path") expect(markers).to_have_count(0) @@ -356,7 +364,8 @@ def test_import_multipolygon(live_server, page, tilelayer): }, } page.goto(f"{live_server.url}/map/new/") - layers = page.locator(".umap-browse-datalayers li") + page.get_by_title("See layers").click() + layers = page.locator(".umap-browser .datalayer") paths = page.locator("path") expect(paths).to_have_count(0) expect(layers).to_have_count(0) @@ -387,7 +396,8 @@ def test_import_multipolyline(live_server, page, tilelayer): ], } page.goto(f"{live_server.url}/map/new/") - layers = page.locator(".umap-browse-datalayers li") + page.get_by_title("See layers").click() + layers = page.locator(".umap-browser .datalayer") paths = page.locator("path") expect(paths).to_have_count(0) expect(layers).to_have_count(0) diff --git a/umap/tests/integration/test_owned_map.py b/umap/tests/integration/test_owned_map.py index 7071e556..d197ff0d 100644 --- a/umap/tests/integration/test_owned_map.py +++ b/umap/tests/integration/test_owned_map.py @@ -236,16 +236,16 @@ def test_can_change_owner(map, live_server, login, user): def test_can_delete_datalayer(live_server, map, login, datalayer): page = login(map.owner) page.goto(f"{live_server.url}{map.get_absolute_url()}?edit") - layers = page.locator(".umap-browse-datalayers li") + page.get_by_title("See layers").click() + layers = page.locator(".umap-browser .datalayer") markers = page.locator(".leaflet-marker-icon") expect(layers).to_have_count(1) expect(markers).to_have_count(1) page.get_by_role("link", name="Manage layers").click() page.once("dialog", lambda dialog: dialog.accept()) - page.locator("#umap-ui-container").get_by_title("Delete layer").click() + page.locator(".panel.right").get_by_title("Delete layer").click() with page.expect_response(re.compile(r".*/datalayer/delete/.*")): page.get_by_role("button", name="Save").click() expect(markers).to_have_count(0) # FIXME does not work, resolve to 1 element, even if this command is empty: - # document.querySelectorAll(".umap-browse-datalayers li") - # expect(layers).to_have_count(0) + expect(layers).to_have_count(0) diff --git a/umap/tests/integration/test_tableeditor.py b/umap/tests/integration/test_tableeditor.py index cb26e511..b2d3cc89 100644 --- a/umap/tests/integration/test_tableeditor.py +++ b/umap/tests/integration/test_tableeditor.py @@ -2,17 +2,13 @@ import json import re from pathlib import Path -from playwright.sync_api import expect - from umap.models import DataLayer def test_table_editor(live_server, openmap, datalayer, page): page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit") page.get_by_role("link", name="Manage layers").click() - page.locator("#umap-ui-container").get_by_title( - "Edit properties in a table" - ).click() + page.locator(".panel").get_by_title("Edit properties in a table").click() page.once("dialog", lambda dialog: dialog.accept(prompt_text="newprop")) page.get_by_text("Add a new property").click() page.locator('input[name="newprop"]').fill("newvalue") From b933c4badd44602642289a39ce3cc04bb66ad9d3 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Mon, 15 Apr 2024 19:25:10 +0200 Subject: [PATCH 40/44] wip: align panel bottom above scale control --- umap/static/umap/css/panel.css | 9 +++++++-- umap/static/umap/vars.css | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/umap/static/umap/css/panel.css b/umap/static/umap/css/panel.css index 71d17d3e..3ecabbd2 100644 --- a/umap/static/umap/css/panel.css +++ b/umap/static/umap/css/panel.css @@ -3,7 +3,7 @@ /* as being out of the visible viewport is not enough */ visibility: hidden; position: absolute; - bottom: var(--panel-gutter); + bottom: var(--panel-bottom); overflow-x: auto; z-index: 1010; background-color: #fff; @@ -31,7 +31,7 @@ max-height: initial; } .umap-caption-bar-enabled .panel { - bottom: var(--footer-height); + bottom: calc(var(--footer-height) + var(--panel-bottom)); } .panel { box-sizing: border-box; @@ -132,4 +132,9 @@ .panel li.umap-resize-link { display: none; } + .umap-caption-bar-enabled .panel { + bottom: var(--footer-height); + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } } diff --git a/umap/static/umap/vars.css b/umap/static/umap/vars.css index 962c9eef..c63a1669 100644 --- a/umap/static/umap/vars.css +++ b/umap/static/umap/vars.css @@ -13,6 +13,7 @@ /* Sizes and spaces */ --panel-gutter: 10px; + --panel-bottom: 40px; --panel-header-height: 36px; --panel-width: 400px; --header-height: 46px; From 4cfe319a91125e637f52ddacfe6ee068f624d4ab Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Mon, 15 Apr 2024 19:34:08 +0200 Subject: [PATCH 41/44] fix: remove white border from black edit buttons --- umap/static/umap/map.css | 1 - 1 file changed, 1 deletion(-) diff --git a/umap/static/umap/map.css b/umap/static/umap/map.css index 3ff54116..4d5c5677 100644 --- a/umap/static/umap/map.css +++ b/umap/static/umap/map.css @@ -294,7 +294,6 @@ ul.photon-autocomplete { vertical-align: top; border-bottom: none; background-color: var(--color-darkGray); - border-right: 1px solid #eee; background-repeat: no-repeat; background-image: url('./img/24.svg'); background-size: auto auto; From 9ee672f1e76206a4dd70520611828a9e60ffcc57 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Mon, 15 Apr 2024 19:35:36 +0200 Subject: [PATCH 42/44] wip: fix border for dark panel --- umap/static/umap/css/panel.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/umap/static/umap/css/panel.css b/umap/static/umap/css/panel.css index 3ecabbd2..73e82500 100644 --- a/umap/static/umap/css/panel.css +++ b/umap/static/umap/css/panel.css @@ -13,7 +13,7 @@ border: 1px solid var(--color-lightGray); } .panel.dark { - border-left: 1px solid #222; + border: 1px solid #222; background-color: var(--color-darkGray); color: #efefef; } From 65bad68efe19d8c03dc63e20b7102adef68590e5 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Mon, 15 Apr 2024 21:41:02 +0200 Subject: [PATCH 43/44] wip: change icon for panel expanded/condensed --- umap/static/umap/base.css | 2 +- umap/static/umap/css/icon.css | 5 ++++- umap/static/umap/img/16-white.svg | 6 ++++-- umap/static/umap/img/16.svg | 14 +++++--------- umap/static/umap/img/source/16-white.svg | 8 +++++--- umap/static/umap/img/source/16.svg | 16 ++++++---------- 6 files changed, 25 insertions(+), 26 deletions(-) diff --git a/umap/static/umap/base.css b/umap/static/umap/base.css index 5c3993e5..ec75c4a0 100644 --- a/umap/static/umap/base.css +++ b/umap/static/umap/base.css @@ -677,7 +677,7 @@ input[type=hidden].blur + [type="button"] { .copiable-input button { background-repeat: no-repeat; background-image: url('./img/16.svg'); - background-position: -45px -140px; + background-position: -141px -140px; display: inline; padding: 0 10px; height: 32px; diff --git a/umap/static/umap/css/icon.css b/umap/static/umap/css/icon.css index 07f0dd1e..2bf10a74 100644 --- a/umap/static/umap/css/icon.css +++ b/umap/static/umap/css/icon.css @@ -74,7 +74,10 @@ background-position: 0 -119px; } .icon-resize { - background-position: -74px -145px; + background-position: -74px -144px; +} +.expanded .icon-resize { + background-position: -50px -144px; } .icon-search { background-position: -27px -120px; diff --git a/umap/static/umap/img/16-white.svg b/umap/static/umap/img/16-white.svg index 88eb6924..b47da5c8 100644 --- a/umap/static/umap/img/16-white.svg +++ b/umap/static/umap/img/16-white.svg @@ -150,7 +150,7 @@ - + @@ -187,6 +187,8 @@ - + + + diff --git a/umap/static/umap/img/16.svg b/umap/static/umap/img/16.svg index 54d14015..4cf58b6b 100644 --- a/umap/static/umap/img/16.svg +++ b/umap/static/umap/img/16.svg @@ -35,9 +35,7 @@ - - - +   @@ -177,13 +175,11 @@ - + - - - - - + + + diff --git a/umap/static/umap/img/source/16-white.svg b/umap/static/umap/img/source/16-white.svg index 943a252c..34d7b53f 100644 --- a/umap/static/umap/img/source/16-white.svg +++ b/umap/static/umap/img/source/16-white.svg @@ -16,7 +16,7 @@ - + @@ -172,7 +172,7 @@ - + @@ -209,6 +209,8 @@ - + + + diff --git a/umap/static/umap/img/source/16.svg b/umap/static/umap/img/source/16.svg index 48b69f61..494ee015 100644 --- a/umap/static/umap/img/source/16.svg +++ b/umap/static/umap/img/source/16.svg @@ -10,7 +10,7 @@ - + @@ -54,9 +54,7 @@ - - - +   @@ -196,13 +194,11 @@ - + - - - - - + + + From 2602b27f341c2693d4f92d7285416b1a68877494 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Tue, 16 Apr 2024 10:30:05 +0200 Subject: [PATCH 44/44] chore: fix tests after rebase --- umap/static/umap/js/umap.js | 1 + umap/static/umap/js/umap.layer.js | 2 +- umap/tests/integration/test_edit_map.py | 34 +++++++++++-------------- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/umap/static/umap/js/umap.js b/umap/static/umap/js/umap.js index c2f31f67..332f8dab 100644 --- a/umap/static/umap/js/umap.js +++ b/umap/static/umap/js/umap.js @@ -270,6 +270,7 @@ U.Map = L.Map.extend({ reindexDataLayers: function () { this.eachDataLayer((datalayer) => datalayer.reindex()) + this.onDataLayersChanged() }, redrawVisibleDataLayers: function () { diff --git a/umap/static/umap/js/umap.layer.js b/umap/static/umap/js/umap.layer.js index c10c3bea..e7d730fe 100644 --- a/umap/static/umap/js/umap.layer.js +++ b/umap/static/umap/js/umap.layer.js @@ -603,7 +603,7 @@ U.DataLayer = L.Evented.extend({ for (let impact of impacts) { switch (impact) { case 'ui': - this.map.updateDatalayersControl() + this.map.onDataLayersChanged() break case 'data': if (fields.includes('options.type')) { diff --git a/umap/tests/integration/test_edit_map.py b/umap/tests/integration/test_edit_map.py index 3d1738de..4d397532 100644 --- a/umap/tests/integration/test_edit_map.py +++ b/umap/tests/integration/test_edit_map.py @@ -24,7 +24,7 @@ def test_can_edit_name(page, live_server, tilelayer): def test_map_name_impacts_ui(live_server, page, tilelayer): page.goto(f"{live_server.url}/en/map/new/") - gear_icon = page.get_by_title("Edit map properties") + gear_icon = page.get_by_title("Edit map name and caption") expect(gear_icon).to_be_visible() gear_icon.click() @@ -39,7 +39,7 @@ def test_map_name_impacts_ui(live_server, page, tilelayer): def test_zoomcontrol_impacts_ui(live_server, page, tilelayer): page.goto(f"{live_server.url}/en/map/new/") - gear_icon = page.get_by_title("Edit map properties") + gear_icon = page.get_by_title("Map advanced properties") expect(gear_icon).to_be_visible() gear_icon.click() @@ -67,7 +67,7 @@ def test_zoomcontrol_impacts_ui(live_server, page, tilelayer): def test_map_color_impacts_data(live_server, page, tilelayer): page.goto(f"{live_server.url}/en/map/new/") - gear_icon = page.get_by_title("Edit map properties") + gear_icon = page.get_by_title("Map advanced properties") expect(gear_icon).to_be_visible() gear_icon.click() @@ -97,7 +97,7 @@ def test_map_color_impacts_data(live_server, page, tilelayer): def test_limitbounds_impacts_ui(live_server, page, tilelayer): page.goto(f"{live_server.url}/en/map/new/") - gear_icon = page.get_by_title("Edit map properties") + gear_icon = page.get_by_title("Map advanced properties") expect(gear_icon).to_be_visible() gear_icon.click() @@ -163,37 +163,33 @@ def test_sortkey_impacts_datalayerindex(map, live_server, page): page.goto(f"{live_server.url}{map.get_absolute_url()}") # By default, features are sorted by name (Third, Second, First) - page.get_by_role("button", name="See data layers").click() - page.get_by_role("button", name="Browse data").click() + page.get_by_role("button", name="See layers").click() + page.get_by_role("heading", name="Show/hide layer").locator("i").click() - first_listed_feature = page.locator("#browse_data_datalayer_123 > ul > li").nth(0) - second_listed_feature = page.locator("#browse_data_datalayer_123 > ul > li").nth(1) - third_listed_feature = page.locator("#browse_data_datalayer_123 > ul > li").nth(2) + first_listed_feature = page.locator(".umap-browser .datalayer ul > li").nth(0) + second_listed_feature = page.locator(".umap-browser .datalayer ul > li").nth(1) + third_listed_feature = page.locator(".umap-browser .datalayer ul > li").nth(2) assert "X Third" == first_listed_feature.text_content() assert "Y Second" == second_listed_feature.text_content() assert "Z First" == third_listed_feature.text_content() # Change the default sortkey to be "key" page.get_by_role("button", name="Edit").click() - page.get_by_role("link", name="Edit map properties").click() + page.get_by_role("link", name="Map advanced properties").click() page.get_by_role("heading", name="Default properties").click() # Click "define" - page.locator( - "div:nth-child(5) > .fields > .umap-form > div:nth-child(4) > .header > a:nth-child(2)" - ).click() + page.locator(".panel .umap-field-sortKey .define").click() page.locator('input[name="sortKey"]').click() page.locator('input[name="sortKey"]').fill("key") # Click the checkmark to apply the changes - page.locator("div:nth-child(4) > div:nth-child(2) > .button").first.click() + page.locator(".panel .umap-field-sortKey .blur-button").click() # Features should be sorted by key (First, Second, Third) - page.get_by_role("button", name="Browse data").click() - - first_listed_feature = page.locator("#browse_data_datalayer_123 > ul > li").nth(0) - second_listed_feature = page.locator("#browse_data_datalayer_123 > ul > li").nth(1) - third_listed_feature = page.locator("#browse_data_datalayer_123 > ul > li").nth(2) + first_listed_feature = page.locator(".umap-browser .datalayer ul > li").nth(0) + second_listed_feature = page.locator(".umap-browser .datalayer ul > li").nth(1) + third_listed_feature = page.locator(".umap-browser .datalayer ul > li").nth(2) assert "Z First" == first_listed_feature.text_content() assert "Y Second" == second_listed_feature.text_content() assert "X Third" == third_listed_feature.text_content()