diff --git a/umap/static/umap/js/modules/sync/engine.js b/umap/static/umap/js/modules/sync/engine.js index da33d136..5f4d08b5 100644 --- a/umap/static/umap/js/modules/sync/engine.js +++ b/umap/static/umap/js/modules/sync/engine.js @@ -1,5 +1,5 @@ import { WebSocketTransport } from "./websocket.js" -import { MapUpdater, MarkerUpdater, PolygonUpdater, PolylineUpdater } from "./updaters.js" +import { MapUpdater, MarkerUpdater, PolygonUpdater, PolylineUpdater, DatalayerUpdater } from "./updaters.js" export class SyncEngine { constructor(map) { @@ -21,6 +21,7 @@ export class MessagesDispatcher { marker: new MarkerUpdater(this.map), polyline: new PolylineUpdater(this.map), polygon: new PolygonUpdater(this.map), + datalayer: new DatalayerUpdater(this.map), } } @@ -34,6 +35,7 @@ export class MessagesDispatcher { return updater } case 'map': + case 'datalayer': return this.updaters[subject] default: throw new Error(`Unknown updater ${subject}, ${metadata}`) diff --git a/umap/static/umap/js/modules/sync/updaters.js b/umap/static/umap/js/modules/sync/updaters.js index f7e69b85..37be4c32 100644 --- a/umap/static/umap/js/modules/sync/updaters.js +++ b/umap/static/umap/js/modules/sync/updaters.js @@ -4,6 +4,10 @@ */ class BaseUpdater { + constructor(map) { + this.map = map + } + updateObjectValue(obj, key, value) { // XXX refactor so it's cleaner let path = key.split('.') @@ -22,6 +26,12 @@ class BaseUpdater { } } + getLayerFromID(layerId) { + if (layerId) + return this.map.getDataLayerByUmapId(layerId) + return this.map.defaultEditDataLayer() + } + applyMessage(message) { let { verb } = message return this[verb](message) @@ -29,10 +39,6 @@ class BaseUpdater { } export class MapUpdater extends BaseUpdater { - constructor(map) { - super() - this.map = map - } update({ key, value }) { console.log(key, value) @@ -41,6 +47,16 @@ export class MapUpdater extends BaseUpdater { } } +export class DatalayerUpdater extends BaseUpdater { + + update({ key, metadata, value }) { + const datalayer = this.getLayerFromID(metadata.id) + console.log(datalayer, key, value) + this.updateObjectValue(datalayer, key, value) + datalayer.renderProperties([key]) + } +} + /** * This is an abstract base class * And needs to be subclassed to be used. @@ -51,17 +67,6 @@ export class MapUpdater extends BaseUpdater { **/ class FeatureUpdater extends BaseUpdater { - constructor(map) { - super() - this.map = map - } - - getLayerFromID(layerId) { - if (layerId) - return this.map.getDataLayerByUmapId(layerId) - return this.map.defaultEditDataLayer() - } - getFeatureFromMetadata({ id, layerId }) { const datalayer = this.getLayerFromID(layerId) return datalayer.getFeatureById(id) diff --git a/umap/static/umap/js/umap.data.js b/umap/static/umap/js/umap.data.js index 824b24bf..3b75a75b 100644 --- a/umap/static/umap/js/umap.data.js +++ b/umap/static/umap/js/umap.data.js @@ -12,17 +12,33 @@ L.U.DataRendererMixin = { /** * Rerender the interface for the properties passed as an argument. * - * @param list updatedProperties : properties that have been updated. + * @param list properties : properties that have been updated. */ - renderProperties: function (updatedProperties) { + renderProperties: function (properties, builder) { let renderers = new Set() - for (const prop of updatedProperties) { + for (const prop of properties) { const propRenderers = this.propertiesRenderers[prop] if (propRenderers) { - for (const renderer of propRenderers) renderers.add(renderer) + for (const renderer of propRenderers) { + renderers.add(renderer) + } } } - for (const renderer of renderers) this[renderer]() + + // If no renderer has been found, use the default one. + const hasDefault = Object.keys(this.propertiesRenderers).includes('default') + const defaultRenderers = this.propertiesRenderers['default'] + + if (hasDefault && renderers.size == 0) { + for (const renderer of defaultRenderers) { + renderers.add(renderer) + } + } + + for (const renderer of renderers) { + this[renderer](properties, builder) + } + }, } diff --git a/umap/static/umap/js/umap.forms.js b/umap/static/umap/js/umap.forms.js index e0874eac..7d6e6c60 100644 --- a/umap/static/umap/js/umap.forms.js +++ b/umap/static/umap/js/umap.forms.js @@ -1276,7 +1276,7 @@ L.U.FormBuilder = L.FormBuilder.extend({ // in the map definition // Remove the "options" prefix for now field = field.replace('options.', '') - this.obj.renderProperties([field]) + this.obj.renderProperties([field], this) }, finish: function () { diff --git a/umap/static/umap/js/umap.layer.js b/umap/static/umap/js/umap.layer.js index df481482..2d404e37 100644 --- a/umap/static/umap/js/umap.layer.js +++ b/umap/static/umap/js/umap.layer.js @@ -513,6 +513,78 @@ L.U.DataLayer = L.Evented.extend({ editMode: 'advanced', }, + propertiesRenderers: { + 'name': ['updateDatalayersControl'], + 'description': ['updateDatalayersControl'], + 'type': ['resetLayer', 'updateDatalayersControl'], + 'displayOnLoad': ['updateDatalayersControl'], + 'browsable': ['updateDatalayersControl'], + 'inCaption': ['updateDatalayersControl'], + + // Shape options + 'color': ['redrawCallback'], + 'iconClass': ['redrawCallback'], + 'iconUrl': ['redrawCallback'], + 'iconOpacity': ['redrawCallback'], + 'opacity': ['redrawCallback'], + 'stroke': ['redrawCallback'], + 'weight': ['redrawCallback'], + 'fill': ['redrawCallback'], + 'fillColor': ['redrawCallback'], + 'fillOpacity': ['redrawCallback'], + + // Options fields + 'smoothFactor': ['redrawCallback'], + 'dashArray': ['redrawCallback'], + 'zoomTo': ['redrawCallback'], + 'fromZoom': ['redrawCallback'], + 'toZoom': ['redrawCallback'], + 'labelKey': ['redrawCallback'], + + // Popup fields + 'popupShape': ['redrawCallback'], + 'popupTemplate': ['redrawCallback'], + 'popupContentTemplate': ['redrawCallback'], + 'showLabel': ['redrawCallback'], + 'labelDirection': ['redrawCallback'], + 'labelInteractive': ['redrawCallback'], + 'outlinkTarget': ['redrawCallback'], + 'interactive': ['redrawCallback'], + + // Remote Data fields + 'remoteData.url': ['fetchRemoteData'], + 'remoteData.format': ['fetchRemoteData'], + 'fromZoom': ['fetchRemoteData'], + 'toZoom': ['fetchRemoteData'], + 'remoteData.dynamic': ['fetchRemoteData'], + 'remoteData.licence': ['fetchRemoteData'], + 'remoteData.proxy': ['fetchRemoteData'], + 'remoteData.ttl': ['fetchRemoteData'], + + 'default': ['redrawCallback'] + + }, + + updateDataLayersControl() { + this.map.updateDatalayersControl() + }, + + redrawCallback: function (properties, builder) { + this.hide() + for (let property of properties) { + this.layer.onEdit(property, builder) + } + this.show() + }, + + getSyncEngine: function () { + return this.map.syncEngine + }, + + getSyncSubject: function () { + return "datalayer" + }, + initialize: function (map, data) { this.map = map this._index = Array() @@ -1197,31 +1269,13 @@ L.U.DataLayer = L.Evented.extend({ ], ] const title = L.DomUtil.add('h3', '', container, L._('Layer properties')) - let builder = new L.U.FormBuilder(this, metadataFields, { - callback: function (e) { - this.map.updateDatalayersControl() - if (e.helper.field === 'options.type') { - this.resetLayer() - this.edit() - } - }, - }) + let builder = new L.U.FormBuilder(this, metadataFields) 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, + id: 'datalayer-layer-properties' }) const layerProperties = L.DomUtil.createFieldset( container, @@ -1244,8 +1298,7 @@ L.U.DataLayer = L.Evented.extend({ ] builder = new L.U.FormBuilder(this, shapeOptions, { - id: 'datalayer-advanced-properties', - callback: redrawCallback, + id: 'datalayer-advanced-properties' }) const shapeProperties = L.DomUtil.createFieldset(container, L._('Shape properties')) shapeProperties.appendChild(builder.build()) @@ -1261,7 +1314,6 @@ L.U.DataLayer = L.Evented.extend({ builder = new L.U.FormBuilder(this, optionsFields, { id: 'datalayer-advanced-properties', - callback: redrawCallback, }) const advancedProperties = L.DomUtil.createFieldset( container, @@ -1279,7 +1331,7 @@ L.U.DataLayer = L.Evented.extend({ 'options.outlinkTarget', 'options.interactive', ] - builder = new L.U.FormBuilder(this, popupFields, { callback: redrawCallback }) + builder = new L.U.FormBuilder(this, popupFields) const popupFieldset = L.DomUtil.createFieldset( container, L._('Interaction options') @@ -1644,6 +1696,8 @@ L.U.DataLayer = L.Evented.extend({ }, }) +L.U.DataLayer.include(L.U.DataRendererMixin) + L.TileLayer.include({ toJSON: function () { return {