feat: layers selector in bottom bar (#2579)

This commit is contained in:
Yohan Boniface 2025-03-28 16:15:20 +01:00 committed by GitHub
commit 7c5d821ec8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 63 additions and 18 deletions

View file

@ -163,11 +163,13 @@
.umap-main-edit-toolbox h3 { .umap-main-edit-toolbox h3 {
display: inline; display: inline;
} }
.umap-caption-bar button { .umap-caption-bar .umap-map-author {
margin-inline-start: 10px; margin-inline-end: 10px;
} }
.umap-caption-bar button + button:before { .umap-caption-bar > button + button:after,
.umap-caption-bar > button + button:before {
content: '|'; content: '|';
padding-inline-start: 10px;
padding-inline-end: 10px; padding-inline-end: 10px;
} }
.umap-main-edit-toolbox .umap-user:hover { .umap-main-edit-toolbox .umap-user:hover {
@ -196,7 +198,14 @@
z-index: var(--zindex-panels); z-index: var(--zindex-panels);
} }
.umap-caption-bar-enabled .umap-caption-bar { .umap-caption-bar-enabled .umap-caption-bar {
display: block; display: flex;
align-items: baseline;
}
.umap-caption-bar select {
margin-top: 0;
line-height: initial;
height: initial;
width: auto;
} }
.umap-caption-bar-enabled { .umap-caption-bar-enabled {
--current-footer-height: var(--footer-height); --current-footer-height: var(--footer-height);

View file

@ -966,12 +966,18 @@ export class DataLayer extends ServerStored {
this.propagateHide() this.propagateHide()
} }
toggle() { toggle(force) {
// From now on, do not try to how/hidedataChanged // From now on, do not try to how/hidedataChanged
// automatically this layer. // automatically this layer.
let display = force
this._forcedVisibility = true this._forcedVisibility = true
if (!this.isVisible()) this.show() if (force === undefined) {
if (!this.isVisible()) display = true
else display = false
}
if (display) this.show()
else this.hide() else this.hide()
this._umap.bottomBar.redraw()
} }
zoomTo() { zoomTo() {
@ -1258,7 +1264,7 @@ export class DataLayer extends ServerStored {
this this
) )
} }
DomEvent.on(toggle, 'click', this.toggle, this) DomEvent.on(toggle, 'click', () => this.toggle())
DomEvent.on(zoomTo, 'click', this.zoomTo, this) DomEvent.on(zoomTo, 'click', this.zoomTo, this)
container.classList.add(this.getHidableClass()) container.classList.add(this.getHidableClass())
container.classList.toggle('off', !this.isVisible()) container.classList.toggle('off', !this.isVisible())

View file

@ -167,6 +167,7 @@ const BOTTOM_BAR_TEMPLATE = `
<button class="umap-about-link flat" type="button" title="${translate('Open caption')}" data-ref="caption">${translate('Open caption')}</button> <button class="umap-about-link flat" type="button" title="${translate('Open caption')}" data-ref="caption">${translate('Open caption')}</button>
<button class="umap-open-browser-link flat" type="button" title="${translate('Browse data')}" data-ref="browse">${translate('Browse data')}</button> <button class="umap-open-browser-link flat" type="button" title="${translate('Browse data')}" data-ref="browse">${translate('Browse data')}</button>
<button class="umap-open-browser-link flat" type="button" title="${translate('Filter data')}" data-ref="filter">${translate('Filter data')}</button> <button class="umap-open-browser-link flat" type="button" title="${translate('Filter data')}" data-ref="filter">${translate('Filter data')}</button>
<select data-ref=layers></select>
</div> </div>
` `
@ -189,6 +190,14 @@ export class BottomBar extends WithTemplate {
this._umap.openBrowser('filters') this._umap.openBrowser('filters')
) )
this._slideshow.renderToolbox(this.element) this._slideshow.renderToolbox(this.element)
this.elements.layers.addEventListener('change', () => {
const select = this.elements.layers
const selected = select.options[select.selectedIndex].value
if (!selected) return
this._umap.eachDataLayer((datalayer) => {
datalayer.toggle(datalayer.id === selected)
})
})
this.redraw() this.redraw()
} }
@ -201,6 +210,27 @@ export class BottomBar extends WithTemplate {
this.elements.caption.hidden = !showMenus this.elements.caption.hidden = !showMenus
this.elements.browse.hidden = !showMenus this.elements.browse.hidden = !showMenus
this.elements.filter.hidden = !showMenus || !this._umap.properties.facetKey this.elements.filter.hidden = !showMenus || !this._umap.properties.facetKey
this.buildDataLayerSwitcher()
}
buildDataLayerSwitcher() {
this.elements.layers.innerHTML = ''
const datalayers = this._umap.datalayersIndex.filter((d) => d.options.inCaption)
if (datalayers.length < 2) {
this.elements.layers.hidden = true
} else {
this.elements.layers.appendChild(Utils.loadTemplate(`<option value=""></option>`))
this.elements.layers.hidden = false
const visible = datalayers.filter((datalayer) => datalayer.isVisible())
for (const datalayer of datalayers) {
const selected = visible.length === 1 && datalayer.isVisible() ? 'selected' : ''
this.elements.layers.appendChild(
Utils.loadTemplate(
`<option value="${datalayer.id}" ${selected}>${datalayer.getName()}</option>`
)
)
}
}
} }
} }

View file

@ -182,7 +182,7 @@ def test_can_restore_version(live_server, openmap, page, datalayer):
page.get_by_role("button", name="Manage layers").click() page.get_by_role("button", name="Manage layers").click()
page.locator(".panel.right").get_by_title("Edit", exact=True).click() page.locator(".panel.right").get_by_title("Edit", exact=True).click()
page.get_by_text("Versions").click() page.get_by_text("Versions").click()
page.get_by_role("button", name="Restore this version").last.click() page.get_by_title("Restore this version").last.click()
page.get_by_role("button", name="OK").click() page.get_by_role("button", name="OK").click()
expect(marker).to_have_class(re.compile(".*umap-ball-icon.*")) expect(marker).to_have_class(re.compile(".*umap-ball-icon.*"))

View file

@ -86,8 +86,8 @@ def test_umap_import_from_textarea(live_server, tilelayer, page, settings):
expect(page.locator(".umap-main-edit-toolbox .map-name")).to_have_text( expect(page.locator(".umap-main-edit-toolbox .map-name")).to_have_text(
"Imported map" "Imported map"
) )
expect(page.get_by_text("Tunnels")).to_be_visible() expect(page.locator(".panel.left").get_by_text("Tunnels")).to_be_visible()
expect(page.get_by_text("Cities")).to_be_visible() expect(page.locator(".panel.left").get_by_text("Cities")).to_be_visible()
expect(page.locator(".leaflet-control-minimap")).to_be_visible() expect(page.locator(".leaflet-control-minimap")).to_be_visible()
expect( expect(
page.locator('img[src="https://tile.openstreetmap.fr/hot/6/32/21.png"]') page.locator('img[src="https://tile.openstreetmap.fr/hot/6/32/21.png"]')

View file

@ -477,23 +477,23 @@ def test_should_sync_datalayers_delete(new_page, asgi_live_server, tilelayer):
peerB.goto(f"{asgi_live_server.url}{map.get_absolute_url()}?edit") peerB.goto(f"{asgi_live_server.url}{map.get_absolute_url()}?edit")
peerA.get_by_role("button", name="Open browser").click() peerA.get_by_role("button", name="Open browser").click()
expect(peerA.get_by_text("datalayer 1")).to_be_visible() expect(peerA.locator(".panel").get_by_text("datalayer 1")).to_be_visible()
expect(peerA.get_by_text("datalayer 2")).to_be_visible() expect(peerA.locator(".panel").get_by_text("datalayer 2")).to_be_visible()
peerB.get_by_role("button", name="Open browser").click() peerB.get_by_role("button", name="Open browser").click()
expect(peerB.get_by_text("datalayer 1")).to_be_visible() expect(peerB.locator(".panel").get_by_text("datalayer 1")).to_be_visible()
expect(peerB.get_by_text("datalayer 2")).to_be_visible() expect(peerB.locator(".panel").get_by_text("datalayer 2")).to_be_visible()
# Delete "datalayer 2" in peerA # Delete "datalayer 2" in peerA
peerA.locator(".datalayer").get_by_role("button", name="Delete layer").first.click() peerA.locator(".datalayer").get_by_role("button", name="Delete layer").first.click()
peerA.get_by_role("button", name="OK").click() peerA.get_by_role("button", name="OK").click()
expect(peerA.get_by_text("datalayer 2")).to_be_hidden() expect(peerA.locator(".panel").get_by_text("datalayer 2")).to_be_hidden()
expect(peerB.get_by_text("datalayer 2")).to_be_hidden() expect(peerB.locator(".panel").get_by_text("datalayer 2")).to_be_hidden()
# Save delete to the server # Save delete to the server
with peerA.expect_response(re.compile(".*/datalayer/delete/.*")): with peerA.expect_response(re.compile(".*/datalayer/delete/.*")):
peerA.get_by_role("button", name="Save").click() peerA.get_by_role("button", name="Save").click()
expect(peerA.get_by_text("datalayer 2")).to_be_hidden() expect(peerA.locator(".panel").get_by_text("datalayer 2")).to_be_hidden()
expect(peerB.get_by_text("datalayer 2")).to_be_hidden() expect(peerB.locator(".panel").get_by_text("datalayer 2")).to_be_hidden()
@pytest.mark.xdist_group(name="websockets") @pytest.mark.xdist_group(name="websockets")