Merge pull request #1661 from umap-project/schema-i18n
Add minimal schema module
This commit is contained in:
commit
6396ee5e58
17 changed files with 557 additions and 470 deletions
|
@ -10,6 +10,7 @@ from django.core.files.base import File
|
||||||
from django.core.signing import Signer
|
from django.core.signing import Signer
|
||||||
from django.template.defaultfilters import slugify
|
from django.template.defaultfilters import slugify
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
from django.utils.functional import classproperty
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from .managers import PublicManager
|
from .managers import PublicManager
|
||||||
|
@ -218,7 +219,7 @@ class Map(NamedModel):
|
||||||
"umap_id": self.pk,
|
"umap_id": self.pk,
|
||||||
"onLoadPanel": "none",
|
"onLoadPanel": "none",
|
||||||
"captionBar": False,
|
"captionBar": False,
|
||||||
"default_iconUrl": "%sumap/img/marker.svg" % settings.STATIC_URL,
|
"schema": self.extra_schema,
|
||||||
"slideshow": {},
|
"slideshow": {},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -329,6 +330,14 @@ class Map(NamedModel):
|
||||||
datalayer.clone(map_inst=new)
|
datalayer.clone(map_inst=new)
|
||||||
return new
|
return new
|
||||||
|
|
||||||
|
@classproperty
|
||||||
|
def extra_schema(self):
|
||||||
|
return {
|
||||||
|
"iconUrl": {
|
||||||
|
"default": "%sumap/img/marker.svg" % settings.STATIC_URL,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class Pictogram(NamedModel):
|
class Pictogram(NamedModel):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -30,7 +30,7 @@ export default class Browser {
|
||||||
title.textContent = feature.getDisplayName() || '—'
|
title.textContent = feature.getDisplayName() || '—'
|
||||||
const bgcolor = feature.getDynamicOption('color')
|
const bgcolor = feature.getDynamicOption('color')
|
||||||
colorBox.style.backgroundColor = bgcolor
|
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)
|
const icon = U.Icon.makeIconElement(symbol, colorBox)
|
||||||
U.Icon.setIconContrast(icon, colorBox, symbol, bgcolor)
|
U.Icon.setIconContrast(icon, colorBox, symbol, bgcolor)
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,7 @@ export default class Browser {
|
||||||
'h3',
|
'h3',
|
||||||
'umap-browse-title',
|
'umap-browse-title',
|
||||||
container,
|
container,
|
||||||
this.map.options.name
|
this.map.getOption('name')
|
||||||
)
|
)
|
||||||
|
|
||||||
const formContainer = DomUtil.create('div', '', container)
|
const formContainer = DomUtil.create('div', '', container)
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
import * as L from '../../vendors/leaflet/leaflet-src.esm.js'
|
|
||||||
import URLs from './urls.js'
|
import URLs from './urls.js'
|
||||||
import Browser from './browser.js'
|
import Browser from './browser.js'
|
||||||
import * as Utils from './utils.js'
|
import * as Utils from './utils.js'
|
||||||
|
import {SCHEMA} from './schema.js'
|
||||||
import { Request, ServerRequest, RequestError, HTTPError, NOKError } from './request.js'
|
import { Request, ServerRequest, RequestError, HTTPError, NOKError } from './request.js'
|
||||||
|
|
||||||
// Import modules and export them to the global scope.
|
// Import modules and export them to the global scope.
|
||||||
// For the not yet module-compatible JS out there.
|
// For the not yet module-compatible JS out there.
|
||||||
|
|
||||||
// Copy the leaflet module, it's expected by leaflet plugins to be writeable.
|
|
||||||
window.L = { ...L }
|
|
||||||
window.U = {
|
window.U = {
|
||||||
URLs,
|
URLs,
|
||||||
Request,
|
Request,
|
||||||
|
@ -18,4 +16,5 @@ window.U = {
|
||||||
NOKError,
|
NOKError,
|
||||||
Browser,
|
Browser,
|
||||||
Utils,
|
Utils,
|
||||||
|
SCHEMA,
|
||||||
}
|
}
|
||||||
|
|
35
umap/static/umap/js/modules/i18n.js
Normal file
35
umap/static/umap/js/modules/i18n.js
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// Comes from https://github.com/Leaflet/Leaflet/pull/9281
|
||||||
|
import { Util } from '../../vendors/leaflet/leaflet-src.esm.js'
|
||||||
|
|
||||||
|
export const locales = {}
|
||||||
|
|
||||||
|
// @property locale: String
|
||||||
|
// The current locale code, that will be used when translating strings.
|
||||||
|
export let locale = null
|
||||||
|
|
||||||
|
// @function registerLocale(code: String, locale?: Object): String
|
||||||
|
// Define localized strings for a given locale, defined by `code`.
|
||||||
|
export function registerLocale(code, locale) {
|
||||||
|
locales[code] = Util.extend({}, locales[code], locale)
|
||||||
|
}
|
||||||
|
// @function setLocale(code: String): undefined
|
||||||
|
// Define or change the locale code to be used when translating strings.
|
||||||
|
export function setLocale(code) {
|
||||||
|
locale = code
|
||||||
|
}
|
||||||
|
// @function translate(string: String, data?: Object): String
|
||||||
|
// Actually try to translate the `string`, with optionnal variable passed in `data`.
|
||||||
|
export function translate(string, data = {}) {
|
||||||
|
if (locale && locales[locale] && locales[locale][string] !== undefined) {
|
||||||
|
string = locales[locale][string]
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// Do not fail if some data is missing
|
||||||
|
// a bad translation should not break the app
|
||||||
|
string = Util.template(string, data)
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return string
|
||||||
|
}
|
7
umap/static/umap/js/modules/leaflet-configure.js
Normal file
7
umap/static/umap/js/modules/leaflet-configure.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import * as L from '../../vendors/leaflet/leaflet-src.esm.js'
|
||||||
|
// Comes from https://github.com/Leaflet/Leaflet/pull/9281
|
||||||
|
// TODELETE once it's merged!
|
||||||
|
import * as i18n from './i18n.js'
|
||||||
|
|
||||||
|
window.L = { ...L, ...i18n }
|
||||||
|
window.L._ = i18n.translate
|
388
umap/static/umap/js/modules/schema.js
Normal file
388
umap/static/umap/js/modules/schema.js
Normal file
|
@ -0,0 +1,388 @@
|
||||||
|
import { translate } from './i18n.js'
|
||||||
|
|
||||||
|
export const SCHEMA = {
|
||||||
|
zoom: {
|
||||||
|
type: Number,
|
||||||
|
},
|
||||||
|
scrollWheelZoom: {
|
||||||
|
type: Boolean,
|
||||||
|
label: translate('Allow scroll wheel zoom?'),
|
||||||
|
},
|
||||||
|
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,
|
||||||
|
label: translate('Do you want to display a panel on load?'),
|
||||||
|
choices: [
|
||||||
|
['none', translate('None')],
|
||||||
|
['caption', translate('Caption')],
|
||||||
|
['databrowser', translate('Data browser')],
|
||||||
|
['facet', translate('Facet search')],
|
||||||
|
],
|
||||||
|
default: 'none',
|
||||||
|
},
|
||||||
|
defaultView: {
|
||||||
|
type: String,
|
||||||
|
label: translate('Default view'),
|
||||||
|
choices: [
|
||||||
|
['center', translate('Saved center and zoom')],
|
||||||
|
['data', translate('Fit all data')],
|
||||||
|
['latest', translate('Latest feature')],
|
||||||
|
['locate', translate('User location')],
|
||||||
|
],
|
||||||
|
default: 'center',
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
label: translate('name'),
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
label: translate('description'),
|
||||||
|
type: 'Text',
|
||||||
|
helpEntries: 'textFormatting',
|
||||||
|
},
|
||||||
|
licence: {
|
||||||
|
type: String,
|
||||||
|
label: translate('licence'),
|
||||||
|
},
|
||||||
|
tilelayer: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
overlay: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
limitBounds: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
handler: 'ColorPicker',
|
||||||
|
label: translate('color'),
|
||||||
|
helpEntries: 'colorValue',
|
||||||
|
inheritable: true,
|
||||||
|
default: 'DarkBlue',
|
||||||
|
},
|
||||||
|
iconClass: {
|
||||||
|
type: String,
|
||||||
|
label: translate('Icon shape'),
|
||||||
|
inheritable: true,
|
||||||
|
choices: [
|
||||||
|
['Default', translate('Default')],
|
||||||
|
['Circle', translate('Circle')],
|
||||||
|
['Drop', translate('Drop')],
|
||||||
|
['Ball', translate('Ball')],
|
||||||
|
],
|
||||||
|
default: 'Default',
|
||||||
|
},
|
||||||
|
iconUrl: {
|
||||||
|
type: String,
|
||||||
|
handler: 'IconUrl',
|
||||||
|
label: translate('Icon symbol'),
|
||||||
|
inheritable: true,
|
||||||
|
// helpText: translate(
|
||||||
|
// 'Symbol can be either a unicode character or an URL. You can use feature properties as variables: ex.: with "http://myserver.org/images/{name}.png", the {name} variable will be replaced by the "name" value of each marker.'
|
||||||
|
// ),
|
||||||
|
},
|
||||||
|
smoothFactor: {
|
||||||
|
type: Number,
|
||||||
|
min: 0,
|
||||||
|
max: 10,
|
||||||
|
step: 0.5,
|
||||||
|
label: translate('Simplify'),
|
||||||
|
helpEntries: 'smoothFactor',
|
||||||
|
inheritable: true,
|
||||||
|
default: 1.0,
|
||||||
|
},
|
||||||
|
iconOpacity: {
|
||||||
|
type: Number,
|
||||||
|
min: 0.1,
|
||||||
|
max: 1,
|
||||||
|
step: 0.1,
|
||||||
|
label: translate('icon opacity'),
|
||||||
|
inheritable: true,
|
||||||
|
default: 1,
|
||||||
|
},
|
||||||
|
opacity: {
|
||||||
|
type: Number,
|
||||||
|
min: 0.1,
|
||||||
|
max: 1,
|
||||||
|
step: 0.1,
|
||||||
|
label: translate('opacity'),
|
||||||
|
inheritable: true,
|
||||||
|
default: 0.5,
|
||||||
|
},
|
||||||
|
weight: {
|
||||||
|
type: Number,
|
||||||
|
min: 1,
|
||||||
|
max: 20,
|
||||||
|
step: 1,
|
||||||
|
label: translate('weight'),
|
||||||
|
inheritable: true,
|
||||||
|
default: 3,
|
||||||
|
},
|
||||||
|
fill: {
|
||||||
|
type: Boolean,
|
||||||
|
label: translate('fill'),
|
||||||
|
helpEntries: 'fill',
|
||||||
|
inheritable: true,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
fillColor: {
|
||||||
|
type: String,
|
||||||
|
handler: 'ColorPicker',
|
||||||
|
label: translate('fill color'),
|
||||||
|
helpEntries: 'fillColor',
|
||||||
|
inheritable: true,
|
||||||
|
},
|
||||||
|
fillOpacity: {
|
||||||
|
type: Number,
|
||||||
|
min: 0.1,
|
||||||
|
max: 1,
|
||||||
|
step: 0.1,
|
||||||
|
label: translate('fill opacity'),
|
||||||
|
inheritable: true,
|
||||||
|
default: 0.3,
|
||||||
|
},
|
||||||
|
dashArray: {
|
||||||
|
type: String,
|
||||||
|
label: translate('dash array'),
|
||||||
|
helpEntries: 'dashArray',
|
||||||
|
inheritable: true,
|
||||||
|
},
|
||||||
|
popupShape: {
|
||||||
|
type: String,
|
||||||
|
label: translate('Popup shape'),
|
||||||
|
inheritable: true,
|
||||||
|
choices: [
|
||||||
|
['Default', translate('Popup')],
|
||||||
|
['Large', translate('Popup (large)')],
|
||||||
|
['Panel', translate('Side panel')],
|
||||||
|
],
|
||||||
|
default: 'Default',
|
||||||
|
},
|
||||||
|
popupTemplate: {
|
||||||
|
type: String,
|
||||||
|
label: translate('Popup content style'),
|
||||||
|
inheritable: true,
|
||||||
|
choices: [
|
||||||
|
['Default', translate('Default')],
|
||||||
|
['Table', translate('Table')],
|
||||||
|
['GeoRSSImage', translate('GeoRSS (title + image)')],
|
||||||
|
['GeoRSSLink', translate('GeoRSS (only link)')],
|
||||||
|
['OSM', translate('OpenStreetMap')],
|
||||||
|
],
|
||||||
|
default: 'Default',
|
||||||
|
},
|
||||||
|
popupContentTemplate: {
|
||||||
|
type: 'Text',
|
||||||
|
label: translate('Popup content template'),
|
||||||
|
helpEntries: ['dynamicProperties', 'textFormatting'],
|
||||||
|
placeholder: '# {name}',
|
||||||
|
inheritable: true,
|
||||||
|
default: '# {name}\n{description}',
|
||||||
|
},
|
||||||
|
zoomTo: {
|
||||||
|
type: Number,
|
||||||
|
placeholder: translate('Inherit'),
|
||||||
|
helpEntries: 'zoomTo',
|
||||||
|
label: translate('Default zoom level'),
|
||||||
|
inheritable: true,
|
||||||
|
},
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
sortKey: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
labelKey: {
|
||||||
|
type: String,
|
||||||
|
helpEntries: 'labelKey',
|
||||||
|
placeholder: translate('Default: name'),
|
||||||
|
label: translate('Label key'),
|
||||||
|
inheritable: true,
|
||||||
|
},
|
||||||
|
filterKey: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
facetKey: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
slugKey: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
showLabel: {
|
||||||
|
type: Boolean,
|
||||||
|
nullable: true,
|
||||||
|
label: translate('Display label'),
|
||||||
|
inheritable: true,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
labelDirection: {
|
||||||
|
type: String,
|
||||||
|
label: translate('Label direction'),
|
||||||
|
inheritable: true,
|
||||||
|
choices: [
|
||||||
|
['auto', translate('Automatic')],
|
||||||
|
['left', translate('On the left')],
|
||||||
|
['right', translate('On the right')],
|
||||||
|
['top', translate('On the top')],
|
||||||
|
['bottom', translate('On the bottom')],
|
||||||
|
],
|
||||||
|
default: 'auto',
|
||||||
|
},
|
||||||
|
labelInteractive: {
|
||||||
|
type: Boolean,
|
||||||
|
label: translate('Labels are clickable'),
|
||||||
|
inheritable: true,
|
||||||
|
},
|
||||||
|
outlinkTarget: {
|
||||||
|
type: String,
|
||||||
|
label: translate('Open link in…'),
|
||||||
|
inheritable: true,
|
||||||
|
default: 'blank',
|
||||||
|
choices: [
|
||||||
|
['blank', translate('new window')],
|
||||||
|
['self', translate('iframe')],
|
||||||
|
['parent', translate('parent window')],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
shortCredit: {
|
||||||
|
type: String,
|
||||||
|
label: translate('Short credits'),
|
||||||
|
helpEntries: ['shortCredit', 'textFormatting'],
|
||||||
|
},
|
||||||
|
longCredit: {
|
||||||
|
type: 'Text',
|
||||||
|
label: translate('Long credits'),
|
||||||
|
helpEntries: ['longCredit', 'textFormatting'],
|
||||||
|
},
|
||||||
|
permanentCredit: {
|
||||||
|
type: 'Text',
|
||||||
|
label: translate('Permanent credits'),
|
||||||
|
helpEntries: ['permanentCredit', 'textFormatting'],
|
||||||
|
},
|
||||||
|
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,
|
||||||
|
nullable: true,
|
||||||
|
label: translate('Display the locate control'),
|
||||||
|
},
|
||||||
|
fullscreenControl: {
|
||||||
|
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,
|
||||||
|
nullable: true,
|
||||||
|
label: translate('Display the measure control'),
|
||||||
|
},
|
||||||
|
tilelayersControl: {
|
||||||
|
type: Boolean,
|
||||||
|
nullable: true,
|
||||||
|
label: translate('Display the tile layers control'),
|
||||||
|
},
|
||||||
|
starControl: {
|
||||||
|
type: Boolean,
|
||||||
|
nullable: true,
|
||||||
|
label: translate('Display the star map button'),
|
||||||
|
},
|
||||||
|
easing: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
interactive: {
|
||||||
|
type: Boolean,
|
||||||
|
label: translate('Allow interactions'),
|
||||||
|
helpEntries: 'interactive',
|
||||||
|
inheritable: true,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
fromZoom: {
|
||||||
|
type: Number,
|
||||||
|
label: translate('From zoom'),
|
||||||
|
helpText: translate('Optional.'),
|
||||||
|
},
|
||||||
|
toZoom: {
|
||||||
|
type: Number,
|
||||||
|
label: translate('To zoom'),
|
||||||
|
helpText: translate('Optional.'),
|
||||||
|
},
|
||||||
|
stroke: {
|
||||||
|
type: Boolean,
|
||||||
|
label: translate('stroke'),
|
||||||
|
helpEntries: 'stroke',
|
||||||
|
inheritable: true,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
outlink: {
|
||||||
|
label: translate('Link to…'),
|
||||||
|
helpEntries: 'outlink',
|
||||||
|
placeholder: 'http://...',
|
||||||
|
inheritable: true,
|
||||||
|
},
|
||||||
|
}
|
|
@ -1184,25 +1184,22 @@ U.AttributionControl = L.Control.Attribution.extend({
|
||||||
this._container,
|
this._container,
|
||||||
credits
|
credits
|
||||||
)
|
)
|
||||||
if (this._map.options.shortCredit) {
|
const shortCredit = this._map.getOption('shortCredit'),
|
||||||
L.DomUtil.add(
|
captionMenus = this._map.getOption('captionMenus')
|
||||||
'span',
|
if (shortCredit) {
|
||||||
'',
|
L.DomUtil.add('span', '', container, ` — ${L.Util.toHTML(shortCredit)}`)
|
||||||
container,
|
|
||||||
` — ${L.Util.toHTML(this._map.options.shortCredit)}`
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
if (this._map.options.captionMenus) {
|
if (captionMenus) {
|
||||||
const link = L.DomUtil.add('a', '', container, ` — ${L._('About')}`)
|
const link = L.DomUtil.add('a', '', container, ` — ${L._('About')}`)
|
||||||
L.DomEvent.on(link, 'click', L.DomEvent.stop)
|
L.DomEvent.on(link, 'click', L.DomEvent.stop)
|
||||||
.on(link, 'click', this._map.displayCaption, this._map)
|
.on(link, 'click', this._map.displayCaption, this._map)
|
||||||
.on(link, 'dblclick', L.DomEvent.stop)
|
.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
|
// We are not in iframe mode
|
||||||
L.DomUtil.createLink('', container, ` — ${L._('Home')}`, '/')
|
L.DomUtil.createLink('', container, ` — ${L._('Home')}`, '/')
|
||||||
}
|
}
|
||||||
if (this._map.options.captionMenus) {
|
if (captionMenus) {
|
||||||
L.DomUtil.createLink(
|
L.DomUtil.createLink(
|
||||||
'',
|
'',
|
||||||
container,
|
container,
|
||||||
|
|
|
@ -415,7 +415,10 @@ L.DomUtil.TextColorFromBackgroundColor = (el, bgcolor) => {
|
||||||
L.DomUtil.contrastWCAG21 = (rgb) => {
|
L.DomUtil.contrastWCAG21 = (rgb) => {
|
||||||
const [r, g, b] = rgb
|
const [r, g, b] = rgb
|
||||||
// luminance of inputted colour
|
// luminance of inputted colour
|
||||||
const lum = 0.2126 * L.DomUtil.colourMod(r) + 0.7152 * L.DomUtil.colourMod(g) + 0.0722 * L.DomUtil.colourMod(b)
|
const lum =
|
||||||
|
0.2126 * L.DomUtil.colourMod(r) +
|
||||||
|
0.7152 * L.DomUtil.colourMod(g) +
|
||||||
|
0.0722 * L.DomUtil.colourMod(b)
|
||||||
// white has a luminance of 1
|
// white has a luminance of 1
|
||||||
const whiteLum = 1
|
const whiteLum = 1
|
||||||
const contrast = (whiteLum + 0.05) / (lum + 0.05)
|
const contrast = (whiteLum + 0.05) / (lum + 0.05)
|
||||||
|
@ -729,9 +732,6 @@ U.Help = L.Class.extend({
|
||||||
formatURL: `${L._(
|
formatURL: `${L._(
|
||||||
'Supported variables that will be dynamically replaced'
|
'Supported variables that will be dynamically replaced'
|
||||||
)}: {bbox}, {lat}, {lng}, {zoom}, {east}, {north}..., {left}, {top}..., locale, lang`,
|
)}: {bbox}, {lat}, {lng}, {zoom}, {east}, {north}..., {left}, {top}..., locale, lang`,
|
||||||
formatIconSymbol: L._(
|
|
||||||
'Symbol can be either a unicode character or an URL. You can use feature properties as variables: ex.: with "http://myserver.org/images/{name}.png", the {name} variable will be replaced by the "name" value of each marker.'
|
|
||||||
),
|
|
||||||
colorValue: L._('Must be a valid CSS value (eg.: DarkBlue or #123456)'),
|
colorValue: L._('Must be a valid CSS value (eg.: DarkBlue or #123456)'),
|
||||||
smoothFactor: L._(
|
smoothFactor: L._(
|
||||||
'How much to simplify the polyline on each zoom level (more = better performance and smoother look, less = more accurate)'
|
'How much to simplify the polyline on each zoom level (more = better performance and smoother look, less = more accurate)'
|
||||||
|
@ -741,7 +741,7 @@ U.Help = L.Class.extend({
|
||||||
),
|
),
|
||||||
zoomTo: L._('Zoom level for automatic zooms'),
|
zoomTo: L._('Zoom level for automatic zooms'),
|
||||||
labelKey: L._(
|
labelKey: L._(
|
||||||
'The name of the property to use as feature label (eg.: "nom"). You can also use properties inside brackets to use more than one or mix with static content (eg.: "{name} in {place}")'
|
'The name of the property to use as feature label (eg.: "nom"). You can also use properties inside brackets to use more than one or mix with static content (eg.: "{name} in {place}")'
|
||||||
),
|
),
|
||||||
stroke: L._('Whether to display or not polygons paths.'),
|
stroke: L._('Whether to display or not polygons paths.'),
|
||||||
fill: L._('Whether to fill polygons with color.'),
|
fill: L._('Whether to fill polygons with color.'),
|
||||||
|
|
|
@ -53,7 +53,7 @@ U.FeatureMixin = {
|
||||||
},
|
},
|
||||||
|
|
||||||
getSlug: function () {
|
getSlug: function () {
|
||||||
return this.properties[this.map.options.slugKey || 'name'] || ''
|
return this.properties[this.map.getOption('slugKey') || 'name'] || ''
|
||||||
},
|
},
|
||||||
|
|
||||||
getPermalink: function () {
|
getPermalink: function () {
|
||||||
|
@ -103,11 +103,15 @@ U.FeatureMixin = {
|
||||||
L._('Feature properties')
|
L._('Feature properties')
|
||||||
)
|
)
|
||||||
|
|
||||||
let builder = new U.FormBuilder(this, ['datalayer'], {
|
let builder = new U.FormBuilder(
|
||||||
callback: function () {
|
this,
|
||||||
this.edit(e)
|
[['datalayer', { handler: 'DataLayerSwitcher' }]],
|
||||||
}, // removeLayer step will close the edit panel, let's reopen it
|
{
|
||||||
})
|
callback: function () {
|
||||||
|
this.edit(e)
|
||||||
|
}, // removeLayer step will close the edit panel, let's reopen it
|
||||||
|
}
|
||||||
|
)
|
||||||
container.appendChild(builder.build())
|
container.appendChild(builder.build())
|
||||||
|
|
||||||
const properties = []
|
const properties = []
|
||||||
|
@ -209,7 +213,7 @@ U.FeatureMixin = {
|
||||||
if (L.Browser.ielt9) return false
|
if (L.Browser.ielt9) return false
|
||||||
if (this.datalayer.isRemoteLayer() && this.datalayer.options.remoteData.dynamic)
|
if (this.datalayer.isRemoteLayer() && this.datalayer.options.remoteData.dynamic)
|
||||||
return false
|
return false
|
||||||
return this.map.options.displayPopupFooter
|
return this.map.getOption('displayPopupFooter')
|
||||||
},
|
},
|
||||||
|
|
||||||
getPopupClass: function () {
|
getPopupClass: function () {
|
||||||
|
@ -309,7 +313,7 @@ U.FeatureMixin = {
|
||||||
|
|
||||||
zoomTo: function (e) {
|
zoomTo: function (e) {
|
||||||
e = 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) {
|
if (easing) {
|
||||||
this.map.flyTo(this.getCenter(), this.getBestZoom())
|
this.map.flyTo(this.getCenter(), this.getBestZoom())
|
||||||
} else {
|
} else {
|
||||||
|
@ -975,7 +979,7 @@ U.PathMixin = {
|
||||||
zoomTo: function (e) {
|
zoomTo: function (e) {
|
||||||
// Use bounds instead of centroid for paths.
|
// Use bounds instead of centroid for paths.
|
||||||
e = 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) {
|
if (easing) {
|
||||||
this.map.flyToBounds(this.getBounds(), this.getBestZoom())
|
this.map.flyToBounds(this.getBounds(), this.getBestZoom())
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -340,15 +340,6 @@ L.FormBuilder.TextColorPicker = L.FormBuilder.ColorPicker.extend({
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
L.FormBuilder.IconClassSwitcher = L.FormBuilder.Select.extend({
|
|
||||||
selectOptions: [
|
|
||||||
['Default', L._('Default')],
|
|
||||||
['Circle', L._('Circle')],
|
|
||||||
['Drop', L._('Drop')],
|
|
||||||
['Ball', L._('Ball')],
|
|
||||||
],
|
|
||||||
})
|
|
||||||
|
|
||||||
L.FormBuilder.ProxyTTLSelect = L.FormBuilder.Select.extend({
|
L.FormBuilder.ProxyTTLSelect = L.FormBuilder.Select.extend({
|
||||||
selectOptions: [
|
selectOptions: [
|
||||||
[undefined, L._('No cache')],
|
[undefined, L._('No cache')],
|
||||||
|
@ -358,24 +349,6 @@ L.FormBuilder.ProxyTTLSelect = L.FormBuilder.Select.extend({
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
L.FormBuilder.PopupShape = L.FormBuilder.Select.extend({
|
|
||||||
selectOptions: [
|
|
||||||
['Default', L._('Popup')],
|
|
||||||
['Large', L._('Popup (large)')],
|
|
||||||
['Panel', L._('Side panel')],
|
|
||||||
],
|
|
||||||
})
|
|
||||||
|
|
||||||
L.FormBuilder.PopupContent = L.FormBuilder.Select.extend({
|
|
||||||
selectOptions: [
|
|
||||||
['Default', L._('Default')],
|
|
||||||
['Table', L._('Table')],
|
|
||||||
['GeoRSSImage', L._('GeoRSS (title + image)')],
|
|
||||||
['GeoRSSLink', L._('GeoRSS (only link)')],
|
|
||||||
['OSM', L._('OpenStreetMap')],
|
|
||||||
],
|
|
||||||
})
|
|
||||||
|
|
||||||
L.FormBuilder.LayerTypeChooser = L.FormBuilder.Select.extend({
|
L.FormBuilder.LayerTypeChooser = L.FormBuilder.Select.extend({
|
||||||
getOptions: function () {
|
getOptions: function () {
|
||||||
const layer_classes = [
|
const layer_classes = [
|
||||||
|
@ -427,24 +400,6 @@ L.FormBuilder.DataLayerSwitcher = L.FormBuilder.Select.extend({
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
L.FormBuilder.DefaultView = L.FormBuilder.Select.extend({
|
|
||||||
selectOptions: [
|
|
||||||
['center', L._('Saved center and zoom')],
|
|
||||||
['data', L._('Fit all data')],
|
|
||||||
['latest', L._('Latest feature')],
|
|
||||||
['locate', L._('User location')],
|
|
||||||
],
|
|
||||||
})
|
|
||||||
|
|
||||||
L.FormBuilder.OnLoadPanel = L.FormBuilder.Select.extend({
|
|
||||||
selectOptions: [
|
|
||||||
['none', L._('None')],
|
|
||||||
['caption', L._('Caption')],
|
|
||||||
['databrowser', L._('Data browser')],
|
|
||||||
['facet', L._('Facet search')],
|
|
||||||
],
|
|
||||||
})
|
|
||||||
|
|
||||||
L.FormBuilder.DataFormat = L.FormBuilder.Select.extend({
|
L.FormBuilder.DataFormat = L.FormBuilder.Select.extend({
|
||||||
selectOptions: [
|
selectOptions: [
|
||||||
[undefined, L._('Choose the data format')],
|
[undefined, L._('Choose the data format')],
|
||||||
|
@ -457,16 +412,6 @@ L.FormBuilder.DataFormat = L.FormBuilder.Select.extend({
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
L.FormBuilder.LabelDirection = L.FormBuilder.Select.extend({
|
|
||||||
selectOptions: [
|
|
||||||
['auto', L._('Automatic')],
|
|
||||||
['left', L._('On the left')],
|
|
||||||
['right', L._('On the right')],
|
|
||||||
['top', L._('On the top')],
|
|
||||||
['bottom', L._('On the bottom')],
|
|
||||||
],
|
|
||||||
})
|
|
||||||
|
|
||||||
L.FormBuilder.LicenceChooser = L.FormBuilder.Select.extend({
|
L.FormBuilder.LicenceChooser = L.FormBuilder.Select.extend({
|
||||||
getOptions: function () {
|
getOptions: function () {
|
||||||
const licences = []
|
const licences = []
|
||||||
|
@ -708,7 +653,7 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
isDefault: function () {
|
isDefault: function () {
|
||||||
return !this.value() || this.value() === U.DEFAULT_ICON_URL
|
return !this.value() || this.value() === U.SCHEMA.iconUrl.default
|
||||||
},
|
},
|
||||||
|
|
||||||
addGrid: function (onSearch) {
|
addGrid: function (onSearch) {
|
||||||
|
@ -905,7 +850,7 @@ L.FormBuilder.TernaryChoices = L.FormBuilder.MultiChoice.extend({
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
L.FormBuilder.ControlChoice = L.FormBuilder.TernaryChoices.extend({
|
L.FormBuilder.NullableChoices = L.FormBuilder.TernaryChoices.extend({
|
||||||
choices: [
|
choices: [
|
||||||
[true, L._('always')],
|
[true, L._('always')],
|
||||||
[false, L._('never')],
|
[false, L._('never')],
|
||||||
|
@ -913,17 +858,7 @@ L.FormBuilder.ControlChoice = L.FormBuilder.TernaryChoices.extend({
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
L.FormBuilder.LabelChoice = L.FormBuilder.TernaryChoices.extend({
|
L.FormBuilder.DataLayersControl = L.FormBuilder.TernaryChoices.extend({
|
||||||
default: false,
|
|
||||||
|
|
||||||
choices: [
|
|
||||||
[true, L._('always')],
|
|
||||||
[false, L._('never')],
|
|
||||||
['null', L._('on hover')],
|
|
||||||
],
|
|
||||||
})
|
|
||||||
|
|
||||||
L.FormBuilder.DataLayersControl = L.FormBuilder.ControlChoice.extend({
|
|
||||||
choices: [
|
choices: [
|
||||||
[true, L._('collapsed')],
|
[true, L._('collapsed')],
|
||||||
['expanded', L._('expanded')],
|
['expanded', L._('expanded')],
|
||||||
|
@ -934,21 +869,11 @@ L.FormBuilder.DataLayersControl = L.FormBuilder.ControlChoice.extend({
|
||||||
toJS: function () {
|
toJS: function () {
|
||||||
let value = this.value()
|
let value = this.value()
|
||||||
if (value !== 'expanded')
|
if (value !== 'expanded')
|
||||||
value = L.FormBuilder.ControlChoice.prototype.toJS.call(this)
|
value = L.FormBuilder.TernaryChoices.prototype.toJS.call(this)
|
||||||
return value
|
return value
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
L.FormBuilder.OutlinkTarget = L.FormBuilder.MultiChoice.extend({
|
|
||||||
default: 'blank',
|
|
||||||
|
|
||||||
choices: [
|
|
||||||
['blank', L._('new window')],
|
|
||||||
['self', L._('iframe')],
|
|
||||||
['parent', L._('parent window')],
|
|
||||||
],
|
|
||||||
})
|
|
||||||
|
|
||||||
L.FormBuilder.Range = L.FormBuilder.FloatInput.extend({
|
L.FormBuilder.Range = L.FormBuilder.FloatInput.extend({
|
||||||
type: function () {
|
type: function () {
|
||||||
return 'range'
|
return 'range'
|
||||||
|
@ -1052,230 +977,55 @@ U.FormBuilder = L.FormBuilder.extend({
|
||||||
className: 'umap-form',
|
className: 'umap-form',
|
||||||
},
|
},
|
||||||
|
|
||||||
defaultOptions: {
|
computeDefaultOptions: function () {
|
||||||
name: { label: L._('name') },
|
for (let [key, schema] of Object.entries(U.SCHEMA)) {
|
||||||
description: {
|
if (schema.type === Boolean) {
|
||||||
label: L._('description'),
|
if (schema.nullable) schema.handler = 'NullableChoices'
|
||||||
handler: 'Textarea',
|
else schema.handler = 'Switch'
|
||||||
helpEntries: 'textFormatting',
|
} else if (schema.type === 'Text') {
|
||||||
},
|
schema.handler = 'Textarea'
|
||||||
color: {
|
} else if (schema.type === Number) {
|
||||||
handler: 'ColorPicker',
|
if (schema.step) schema.handler = 'Range'
|
||||||
label: L._('color'),
|
else schema.handler = 'IntInput'
|
||||||
helpEntries: 'colorValue',
|
} else if (schema.choices) {
|
||||||
inheritable: true,
|
const text_length = schema.choices.reduce(
|
||||||
},
|
(acc, [value, label]) => acc + label.length,
|
||||||
iconOpacity: {
|
0
|
||||||
handler: 'Range',
|
)
|
||||||
min: 0.1,
|
// Try to be smart and use MultiChoice only
|
||||||
max: 1,
|
// for choices where labels are shorts…
|
||||||
step: 0.1,
|
if (text_length < 40) {
|
||||||
label: L._('icon opacity'),
|
schema.handler = 'MultiChoice'
|
||||||
inheritable: true,
|
} else {
|
||||||
},
|
schema.handler = 'Select'
|
||||||
opacity: {
|
schema.selectOptions = schema.choices
|
||||||
handler: 'Range',
|
}
|
||||||
min: 0.1,
|
} else {
|
||||||
max: 1,
|
switch (key) {
|
||||||
step: 0.1,
|
case 'color':
|
||||||
label: L._('opacity'),
|
case 'fillColor':
|
||||||
inheritable: true,
|
schema.handler = 'ColorPicker'
|
||||||
},
|
break
|
||||||
stroke: {
|
case 'iconUrl':
|
||||||
handler: 'Switch',
|
schema.handler = 'IconUrl'
|
||||||
label: L._('stroke'),
|
break
|
||||||
helpEntries: 'stroke',
|
case 'datalayersControl':
|
||||||
inheritable: true,
|
schema.handler = 'DataLayersControl'
|
||||||
},
|
break
|
||||||
weight: {
|
case 'licence':
|
||||||
handler: 'Range',
|
schema.handler = 'LicenceChooser'
|
||||||
min: 1,
|
break
|
||||||
max: 20,
|
}
|
||||||
step: 1,
|
}
|
||||||
label: L._('weight'),
|
// FormBuilder use this key for the input type itself
|
||||||
inheritable: true,
|
delete schema.type
|
||||||
},
|
this.defaultOptions[key] = schema
|
||||||
fill: {
|
}
|
||||||
handler: 'Switch',
|
|
||||||
label: L._('fill'),
|
|
||||||
helpEntries: 'fill',
|
|
||||||
inheritable: true,
|
|
||||||
},
|
|
||||||
fillColor: {
|
|
||||||
handler: 'ColorPicker',
|
|
||||||
label: L._('fill color'),
|
|
||||||
helpEntries: 'fillColor',
|
|
||||||
inheritable: true,
|
|
||||||
},
|
|
||||||
fillOpacity: {
|
|
||||||
handler: 'Range',
|
|
||||||
min: 0.1,
|
|
||||||
max: 1,
|
|
||||||
step: 0.1,
|
|
||||||
label: L._('fill opacity'),
|
|
||||||
inheritable: true,
|
|
||||||
},
|
|
||||||
smoothFactor: {
|
|
||||||
handler: 'Range',
|
|
||||||
min: 0,
|
|
||||||
max: 10,
|
|
||||||
step: 0.5,
|
|
||||||
label: L._('Simplify'),
|
|
||||||
helpEntries: 'smoothFactor',
|
|
||||||
inheritable: true,
|
|
||||||
},
|
|
||||||
dashArray: {
|
|
||||||
label: L._('dash array'),
|
|
||||||
helpEntries: 'dashArray',
|
|
||||||
inheritable: true,
|
|
||||||
},
|
|
||||||
iconClass: {
|
|
||||||
handler: 'IconClassSwitcher',
|
|
||||||
label: L._('Icon shape'),
|
|
||||||
inheritable: true,
|
|
||||||
},
|
|
||||||
iconUrl: {
|
|
||||||
handler: 'IconUrl',
|
|
||||||
label: L._('Icon symbol'),
|
|
||||||
inheritable: true,
|
|
||||||
helpText: U.Help.formatIconSymbol,
|
|
||||||
},
|
|
||||||
popupShape: { handler: 'PopupShape', label: L._('Popup shape'), inheritable: true },
|
|
||||||
popupTemplate: {
|
|
||||||
handler: 'PopupContent',
|
|
||||||
label: L._('Popup content style'),
|
|
||||||
inheritable: true,
|
|
||||||
},
|
|
||||||
popupContentTemplate: {
|
|
||||||
label: L._('Popup content template'),
|
|
||||||
handler: 'Textarea',
|
|
||||||
helpEntries: ['dynamicProperties', 'textFormatting'],
|
|
||||||
placeholder: '# {name}',
|
|
||||||
inheritable: true,
|
|
||||||
},
|
|
||||||
datalayer: {
|
|
||||||
handler: 'DataLayerSwitcher',
|
|
||||||
label: L._('Choose the layer of the feature'),
|
|
||||||
},
|
|
||||||
moreControl: {
|
|
||||||
handler: 'Switch',
|
|
||||||
label: L._('Do you want to display the «more» control?'),
|
|
||||||
},
|
|
||||||
scrollWheelZoom: { handler: 'Switch', label: L._('Allow scroll wheel zoom?') },
|
|
||||||
miniMap: { handler: 'Switch', label: L._('Do you want to display a minimap?') },
|
|
||||||
scaleControl: {
|
|
||||||
handler: 'Switch',
|
|
||||||
label: L._('Do you want to display the scale control?'),
|
|
||||||
},
|
|
||||||
onLoadPanel: {
|
|
||||||
handler: 'OnLoadPanel',
|
|
||||||
label: L._('Do you want to display a panel on load?'),
|
|
||||||
},
|
|
||||||
defaultView: {
|
|
||||||
handler: 'DefaultView',
|
|
||||||
label: L._('Default view'),
|
|
||||||
},
|
|
||||||
displayPopupFooter: {
|
|
||||||
handler: 'Switch',
|
|
||||||
label: L._('Do you want to display popup footer?'),
|
|
||||||
},
|
|
||||||
captionBar: {
|
|
||||||
handler: 'Switch',
|
|
||||||
label: L._('Do you want to display a caption bar?'),
|
|
||||||
},
|
|
||||||
captionMenus: {
|
|
||||||
handler: 'Switch',
|
|
||||||
label: L._('Do you want to display caption menus?'),
|
|
||||||
},
|
|
||||||
zoomTo: {
|
|
||||||
handler: 'IntInput',
|
|
||||||
placeholder: L._('Inherit'),
|
|
||||||
helpEntries: 'zoomTo',
|
|
||||||
label: L._('Default zoom level'),
|
|
||||||
inheritable: true,
|
|
||||||
},
|
|
||||||
showLabel: {
|
|
||||||
handler: 'LabelChoice',
|
|
||||||
label: L._('Display label'),
|
|
||||||
inheritable: true,
|
|
||||||
},
|
|
||||||
labelDirection: {
|
|
||||||
handler: 'LabelDirection',
|
|
||||||
label: L._('Label direction'),
|
|
||||||
inheritable: true,
|
|
||||||
},
|
|
||||||
labelInteractive: {
|
|
||||||
handler: 'Switch',
|
|
||||||
label: L._('Labels are clickable'),
|
|
||||||
inheritable: true,
|
|
||||||
},
|
|
||||||
outlink: {
|
|
||||||
label: L._('Link to…'),
|
|
||||||
helpEntries: 'outlink',
|
|
||||||
placeholder: 'http://...',
|
|
||||||
inheritable: true,
|
|
||||||
},
|
|
||||||
outlinkTarget: {
|
|
||||||
handler: 'OutlinkTarget',
|
|
||||||
label: L._('Open link in…'),
|
|
||||||
inheritable: true,
|
|
||||||
},
|
|
||||||
labelKey: {
|
|
||||||
helpEntries: 'labelKey',
|
|
||||||
placeholder: L._('Default: name'),
|
|
||||||
label: L._('Label key'),
|
|
||||||
inheritable: true,
|
|
||||||
},
|
|
||||||
zoomControl: { handler: 'ControlChoice', label: L._('Display the zoom control') },
|
|
||||||
searchControl: {
|
|
||||||
handler: 'ControlChoice',
|
|
||||||
label: L._('Display the search control'),
|
|
||||||
},
|
|
||||||
fullscreenControl: {
|
|
||||||
handler: 'ControlChoice',
|
|
||||||
label: L._('Display the fullscreen control'),
|
|
||||||
},
|
|
||||||
embedControl: { handler: 'ControlChoice', label: L._('Display the embed control') },
|
|
||||||
locateControl: {
|
|
||||||
handler: 'ControlChoice',
|
|
||||||
label: L._('Display the locate control'),
|
|
||||||
},
|
|
||||||
measureControl: {
|
|
||||||
handler: 'ControlChoice',
|
|
||||||
label: L._('Display the measure control'),
|
|
||||||
},
|
|
||||||
tilelayersControl: {
|
|
||||||
handler: 'ControlChoice',
|
|
||||||
label: L._('Display the tile layers control'),
|
|
||||||
},
|
|
||||||
editinosmControl: {
|
|
||||||
handler: 'ControlChoice',
|
|
||||||
label: L._('Display the control to open OpenStreetMap editor'),
|
|
||||||
},
|
|
||||||
datalayersControl: {
|
|
||||||
handler: 'DataLayersControl',
|
|
||||||
label: L._('Display the data layers control'),
|
|
||||||
},
|
|
||||||
starControl: {
|
|
||||||
handler: 'ControlChoice',
|
|
||||||
label: L._('Display the star map button'),
|
|
||||||
},
|
|
||||||
fromZoom: {
|
|
||||||
handler: 'IntInput',
|
|
||||||
label: L._('From zoom'),
|
|
||||||
helpText: L._('Optional.'),
|
|
||||||
},
|
|
||||||
toZoom: { handler: 'IntInput', label: L._('To zoom'), helpText: L._('Optional.') },
|
|
||||||
interactive: {
|
|
||||||
handler: 'Switch',
|
|
||||||
label: L._('Allow interactions'),
|
|
||||||
helpEntries: 'interactive',
|
|
||||||
inheritable: true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize: function (obj, fields, options) {
|
initialize: function (obj, fields, options) {
|
||||||
this.map = obj.map || obj.getMap()
|
this.map = obj.map || obj.getMap()
|
||||||
|
this.computeDefaultOptions()
|
||||||
L.FormBuilder.prototype.initialize.call(this, obj, fields, options)
|
L.FormBuilder.prototype.initialize.call(this, obj, fields, options)
|
||||||
this.on('finish', this.finish)
|
this.on('finish', this.finish)
|
||||||
},
|
},
|
||||||
|
|
|
@ -19,7 +19,7 @@ U.Icon = L.DivIcon.extend({
|
||||||
|
|
||||||
_setRecent: function (url) {
|
_setRecent: function (url) {
|
||||||
if (L.Util.hasVar(url)) return
|
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) {
|
if (U.Icon.RECENT.indexOf(url) === -1) {
|
||||||
U.Icon.RECENT.push(url)
|
U.Icon.RECENT.push(url)
|
||||||
}
|
}
|
||||||
|
@ -236,7 +236,7 @@ U.Icon.setIconContrast = function (icon, parent, src, bgcolor) {
|
||||||
if (L.DomUtil.contrastedColor(parent, bgcolor)) {
|
if (L.DomUtil.contrastedColor(parent, bgcolor)) {
|
||||||
// Decide whether to switch svg to white or not, but do it
|
// Decide whether to switch svg to white or not, but do it
|
||||||
// only for internal SVG, as invert could do weird things
|
// 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
|
// Must be called after icon container is added to the DOM
|
||||||
// An image
|
// An image
|
||||||
icon.style.filter = 'invert(1)'
|
icon.style.filter = 'invert(1)'
|
||||||
|
|
|
@ -2,33 +2,12 @@ L.Map.mergeOptions({
|
||||||
overlay: null,
|
overlay: null,
|
||||||
datalayers: [],
|
datalayers: [],
|
||||||
hash: true,
|
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,
|
maxZoomLimit: 24,
|
||||||
attributionControl: false,
|
attributionControl: false,
|
||||||
editMode: 'advanced',
|
editMode: 'advanced',
|
||||||
embedControl: true,
|
|
||||||
zoomControl: true,
|
|
||||||
datalayersControl: true,
|
|
||||||
searchControl: true,
|
|
||||||
editInOSMControl: false,
|
|
||||||
editInOSMControlOptions: false,
|
|
||||||
scaleControl: true,
|
|
||||||
noControl: false, // Do not render any control.
|
noControl: false, // Do not render any control.
|
||||||
miniMap: false,
|
|
||||||
name: '',
|
name: '',
|
||||||
description: '',
|
description: '',
|
||||||
displayPopupFooter: false,
|
|
||||||
// When a TileLayer is in TMS mode, it needs -y instead of y.
|
// When a TileLayer is in TMS mode, it needs -y instead of y.
|
||||||
// This is usually handled by the TileLayer instance itself, but
|
// This is usually handled by the TileLayer instance itself, but
|
||||||
// we cannot rely on this because of the y is overriden by Leaflet
|
// we cannot rely on this because of the y is overriden by Leaflet
|
||||||
|
@ -44,77 +23,14 @@ L.Map.mergeOptions({
|
||||||
importPresets: [
|
importPresets: [
|
||||||
// {url: 'http://localhost:8019/en/datalayer/1502/', label: 'Simplified World Countries', format: 'geojson'}
|
// {url: 'http://localhost:8019/en/datalayer/1502/', label: 'Simplified World Countries', format: 'geojson'}
|
||||||
],
|
],
|
||||||
moreControl: true,
|
|
||||||
captionBar: false,
|
|
||||||
captionMenus: true,
|
|
||||||
slideshow: {},
|
slideshow: {},
|
||||||
clickable: true,
|
clickable: true,
|
||||||
easing: false,
|
|
||||||
permissions: {},
|
permissions: {},
|
||||||
permanentCreditBackground: true,
|
|
||||||
featuresHaveOwner: false,
|
featuresHaveOwner: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
U.Map = L.Map.extend({
|
U.Map = L.Map.extend({
|
||||||
includes: [ControlsMixin],
|
includes: [ControlsMixin],
|
||||||
editableOptions: {
|
|
||||||
zoom: undefined,
|
|
||||||
scrollWheelZoom: Boolean,
|
|
||||||
scaleControl: Boolean,
|
|
||||||
moreControl: Boolean,
|
|
||||||
miniMap: Boolean,
|
|
||||||
displayPopupFooter: undefined,
|
|
||||||
onLoadPanel: String,
|
|
||||||
defaultView: String,
|
|
||||||
name: String,
|
|
||||||
description: String,
|
|
||||||
licence: undefined,
|
|
||||||
tilelayer: undefined,
|
|
||||||
overlay: undefined,
|
|
||||||
limitBounds: undefined,
|
|
||||||
color: String,
|
|
||||||
iconClass: String,
|
|
||||||
iconUrl: String,
|
|
||||||
smoothFactor: undefined,
|
|
||||||
iconOpacity: undefined,
|
|
||||||
opacity: undefined,
|
|
||||||
weight: undefined,
|
|
||||||
fill: undefined,
|
|
||||||
fillColor: undefined,
|
|
||||||
fillOpacity: undefined,
|
|
||||||
dashArray: undefined,
|
|
||||||
popupShape: String,
|
|
||||||
popupTemplate: String,
|
|
||||||
popupContentTemplate: String,
|
|
||||||
zoomTo: Number,
|
|
||||||
captionBar: Boolean,
|
|
||||||
captionMenus: Boolean,
|
|
||||||
slideshow: undefined,
|
|
||||||
sortKey: undefined,
|
|
||||||
labelKey: String,
|
|
||||||
filterKey: undefined,
|
|
||||||
facetKey: undefined,
|
|
||||||
slugKey: undefined,
|
|
||||||
showLabel: 'NullableBoolean',
|
|
||||||
labelDirection: undefined,
|
|
||||||
labelInteractive: undefined,
|
|
||||||
outlinkTarget: undefined,
|
|
||||||
shortCredit: undefined,
|
|
||||||
longCredit: undefined,
|
|
||||||
permanentCredit: undefined,
|
|
||||||
permanentCreditBackground: undefined,
|
|
||||||
zoomControl: 'NullableBoolean',
|
|
||||||
datalayersControl: 'NullableBoolean',
|
|
||||||
searchControl: 'NullableBoolean',
|
|
||||||
locateControl: 'NullableBoolean',
|
|
||||||
fullscreenControl: 'NullableBoolean',
|
|
||||||
editinosmControl: 'NullableBoolean',
|
|
||||||
embedControl: 'NullableBoolean',
|
|
||||||
measureControl: 'NullableBoolean',
|
|
||||||
tilelayersControl: 'NullableBoolean',
|
|
||||||
starControl: 'NullableBoolean',
|
|
||||||
easing: undefined,
|
|
||||||
},
|
|
||||||
|
|
||||||
initialize: function (el, geojson) {
|
initialize: function (el, geojson) {
|
||||||
// Locale name (pt_PT, en_US…)
|
// Locale name (pt_PT, en_US…)
|
||||||
|
@ -133,7 +49,8 @@ U.Map = L.Map.extend({
|
||||||
geojson.properties.fullscreenControl = false
|
geojson.properties.fullscreenControl = false
|
||||||
|
|
||||||
L.Map.prototype.initialize.call(this, el, geojson.properties)
|
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
|
// After calling parent initialize, as we are doing initCenter our-selves
|
||||||
if (geojson.geometry) this.options.center = this.latLng(geojson.geometry)
|
if (geojson.geometry) this.options.center = this.latLng(geojson.geometry)
|
||||||
|
@ -329,13 +246,11 @@ U.Map = L.Map.extend({
|
||||||
// FIXME retrocompat
|
// FIXME retrocompat
|
||||||
L.Util.setBooleanFromQueryString(options, 'displayDataBrowserOnLoad')
|
L.Util.setBooleanFromQueryString(options, 'displayDataBrowserOnLoad')
|
||||||
L.Util.setBooleanFromQueryString(options, 'displayCaptionOnLoad')
|
L.Util.setBooleanFromQueryString(options, 'displayCaptionOnLoad')
|
||||||
for (const [key, type] of Object.entries(this.editableOptions)) {
|
for (const [key, schema] of Object.entries(U.SCHEMA)) {
|
||||||
switch (type) {
|
switch (schema.type) {
|
||||||
case Boolean:
|
case Boolean:
|
||||||
L.Util.setBooleanFromQueryString(options, key)
|
if (schema.nullable) L.Util.setNullableBooleanFromQueryString(options, key)
|
||||||
break
|
else L.Util.setBooleanFromQueryString(options, key)
|
||||||
case 'NullableBoolean':
|
|
||||||
L.Util.setNullableBooleanFromQueryString(options, key)
|
|
||||||
break
|
break
|
||||||
case Number:
|
case Number:
|
||||||
L.Util.setNumberFromQueryString(options, key)
|
L.Util.setNumberFromQueryString(options, key)
|
||||||
|
@ -352,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 () {
|
initControls: function () {
|
||||||
this.helpMenuActions = {}
|
this.helpMenuActions = {}
|
||||||
this._controls = {}
|
this._controls = {}
|
||||||
|
@ -393,7 +314,7 @@ U.Map = L.Map.extend({
|
||||||
title: { false: L._('View Fullscreen'), true: L._('Exit Fullscreen') },
|
title: { false: L._('View Fullscreen'), true: L._('Exit Fullscreen') },
|
||||||
})
|
})
|
||||||
this._controls.search = new U.SearchControl()
|
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)
|
this._controls.tilelayersChooser = new U.TileLayerChooser(this)
|
||||||
if (this.options.user) this._controls.star = new U.StarControl(this)
|
if (this.options.user) this._controls.star = new U.StarControl(this)
|
||||||
this._controls.editinosm = new L.Control.EditInOSM({
|
this._controls.editinosm = new L.Control.EditInOSM({
|
||||||
|
@ -459,7 +380,7 @@ U.Map = L.Map.extend({
|
||||||
let name, status, control
|
let name, status, control
|
||||||
for (let i = 0; i < this.HIDDABLE_CONTROLS.length; i++) {
|
for (let i = 0; i < this.HIDDABLE_CONTROLS.length; i++) {
|
||||||
name = this.HIDDABLE_CONTROLS[i]
|
name = this.HIDDABLE_CONTROLS[i]
|
||||||
status = this.options[`${name}Control`]
|
status = this.getOption(`${name}Control`)
|
||||||
if (status === false) continue
|
if (status === false) continue
|
||||||
control = this._controls[name]
|
control = this._controls[name]
|
||||||
if (!control) continue
|
if (!control) continue
|
||||||
|
@ -468,9 +389,9 @@ U.Map = L.Map.extend({
|
||||||
L.DomUtil.addClass(control._container, 'display-on-more')
|
L.DomUtil.addClass(control._container, 'display-on-more')
|
||||||
else L.DomUtil.removeClass(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.getOption('permanentCredit')) this._controls.permanentCredit.addTo(this)
|
||||||
if (this.options.moreControl) this._controls.more.addTo(this)
|
if (this.getOption('moreControl')) this._controls.more.addTo(this)
|
||||||
if (this.options.scaleControl) this._controls.scale.addTo(this)
|
if (this.getOption('scaleControl')) this._controls.scale.addTo(this)
|
||||||
},
|
},
|
||||||
|
|
||||||
initDataLayers: async function (datalayers) {
|
initDataLayers: async function (datalayers) {
|
||||||
|
@ -820,7 +741,7 @@ U.Map = L.Map.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
getDefaultOption: function (option) {
|
getDefaultOption: function (option) {
|
||||||
return this.options[`default_${option}`]
|
return U.SCHEMA[option] && U.SCHEMA[option].default
|
||||||
},
|
},
|
||||||
|
|
||||||
getOption: function (option) {
|
getOption: function (option) {
|
||||||
|
@ -904,7 +825,7 @@ U.Map = L.Map.extend({
|
||||||
|
|
||||||
let mustReindex = false
|
let mustReindex = false
|
||||||
|
|
||||||
for (const option of Object.keys(this.editableOptions)) {
|
for (const option of Object.keys(U.SCHEMA)) {
|
||||||
if (typeof importedData.properties[option] !== 'undefined') {
|
if (typeof importedData.properties[option] !== 'undefined') {
|
||||||
this.options[option] = importedData.properties[option]
|
this.options[option] = importedData.properties[option]
|
||||||
if (option === 'sortKey') mustReindex = true
|
if (option === 'sortKey') mustReindex = true
|
||||||
|
@ -1033,7 +954,7 @@ U.Map = L.Map.extend({
|
||||||
|
|
||||||
exportOptions: function () {
|
exportOptions: function () {
|
||||||
const properties = {}
|
const properties = {}
|
||||||
for (const option of Object.keys(this.editableOptions)) {
|
for (const option of Object.keys(U.SCHEMA)) {
|
||||||
if (typeof this.options[option] !== 'undefined') {
|
if (typeof this.options[option] !== 'undefined') {
|
||||||
properties[option] = this.options[option]
|
properties[option] = this.options[option]
|
||||||
}
|
}
|
||||||
|
@ -1555,35 +1476,11 @@ U.Map = L.Map.extend({
|
||||||
_editCredits: function (container) {
|
_editCredits: function (container) {
|
||||||
const credits = L.DomUtil.createFieldset(container, L._('Credits'))
|
const credits = L.DomUtil.createFieldset(container, L._('Credits'))
|
||||||
const creditsFields = [
|
const creditsFields = [
|
||||||
['options.licence', { handler: 'LicenceChooser', label: L._('licence') }],
|
'options.licence',
|
||||||
[
|
'options.shortCredit',
|
||||||
'options.shortCredit',
|
'options.longCredit',
|
||||||
{
|
'options.permanentCredit',
|
||||||
handler: 'Input',
|
'options.permanentCreditBackground',
|
||||||
label: L._('Short credits'),
|
|
||||||
helpEntries: ['shortCredit', 'textFormatting'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'options.longCredit',
|
|
||||||
{
|
|
||||||
handler: 'Textarea',
|
|
||||||
label: L._('Long credits'),
|
|
||||||
helpEntries: ['longCredit', 'textFormatting'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'options.permanentCredit',
|
|
||||||
{
|
|
||||||
handler: 'Textarea',
|
|
||||||
label: L._('Permanent credits'),
|
|
||||||
helpEntries: ['permanentCredit', 'textFormatting'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'options.permanentCreditBackground',
|
|
||||||
{ handler: 'Switch', label: L._('Permanent credits background') },
|
|
||||||
],
|
|
||||||
]
|
]
|
||||||
const creditsBuilder = new U.FormBuilder(this, creditsFields, {
|
const creditsBuilder = new U.FormBuilder(this, creditsFields, {
|
||||||
callback: this.renderControls,
|
callback: this.renderControls,
|
||||||
|
@ -1691,7 +1588,7 @@ U.Map = L.Map.extend({
|
||||||
name = L.DomUtil.create('h3', '', container)
|
name = L.DomUtil.create('h3', '', container)
|
||||||
L.DomEvent.disableClickPropagation(container)
|
L.DomEvent.disableClickPropagation(container)
|
||||||
this.permissions.addOwnerLink('span', container)
|
this.permissions.addOwnerLink('span', container)
|
||||||
if (this.options.captionMenus) {
|
if (this.getOption('captionMenus')) {
|
||||||
L.DomUtil.createButton(
|
L.DomUtil.createButton(
|
||||||
'umap-about-link flat',
|
'umap-about-link flat',
|
||||||
container,
|
container,
|
||||||
|
|
|
@ -215,7 +215,7 @@ U.IframeExporter = L.Evented.extend({
|
||||||
this.map = map
|
this.map = map
|
||||||
this.baseUrl = L.Util.getBaseUrl()
|
this.baseUrl = L.Util.getBaseUrl()
|
||||||
// Use map default, not generic default
|
// Use map default, not generic default
|
||||||
this.queryString.onLoadPanel = this.map.options.onLoadPanel
|
this.queryString.onLoadPanel = this.map.getOption('onLoadPanel')
|
||||||
},
|
},
|
||||||
|
|
||||||
getMap: function () {
|
getMap: function () {
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
<script src="../vendors/editable/Path.Drag.js" defer></script>
|
<script src="../vendors/editable/Path.Drag.js" defer></script>
|
||||||
<script src="../vendors/editable/Leaflet.Editable.js" defer></script>
|
<script src="../vendors/editable/Leaflet.Editable.js" defer></script>
|
||||||
<script src="../vendors/hash/leaflet-hash.js" defer></script>
|
<script src="../vendors/hash/leaflet-hash.js" defer></script>
|
||||||
<script src="../vendors/i18n/Leaflet.i18n.js" defer></script>
|
|
||||||
<script src="../vendors/editinosm/Leaflet.EditInOSM.js" defer></script>
|
<script src="../vendors/editinosm/Leaflet.EditInOSM.js" defer></script>
|
||||||
<script src="../vendors/minimap/Control.MiniMap.min.js" defer></script>
|
<script src="../vendors/minimap/Control.MiniMap.min.js" defer></script>
|
||||||
<script src="../vendors/csv2geojson/csv2geojson.js" defer></script>
|
<script src="../vendors/csv2geojson/csv2geojson.js" defer></script>
|
||||||
|
|
|
@ -2,11 +2,16 @@
|
||||||
<script type="module"
|
<script type="module"
|
||||||
src="{% static 'umap/vendors/leaflet/leaflet-src.esm.js' %}"
|
src="{% static 'umap/vendors/leaflet/leaflet-src.esm.js' %}"
|
||||||
defer></script>
|
defer></script>
|
||||||
|
<script type="module" src="{% static 'umap/js/modules/leaflet-configure.js' %}" defer></script>
|
||||||
|
{% if locale %}
|
||||||
|
{% with "umap/locale/"|add:locale|add:".js" as path %}
|
||||||
|
<script src="{% static path %}" defer></script>
|
||||||
|
{% endwith %}
|
||||||
|
{% endif %}
|
||||||
<script type="module" src="{% static 'umap/js/modules/global.js' %}" defer></script>
|
<script type="module" src="{% static 'umap/js/modules/global.js' %}" defer></script>
|
||||||
<script src="{% static 'umap/vendors/editable/Path.Drag.js' %}" defer></script>
|
<script src="{% static 'umap/vendors/editable/Path.Drag.js' %}" defer></script>
|
||||||
<script src="{% static 'umap/vendors/editable/Leaflet.Editable.js' %}" defer></script>
|
<script src="{% static 'umap/vendors/editable/Leaflet.Editable.js' %}" defer></script>
|
||||||
<script src="{% static 'umap/vendors/hash/leaflet-hash.js' %}" defer></script>
|
<script src="{% static 'umap/vendors/hash/leaflet-hash.js' %}" defer></script>
|
||||||
<script src="{% static 'umap/vendors/i18n/Leaflet.i18n.js' %}" defer></script>
|
|
||||||
<script src="{% static 'umap/vendors/editinosm/Leaflet.EditInOSM.js' %}"
|
<script src="{% static 'umap/vendors/editinosm/Leaflet.EditInOSM.js' %}"
|
||||||
defer></script>
|
defer></script>
|
||||||
<script src="{% static 'umap/vendors/minimap/Control.MiniMap.min.js' %}"
|
<script src="{% static 'umap/vendors/minimap/Control.MiniMap.min.js' %}"
|
||||||
|
@ -39,11 +44,7 @@
|
||||||
<script src="{% static 'umap/vendors/colorbrewer/colorbrewer.js' %}" defer></script>
|
<script src="{% static 'umap/vendors/colorbrewer/colorbrewer.js' %}" defer></script>
|
||||||
<script src="{% static 'umap/vendors/simple-statistics/simple-statistics.min.js' %}"
|
<script src="{% static 'umap/vendors/simple-statistics/simple-statistics.min.js' %}"
|
||||||
defer></script>
|
defer></script>
|
||||||
{% if locale %}
|
|
||||||
{% with "umap/locale/"|add:locale|add:".js" as path %}
|
|
||||||
<script src="{% static path %}" defer></script>
|
|
||||||
{% endwith %}
|
|
||||||
{% endif %}
|
|
||||||
<script src="{% static 'umap/js/umap.core.js' %}" defer></script>
|
<script src="{% static 'umap/js/umap.core.js' %}" defer></script>
|
||||||
<script src="{% static 'umap/js/umap.autocomplete.js' %}" defer></script>
|
<script src="{% static 'umap/js/umap.autocomplete.js' %}" defer></script>
|
||||||
<script src="{% static 'umap/js/umap.popup.js' %}" defer></script>
|
<script src="{% static 'umap/js/umap.popup.js' %}" defer></script>
|
||||||
|
|
|
@ -210,7 +210,8 @@ def test_can_change_owner(map, live_server, login, user):
|
||||||
close = page.locator(".umap-field-owner .close")
|
close = page.locator(".umap-field-owner .close")
|
||||||
close.click()
|
close.click()
|
||||||
input = page.locator("input.edit-owner")
|
input = page.locator("input.edit-owner")
|
||||||
input.type(user.username)
|
with page.expect_response(re.compile(r".*/agnocomplete/.*")):
|
||||||
|
input.type(user.username)
|
||||||
input.press("Tab")
|
input.press("Tab")
|
||||||
save = page.get_by_role("button", name="Save")
|
save = page.get_by_role("button", name="Save")
|
||||||
expect(save).to_be_visible()
|
expect(save).to_be_visible()
|
||||||
|
|
|
@ -495,7 +495,7 @@ class MapDetailMixin:
|
||||||
"urls": _urls_for_js(),
|
"urls": _urls_for_js(),
|
||||||
"tilelayers": TileLayer.get_list(),
|
"tilelayers": TileLayer.get_list(),
|
||||||
"editMode": self.edit_mode,
|
"editMode": self.edit_mode,
|
||||||
"default_iconUrl": "%sumap/img/marker.svg" % settings.STATIC_URL, # noqa
|
"schema": Map.extra_schema,
|
||||||
"umap_id": self.get_umap_id(),
|
"umap_id": self.get_umap_id(),
|
||||||
"starred": self.is_starred(),
|
"starred": self.is_starred(),
|
||||||
"licences": dict((l.name, l.json) for l in Licence.objects.all()),
|
"licences": dict((l.name, l.json) for l in Licence.objects.all()),
|
||||||
|
|
Loading…
Reference in a new issue