diff --git a/umap/static/umap/css/form.css b/umap/static/umap/css/form.css index 020888bf..e7496bb9 100644 --- a/umap/static/umap/css/form.css +++ b/umap/static/umap/css/form.css @@ -476,15 +476,6 @@ i.info { .umap-download:before { background-position: -72px -78px; } -.permissions-panel, -.umap-upload, -.umap-share, -.umap-datalayer-container, -.umap-layer-properties-container, -.umap-browse-data, -.umap-tilelayer-switcher-container { - padding: 0 10px; -} .umap-field-datalist { display: flex; justify-content: space-between; @@ -615,6 +606,6 @@ input[type=hidden].blur + [type="button"] { input.highlightable:not(:placeholder-shown) { border: 1px solid var(--color-brightCyan); } -.umap-upload [type=url] { +.umap-import [type=url] { margin-bottom: 0; } diff --git a/umap/static/umap/css/panel.css b/umap/static/umap/css/panel.css index 1a09b09c..b43a8027 100644 --- a/umap/static/umap/css/panel.css +++ b/umap/static/umap/css/panel.css @@ -107,3 +107,20 @@ border-bottom-right-radius: 0; } } + +:has(.right[data-highlight="caption"]) li[data-ref="caption"] button, +:has(.right[data-highlight="caption"]) li[data-ref="caption"] button:hover, +:has(.right[data-highlight="import"]) li[data-ref="import"] button, +:has(.right[data-highlight="import"]) li[data-ref="import"] button:hover, +:has(.right[data-highlight="layers"]) li[data-ref="layers"] button, +:has(.right[data-highlight="layers"]) li[data-ref="layers"] button:hover, +:has(.right[data-highlight="tilelayers"]) li[data-ref="tilelayers"] button, +:has(.right[data-highlight="tilelayers"]) li[data-ref="tilelayers"] button:hover, +:has(.right[data-highlight="center"]) li[data-ref="center"] button, +:has(.right[data-highlight="center"]) li[data-ref="center"] button:hover, +:has(.right[data-highlight="permissions"]) li[data-ref="permissions"] button, +:has(.right[data-highlight="permissions"]) li[data-ref="permissions"] button:hover, +:has(.right[data-highlight="settings"]) li[data-ref="settings"] button, +:has(.right[data-highlight="settings"]) li[data-ref="settings"] button:hover { + background-color: var(--color-mediumGray); +} diff --git a/umap/static/umap/js/modules/data/layer.js b/umap/static/umap/js/modules/data/layer.js index fa839b35..e17fc758 100644 --- a/umap/static/umap/js/modules/data/layer.js +++ b/umap/static/umap/js/modules/data/layer.js @@ -897,6 +897,7 @@ export class DataLayer extends ServerStored { this._umap.editPanel.open({ content: container, + highlight: 'layers', actions: [backButton], }) } diff --git a/umap/static/umap/js/modules/importer.js b/umap/static/umap/js/modules/importer.js index 7672dcdb..d375d164 100644 --- a/umap/static/umap/js/modules/importer.js +++ b/umap/static/umap/js/modules/importer.js @@ -10,7 +10,7 @@ import Dialog from './ui/dialog.js' import * as Utils from './utils.js' const TEMPLATE = ` -
+

${translate('Import data')}

${translate('Choose data')} @@ -261,7 +261,10 @@ export default class Importer extends Utils.WithTemplate { open() { if (!this.container) this.build() - const onLoad = this._umap.editPanel.open({ content: this.container }) + const onLoad = this._umap.editPanel.open({ + content: this.container, + highlight: 'import', + }) onLoad.then(() => this.onLoad()) } diff --git a/umap/static/umap/js/modules/permissions.js b/umap/static/umap/js/modules/permissions.js index 3ece0029..d206496a 100644 --- a/umap/static/umap/js/modules/permissions.js +++ b/umap/static/umap/js/modules/permissions.js @@ -166,12 +166,16 @@ export class MapPermissions extends ServerStored { Alert.info(translate('Please save the map first')) return } - const container = DomUtil.create('div', 'permissions-panel') + const container = DomUtil.create('div', 'umap-edit-permissions') DomUtil.createTitle(container, translate('Update permissions'), 'icon-key') if (this.isAnonymousMap()) this._editAnonymous(container) else this._editWithOwner(container) this._editDatalayers(container) - this._umap.editPanel.open({ content: container, className: 'dark' }) + this._umap.editPanel.open({ + content: container, + className: 'dark', + highlight: 'permissions', + }) } async attach() { diff --git a/umap/static/umap/js/modules/rendering/map.js b/umap/static/umap/js/modules/rendering/map.js index 1226bfa9..04ca2599 100644 --- a/umap/static/umap/js/modules/rendering/map.js +++ b/umap/static/umap/js/modules/rendering/map.js @@ -217,7 +217,7 @@ const ManageTilelayerMixin = { } }, - updateTileLayers: function () { + editTileLayers: function () { if (this._controls.tilelayersChooser) { this._controls.tilelayersChooser.openSwitcher({ edit: true }) } diff --git a/umap/static/umap/js/modules/rules.js b/umap/static/umap/js/modules/rules.js index 2e79ece1..f03fc20c 100644 --- a/umap/static/umap/js/modules/rules.js +++ b/umap/static/umap/js/modules/rules.js @@ -147,7 +147,7 @@ class Rule { .map((str) => `${value}${str || ''}`) } }) - this._umap.editPanel.open({ content: container }) + this._umap.editPanel.open({ content: container, highlight: 'settings' }) } renderToolbox(row) { diff --git a/umap/static/umap/js/modules/ui/bar.js b/umap/static/umap/js/modules/ui/bar.js index 32e17c5e..d7bf77de 100644 --- a/umap/static/umap/js/modules/ui/bar.js +++ b/umap/static/umap/js/modules/ui/bar.js @@ -219,9 +219,9 @@ const EDIT_BAR_TEMPLATE = ` - + - + ` @@ -249,9 +249,9 @@ export class EditBar extends WithTemplate { this._onClick('caption', () => this._umap.editCaption()) this._onClick('import', () => this._umap.importer.open()) this._onClick('layers', () => this._umap.editDatalayers()) - this._onClick('tiles', () => this._leafletMap.updateTileLayers()) + this._onClick('tilelayers', () => this._leafletMap.editTileLayers()) this._onClick('center', () => this._umap.editCenter()) - this._onClick('key', () => this._umap.permissions.edit()) + this._onClick('permissions', () => this._umap.permissions.edit()) this._onClick('settings', () => this._umap.edit()) this._addTitle('import', 'IMPORT_PANEL') this._addTitle('marker', 'DRAW_MARKER') @@ -267,9 +267,9 @@ export class EditBar extends WithTemplate { this.elements.caption.hidden = this._umap.properties.editMode !== 'advanced' this.elements.import.hidden = this._umap.properties.editMode !== 'advanced' this.elements.layers.hidden = this._umap.properties.editMode !== 'advanced' - this.elements.tiles.hidden = this._umap.properties.editMode !== 'advanced' + this.elements.tilelayers.hidden = this._umap.properties.editMode !== 'advanced' this.elements.center.hidden = this._umap.properties.editMode !== 'advanced' - this.elements.key.hidden = this._umap.properties.editMode !== 'advanced' + this.elements.permissions.hidden = this._umap.properties.editMode !== 'advanced' this.elements.settings.hidden = this._umap.properties.editMode !== 'advanced' } diff --git a/umap/static/umap/js/modules/ui/panel.js b/umap/static/umap/js/modules/ui/panel.js index e464a56a..741cfd30 100644 --- a/umap/static/umap/js/modules/ui/panel.js +++ b/umap/static/umap/js/modules/ui/panel.js @@ -25,13 +25,16 @@ export class Panel { return this.container.classList.contains('on') } - open({ content, className, actions = [] } = {}) { + open({ content, className, highlight, actions = [] } = {}) { if (this.isOpen()) { this.onClose() } this.container.className = `with-transition panel window ${this.className} ${ this.mode || '' }` + if (highlight) { + this.container.dataset.highlight = highlight + } document.body.classList.add(`panel-${this.className.split(' ')[0]}-on`) this.container.innerHTML = '' const actionsContainer = DomUtil.create('ul', 'buttons', this.container) @@ -75,6 +78,7 @@ export class Panel { close() { document.body.classList.remove(`panel-${this.className.split(' ')[0]}-on`) + this.container.dataset.highlight = null this.onClose() } diff --git a/umap/static/umap/js/modules/umap.js b/umap/static/umap/js/modules/umap.js index 9d5926d3..740cc9b9 100644 --- a/umap/static/umap/js/modules/umap.js +++ b/umap/static/umap/js/modules/umap.js @@ -744,7 +744,7 @@ export default class Umap extends ServerStored { editCaption() { if (!this.editEnabled) return if (this.properties.editMode !== 'advanced') return - const container = DomUtil.create('div', 'umap-edit-container') + const container = DomUtil.create('div') const metadataFields = ['properties.name', 'properties.description'] DomUtil.createTitle(container, translate('Edit map details'), 'icon-caption') @@ -765,13 +765,13 @@ export default class Umap extends ServerStored { ] const creditsBuilder = new MutatingForm(this, creditsFields, { umap: this }) credits.appendChild(creditsBuilder.build()) - this.editPanel.open({ content: container }) + this.editPanel.open({ content: container, highlight: 'caption' }) } editCenter() { if (!this.editEnabled) return if (this.properties.editMode !== 'advanced') return - const container = DomUtil.create('div', 'umap-edit-container') + const container = DomUtil.create('div') const metadataFields = [ ['properties.zoom', { handler: 'IntInput', label: translate('Default zoom') }], [ @@ -800,7 +800,7 @@ export default class Umap extends ServerStored { }) container.appendChild(form) container.appendChild(button) - this.editPanel.open({ content: container }) + this.editPanel.open({ content: container, highlight: 'center' }) } _editControls(container) { @@ -1157,7 +1157,11 @@ export default class Umap extends ServerStored { } this._advancedActions(container) - this.editPanel.open({ content: container, className: 'dark' }) + this.editPanel.open({ + content: container, + className: 'dark', + highlight: 'settings', + }) } reset() { @@ -1546,7 +1550,7 @@ export default class Umap extends ServerStored { this ) - this.editPanel.open({ content: container }) + this.editPanel.open({ content: container, highlight: 'layers' }) } getDataLayerByUmapId(id) { diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js index 472dd515..59b00a76 100644 --- a/umap/static/umap/js/umap.controls.js +++ b/umap/static/umap/js/umap.controls.js @@ -432,12 +432,12 @@ U.TileLayerChooser = L.Control.extend({ }, openSwitcher: function (options = {}) { - const container = L.DomUtil.create('div', 'umap-tilelayer-switcher-container') + const container = L.DomUtil.create('div', 'umap-edit-tilelayers') L.DomUtil.createTitle(container, L._('Change tilelayers'), 'icon-tilelayer') this._tilelayers_container = L.DomUtil.create('ul', '', container) this.buildList(options) const panel = options.edit ? this.map._umap.editPanel : this.map._umap.panel - panel.open({ content: container }) + panel.open({ content: container, highlight: 'tilelayers' }) }, buildList: function (options) { diff --git a/umap/static/umap/map.css b/umap/static/umap/map.css index 6ca508f8..7d26aa67 100644 --- a/umap/static/umap/map.css +++ b/umap/static/umap/map.css @@ -688,7 +688,7 @@ a.umap-control-caption, /* Tilelayer switcher */ /* ********************************* */ -.umap-tilelayer-switcher-container li { +.umap-edit-tilelayers li { border: 1px solid rgb(116, 116, 116); border-radius: 4px 4px 4px 4px; margin-bottom: 14px; @@ -700,7 +700,7 @@ a.umap-control-caption, margin-left: auto; margin-right: auto; } -.umap-tilelayer-switcher-container li div { +.umap-edit-tilelayers li div { background-color: rgb(116, 116, 116); bottom: 0; color: rgb(247, 246, 241); @@ -712,8 +712,8 @@ a.umap-control-caption, width: 100%; text-align: center; } -.umap-tilelayer-switcher-container li:hover div:before, -.umap-tilelayer-switcher-container .selected div:before { +.umap-edit-tilelayers li:hover div:before, +.umap-edit-tilelayers .selected div:before { content: "✓"; font-size: 1.3em; line-height: 56px; @@ -721,7 +721,7 @@ a.umap-control-caption, position: absolute; inset-inline-start: 7px; } -.umap-tilelayer-switcher-container li img { +.umap-edit-tilelayers li img { display: block; max-width: 100%; } diff --git a/umap/static/umap/vars.css b/umap/static/umap/vars.css index effda252..431b16b6 100644 --- a/umap/static/umap/vars.css +++ b/umap/static/umap/vars.css @@ -4,7 +4,7 @@ --color-darkBlue: #263B58; --color-lighterGray: #f6f6f6; --color-lightGray: #ddd; - --color-mediumGray: #3e4444; + --color-mediumGray: #474e4e; --color-darkGray: #323737; --color-darkerGray: #2a2e30; --color-light: white; @@ -58,7 +58,7 @@ --block-shadow: 0 1px 7px var(--color-mediumGray); } .dark { - --background-color: var(--color-darkGray); + --background-color: var(--color-mediumGray); --text-color: #efefef; } diff --git a/umap/tests/integration/test_draw_polygon.py b/umap/tests/integration/test_draw_polygon.py index 33bd3753..1f846fc8 100644 --- a/umap/tests/integration/test_draw_polygon.py +++ b/umap/tests/integration/test_draw_polygon.py @@ -471,7 +471,7 @@ def test_vertexmarker_not_shown_if_too_many(live_server, map, page, settings): settings.UMAP_ALLOW_ANONYMOUS = True page.goto(f"{live_server.url}/en/map/new/#15/48.4395/3.3189") page.get_by_title("Import data").click() - page.locator(".umap-upload textarea").fill(geojson) + page.locator(".umap-import textarea").fill(geojson) page.locator('select[name="format"]').select_option("geojson") page.get_by_role("button", name="Import data", exact=True).click() page.locator("path").click() diff --git a/umap/tests/integration/test_import.py b/umap/tests/integration/test_import.py index 449da6ad..d0ff7c19 100644 --- a/umap/tests/integration/test_import.py +++ b/umap/tests/integration/test_import.py @@ -76,7 +76,7 @@ def test_umap_import_from_textarea(live_server, tilelayer, page, settings): page.goto(f"{live_server.url}/map/new/") page.get_by_role("button", name="Open browser").click() page.get_by_title("Import data").click() - textarea = page.locator(".umap-upload textarea") + textarea = page.locator(".umap-import textarea") path = Path(__file__).parent.parent / "fixtures/test_upload_data.umap" textarea.fill(path.read_text()) page.locator('select[name="format"]').select_option("umap") @@ -111,7 +111,7 @@ def test_import_geojson_from_textarea(tilelayer, live_server, page): button = page.get_by_title("Import data") expect(button).to_be_visible() button.click() - textarea = page.locator(".umap-upload textarea") + textarea = page.locator(".umap-import textarea") path = Path(__file__).parent.parent / "fixtures/test_upload_data.json" textarea.fill(path.read_text()) page.locator('select[name="format"]').select_option("geojson") @@ -136,7 +136,7 @@ def test_import_invalid_data(tilelayer, live_server, page): button = page.get_by_title("Import data") expect(button).to_be_visible() button.click() - textarea = page.locator(".umap-upload textarea") + textarea = page.locator(".umap-import textarea") textarea.fill("invalid data") for format in ["geojson", "csv", "gpx", "kml", "georss", "osm", "umap"]: page.locator('select[name="format"]').select_option(format) @@ -156,7 +156,7 @@ def test_import_kml_from_textarea(tilelayer, live_server, page): button = page.get_by_title("Import data") expect(button).to_be_visible() button.click() - textarea = page.locator(".umap-upload textarea") + textarea = page.locator(".umap-import textarea") path = Path(__file__).parent.parent / "fixtures/test_upload_data.kml" textarea.fill(path.read_text()) page.locator('select[name="format"]').select_option("kml") @@ -180,7 +180,7 @@ def test_import_gpx_from_textarea(tilelayer, live_server, page, settings): button = page.get_by_title("Import data") expect(button).to_be_visible() button.click() - textarea = page.locator(".umap-upload textarea") + textarea = page.locator(".umap-import textarea") path = Path(__file__).parent.parent / "fixtures/test_upload_data.gpx" textarea.fill(path.read_text()) page.locator('select[name="format"]').select_option("gpx") @@ -237,7 +237,7 @@ def test_import_osm_from_textarea(tilelayer, live_server, page): button = page.get_by_title("Import data") expect(button).to_be_visible() button.click() - textarea = page.locator(".umap-upload textarea") + textarea = page.locator(".umap-import textarea") path = Path(__file__).parent.parent / "fixtures/test_upload_data_osm.json" textarea.fill(path.read_text()) page.locator('select[name="format"]').select_option("osm") @@ -257,7 +257,7 @@ def test_import_csv_from_textarea(tilelayer, live_server, page): button = page.get_by_title("Import data") expect(button).to_be_visible() button.click() - textarea = page.locator(".umap-upload textarea") + textarea = page.locator(".umap-import textarea") path = Path(__file__).parent.parent / "fixtures/test_upload_data.csv" textarea.fill(path.read_text()) page.locator('select[name="format"]').select_option("csv") @@ -276,7 +276,7 @@ def test_can_import_in_existing_datalayer(live_server, datalayer, page, openmap) expect(layers).to_have_count(1) page.get_by_role("button", name="Edit").click() page.get_by_title("Import data").click() - textarea = page.locator(".umap-upload textarea") + textarea = page.locator(".umap-import textarea") path = Path(__file__).parent.parent / "fixtures/test_upload_data.csv" textarea.fill(path.read_text()) page.locator('select[name="format"]').select_option("csv") @@ -297,7 +297,7 @@ def test_can_replace_datalayer_data(live_server, datalayer, page, openmap): expect(layers).to_have_count(1) page.get_by_role("button", name="Edit").click() page.get_by_title("Import data").click() - textarea = page.locator(".umap-upload textarea") + textarea = page.locator(".umap-import textarea") path = Path(__file__).parent.parent / "fixtures/test_upload_data.csv" textarea.fill(path.read_text()) page.locator('select[name="format"]').select_option("csv") @@ -318,7 +318,7 @@ def test_can_import_in_new_datalayer(live_server, datalayer, page, openmap): expect(layers).to_have_count(1) page.get_by_role("button", name="Edit").click() page.get_by_title("Import data").click() - textarea = page.locator(".umap-upload textarea") + textarea = page.locator(".umap-import textarea") path = Path(__file__).parent.parent / "fixtures/test_upload_data.csv" textarea.fill(path.read_text()) page.locator("select[name=format]").select_option("csv") @@ -364,7 +364,7 @@ def test_should_remove_dot_in_property_names(live_server, page, settings, tilela } page.goto(f"{live_server.url}/map/new/") page.get_by_title("Import data").click() - textarea = page.locator(".umap-upload textarea") + textarea = page.locator(".umap-import textarea") textarea.fill(json.dumps(data)) page.locator('select[name="format"]').select_option("geojson") page.get_by_role("button", name="Import data", exact=True).click() @@ -425,7 +425,7 @@ def test_import_geometry_collection(live_server, page, tilelayer): button = page.get_by_title("Import data") expect(button).to_be_visible() button.click() - textarea = page.locator(".umap-upload textarea") + textarea = page.locator(".umap-import textarea") textarea.fill(json.dumps(data)) page.locator('select[name="format"]').select_option("geojson") page.get_by_role("button", name="Import data", exact=True).click() @@ -459,7 +459,7 @@ def test_import_multipolygon(live_server, page, tilelayer): button = page.get_by_title("Import data") expect(button).to_be_visible() button.click() - textarea = page.locator(".umap-upload textarea") + textarea = page.locator(".umap-import textarea") textarea.fill(json.dumps(data)) page.locator('select[name="format"]').select_option("geojson") page.get_by_role("button", name="Import data", exact=True).click() @@ -491,7 +491,7 @@ def test_import_multipolyline(live_server, page, tilelayer): button = page.get_by_title("Import data") expect(button).to_be_visible() button.click() - textarea = page.locator(".umap-upload textarea") + textarea = page.locator(".umap-import textarea") textarea.fill(json.dumps(data)) page.locator('select[name="format"]').select_option("geojson") page.get_by_role("button", name="Import data", exact=True).click() @@ -506,7 +506,7 @@ def test_import_csv_without_valid_latlon_headers(tilelayer, live_server, page): layers = page.locator(".umap-browser .datalayer") markers = page.locator(".leaflet-marker-icon") page.get_by_title("Import data").click() - textarea = page.locator(".umap-upload textarea") + textarea = page.locator(".umap-import textarea") textarea.fill("a,b,c\n12.23,48.34,mypoint\n12.23,48.34,mypoint2") page.locator('select[name="format"]').select_option("csv") page.get_by_role("button", name="Import data", exact=True).click() @@ -523,7 +523,7 @@ def test_import_csv_with_commas_in_latlon(tilelayer, live_server, page, settings layers = page.locator(".umap-browser .datalayer") markers = page.locator(".leaflet-marker-icon") page.get_by_title("Import data").click() - textarea = page.locator(".umap-upload textarea") + textarea = page.locator(".umap-import textarea") textarea.fill("lat;lon;foobar\n12,24;48,34;mypoint\n12,23;48,35;mypoint2") page.locator('select[name="format"]').select_option("csv") page.get_by_role("button", name="Import data", exact=True).click() @@ -758,7 +758,7 @@ def test_import_osm_relation(tilelayer, live_server, page): button = page.get_by_title("Import data") expect(button).to_be_visible() button.click() - textarea = page.locator(".umap-upload textarea") + textarea = page.locator(".umap-import textarea") file_path = Path(__file__).parent.parent / "fixtures/test_import_osm_relation.json" textarea.fill(file_path.read_text()) page.locator('select[name="format"]').select_option("osm") @@ -778,7 +778,7 @@ def test_import_georss_from_textarea(tilelayer, live_server, page): button = page.get_by_title("Import data") expect(button).to_be_visible() button.click() - textarea = page.locator(".umap-upload textarea") + textarea = page.locator(".umap-import textarea") path = Path(__file__).parent.parent / "fixtures/test_upload_georss.xml" textarea.fill(path.read_text()) page.locator('select[name="format"]').select_option("georss")