diff --git a/umap/static/umap/js/umap.forms.js b/umap/static/umap/js/umap.forms.js index 97f39d15..fabf2424 100644 --- a/umap/static/umap/js/umap.forms.js +++ b/umap/static/umap/js/umap.forms.js @@ -377,12 +377,15 @@ L.FormBuilder.PopupContent = L.FormBuilder.Select.extend({ }) L.FormBuilder.LayerTypeChooser = L.FormBuilder.Select.extend({ - selectOptions: [ - ['Default', L._('Default')], - ['Cluster', L._('Clustered')], - ['Heat', L._('Heatmap')], - ['Choropleth', L._('Choropleth')], - ], + getOptions: function () { + const layer_classes = [ + L.U.Layer.Default, + L.U.Layer.Cluster, + L.U.Layer.Heat, + L.U.Layer.Choropleth, + ] + return layer_classes.map((class_) => [class_.TYPE, class_.NAME]) + }, }) L.FormBuilder.SlideshowDelay = L.FormBuilder.IntSelect.extend({ diff --git a/umap/static/umap/js/umap.layer.js b/umap/static/umap/js/umap.layer.js index 534fc856..0f47df7b 100644 --- a/umap/static/umap/js/umap.layer.js +++ b/umap/static/umap/js/umap.layer.js @@ -1,6 +1,16 @@ L.U.Layer = { canBrowse: true, + getType: function () { + const proto = Object.getPrototypeOf(this) + return proto.constructor.TYPE + }, + + getName: function () { + const proto = Object.getPrototypeOf(this) + return proto.constructor.NAME + }, + getFeatures: function () { return this._layers }, @@ -17,7 +27,10 @@ L.U.Layer = { } L.U.Layer.Default = L.FeatureGroup.extend({ - _type: 'Default', + statics: { + NAME: L._('Default'), + TYPE: 'Default', + }, includes: [L.U.Layer], initialize: function (datalayer) { @@ -39,7 +52,10 @@ L.U.MarkerCluster = L.MarkerCluster.extend({ }) L.U.Layer.Cluster = L.MarkerClusterGroup.extend({ - _type: 'Cluster', + statics: { + NAME: L._('Clustered'), + TYPE: 'Cluster', + }, includes: [L.U.Layer], initialize: function (datalayer) { @@ -117,7 +133,10 @@ L.U.Layer.Cluster = L.MarkerClusterGroup.extend({ }) L.U.Layer.Choropleth = L.FeatureGroup.extend({ - _type: 'Choropleth', + statics: { + NAME: L._('Choropleth'), + TYPE: 'Choropleth', + }, includes: [L.U.Layer], canBrowse: true, // Have defaults that better suit the choropleth mode. @@ -320,7 +339,10 @@ L.U.Layer.Choropleth = L.FeatureGroup.extend({ }) L.U.Layer.Heat = L.HeatLayer.extend({ - _type: 'Heat', + statics: { + NAME: L._('Heatmap'), + TYPE: 'Heat', + }, includes: [L.U.Layer], canBrowse: false, @@ -615,7 +637,7 @@ L.U.DataLayer = L.Evented.extend({ // Only reset if type is defined (undefined is the default) and different from current type if ( this.layer && - (!this.options.type || this.options.type === this.layer._type) && + (!this.options.type || this.options.type === this.layer.getType()) && !force ) { return @@ -1188,6 +1210,28 @@ L.U.DataLayer = L.Evented.extend({ }) container.appendChild(builder.build()) + const redrawCallback = function (e) { + const field = e.helper.field, + builder = e.helper.builder + this.hide() + this.layer.onEdit(field, builder) + this.show() + } + + const layerOptions = this.layer.getEditableOptions() + + if (layerOptions.length) { + builder = new L.U.FormBuilder(this, layerOptions, { + id: 'datalayer-layer-properties', + callback: redrawCallback, + }) + const layerProperties = L.DomUtil.createFieldset( + container, + `${this.layer.getName()}: ${L._('settings')}` + ) + layerProperties.appendChild(builder.build()) + } + let shapeOptions = [ 'options.color', 'options.iconClass', @@ -1201,13 +1245,6 @@ L.U.DataLayer = L.Evented.extend({ 'options.fillOpacity', ] - const redrawCallback = function (e) { - const field = e.helper.field, - builder = e.helper.builder - this.hide() - this.layer.onEdit(field, builder) - this.show() - } builder = new L.U.FormBuilder(this, shapeOptions, { id: 'datalayer-advanced-properties', callback: redrawCallback, @@ -1224,8 +1261,6 @@ L.U.DataLayer = L.Evented.extend({ 'options.labelKey', ] - optionsFields = optionsFields.concat(this.layer.getEditableOptions()) - builder = new L.U.FormBuilder(this, optionsFields, { id: 'datalayer-advanced-properties', callback: redrawCallback, diff --git a/umap/tests/integration/test_edit_datalayer.py b/umap/tests/integration/test_edit_datalayer.py new file mode 100644 index 00000000..dc393400 --- /dev/null +++ b/umap/tests/integration/test_edit_datalayer.py @@ -0,0 +1,45 @@ +from playwright.sync_api import expect + + +def test_should_have_fieldset_for_layer_type_properties(page, live_server, tilelayer): + page.goto(f"{live_server.url}/en/map/new/") + + # Open DataLayers list + button = page.get_by_title("Manage Layers") + expect(button).to_be_visible() + button.click() + + edit = page.locator("#umap-ui-container").get_by_title("Edit", exact=True) + expect(edit).to_be_visible() + edit.click() + + select = page.locator("#umap-ui-container .umap-field-type select") + expect(select).to_be_visible() + + choropleth_header = page.get_by_text("Choropleth: settings") + heat_header = page.get_by_text("Heatmap: settings") + cluster_header = page.get_by_text("Clustered: settings") + expect(choropleth_header).to_be_hidden() + expect(heat_header).to_be_hidden() + expect(cluster_header).to_be_hidden() + + # Switching to Choropleth should add a dedicated fieldset + select.select_option("Choropleth") + expect(choropleth_header).to_be_visible() + expect(heat_header).to_be_hidden() + expect(cluster_header).to_be_hidden() + + select.select_option("Heat") + expect(heat_header).to_be_visible() + expect(choropleth_header).to_be_hidden() + expect(cluster_header).to_be_hidden() + + select.select_option("Cluster") + expect(cluster_header).to_be_visible() + expect(choropleth_header).to_be_hidden() + expect(heat_header).to_be_hidden() + + select.select_option("Default") + expect(choropleth_header).to_be_hidden() + expect(heat_header).to_be_hidden() + expect(cluster_header).to_be_hidden()