Merge pull request #1994 from umap-project/more-tilelayers-button

feat: add a "+" button in the tilelayer switcher
This commit is contained in:
Yohan Boniface 2024-08-13 11:05:02 +02:00 committed by GitHub
commit a04accf16c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 64 additions and 15 deletions

View file

@ -763,6 +763,7 @@ const ControlsMixin = {
U.TileLayerControl = L.Control.IconLayers.extend({ U.TileLayerControl = L.Control.IconLayers.extend({
initialize: function (map, options) { initialize: function (map, options) {
this.map = map this.map = map
this.maxShown = 9
L.Control.IconLayers.prototype.initialize.call(this, { L.Control.IconLayers.prototype.initialize.call(this, {
position: 'topleft', position: 'topleft',
manageLayers: false, manageLayers: false,
@ -794,10 +795,26 @@ U.TileLayerControl = L.Control.IconLayers.extend({
} }
}) })
} }
const maxShown = 10 L.Control.IconLayers.prototype.setLayers.call(this, layers.slice(0, this.maxShown))
L.Control.IconLayers.prototype.setLayers.call(this, layers.slice(0, maxShown))
if (this.map.selected_tilelayer) this.setActiveLayer(this.map.selected_tilelayer) if (this.map.selected_tilelayer) this.setActiveLayer(this.map.selected_tilelayer)
}, },
_createLayerElements: function () {
L.Control.IconLayers.prototype._createLayerElements.call(this)
if (Object.keys(this._layers) <= this.maxShown) return
const lastRow = this._container.querySelector(
'.leaflet-iconLayers-layersRow:last-child'
)
const button = L.DomUtil.element({
tagName: 'button',
className: 'leaflet-iconLayers-layerCell leaflet-iconLayers-layerCell-plus button',
textContent: '+',
parent: lastRow,
})
L.DomEvent.on(button, 'click', () =>
this.map._controls.tilelayersChooser.openSwitcher()
)
},
}) })
/* Used in edit mode to define the default tilelayer */ /* Used in edit mode to define the default tilelayer */
@ -806,7 +823,7 @@ U.TileLayerChooser = L.Control.extend({
position: 'topleft', position: 'topleft',
}, },
initialize: function (map, options) { initialize: function (map, options = {}) {
this.map = map this.map = map
L.Control.prototype.initialize.call(this, options) L.Control.prototype.initialize.call(this, options)
}, },
@ -824,15 +841,13 @@ U.TileLayerChooser = L.Control.extend({
return container return container
}, },
openSwitcher: function (options) { openSwitcher: function (options = {}) {
const container = L.DomUtil.create('div', 'umap-tilelayer-switcher-container') const container = L.DomUtil.create('div', 'umap-tilelayer-switcher-container')
L.DomUtil.createTitle(container, L._('Change tilelayers'), 'icon-tilelayer') L.DomUtil.createTitle(container, L._('Change tilelayers'), 'icon-tilelayer')
this._tilelayers_container = L.DomUtil.create('ul', '', container) this._tilelayers_container = L.DomUtil.create('ul', '', container)
this.buildList(options) this.buildList(options)
this.map.editPanel.open({ const panel = options.edit ? this.map.editPanel : this.map.panel
content: container, panel.open({ content: container })
className: options.className,
})
}, },
buildList: function (options) { buildList: function (options) {

View file

@ -843,11 +843,9 @@ U.Map = L.Map.extend({
this.options.tilelayer = tilelayer.toJSON() this.options.tilelayer = tilelayer.toJSON()
this.isDirty = true this.isDirty = true
} }
if (this._controls.tilelayersChooser) if (this._controls.tilelayersChooser) {
this._controls.tilelayersChooser.openSwitcher({ this._controls.tilelayersChooser.openSwitcher({ callback, edit: true })
callback: callback, }
className: 'dark',
})
}, },
toGeoJSON: function () { toGeoJSON: function () {

View file

@ -193,8 +193,8 @@
.leaflet-iconLayers-layer { .leaflet-iconLayers-layer {
width: 38px; width: 38px;
height: 38px; height: 38px;
box-shadow: 0px 0px 2px #444; box-shadow: none;
border: 1px solid #bbb; border: 1px solid var(--color-lightGray);
border-radius: 4px; border-radius: 4px;
} }
.leaflet-iconLayers-layerTitleContainer { .leaflet-iconLayers-layerTitleContainer {
@ -218,6 +218,25 @@
.leaflet-iconLayers-layerCell:hover .leaflet-iconLayers-layerTitleContainer { .leaflet-iconLayers-layerCell:hover .leaflet-iconLayers-layerTitleContainer {
height: initial; height: initial;
} }
.leaflet-iconLayers-layerCell-plus {
width: 80px;
height: 80px;
background-color: var(--background-color);
vertical-align: middle;
text-align: center;
font-size: 3rem;
display: none;
line-height: 100%;
border-radius: var(--border-radius);
margin-bottom: 0;
border: 1px solid var(--color-lightGray);
}
.leaflet-iconLayers-layerCell-plus:hover {
background-color: var(--color-lightGray);
}
.leaflet-iconLayers:hover .leaflet-iconLayers-layerCell-plus {
display: block;
}

View file

@ -122,3 +122,20 @@ def test_can_have_smart_text_in_attribution(tilelayer, map, live_server, page):
page.goto(f"{live_server.url}{map.get_absolute_url()}") page.goto(f"{live_server.url}{map.get_absolute_url()}")
expect(page.get_by_text("© OpenStreetMap contributors")).to_be_visible() expect(page.get_by_text("© OpenStreetMap contributors")).to_be_visible()
expect(page.get_by_role("link", name="OpenStreetMap")).to_be_visible() expect(page.get_by_role("link", name="OpenStreetMap")).to_be_visible()
def test_map_should_display_a_more_button(map, live_server, tilelayers, page):
map.settings["properties"]["tilelayersControl"] = True
map.save()
page.goto(f"{live_server.url}{map.get_absolute_url()}")
page.locator(".leaflet-iconLayers").hover()
page.get_by_role("button", name="+").click()
panel = page.locator(".panel.left.on")
expect(panel).to_be_visible()
expect(panel.get_by_text("Forte")).to_be_visible()
panel.get_by_text("Forte").click()
tiles = page.locator(".leaflet-tile-pane img")
url_pattern = re.compile(
r"https://[abc]{1}.forte.tiles.quaidorsay.fr/fr/\d+/\d+/\d+.png"
)
expect(tiles.first).to_have_attribute("src", url_pattern)