umap-project 2.5.1__py3-none-any.whl → 2.6.0__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.

Files changed (276) hide show
  1. umap/__init__.py +1 -1
  2. umap/admin.py +6 -1
  3. umap/context_processors.py +2 -1
  4. umap/decorators.py +13 -2
  5. umap/forms.py +26 -2
  6. umap/locale/br/LC_MESSAGES/django.mo +0 -0
  7. umap/locale/br/LC_MESSAGES/django.po +252 -146
  8. umap/locale/ca/LC_MESSAGES/django.mo +0 -0
  9. umap/locale/ca/LC_MESSAGES/django.po +274 -162
  10. umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
  11. umap/locale/cs_CZ/LC_MESSAGES/django.po +261 -150
  12. umap/locale/de/LC_MESSAGES/django.mo +0 -0
  13. umap/locale/de/LC_MESSAGES/django.po +299 -187
  14. umap/locale/el/LC_MESSAGES/django.mo +0 -0
  15. umap/locale/el/LC_MESSAGES/django.po +215 -159
  16. umap/locale/en/LC_MESSAGES/django.po +211 -155
  17. umap/locale/es/LC_MESSAGES/django.mo +0 -0
  18. umap/locale/es/LC_MESSAGES/django.po +255 -144
  19. umap/locale/eu/LC_MESSAGES/django.mo +0 -0
  20. umap/locale/eu/LC_MESSAGES/django.po +254 -198
  21. umap/locale/fa_IR/LC_MESSAGES/django.mo +0 -0
  22. umap/locale/fa_IR/LC_MESSAGES/django.po +347 -235
  23. umap/locale/fr/LC_MESSAGES/django.mo +0 -0
  24. umap/locale/fr/LC_MESSAGES/django.po +216 -160
  25. umap/locale/hu/LC_MESSAGES/django.mo +0 -0
  26. umap/locale/hu/LC_MESSAGES/django.po +215 -159
  27. umap/locale/it/LC_MESSAGES/django.mo +0 -0
  28. umap/locale/it/LC_MESSAGES/django.po +252 -146
  29. umap/locale/ms/LC_MESSAGES/django.mo +0 -0
  30. umap/locale/ms/LC_MESSAGES/django.po +252 -146
  31. umap/locale/pl/LC_MESSAGES/django.mo +0 -0
  32. umap/locale/pl/LC_MESSAGES/django.po +254 -148
  33. umap/locale/pt/LC_MESSAGES/django.mo +0 -0
  34. umap/locale/pt/LC_MESSAGES/django.po +215 -159
  35. umap/locale/sv/LC_MESSAGES/django.mo +0 -0
  36. umap/locale/sv/LC_MESSAGES/django.po +254 -143
  37. umap/locale/th_TH/LC_MESSAGES/django.mo +0 -0
  38. umap/locale/th_TH/LC_MESSAGES/django.po +125 -70
  39. umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
  40. umap/locale/zh_TW/LC_MESSAGES/django.po +256 -145
  41. umap/migrations/0022_add_team.py +94 -0
  42. umap/models.py +45 -10
  43. umap/settings/__init__.py +2 -0
  44. umap/settings/base.py +9 -2
  45. umap/static/umap/base.css +32 -41
  46. umap/static/umap/content.css +19 -25
  47. umap/static/umap/css/icon.css +63 -37
  48. umap/static/umap/css/importers.css +1 -1
  49. umap/static/umap/css/slideshow.css +7 -5
  50. umap/static/umap/css/tableeditor.css +4 -3
  51. umap/static/umap/img/16-white.svg +1 -4
  52. umap/static/umap/img/16.svg +2 -6
  53. umap/static/umap/img/24-white.svg +4 -4
  54. umap/static/umap/img/24.svg +6 -6
  55. umap/static/umap/img/source/16-white.svg +2 -5
  56. umap/static/umap/img/source/16.svg +3 -7
  57. umap/static/umap/img/source/24-white.svg +7 -14
  58. umap/static/umap/img/source/24.svg +10 -17
  59. umap/static/umap/js/components/alerts/alert.css +20 -8
  60. umap/static/umap/js/modules/autocomplete.js +8 -12
  61. umap/static/umap/js/modules/browser.js +4 -3
  62. umap/static/umap/js/modules/caption.js +9 -11
  63. umap/static/umap/js/modules/data/features.js +993 -0
  64. umap/static/umap/js/modules/data/layer.js +1210 -0
  65. umap/static/umap/js/modules/formatter.js +12 -3
  66. umap/static/umap/js/modules/global.js +21 -5
  67. umap/static/umap/js/modules/importers/overpass.js +22 -8
  68. umap/static/umap/js/modules/permissions.js +280 -0
  69. umap/static/umap/js/{umap.icon.js → modules/rendering/icon.js} +77 -56
  70. umap/static/umap/js/modules/rendering/layers/base.js +105 -0
  71. umap/static/umap/js/modules/rendering/layers/classified.js +484 -0
  72. umap/static/umap/js/modules/rendering/layers/cluster.js +103 -0
  73. umap/static/umap/js/modules/rendering/layers/heat.js +182 -0
  74. umap/static/umap/js/modules/rendering/popup.js +99 -0
  75. umap/static/umap/js/modules/rendering/template.js +217 -0
  76. umap/static/umap/js/modules/rendering/ui.js +610 -0
  77. umap/static/umap/js/modules/rules.js +16 -3
  78. umap/static/umap/js/modules/schema.js +25 -1
  79. umap/static/umap/js/modules/share.js +66 -45
  80. umap/static/umap/js/modules/sync/updaters.js +9 -10
  81. umap/static/umap/js/modules/tableeditor.js +7 -7
  82. umap/static/umap/js/modules/ui/dialog.js +8 -4
  83. umap/static/umap/js/modules/utils.js +22 -13
  84. umap/static/umap/js/umap.controls.js +80 -146
  85. umap/static/umap/js/umap.core.js +9 -9
  86. umap/static/umap/js/umap.forms.js +41 -17
  87. umap/static/umap/js/umap.js +72 -65
  88. umap/static/umap/locale/am_ET.js +8 -2
  89. umap/static/umap/locale/am_ET.json +8 -2
  90. umap/static/umap/locale/ar.js +8 -2
  91. umap/static/umap/locale/ar.json +8 -2
  92. umap/static/umap/locale/ast.js +8 -2
  93. umap/static/umap/locale/ast.json +8 -2
  94. umap/static/umap/locale/bg.js +8 -2
  95. umap/static/umap/locale/bg.json +8 -2
  96. umap/static/umap/locale/br.js +42 -36
  97. umap/static/umap/locale/br.json +42 -36
  98. umap/static/umap/locale/ca.js +67 -61
  99. umap/static/umap/locale/ca.json +67 -61
  100. umap/static/umap/locale/cs_CZ.js +8 -2
  101. umap/static/umap/locale/cs_CZ.json +8 -2
  102. umap/static/umap/locale/da.js +8 -2
  103. umap/static/umap/locale/da.json +8 -2
  104. umap/static/umap/locale/de.js +143 -137
  105. umap/static/umap/locale/de.json +143 -137
  106. umap/static/umap/locale/el.js +54 -48
  107. umap/static/umap/locale/el.json +54 -48
  108. umap/static/umap/locale/en.js +10 -2
  109. umap/static/umap/locale/en.json +10 -2
  110. umap/static/umap/locale/en_US.json +8 -2
  111. umap/static/umap/locale/es.js +8 -2
  112. umap/static/umap/locale/es.json +8 -2
  113. umap/static/umap/locale/et.js +8 -2
  114. umap/static/umap/locale/et.json +8 -2
  115. umap/static/umap/locale/eu.js +346 -338
  116. umap/static/umap/locale/eu.json +346 -338
  117. umap/static/umap/locale/fa_IR.js +415 -407
  118. umap/static/umap/locale/fa_IR.json +415 -407
  119. umap/static/umap/locale/fi.js +8 -2
  120. umap/static/umap/locale/fi.json +8 -2
  121. umap/static/umap/locale/fr.js +11 -3
  122. umap/static/umap/locale/fr.json +11 -3
  123. umap/static/umap/locale/gl.js +8 -2
  124. umap/static/umap/locale/gl.json +8 -2
  125. umap/static/umap/locale/he.js +8 -2
  126. umap/static/umap/locale/he.json +8 -2
  127. umap/static/umap/locale/hr.js +8 -2
  128. umap/static/umap/locale/hr.json +8 -2
  129. umap/static/umap/locale/hu.js +31 -23
  130. umap/static/umap/locale/hu.json +31 -23
  131. umap/static/umap/locale/id.js +8 -2
  132. umap/static/umap/locale/id.json +8 -2
  133. umap/static/umap/locale/is.js +8 -2
  134. umap/static/umap/locale/is.json +8 -2
  135. umap/static/umap/locale/it.js +8 -2
  136. umap/static/umap/locale/it.json +8 -2
  137. umap/static/umap/locale/ja.js +8 -2
  138. umap/static/umap/locale/ja.json +8 -2
  139. umap/static/umap/locale/ko.js +8 -2
  140. umap/static/umap/locale/ko.json +8 -2
  141. umap/static/umap/locale/lt.js +8 -2
  142. umap/static/umap/locale/lt.json +8 -2
  143. umap/static/umap/locale/ms.js +8 -2
  144. umap/static/umap/locale/ms.json +8 -2
  145. umap/static/umap/locale/nl.js +8 -2
  146. umap/static/umap/locale/nl.json +8 -2
  147. umap/static/umap/locale/no.js +8 -2
  148. umap/static/umap/locale/no.json +8 -2
  149. umap/static/umap/locale/pl.js +54 -48
  150. umap/static/umap/locale/pl.json +54 -48
  151. umap/static/umap/locale/pl_PL.json +8 -2
  152. umap/static/umap/locale/pt.js +24 -18
  153. umap/static/umap/locale/pt.json +24 -18
  154. umap/static/umap/locale/pt_BR.js +8 -2
  155. umap/static/umap/locale/pt_BR.json +8 -2
  156. umap/static/umap/locale/pt_PT.js +214 -208
  157. umap/static/umap/locale/pt_PT.json +214 -208
  158. umap/static/umap/locale/ro.js +8 -2
  159. umap/static/umap/locale/ro.json +8 -2
  160. umap/static/umap/locale/ru.js +8 -2
  161. umap/static/umap/locale/ru.json +8 -2
  162. umap/static/umap/locale/sk_SK.js +8 -2
  163. umap/static/umap/locale/sk_SK.json +8 -2
  164. umap/static/umap/locale/sl.js +8 -2
  165. umap/static/umap/locale/sl.json +8 -2
  166. umap/static/umap/locale/sr.js +8 -2
  167. umap/static/umap/locale/sr.json +8 -2
  168. umap/static/umap/locale/sv.js +8 -2
  169. umap/static/umap/locale/sv.json +8 -2
  170. umap/static/umap/locale/th_TH.js +33 -27
  171. umap/static/umap/locale/th_TH.json +33 -27
  172. umap/static/umap/locale/tr.js +8 -2
  173. umap/static/umap/locale/tr.json +8 -2
  174. umap/static/umap/locale/uk_UA.js +8 -2
  175. umap/static/umap/locale/uk_UA.json +8 -2
  176. umap/static/umap/locale/vi.js +8 -2
  177. umap/static/umap/locale/vi.json +8 -2
  178. umap/static/umap/locale/vi_VN.json +8 -2
  179. umap/static/umap/locale/zh.js +8 -2
  180. umap/static/umap/locale/zh.json +8 -2
  181. umap/static/umap/locale/zh_CN.json +8 -2
  182. umap/static/umap/locale/zh_TW.Big5.json +8 -2
  183. umap/static/umap/locale/zh_TW.js +102 -96
  184. umap/static/umap/locale/zh_TW.json +102 -96
  185. umap/static/umap/map.css +111 -108
  186. umap/static/umap/nav.css +19 -10
  187. umap/static/umap/unittests/utils.js +230 -107
  188. umap/static/umap/vars.css +1 -0
  189. umap/static/umap/vendors/csv2geojson/csv2geojson.js +62 -40
  190. umap/static/umap/vendors/editable/Leaflet.Editable.js +2079 -1937
  191. umap/storage.py +1 -0
  192. umap/templates/404.html +5 -1
  193. umap/templates/500.html +3 -1
  194. umap/templates/auth/user_detail.html +8 -2
  195. umap/templates/auth/user_form.html +19 -10
  196. umap/templates/auth/user_stars.html +8 -2
  197. umap/templates/base.html +1 -0
  198. umap/templates/registration/login.html +18 -3
  199. umap/templates/umap/about.html +1 -0
  200. umap/templates/umap/about_summary.html +22 -7
  201. umap/templates/umap/components/alerts/alert.html +42 -21
  202. umap/templates/umap/content.html +2 -0
  203. umap/templates/umap/content_footer.html +7 -3
  204. umap/templates/umap/css.html +1 -0
  205. umap/templates/umap/dashboard_menu.html +15 -0
  206. umap/templates/umap/home.html +14 -4
  207. umap/templates/umap/js.html +4 -9
  208. umap/templates/umap/login_popup_end.html +10 -4
  209. umap/templates/umap/map_detail.html +8 -2
  210. umap/templates/umap/map_fragment.html +3 -1
  211. umap/templates/umap/map_init.html +2 -1
  212. umap/templates/umap/map_list.html +6 -3
  213. umap/templates/umap/map_table.html +36 -12
  214. umap/templates/umap/messages.html +0 -1
  215. umap/templates/umap/navigation.html +2 -1
  216. umap/templates/umap/password_change.html +5 -1
  217. umap/templates/umap/password_change_done.html +8 -2
  218. umap/templates/umap/search.html +8 -2
  219. umap/templates/umap/search_bar.html +1 -0
  220. umap/templates/umap/team_confirm_delete.html +19 -0
  221. umap/templates/umap/team_detail.html +27 -0
  222. umap/templates/umap/team_form.html +60 -0
  223. umap/templates/umap/user_dashboard.html +7 -9
  224. umap/templates/umap/user_teams.html +51 -0
  225. umap/tests/base.py +8 -1
  226. umap/tests/conftest.py +6 -0
  227. umap/tests/fixtures/test_circles_layer.geojson +219 -0
  228. umap/tests/fixtures/test_upload_georss.xml +20 -0
  229. umap/tests/integration/conftest.py +18 -4
  230. umap/tests/integration/helpers.py +12 -0
  231. umap/tests/integration/test_anonymous_owned_map.py +23 -0
  232. umap/tests/integration/test_basics.py +29 -0
  233. umap/tests/integration/test_browser.py +20 -0
  234. umap/tests/integration/test_caption.py +20 -0
  235. umap/tests/integration/test_circles_layer.py +69 -0
  236. umap/tests/integration/test_conditional_rules.py +102 -17
  237. umap/tests/integration/test_draw_polygon.py +138 -13
  238. umap/tests/integration/test_draw_polyline.py +8 -18
  239. umap/tests/integration/test_edit_datalayer.py +3 -3
  240. umap/tests/integration/test_import.py +124 -5
  241. umap/tests/integration/test_owned_map.py +21 -13
  242. umap/tests/integration/test_querystring.py +7 -0
  243. umap/tests/integration/test_team.py +47 -0
  244. umap/tests/integration/test_tilelayer.py +19 -2
  245. umap/tests/integration/test_view_marker.py +28 -1
  246. umap/tests/integration/test_websocket_sync.py +5 -5
  247. umap/tests/test_datalayer.py +32 -7
  248. umap/tests/test_datalayer_views.py +1 -1
  249. umap/tests/test_map.py +30 -4
  250. umap/tests/test_map_views.py +2 -2
  251. umap/tests/test_statics.py +40 -0
  252. umap/tests/test_team_views.py +131 -0
  253. umap/tests/test_views.py +15 -1
  254. umap/urls.py +23 -13
  255. umap/views.py +116 -10
  256. {umap_project-2.5.1.dist-info → umap_project-2.6.0.dist-info}/METADATA +14 -14
  257. {umap_project-2.5.1.dist-info → umap_project-2.6.0.dist-info}/RECORD +260 -253
  258. umap/static/umap/js/umap.datalayer.permissions.js +0 -70
  259. umap/static/umap/js/umap.features.js +0 -1290
  260. umap/static/umap/js/umap.layer.js +0 -1837
  261. umap/static/umap/js/umap.permissions.js +0 -208
  262. umap/static/umap/js/umap.popup.js +0 -341
  263. umap/static/umap/test/TableEditor.js +0 -104
  264. umap/static/umap/vendors/leaflet/leaflet-src.js +0 -14512
  265. umap/static/umap/vendors/leaflet/leaflet-src.js.map +0 -1
  266. umap/static/umap/vendors/leaflet/leaflet.js +0 -6
  267. umap/static/umap/vendors/leaflet/leaflet.js.map +0 -1
  268. umap/static/umap/vendors/markercluster/WhereAreTheJavascriptFiles.txt +0 -5
  269. umap/static/umap/vendors/markercluster/leaflet.markercluster-src.js +0 -2718
  270. umap/static/umap/vendors/markercluster/leaflet.markercluster-src.js.map +0 -1
  271. umap/static/umap/vendors/toolbar/leaflet.toolbar-src.css +0 -117
  272. umap/static/umap/vendors/toolbar/leaflet.toolbar-src.js +0 -365
  273. umap/tests/integration/test_statics.py +0 -47
  274. {umap_project-2.5.1.dist-info → umap_project-2.6.0.dist-info}/WHEEL +0 -0
  275. {umap_project-2.5.1.dist-info → umap_project-2.6.0.dist-info}/entry_points.txt +0 -0
  276. {umap_project-2.5.1.dist-info → umap_project-2.6.0.dist-info}/licenses/LICENSE +0 -0
@@ -142,7 +142,7 @@ U.AddPolylineShapeAction = U.BaseAction.extend({
142
142
  },
143
143
 
144
144
  addHooks: function () {
145
- this.map.editedFeature.editor.newShape()
145
+ this.map.editedFeature.ui.editor.newShape()
146
146
  },
147
147
  })
148
148
 
@@ -182,8 +182,8 @@ U.CreateHoleAction = U.BaseFeatureAction.extend({
182
182
  },
183
183
  },
184
184
 
185
- onClick: function (e) {
186
- this.feature.startHole(e)
185
+ onClick: function (event) {
186
+ this.feature.ui.startHole(event)
187
187
  },
188
188
  })
189
189
 
@@ -195,11 +195,11 @@ U.ToggleEditAction = U.BaseFeatureAction.extend({
195
195
  },
196
196
  },
197
197
 
198
- onClick: function (e) {
198
+ onClick: function (event) {
199
199
  if (this.feature._toggleEditing) {
200
- this.feature._toggleEditing(e) // Path
200
+ this.feature._toggleEditing(event) // Path
201
201
  } else {
202
- this.feature.edit(e) // Marker
202
+ this.feature.edit(event) // Marker
203
203
  }
204
204
  },
205
205
  })
@@ -244,7 +244,7 @@ U.ExtractShapeFromMultiAction = U.BaseFeatureAction.extend({
244
244
  },
245
245
 
246
246
  onClick: function (e) {
247
- this.feature.isolateShape(e.latlng)
247
+ this.feature.ui.isolateShape(e.latlng)
248
248
  },
249
249
  })
250
250
 
@@ -310,7 +310,7 @@ U.DrawToolbar = L.Toolbar.Control.extend({
310
310
  }
311
311
  if (this.map.options.enablePolylineDraw) {
312
312
  this.options.actions.push(U.DrawPolylineAction)
313
- if (this.map.editedFeature && this.map.editedFeature instanceof U.Polyline) {
313
+ if (this.map.editedFeature && this.map.editedFeature instanceof U.LineString) {
314
314
  this.options.actions.push(U.AddPolylineShapeAction)
315
315
  }
316
316
  }
@@ -562,107 +562,6 @@ L.Control.Embed = L.Control.Button.extend({
562
562
  },
563
563
  })
564
564
 
565
- U.DataLayer.include({
566
- renderLegend: function (container) {
567
- if (this.layer.renderLegend) return this.layer.renderLegend(container)
568
- const color = L.DomUtil.create('span', 'datalayer-color', container)
569
- color.style.backgroundColor = this.getColor()
570
- },
571
-
572
- renderToolbox: function (container) {
573
- const toggle = L.DomUtil.createButtonIcon(
574
- container,
575
- 'icon-eye',
576
- L._('Show/hide layer')
577
- )
578
- const zoomTo = L.DomUtil.createButtonIcon(
579
- container,
580
- 'icon-zoom',
581
- L._('Zoom to layer extent')
582
- )
583
- const edit = L.DomUtil.createButtonIcon(
584
- container,
585
- 'icon-edit show-on-edit',
586
- L._('Edit')
587
- )
588
- const table = L.DomUtil.createButtonIcon(
589
- container,
590
- 'icon-table show-on-edit',
591
- L._('Edit properties in a table')
592
- )
593
- const remove = L.DomUtil.createButtonIcon(
594
- container,
595
- 'icon-delete show-on-edit',
596
- L._('Delete layer')
597
- )
598
- if (this.isReadOnly()) {
599
- L.DomUtil.addClass(container, 'readonly')
600
- } else {
601
- L.DomEvent.on(edit, 'click', this.edit, this)
602
- L.DomEvent.on(table, 'click', this.tableEdit, this)
603
- L.DomEvent.on(
604
- remove,
605
- 'click',
606
- function () {
607
- if (!this.isVisible()) return
608
- if (!confirm(L._('Are you sure you want to delete this layer?'))) return
609
- this._delete()
610
- },
611
- this
612
- )
613
- }
614
- L.DomEvent.on(toggle, 'click', this.toggle, this)
615
- L.DomEvent.on(zoomTo, 'click', this.zoomTo, this)
616
- container.classList.add(this.getHidableClass())
617
- container.classList.toggle('off', !this.isVisible())
618
- },
619
-
620
- getHidableElements: function () {
621
- return document.querySelectorAll(`.${this.getHidableClass()}`)
622
- },
623
-
624
- getHidableClass: function () {
625
- return `show_with_datalayer_${L.stamp(this)}`
626
- },
627
-
628
- propagateDelete: function () {
629
- const els = this.getHidableElements()
630
- for (const el of els) {
631
- L.DomUtil.remove(el)
632
- }
633
- },
634
-
635
- propagateRemote: function () {
636
- const els = this.getHidableElements()
637
- for (const el of els) {
638
- el.classList.toggle('remotelayer', this.isRemoteLayer())
639
- }
640
- },
641
-
642
- propagateHide: function () {
643
- const els = this.getHidableElements()
644
- for (let i = 0; i < els.length; i++) {
645
- L.DomUtil.addClass(els[i], 'off')
646
- }
647
- },
648
-
649
- propagateShow: function () {
650
- this.onceLoaded(function () {
651
- const els = this.getHidableElements()
652
- for (let i = 0; i < els.length; i++) {
653
- L.DomUtil.removeClass(els[i], 'off')
654
- }
655
- }, this)
656
- },
657
- })
658
-
659
- U.DataLayer.addInitHook(function () {
660
- this.on('hide', this.propagateHide)
661
- this.on('show', this.propagateShow)
662
- this.on('erase', this.propagateDelete)
663
- if (this.isVisible()) this.propagateShow()
664
- })
665
-
666
565
  const ControlsMixin = {
667
566
  HIDDABLE_CONTROLS: [
668
567
  'zoom',
@@ -741,7 +640,7 @@ const ControlsMixin = {
741
640
  L.DomEvent.on(shareStatusButton, 'click', this.permissions.edit, this.permissions)
742
641
  }
743
642
  this.on('postsync', L.bind(update, this))
744
- if (this.options.user) {
643
+ if (this.options.user?.id) {
745
644
  L.DomUtil.createLink(
746
645
  'umap-user',
747
646
  rightContainer,
@@ -864,6 +763,7 @@ const ControlsMixin = {
864
763
  U.TileLayerControl = L.Control.IconLayers.extend({
865
764
  initialize: function (map, options) {
866
765
  this.map = map
766
+ this.maxShown = 9
867
767
  L.Control.IconLayers.prototype.initialize.call(this, {
868
768
  position: 'topleft',
869
769
  manageLayers: false,
@@ -895,10 +795,27 @@ U.TileLayerControl = L.Control.IconLayers.extend({
895
795
  }
896
796
  })
897
797
  }
898
- const maxShown = 10
899
- L.Control.IconLayers.prototype.setLayers.call(this, layers.slice(0, maxShown))
798
+ this._allLayers = layers
799
+ L.Control.IconLayers.prototype.setLayers.call(this, layers.slice(0, this.maxShown))
900
800
  if (this.map.selected_tilelayer) this.setActiveLayer(this.map.selected_tilelayer)
901
801
  },
802
+
803
+ _createLayerElements: function () {
804
+ L.Control.IconLayers.prototype._createLayerElements.call(this)
805
+ if (Object.keys(this._allLayers).length <= this.maxShown) return
806
+ const lastRow = this._container.querySelector(
807
+ '.leaflet-iconLayers-layersRow:last-child'
808
+ )
809
+ const button = L.DomUtil.element({
810
+ tagName: 'button',
811
+ className: 'leaflet-iconLayers-layerCell leaflet-iconLayers-layerCell-plus button',
812
+ textContent: '+',
813
+ parent: lastRow,
814
+ })
815
+ L.DomEvent.on(button, 'click', () =>
816
+ this.map._controls.tilelayersChooser.openSwitcher()
817
+ )
818
+ },
902
819
  })
903
820
 
904
821
  /* Used in edit mode to define the default tilelayer */
@@ -907,7 +824,7 @@ U.TileLayerChooser = L.Control.extend({
907
824
  position: 'topleft',
908
825
  },
909
826
 
910
- initialize: function (map, options) {
827
+ initialize: function (map, options = {}) {
911
828
  this.map = map
912
829
  L.Control.prototype.initialize.call(this, options)
913
830
  },
@@ -925,15 +842,13 @@ U.TileLayerChooser = L.Control.extend({
925
842
  return container
926
843
  },
927
844
 
928
- openSwitcher: function (options) {
845
+ openSwitcher: function (options = {}) {
929
846
  const container = L.DomUtil.create('div', 'umap-tilelayer-switcher-container')
930
847
  L.DomUtil.createTitle(container, L._('Change tilelayers'), 'icon-tilelayer')
931
848
  this._tilelayers_container = L.DomUtil.create('ul', '', container)
932
849
  this.buildList(options)
933
- this.map.editPanel.open({
934
- content: container,
935
- className: options.className,
936
- })
850
+ const panel = options.edit ? this.map.editPanel : this.map.panel
851
+ panel.open({ content: container })
937
852
  },
938
853
 
939
854
  buildList: function (options) {
@@ -1123,7 +1038,7 @@ U.Search = L.PhotonSearch.extend({
1123
1038
  L.DomEvent.on(edit, 'mousedown', (e) => {
1124
1039
  L.DomEvent.stop(e)
1125
1040
  const datalayer = this.map.defaultEditDataLayer()
1126
- const layer = datalayer.geojsonToFeatures(feature)
1041
+ const layer = datalayer.makeFeature(feature)
1127
1042
  layer.isDirty = true
1128
1043
  layer.edit()
1129
1044
  })
@@ -1246,56 +1161,71 @@ U.Editable = L.Editable.extend({
1246
1161
  initialize: function (map, options) {
1247
1162
  L.Editable.prototype.initialize.call(this, map, options)
1248
1163
  this.on('editable:drawing:click editable:drawing:move', this.drawingTooltip)
1249
- this.on('editable:drawing:end', (e) => {
1164
+ this.on('editable:drawing:end', (event) => {
1250
1165
  this.map.tooltip.close()
1251
1166
  // Leaflet.Editable will delete the drawn shape if invalid
1252
1167
  // (eg. line has only one drawn point)
1253
1168
  // So let's check if the layer has no more shape
1254
- if (!e.layer.hasGeom()) e.layer.del()
1255
- else e.layer.edit()
1169
+ if (!event.layer.feature.hasGeom()) {
1170
+ event.layer.feature.del()
1171
+ } else {
1172
+ event.layer.feature.edit()
1173
+ }
1256
1174
  })
1257
1175
  // Layer for items added by users
1258
- this.on('editable:drawing:cancel', (e) => {
1259
- if (e.layer instanceof U.Marker) e.layer.del()
1176
+ this.on('editable:drawing:cancel', (event) => {
1177
+ if (event.layer instanceof U.LeafletMarker) event.layer.feature.del()
1260
1178
  })
1261
- this.on('editable:drawing:commit', function (e) {
1262
- e.layer.isDirty = true
1263
- if (this.map.editedFeature !== e.layer) e.layer.edit(e)
1179
+ this.on('editable:drawing:commit', function (event) {
1180
+ event.layer.feature.isDirty = true
1181
+ if (this.map.editedFeature !== event.layer) event.layer.feature.edit(event)
1264
1182
  })
1265
- this.on('editable:editing', (e) => {
1266
- const layer = e.layer
1267
- layer.isDirty = true
1268
- if (layer._tooltip && layer.isTooltipOpen()) {
1269
- layer._tooltip.setLatLng(layer.getCenter())
1270
- layer._tooltip.update()
1271
- }
1183
+ this.on('editable:editing', (event) => {
1184
+ const layer = event.layer
1185
+ layer.feature.isDirty = true
1186
+ layer.feature.fromLatLngs(layer.getLatLngs())
1272
1187
  })
1273
- this.on('editable:vertex:ctrlclick', (e) => {
1274
- const index = e.vertex.getIndex()
1275
- if (index === 0 || (index === e.vertex.getLastIndex() && e.vertex.continue))
1276
- e.vertex.continue()
1188
+ this.on('editable:vertex:ctrlclick', (event) => {
1189
+ const index = event.vertex.getIndex()
1190
+ if (
1191
+ index === 0 ||
1192
+ (index === event.vertex.getLastIndex() && event.vertex.continue)
1193
+ )
1194
+ event.vertex.continue()
1277
1195
  })
1278
- this.on('editable:vertex:altclick', (e) => {
1279
- if (e.vertex.editor.vertexCanBeDeleted(e.vertex)) e.vertex.delete()
1196
+ this.on('editable:vertex:altclick', (event) => {
1197
+ if (event.vertex.editor.vertexCanBeDeleted(event.vertex)) event.vertex.delete()
1280
1198
  })
1281
1199
  this.on('editable:vertex:rawclick', this.onVertexRawClick)
1282
1200
  },
1283
1201
 
1284
1202
  createPolyline: function (latlngs) {
1285
- return new U.Polyline(this.map, latlngs, this._getDefaultProperties())
1203
+ const datalayer = this.map.defaultEditDataLayer()
1204
+ const point = new U.LineString(datalayer, {
1205
+ geometry: { type: 'LineString', coordinates: [] },
1206
+ })
1207
+ return point.ui
1286
1208
  },
1287
1209
 
1288
1210
  createPolygon: function (latlngs) {
1289
- return new U.Polygon(this.map, latlngs, this._getDefaultProperties())
1211
+ const datalayer = this.map.defaultEditDataLayer()
1212
+ const point = new U.Polygon(datalayer, {
1213
+ geometry: { type: 'Polygon', coordinates: [] },
1214
+ })
1215
+ return point.ui
1290
1216
  },
1291
1217
 
1292
1218
  createMarker: function (latlng) {
1293
- return new U.Marker(this.map, latlng, this._getDefaultProperties())
1219
+ const datalayer = this.map.defaultEditDataLayer()
1220
+ const point = new U.Point(datalayer, {
1221
+ geometry: { type: 'Point', coordinates: [latlng.lng, latlng.lat] },
1222
+ })
1223
+ return point.ui
1294
1224
  },
1295
1225
 
1296
1226
  _getDefaultProperties: function () {
1297
1227
  const result = {}
1298
- if (this.map.options.featuresHaveOwner && this.map.options.hasOwnProperty('user')) {
1228
+ if (this.map.options.featuresHaveOwner?.user) {
1299
1229
  result.geojson = { properties: { owner: this.map.options.user.id } }
1300
1230
  }
1301
1231
  return result
@@ -1304,7 +1234,7 @@ U.Editable = L.Editable.extend({
1304
1234
  connectCreatedToMap: function (layer) {
1305
1235
  // Overrided from Leaflet.Editable
1306
1236
  const datalayer = this.map.defaultEditDataLayer()
1307
- datalayer.addLayer(layer)
1237
+ datalayer.addFeature(layer.feature)
1308
1238
  layer.isDirty = true
1309
1239
  return layer
1310
1240
  },
@@ -1331,7 +1261,11 @@ U.Editable = L.Editable.extend({
1331
1261
  }
1332
1262
  } else {
1333
1263
  const tmpLatLngs = e.layer.editor._drawnLatLngs.slice()
1334
- tmpLatLngs.push(e.latlng)
1264
+ if (e.layer.editor._drawing === L.Editable.BACKWARD) {
1265
+ tmpLatLngs.unshift(e.latlng)
1266
+ } else {
1267
+ tmpLatLngs.push(e.latlng)
1268
+ }
1335
1269
  measure = e.layer.getMeasure(tmpLatLngs)
1336
1270
 
1337
1271
  if (e.layer.editor._drawnLatLngs.length < e.layer.editor.MIN_VERTEX) {
@@ -128,13 +128,17 @@ L.DomUtil.createIcon = (parent, className, title, size = 16) => {
128
128
  })
129
129
  }
130
130
 
131
- L.DomUtil.createButtonIcon = (parent, className, title, size = 16) => {
132
- return L.DomUtil.element({
131
+ L.DomUtil.createButtonIcon = (parent, className, title, callback, size = 16) => {
132
+ const el = L.DomUtil.element({
133
133
  tagName: 'button',
134
134
  parent: parent,
135
135
  className: `icon icon-${size} ${className}`,
136
136
  title: title || '',
137
137
  })
138
+ if (callback) {
139
+ L.DomEvent.on(el, 'click', L.DomEvent.stop).on(el, 'click', callback)
140
+ }
141
+ return el
138
142
  }
139
143
 
140
144
  L.DomUtil.createTitle = (parent, text, className, tag = 'h3') => {
@@ -151,14 +155,10 @@ L.DomUtil.createCopiableInput = (parent, label, value) => {
151
155
  input.type = 'text'
152
156
  input.readOnly = true
153
157
  input.value = value
154
- const button = L.DomUtil.createButton(
155
- '',
156
- wrapper,
157
- '',
158
- () => L.Util.copyToClipboard(input.value),
159
- this
158
+ const button = L.DomUtil.createButtonIcon(wrapper, 'icon-copy', L._('copy'), () =>
159
+ L.Util.copyToClipboard(input.value)
160
160
  )
161
- button.title = L._('copy')
161
+ button.type = 'button'
162
162
  return input
163
163
  }
164
164
 
@@ -220,9 +220,9 @@ L.FormBuilder.Element.include({
220
220
  if (this.options.label) {
221
221
  this.label = L.DomUtil.create('label', '', this.getLabelParent())
222
222
  this.label.textContent = this.label.title = this.options.label
223
- if (this.options.helpEntries)
223
+ if (this.options.helpEntries) {
224
224
  this.builder.map.help.button(this.label, this.options.helpEntries)
225
- else if (this.options.helpTooltip) {
225
+ } else if (this.options.helpTooltip) {
226
226
  const info = L.DomUtil.create('i', 'info', this.label)
227
227
  L.DomEvent.on(
228
228
  info,
@@ -342,14 +342,7 @@ L.FormBuilder.TextColorPicker = L.FormBuilder.ColorPicker.extend({
342
342
 
343
343
  L.FormBuilder.LayerTypeChooser = L.FormBuilder.Select.extend({
344
344
  getOptions: () => {
345
- const layer_classes = [
346
- U.Layer.Default,
347
- U.Layer.Cluster,
348
- U.Layer.Heat,
349
- U.Layer.Choropleth,
350
- U.Layer.Categorized,
351
- ]
352
- return layer_classes.map((class_) => [class_.TYPE, class_.NAME])
345
+ return U.LAYER_TYPES.map((class_) => [class_.TYPE, class_.NAME])
353
346
  },
354
347
  })
355
348
 
@@ -557,7 +550,7 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
557
550
  // Do not try to render URL with variables
558
551
  const box = L.DomUtil.create('div', 'umap-pictogram-choice', this.buttons)
559
552
  L.DomEvent.on(box, 'click', this.onDefine, this)
560
- const icon = U.Icon.makeIconElement(this.value(), box)
553
+ const icon = U.Icon.makeElement(this.value(), box)
561
554
  }
562
555
  this.button = L.DomUtil.createButton(
563
556
  'button action-button',
@@ -578,7 +571,7 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
578
571
  if (search && U.Utils.normalize(title).indexOf(search) === -1) return
579
572
  const className = value === this.value() ? `${baseClass} selected` : baseClass
580
573
  const container = L.DomUtil.create('div', className, parent)
581
- U.Icon.makeIconElement(value, container)
574
+ U.Icon.makeElement(value, container)
582
575
  container.title = title
583
576
  L.DomEvent.on(
584
577
  container,
@@ -909,8 +902,8 @@ L.FormBuilder.MultiChoice = L.FormBuilder.Element.extend({
909
902
  if (!this.container.querySelector(`input[type="radio"][value="${value}"]`)) {
910
903
  value = this.options.default !== undefined ? this.options.default : this.default
911
904
  }
912
- const choices = this.getChoices().map(([value, label]) => value)
913
- if (choices.includes(value)) {
905
+ const choices = this.getChoices().map(([value, label]) => `${value}`)
906
+ if (choices.includes(`${value}`)) {
914
907
  this.container.querySelector(`input[type="radio"][value="${value}"]`).checked =
915
908
  true
916
909
  }
@@ -932,8 +925,8 @@ L.FormBuilder.MultiChoice = L.FormBuilder.Element.extend({
932
925
  `${this.className} by${choices.length}`,
933
926
  this.parentNode
934
927
  )
935
- for (let i = 0; i < choices.length; i++) {
936
- this.addChoice(choices[i][0], choices[i][1], i)
928
+ for (const [i, [value, label]] of choices.entries()) {
929
+ this.addChoice(value, label, i)
937
930
  }
938
931
  this.fetch()
939
932
  },
@@ -965,8 +958,12 @@ L.FormBuilder.TernaryChoices = L.FormBuilder.MultiChoice.extend({
965
958
  case false:
966
959
  value = false
967
960
  break
968
- default:
961
+ case 'null':
962
+ case null:
969
963
  value = null
964
+ break
965
+ default:
966
+ value = undefined
970
967
  }
971
968
  return value
972
969
  },
@@ -1093,11 +1090,35 @@ L.FormBuilder.ManageEditors = L.FormBuilder.Element.extend({
1093
1090
  },
1094
1091
  })
1095
1092
 
1093
+ L.FormBuilder.ManageTeam = L.FormBuilder.IntSelect.extend({
1094
+ getOptions: function () {
1095
+ return [[null, L._('None')]].concat(
1096
+ this.options.teams.map((team) => [team.id, team.name])
1097
+ )
1098
+ },
1099
+ toHTML: function () {
1100
+ return this.get()?.id
1101
+ },
1102
+ toJS: function () {
1103
+ const value = this.value()
1104
+ for (const team of this.options.teams) {
1105
+ if (team.id === value) return team
1106
+ }
1107
+ },
1108
+ })
1109
+
1096
1110
  U.FormBuilder = L.FormBuilder.extend({
1097
1111
  options: {
1098
1112
  className: 'umap-form',
1099
1113
  },
1100
1114
 
1115
+ customHandlers: {
1116
+ sortKey: 'BlurInput',
1117
+ easing: 'Switch',
1118
+ facetKey: 'BlurInput',
1119
+ slugKey: 'BlurInput',
1120
+ },
1121
+
1101
1122
  computeDefaultOptions: function () {
1102
1123
  for (const [key, schema] of Object.entries(U.SCHEMA)) {
1103
1124
  if (schema.type === Boolean) {
@@ -1135,6 +1156,9 @@ U.FormBuilder = L.FormBuilder.extend({
1135
1156
  break
1136
1157
  }
1137
1158
  }
1159
+ if (this.customHandlers[key]) {
1160
+ schema.handler = this.customHandlers[key]
1161
+ }
1138
1162
  // FormBuilder use this key for the input type itself
1139
1163
  delete schema.type
1140
1164
  this.defaultOptions[key] = schema