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.

Files changed (216) hide show
  1. umap/__init__.py +1 -1
  2. umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
  3. umap/locale/cs_CZ/LC_MESSAGES/django.po +43 -33
  4. umap/locale/da/LC_MESSAGES/django.mo +0 -0
  5. umap/locale/da/LC_MESSAGES/django.po +43 -33
  6. umap/locale/de/LC_MESSAGES/django.mo +0 -0
  7. umap/locale/de/LC_MESSAGES/django.po +35 -29
  8. umap/locale/el/LC_MESSAGES/django.mo +0 -0
  9. umap/locale/el/LC_MESSAGES/django.po +35 -29
  10. umap/locale/en/LC_MESSAGES/django.po +34 -28
  11. umap/locale/es/LC_MESSAGES/django.mo +0 -0
  12. umap/locale/es/LC_MESSAGES/django.po +43 -33
  13. umap/locale/et/LC_MESSAGES/django.mo +0 -0
  14. umap/locale/et/LC_MESSAGES/django.po +58 -54
  15. umap/locale/eu/LC_MESSAGES/django.mo +0 -0
  16. umap/locale/eu/LC_MESSAGES/django.po +43 -33
  17. umap/locale/fa_IR/LC_MESSAGES/django.mo +0 -0
  18. umap/locale/fa_IR/LC_MESSAGES/django.po +43 -33
  19. umap/locale/fr/LC_MESSAGES/django.mo +0 -0
  20. umap/locale/fr/LC_MESSAGES/django.po +36 -30
  21. umap/locale/gl/LC_MESSAGES/django.mo +0 -0
  22. umap/locale/gl/LC_MESSAGES/django.po +43 -33
  23. umap/locale/hu/LC_MESSAGES/django.mo +0 -0
  24. umap/locale/hu/LC_MESSAGES/django.po +35 -29
  25. umap/locale/is/LC_MESSAGES/django.mo +0 -0
  26. umap/locale/is/LC_MESSAGES/django.po +43 -33
  27. umap/locale/it/LC_MESSAGES/django.mo +0 -0
  28. umap/locale/it/LC_MESSAGES/django.po +43 -33
  29. umap/locale/nl/LC_MESSAGES/django.mo +0 -0
  30. umap/locale/nl/LC_MESSAGES/django.po +35 -29
  31. umap/locale/pl/LC_MESSAGES/django.mo +0 -0
  32. umap/locale/pl/LC_MESSAGES/django.po +43 -33
  33. umap/locale/pt/LC_MESSAGES/django.mo +0 -0
  34. umap/locale/pt/LC_MESSAGES/django.po +43 -33
  35. umap/locale/th_TH/LC_MESSAGES/django.mo +0 -0
  36. umap/locale/th_TH/LC_MESSAGES/django.po +310 -109
  37. umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
  38. umap/locale/zh_TW/LC_MESSAGES/django.po +80 -70
  39. umap/management/commands/switch_user.py +2 -2
  40. umap/static/umap/base.css +89 -32
  41. umap/static/umap/content.css +129 -33
  42. umap/static/umap/css/bar.css +82 -20
  43. umap/static/umap/css/browser.css +163 -0
  44. umap/static/umap/css/contextmenu.css +15 -0
  45. umap/static/umap/css/dialog.css +36 -16
  46. umap/static/umap/css/form.css +122 -32
  47. umap/static/umap/css/icon.css +46 -3
  48. umap/static/umap/css/panel.css +7 -3
  49. umap/static/umap/css/popup.css +34 -8
  50. umap/static/umap/css/tooltip.css +8 -4
  51. umap/static/umap/img/16-white.svg +26 -8
  52. umap/static/umap/img/16.svg +1 -1
  53. umap/static/umap/img/source/16-white.svg +36 -18
  54. umap/static/umap/img/source/16.svg +1 -1
  55. umap/static/umap/js/components/alerts/alert.css +69 -31
  56. umap/static/umap/js/components/alerts/alert.js +20 -2
  57. umap/static/umap/js/modules/browser.js +63 -55
  58. umap/static/umap/js/modules/caption.js +10 -7
  59. umap/static/umap/js/modules/data/features.js +82 -59
  60. umap/static/umap/js/modules/data/layer.js +56 -157
  61. umap/static/umap/js/modules/domutils.js +109 -0
  62. umap/static/umap/js/modules/filters.js +807 -0
  63. umap/static/umap/js/modules/form/builder.js +8 -5
  64. umap/static/umap/js/modules/form/fields.js +110 -220
  65. umap/static/umap/js/modules/formatter.js +24 -1
  66. umap/static/umap/js/modules/help.js +3 -2
  67. umap/static/umap/js/modules/importers/opendata.js +5 -0
  68. umap/static/umap/js/modules/importers/openrouteservice.js +6 -1
  69. umap/static/umap/js/modules/managers.js +265 -1
  70. umap/static/umap/js/modules/permissions.js +35 -31
  71. umap/static/umap/js/modules/rendering/controls.js +7 -7
  72. umap/static/umap/js/modules/rendering/icon.js +3 -8
  73. umap/static/umap/js/modules/rendering/layers/classified.js +17 -10
  74. umap/static/umap/js/modules/rendering/layers/cluster.js +2 -2
  75. umap/static/umap/js/modules/rendering/template.js +44 -8
  76. umap/static/umap/js/modules/rendering/ui.js +29 -23
  77. umap/static/umap/js/modules/rules.js +4 -3
  78. umap/static/umap/js/modules/schema.js +3 -6
  79. umap/static/umap/js/modules/share.js +4 -3
  80. umap/static/umap/js/modules/tableeditor.js +50 -38
  81. umap/static/umap/js/modules/templates.js +2 -3
  82. umap/static/umap/js/modules/ui/bar.js +42 -18
  83. umap/static/umap/js/modules/ui/dialog.js +33 -31
  84. umap/static/umap/js/modules/ui/panel.js +21 -7
  85. umap/static/umap/js/modules/ui/tooltip.js +6 -5
  86. umap/static/umap/js/modules/umap.js +148 -51
  87. umap/static/umap/js/modules/utils.js +23 -1
  88. umap/static/umap/js/umap.core.js +1 -110
  89. umap/static/umap/locale/am_ET.js +40 -14
  90. umap/static/umap/locale/am_ET.json +40 -14
  91. umap/static/umap/locale/ar.js +40 -14
  92. umap/static/umap/locale/ar.json +40 -14
  93. umap/static/umap/locale/ast.js +40 -14
  94. umap/static/umap/locale/ast.json +40 -14
  95. umap/static/umap/locale/bg.js +40 -14
  96. umap/static/umap/locale/bg.json +40 -14
  97. umap/static/umap/locale/br.js +47 -21
  98. umap/static/umap/locale/br.json +47 -21
  99. umap/static/umap/locale/ca.js +40 -14
  100. umap/static/umap/locale/ca.json +40 -14
  101. umap/static/umap/locale/cs_CZ.js +40 -14
  102. umap/static/umap/locale/cs_CZ.json +40 -14
  103. umap/static/umap/locale/da.js +40 -14
  104. umap/static/umap/locale/da.json +40 -14
  105. umap/static/umap/locale/de.js +39 -13
  106. umap/static/umap/locale/de.json +39 -13
  107. umap/static/umap/locale/el.js +40 -14
  108. umap/static/umap/locale/el.json +40 -14
  109. umap/static/umap/locale/en.js +39 -13
  110. umap/static/umap/locale/en.json +39 -13
  111. umap/static/umap/locale/en_US.json +40 -14
  112. umap/static/umap/locale/es.js +40 -14
  113. umap/static/umap/locale/es.json +40 -14
  114. umap/static/umap/locale/et.js +79 -53
  115. umap/static/umap/locale/et.json +79 -53
  116. umap/static/umap/locale/eu.js +72 -46
  117. umap/static/umap/locale/eu.json +72 -46
  118. umap/static/umap/locale/fa_IR.js +40 -14
  119. umap/static/umap/locale/fa_IR.json +40 -14
  120. umap/static/umap/locale/fi.js +40 -14
  121. umap/static/umap/locale/fi.json +40 -14
  122. umap/static/umap/locale/fr.js +39 -13
  123. umap/static/umap/locale/fr.json +39 -13
  124. umap/static/umap/locale/gl.js +40 -14
  125. umap/static/umap/locale/gl.json +40 -14
  126. umap/static/umap/locale/he.js +40 -14
  127. umap/static/umap/locale/he.json +40 -14
  128. umap/static/umap/locale/hr.js +40 -14
  129. umap/static/umap/locale/hr.json +40 -14
  130. umap/static/umap/locale/hu.js +40 -14
  131. umap/static/umap/locale/hu.json +40 -14
  132. umap/static/umap/locale/id.js +40 -14
  133. umap/static/umap/locale/id.json +40 -14
  134. umap/static/umap/locale/is.js +40 -14
  135. umap/static/umap/locale/is.json +40 -14
  136. umap/static/umap/locale/it.js +40 -14
  137. umap/static/umap/locale/it.json +40 -14
  138. umap/static/umap/locale/ja.js +40 -14
  139. umap/static/umap/locale/ja.json +40 -14
  140. umap/static/umap/locale/ko.js +40 -14
  141. umap/static/umap/locale/ko.json +40 -14
  142. umap/static/umap/locale/lt.js +40 -14
  143. umap/static/umap/locale/lt.json +40 -14
  144. umap/static/umap/locale/ms.js +40 -14
  145. umap/static/umap/locale/ms.json +40 -14
  146. umap/static/umap/locale/nl.js +40 -14
  147. umap/static/umap/locale/nl.json +40 -14
  148. umap/static/umap/locale/no.js +40 -14
  149. umap/static/umap/locale/no.json +40 -14
  150. umap/static/umap/locale/pl.js +40 -14
  151. umap/static/umap/locale/pl.json +40 -14
  152. umap/static/umap/locale/pl_PL.json +40 -14
  153. umap/static/umap/locale/pt.js +40 -14
  154. umap/static/umap/locale/pt.json +40 -14
  155. umap/static/umap/locale/pt_BR.js +40 -14
  156. umap/static/umap/locale/pt_BR.json +40 -14
  157. umap/static/umap/locale/pt_PT.js +40 -14
  158. umap/static/umap/locale/pt_PT.json +40 -14
  159. umap/static/umap/locale/ro.js +40 -14
  160. umap/static/umap/locale/ro.json +40 -14
  161. umap/static/umap/locale/ru.js +40 -14
  162. umap/static/umap/locale/ru.json +40 -14
  163. umap/static/umap/locale/sk_SK.js +40 -14
  164. umap/static/umap/locale/sk_SK.json +40 -14
  165. umap/static/umap/locale/sl.js +40 -14
  166. umap/static/umap/locale/sl.json +40 -14
  167. umap/static/umap/locale/sr.js +40 -14
  168. umap/static/umap/locale/sr.json +40 -14
  169. umap/static/umap/locale/sv.js +40 -14
  170. umap/static/umap/locale/sv.json +40 -14
  171. umap/static/umap/locale/th_TH.js +40 -14
  172. umap/static/umap/locale/th_TH.json +40 -14
  173. umap/static/umap/locale/tr.js +40 -14
  174. umap/static/umap/locale/tr.json +40 -14
  175. umap/static/umap/locale/uk_UA.js +40 -14
  176. umap/static/umap/locale/uk_UA.json +40 -14
  177. umap/static/umap/locale/vi.js +40 -14
  178. umap/static/umap/locale/vi.json +40 -14
  179. umap/static/umap/locale/vi_VN.json +40 -14
  180. umap/static/umap/locale/zh.js +40 -14
  181. umap/static/umap/locale/zh.json +40 -14
  182. umap/static/umap/locale/zh_CN.json +40 -14
  183. umap/static/umap/locale/zh_TW.Big5.json +40 -14
  184. umap/static/umap/locale/zh_TW.js +39 -13
  185. umap/static/umap/locale/zh_TW.json +39 -13
  186. umap/static/umap/map.css +60 -223
  187. umap/static/umap/unittests/utils.js +18 -0
  188. umap/static/umap/vars.css +23 -5
  189. umap/templates/umap/components/alerts/alert.html +32 -29
  190. umap/templates/umap/css.html +2 -1
  191. umap/templates/umap/login_popup_end.html +18 -9
  192. umap/templates/umap/user_map_table.html +7 -2
  193. umap/tests/integration/conftest.py +2 -6
  194. umap/tests/integration/test_anonymous_owned_map.py +89 -36
  195. umap/tests/integration/test_basics.py +25 -1
  196. umap/tests/integration/test_browser.py +37 -0
  197. umap/tests/integration/test_draw_polygon.py +2 -0
  198. umap/tests/integration/test_edit_marker.py +1 -1
  199. umap/tests/integration/test_export_map.py +19 -0
  200. umap/tests/integration/test_fields.py +522 -0
  201. umap/tests/integration/test_filters.py +617 -0
  202. umap/tests/integration/test_import.py +15 -42
  203. umap/tests/integration/test_remote_data.py +60 -4
  204. umap/tests/integration/test_share.py +4 -4
  205. umap/tests/integration/test_tableeditor.py +31 -7
  206. umap/tests/integration/test_websocket_sync.py +3 -1
  207. umap/tests/test_dashboard.py +10 -0
  208. umap/urls.py +1 -0
  209. umap/views.py +5 -0
  210. {umap_project-3.3.6.dist-info → umap_project-3.4.0b0.dist-info}/METADATA +12 -12
  211. {umap_project-3.3.6.dist-info → umap_project-3.4.0b0.dist-info}/RECORD +214 -211
  212. umap/static/umap/js/modules/facets.js +0 -164
  213. umap/tests/integration/test_facets_browser.py +0 -279
  214. {umap_project-3.3.6.dist-info → umap_project-3.4.0b0.dist-info}/WHEEL +0 -0
  215. {umap_project-3.3.6.dist-info → umap_project-3.4.0b0.dist-info}/entry_points.txt +0 -0
  216. {umap_project-3.3.6.dist-info → umap_project-3.4.0b0.dist-info}/licenses/LICENSE +0 -0
@@ -22,9 +22,8 @@ def test_layers_list_is_updated(live_server, tilelayer, page):
22
22
  page.locator("[name=layer-id]").select_option(label="Import in a new layer")
23
23
  page.get_by_role("button", name="Manage layers").click()
24
24
  page.get_by_role("button", name="Add a layer").click()
25
- page.locator('input[name="name"]').click()
26
25
  page.locator('input[name="name"]').fill("foobar")
27
- page.wait_for_timeout(300) # Time for the input debounce.
26
+ page.wait_for_timeout(300) # Wait for the input throttling.
28
27
  page.get_by_role("button", name=f"Import data ({modifier}+I)").click()
29
28
  # Should still work
30
29
  page.locator("[name=layer-id]").select_option(label="Import in a new layer")
@@ -108,9 +107,7 @@ def test_import_geojson_from_textarea(tilelayer, live_server, page):
108
107
  expect(markers).to_have_count(0)
109
108
  expect(paths).to_have_count(0)
110
109
  expect(layers).to_have_count(0)
111
- button = page.get_by_title("Import data")
112
- expect(button).to_be_visible()
113
- button.click()
110
+ page.get_by_title("Import data").click()
114
111
  textarea = page.locator(".umap-import textarea")
115
112
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.json"
116
113
  textarea.fill(path.read_text())
@@ -133,9 +130,7 @@ def test_import_invalid_data(tilelayer, live_server, page):
133
130
  expect(markers).to_have_count(0)
134
131
  expect(paths).to_have_count(0)
135
132
  expect(layers).to_have_count(0)
136
- button = page.get_by_title("Import data")
137
- expect(button).to_be_visible()
138
- button.click()
133
+ page.get_by_title("Import data").click()
139
134
  textarea = page.locator(".umap-import textarea")
140
135
  textarea.fill("invalid data")
141
136
  for format in ["geojson", "csv", "gpx", "kml", "georss", "osm", "umap"]:
@@ -153,9 +148,7 @@ def test_import_kml_from_textarea(tilelayer, live_server, page):
153
148
  expect(markers).to_have_count(0)
154
149
  expect(paths).to_have_count(0)
155
150
  expect(layers).to_have_count(0)
156
- button = page.get_by_title("Import data")
157
- expect(button).to_be_visible()
158
- button.click()
151
+ page.get_by_title("Import data").click()
159
152
  textarea = page.locator(".umap-import textarea")
160
153
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.kml"
161
154
  textarea.fill(path.read_text())
@@ -177,9 +170,7 @@ def test_import_gpx_from_textarea(tilelayer, live_server, page, settings):
177
170
  expect(markers).to_have_count(0)
178
171
  expect(paths).to_have_count(0)
179
172
  expect(layers).to_have_count(0)
180
- button = page.get_by_title("Import data")
181
- expect(button).to_be_visible()
182
- button.click()
173
+ page.get_by_title("Import data").click()
183
174
  textarea = page.locator(".umap-import textarea")
184
175
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.gpx"
185
176
  textarea.fill(path.read_text())
@@ -234,9 +225,7 @@ def test_import_osm_from_textarea(tilelayer, live_server, page):
234
225
  markers = page.locator(".leaflet-marker-icon")
235
226
  expect(markers).to_have_count(0)
236
227
  expect(layers).to_have_count(0)
237
- button = page.get_by_title("Import data")
238
- expect(button).to_be_visible()
239
- button.click()
228
+ page.get_by_title("Import data").click()
240
229
  textarea = page.locator(".umap-import textarea")
241
230
  path = Path(__file__).parent.parent / "fixtures/test_upload_data_osm.json"
242
231
  textarea.fill(path.read_text())
@@ -254,9 +243,7 @@ def test_import_csv_from_textarea(tilelayer, live_server, page):
254
243
  markers = page.locator(".leaflet-marker-icon")
255
244
  expect(markers).to_have_count(0)
256
245
  expect(layers).to_have_count(0)
257
- button = page.get_by_title("Import data")
258
- expect(button).to_be_visible()
259
- button.click()
246
+ page.get_by_title("Import data").click()
260
247
  textarea = page.locator(".umap-import textarea")
261
248
  path = Path(__file__).parent.parent / "fixtures/test_upload_data.csv"
262
249
  textarea.fill(path.read_text())
@@ -422,9 +409,7 @@ def test_import_geometry_collection(live_server, page, tilelayer):
422
409
  expect(markers).to_have_count(0)
423
410
  expect(paths).to_have_count(0)
424
411
  expect(layers).to_have_count(0)
425
- button = page.get_by_title("Import data")
426
- expect(button).to_be_visible()
427
- button.click()
412
+ page.get_by_title("Import data").click()
428
413
  textarea = page.locator(".umap-import textarea")
429
414
  textarea.fill(json.dumps(data))
430
415
  page.locator('select[name="format"]').select_option("geojson")
@@ -477,9 +462,7 @@ def test_import_geometry_collection_in_feature(live_server, page, tilelayer):
477
462
  expect(markers).to_have_count(0)
478
463
  expect(paths).to_have_count(0)
479
464
  expect(layers).to_have_count(0)
480
- button = page.get_by_title("Import data")
481
- expect(button).to_be_visible()
482
- button.click()
465
+ page.get_by_title("Import data").click()
483
466
  textarea = page.locator(".umap-import textarea")
484
467
  textarea.fill(json.dumps(data))
485
468
  page.locator('select[name="format"]').select_option("geojson")
@@ -513,9 +496,7 @@ def test_import_multipolygon(live_server, page, tilelayer):
513
496
  paths = page.locator("path")
514
497
  expect(paths).to_have_count(0)
515
498
  expect(layers).to_have_count(0)
516
- button = page.get_by_title("Import data")
517
- expect(button).to_be_visible()
518
- button.click()
499
+ page.get_by_title("Import data").click()
519
500
  textarea = page.locator(".umap-import textarea")
520
501
  textarea.fill(json.dumps(data))
521
502
  page.locator('select[name="format"]').select_option("geojson")
@@ -545,9 +526,7 @@ def test_import_multipolyline(live_server, page, tilelayer):
545
526
  paths = page.locator("path")
546
527
  expect(paths).to_have_count(0)
547
528
  expect(layers).to_have_count(0)
548
- button = page.get_by_title("Import data")
549
- expect(button).to_be_visible()
550
- button.click()
529
+ page.get_by_title("Import data").click()
551
530
  textarea = page.locator(".umap-import textarea")
552
531
  textarea.fill(json.dumps(data))
553
532
  page.locator('select[name="format"]').select_option("geojson")
@@ -577,9 +556,7 @@ def test_import_false_multipoint(live_server, page, tilelayer):
577
556
  markers = page.locator(".leaflet-marker-icon")
578
557
  expect(markers).to_have_count(0)
579
558
  expect(layers).to_have_count(0)
580
- button = page.get_by_title("Import data")
581
- expect(button).to_be_visible()
582
- button.click()
559
+ page.get_by_title("Import data").click()
583
560
  textarea = page.locator(".umap-import textarea")
584
561
  textarea.fill(json.dumps(data))
585
562
  page.locator('select[name="format"]').select_option("geojson")
@@ -712,7 +689,7 @@ def test_import_csv_with_wkt_geom(tilelayer, live_server, page, settings):
712
689
  page.get_by_title("Import data").click()
713
690
  textarea = page.locator(".umap-import textarea")
714
691
  textarea.fill(
715
- "geom;foobar\nPOLYGON ((-64.8 32.3, -65.5 18.3, -80.3 25.2, -64.8 32.3));mypoly\nPOINT(48.35 12.23);mypoint"
692
+ "Geom;foobar\nPOLYGON ((-64.8 32.3, -65.5 18.3, -80.3 25.2, -64.8 32.3));mypoly\nPOINT(48.35 12.23);mypoint"
716
693
  )
717
694
  page.locator('select[name="format"]').select_option("csv")
718
695
  page.get_by_role("button", name="Import data", exact=True).click()
@@ -1056,9 +1033,7 @@ def test_import_osm_relation(tilelayer, live_server, page):
1056
1033
  paths = page.locator("path")
1057
1034
  expect(paths).to_have_count(0)
1058
1035
  expect(layers).to_have_count(0)
1059
- button = page.get_by_title("Import data")
1060
- expect(button).to_be_visible()
1061
- button.click()
1036
+ page.get_by_title("Import data").click()
1062
1037
  textarea = page.locator(".umap-import textarea")
1063
1038
  file_path = Path(__file__).parent.parent / "fixtures/test_import_osm_relation.json"
1064
1039
  textarea.fill(file_path.read_text())
@@ -1076,9 +1051,7 @@ def test_import_georss_from_textarea(tilelayer, live_server, page):
1076
1051
  markers = page.locator(".leaflet-marker-icon")
1077
1052
  expect(markers).to_have_count(0)
1078
1053
  expect(layers).to_have_count(0)
1079
- button = page.get_by_title("Import data")
1080
- expect(button).to_be_visible()
1081
- button.click()
1054
+ page.get_by_title("Import data").click()
1082
1055
  textarea = page.locator(".umap-import textarea")
1083
1056
  path = Path(__file__).parent.parent / "fixtures/test_upload_georss.xml"
1084
1057
  textarea.fill(path.read_text())
@@ -1,11 +1,15 @@
1
+ import json
2
+ import re
3
+ from pathlib import Path
4
+
1
5
  from playwright.sync_api import expect
2
6
 
3
- from umap.models import Map
7
+ from umap.models import DataLayer, Map
4
8
 
5
9
  from ..base import DataLayerFactory
6
10
 
7
11
 
8
- def test_dynamic_remote_data(page, live_server, tilelayer, map):
12
+ def intercept_remote_data(page):
9
13
  data = [
10
14
  {
11
15
  "type": "FeatureCollection",
@@ -38,6 +42,13 @@ def test_dynamic_remote_data(page, live_server, tilelayer, map):
38
42
  def handle(route):
39
43
  route.fulfill(json=data.pop())
40
44
 
45
+ # Intercept the route to the proxy
46
+ page.route("https://remote.org/data.json", handle)
47
+ page.on("request", lambda *a, **k: print(a, k))
48
+
49
+
50
+ def test_dynamic_remote_data(page, live_server, tilelayer, map):
51
+ intercept_remote_data(page)
41
52
  settings = {
42
53
  "remoteData": {
43
54
  "url": "https://remote.org/data.json",
@@ -55,8 +66,6 @@ def test_dynamic_remote_data(page, live_server, tilelayer, map):
55
66
  }
56
67
  map.save()
57
68
 
58
- # Intercept the route to the proxy
59
- page.route("https://remote.org/data.json", handle)
60
69
  page.goto(f"{live_server.url}{map.get_absolute_url()}")
61
70
 
62
71
  expect(page.get_by_role("tooltip", name="Point 1")).to_be_visible()
@@ -77,3 +86,50 @@ def test_dynamic_remote_data(page, live_server, tilelayer, map):
77
86
  # Map must not be dirty
78
87
  page.get_by_role("button", name="Edit").click()
79
88
  expect(page.locator(".edit-undo")).to_be_disabled()
89
+
90
+
91
+ def test_create_remote_data_layer(page, live_server, tilelayer, settings):
92
+ settings.UMAP_ALLOW_ANONYMOUS = True
93
+ intercept_remote_data(page)
94
+ page.goto(f"{live_server.url}/en/map/new#6/11.2707/4.3375")
95
+ page.get_by_role("button", name="Manage layers").click()
96
+ page.get_by_role("button", name="Add a layer").click()
97
+ page.get_by_text("Remote data").click()
98
+ page.locator('.panel input[name="url"]').fill("https://remote.org/data.json")
99
+ # We have a setTimeout on each input to throttle, so wait for it
100
+ page.wait_for_timeout(300)
101
+ page.locator('select[name="format"]').select_option("geojson")
102
+ # with page.expect_response(re.compile("https://remote.org/data.json")):
103
+ page.get_by_role("button", name="Verify remote URL").click()
104
+ expect(page.locator(".leaflet-marker-icon")).to_have_count(1)
105
+ with page.expect_response(re.compile(".*/datalayer/create/.*")):
106
+ page.get_by_role("button", name="Save draft", exact=True).click()
107
+ datalayer = DataLayer.objects.last()
108
+ data = json.loads(Path(datalayer.geojson.path).read_text())
109
+ assert data == {
110
+ "_umap_options": {
111
+ "browsable": True,
112
+ "displayOnLoad": True,
113
+ "editMode": "advanced",
114
+ "fields": [
115
+ {
116
+ "key": "name",
117
+ "type": "String",
118
+ },
119
+ {
120
+ "key": "description",
121
+ "type": "Text",
122
+ },
123
+ ],
124
+ "id": str(datalayer.pk),
125
+ "inCaption": True,
126
+ "name": "Layer 1",
127
+ "rank": 0,
128
+ "remoteData": {
129
+ "format": "geojson",
130
+ "url": "https://remote.org/data.json",
131
+ },
132
+ },
133
+ "features": [],
134
+ "type": "FeatureCollection",
135
+ }
@@ -18,10 +18,10 @@ def test_iframe_code_can_contain_datalayers(map, live_server, datalayer, page):
18
18
  expect(textarea).not_to_have_text(re.compile(f"datalayers={datalayer.pk}"))
19
19
  # Open options
20
20
  page.get_by_text("Embed and link options").click()
21
- page.get_by_title("Keep current visible layers").click()
21
+ page.get_by_text("Keep current visible layers").click()
22
22
  expect(textarea).to_have_text(re.compile(f"datalayers={datalayer.pk}"))
23
23
  # Now click again
24
- page.get_by_title("Keep current visible layers").click()
24
+ page.get_by_text("Keep current visible layers").click()
25
25
  expect(textarea).not_to_have_text(re.compile(f"datalayers={datalayer.pk}"))
26
26
 
27
27
 
@@ -33,8 +33,8 @@ def test_iframe_code_can_contain_feature(map, live_server, datalayer, page):
33
33
  expect(textarea).not_to_have_text(re.compile("feature=Here"))
34
34
  # Open options
35
35
  page.get_by_text("Embed and link options").click()
36
- page.get_by_title("Open current feature on load").click()
36
+ page.get_by_text("Open current feature on load").click()
37
37
  expect(textarea).to_have_text(re.compile("feature=Here"))
38
38
  # Click again to deactivate it
39
- page.get_by_title("Open current feature on load").click()
39
+ page.get_by_text("Open current feature on load").click()
40
40
  expect(textarea).not_to_have_text(re.compile("feature=Here"))
@@ -4,7 +4,7 @@ from pathlib import Path
4
4
 
5
5
  from playwright.sync_api import expect
6
6
 
7
- from umap.models import DataLayer
7
+ from umap.models import DataLayer, Map
8
8
 
9
9
  from ..base import DataLayerFactory
10
10
 
@@ -79,7 +79,7 @@ def test_table_editor(live_server, openmap, datalayer, page):
79
79
  page.wait_for_timeout(300) # Time for the input debounce.
80
80
  page.keyboard.press("Enter")
81
81
  page.locator("thead button[data-property=name]").click()
82
- page.get_by_role("button", name="Delete this column").click()
82
+ page.get_by_role("button", name="Delete this field").click()
83
83
  page.locator("dialog").get_by_role("button", name="OK").click()
84
84
  with page.expect_response(re.compile(r".*/datalayer/update/.*")):
85
85
  page.get_by_role("button", name="Save").click()
@@ -116,14 +116,14 @@ def test_cannot_add_property_with_a_dot(live_server, openmap, datalayer, page):
116
116
  expect(page.locator("table th button[data-property=name]")).to_have_count(1)
117
117
 
118
118
 
119
- def test_rename_property(live_server, openmap, page):
119
+ def test_rename_field(live_server, openmap, page):
120
120
  DataLayerFactory(map=openmap, data=DATALAYER_DATA)
121
121
  page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit#6/48.093/1.890")
122
122
  page.get_by_role("button", name="Manage layers").click()
123
123
  page.locator(".panel").get_by_title("Edit properties in a table").click()
124
124
  expect(page.locator("table th button[data-property=mytype]")).to_have_count(1)
125
125
  page.locator("thead button[data-property=mytype]").click()
126
- page.get_by_text("Rename this column").click()
126
+ page.get_by_text("Edit this field").click()
127
127
  page.locator("dialog").locator("input").fill("mynewtype")
128
128
  page.get_by_role("button", name="OK").click()
129
129
  expect(page.locator("table th button[data-property=mynewtype]")).to_have_count(1)
@@ -142,14 +142,14 @@ def test_rename_property(live_server, openmap, page):
142
142
  expect(page.locator(".panel.right .umap-field-mytype")).to_be_visible()
143
143
 
144
144
 
145
- def test_delete_property(live_server, openmap, page):
145
+ def test_delete_field(live_server, openmap, page):
146
146
  DataLayerFactory(map=openmap, data=DATALAYER_DATA)
147
147
  page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit#6/48.093/1.890")
148
148
  page.get_by_role("button", name="Manage layers").click()
149
149
  page.locator(".panel").get_by_title("Edit properties in a table").click()
150
150
  expect(page.locator("table th button[data-property=mytype]")).to_have_count(1)
151
151
  page.locator("thead button[data-property=mytype]").click()
152
- page.get_by_text("Delete this column").click()
152
+ page.get_by_text("Delete this field").click()
153
153
  page.get_by_role("button", name="OK").click()
154
154
  expect(page.locator("table th button[data-property=mytype]")).to_have_count(0)
155
155
 
@@ -202,7 +202,8 @@ def test_filter_and_delete_rows(live_server, openmap, page):
202
202
  expect(table.locator("tbody tr")).to_have_count(4)
203
203
  expect(page.locator(".leaflet-marker-icon")).to_have_count(4)
204
204
  table.locator("thead button[data-property=mytype]").click()
205
- page.get_by_role("button", name="Add filter for this column").click()
205
+ page.get_by_role("button", name="Add filter for this field").click()
206
+ page.get_by_role("button", name="OK").click()
206
207
  expect(panel).to_be_visible()
207
208
  panel.get_by_label("even").check()
208
209
  table.locator("thead").get_by_role("checkbox").check()
@@ -214,3 +215,26 @@ def test_filter_and_delete_rows(live_server, openmap, page):
214
215
  expect(table.get_by_text("Point 3")).to_be_visible()
215
216
  expect(table.get_by_text("Point 2")).to_be_hidden()
216
217
  expect(table.get_by_text("Point 4")).to_be_hidden()
218
+
219
+
220
+ def test_add_filter_on_map_field(live_server, openmap, page):
221
+ openmap.settings["properties"]["fields"] = [{"key": "mynumber", "type": "Number"}]
222
+ openmap.save()
223
+ table = page.locator(".panel.full table")
224
+ DataLayerFactory(map=openmap, data=DATALAYER_DATA)
225
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit#6/48.093/1.890")
226
+ page.get_by_role("button", name="Manage layers").click()
227
+ page.locator(".panel").get_by_title("Edit properties in a table").click()
228
+ table.locator("thead button[data-property=mynumber]").click()
229
+ page.get_by_role("button", name="Add filter for this field").click()
230
+ expect(page.locator("dialog").get_by_label("Min/Max", exact=True)).to_be_checked()
231
+ page.locator("dialog").get_by_label("human readable name").fill("My Fun Filter")
232
+ page.wait_for_timeout(300) # Throttling…
233
+ page.get_by_role("button", name="OK").click()
234
+ expect(page.locator(".panel.left.on").get_by_text("My Fun Filter")).to_be_visible()
235
+ with page.expect_response(re.compile("./update/settings/.*")):
236
+ page.get_by_role("button", name="Save").click()
237
+ saved = Map.objects.first()
238
+ assert saved.settings["properties"]["filters"] == [
239
+ {"fieldKey": "mynumber", "widget": "MinMax", "label": "My Fun Filter"}
240
+ ]
@@ -227,7 +227,9 @@ def test_websocket_connection_can_sync_datalayer_properties(
227
227
  peerA.locator("body").press("Escape")
228
228
 
229
229
  peerB.get_by_role("button", name="Manage layers").click()
230
- peerB.locator(".panel.right").get_by_role("button", name="Edit").first.click()
230
+ peerB.locator(".panel.right").get_by_role(
231
+ "button", name="Edit", exact=True
232
+ ).first.click()
231
233
  expect(peerB.locator('input[name="name"]')).to_have_value("synced layer!")
232
234
  expect(peerB.get_by_role("combobox")).to_have_value("Choropleth")
233
235
 
@@ -99,3 +99,13 @@ def test_user_dashboard_search_empty(client, map):
99
99
  body = response.content.decode()
100
100
  assert map.name not in body
101
101
  assert "No map found." in body
102
+
103
+
104
+ def test_user_dashboard_filter_by_tag(client, map):
105
+ new_map = MapFactory(name="A map about bicycle", owner=map.owner, tags=["cycling"])
106
+ client.login(username=map.owner.username, password="123123")
107
+ response = client.get(f"{reverse('user_dashboard')}?tags=cycling")
108
+ assert response.status_code == 200
109
+ body = response.content.decode()
110
+ assert map.name not in body
111
+ assert new_map.name in body
umap/urls.py CHANGED
@@ -124,6 +124,7 @@ i18n_urls += decorated_patterns(
124
124
  path("me/teams", views.UserTeams.as_view(), name="user_teams"),
125
125
  path("me/templates", views.UserTemplates.as_view(), name="user_templates"),
126
126
  path("team/create/", views.TeamNew.as_view(), name="team_new"),
127
+ path("whoami", views.WhoAmI.as_view(), name="whoami"),
127
128
  )
128
129
 
129
130
  if settings.UMAP_ALLOW_EDIT_PROFILE:
umap/views.py CHANGED
@@ -585,6 +585,11 @@ class SessionMixin:
585
585
  }
586
586
 
587
587
 
588
+ class WhoAmI(SessionMixin, View):
589
+ def get(self, request, *args, **kwargs):
590
+ return simple_json_response(user=self.get_user_data())
591
+
592
+
588
593
  class FormLessEditMixin:
589
594
  http_method_names = [
590
595
  "post",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: umap-project
3
- Version: 3.3.6
3
+ Version: 3.4.0b0
4
4
  Summary: Create maps with OpenStreetMap layers in a minute and embed them in your site.
5
5
  Author-email: Yohan Boniface <yb@enix.org>
6
6
  Maintainer-email: David Larlet <david@larlet.fr>
@@ -19,9 +19,9 @@ Requires-Python: >=3.10
19
19
  Requires-Dist: django-agnocomplete==2.2.0
20
20
  Requires-Dist: django-environ==0.12.0
21
21
  Requires-Dist: django-probes==1.7.0
22
- Requires-Dist: django==5.2.5
22
+ Requires-Dist: django==5.2.7
23
23
  Requires-Dist: pillow==11.3.0
24
- Requires-Dist: psycopg==3.2.9
24
+ Requires-Dist: psycopg==3.2.10
25
25
  Requires-Dist: rcssmin==1.2.1
26
26
  Requires-Dist: requests==2.32.5
27
27
  Requires-Dist: rjsmin==1.2.4
@@ -29,32 +29,32 @@ Requires-Dist: social-auth-app-django==5.4.3
29
29
  Requires-Dist: social-auth-core==4.5.6
30
30
  Provides-Extra: dev
31
31
  Requires-Dist: djlint==1.36.4; extra == 'dev'
32
- Requires-Dist: hatch==1.14.1; extra == 'dev'
32
+ Requires-Dist: hatch==1.14.2; extra == 'dev'
33
33
  Requires-Dist: isort==6.0.1; extra == 'dev'
34
- Requires-Dist: mkdocs-material==9.6.18; extra == 'dev'
34
+ Requires-Dist: mkdocs-material==9.6.21; extra == 'dev'
35
35
  Requires-Dist: mkdocs-static-i18n==1.3.0; extra == 'dev'
36
36
  Requires-Dist: mkdocs==1.6.1; extra == 'dev'
37
37
  Requires-Dist: pymdown-extensions==10.16.1; extra == 'dev'
38
- Requires-Dist: ruff==0.12.11; extra == 'dev'
38
+ Requires-Dist: ruff==0.14.0; extra == 'dev'
39
39
  Requires-Dist: vermin==1.6.0; extra == 'dev'
40
40
  Provides-Extra: docker
41
- Requires-Dist: uvicorn==0.35.0; extra == 'docker'
41
+ Requires-Dist: uvicorn==0.37.0; extra == 'docker'
42
42
  Provides-Extra: s3
43
43
  Requires-Dist: django-storages[s3]==1.14.6; extra == 's3'
44
44
  Provides-Extra: sync
45
- Requires-Dist: pydantic==2.11.7; extra == 'sync'
45
+ Requires-Dist: pydantic==2.11.9; extra == 'sync'
46
46
  Requires-Dist: redis==6.4.0; extra == 'sync'
47
47
  Requires-Dist: websockets==15.0.1; extra == 'sync'
48
48
  Provides-Extra: test
49
49
  Requires-Dist: daphne==4.2.1; extra == 'test'
50
50
  Requires-Dist: factory-boy==3.3.3; extra == 'test'
51
- Requires-Dist: moto[s3]==5.1.11; extra == 'test'
51
+ Requires-Dist: moto[s3]==5.1.14; extra == 'test'
52
52
  Requires-Dist: playwright>=1.39; extra == 'test'
53
53
  Requires-Dist: pytest-django==4.11.1; extra == 'test'
54
- Requires-Dist: pytest-playwright==0.7.0; extra == 'test'
55
- Requires-Dist: pytest-rerunfailures==15.1; extra == 'test'
54
+ Requires-Dist: pytest-playwright==0.7.1; extra == 'test'
55
+ Requires-Dist: pytest-rerunfailures==16.0.1; extra == 'test'
56
56
  Requires-Dist: pytest-xdist<4,>=3.5.0; extra == 'test'
57
- Requires-Dist: pytest==8.4.1; extra == 'test'
57
+ Requires-Dist: pytest==8.4.2; extra == 'test'
58
58
  Description-Content-Type: text/markdown
59
59
 
60
60
  [![Matrix](https://img.shields.io/matrix/umap:matrix.org?server_fqdn=matrix.org&logo=matrix)](https://matrix.to/#/#umap:matrix.org)