diff --git a/umap/static/umap/css/icon.css b/umap/static/umap/css/icon.css
index 6da14e7d..b76020b1 100644
--- a/umap/static/umap/css/icon.css
+++ b/umap/static/umap/css/icon.css
@@ -112,6 +112,9 @@ html[dir="rtl"] .icon {
.icon-polyline {
background-position: 0 calc(var(--tile) * 3);
}
+.icon-profile {
+ background-position: 0 calc(var(--tile) * 4);
+}
.icon-resize {
background-position: calc(var(--tile) * 3) calc(var(--tile) * 6);
}
diff --git a/umap/static/umap/img/16-white.svg b/umap/static/umap/img/16-white.svg
index ceabb640..86704816 100644
--- a/umap/static/umap/img/16-white.svg
+++ b/umap/static/umap/img/16-white.svg
@@ -190,5 +190,11 @@
+
+
+
+
+
+
diff --git a/umap/static/umap/img/source/16-white.svg b/umap/static/umap/img/source/16-white.svg
index 0333e0af..9e99a16a 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,11 @@
+
+
+
+
+
+
diff --git a/umap/static/umap/js/modules/ui/contextmenu.js b/umap/static/umap/js/modules/ui/contextmenu.js
index 9231129a..fd61c84a 100644
--- a/umap/static/umap/js/modules/ui/contextmenu.js
+++ b/umap/static/umap/js/modules/ui/contextmenu.js
@@ -15,11 +15,16 @@ export default class ContextMenu extends Positioned {
})
}
- open([x, y], items) {
+ open([left, top], items) {
this.container.innerHTML = ''
for (const item of items) {
if (item === '-') {
this.container.appendChild(document.createElement('hr'))
+ } else if (typeof item.action === 'string') {
+ const li = loadTemplate(
+ `${item.label}`
+ )
+ this.container.appendChild(li)
} else {
const li = loadTemplate(
``
@@ -32,14 +37,22 @@ export default class ContextMenu extends Positioned {
}
}
document.body.appendChild(this.container)
- this.computePosition([x, y])
- this.container.querySelector('button').focus()
- this.container.addEventListener('keydown', (event) => {
- if (event.key === 'Escape') {
- event.stopPropagation()
- this.close()
- }
- })
+ if (this.options.fixed) {
+ this.setPosition({ left, top })
+ } else {
+ this.computePosition([left, top])
+ }
+ this.container.querySelector('li > *').focus()
+ this.container.addEventListener(
+ 'keydown',
+ (event) => {
+ if (event.key === 'Escape') {
+ event.stopPropagation()
+ this.close()
+ }
+ },
+ { once: true }
+ )
}
close() {
diff --git a/umap/static/umap/js/modules/urls.js b/umap/static/umap/js/modules/urls.js
index 171ca91b..c3cb8a2a 100644
--- a/umap/static/umap/js/modules/urls.js
+++ b/umap/static/umap/js/modules/urls.js
@@ -5,10 +5,14 @@ export default class URLs {
this.urls = serverUrls
}
+ has(urlName) {
+ return urlName in this.urls
+ }
+
get(urlName, params) {
if (typeof this[urlName] === 'function') return this[urlName](params)
- if (this.urls.hasOwnProperty(urlName)) {
+ if (this.has(urlName)) {
return template(this.urls[urlName], params)
}
throw `Unable to find a URL for route ${urlName}`
diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js
index 869a7211..5bad389a 100644
--- a/umap/static/umap/js/umap.controls.js
+++ b/umap/static/umap/js/umap.controls.js
@@ -632,14 +632,39 @@ const ControlsMixin = {
L.DomEvent.on(shareStatusButton, 'click', this.permissions.edit, this.permissions)
}
if (this.options.user?.id) {
- L.DomUtil.createLink(
- 'umap-user',
- rightContainer,
- L._('My Dashboard ({username})', {
- username: this.options.user.name,
- }),
- this.options.user.url
- )
+ const button = U.Utils.loadTemplate(`
+
+ `)
+ rightContainer.appendChild(button)
+ const menu = new U.ContextMenu({ className: 'dark', fixed: true })
+ const actions = [
+ {
+ label: L._('New map'),
+ action: this.urls.get('map_new'),
+ },
+ {
+ label: L._('My maps'),
+ action: this.urls.get('user_dashboard'),
+ },
+ {
+ label: L._('My teams'),
+ action: this.urls.get('user_teams'),
+ },
+ ]
+ if (this.urls.has('user_profile')) {
+ actions.push({
+ label: L._('My profile'),
+ action: this.urls.get('user_profile'),
+ })
+ }
+ button.addEventListener('click', () => {
+ const x = button.offsetLeft
+ const y = button.offsetTop + button.offsetHeight
+ menu.open([x, y], actions)
+ })
}
this.help.getStartedLink(rightContainer)
const controlEditCancel = L.DomUtil.createButton(
@@ -799,7 +824,8 @@ U.TileLayerControl = L.Control.IconLayers.extend({
)
const button = L.DomUtil.element({
tagName: 'button',
- className: 'leaflet-iconLayers-layerCell leaflet-iconLayers-layerCell-plus button',
+ className:
+ 'leaflet-iconLayers-layerCell leaflet-iconLayers-layerCell-plus button',
textContent: '+',
parent: lastRow,
})
diff --git a/umap/static/umap/map.css b/umap/static/umap/map.css
index c330e00b..4c57acf9 100644
--- a/umap/static/umap/map.css
+++ b/umap/static/umap/map.css
@@ -592,17 +592,16 @@ ul.photon-autocomplete {
left: 0;
right: 0;
height: 46px;
- background-color: var(--color-darkGray);
padding: 0 10px;
text-align: start;
line-height: var(--control-size);
cursor: auto;
border-bottom: 1px solid #222;
z-index: var(--zindex-panels);
- opacity: 0.98;
- color: #fff;
display: flex;
justify-content: space-between;
+ background-color: var(--background-color);
+ color: var(--text-color);
}
.umap-left-edit-toolbox,
.umap-right-edit-toolbox {
@@ -1488,9 +1487,6 @@ span.popup-icon {
.umap-main-edit-toolbox .umap-user {
margin-inline-end: 10px;
}
- .umap-main-edit-toolbox .umap-user:after {
- display: none;
- }
}
@media all and (max-width: 640px) {
.umap-main-edit-toolbox .umap-user {
diff --git a/umap/tests/integration/test_basics.py b/umap/tests/integration/test_basics.py
index c19c4a96..3ea7c2a7 100644
--- a/umap/tests/integration/test_basics.py
+++ b/umap/tests/integration/test_basics.py
@@ -94,4 +94,4 @@ def test_login_from_map_page(live_server, page, tilelayer, settings, user, conte
# Save should have proceed
assert Map.objects.count() == 1
# Use name should now appear on the header toolbar
- expect(page.get_by_text("My Dashboard (Joe)")).to_be_visible()
+ expect(page.get_by_role("button", name="Joe")).to_be_visible()