From 3df52e002dc9d0ca5f4f86013a0a012090f768b7 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Mon, 17 Mar 2025 17:11:38 +0100 Subject: [PATCH 1/7] wip --- umap/static/umap/css/bar.css | 12 ++++++++++-- umap/static/umap/js/modules/ui/bar.js | 20 ++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/umap/static/umap/css/bar.css b/umap/static/umap/css/bar.css index 5df3bd87..444a6480 100644 --- a/umap/static/umap/css/bar.css +++ b/umap/static/umap/css/bar.css @@ -166,7 +166,8 @@ .umap-caption-bar button { margin-inline-start: 10px; } -.umap-caption-bar button + button:before { +.umap-caption-bar > button + select:before, +.umap-caption-bar > button + button:before { content: '|'; padding-inline-end: 10px; } @@ -196,7 +197,14 @@ z-index: var(--zindex-panels); } .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 { --current-footer-height: var(--footer-height); diff --git a/umap/static/umap/js/modules/ui/bar.js b/umap/static/umap/js/modules/ui/bar.js index d7bf77de..32f64e0c 100644 --- a/umap/static/umap/js/modules/ui/bar.js +++ b/umap/static/umap/js/modules/ui/bar.js @@ -167,6 +167,7 @@ const BOTTOM_BAR_TEMPLATE = ` + ` @@ -189,6 +190,17 @@ export class BottomBar extends WithTemplate { this._umap.openBrowser('filters') ) this._slideshow.renderToolbox(this.element) + this.elements.layers.addEventListener('change', () => { + const select = this.elements.layers + const selected = select.options[select.selectedIndex].value + this._umap.eachDataLayer((datalayer) => { + if (datalayer.id === selected) { + datalayer.show() + } else { + datalayer.hide() + } + }) + }) this.redraw() } @@ -201,6 +213,14 @@ export class BottomBar extends WithTemplate { this.elements.caption.hidden = !showMenus this.elements.browse.hidden = !showMenus this.elements.filter.hidden = !showMenus || !this._umap.properties.facetKey + this.elements.layers.innerHTML = '' + this._umap.eachDataLayer((datalayer) => { + this.elements.layers.appendChild( + Utils.loadTemplate( + `` + ) + ) + }) } } From 254a2018f51cc1f4693791a5185d032bc22b5396 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Mon, 17 Mar 2025 21:52:00 +0100 Subject: [PATCH 2/7] chore: use toggle to switch visibility in datalayer switcher --- umap/static/umap/js/modules/data/layer.js | 6 +++--- umap/static/umap/js/modules/ui/bar.js | 6 +----- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/umap/static/umap/js/modules/data/layer.js b/umap/static/umap/js/modules/data/layer.js index 92808cc2..61e2dc8a 100644 --- a/umap/static/umap/js/modules/data/layer.js +++ b/umap/static/umap/js/modules/data/layer.js @@ -966,11 +966,11 @@ export class DataLayer extends ServerStored { this.propagateHide() } - toggle() { + toggle(status) { // From now on, do not try to how/hidedataChanged // automatically this layer. this._forcedVisibility = true - if (!this.isVisible()) this.show() + if (!this.isVisible() || status) this.show() else this.hide() } @@ -1258,7 +1258,7 @@ export class DataLayer extends ServerStored { this ) } - DomEvent.on(toggle, 'click', this.toggle, this) + DomEvent.on(toggle, 'click', () => this.toggle()) DomEvent.on(zoomTo, 'click', this.zoomTo, this) container.classList.add(this.getHidableClass()) container.classList.toggle('off', !this.isVisible()) diff --git a/umap/static/umap/js/modules/ui/bar.js b/umap/static/umap/js/modules/ui/bar.js index 32f64e0c..146ec3b3 100644 --- a/umap/static/umap/js/modules/ui/bar.js +++ b/umap/static/umap/js/modules/ui/bar.js @@ -194,11 +194,7 @@ export class BottomBar extends WithTemplate { const select = this.elements.layers const selected = select.options[select.selectedIndex].value this._umap.eachDataLayer((datalayer) => { - if (datalayer.id === selected) { - datalayer.show() - } else { - datalayer.hide() - } + datalayer.toggle(datalayer.id === selected) }) }) this.redraw() From a4abecbd2ce36b49d32c9c451e8a98a59f71fe6f Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Mon, 17 Mar 2025 21:52:18 +0100 Subject: [PATCH 3/7] fixup: only show datalayers with inCaption=true in switcher --- umap/static/umap/js/modules/ui/bar.js | 1 + 1 file changed, 1 insertion(+) diff --git a/umap/static/umap/js/modules/ui/bar.js b/umap/static/umap/js/modules/ui/bar.js index 146ec3b3..05adefd8 100644 --- a/umap/static/umap/js/modules/ui/bar.js +++ b/umap/static/umap/js/modules/ui/bar.js @@ -211,6 +211,7 @@ export class BottomBar extends WithTemplate { this.elements.filter.hidden = !showMenus || !this._umap.properties.facetKey this.elements.layers.innerHTML = '' this._umap.eachDataLayer((datalayer) => { + if (!datalayer.options.inCaption) return this.elements.layers.appendChild( Utils.loadTemplate( `` From f2cde6af4eef71b8ebc31a7008b99447ac49a7e6 Mon Sep 17 00:00:00 2001 From: David Larlet Date: Wed, 26 Mar 2025 14:11:14 -0400 Subject: [PATCH 4/7] fixup: positionning of caption bar elements --- umap/static/umap/css/bar.css | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/umap/static/umap/css/bar.css b/umap/static/umap/css/bar.css index 444a6480..cf71e2c1 100644 --- a/umap/static/umap/css/bar.css +++ b/umap/static/umap/css/bar.css @@ -163,12 +163,13 @@ .umap-main-edit-toolbox h3 { display: inline; } -.umap-caption-bar button { - margin-inline-start: 10px; +.umap-caption-bar .umap-map-author { + margin-inline-end: 10px; } -.umap-caption-bar > button + select:before, +.umap-caption-bar > button + button:after, .umap-caption-bar > button + button:before { content: '|'; + padding-inline-start: 10px; padding-inline-end: 10px; } .umap-main-edit-toolbox .umap-user:hover { From 9eaf33c118eaaf74a6e6863208032d8408aba891 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Thu, 27 Mar 2025 10:34:38 +0100 Subject: [PATCH 5/7] wip: only show layer selector if there are at least two layers --- umap/static/umap/js/modules/ui/bar.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/umap/static/umap/js/modules/ui/bar.js b/umap/static/umap/js/modules/ui/bar.js index 05adefd8..6e42a4dc 100644 --- a/umap/static/umap/js/modules/ui/bar.js +++ b/umap/static/umap/js/modules/ui/bar.js @@ -210,14 +210,19 @@ export class BottomBar extends WithTemplate { this.elements.browse.hidden = !showMenus this.elements.filter.hidden = !showMenus || !this._umap.properties.facetKey this.elements.layers.innerHTML = '' - this._umap.eachDataLayer((datalayer) => { - if (!datalayer.options.inCaption) return - this.elements.layers.appendChild( - Utils.loadTemplate( - `` + const datalayers = this._umap.datalayersIndex.filter((d) => d.options.inCaption) + if (datalayers.length < 2) { + this.elements.layers.hidden = true + } else { + this.elements.layers.hidden = false + for (const datalayer of datalayers) { + this.elements.layers.appendChild( + Utils.loadTemplate( + `` + ) ) - ) - }) + } + } } } From 953b37a181ece6a651d6ddfff51c15b5d2a47eae Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Thu, 27 Mar 2025 11:59:56 +0100 Subject: [PATCH 6/7] fixup: fix tests --- umap/tests/integration/test_edit_datalayer.py | 2 +- umap/tests/integration/test_import.py | 4 ++-- umap/tests/integration/test_websocket_sync.py | 16 ++++++++-------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/umap/tests/integration/test_edit_datalayer.py b/umap/tests/integration/test_edit_datalayer.py index 7353d25d..e01c0ace 100644 --- a/umap/tests/integration/test_edit_datalayer.py +++ b/umap/tests/integration/test_edit_datalayer.py @@ -182,7 +182,7 @@ def test_can_restore_version(live_server, openmap, page, datalayer): page.get_by_role("button", name="Manage layers").click() page.locator(".panel.right").get_by_title("Edit", exact=True).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() expect(marker).to_have_class(re.compile(".*umap-ball-icon.*")) diff --git a/umap/tests/integration/test_import.py b/umap/tests/integration/test_import.py index 095b2da6..9429be55 100644 --- a/umap/tests/integration/test_import.py +++ b/umap/tests/integration/test_import.py @@ -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( "Imported map" ) - expect(page.get_by_text("Tunnels")).to_be_visible() - expect(page.get_by_text("Cities")).to_be_visible() + expect(page.locator(".panel.left").get_by_text("Tunnels")).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('img[src="https://tile.openstreetmap.fr/hot/6/32/21.png"]') diff --git a/umap/tests/integration/test_websocket_sync.py b/umap/tests/integration/test_websocket_sync.py index 40db583e..7c3c3f34 100644 --- a/umap/tests/integration/test_websocket_sync.py +++ b/umap/tests/integration/test_websocket_sync.py @@ -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") peerA.get_by_role("button", name="Open browser").click() - expect(peerA.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 1")).to_be_visible() + expect(peerA.locator(".panel").get_by_text("datalayer 2")).to_be_visible() peerB.get_by_role("button", name="Open browser").click() - expect(peerB.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 1")).to_be_visible() + expect(peerB.locator(".panel").get_by_text("datalayer 2")).to_be_visible() # Delete "datalayer 2" in peerA peerA.locator(".datalayer").get_by_role("button", name="Delete layer").first.click() peerA.get_by_role("button", name="OK").click() - expect(peerA.get_by_text("datalayer 2")).to_be_hidden() - expect(peerB.get_by_text("datalayer 2")).to_be_hidden() + expect(peerA.locator(".panel").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 with peerA.expect_response(re.compile(".*/datalayer/delete/.*")): peerA.get_by_role("button", name="Save").click() - expect(peerA.get_by_text("datalayer 2")).to_be_hidden() - expect(peerB.get_by_text("datalayer 2")).to_be_hidden() + expect(peerA.locator(".panel").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") From 79d60d09958dd09e44c4f8b72d342ab35bcac7c8 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Fri, 28 Mar 2025 15:56:28 +0100 Subject: [PATCH 7/7] fix: update datalayers switcher when datalayer visibility changes Co-authored-by: David Larlet --- umap/static/umap/js/modules/data/layer.js | 10 ++++++++-- umap/static/umap/js/modules/ui/bar.js | 10 +++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/umap/static/umap/js/modules/data/layer.js b/umap/static/umap/js/modules/data/layer.js index 61e2dc8a..f7d1cdd7 100644 --- a/umap/static/umap/js/modules/data/layer.js +++ b/umap/static/umap/js/modules/data/layer.js @@ -966,12 +966,18 @@ export class DataLayer extends ServerStored { this.propagateHide() } - toggle(status) { + toggle(force) { // From now on, do not try to how/hidedataChanged // automatically this layer. + let display = force this._forcedVisibility = true - if (!this.isVisible() || status) this.show() + if (force === undefined) { + if (!this.isVisible()) display = true + else display = false + } + if (display) this.show() else this.hide() + this._umap.bottomBar.redraw() } zoomTo() { diff --git a/umap/static/umap/js/modules/ui/bar.js b/umap/static/umap/js/modules/ui/bar.js index 6e42a4dc..d973fca1 100644 --- a/umap/static/umap/js/modules/ui/bar.js +++ b/umap/static/umap/js/modules/ui/bar.js @@ -193,6 +193,7 @@ export class BottomBar extends WithTemplate { 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) }) @@ -209,16 +210,23 @@ export class BottomBar extends WithTemplate { this.elements.caption.hidden = !showMenus this.elements.browse.hidden = !showMenus 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(``)) 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( - `` + `` ) ) }