umap-project 2.5.0__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 +4 -3
  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.0.dist-info → umap_project-2.6.0.dist-info}/METADATA +14 -14
  257. {umap_project-2.5.0.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.0.dist-info → umap_project-2.6.0.dist-info}/WHEEL +0 -0
  275. {umap_project-2.5.0.dist-info → umap_project-2.6.0.dist-info}/entry_points.txt +0 -0
  276. {umap_project-2.5.0.dist-info → umap_project-2.6.0.dist-info}/licenses/LICENSE +0 -0
@@ -22,7 +22,7 @@ export const EXPORT_FORMATS = {
22
22
  const table = []
23
23
  map.eachFeature((feature) => {
24
24
  const row = feature.toGeoJSON().properties
25
- const center = feature.getCenter()
25
+ const center = feature.center
26
26
  delete row._umap_options
27
27
  row.Latitude = center.lat
28
28
  row.Longitude = center.lng
@@ -38,7 +38,16 @@ export const EXPORT_FORMATS = {
38
38
  export class Formatter {
39
39
  async fromGPX(str) {
40
40
  const togeojson = await import('../../vendors/togeojson/togeojson.es.js')
41
- return togeojson.gpx(this.toDom(str))
41
+ const data = togeojson.gpx(this.toDom(str))
42
+ for (const feature of data.features || []) {
43
+ feature.properties.description = feature.properties.desc
44
+ for (const key in feature.properties) {
45
+ if (key.startsWith('_') || typeof feature.properties[key] === 'object') {
46
+ delete feature.properties[key]
47
+ }
48
+ }
49
+ }
50
+ return data
42
51
  }
43
52
 
44
53
  async fromKML(str) {
@@ -106,7 +115,7 @@ export class Formatter {
106
115
  }
107
116
 
108
117
  async fromGeoRSS(str) {
109
- return GeoRSSToGeoJSON(this.toDom(c))
118
+ return GeoRSSToGeoJSON(this.toDom(str))
110
119
  }
111
120
 
112
121
  toDom(x) {
@@ -1,9 +1,12 @@
1
1
  import {
2
2
  uMapAlert as Alert,
3
- uMapAlertConflict as AlertConflict,
4
3
  uMapAlertCreation as AlertCreation,
5
4
  } from '../components/alerts/alert.js'
6
- import { AjaxAutocomplete, AjaxAutocompleteMultiple, AutocompleteDatalist } from './autocomplete.js'
5
+ import {
6
+ AjaxAutocomplete,
7
+ AjaxAutocompleteMultiple,
8
+ AutocompleteDatalist,
9
+ } from './autocomplete.js'
7
10
  import Browser from './browser.js'
8
11
  import Caption from './caption.js'
9
12
  import Facets from './facets.js'
@@ -19,10 +22,14 @@ import Slideshow from './slideshow.js'
19
22
  import { SyncEngine } from './sync/engine.js'
20
23
  import Dialog from './ui/dialog.js'
21
24
  import { EditPanel, FullPanel, Panel } from './ui/panel.js'
22
- import TableEditor from './tableeditor.js'
23
25
  import Tooltip from './ui/tooltip.js'
24
26
  import URLs from './urls.js'
25
27
  import * as Utils from './utils.js'
28
+ import * as Icon from './rendering/icon.js'
29
+ import { DataLayer, LAYER_TYPES } from './data/layer.js'
30
+ import { DataLayerPermissions, MapPermissions } from './permissions.js'
31
+ import { Point, LineString, Polygon } from './data/features.js'
32
+ import { LeafletMarker, LeafletPolyline, LeafletPolygon } from './rendering/ui.js'
26
33
 
27
34
  // Import modules and export them to the global scope.
28
35
  // For the not yet module-compatible JS out there.
@@ -31,12 +38,13 @@ import * as Utils from './utils.js'
31
38
  window.U = {
32
39
  Alert,
33
40
  AlertCreation,
34
- AlertConflict,
35
41
  AjaxAutocomplete,
36
42
  AjaxAutocompleteMultiple,
37
43
  AutocompleteDatalist,
38
44
  Browser,
39
45
  Caption,
46
+ DataLayer,
47
+ DataLayerPermissions,
40
48
  Dialog,
41
49
  EditPanel,
42
50
  Facets,
@@ -44,10 +52,19 @@ window.U = {
44
52
  FullPanel,
45
53
  Help,
46
54
  HTTPError,
55
+ Icon,
47
56
  Importer,
57
+ LAYER_TYPES,
58
+ LeafletMarker,
59
+ LeafletPolygon,
60
+ LeafletPolyline,
61
+ LineString,
62
+ MapPermissions,
48
63
  NOKError,
49
64
  Orderable,
50
65
  Panel,
66
+ Point,
67
+ Polygon,
51
68
  Request,
52
69
  RequestError,
53
70
  Rules,
@@ -56,7 +73,6 @@ window.U = {
56
73
  Share,
57
74
  Slideshow,
58
75
  SyncEngine,
59
- TableEditor,
60
76
  Tooltip,
61
77
  URLs,
62
78
  Utils,
@@ -25,10 +25,20 @@ class Autocomplete extends SingleMixin(BaseAjax) {
25
25
  }
26
26
 
27
27
  createResult(item) {
28
+ const labels = [item.properties.name]
29
+ if (item.properties.county) {
30
+ labels.push(item.properties.county)
31
+ }
32
+ if (item.properties.state) {
33
+ labels.push(item.properties.state)
34
+ }
35
+ if (item.properties.country) {
36
+ labels.push(item.properties.country)
37
+ }
28
38
  return super.createResult({
29
39
  // Overpass convention to get their id from an osm one.
30
40
  value: item.properties.osm_id + 3600000000,
31
- label: `${item.properties.name}`,
41
+ label: labels.join(', '),
32
42
  })
33
43
  }
34
44
  }
@@ -42,11 +52,10 @@ export class Importer {
42
52
  options?.searchUrl ||
43
53
  'https://photon.komoot.io/api?q={q}&layer=county&layer=city&layer=state'
44
54
  this.id = 'overpass'
55
+ this.boundaryChoice = null
45
56
  }
46
57
 
47
58
  async open(importer) {
48
- let boundary = null
49
- let boundaryName = null
50
59
  const container = DomUtil.create('div')
51
60
  container.innerHTML = TEMPLATE
52
61
  this.autocomplete = new Autocomplete(container.querySelector('#area'), {
@@ -55,10 +64,15 @@ export class Importer {
55
64
  'Type area name, or let empty to load data in current map view'
56
65
  ),
57
66
  on_select: (choice) => {
58
- boundary = choice.item.value
59
- boundaryName = choice.item.label
67
+ this.boundaryChoice = choice
68
+ },
69
+ on_unselect: (choice) => {
70
+ this.boundaryChoice = null
60
71
  },
61
72
  })
73
+ if (this.boundaryChoice) {
74
+ this.autocomplete.displaySelected(this.boundaryChoice)
75
+ }
62
76
  this.map.help.parse(container)
63
77
 
64
78
  const confirm = (form) => {
@@ -69,10 +83,10 @@ export class Importer {
69
83
  let tags = form.tags
70
84
  if (!tags.startsWith('[')) tags = `[${tags}]`
71
85
  let area = '{south},{west},{north},{east}'
72
- if (boundary) area = `area:${boundary}`
86
+ if (this.boundaryChoice) area = `area:${this.boundaryChoice.item.value}`
73
87
  const query = `[out:json];nwr${tags}(${area});out ${form.out};`
74
88
  importer.url = `${this.baseUrl}?data=${query}`
75
- if (boundary) importer.layerName = boundaryName
89
+ if (this.boundaryChoice) importer.layerName = this.boundaryChoice.item.label
76
90
  importer.format = 'osm'
77
91
  }
78
92
 
@@ -81,7 +95,7 @@ export class Importer {
81
95
  template: container,
82
96
  className: `${this.id} importer dark`,
83
97
  accept: translate('Choose this data'),
84
- cancel: false
98
+ cancel: false,
85
99
  })
86
100
  .then(confirm)
87
101
  }
@@ -0,0 +1,280 @@
1
+ import { DomUtil } from '../../vendors/leaflet/leaflet-src.esm.js'
2
+ import { translate } from './i18n.js'
3
+ import { uMapAlert as Alert } from '../components/alerts/alert.js'
4
+ import * as Utils from './utils.js'
5
+
6
+ // Dedicated object so we can deal with a separate dirty status, and thus
7
+ // call the endpoint only when needed, saving one call at each save.
8
+ export class MapPermissions {
9
+ constructor(map) {
10
+ this.setOptions(map.options.permissions)
11
+ this.map = map
12
+ this._isDirty = false
13
+ }
14
+
15
+ set isDirty(status) {
16
+ this._isDirty = status
17
+ if (status) this.map.isDirty = status
18
+ }
19
+
20
+ get isDirty() {
21
+ return this._isDirty
22
+ }
23
+
24
+ setOptions(options) {
25
+ this.options = Object.assign(
26
+ {
27
+ owner: null,
28
+ team: null,
29
+ editors: [],
30
+ share_status: null,
31
+ edit_status: null,
32
+ },
33
+ options
34
+ )
35
+ }
36
+
37
+ isOwner() {
38
+ return Boolean(this.map.options.user?.is_owner)
39
+ }
40
+
41
+ isAnonymousMap() {
42
+ return !this.map.options.permissions.owner
43
+ }
44
+
45
+ getMap() {
46
+ return this.map
47
+ }
48
+
49
+ edit() {
50
+ if (this.map.options.editMode !== 'advanced') return
51
+ if (!this.map.options.umap_id) {
52
+ return Alert.info(translate('Please save the map first'))
53
+ }
54
+ const container = DomUtil.create('div', 'permissions-panel')
55
+ const fields = []
56
+ DomUtil.createTitle(container, translate('Update permissions'), 'icon-key')
57
+ if (this.isAnonymousMap()) {
58
+ if (this.options.anonymous_edit_url) {
59
+ const helpText = `${translate('Secret edit link:')}<br>${
60
+ this.options.anonymous_edit_url
61
+ }`
62
+ DomUtil.element({
63
+ tagName: 'p',
64
+ className: 'help-text',
65
+ innerHTML: helpText,
66
+ parent: container,
67
+ })
68
+ fields.push([
69
+ 'options.edit_status',
70
+ {
71
+ handler: 'IntSelect',
72
+ label: translate('Who can edit'),
73
+ selectOptions: this.map.options.edit_statuses,
74
+ helpText: helpText,
75
+ },
76
+ ])
77
+ }
78
+ } else {
79
+ if (this.isOwner()) {
80
+ fields.push([
81
+ 'options.edit_status',
82
+ {
83
+ handler: 'IntSelect',
84
+ label: translate('Who can edit'),
85
+ selectOptions: this.map.options.edit_statuses,
86
+ },
87
+ ])
88
+ fields.push([
89
+ 'options.share_status',
90
+ {
91
+ handler: 'IntSelect',
92
+ label: translate('Who can view'),
93
+ selectOptions: this.map.options.share_statuses,
94
+ },
95
+ ])
96
+ fields.push([
97
+ 'options.owner',
98
+ { handler: 'ManageOwner', label: translate("Map's owner") },
99
+ ])
100
+ if (this.map.options.user?.teams?.length) {
101
+ fields.push([
102
+ 'options.team',
103
+ {
104
+ handler: 'ManageTeam',
105
+ label: translate('Attach map to a team'),
106
+ teams: this.map.options.user.teams,
107
+ },
108
+ ])
109
+ }
110
+ }
111
+ fields.push([
112
+ 'options.editors',
113
+ { handler: 'ManageEditors', label: translate("Map's editors") },
114
+ ])
115
+ }
116
+
117
+ const builder = new U.FormBuilder(this, fields)
118
+ const form = builder.build()
119
+ container.appendChild(form)
120
+ if (this.isAnonymousMap() && this.map.options.user) {
121
+ // We have a user, and this user has come through here, so they can edit the map, so let's allow to own the map.
122
+ // Note: real check is made on the back office anyway.
123
+ const advancedActions = DomUtil.createFieldset(
124
+ container,
125
+ translate('Advanced actions')
126
+ )
127
+ const advancedButtons = DomUtil.create('div', 'button-bar', advancedActions)
128
+ DomUtil.createButton(
129
+ 'button',
130
+ advancedButtons,
131
+ translate('Attach the map to my account'),
132
+ this.attach,
133
+ this
134
+ )
135
+ }
136
+ DomUtil.add('h4', '', container, translate('Datalayers'))
137
+ this.map.eachDataLayer((datalayer) => {
138
+ datalayer.permissions.edit(container)
139
+ })
140
+ this.map.editPanel.open({ content: container, className: 'dark' })
141
+ }
142
+
143
+ async attach() {
144
+ const [data, response, error] = await this.map.server.post(this.getAttachUrl())
145
+ if (!error) {
146
+ this.options.owner = this.map.options.user
147
+ Alert.success(translate('Map has been attached to your account'))
148
+ this.map.editPanel.close()
149
+ }
150
+ }
151
+
152
+ async save() {
153
+ if (!this.isDirty) return this.map.continueSaving()
154
+ const formData = new FormData()
155
+ if (!this.isAnonymousMap() && this.options.editors) {
156
+ const editors = this.options.editors.map((u) => u.id)
157
+ for (let i = 0; i < this.options.editors.length; i++)
158
+ formData.append('editors', this.options.editors[i].id)
159
+ }
160
+ if (this.isOwner() || this.isAnonymousMap())
161
+ formData.append('edit_status', this.options.edit_status)
162
+ if (this.isOwner()) {
163
+ formData.append('owner', this.options.owner?.id)
164
+ formData.append('team', this.options.team?.id || '')
165
+ formData.append('share_status', this.options.share_status)
166
+ }
167
+ const [data, response, error] = await this.map.server.post(
168
+ this.getUrl(),
169
+ {},
170
+ formData
171
+ )
172
+ if (!error) {
173
+ this.commit()
174
+ this.isDirty = false
175
+ this.map.continueSaving()
176
+ this.map.fire('postsync')
177
+ }
178
+ }
179
+
180
+ getUrl() {
181
+ return Utils.template(this.map.options.urls.map_update_permissions, {
182
+ map_id: this.map.options.umap_id,
183
+ })
184
+ }
185
+
186
+ getAttachUrl() {
187
+ return Utils.template(this.map.options.urls.map_attach_owner, {
188
+ map_id: this.map.options.umap_id,
189
+ })
190
+ }
191
+
192
+ commit() {
193
+ this.map.options.permissions = Object.assign(
194
+ this.map.options.permissions,
195
+ this.options
196
+ )
197
+ }
198
+
199
+ getShareStatusDisplay() {
200
+ return Object.fromEntries(this.map.options.share_statuses)[
201
+ this.options.share_status
202
+ ]
203
+ }
204
+ }
205
+
206
+ export class DataLayerPermissions {
207
+ constructor(datalayer) {
208
+ this.options = Object.assign(
209
+ {
210
+ edit_status: null,
211
+ },
212
+ datalayer.options.permissions
213
+ )
214
+
215
+ this.datalayer = datalayer
216
+ this._isDirty = false
217
+ }
218
+
219
+ set isDirty(status) {
220
+ this._isDirty = status
221
+ if (status) this.datalayer.isDirty = status
222
+ }
223
+
224
+ get isDirty() {
225
+ return this._isDirty
226
+ }
227
+
228
+ getMap() {
229
+ return this.datalayer.map
230
+ }
231
+
232
+ edit(container) {
233
+ const fields = [
234
+ [
235
+ 'options.edit_status',
236
+ {
237
+ handler: 'IntSelect',
238
+ label: translate('Who can edit "{layer}"', {
239
+ layer: this.datalayer.getName(),
240
+ }),
241
+ selectOptions: this.datalayer.map.options.datalayer_edit_statuses,
242
+ },
243
+ ],
244
+ ]
245
+ const builder = new U.FormBuilder(this, fields, {
246
+ className: 'umap-form datalayer-permissions',
247
+ })
248
+ const form = builder.build()
249
+ container.appendChild(form)
250
+ }
251
+
252
+ getUrl() {
253
+ return Utils.template(this.datalayer.map.options.urls.datalayer_permissions, {
254
+ map_id: this.datalayer.map.options.umap_id,
255
+ pk: this.datalayer.umap_id,
256
+ })
257
+ }
258
+ async save() {
259
+ if (!this.isDirty) return this.datalayer.map.continueSaving()
260
+ const formData = new FormData()
261
+ formData.append('edit_status', this.options.edit_status)
262
+ const [data, response, error] = await this.datalayer.map.server.post(
263
+ this.getUrl(),
264
+ {},
265
+ formData
266
+ )
267
+ if (!error) {
268
+ this.commit()
269
+ this.isDirty = false
270
+ this.datalayer.map.continueSaving()
271
+ }
272
+ }
273
+
274
+ commit() {
275
+ this.datalayer.options.permissions = Object.assign(
276
+ this.datalayer.options.permissions,
277
+ this.options
278
+ )
279
+ }
280
+ }