umap-project 3.3.6__py3-none-any.whl → 3.4.0b0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of umap-project might be problematic. Click here for more details.
- umap/__init__.py +1 -1
- umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
- umap/locale/cs_CZ/LC_MESSAGES/django.po +43 -33
- umap/locale/da/LC_MESSAGES/django.mo +0 -0
- umap/locale/da/LC_MESSAGES/django.po +43 -33
- umap/locale/de/LC_MESSAGES/django.mo +0 -0
- umap/locale/de/LC_MESSAGES/django.po +35 -29
- umap/locale/el/LC_MESSAGES/django.mo +0 -0
- umap/locale/el/LC_MESSAGES/django.po +35 -29
- umap/locale/en/LC_MESSAGES/django.po +34 -28
- umap/locale/es/LC_MESSAGES/django.mo +0 -0
- umap/locale/es/LC_MESSAGES/django.po +43 -33
- umap/locale/et/LC_MESSAGES/django.mo +0 -0
- umap/locale/et/LC_MESSAGES/django.po +58 -54
- umap/locale/eu/LC_MESSAGES/django.mo +0 -0
- umap/locale/eu/LC_MESSAGES/django.po +43 -33
- umap/locale/fa_IR/LC_MESSAGES/django.mo +0 -0
- umap/locale/fa_IR/LC_MESSAGES/django.po +43 -33
- umap/locale/fr/LC_MESSAGES/django.mo +0 -0
- umap/locale/fr/LC_MESSAGES/django.po +36 -30
- umap/locale/gl/LC_MESSAGES/django.mo +0 -0
- umap/locale/gl/LC_MESSAGES/django.po +43 -33
- umap/locale/hu/LC_MESSAGES/django.mo +0 -0
- umap/locale/hu/LC_MESSAGES/django.po +35 -29
- umap/locale/is/LC_MESSAGES/django.mo +0 -0
- umap/locale/is/LC_MESSAGES/django.po +43 -33
- umap/locale/it/LC_MESSAGES/django.mo +0 -0
- umap/locale/it/LC_MESSAGES/django.po +43 -33
- umap/locale/nl/LC_MESSAGES/django.mo +0 -0
- umap/locale/nl/LC_MESSAGES/django.po +35 -29
- umap/locale/pl/LC_MESSAGES/django.mo +0 -0
- umap/locale/pl/LC_MESSAGES/django.po +43 -33
- umap/locale/pt/LC_MESSAGES/django.mo +0 -0
- umap/locale/pt/LC_MESSAGES/django.po +43 -33
- umap/locale/th_TH/LC_MESSAGES/django.mo +0 -0
- umap/locale/th_TH/LC_MESSAGES/django.po +310 -109
- umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
- umap/locale/zh_TW/LC_MESSAGES/django.po +80 -70
- umap/management/commands/switch_user.py +2 -2
- umap/static/umap/base.css +89 -32
- umap/static/umap/content.css +129 -33
- umap/static/umap/css/bar.css +82 -20
- umap/static/umap/css/browser.css +163 -0
- umap/static/umap/css/contextmenu.css +15 -0
- umap/static/umap/css/dialog.css +36 -16
- umap/static/umap/css/form.css +122 -32
- umap/static/umap/css/icon.css +46 -3
- umap/static/umap/css/panel.css +7 -3
- umap/static/umap/css/popup.css +34 -8
- umap/static/umap/css/tooltip.css +8 -4
- umap/static/umap/img/16-white.svg +26 -8
- umap/static/umap/img/16.svg +1 -1
- umap/static/umap/img/source/16-white.svg +36 -18
- umap/static/umap/img/source/16.svg +1 -1
- umap/static/umap/js/components/alerts/alert.css +69 -31
- umap/static/umap/js/components/alerts/alert.js +20 -2
- umap/static/umap/js/modules/browser.js +63 -55
- umap/static/umap/js/modules/caption.js +10 -7
- umap/static/umap/js/modules/data/features.js +82 -59
- umap/static/umap/js/modules/data/layer.js +56 -157
- umap/static/umap/js/modules/domutils.js +109 -0
- umap/static/umap/js/modules/filters.js +807 -0
- umap/static/umap/js/modules/form/builder.js +8 -5
- umap/static/umap/js/modules/form/fields.js +110 -220
- umap/static/umap/js/modules/formatter.js +24 -1
- umap/static/umap/js/modules/help.js +3 -2
- umap/static/umap/js/modules/importers/opendata.js +5 -0
- umap/static/umap/js/modules/importers/openrouteservice.js +6 -1
- umap/static/umap/js/modules/managers.js +265 -1
- umap/static/umap/js/modules/permissions.js +35 -31
- umap/static/umap/js/modules/rendering/controls.js +7 -7
- umap/static/umap/js/modules/rendering/icon.js +3 -8
- umap/static/umap/js/modules/rendering/layers/classified.js +17 -10
- umap/static/umap/js/modules/rendering/layers/cluster.js +2 -2
- umap/static/umap/js/modules/rendering/template.js +44 -8
- umap/static/umap/js/modules/rendering/ui.js +29 -23
- umap/static/umap/js/modules/rules.js +4 -3
- umap/static/umap/js/modules/schema.js +3 -6
- umap/static/umap/js/modules/share.js +4 -3
- umap/static/umap/js/modules/tableeditor.js +50 -38
- umap/static/umap/js/modules/templates.js +2 -3
- umap/static/umap/js/modules/ui/bar.js +42 -18
- umap/static/umap/js/modules/ui/dialog.js +33 -31
- umap/static/umap/js/modules/ui/panel.js +21 -7
- umap/static/umap/js/modules/ui/tooltip.js +6 -5
- umap/static/umap/js/modules/umap.js +148 -51
- umap/static/umap/js/modules/utils.js +23 -1
- umap/static/umap/js/umap.core.js +1 -110
- umap/static/umap/locale/am_ET.js +40 -14
- umap/static/umap/locale/am_ET.json +40 -14
- umap/static/umap/locale/ar.js +40 -14
- umap/static/umap/locale/ar.json +40 -14
- umap/static/umap/locale/ast.js +40 -14
- umap/static/umap/locale/ast.json +40 -14
- umap/static/umap/locale/bg.js +40 -14
- umap/static/umap/locale/bg.json +40 -14
- umap/static/umap/locale/br.js +47 -21
- umap/static/umap/locale/br.json +47 -21
- umap/static/umap/locale/ca.js +40 -14
- umap/static/umap/locale/ca.json +40 -14
- umap/static/umap/locale/cs_CZ.js +40 -14
- umap/static/umap/locale/cs_CZ.json +40 -14
- umap/static/umap/locale/da.js +40 -14
- umap/static/umap/locale/da.json +40 -14
- umap/static/umap/locale/de.js +39 -13
- umap/static/umap/locale/de.json +39 -13
- umap/static/umap/locale/el.js +40 -14
- umap/static/umap/locale/el.json +40 -14
- umap/static/umap/locale/en.js +39 -13
- umap/static/umap/locale/en.json +39 -13
- umap/static/umap/locale/en_US.json +40 -14
- umap/static/umap/locale/es.js +40 -14
- umap/static/umap/locale/es.json +40 -14
- umap/static/umap/locale/et.js +79 -53
- umap/static/umap/locale/et.json +79 -53
- umap/static/umap/locale/eu.js +72 -46
- umap/static/umap/locale/eu.json +72 -46
- umap/static/umap/locale/fa_IR.js +40 -14
- umap/static/umap/locale/fa_IR.json +40 -14
- umap/static/umap/locale/fi.js +40 -14
- umap/static/umap/locale/fi.json +40 -14
- umap/static/umap/locale/fr.js +39 -13
- umap/static/umap/locale/fr.json +39 -13
- umap/static/umap/locale/gl.js +40 -14
- umap/static/umap/locale/gl.json +40 -14
- umap/static/umap/locale/he.js +40 -14
- umap/static/umap/locale/he.json +40 -14
- umap/static/umap/locale/hr.js +40 -14
- umap/static/umap/locale/hr.json +40 -14
- umap/static/umap/locale/hu.js +40 -14
- umap/static/umap/locale/hu.json +40 -14
- umap/static/umap/locale/id.js +40 -14
- umap/static/umap/locale/id.json +40 -14
- umap/static/umap/locale/is.js +40 -14
- umap/static/umap/locale/is.json +40 -14
- umap/static/umap/locale/it.js +40 -14
- umap/static/umap/locale/it.json +40 -14
- umap/static/umap/locale/ja.js +40 -14
- umap/static/umap/locale/ja.json +40 -14
- umap/static/umap/locale/ko.js +40 -14
- umap/static/umap/locale/ko.json +40 -14
- umap/static/umap/locale/lt.js +40 -14
- umap/static/umap/locale/lt.json +40 -14
- umap/static/umap/locale/ms.js +40 -14
- umap/static/umap/locale/ms.json +40 -14
- umap/static/umap/locale/nl.js +40 -14
- umap/static/umap/locale/nl.json +40 -14
- umap/static/umap/locale/no.js +40 -14
- umap/static/umap/locale/no.json +40 -14
- umap/static/umap/locale/pl.js +40 -14
- umap/static/umap/locale/pl.json +40 -14
- umap/static/umap/locale/pl_PL.json +40 -14
- umap/static/umap/locale/pt.js +40 -14
- umap/static/umap/locale/pt.json +40 -14
- umap/static/umap/locale/pt_BR.js +40 -14
- umap/static/umap/locale/pt_BR.json +40 -14
- umap/static/umap/locale/pt_PT.js +40 -14
- umap/static/umap/locale/pt_PT.json +40 -14
- umap/static/umap/locale/ro.js +40 -14
- umap/static/umap/locale/ro.json +40 -14
- umap/static/umap/locale/ru.js +40 -14
- umap/static/umap/locale/ru.json +40 -14
- umap/static/umap/locale/sk_SK.js +40 -14
- umap/static/umap/locale/sk_SK.json +40 -14
- umap/static/umap/locale/sl.js +40 -14
- umap/static/umap/locale/sl.json +40 -14
- umap/static/umap/locale/sr.js +40 -14
- umap/static/umap/locale/sr.json +40 -14
- umap/static/umap/locale/sv.js +40 -14
- umap/static/umap/locale/sv.json +40 -14
- umap/static/umap/locale/th_TH.js +40 -14
- umap/static/umap/locale/th_TH.json +40 -14
- umap/static/umap/locale/tr.js +40 -14
- umap/static/umap/locale/tr.json +40 -14
- umap/static/umap/locale/uk_UA.js +40 -14
- umap/static/umap/locale/uk_UA.json +40 -14
- umap/static/umap/locale/vi.js +40 -14
- umap/static/umap/locale/vi.json +40 -14
- umap/static/umap/locale/vi_VN.json +40 -14
- umap/static/umap/locale/zh.js +40 -14
- umap/static/umap/locale/zh.json +40 -14
- umap/static/umap/locale/zh_CN.json +40 -14
- umap/static/umap/locale/zh_TW.Big5.json +40 -14
- umap/static/umap/locale/zh_TW.js +39 -13
- umap/static/umap/locale/zh_TW.json +39 -13
- umap/static/umap/map.css +60 -223
- umap/static/umap/unittests/utils.js +18 -0
- umap/static/umap/vars.css +23 -5
- umap/templates/umap/components/alerts/alert.html +32 -29
- umap/templates/umap/css.html +2 -1
- umap/templates/umap/login_popup_end.html +18 -9
- umap/templates/umap/user_map_table.html +7 -2
- umap/tests/integration/conftest.py +2 -6
- umap/tests/integration/test_anonymous_owned_map.py +89 -36
- umap/tests/integration/test_basics.py +25 -1
- umap/tests/integration/test_browser.py +37 -0
- umap/tests/integration/test_draw_polygon.py +2 -0
- umap/tests/integration/test_edit_marker.py +1 -1
- umap/tests/integration/test_export_map.py +19 -0
- umap/tests/integration/test_fields.py +522 -0
- umap/tests/integration/test_filters.py +617 -0
- umap/tests/integration/test_import.py +15 -42
- umap/tests/integration/test_remote_data.py +60 -4
- umap/tests/integration/test_share.py +4 -4
- umap/tests/integration/test_tableeditor.py +31 -7
- umap/tests/integration/test_websocket_sync.py +3 -1
- umap/tests/test_dashboard.py +10 -0
- umap/urls.py +1 -0
- umap/views.py +5 -0
- {umap_project-3.3.6.dist-info → umap_project-3.4.0b0.dist-info}/METADATA +12 -12
- {umap_project-3.3.6.dist-info → umap_project-3.4.0b0.dist-info}/RECORD +214 -211
- umap/static/umap/js/modules/facets.js +0 -164
- umap/tests/integration/test_facets_browser.py +0 -279
- {umap_project-3.3.6.dist-info → umap_project-3.4.0b0.dist-info}/WHEEL +0 -0
- {umap_project-3.3.6.dist-info → umap_project-3.4.0b0.dist-info}/entry_points.txt +0 -0
- {umap_project-3.3.6.dist-info → umap_project-3.4.0b0.dist-info}/licenses/LICENSE +0 -0
|
@@ -111,6 +111,10 @@ const FeatureMixin = {
|
|
|
111
111
|
onCommit: function () {
|
|
112
112
|
this.feature.onCommit()
|
|
113
113
|
},
|
|
114
|
+
|
|
115
|
+
isVisible() {
|
|
116
|
+
return Boolean(this._map?.hasLayer(this))
|
|
117
|
+
},
|
|
114
118
|
}
|
|
115
119
|
|
|
116
120
|
const PointMixin = {
|
|
@@ -377,6 +381,27 @@ const PathMixin = {
|
|
|
377
381
|
// https://github.com/Leaflet/Leaflet/pull/9475
|
|
378
382
|
|
|
379
383
|
this._path.classList.toggle('leaflet-interactive', options.interactive)
|
|
384
|
+
|
|
385
|
+
// Text decoration
|
|
386
|
+
this.setText(null) // Reset.
|
|
387
|
+
const textPath = this.feature.getDynamicOption('textPath')
|
|
388
|
+
if (textPath) {
|
|
389
|
+
const color =
|
|
390
|
+
this.feature.getOption('textPathColor') ||
|
|
391
|
+
this.feature.getDynamicOption('color')
|
|
392
|
+
const textPathOptions = {
|
|
393
|
+
repeat: this.feature.getOption('textPathRepeat'),
|
|
394
|
+
offset: this.feature.getOption('textPathOffset') || undefined,
|
|
395
|
+
position: this.feature.getOption('textPathPosition'),
|
|
396
|
+
attributes: {
|
|
397
|
+
fill: color,
|
|
398
|
+
opacity: this.feature.getDynamicOption('opacity'),
|
|
399
|
+
rotate: this.feature.getOption('textPathRotate'),
|
|
400
|
+
'font-size': this.feature.getOption('textPathSize'),
|
|
401
|
+
},
|
|
402
|
+
}
|
|
403
|
+
this.setText(textPath, textPathOptions)
|
|
404
|
+
}
|
|
380
405
|
},
|
|
381
406
|
|
|
382
407
|
_redraw: function () {
|
|
@@ -423,29 +448,6 @@ export const LeafletPolyline = Polyline.extend({
|
|
|
423
448
|
parentClass: Polyline,
|
|
424
449
|
includes: [FeatureMixin, PathMixin],
|
|
425
450
|
|
|
426
|
-
setStyle: function (options) {
|
|
427
|
-
PathMixin.setStyle.call(this, options)
|
|
428
|
-
this.setText(null) // Reset.
|
|
429
|
-
const textPath = this.feature.getDynamicOption('textPath')
|
|
430
|
-
if (textPath) {
|
|
431
|
-
const color =
|
|
432
|
-
this.feature.getOption('textPathColor') ||
|
|
433
|
-
this.feature.getDynamicOption('color')
|
|
434
|
-
const textPathOptions = {
|
|
435
|
-
repeat: this.feature.getOption('textPathRepeat'),
|
|
436
|
-
offset: this.feature.getOption('textPathOffset') || undefined,
|
|
437
|
-
position: this.feature.getOption('textPathPosition'),
|
|
438
|
-
attributes: {
|
|
439
|
-
fill: color,
|
|
440
|
-
opacity: this.feature.getDynamicOption('opacity'),
|
|
441
|
-
rotate: this.feature.getOption('textPathRotate'),
|
|
442
|
-
'font-size': this.feature.getOption('textPathSize'),
|
|
443
|
-
},
|
|
444
|
-
}
|
|
445
|
-
this.setText(textPath, textPathOptions)
|
|
446
|
-
}
|
|
447
|
-
},
|
|
448
|
-
|
|
449
451
|
getClass: () => LeafletPolyline,
|
|
450
452
|
|
|
451
453
|
getMeasure: function (shape) {
|
|
@@ -632,4 +634,8 @@ export const CircleMarker = BaseCircleMarker.extend({
|
|
|
632
634
|
getCenter: function () {
|
|
633
635
|
return this._latlng
|
|
634
636
|
},
|
|
637
|
+
|
|
638
|
+
setText() {
|
|
639
|
+
// Dummy function, as it inherits from PathMixin
|
|
640
|
+
},
|
|
635
641
|
})
|
|
@@ -207,7 +207,8 @@ class Rule {
|
|
|
207
207
|
const [li, { colorBox }] = Utils.loadTemplateWithRefs(
|
|
208
208
|
`<li><span class="color-box" data-ref=colorBox></span>${this.label}</li>`
|
|
209
209
|
)
|
|
210
|
-
const bgcolor =
|
|
210
|
+
const bgcolor =
|
|
211
|
+
this.properties.fillColor || this.properties.color || this.parent.getColor()
|
|
211
212
|
const symbol = this.properties.iconUrl
|
|
212
213
|
colorBox.style.backgroundColor = bgcolor
|
|
213
214
|
if (symbol && symbol !== SCHEMA.iconUrl.default) {
|
|
@@ -265,10 +266,10 @@ export default class Rules {
|
|
|
265
266
|
edit(container) {
|
|
266
267
|
const template = `
|
|
267
268
|
<details id="rules">
|
|
268
|
-
<summary>${translate('Conditional style rules')}</summary>
|
|
269
|
+
<summary><h4>${translate('Conditional style rules')}</h4></summary>
|
|
269
270
|
<fieldset>
|
|
270
271
|
<ul data-ref=ul></ul>
|
|
271
|
-
<button
|
|
272
|
+
<button type="button" data-ref=add>${translate('Add rule')}</button>
|
|
272
273
|
</fieldset>
|
|
273
274
|
</details>
|
|
274
275
|
`
|
|
@@ -140,15 +140,12 @@ export const SCHEMA = {
|
|
|
140
140
|
label: translate('Display the embed control'),
|
|
141
141
|
default: true,
|
|
142
142
|
},
|
|
143
|
-
|
|
144
|
-
type:
|
|
143
|
+
filters: {
|
|
144
|
+
type: Array,
|
|
145
145
|
impacts: ['ui'],
|
|
146
|
-
helpEntries: ['facetKey'],
|
|
147
|
-
placeholder: translate('Example: key1,key2|Label 2,key3|Label 3|checkbox'),
|
|
148
|
-
label: translate('Filters keys'),
|
|
149
146
|
},
|
|
150
147
|
fields: {
|
|
151
|
-
type:
|
|
148
|
+
type: Array,
|
|
152
149
|
},
|
|
153
150
|
fill: {
|
|
154
151
|
type: Boolean,
|
|
@@ -3,6 +3,7 @@ import { MutatingForm } from './form/builder.js'
|
|
|
3
3
|
import { EXPORT_FORMATS } from './formatter.js'
|
|
4
4
|
import { translate } from './i18n.js'
|
|
5
5
|
import * as Utils from './utils.js'
|
|
6
|
+
import * as DOMUtils from './domutils.js'
|
|
6
7
|
|
|
7
8
|
export default class Share {
|
|
8
9
|
constructor(umap) {
|
|
@@ -17,14 +18,14 @@ export default class Share {
|
|
|
17
18
|
'icon-share'
|
|
18
19
|
)
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
DOMUtils.copiableInput(
|
|
21
22
|
this.container,
|
|
22
23
|
translate('Link to view the map'),
|
|
23
24
|
window.location.protocol + Utils.getBaseUrl()
|
|
24
25
|
)
|
|
25
26
|
|
|
26
27
|
if (this._umap.properties.shortUrl) {
|
|
27
|
-
|
|
28
|
+
DOMUtils.copiableInput(
|
|
28
29
|
this.container,
|
|
29
30
|
translate('Short link'),
|
|
30
31
|
this._umap.properties.shortUrl
|
|
@@ -79,7 +80,7 @@ export default class Share {
|
|
|
79
80
|
const embedTitle = DomUtil.add('h4', '', this.container, translate('Embed the map'))
|
|
80
81
|
const iframe = DomUtil.create('textarea', 'umap-share-iframe', this.container)
|
|
81
82
|
const urlTitle = DomUtil.add('h4', '', this.container, translate('Direct link'))
|
|
82
|
-
const exportUrl =
|
|
83
|
+
const exportUrl = DOMUtils.copiableInput(
|
|
83
84
|
this.container,
|
|
84
85
|
translate('Share this link to open a customized map view'),
|
|
85
86
|
''
|
|
@@ -31,53 +31,73 @@ export default class TableEditor extends WithTemplate {
|
|
|
31
31
|
this.elements.body.addEventListener('keydown', (event) => this.onKeyDown(event))
|
|
32
32
|
this.elements.header.addEventListener('click', (event) => {
|
|
33
33
|
const property = event.target.dataset.property
|
|
34
|
-
|
|
34
|
+
const parentType = event.target.dataset.fieldParent
|
|
35
|
+
if (property)
|
|
36
|
+
this.openHeaderMenu(
|
|
37
|
+
property,
|
|
38
|
+
parentType === 'map' ? this._umap : this.datalayer
|
|
39
|
+
)
|
|
35
40
|
})
|
|
36
41
|
}
|
|
37
42
|
|
|
38
|
-
openHeaderMenu(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
openHeaderMenu(name, parent) {
|
|
44
|
+
let actionLabel
|
|
45
|
+
if (parent.filters.has(name)) {
|
|
46
|
+
actionLabel = translate('Edit filter for this field')
|
|
47
|
+
} else {
|
|
48
|
+
actionLabel = translate('Add filter for this field')
|
|
49
|
+
}
|
|
50
|
+
const actions = [
|
|
51
|
+
{
|
|
52
|
+
label: actionLabel,
|
|
44
53
|
action: () => {
|
|
45
|
-
|
|
54
|
+
parent.filters.createFilterForm(name)
|
|
46
55
|
this._umap.browser.open('filters')
|
|
47
56
|
},
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
label: translate('Add filter for this column'),
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
label: translate('Edit this field'),
|
|
52
60
|
action: () => {
|
|
53
|
-
|
|
54
|
-
this._umap.browser.open('filters')
|
|
61
|
+
parent.fields.editField(name).then(() => this.open())
|
|
55
62
|
},
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (!
|
|
63
|
+
},
|
|
64
|
+
]
|
|
65
|
+
// Only allow deleting fields for map and local datalayer.
|
|
66
|
+
if (!parent.isRemoteLayer?.()) {
|
|
60
67
|
actions.push({
|
|
61
|
-
label: translate('
|
|
62
|
-
action: () =>
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
label: translate('Delete this column'),
|
|
66
|
-
action: () => this.deleteProperty(property),
|
|
68
|
+
label: translate('Delete this field'),
|
|
69
|
+
action: () => {
|
|
70
|
+
parent.fields.confirmDelete(name).then(() => this.open())
|
|
71
|
+
},
|
|
67
72
|
})
|
|
68
73
|
}
|
|
69
74
|
this.contextmenu.open(event, actions)
|
|
70
75
|
}
|
|
71
76
|
|
|
77
|
+
get fields() {
|
|
78
|
+
return [
|
|
79
|
+
...this.datalayer.fields.all().map((field) => {
|
|
80
|
+
const copy = { ...field }
|
|
81
|
+
copy.parent = 'datalayer'
|
|
82
|
+
return copy
|
|
83
|
+
}),
|
|
84
|
+
...this._umap.fields.all().map((field) => {
|
|
85
|
+
const copy = { ...field }
|
|
86
|
+
copy.parent = 'map'
|
|
87
|
+
return copy
|
|
88
|
+
}),
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
|
|
72
92
|
renderHeaders() {
|
|
73
93
|
this.elements.header.innerHTML = ''
|
|
74
94
|
const th = loadTemplate('<th><input type="checkbox" /></th>')
|
|
75
95
|
const checkbox = th.firstChild
|
|
76
96
|
this.elements.header.appendChild(th)
|
|
77
|
-
for (const field of this.
|
|
97
|
+
for (const field of this.fields) {
|
|
78
98
|
this.elements.header.appendChild(
|
|
79
99
|
loadTemplate(
|
|
80
|
-
`<th>${field.key}<button data-property="${field.key}" class="flat" aria-label="${translate('Advanced actions')}">…</button></th>`
|
|
100
|
+
`<th>${field.key}<button data-property="${field.key}" data-field-parent="${field.parent}" class="flat" aria-label="${translate('Advanced actions')}">…</button></th>`
|
|
81
101
|
)
|
|
82
102
|
)
|
|
83
103
|
}
|
|
@@ -94,7 +114,7 @@ export default class TableEditor extends WithTemplate {
|
|
|
94
114
|
this.datalayer.features.forEach((feature) => {
|
|
95
115
|
if (feature.isFiltered()) return
|
|
96
116
|
if (inBbox && !feature.isOnScreen(bounds)) return
|
|
97
|
-
const tds = this.
|
|
117
|
+
const tds = this.fields.map(
|
|
98
118
|
(field) =>
|
|
99
119
|
`<td tabindex="0" data-property="${field.key}">${feature.properties[field.key] ?? ''}</td>`
|
|
100
120
|
)
|
|
@@ -103,16 +123,8 @@ export default class TableEditor extends WithTemplate {
|
|
|
103
123
|
this.elements.body.innerHTML = html
|
|
104
124
|
}
|
|
105
125
|
|
|
106
|
-
|
|
107
|
-
this.datalayer.
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
deleteProperty(property) {
|
|
111
|
-
this.datalayer.confirmDeleteProperty(property).then(() => this.open())
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
addProperty() {
|
|
115
|
-
this.datalayer.addProperty().then(() => this.open())
|
|
126
|
+
addField() {
|
|
127
|
+
this.datalayer.fields.editField().then(() => this.open())
|
|
116
128
|
}
|
|
117
129
|
|
|
118
130
|
open() {
|
|
@@ -127,7 +139,7 @@ export default class TableEditor extends WithTemplate {
|
|
|
127
139
|
<button class="flat" type="button" data-ref="add">
|
|
128
140
|
<i class="icon icon-16 icon-add"></i>${translate('Add a new field')}
|
|
129
141
|
</button>`)
|
|
130
|
-
addButton.addEventListener('click', () => this.
|
|
142
|
+
addButton.addEventListener('click', () => this.addField())
|
|
131
143
|
actions.push(addButton)
|
|
132
144
|
|
|
133
145
|
const deleteButton = loadTemplate(`
|
|
@@ -32,9 +32,8 @@ export default class TemplateImporter {
|
|
|
32
32
|
const [root, { tabs, form, body, mine, confirm, confirmData }] =
|
|
33
33
|
Utils.loadTemplateWithRefs(TEMPLATE)
|
|
34
34
|
const uri = this.umap.urls.get('template_list')
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
mine.hidden = !userIsAuth
|
|
35
|
+
const defaultTab = this.umap.permissions.userIsAuth() ? 'mine' : 'staff'
|
|
36
|
+
mine.hidden = !this.umap.permissions.userIsAuth()
|
|
38
37
|
|
|
39
38
|
const loadTemplates = async (source) => {
|
|
40
39
|
const [data, response, error] = await this.umap.server.get(
|
|
@@ -11,11 +11,16 @@ const TOP_BAR_TEMPLATE = `
|
|
|
11
11
|
<div class="umap-left-edit-toolbox" data-ref="left">
|
|
12
12
|
<div class="logo"><a class="" href="/" title="${translate('Go to the homepage')}">uMap</a></div>
|
|
13
13
|
<button class="map-name flat truncate" type="button" data-ref="name"></button>
|
|
14
|
-
<button class="
|
|
15
|
-
|
|
14
|
+
<button class="flat truncate" type="button" data-ref="share">
|
|
15
|
+
<i class="icon icon-16 icon-draft show-on-draft"></i><span class="share-status"></span>
|
|
16
|
+
</button>
|
|
17
|
+
<button class="anonymous truncate soft-round" type="button" data-ref="shareAnonymous" hidden>
|
|
18
|
+
<i class="icon icon-16 icon-anonymous"></i><span class="share-status"></span>
|
|
19
|
+
</button>
|
|
20
|
+
<button class="edit-undo flat" type="button" data-ref="undo" disabled>
|
|
16
21
|
<i class="icon icon-16 icon-undo"></i>
|
|
17
22
|
</button>
|
|
18
|
-
<button class="edit-redo
|
|
23
|
+
<button class="edit-redo flat" type="button" data-ref="redo" disabled>
|
|
19
24
|
<i class="icon icon-16 icon-redo"></i>
|
|
20
25
|
</button>
|
|
21
26
|
</div>
|
|
@@ -26,7 +31,7 @@ const TOP_BAR_TEMPLATE = `
|
|
|
26
31
|
</button>
|
|
27
32
|
<button class="umap-user flat" type="button" data-ref="user">
|
|
28
33
|
<i class="icon icon-16 icon-profile"></i>
|
|
29
|
-
<span class="username truncate" data-ref="username"
|
|
34
|
+
<span class="username truncate" data-ref="username">${translate('Anonymous')}</span>
|
|
30
35
|
</button>
|
|
31
36
|
<button class="umap-help-link flat" type="button" title="${translate('Help')}" data-ref="help">${translate('Help')}</button>
|
|
32
37
|
<button class="edit-disable round disabled-on-dirty" type="button" data-ref="view">
|
|
@@ -72,17 +77,31 @@ export class TopBar extends WithTemplate {
|
|
|
72
77
|
duration: 5000,
|
|
73
78
|
})
|
|
74
79
|
})
|
|
80
|
+
this.elements.shareAnonymous.addEventListener('mouseover', () => {
|
|
81
|
+
this._umap.tooltip.open({
|
|
82
|
+
content: translate('Anonymous map: update who can see and edit it'),
|
|
83
|
+
anchor: this.elements.shareAnonymous,
|
|
84
|
+
position: 'bottom',
|
|
85
|
+
delay: 500,
|
|
86
|
+
duration: 5000,
|
|
87
|
+
})
|
|
88
|
+
})
|
|
75
89
|
if (this._umap.properties.editMode === 'advanced') {
|
|
76
90
|
this.elements.name.addEventListener('click', () => this._umap.editCaption())
|
|
77
91
|
this.elements.share.addEventListener('click', () => this._umap.permissions.edit())
|
|
92
|
+
this.elements.shareAnonymous.addEventListener('click', () =>
|
|
93
|
+
this._umap.permissions.edit()
|
|
94
|
+
)
|
|
78
95
|
}
|
|
79
96
|
this.elements.user.addEventListener('click', () => {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
97
|
+
const actions = [
|
|
98
|
+
{
|
|
99
|
+
label: translate('New map'),
|
|
100
|
+
action: this._umap.urls.get('map_new'),
|
|
101
|
+
},
|
|
102
|
+
]
|
|
103
|
+
if (this._umap.permissions.userIsAuth()) {
|
|
104
|
+
actions.push(
|
|
86
105
|
{
|
|
87
106
|
label: translate('My maps'),
|
|
88
107
|
action: this._umap.urls.get('user_dashboard'),
|
|
@@ -90,18 +109,22 @@ export class TopBar extends WithTemplate {
|
|
|
90
109
|
{
|
|
91
110
|
label: translate('My teams'),
|
|
92
111
|
action: this._umap.urls.get('user_teams'),
|
|
93
|
-
}
|
|
94
|
-
|
|
112
|
+
}
|
|
113
|
+
)
|
|
95
114
|
if (this._umap.urls.has('user_profile')) {
|
|
96
115
|
actions.push({
|
|
97
116
|
label: translate('My profile'),
|
|
98
117
|
action: this._umap.urls.get('user_profile'),
|
|
99
118
|
})
|
|
100
119
|
}
|
|
101
|
-
|
|
120
|
+
} else {
|
|
121
|
+
actions.push({
|
|
122
|
+
label: translate('Login'),
|
|
123
|
+
action: () => this._umap.askForLogin(),
|
|
124
|
+
})
|
|
102
125
|
}
|
|
126
|
+
this._menu.openBelow(this.elements.user, actions)
|
|
103
127
|
})
|
|
104
|
-
|
|
105
128
|
this.elements.peers.addEventListener('mouseover', () => {
|
|
106
129
|
const connectedPeers = this._umap.sync.getPeers()
|
|
107
130
|
if (!Object.keys(connectedPeers).length) return
|
|
@@ -162,10 +185,10 @@ export class TopBar extends WithTemplate {
|
|
|
162
185
|
duration: 5000,
|
|
163
186
|
})
|
|
164
187
|
})
|
|
165
|
-
this.redraw()
|
|
166
188
|
}
|
|
167
189
|
|
|
168
190
|
redraw() {
|
|
191
|
+
this.element.classList.toggle('draft', this._umap.permissions.isDraft())
|
|
169
192
|
const syncEnabled = this._umap.getProperty('syncEnabled')
|
|
170
193
|
this.elements.peers.hidden = !syncEnabled
|
|
171
194
|
this.elements.view.disabled = this._umap.sync._undoManager.isDirty()
|
|
@@ -175,6 +198,8 @@ export class TopBar extends WithTemplate {
|
|
|
175
198
|
this.elements.saveDraftLabel.hidden = !isDraft || isTemplate
|
|
176
199
|
this.elements.saveTemplateLabel.hidden = !isTemplate
|
|
177
200
|
this._umap.sync._undoManager.toggleState()
|
|
201
|
+
this.elements.share.hidden = this._umap.permissions.isAnonymousMap()
|
|
202
|
+
this.elements.shareAnonymous.hidden = !this._umap.permissions.isAnonymousMap()
|
|
178
203
|
}
|
|
179
204
|
}
|
|
180
205
|
|
|
@@ -218,7 +243,6 @@ export class BottomBar extends WithTemplate {
|
|
|
218
243
|
}
|
|
219
244
|
})
|
|
220
245
|
})
|
|
221
|
-
this.redraw()
|
|
222
246
|
}
|
|
223
247
|
|
|
224
248
|
redraw() {
|
|
@@ -229,7 +253,7 @@ export class BottomBar extends WithTemplate {
|
|
|
229
253
|
const showMenus = this._umap.getProperty('captionMenus')
|
|
230
254
|
this.elements.caption.hidden = !showMenus
|
|
231
255
|
this.elements.browse.hidden = !showMenus
|
|
232
|
-
this.elements.filter.hidden = !showMenus || !this._umap.
|
|
256
|
+
this.elements.filter.hidden = !showMenus || !this._umap.hasFilters()
|
|
233
257
|
this.buildDataLayerSwitcher()
|
|
234
258
|
}
|
|
235
259
|
|
|
@@ -267,7 +291,7 @@ const EDIT_BAR_TEMPLATE = `
|
|
|
267
291
|
</li>
|
|
268
292
|
<li data-ref="route" hidden><button type="button" data-getstarted title="${translate('Draw along routes')}"><i class="icon icon-24 icon-route"></i></button></li>
|
|
269
293
|
<hr>
|
|
270
|
-
<li data-ref="caption" hidden><button data-getstarted type="button" title="${translate('Edit map name and caption')}"><i class="icon icon-24 icon-
|
|
294
|
+
<li data-ref="caption" hidden><button data-getstarted type="button" title="${translate('Edit map name and caption')}"><i class="icon icon-24 icon-info"></i></button></li>
|
|
271
295
|
<li data-ref="import" hidden><button type="button"><i class="icon icon-24 icon-upload"></i></button></li>
|
|
272
296
|
<li data-ref="templates" hidden><button type="button" title="${translate('Load template')}" data-getstarted><i class="icon icon-24 icon-template"></i></button></li>
|
|
273
297
|
<li data-ref="layers" hidden><button type="button" title="${translate('Manage layers')}"><i class="icon icon-24 icon-layers"></i></button></li>
|
|
@@ -78,8 +78,7 @@ export default class Dialog extends WithTemplate {
|
|
|
78
78
|
if (!this.dialogSupported) {
|
|
79
79
|
this.elements.form.addEventListener('submit', (event) => {
|
|
80
80
|
event.preventDefault()
|
|
81
|
-
this.
|
|
82
|
-
this.close()
|
|
81
|
+
this.accept()
|
|
83
82
|
})
|
|
84
83
|
}
|
|
85
84
|
this.dialog.addEventListener('keydown', (e) => {
|
|
@@ -118,7 +117,6 @@ export default class Dialog extends WithTemplate {
|
|
|
118
117
|
this.elements.cancel.hidden = !dialog.cancel
|
|
119
118
|
this.elements.message.textContent = dialog.message
|
|
120
119
|
this.elements.message.hidden = !dialog.message
|
|
121
|
-
this.elements.target = dialog.target || ''
|
|
122
120
|
this.elements.template.innerHTML = ''
|
|
123
121
|
if (dialog.template?.nodeType === 1) {
|
|
124
122
|
this.elements.template.appendChild(dialog.template)
|
|
@@ -137,12 +135,13 @@ export default class Dialog extends WithTemplate {
|
|
|
137
135
|
if (currentZIndex) {
|
|
138
136
|
this.dialog.style.zIndex = currentZIndex + 1
|
|
139
137
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
138
|
+
if (this.dialogSupported) {
|
|
139
|
+
this.dialog.show()
|
|
140
|
+
} else {
|
|
141
|
+
this.dialog.hidden = false
|
|
142
|
+
}
|
|
143
143
|
if (this.hasFormData) this.focusable[0].focus()
|
|
144
144
|
else this.elements.accept.focus()
|
|
145
|
-
|
|
146
145
|
return this.waitForUser()
|
|
147
146
|
}
|
|
148
147
|
|
|
@@ -151,37 +150,40 @@ export default class Dialog extends WithTemplate {
|
|
|
151
150
|
}
|
|
152
151
|
|
|
153
152
|
close() {
|
|
154
|
-
this.
|
|
155
|
-
this.dialog.returnValue = undefined
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
toggle(open = false) {
|
|
153
|
+
this._closing = true
|
|
159
154
|
if (this.dialogSupported) {
|
|
160
|
-
|
|
161
|
-
else this.dialog.close()
|
|
155
|
+
this.dialog.close()
|
|
162
156
|
} else {
|
|
163
|
-
this.dialog.hidden =
|
|
164
|
-
|
|
165
|
-
this.elements.target.focus()
|
|
166
|
-
}
|
|
167
|
-
if (!open) {
|
|
168
|
-
this.dialog.dispatchEvent(new CustomEvent('close'))
|
|
169
|
-
}
|
|
157
|
+
this.dialog.hidden = true
|
|
158
|
+
this.dialog.dispatchEvent(new CustomEvent('close'))
|
|
170
159
|
}
|
|
171
160
|
}
|
|
172
161
|
|
|
162
|
+
accept() {
|
|
163
|
+
this.dialog.returnValue = 'accept'
|
|
164
|
+
this.close()
|
|
165
|
+
}
|
|
166
|
+
|
|
173
167
|
waitForUser() {
|
|
174
168
|
return new Promise((resolve) => {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
(
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
169
|
+
const onClose = () => {
|
|
170
|
+
this._closing = false
|
|
171
|
+
if (this.dialog.returnValue === 'accept') {
|
|
172
|
+
const value = this.hasFormData ? this.collectFormData() : true
|
|
173
|
+
resolve(value)
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
const waitForClose = () => {
|
|
177
|
+
this.dialog.returnValue = undefined
|
|
178
|
+
this.dialog.addEventListener('close', () => onClose(), { once: true })
|
|
179
|
+
}
|
|
180
|
+
if (this._closing) {
|
|
181
|
+
// We are opening a new dialog while another is not fully closed,
|
|
182
|
+
// so let's first wait for that one to be fully closed
|
|
183
|
+
this.dialog.addEventListener('close', () => waitForClose(), { once: true })
|
|
184
|
+
} else {
|
|
185
|
+
waitForClose()
|
|
186
|
+
}
|
|
185
187
|
})
|
|
186
188
|
}
|
|
187
189
|
|
|
@@ -26,12 +26,12 @@ export class Panel {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
open({ content, className, highlight, actions = [] } = {}) {
|
|
29
|
+
let isOpen = false
|
|
29
30
|
if (this.isOpen()) {
|
|
31
|
+
isOpen = true
|
|
30
32
|
this.onClose()
|
|
31
33
|
}
|
|
32
|
-
this.container.className = `with-transition panel window ${this.className} ${
|
|
33
|
-
this.mode || ''
|
|
34
|
-
}`
|
|
34
|
+
this.container.className = `with-transition panel window ${this.className} ${this.mode || ''} ${isOpen ? 'on' : ''}`
|
|
35
35
|
if (highlight) {
|
|
36
36
|
this.container.dataset.highlight = highlight
|
|
37
37
|
}
|
|
@@ -56,8 +56,22 @@ export class Panel {
|
|
|
56
56
|
}
|
|
57
57
|
if (className) DomUtil.addClass(body, className)
|
|
58
58
|
const promise = new Promise((resolve, reject) => {
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
if (isOpen) {
|
|
60
|
+
resolve(this)
|
|
61
|
+
} else {
|
|
62
|
+
Promise.all(
|
|
63
|
+
this.container.getAnimations().map((animation) => animation.finished)
|
|
64
|
+
)
|
|
65
|
+
.then(() => {
|
|
66
|
+
resolve(this)
|
|
67
|
+
})
|
|
68
|
+
.catch(() => {
|
|
69
|
+
// Panel has been removed, so the DOM has changed, so the animations
|
|
70
|
+
// were cancelled, we want the new panel callabck to be called anyway.
|
|
71
|
+
resolve(this)
|
|
72
|
+
})
|
|
73
|
+
this.container.classList.add('on')
|
|
74
|
+
}
|
|
61
75
|
})
|
|
62
76
|
DomEvent.on(closeButton, 'click', this.close, this)
|
|
63
77
|
DomEvent.on(resizeButton, 'click', this.resize, this)
|
|
@@ -83,8 +97,8 @@ export class Panel {
|
|
|
83
97
|
}
|
|
84
98
|
|
|
85
99
|
onClose() {
|
|
86
|
-
if (
|
|
87
|
-
|
|
100
|
+
if (this.container.classList.contains('on')) {
|
|
101
|
+
this.container.classList.remove('on')
|
|
88
102
|
this._leafletMap.invalidateSize({ pan: false })
|
|
89
103
|
}
|
|
90
104
|
}
|
|
@@ -4,11 +4,10 @@ import * as Utils from '../utils.js'
|
|
|
4
4
|
import { Positioned } from './base.js'
|
|
5
5
|
|
|
6
6
|
export default class Tooltip extends Positioned {
|
|
7
|
-
constructor(
|
|
7
|
+
constructor() {
|
|
8
8
|
super()
|
|
9
|
-
this.parent =
|
|
9
|
+
this.parent = document.body
|
|
10
10
|
this.container = Utils.loadTemplate('<div class="umap-tooltip-container"></div>')
|
|
11
|
-
this.parent.appendChild(this.container)
|
|
12
11
|
DomEvent.disableClickPropagation(this.container)
|
|
13
12
|
this.container.addEventListener('contextmenu', (event) => event.stopPropagation()) // Do not activate our custom context menu.
|
|
14
13
|
this.container.addEventListener('wheel', (event) => event.stopPropagation())
|
|
@@ -25,7 +24,7 @@ export default class Tooltip extends Positioned {
|
|
|
25
24
|
} else {
|
|
26
25
|
this.container.innerHTML = Utils.escapeHTML(opts.content)
|
|
27
26
|
}
|
|
28
|
-
this.parent.
|
|
27
|
+
this.parent.appendChild(this.container)
|
|
29
28
|
this.openAt(opts)
|
|
30
29
|
}
|
|
31
30
|
this.TOOLTIP_ID = window.setTimeout(L.bind(showIt, this), opts.delay || 0)
|
|
@@ -49,6 +48,8 @@ export default class Tooltip extends Positioned {
|
|
|
49
48
|
this.toggleClassPosition()
|
|
50
49
|
this.container.innerHTML = ''
|
|
51
50
|
this.setPosition({})
|
|
52
|
-
this.parent.
|
|
51
|
+
if (this.parent.contains(this.container)) {
|
|
52
|
+
this.parent.removeChild(this.container)
|
|
53
|
+
}
|
|
53
54
|
}
|
|
54
55
|
}
|