wip: move default options to schema
This commit also introduce a new settings UMAP_SCHEMA, that could be used to easily override schema default, like the default color, the default path weigth and so on. I'm not documenting yet, because I'm not yet totally sure we want this.
This commit is contained in:
parent
da945cf733
commit
a7a854dd74
11 changed files with 73 additions and 56 deletions
|
@ -9,6 +9,7 @@ from django.core.files.base import File
|
|||
from django.core.signing import Signer
|
||||
from django.template.defaultfilters import slugify
|
||||
from django.urls import reverse
|
||||
from django.utils.functional import classproperty
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from .managers import PublicManager
|
||||
|
@ -217,7 +218,7 @@ class Map(NamedModel):
|
|||
"umap_id": self.pk,
|
||||
"onLoadPanel": "none",
|
||||
"captionBar": False,
|
||||
"default_iconUrl": "%sumap/img/marker.svg" % settings.STATIC_URL,
|
||||
"schema": self.schema,
|
||||
"slideshow": {},
|
||||
}
|
||||
)
|
||||
|
@ -328,6 +329,17 @@ class Map(NamedModel):
|
|||
datalayer.clone(map_inst=new)
|
||||
return new
|
||||
|
||||
@classproperty
|
||||
def schema(self):
|
||||
schema = settings.UMAP_SCHEMA
|
||||
schema.setdefault(
|
||||
"iconUrl",
|
||||
{
|
||||
"default": "%sumap/img/marker.svg" % settings.STATIC_URL,
|
||||
},
|
||||
)
|
||||
return schema
|
||||
|
||||
|
||||
class Pictogram(NamedModel):
|
||||
"""
|
||||
|
|
|
@ -256,6 +256,7 @@ UMAP_DEFAULT_SHARE_STATUS = None
|
|||
UMAP_DEFAULT_EDIT_STATUS = None
|
||||
UMAP_DEFAULT_FEATURES_HAVE_OWNERS = False
|
||||
UMAP_HOME_FEED = "latest"
|
||||
UMAP_SCHEMA = {}
|
||||
|
||||
UMAP_READONLY = env("UMAP_READONLY", default=False)
|
||||
UMAP_GZIP = True
|
||||
|
|
|
@ -30,7 +30,7 @@ export default class Browser {
|
|||
title.textContent = feature.getDisplayName() || '—'
|
||||
const bgcolor = feature.getDynamicOption('color')
|
||||
colorBox.style.backgroundColor = bgcolor
|
||||
if (symbol && symbol !== this.map.options.default_iconUrl) {
|
||||
if (symbol && symbol !== U.SCHEMA.iconUrl.default) {
|
||||
const icon = U.Icon.makeIconElement(symbol, colorBox)
|
||||
U.Icon.setIconContrast(icon, colorBox, symbol, bgcolor)
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ export default class Browser {
|
|||
'h3',
|
||||
'umap-browse-title',
|
||||
container,
|
||||
this.map.options.name
|
||||
this.map.getOption('name')
|
||||
)
|
||||
|
||||
const formContainer = DomUtil.create('div', '', container)
|
||||
|
|
|
@ -11,18 +11,22 @@ export const SCHEMA = {
|
|||
scaleControl: {
|
||||
type: Boolean,
|
||||
label: translate('Do you want to display the scale control?'),
|
||||
default: true,
|
||||
},
|
||||
moreControl: {
|
||||
type: Boolean,
|
||||
label: translate('Do you want to display the «more» control?'),
|
||||
default: true,
|
||||
},
|
||||
miniMap: {
|
||||
type: Boolean,
|
||||
label: translate('Do you want to display a minimap?'),
|
||||
default: false,
|
||||
},
|
||||
displayPopupFooter: {
|
||||
type: Boolean,
|
||||
label: translate('Do you want to display popup footer?'),
|
||||
default: false,
|
||||
},
|
||||
onLoadPanel: {
|
||||
type: String,
|
||||
|
@ -74,6 +78,7 @@ export const SCHEMA = {
|
|||
label: translate('color'),
|
||||
helpEntries: 'colorValue',
|
||||
inheritable: true,
|
||||
default: 'DarkBlue',
|
||||
},
|
||||
iconClass: {
|
||||
type: String,
|
||||
|
@ -85,6 +90,7 @@ export const SCHEMA = {
|
|||
['Drop', translate('Drop')],
|
||||
['Ball', translate('Ball')],
|
||||
],
|
||||
default: 'Default',
|
||||
},
|
||||
iconUrl: {
|
||||
type: String,
|
||||
|
@ -101,6 +107,7 @@ export const SCHEMA = {
|
|||
label: translate('Simplify'),
|
||||
helpEntries: 'smoothFactor',
|
||||
inheritable: true,
|
||||
default: 1.0,
|
||||
},
|
||||
iconOpacity: {
|
||||
type: Number,
|
||||
|
@ -109,6 +116,7 @@ export const SCHEMA = {
|
|||
step: 0.1,
|
||||
label: translate('icon opacity'),
|
||||
inheritable: true,
|
||||
default: 1,
|
||||
},
|
||||
opacity: {
|
||||
type: Number,
|
||||
|
@ -117,6 +125,7 @@ export const SCHEMA = {
|
|||
step: 0.1,
|
||||
label: translate('opacity'),
|
||||
inheritable: true,
|
||||
default: 0.5,
|
||||
},
|
||||
weight: {
|
||||
type: Number,
|
||||
|
@ -125,12 +134,14 @@ export const SCHEMA = {
|
|||
step: 1,
|
||||
label: translate('weight'),
|
||||
inheritable: true,
|
||||
default: 3,
|
||||
},
|
||||
fill: {
|
||||
type: Boolean,
|
||||
label: translate('fill'),
|
||||
helpEntries: 'fill',
|
||||
inheritable: true,
|
||||
default: true,
|
||||
},
|
||||
fillColor: {
|
||||
type: String,
|
||||
|
@ -146,6 +157,7 @@ export const SCHEMA = {
|
|||
step: 0.1,
|
||||
label: translate('fill opacity'),
|
||||
inheritable: true,
|
||||
default: 0.3,
|
||||
},
|
||||
dashArray: {
|
||||
type: String,
|
||||
|
@ -183,6 +195,7 @@ export const SCHEMA = {
|
|||
helpEntries: ['dynamicProperties', 'textFormatting'],
|
||||
placeholder: '# {name}',
|
||||
inheritable: true,
|
||||
default: '# {name}\n{description}',
|
||||
},
|
||||
zoomTo: {
|
||||
type: Number,
|
||||
|
@ -194,10 +207,12 @@ export const SCHEMA = {
|
|||
captionBar: {
|
||||
type: Boolean,
|
||||
label: translate('Do you want to display a caption bar?'),
|
||||
default: false,
|
||||
},
|
||||
captionMenus: {
|
||||
type: Boolean,
|
||||
label: translate('Do you want to display caption menus?'),
|
||||
default: true,
|
||||
},
|
||||
slideshow: {
|
||||
type: Object,
|
||||
|
@ -239,6 +254,7 @@ export const SCHEMA = {
|
|||
['top', translate('On the top')],
|
||||
['bottom', translate('On the bottom')],
|
||||
],
|
||||
default: 'auto',
|
||||
},
|
||||
labelInteractive: {
|
||||
type: Boolean,
|
||||
|
@ -274,22 +290,26 @@ export const SCHEMA = {
|
|||
permanentCreditBackground: {
|
||||
type: Boolean,
|
||||
label: translate('Permanent credits background'),
|
||||
default: true,
|
||||
},
|
||||
zoomControl: {
|
||||
type: Boolean,
|
||||
nullable: true,
|
||||
label: translate('Display the zoom control'),
|
||||
default: true,
|
||||
},
|
||||
datalayersControl: {
|
||||
type: Boolean,
|
||||
nullable: true,
|
||||
handler: 'DataLayersControl',
|
||||
label: translate('Display the data layers control'),
|
||||
default: true,
|
||||
},
|
||||
searchControl: {
|
||||
type: Boolean,
|
||||
nullable: true,
|
||||
label: translate('Display the search control'),
|
||||
default: true,
|
||||
},
|
||||
locateControl: {
|
||||
type: Boolean,
|
||||
|
@ -300,16 +320,19 @@ export const SCHEMA = {
|
|||
type: Boolean,
|
||||
nullable: true,
|
||||
label: translate('Display the fullscreen control'),
|
||||
default: true,
|
||||
},
|
||||
editinosmControl: {
|
||||
type: Boolean,
|
||||
nullable: true,
|
||||
label: translate('Display the control to open OpenStreetMap editor'),
|
||||
default: null,
|
||||
},
|
||||
embedControl: {
|
||||
type: Boolean,
|
||||
nullable: true,
|
||||
label: translate('Display the embed control'),
|
||||
default: true,
|
||||
},
|
||||
measureControl: {
|
||||
type: Boolean,
|
||||
|
@ -328,12 +351,14 @@ export const SCHEMA = {
|
|||
},
|
||||
easing: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
interactive: {
|
||||
type: Boolean,
|
||||
label: translate('Allow interactions'),
|
||||
helpEntries: 'interactive',
|
||||
inheritable: true,
|
||||
default: true,
|
||||
},
|
||||
fromZoom: {
|
||||
type: Number,
|
||||
|
@ -350,6 +375,7 @@ export const SCHEMA = {
|
|||
label: translate('stroke'),
|
||||
helpEntries: 'stroke',
|
||||
inheritable: true,
|
||||
default: true,
|
||||
},
|
||||
outlink: {
|
||||
label: translate('Link to…'),
|
||||
|
|
|
@ -1184,25 +1184,22 @@ U.AttributionControl = L.Control.Attribution.extend({
|
|||
this._container,
|
||||
credits
|
||||
)
|
||||
if (this._map.options.shortCredit) {
|
||||
L.DomUtil.add(
|
||||
'span',
|
||||
'',
|
||||
container,
|
||||
` — ${L.Util.toHTML(this._map.options.shortCredit)}`
|
||||
)
|
||||
const shortCredit = this._map.getOption('shortCredit'),
|
||||
captionMenus = this._map.getOption('captionMenus')
|
||||
if (shortCredit) {
|
||||
L.DomUtil.add('span', '', container, ` — ${L.Util.toHTML(shortCredit)}`)
|
||||
}
|
||||
if (this._map.options.captionMenus) {
|
||||
if (captionMenus) {
|
||||
const link = L.DomUtil.add('a', '', container, ` — ${L._('About')}`)
|
||||
L.DomEvent.on(link, 'click', L.DomEvent.stop)
|
||||
.on(link, 'click', this._map.displayCaption, this._map)
|
||||
.on(link, 'dblclick', L.DomEvent.stop)
|
||||
}
|
||||
if (window.top === window.self && this._map.options.captionMenus) {
|
||||
if (window.top === window.self && captionMenus) {
|
||||
// We are not in iframe mode
|
||||
L.DomUtil.createLink('', container, ` — ${L._('Home')}`, '/')
|
||||
}
|
||||
if (this._map.options.captionMenus) {
|
||||
if (captionMenus) {
|
||||
L.DomUtil.createLink(
|
||||
'',
|
||||
container,
|
||||
|
|
|
@ -53,7 +53,7 @@ U.FeatureMixin = {
|
|||
},
|
||||
|
||||
getSlug: function () {
|
||||
return this.properties[this.map.options.slugKey || 'name'] || ''
|
||||
return this.properties[this.map.getOption('slugKey') || 'name'] || ''
|
||||
},
|
||||
|
||||
getPermalink: function () {
|
||||
|
@ -209,7 +209,7 @@ U.FeatureMixin = {
|
|||
if (L.Browser.ielt9) return false
|
||||
if (this.datalayer.isRemoteLayer() && this.datalayer.options.remoteData.dynamic)
|
||||
return false
|
||||
return this.map.options.displayPopupFooter
|
||||
return this.map.getOption('displayPopupFooter')
|
||||
},
|
||||
|
||||
getPopupClass: function () {
|
||||
|
@ -309,7 +309,7 @@ U.FeatureMixin = {
|
|||
|
||||
zoomTo: function (e) {
|
||||
e = e || {}
|
||||
const easing = e.easing !== undefined ? e.easing : this.map.options.easing
|
||||
const easing = e.easing !== undefined ? e.easing : this.map.getOption('easing')
|
||||
if (easing) {
|
||||
this.map.flyTo(this.getCenter(), this.getBestZoom())
|
||||
} else {
|
||||
|
@ -975,7 +975,7 @@ U.PathMixin = {
|
|||
zoomTo: function (e) {
|
||||
// Use bounds instead of centroid for paths.
|
||||
e = e || {}
|
||||
const easing = e.easing !== undefined ? e.easing : this.map.options.easing
|
||||
const easing = e.easing !== undefined ? e.easing : this.map.getOption('easing')
|
||||
if (easing) {
|
||||
this.map.flyToBounds(this.getBounds(), this.getBestZoom())
|
||||
} else {
|
||||
|
|
|
@ -653,7 +653,7 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
|
|||
},
|
||||
|
||||
isDefault: function () {
|
||||
return !this.value() || this.value() === U.DEFAULT_ICON_URL
|
||||
return !this.value() || this.value() === U.SCHEMA.iconUrl.default
|
||||
},
|
||||
|
||||
addGrid: function (onSearch) {
|
||||
|
|
|
@ -19,7 +19,7 @@ U.Icon = L.DivIcon.extend({
|
|||
|
||||
_setRecent: function (url) {
|
||||
if (L.Util.hasVar(url)) return
|
||||
if (url === U.DEFAULT_ICON_URL) return
|
||||
if (url === U.SCHEMA.iconUrl.default) return
|
||||
if (U.Icon.RECENT.indexOf(url) === -1) {
|
||||
U.Icon.RECENT.push(url)
|
||||
}
|
||||
|
@ -236,7 +236,7 @@ U.Icon.setIconContrast = function (icon, parent, src, bgcolor) {
|
|||
if (L.DomUtil.contrastedColor(parent, bgcolor)) {
|
||||
// Decide whether to switch svg to white or not, but do it
|
||||
// only for internal SVG, as invert could do weird things
|
||||
if (L.Util.isPath(src) && src.endsWith('.svg') && src !== U.DEFAULT_ICON_URL) {
|
||||
if (L.Util.isPath(src) && src.endsWith('.svg') && src !== U.SCHEMA.iconUrl.default) {
|
||||
// Must be called after icon container is added to the DOM
|
||||
// An image
|
||||
icon.style.filter = 'invert(1)'
|
||||
|
|
|
@ -2,33 +2,12 @@ L.Map.mergeOptions({
|
|||
overlay: null,
|
||||
datalayers: [],
|
||||
hash: true,
|
||||
default_color: 'DarkBlue',
|
||||
default_smoothFactor: 1.0,
|
||||
default_opacity: 0.5,
|
||||
default_fillOpacity: 0.3,
|
||||
default_stroke: true,
|
||||
default_fill: true,
|
||||
default_weight: 3,
|
||||
default_iconOpacity: 1,
|
||||
default_iconClass: 'Default',
|
||||
default_popupContentTemplate: '# {name}\n{description}',
|
||||
default_interactive: true,
|
||||
default_labelDirection: 'auto',
|
||||
maxZoomLimit: 24,
|
||||
attributionControl: false,
|
||||
editMode: 'advanced',
|
||||
embedControl: true,
|
||||
zoomControl: true,
|
||||
datalayersControl: true,
|
||||
searchControl: true,
|
||||
editInOSMControl: false,
|
||||
editInOSMControlOptions: false,
|
||||
scaleControl: true,
|
||||
noControl: false, // Do not render any control.
|
||||
miniMap: false,
|
||||
name: '',
|
||||
description: '',
|
||||
displayPopupFooter: false,
|
||||
// When a TileLayer is in TMS mode, it needs -y instead of y.
|
||||
// This is usually handled by the TileLayer instance itself, but
|
||||
// we cannot rely on this because of the y is overriden by Leaflet
|
||||
|
@ -44,14 +23,9 @@ L.Map.mergeOptions({
|
|||
importPresets: [
|
||||
// {url: 'http://localhost:8019/en/datalayer/1502/', label: 'Simplified World Countries', format: 'geojson'}
|
||||
],
|
||||
moreControl: true,
|
||||
captionBar: false,
|
||||
captionMenus: true,
|
||||
slideshow: {},
|
||||
clickable: true,
|
||||
easing: false,
|
||||
permissions: {},
|
||||
permanentCreditBackground: true,
|
||||
featuresHaveOwner: false,
|
||||
})
|
||||
|
||||
|
@ -75,7 +49,8 @@ U.Map = L.Map.extend({
|
|||
geojson.properties.fullscreenControl = false
|
||||
|
||||
L.Map.prototype.initialize.call(this, el, geojson.properties)
|
||||
U.DEFAULT_ICON_URL = this.options.default_iconUrl
|
||||
|
||||
if (geojson.properties.schema) this.overrideSchema(geojson.properties.schema)
|
||||
|
||||
// After calling parent initialize, as we are doing initCenter our-selves
|
||||
if (geojson.geometry) this.options.center = this.latLng(geojson.geometry)
|
||||
|
@ -292,6 +267,12 @@ U.Map = L.Map.extend({
|
|||
}
|
||||
},
|
||||
|
||||
overrideSchema: function (schema) {
|
||||
for (const [key, extra] of Object.entries(schema)) {
|
||||
U.SCHEMA[key] = L.extend({}, U.SCHEMA[key], extra)
|
||||
}
|
||||
},
|
||||
|
||||
initControls: function () {
|
||||
this.helpMenuActions = {}
|
||||
this._controls = {}
|
||||
|
@ -333,7 +314,7 @@ U.Map = L.Map.extend({
|
|||
title: { false: L._('View Fullscreen'), true: L._('Exit Fullscreen') },
|
||||
})
|
||||
this._controls.search = new U.SearchControl()
|
||||
this._controls.embed = new L.Control.Embed(this, this.options.embedOptions)
|
||||
this._controls.embed = new L.Control.Embed(this)
|
||||
this._controls.tilelayersChooser = new U.TileLayerChooser(this)
|
||||
if (this.options.user) this._controls.star = new U.StarControl(this)
|
||||
this._controls.editinosm = new L.Control.EditInOSM({
|
||||
|
@ -399,7 +380,7 @@ U.Map = L.Map.extend({
|
|||
let name, status, control
|
||||
for (let i = 0; i < this.HIDDABLE_CONTROLS.length; i++) {
|
||||
name = this.HIDDABLE_CONTROLS[i]
|
||||
status = this.options[`${name}Control`]
|
||||
status = this.getOption(`${name}Control`)
|
||||
if (status === false) continue
|
||||
control = this._controls[name]
|
||||
if (!control) continue
|
||||
|
@ -408,9 +389,9 @@ U.Map = L.Map.extend({
|
|||
L.DomUtil.addClass(control._container, 'display-on-more')
|
||||
else L.DomUtil.removeClass(control._container, 'display-on-more')
|
||||
}
|
||||
if (this.options.permanentCredit) this._controls.permanentCredit.addTo(this)
|
||||
if (this.options.moreControl) this._controls.more.addTo(this)
|
||||
if (this.options.scaleControl) this._controls.scale.addTo(this)
|
||||
if (this.getOption('permanentCredit')) this._controls.permanentCredit.addTo(this)
|
||||
if (this.getOption('moreControl')) this._controls.more.addTo(this)
|
||||
if (this.getOption('scaleControl')) this._controls.scale.addTo(this)
|
||||
},
|
||||
|
||||
initDataLayers: async function (datalayers) {
|
||||
|
@ -760,7 +741,7 @@ U.Map = L.Map.extend({
|
|||
},
|
||||
|
||||
getDefaultOption: function (option) {
|
||||
return this.options[`default_${option}`]
|
||||
return U.SCHEMA[option] && U.SCHEMA[option].default
|
||||
},
|
||||
|
||||
getOption: function (option) {
|
||||
|
@ -1607,7 +1588,7 @@ U.Map = L.Map.extend({
|
|||
name = L.DomUtil.create('h3', '', container)
|
||||
L.DomEvent.disableClickPropagation(container)
|
||||
this.permissions.addOwnerLink('span', container)
|
||||
if (this.options.captionMenus) {
|
||||
if (this.getOption('captionMenus')) {
|
||||
L.DomUtil.createButton(
|
||||
'umap-about-link flat',
|
||||
container,
|
||||
|
|
|
@ -215,7 +215,7 @@ U.IframeExporter = L.Evented.extend({
|
|||
this.map = map
|
||||
this.baseUrl = L.Util.getBaseUrl()
|
||||
// Use map default, not generic default
|
||||
this.queryString.onLoadPanel = this.map.options.onLoadPanel
|
||||
this.queryString.onLoadPanel = this.map.getOption('onLoadPanel')
|
||||
},
|
||||
|
||||
getMap: function () {
|
||||
|
|
|
@ -488,7 +488,7 @@ class MapDetailMixin:
|
|||
"urls": _urls_for_js(),
|
||||
"tilelayers": TileLayer.get_list(),
|
||||
"editMode": self.edit_mode,
|
||||
"default_iconUrl": "%sumap/img/marker.svg" % settings.STATIC_URL, # noqa
|
||||
"schema": Map.schema,
|
||||
"umap_id": self.get_umap_id(),
|
||||
"starred": self.is_starred(),
|
||||
"licences": dict((l.name, l.json) for l in Licence.objects.all()),
|
||||
|
|
Loading…
Reference in a new issue