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

Files changed (193) 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 +346 -234
  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 +3 -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 +3 -3
  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 +994 -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/permissions.js +280 -0
  68. umap/static/umap/js/{umap.icon.js → modules/rendering/icon.js} +77 -56
  69. umap/static/umap/js/modules/rendering/layers/base.js +105 -0
  70. umap/static/umap/js/modules/rendering/layers/classified.js +484 -0
  71. umap/static/umap/js/modules/rendering/layers/cluster.js +103 -0
  72. umap/static/umap/js/modules/rendering/layers/heat.js +182 -0
  73. umap/static/umap/js/modules/rendering/popup.js +99 -0
  74. umap/static/umap/js/modules/rendering/template.js +217 -0
  75. umap/static/umap/js/modules/rendering/ui.js +573 -0
  76. umap/static/umap/js/modules/schema.js +24 -0
  77. umap/static/umap/js/modules/share.js +66 -45
  78. umap/static/umap/js/modules/sync/updaters.js +9 -10
  79. umap/static/umap/js/modules/tableeditor.js +7 -7
  80. umap/static/umap/js/modules/ui/dialog.js +8 -4
  81. umap/static/umap/js/modules/utils.js +22 -13
  82. umap/static/umap/js/umap.controls.js +79 -146
  83. umap/static/umap/js/umap.core.js +9 -9
  84. umap/static/umap/js/umap.forms.js +32 -12
  85. umap/static/umap/js/umap.js +65 -63
  86. umap/static/umap/locale/br.js +35 -35
  87. umap/static/umap/locale/br.json +35 -35
  88. umap/static/umap/locale/ca.js +50 -50
  89. umap/static/umap/locale/ca.json +50 -50
  90. umap/static/umap/locale/de.js +136 -136
  91. umap/static/umap/locale/de.json +136 -136
  92. umap/static/umap/locale/el.js +47 -47
  93. umap/static/umap/locale/el.json +47 -47
  94. umap/static/umap/locale/en.js +7 -1
  95. umap/static/umap/locale/en.json +7 -1
  96. umap/static/umap/locale/fa_IR.js +44 -44
  97. umap/static/umap/locale/fa_IR.json +44 -44
  98. umap/static/umap/locale/fr.js +8 -2
  99. umap/static/umap/locale/fr.json +8 -2
  100. umap/static/umap/locale/pt.js +17 -17
  101. umap/static/umap/locale/pt.json +17 -17
  102. umap/static/umap/locale/pt_PT.js +207 -207
  103. umap/static/umap/locale/pt_PT.json +207 -207
  104. umap/static/umap/locale/th_TH.js +25 -25
  105. umap/static/umap/locale/th_TH.json +25 -25
  106. umap/static/umap/map.css +107 -104
  107. umap/static/umap/nav.css +19 -10
  108. umap/static/umap/unittests/utils.js +230 -107
  109. umap/static/umap/vendors/csv2geojson/csv2geojson.js +62 -40
  110. umap/static/umap/vendors/markercluster/MarkerCluster.Default.css +1 -1
  111. umap/storage.py +1 -0
  112. umap/templates/404.html +5 -1
  113. umap/templates/500.html +3 -1
  114. umap/templates/auth/user_detail.html +8 -2
  115. umap/templates/auth/user_form.html +19 -10
  116. umap/templates/auth/user_stars.html +8 -2
  117. umap/templates/base.html +1 -0
  118. umap/templates/registration/login.html +18 -3
  119. umap/templates/umap/about.html +1 -0
  120. umap/templates/umap/about_summary.html +22 -7
  121. umap/templates/umap/components/alerts/alert.html +42 -21
  122. umap/templates/umap/content.html +2 -0
  123. umap/templates/umap/content_footer.html +6 -2
  124. umap/templates/umap/css.html +1 -0
  125. umap/templates/umap/dashboard_menu.html +15 -0
  126. umap/templates/umap/home.html +14 -4
  127. umap/templates/umap/js.html +4 -9
  128. umap/templates/umap/login_popup_end.html +10 -4
  129. umap/templates/umap/map_detail.html +8 -2
  130. umap/templates/umap/map_fragment.html +3 -1
  131. umap/templates/umap/map_init.html +2 -1
  132. umap/templates/umap/map_list.html +4 -3
  133. umap/templates/umap/map_table.html +36 -12
  134. umap/templates/umap/messages.html +0 -1
  135. umap/templates/umap/navigation.html +2 -1
  136. umap/templates/umap/password_change.html +5 -1
  137. umap/templates/umap/password_change_done.html +8 -2
  138. umap/templates/umap/search.html +8 -2
  139. umap/templates/umap/search_bar.html +1 -0
  140. umap/templates/umap/team_confirm_delete.html +19 -0
  141. umap/templates/umap/team_detail.html +27 -0
  142. umap/templates/umap/team_form.html +60 -0
  143. umap/templates/umap/user_dashboard.html +7 -9
  144. umap/templates/umap/user_teams.html +51 -0
  145. umap/tests/base.py +8 -1
  146. umap/tests/conftest.py +6 -0
  147. umap/tests/fixtures/test_circles_layer.geojson +219 -0
  148. umap/tests/fixtures/test_upload_georss.xml +20 -0
  149. umap/tests/integration/conftest.py +18 -4
  150. umap/tests/integration/helpers.py +12 -0
  151. umap/tests/integration/test_anonymous_owned_map.py +23 -0
  152. umap/tests/integration/test_basics.py +29 -0
  153. umap/tests/integration/test_caption.py +20 -0
  154. umap/tests/integration/test_circles_layer.py +69 -0
  155. umap/tests/integration/test_draw_polygon.py +110 -13
  156. umap/tests/integration/test_draw_polyline.py +8 -18
  157. umap/tests/integration/test_edit_datalayer.py +1 -1
  158. umap/tests/integration/test_import.py +64 -5
  159. umap/tests/integration/test_owned_map.py +21 -13
  160. umap/tests/integration/test_team.py +47 -0
  161. umap/tests/integration/test_tilelayer.py +19 -2
  162. umap/tests/integration/test_view_marker.py +28 -1
  163. umap/tests/integration/test_websocket_sync.py +5 -5
  164. umap/tests/test_datalayer.py +32 -7
  165. umap/tests/test_datalayer_views.py +1 -1
  166. umap/tests/test_map.py +30 -4
  167. umap/tests/test_map_views.py +2 -2
  168. umap/tests/test_statics.py +40 -0
  169. umap/tests/test_team_views.py +131 -0
  170. umap/tests/test_views.py +15 -1
  171. umap/urls.py +23 -13
  172. umap/views.py +116 -10
  173. {umap_project-2.5.1.dist-info → umap_project-2.6.0b0.dist-info}/METADATA +9 -9
  174. {umap_project-2.5.1.dist-info → umap_project-2.6.0b0.dist-info}/RECORD +177 -170
  175. umap/static/umap/js/umap.datalayer.permissions.js +0 -70
  176. umap/static/umap/js/umap.features.js +0 -1290
  177. umap/static/umap/js/umap.layer.js +0 -1837
  178. umap/static/umap/js/umap.permissions.js +0 -208
  179. umap/static/umap/js/umap.popup.js +0 -341
  180. umap/static/umap/test/TableEditor.js +0 -104
  181. umap/static/umap/vendors/leaflet/leaflet-src.js +0 -14512
  182. umap/static/umap/vendors/leaflet/leaflet-src.js.map +0 -1
  183. umap/static/umap/vendors/leaflet/leaflet.js +0 -6
  184. umap/static/umap/vendors/leaflet/leaflet.js.map +0 -1
  185. umap/static/umap/vendors/markercluster/WhereAreTheJavascriptFiles.txt +0 -5
  186. umap/static/umap/vendors/markercluster/leaflet.markercluster-src.js +0 -2718
  187. umap/static/umap/vendors/markercluster/leaflet.markercluster-src.js.map +0 -1
  188. umap/static/umap/vendors/toolbar/leaflet.toolbar-src.css +0 -117
  189. umap/static/umap/vendors/toolbar/leaflet.toolbar-src.js +0 -365
  190. umap/tests/integration/test_statics.py +0 -47
  191. {umap_project-2.5.1.dist-info → umap_project-2.6.0b0.dist-info}/WHEEL +0 -0
  192. {umap_project-2.5.1.dist-info → umap_project-2.6.0b0.dist-info}/entry_points.txt +0 -0
  193. {umap_project-2.5.1.dist-info → umap_project-2.6.0b0.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,26 @@ 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
+ L.Control.IconLayers.prototype.setLayers.call(this, layers.slice(0, this.maxShown))
900
799
  if (this.map.selected_tilelayer) this.setActiveLayer(this.map.selected_tilelayer)
901
800
  },
801
+
802
+ _createLayerElements: function () {
803
+ L.Control.IconLayers.prototype._createLayerElements.call(this)
804
+ if (Object.keys(this._layers) <= this.maxShown) return
805
+ const lastRow = this._container.querySelector(
806
+ '.leaflet-iconLayers-layersRow:last-child'
807
+ )
808
+ const button = L.DomUtil.element({
809
+ tagName: 'button',
810
+ className: 'leaflet-iconLayers-layerCell leaflet-iconLayers-layerCell-plus button',
811
+ textContent: '+',
812
+ parent: lastRow,
813
+ })
814
+ L.DomEvent.on(button, 'click', () =>
815
+ this.map._controls.tilelayersChooser.openSwitcher()
816
+ )
817
+ },
902
818
  })
903
819
 
904
820
  /* Used in edit mode to define the default tilelayer */
@@ -907,7 +823,7 @@ U.TileLayerChooser = L.Control.extend({
907
823
  position: 'topleft',
908
824
  },
909
825
 
910
- initialize: function (map, options) {
826
+ initialize: function (map, options = {}) {
911
827
  this.map = map
912
828
  L.Control.prototype.initialize.call(this, options)
913
829
  },
@@ -925,15 +841,13 @@ U.TileLayerChooser = L.Control.extend({
925
841
  return container
926
842
  },
927
843
 
928
- openSwitcher: function (options) {
844
+ openSwitcher: function (options = {}) {
929
845
  const container = L.DomUtil.create('div', 'umap-tilelayer-switcher-container')
930
846
  L.DomUtil.createTitle(container, L._('Change tilelayers'), 'icon-tilelayer')
931
847
  this._tilelayers_container = L.DomUtil.create('ul', '', container)
932
848
  this.buildList(options)
933
- this.map.editPanel.open({
934
- content: container,
935
- className: options.className,
936
- })
849
+ const panel = options.edit ? this.map.editPanel : this.map.panel
850
+ panel.open({ content: container })
937
851
  },
938
852
 
939
853
  buildList: function (options) {
@@ -1123,7 +1037,7 @@ U.Search = L.PhotonSearch.extend({
1123
1037
  L.DomEvent.on(edit, 'mousedown', (e) => {
1124
1038
  L.DomEvent.stop(e)
1125
1039
  const datalayer = this.map.defaultEditDataLayer()
1126
- const layer = datalayer.geojsonToFeatures(feature)
1040
+ const layer = datalayer.makeFeature(feature)
1127
1041
  layer.isDirty = true
1128
1042
  layer.edit()
1129
1043
  })
@@ -1246,56 +1160,71 @@ U.Editable = L.Editable.extend({
1246
1160
  initialize: function (map, options) {
1247
1161
  L.Editable.prototype.initialize.call(this, map, options)
1248
1162
  this.on('editable:drawing:click editable:drawing:move', this.drawingTooltip)
1249
- this.on('editable:drawing:end', (e) => {
1163
+ this.on('editable:drawing:end', (event) => {
1250
1164
  this.map.tooltip.close()
1251
1165
  // Leaflet.Editable will delete the drawn shape if invalid
1252
1166
  // (eg. line has only one drawn point)
1253
1167
  // So let's check if the layer has no more shape
1254
- if (!e.layer.hasGeom()) e.layer.del()
1255
- else e.layer.edit()
1168
+ if (!event.layer.feature.hasGeom()) {
1169
+ event.layer.feature.del()
1170
+ } else {
1171
+ event.layer.feature.edit()
1172
+ }
1256
1173
  })
1257
1174
  // Layer for items added by users
1258
- this.on('editable:drawing:cancel', (e) => {
1259
- if (e.layer instanceof U.Marker) e.layer.del()
1175
+ this.on('editable:drawing:cancel', (event) => {
1176
+ if (event.layer instanceof U.LeafletMarker) event.layer.feature.del()
1260
1177
  })
1261
- this.on('editable:drawing:commit', function (e) {
1262
- e.layer.isDirty = true
1263
- if (this.map.editedFeature !== e.layer) e.layer.edit(e)
1178
+ this.on('editable:drawing:commit', function (event) {
1179
+ event.layer.feature.isDirty = true
1180
+ if (this.map.editedFeature !== event.layer) event.layer.feature.edit(event)
1264
1181
  })
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
- }
1182
+ this.on('editable:editing', (event) => {
1183
+ const layer = event.layer
1184
+ layer.feature.isDirty = true
1185
+ layer.feature.fromLatLngs(layer.getLatLngs())
1272
1186
  })
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()
1187
+ this.on('editable:vertex:ctrlclick', (event) => {
1188
+ const index = event.vertex.getIndex()
1189
+ if (
1190
+ index === 0 ||
1191
+ (index === event.vertex.getLastIndex() && event.vertex.continue)
1192
+ )
1193
+ event.vertex.continue()
1277
1194
  })
1278
- this.on('editable:vertex:altclick', (e) => {
1279
- if (e.vertex.editor.vertexCanBeDeleted(e.vertex)) e.vertex.delete()
1195
+ this.on('editable:vertex:altclick', (event) => {
1196
+ if (event.vertex.editor.vertexCanBeDeleted(event.vertex)) event.vertex.delete()
1280
1197
  })
1281
1198
  this.on('editable:vertex:rawclick', this.onVertexRawClick)
1282
1199
  },
1283
1200
 
1284
1201
  createPolyline: function (latlngs) {
1285
- return new U.Polyline(this.map, latlngs, this._getDefaultProperties())
1202
+ const datalayer = this.map.defaultEditDataLayer()
1203
+ const point = new U.LineString(datalayer, {
1204
+ geometry: { type: 'LineString', coordinates: [] },
1205
+ })
1206
+ return point.ui
1286
1207
  },
1287
1208
 
1288
1209
  createPolygon: function (latlngs) {
1289
- return new U.Polygon(this.map, latlngs, this._getDefaultProperties())
1210
+ const datalayer = this.map.defaultEditDataLayer()
1211
+ const point = new U.Polygon(datalayer, {
1212
+ geometry: { type: 'Polygon', coordinates: [] },
1213
+ })
1214
+ return point.ui
1290
1215
  },
1291
1216
 
1292
1217
  createMarker: function (latlng) {
1293
- return new U.Marker(this.map, latlng, this._getDefaultProperties())
1218
+ const datalayer = this.map.defaultEditDataLayer()
1219
+ const point = new U.Point(datalayer, {
1220
+ geometry: { type: 'Point', coordinates: [latlng.lng, latlng.lat] },
1221
+ })
1222
+ return point.ui
1294
1223
  },
1295
1224
 
1296
1225
  _getDefaultProperties: function () {
1297
1226
  const result = {}
1298
- if (this.map.options.featuresHaveOwner && this.map.options.hasOwnProperty('user')) {
1227
+ if (this.map.options.featuresHaveOwner?.user) {
1299
1228
  result.geojson = { properties: { owner: this.map.options.user.id } }
1300
1229
  }
1301
1230
  return result
@@ -1304,7 +1233,7 @@ U.Editable = L.Editable.extend({
1304
1233
  connectCreatedToMap: function (layer) {
1305
1234
  // Overrided from Leaflet.Editable
1306
1235
  const datalayer = this.map.defaultEditDataLayer()
1307
- datalayer.addLayer(layer)
1236
+ datalayer.addFeature(layer.feature)
1308
1237
  layer.isDirty = true
1309
1238
  return layer
1310
1239
  },
@@ -1331,7 +1260,11 @@ U.Editable = L.Editable.extend({
1331
1260
  }
1332
1261
  } else {
1333
1262
  const tmpLatLngs = e.layer.editor._drawnLatLngs.slice()
1334
- tmpLatLngs.push(e.latlng)
1263
+ if (e.layer.editor._drawing === L.Editable.BACKWARD) {
1264
+ tmpLatLngs.unshift(e.latlng)
1265
+ } else {
1266
+ tmpLatLngs.push(e.latlng)
1267
+ }
1335
1268
  measure = e.layer.getMeasure(tmpLatLngs)
1336
1269
 
1337
1270
  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,
@@ -1093,11 +1086,35 @@ L.FormBuilder.ManageEditors = L.FormBuilder.Element.extend({
1093
1086
  },
1094
1087
  })
1095
1088
 
1089
+ L.FormBuilder.ManageTeam = L.FormBuilder.IntSelect.extend({
1090
+ getOptions: function () {
1091
+ return [[null, L._('None')]].concat(
1092
+ this.options.teams.map((team) => [team.id, team.name])
1093
+ )
1094
+ },
1095
+ toHTML: function () {
1096
+ return this.get()?.id
1097
+ },
1098
+ toJS: function () {
1099
+ const value = this.value()
1100
+ for (const team of this.options.teams) {
1101
+ if (team.id === value) return team
1102
+ }
1103
+ },
1104
+ })
1105
+
1096
1106
  U.FormBuilder = L.FormBuilder.extend({
1097
1107
  options: {
1098
1108
  className: 'umap-form',
1099
1109
  },
1100
1110
 
1111
+ customHandlers: {
1112
+ sortKey: 'BlurInput',
1113
+ easing: 'Switch',
1114
+ facetKey: 'BlurInput',
1115
+ slugKey: 'BlurInput',
1116
+ },
1117
+
1101
1118
  computeDefaultOptions: function () {
1102
1119
  for (const [key, schema] of Object.entries(U.SCHEMA)) {
1103
1120
  if (schema.type === Boolean) {
@@ -1135,6 +1152,9 @@ U.FormBuilder = L.FormBuilder.extend({
1135
1152
  break
1136
1153
  }
1137
1154
  }
1155
+ if (this.customHandlers[key]) {
1156
+ schema.handler = this.customHandlers[key]
1157
+ }
1138
1158
  // FormBuilder use this key for the input type itself
1139
1159
  delete schema.type
1140
1160
  this.defaultOptions[key] = schema