umap-project 2.9.3__py3-none-any.whl → 3.0.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 (217) hide show
  1. umap/__init__.py +1 -1
  2. umap/context_processors.py +1 -0
  3. umap/forms.py +1 -2
  4. umap/locale/de/LC_MESSAGES/django.mo +0 -0
  5. umap/locale/de/LC_MESSAGES/django.po +218 -96
  6. umap/locale/en/LC_MESSAGES/django.po +128 -52
  7. umap/locale/fr/LC_MESSAGES/django.mo +0 -0
  8. umap/locale/fr/LC_MESSAGES/django.po +128 -52
  9. umap/locale/hu/LC_MESSAGES/django.mo +0 -0
  10. umap/locale/hu/LC_MESSAGES/django.po +209 -88
  11. umap/locale/is/LC_MESSAGES/django.mo +0 -0
  12. umap/locale/is/LC_MESSAGES/django.po +296 -175
  13. umap/migrations/0027_map_tags.py +23 -0
  14. umap/models.py +13 -2
  15. umap/settings/base.py +23 -5
  16. umap/static/umap/base.css +41 -8
  17. umap/static/umap/content.css +72 -37
  18. umap/static/umap/css/bar.css +43 -21
  19. umap/static/umap/css/dialog.css +4 -1
  20. umap/static/umap/css/form.css +40 -27
  21. umap/static/umap/css/icon.css +11 -1
  22. umap/static/umap/css/importers.css +7 -0
  23. umap/static/umap/img/16-white.svg +23 -2
  24. umap/static/umap/img/16.svg +1 -1
  25. umap/static/umap/img/24.svg +4 -4
  26. umap/static/umap/img/home.svg +7 -0
  27. umap/static/umap/img/importers/banfr.svg +1 -0
  28. umap/static/umap/img/marker.svg +2 -5
  29. umap/static/umap/img/source/16-white.svg +24 -3
  30. umap/static/umap/img/source/16.svg +1 -1
  31. umap/static/umap/img/source/24.svg +5 -5
  32. umap/static/umap/img/target.svg +1 -0
  33. umap/static/umap/js/components/alerts/alert.js +0 -1
  34. umap/static/umap/js/modules/browser.js +4 -4
  35. umap/static/umap/js/modules/caption.js +1 -1
  36. umap/static/umap/js/modules/data/features.js +25 -25
  37. umap/static/umap/js/modules/data/layer.js +91 -97
  38. umap/static/umap/js/modules/facets.js +9 -5
  39. umap/static/umap/js/modules/form/builder.js +21 -29
  40. umap/static/umap/js/modules/form/fields.js +40 -14
  41. umap/static/umap/js/modules/formatter.js +1 -1
  42. umap/static/umap/js/modules/global.js +9 -5
  43. umap/static/umap/js/modules/help.js +18 -5
  44. umap/static/umap/js/modules/importer.js +5 -2
  45. umap/static/umap/js/modules/importers/banfr.js +93 -0
  46. umap/static/umap/js/modules/importers/cadastrefr.js +2 -2
  47. umap/static/umap/js/modules/importers/communesfr.js +1 -1
  48. umap/static/umap/js/modules/permissions.js +20 -10
  49. umap/static/umap/js/modules/rendering/icon.js +15 -2
  50. umap/static/umap/js/modules/rendering/layers/classified.js +7 -7
  51. umap/static/umap/js/modules/rendering/layers/cluster.js +2 -2
  52. umap/static/umap/js/modules/rendering/layers/heat.js +4 -4
  53. umap/static/umap/js/modules/rendering/map.js +14 -6
  54. umap/static/umap/js/modules/rendering/popup.js +2 -2
  55. umap/static/umap/js/modules/rendering/template.js +3 -3
  56. umap/static/umap/js/modules/rendering/ui.js +17 -11
  57. umap/static/umap/js/modules/rules.js +13 -16
  58. umap/static/umap/js/modules/schema.js +23 -1
  59. umap/static/umap/js/modules/share.js +1 -1
  60. umap/static/umap/js/modules/slideshow.js +1 -0
  61. umap/static/umap/js/modules/sync/engine.js +141 -19
  62. umap/static/umap/js/modules/sync/undo.js +101 -0
  63. umap/static/umap/js/modules/sync/updaters.js +51 -28
  64. umap/static/umap/js/modules/tableeditor.js +1 -1
  65. umap/static/umap/js/modules/ui/bar.js +61 -21
  66. umap/static/umap/js/modules/ui/tooltip.js +1 -1
  67. umap/static/umap/js/modules/umap.js +190 -176
  68. umap/static/umap/js/modules/utils.js +30 -4
  69. umap/static/umap/js/umap.controls.js +82 -38
  70. umap/static/umap/locale/am_ET.js +11 -6
  71. umap/static/umap/locale/am_ET.json +11 -6
  72. umap/static/umap/locale/ar.js +11 -6
  73. umap/static/umap/locale/ar.json +11 -6
  74. umap/static/umap/locale/ast.js +11 -6
  75. umap/static/umap/locale/ast.json +11 -6
  76. umap/static/umap/locale/bg.js +11 -6
  77. umap/static/umap/locale/bg.json +11 -6
  78. umap/static/umap/locale/br.js +12 -7
  79. umap/static/umap/locale/br.json +12 -7
  80. umap/static/umap/locale/ca.js +11 -6
  81. umap/static/umap/locale/ca.json +11 -6
  82. umap/static/umap/locale/cs_CZ.js +11 -6
  83. umap/static/umap/locale/cs_CZ.json +11 -6
  84. umap/static/umap/locale/da.js +11 -6
  85. umap/static/umap/locale/da.json +11 -6
  86. umap/static/umap/locale/de.js +47 -42
  87. umap/static/umap/locale/de.json +47 -42
  88. umap/static/umap/locale/el.js +11 -6
  89. umap/static/umap/locale/el.json +11 -6
  90. umap/static/umap/locale/en.js +11 -6
  91. umap/static/umap/locale/en.json +11 -6
  92. umap/static/umap/locale/en_US.json +11 -6
  93. umap/static/umap/locale/es.js +11 -6
  94. umap/static/umap/locale/es.json +11 -6
  95. umap/static/umap/locale/et.js +11 -6
  96. umap/static/umap/locale/et.json +11 -6
  97. umap/static/umap/locale/eu.js +11 -6
  98. umap/static/umap/locale/eu.json +11 -6
  99. umap/static/umap/locale/fa_IR.js +11 -6
  100. umap/static/umap/locale/fa_IR.json +11 -6
  101. umap/static/umap/locale/fi.js +11 -6
  102. umap/static/umap/locale/fi.json +11 -6
  103. umap/static/umap/locale/fr.js +11 -6
  104. umap/static/umap/locale/fr.json +11 -6
  105. umap/static/umap/locale/gl.js +12 -7
  106. umap/static/umap/locale/gl.json +12 -7
  107. umap/static/umap/locale/he.js +11 -6
  108. umap/static/umap/locale/he.json +11 -6
  109. umap/static/umap/locale/hr.js +11 -6
  110. umap/static/umap/locale/hr.json +11 -6
  111. umap/static/umap/locale/hu.js +25 -20
  112. umap/static/umap/locale/hu.json +25 -20
  113. umap/static/umap/locale/id.js +11 -6
  114. umap/static/umap/locale/id.json +11 -6
  115. umap/static/umap/locale/is.js +151 -146
  116. umap/static/umap/locale/is.json +151 -146
  117. umap/static/umap/locale/it.js +11 -6
  118. umap/static/umap/locale/it.json +11 -6
  119. umap/static/umap/locale/ja.js +11 -6
  120. umap/static/umap/locale/ja.json +11 -6
  121. umap/static/umap/locale/ko.js +11 -6
  122. umap/static/umap/locale/ko.json +11 -6
  123. umap/static/umap/locale/lt.js +11 -6
  124. umap/static/umap/locale/lt.json +11 -6
  125. umap/static/umap/locale/ms.js +11 -6
  126. umap/static/umap/locale/ms.json +11 -6
  127. umap/static/umap/locale/nl.js +12 -7
  128. umap/static/umap/locale/nl.json +12 -7
  129. umap/static/umap/locale/no.js +11 -6
  130. umap/static/umap/locale/no.json +11 -6
  131. umap/static/umap/locale/pl.js +11 -6
  132. umap/static/umap/locale/pl.json +11 -6
  133. umap/static/umap/locale/pl_PL.json +11 -6
  134. umap/static/umap/locale/pt.js +11 -6
  135. umap/static/umap/locale/pt.json +11 -6
  136. umap/static/umap/locale/pt_BR.js +11 -6
  137. umap/static/umap/locale/pt_BR.json +11 -6
  138. umap/static/umap/locale/pt_PT.js +11 -6
  139. umap/static/umap/locale/pt_PT.json +11 -6
  140. umap/static/umap/locale/ro.js +11 -6
  141. umap/static/umap/locale/ro.json +11 -6
  142. umap/static/umap/locale/ru.js +11 -6
  143. umap/static/umap/locale/ru.json +11 -6
  144. umap/static/umap/locale/sk_SK.js +11 -6
  145. umap/static/umap/locale/sk_SK.json +11 -6
  146. umap/static/umap/locale/sl.js +11 -6
  147. umap/static/umap/locale/sl.json +11 -6
  148. umap/static/umap/locale/sr.js +11 -6
  149. umap/static/umap/locale/sr.json +11 -6
  150. umap/static/umap/locale/sv.js +11 -6
  151. umap/static/umap/locale/sv.json +11 -6
  152. umap/static/umap/locale/th_TH.js +11 -6
  153. umap/static/umap/locale/th_TH.json +11 -6
  154. umap/static/umap/locale/tr.js +11 -6
  155. umap/static/umap/locale/tr.json +11 -6
  156. umap/static/umap/locale/uk_UA.js +11 -6
  157. umap/static/umap/locale/uk_UA.json +11 -6
  158. umap/static/umap/locale/vi.js +11 -6
  159. umap/static/umap/locale/vi.json +11 -6
  160. umap/static/umap/locale/vi_VN.json +11 -6
  161. umap/static/umap/locale/zh.js +11 -6
  162. umap/static/umap/locale/zh.json +11 -6
  163. umap/static/umap/locale/zh_CN.json +11 -6
  164. umap/static/umap/locale/zh_TW.Big5.json +11 -6
  165. umap/static/umap/locale/zh_TW.js +19 -14
  166. umap/static/umap/locale/zh_TW.json +19 -14
  167. umap/static/umap/map.css +58 -28
  168. umap/static/umap/unittests/sync.js +0 -57
  169. umap/static/umap/unittests/utils.js +47 -0
  170. umap/static/umap/vars.css +5 -2
  171. umap/static/umap/vendors/photon/leaflet.photon.js +3 -0
  172. umap/sync/payloads.py +3 -2
  173. umap/templates/auth/user_detail.html +1 -1
  174. umap/templates/auth/user_stars.html +1 -1
  175. umap/templates/umap/content.html +17 -12
  176. umap/templates/umap/home.html +7 -5
  177. umap/templates/umap/map_fragment.html +1 -1
  178. umap/templates/umap/map_list.html +20 -13
  179. umap/templates/umap/search.html +7 -3
  180. umap/templates/umap/search_bar.html +13 -11
  181. umap/templates/umap/team_detail.html +1 -1
  182. umap/tests/base.py +2 -1
  183. umap/tests/fixtures/remote_data.umap +55 -0
  184. umap/tests/fixtures/test_upload_data_with_iconurl.umap +122 -0
  185. umap/tests/integration/test_browser.py +1 -3
  186. umap/tests/integration/test_conditional_rules.py +3 -0
  187. umap/tests/integration/test_edit_datalayer.py +2 -7
  188. umap/tests/integration/test_edit_map.py +15 -0
  189. umap/tests/integration/test_edit_polygon.py +1 -2
  190. umap/tests/integration/test_import.py +59 -2
  191. umap/tests/integration/test_optimistic_merge.py +4 -3
  192. umap/tests/integration/test_owned_map.py +0 -1
  193. umap/tests/integration/test_save.py +2 -4
  194. umap/tests/integration/test_undo_redo.py +267 -0
  195. umap/tests/integration/test_websocket_sync.py +78 -11
  196. umap/tests/settings.py +1 -3
  197. umap/tests/test_datalayer_s3.py +1 -0
  198. umap/tests/test_map_views.py +1 -0
  199. umap/tests/test_views.py +34 -0
  200. umap/utils.py +1 -1
  201. umap/views.py +23 -2
  202. {umap_project-2.9.3.dist-info → umap_project-3.0.0.dist-info}/METADATA +13 -12
  203. {umap_project-2.9.3.dist-info → umap_project-3.0.0.dist-info}/RECORD +206 -208
  204. umap/static/umap/js/modules/saving.js +0 -52
  205. umap/static/umap/test/.eslintrc +0 -21
  206. umap/static/umap/test/DataLayer.js +0 -463
  207. umap/static/umap/test/Feature.js +0 -131
  208. umap/static/umap/test/Map.js +0 -37
  209. umap/static/umap/test/Marker.js +0 -126
  210. umap/static/umap/test/Polygon.js +0 -111
  211. umap/static/umap/test/Polyline.js +0 -286
  212. umap/static/umap/test/Util.js +0 -28
  213. umap/static/umap/test/_pre.js +0 -455
  214. umap/static/umap/test/index.html +0 -139
  215. {umap_project-2.9.3.dist-info → umap_project-3.0.0.dist-info}/WHEEL +0 -0
  216. {umap_project-2.9.3.dist-info → umap_project-3.0.0.dist-info}/entry_points.txt +0 -0
  217. {umap_project-2.9.3.dist-info → umap_project-3.0.0.dist-info}/licenses/LICENSE +0 -0
@@ -27,10 +27,7 @@ const locale = {
27
27
  "Allow scroll wheel zoom?": "允許捲動放大?",
28
28
  "always": "經常",
29
29
  "Animated transitions": "動畫轉換",
30
- "Are you sure you want to cancel your changes?": "您確定要取消您所做的變更?",
31
30
  "Are you sure you want to clone this map and all its datalayers?": "您確定要複製此地圖及所有資料圖層?",
32
- "Are you sure you want to delete the feature?": "您確定要刪除該圖徵?",
33
- "Are you sure you want to delete this layer?": "你確定要刪除這個圖層嗎?",
34
31
  "Are you sure you want to delete this map?": "您確定要刪除此地圖?",
35
32
  "Are you sure you want to delete this property on all the features?": "您確定要刪除所有圖徵中的此項屬性?",
36
33
  "Are you sure you want to restore this version?": "您確定要回復此一版本嗎?",
@@ -46,7 +43,6 @@ const locale = {
46
43
  "Browse data": "瀏覽資料",
47
44
  "by": "由",
48
45
  "Cache proxied request": "快取代理請求",
49
- "Cancel edits": "取消編輯",
50
46
  "Caption": "標題",
51
47
  "Center map on your location": "將您的位置設為地圖中心",
52
48
  "Change map background": "更改地圖背景",
@@ -524,16 +520,25 @@ const locale = {
524
520
  "Cannot parse remote data for layer \"{layer}\" with url \"{url}\"": "無法用網址 \"{url}\" 為圖層 \"{layer}\" 解析遠端資料",
525
521
  "Import failed: invalid data": "匯入失敗:無效的資料",
526
522
  "Anonymous": "暱名",
527
- "created at {date}": "created at {date}",
528
- "modified at {date}": "modified at {date}",
529
- "Default zoom": "Default zoom",
530
- "Default latitude": "Default latitude",
531
- "Default longitude": "Default longitude",
532
- "Edit map default view": "Edit map default view",
533
- "Use current center and zoom": "Use current center and zoom",
534
- "Layer permalink": "Layer permalink",
535
- "Save this geometry as a new feature": "Save this geometry as a new feature",
536
- "Save this place as a new feature": "Save this place as a new feature"
523
+ "created at {date}": " {date} 創建",
524
+ "modified at {date}": " {date} 變更",
525
+ "Default zoom": "預設縮放大小",
526
+ "Default latitude": "預設緯度",
527
+ "Default longitude": "預設經度",
528
+ "Edit map default view": "編輯地圖預設檢視",
529
+ "Use current center and zoom": "使用目前中心與縮放大小",
530
+ "Layer permalink": "圖層永久連結",
531
+ "Back to home": "Back to home",
532
+ "Home logo": "Home logo",
533
+ "Add this geometry to my map": "Add this geometry to my map",
534
+ "Add this place to my map": "Add this place to my map",
535
+ "Cancel last edit": "Cancel last edit",
536
+ "Redo last edit": "Redo last edit",
537
+ "Links": "Links",
538
+ "Images": "Images",
539
+ "Iframes": "Iframes",
540
+ "Tags": "Tags",
541
+ "Geocode": "Geocode"
537
542
  }
538
543
  L.registerLocale("zh_TW", locale)
539
544
  L.setLocale("zh_TW")
@@ -27,10 +27,7 @@
27
27
  "Allow scroll wheel zoom?": "允許捲動放大?",
28
28
  "always": "經常",
29
29
  "Animated transitions": "動畫轉換",
30
- "Are you sure you want to cancel your changes?": "您確定要取消您所做的變更?",
31
30
  "Are you sure you want to clone this map and all its datalayers?": "您確定要複製此地圖及所有資料圖層?",
32
- "Are you sure you want to delete the feature?": "您確定要刪除該圖徵?",
33
- "Are you sure you want to delete this layer?": "你確定要刪除這個圖層嗎?",
34
31
  "Are you sure you want to delete this map?": "您確定要刪除此地圖?",
35
32
  "Are you sure you want to delete this property on all the features?": "您確定要刪除所有圖徵中的此項屬性?",
36
33
  "Are you sure you want to restore this version?": "您確定要回復此一版本嗎?",
@@ -46,7 +43,6 @@
46
43
  "Browse data": "瀏覽資料",
47
44
  "by": "由",
48
45
  "Cache proxied request": "快取代理請求",
49
- "Cancel edits": "取消編輯",
50
46
  "Caption": "標題",
51
47
  "Center map on your location": "將您的位置設為地圖中心",
52
48
  "Change map background": "更改地圖背景",
@@ -524,14 +520,23 @@
524
520
  "Cannot parse remote data for layer \"{layer}\" with url \"{url}\"": "無法用網址 \"{url}\" 為圖層 \"{layer}\" 解析遠端資料",
525
521
  "Import failed: invalid data": "匯入失敗:無效的資料",
526
522
  "Anonymous": "暱名",
527
- "created at {date}": "created at {date}",
528
- "modified at {date}": "modified at {date}",
529
- "Default zoom": "Default zoom",
530
- "Default latitude": "Default latitude",
531
- "Default longitude": "Default longitude",
532
- "Edit map default view": "Edit map default view",
533
- "Use current center and zoom": "Use current center and zoom",
534
- "Layer permalink": "Layer permalink",
535
- "Save this geometry as a new feature": "Save this geometry as a new feature",
536
- "Save this place as a new feature": "Save this place as a new feature"
523
+ "created at {date}": " {date} 創建",
524
+ "modified at {date}": " {date} 變更",
525
+ "Default zoom": "預設縮放大小",
526
+ "Default latitude": "預設緯度",
527
+ "Default longitude": "預設經度",
528
+ "Edit map default view": "編輯地圖預設檢視",
529
+ "Use current center and zoom": "使用目前中心與縮放大小",
530
+ "Layer permalink": "圖層永久連結",
531
+ "Back to home": "Back to home",
532
+ "Home logo": "Home logo",
533
+ "Add this geometry to my map": "Add this geometry to my map",
534
+ "Add this place to my map": "Add this place to my map",
535
+ "Cancel last edit": "Cancel last edit",
536
+ "Redo last edit": "Redo last edit",
537
+ "Links": "Links",
538
+ "Images": "Images",
539
+ "Iframes": "Iframes",
540
+ "Tags": "Tags",
541
+ "Geocode": "Geocode"
537
542
  }
umap/static/umap/map.css CHANGED
@@ -37,7 +37,6 @@ html[dir="rtl"] .leaflet-tooltip-pane > * {
37
37
  background-color: var(--color-lightGray);
38
38
  }
39
39
 
40
-
41
40
  /* *********** */
42
41
  /* Structure */
43
42
  /* *********** */
@@ -94,6 +93,8 @@ html[dir="rtl"] .leaflet-tooltip-pane > * {
94
93
  background-image: url('./img/24.svg');
95
94
  text-indent: -9999px;
96
95
  margin-bottom: 0;
96
+ background-color: white;
97
+ min-height: initial;
97
98
  }
98
99
  .leaflet-control.display-on-more,
99
100
  .umap-control-less {
@@ -247,7 +248,19 @@ html[dir="rtl"] .leaflet-tooltip-pane > * {
247
248
  .leaflet-iconLayers:hover .leaflet-iconLayers-layerCell-plus {
248
249
  display: block;
249
250
  }
250
-
251
+ .home-button {
252
+ cursor: pointer;
253
+ line-height: 0;
254
+ border: 1px solid var(--color-darkBlue);
255
+ border-radius: 50%;
256
+ background-color: var(--background-color);
257
+ }
258
+ .home-button:hover {
259
+ background-color: var(--color-lighterGray);
260
+ }
261
+ .umap-edit-enabled .home-button {
262
+ display: none;
263
+ }
251
264
 
252
265
 
253
266
 
@@ -263,18 +276,30 @@ ul.photon-autocomplete {
263
276
  .photon-autocomplete li {
264
277
  min-height: 40px;
265
278
  line-height: 1em;
266
- padding: 5px 10px;
279
+ padding-inline-start: 10px;
267
280
  overflow: hidden;
268
281
  white-space: nowrap;
269
282
  font-size: 1em;
270
- border-inline-start: 4px solid #efefef;
283
+ border-inline-start: 4px solid var(--color-lightGray);
271
284
  }
272
285
  .photon-autocomplete li strong {
273
286
  display: block;
287
+ margin-top: 5px;
288
+ }
289
+ .photon-autocomplete button {
290
+ margin: 0;
291
+ }
292
+ .photon-autocomplete button:hover {
293
+ background-color: var(--color-darkCyan);
294
+ }
295
+ .photon-autocomplete button:hover i {
296
+ /* TODO deal with this in icon.css */
297
+ background-image: url('./img/16-white.svg');
274
298
  }
275
299
  .photon-autocomplete li.on {
276
- border-inline-start: 4px solid #2980b9;
300
+ border-inline-start: 4px solid var(--color-darkCyan);
277
301
  cursor: pointer;
302
+ background-color: var(--color-lightCyan);
278
303
  }
279
304
  .photon-autocomplete li.photon-no-result {
280
305
  text-align: center;
@@ -292,7 +317,13 @@ ul.photon-autocomplete {
292
317
  }
293
318
  .search-result-tools {
294
319
  float: inline-end;
295
- display: block;
320
+ display: none;
321
+ }
322
+ .search-result-tools button {
323
+ padding: 8px;
324
+ }
325
+ .umap-edit-enabled .photon-autocomplete li.on .search-result-tools {
326
+ display: flex;
296
327
  }
297
328
 
298
329
 
@@ -419,7 +450,7 @@ ul.photon-autocomplete {
419
450
  display: inline-block;
420
451
  width: 16px;
421
452
  height: 16px;
422
- margin-inline-start: 5px;
453
+ margin-inline-start: 2px;
423
454
  background-position: 2px -4px;
424
455
  background-repeat: no-repeat;
425
456
  background-image: url('./img/16.svg');
@@ -440,27 +471,12 @@ ul.photon-autocomplete {
440
471
  }
441
472
  .umap-getstarted button {
442
473
  width: 100%;
474
+ margin-bottom: var(--text-margin);
443
475
  }
444
476
  .umap-help {
445
477
  font-style: italic;
446
478
  }
447
479
 
448
-
449
-
450
- .umap-datalayer-version {
451
- padding: 5px 0;
452
- border-bottom: 1px solid #202425;
453
- }
454
- .umap-datalayer-version button {
455
- display: inline-block;
456
- width: 24px;
457
- min-height: 24px;
458
- background-position: -122px -73px;
459
- background-repeat: no-repeat;
460
- background-image: url('./img/16-white.svg');
461
- margin-inline-end: 10px;
462
- }
463
-
464
480
  .leaflet-toolbar-tip {
465
481
  background-color: var(--color-darkGray);
466
482
  }
@@ -646,9 +662,9 @@ a.umap-control-caption,
646
662
  .umap-caption .header i.icon {
647
663
  flex-shrink: 0;
648
664
  }
649
- .umap-caption hgroup p,
650
- .umap-caption hgroup button {
651
- margin: 0;
665
+ .umap-caption button {
666
+ background-color: var(--background-color);
667
+ color: var(--text-color);
652
668
  }
653
669
  .umap-browser .main-toolbox {
654
670
  padding-left: 4px; /* Align with toolbox below */
@@ -882,7 +898,21 @@ a.umap-control-caption,
882
898
  .umap-edit-enabled .readonly {
883
899
  cursor: not-allowed;
884
900
  }
885
-
901
+ .leaflet-container .umap-raw-icon img {
902
+ max-height: 48px !important;
903
+ max-width: 48px !important;
904
+ }
905
+ .umap-raw-icon {
906
+ display: flex;
907
+ flex-direction: column;
908
+ justify-content: center;
909
+ align-items: center;
910
+ align-content: center;
911
+ overflow: hidden;
912
+ }
913
+ .umap-raw-icon.umap-icon-active {
914
+ box-shadow: var(--block-shadow);
915
+ }
886
916
 
887
917
  /* ********************************* */
888
918
  /* Ajax loader */
@@ -976,7 +1006,7 @@ a.umap-control-caption,
976
1006
  .umap-main-edit-toolbox .umap-user span,
977
1007
  .leaflet-container .leaflet-control-edit-save span,
978
1008
  .leaflet-container .leaflet-control-edit-disable span,
979
- .leaflet-container .leaflet-control-edit-cancel span {
1009
+ .leaflet-container .edit-cancel span {
980
1010
  display: none;
981
1011
  }
982
1012
  .umap-main-edit-toolbox .umap-help-button {
@@ -49,63 +49,6 @@ describe('#dispatch', () => {
49
49
  })
50
50
  })
51
51
 
52
- describe('Updaters', () => {
53
- describe('BaseUpdater', () => {
54
- let updater
55
- let map
56
- let obj
57
-
58
- beforeEach(() => {
59
- map = {}
60
- updater = new MapUpdater(map)
61
- obj = {}
62
- })
63
- it('should be able to set object properties', () => {
64
- let obj = {}
65
- updater.updateObjectValue(obj, 'foo', 'foo')
66
- expect(obj).deep.equal({ foo: 'foo' })
67
- })
68
-
69
- it('should be able to set object properties recursively on existing objects', () => {
70
- let obj = { foo: {} }
71
- updater.updateObjectValue(obj, 'foo.bar', 'foo')
72
- expect(obj).deep.equal({ foo: { bar: 'foo' } })
73
- })
74
-
75
- it('should be able to set object properties recursively on deep objects', () => {
76
- let obj = { foo: { bar: { baz: {} } } }
77
- updater.updateObjectValue(obj, 'foo.bar.baz.test', 'value')
78
- expect(obj).deep.equal({ foo: { bar: { baz: { test: 'value' } } } })
79
- })
80
-
81
- it('should be able to replace object properties recursively on deep objects', () => {
82
- let obj = { foo: { bar: { baz: { test: 'test' } } } }
83
- updater.updateObjectValue(obj, 'foo.bar.baz.test', 'value')
84
- expect(obj).deep.equal({ foo: { bar: { baz: { test: 'value' } } } })
85
- })
86
-
87
- it('should not set object properties recursively on non-existing objects', () => {
88
- let obj = { foo: {} }
89
- updater.updateObjectValue(obj, 'bar.bar', 'value')
90
-
91
- expect(obj).deep.equal({ foo: {} })
92
- })
93
-
94
- it('should delete keys for undefined values', () => {
95
- let obj = { foo: 'foo' }
96
- updater.updateObjectValue(obj, 'foo', undefined)
97
-
98
- expect(obj).deep.equal({})
99
- })
100
-
101
- it('should delete keys for undefined values, recursively', () => {
102
- let obj = { foo: { bar: 'bar' } }
103
- updater.updateObjectValue(obj, 'foo.bar', undefined)
104
-
105
- expect(obj).deep.equal({ foo: {} })
106
- })
107
- })
108
- })
109
52
 
110
53
  describe('Operations', () => {
111
54
  describe('haveSameContext', () => {
@@ -862,4 +862,51 @@ describe('Utils', () => {
862
862
  assert.equal(Utils.isObject(''), false)
863
863
  })
864
864
  })
865
+
866
+ describe('setObjectValue', () => {
867
+ it('should be able to set object properties', () => {
868
+ let obj = {}
869
+ Utils.setObjectValue(obj, 'foo', 'foo')
870
+ expect(obj).deep.equal({ foo: 'foo' })
871
+ })
872
+
873
+ it('should be able to set object properties recursively on existing objects', () => {
874
+ let obj = { foo: {} }
875
+ Utils.setObjectValue(obj, 'foo.bar', 'foo')
876
+ expect(obj).deep.equal({ foo: { bar: 'foo' } })
877
+ })
878
+
879
+ it('should be able to set object properties recursively on deep objects', () => {
880
+ let obj = { foo: { bar: { baz: {} } } }
881
+ Utils.setObjectValue(obj, 'foo.bar.baz.test', 'value')
882
+ expect(obj).deep.equal({ foo: { bar: { baz: { test: 'value' } } } })
883
+ })
884
+
885
+ it('should be able to replace object properties recursively on deep objects', () => {
886
+ let obj = { foo: { bar: { baz: { test: 'test' } } } }
887
+ Utils.setObjectValue(obj, 'foo.bar.baz.test', 'value')
888
+ expect(obj).deep.equal({ foo: { bar: { baz: { test: 'value' } } } })
889
+ })
890
+
891
+ it('should not set object properties recursively on non-existing objects', () => {
892
+ let obj = { foo: {} }
893
+ Utils.setObjectValue(obj, 'bar.bar', 'value')
894
+
895
+ expect(obj).deep.equal({ foo: {} })
896
+ })
897
+
898
+ it('should delete keys for undefined values', () => {
899
+ let obj = { foo: 'foo' }
900
+ Utils.setObjectValue(obj, 'foo', undefined)
901
+
902
+ expect(obj).deep.equal({})
903
+ })
904
+
905
+ it('should delete keys for undefined values, recursively', () => {
906
+ let obj = { foo: { bar: 'bar' } }
907
+ Utils.setObjectValue(obj, 'foo.bar', undefined)
908
+
909
+ expect(obj).deep.equal({ foo: {} })
910
+ })
911
+ })
865
912
  })
umap/static/umap/vars.css CHANGED
@@ -1,6 +1,5 @@
1
1
  :root {
2
2
  /* Colors. */
3
- --color-waterMint: #B9F5D2;
4
3
  --color-darkBlue: #263B58;
5
4
  --color-lighterGray: #f6f6f6;
6
5
  --color-lightGray: #ddd;
@@ -12,15 +11,17 @@
12
11
  --color-limeGreen: #b9f5d2;
13
12
  --color-brightCyan: #46ece6;
14
13
  --color-lightCyan: #d4fbf9;
14
+ --color-darkCyan: #009099;
15
15
  --color-red: #c60f13;
16
16
  --color-darkRed: #5b2a2a;
17
17
 
18
18
  --background-color: var(--color-light);
19
19
  --color-accent: var(--color-brightCyan);
20
20
  --text-color: var(--color-dark);
21
+ --link-color: var(--color-darkCyan);
21
22
 
22
23
  /* Buttons. */
23
- --button-primary-background: var(--color-waterMint);
24
+ --button-primary-background: var(--color-limeGreen);
24
25
  --button-primary-color: var(--color-darkBlue);
25
26
  --button-neutral-background: var(--color-lightGray);
26
27
  --button-neutral-color: var(--color-darkGray);
@@ -43,6 +44,8 @@
43
44
  --small-box-padding: 4px;
44
45
  --box-margin: 14px;
45
46
  --text-margin: 7px;
47
+ --dialog-width: 40vw;
48
+ --map-fragment-height: 210px;
46
49
 
47
50
  /* z-indexes (leaflet CSS sets the map at 400 by default) */
48
51
  --zindex-alert: 500;
@@ -258,6 +258,9 @@ L.PhotonBaseSearch = L.PhotonBase.extend({
258
258
  if (feature.properties.city && feature.properties.city !== feature.properties.name) {
259
259
  details.push(feature.properties.city);
260
260
  }
261
+ if (feature.properties.state && feature.properties.state !== feature.properties.name) {
262
+ details.push(feature.properties.state);
263
+ }
261
264
  if (feature.properties.country) details.push(feature.properties.country);
262
265
  detailsContainer.innerHTML = details.join(', ');
263
266
  },
umap/sync/payloads.py CHANGED
@@ -1,4 +1,4 @@
1
- from typing import Literal, Optional, Union
1
+ from typing import List, Literal, Optional, Union
2
2
 
3
3
  from pydantic import BaseModel, Field, RootModel
4
4
 
@@ -14,10 +14,11 @@ class OperationMessage(BaseModel):
14
14
  """Message sent from one peer to all the others"""
15
15
 
16
16
  kind: Literal["OperationMessage"] = "OperationMessage"
17
- verb: Literal["upsert", "update", "delete"]
17
+ verb: Literal["upsert", "update", "delete", "batch"]
18
18
  subject: Literal["map", "datalayer", "feature"]
19
19
  metadata: Optional[dict] = None
20
20
  key: Optional[str] = None
21
+ operations: Optional[List] = None
21
22
 
22
23
 
23
24
  class PeerMessage(BaseModel):
@@ -13,7 +13,7 @@
13
13
  </h2>
14
14
  </div>
15
15
  <div class="wrapper">
16
- <div class="map_list row">
16
+ <div class="row grid-container">
17
17
  {% if maps %}
18
18
  {% include "umap/map_list.html" %}
19
19
  {% else %}
@@ -13,7 +13,7 @@
13
13
  </h2>
14
14
  </div>
15
15
  <div class="wrapper">
16
- <div class="map_list row">
16
+ <div class="grid-container row">
17
17
  {% if maps %}
18
18
  {% include "umap/map_list.html" %}
19
19
  {% else %}
@@ -43,22 +43,27 @@
43
43
  <script type="text/javascript">
44
44
  window.addEventListener('DOMContentLoaded', event => {
45
45
  const server = new U.ServerRequest()
46
- const getMore = async function (e) {
47
- L.DomEvent.stop(e)
48
- const [{html}, response, error] = await server.get(this.href)
46
+ const getMore = async function (link) {
47
+ const container = link.parentNode
48
+ container.removeChild(link)
49
+ const [{html}, response, error] = await server.get(link.href)
49
50
  if (!error) {
50
- const container = this.parentNode
51
- container.innerHTML = html
52
- const more = document.querySelector('.more_button')
53
- if (more) {
54
- L.DomEvent.on(more, 'click', getMore, more)
55
- }
51
+ const template = document.createElement('template')
52
+ template.innerHTML = html
53
+ container.appendChild(template.content)
54
+ listenForMore()
56
55
  }
57
56
  }
58
- const more = document.querySelector('.more_button')
59
- if (more) {
60
- L.DomEvent.on(more, 'click', getMore, more)
57
+ const listenForMore = () => {
58
+ const more = document.querySelector('.more_button')
59
+ if (more) {
60
+ L.DomEvent.on(more, 'click', (e) => {
61
+ L.DomEvent.stop(e)
62
+ getMore(more)
63
+ })
64
+ }
61
65
  }
66
+ listenForMore()
62
67
  })
63
68
  </script>
64
69
  {% endblock bottom_js %}
@@ -20,11 +20,13 @@
20
20
  {% endif %}
21
21
  <div class="wrapper">
22
22
  {% if maps %}
23
- <h2 class="section">
24
- {% blocktrans %}Get inspired, browse maps{% endblocktrans %}
25
- </h2>
26
- <div class="map_list row">
27
- {% include "umap/map_list.html" %}
23
+ <div class="row">
24
+ <h2 class="section">
25
+ {% blocktrans %}Get inspired, browse maps{% endblocktrans %}
26
+ </h2>
27
+ <div class="grid-container">
28
+ {% include "umap/map_list.html" %}
29
+ </div>
28
30
  </div>
29
31
  {% endif %}
30
32
  </div>
@@ -1,6 +1,6 @@
1
1
  {% load umap_tags %}
2
2
 
3
- <umap-fragment data-settings='{{ map_settings|escape }}'>
3
+ <umap-fragment data-settings='{{ map_settings|escape }}' inert>
4
4
  <div id="{{ unique_id }}" class="map_fragment">
5
5
  </div>
6
6
  </umap-fragment>
@@ -1,22 +1,29 @@
1
1
  {% load umap_tags i18n %}
2
2
 
3
3
  {% for map_inst in maps %}
4
- <hr />
5
- <div class="col wide">
4
+ <div class="card">
6
5
  {% map_fragment map_inst prefix=prefix page=request.GET.p %}
7
- <div class="legend">
8
- <a href="{{ map_inst.get_absolute_url }}">{{ map_inst.name }}</a>
9
- {% with author=map_inst.get_author %}
10
- {% if author %}
11
- <em>{% trans "by" %} <a href="{{ author.get_url }}">{{ author }}</a></em>
6
+ <hgroup>
7
+ <div>
8
+ {% if map_inst.tags %}
9
+ <ul class="tag-list">
10
+ {% for tag, label in map_inst.get_tags_display %}
11
+ <li><a href="{% url 'search' %}?tags={{ tag }}">{{ label }}</a></li>
12
+ {% endfor %}
13
+ </ul>
12
14
  {% endif %}
13
- {% endwith %}
14
- </div>
15
+ <h3>{{ map_inst.name }}</h3>
16
+ {% with author=map_inst.get_author %}
17
+ {% if author %}
18
+ <p>{% trans "by" %} <a href="{{ author.get_url }}">{{ author }}</a></p>
19
+ {% endif %}
20
+ {% endwith %}
21
+ </div>
22
+ <a class="main" href="{{ map_inst.get_absolute_url }}">{% translate "See the map" %}</a>
23
+ </hgroup>
15
24
  </div>
16
25
  {% endfor %}
17
26
  {% if maps.has_next %}
18
- <div class="col wide">
19
- <a href="?{% paginate_querystring maps.next_page_number %}"
20
- class="button more_button neutral">{% trans "More" %}</a>
21
- </div>
27
+ <a href="?{% paginate_querystring maps.next_page_number %}"
28
+ class="button more_button neutral">{% trans "More" %}</a>
22
29
  {% endif %}
@@ -12,7 +12,7 @@
12
12
  {% block maincontent %}
13
13
  {% include "umap/search_bar.html" %}
14
14
  <div class="wrapper">
15
- <div class="map_list row">
15
+ <div class="row">
16
16
  {% if request.GET.q %}
17
17
  {% if maps %}
18
18
  <h2>
@@ -22,7 +22,9 @@
22
22
  {{ count }} maps found:
23
23
  {% endblocktranslate %}
24
24
  </h2>
25
- {% include "umap/map_list.html" with prefix="search_map" %}
25
+ <div class="grid-container">
26
+ {% include "umap/map_list.html" with prefix="search_map" %}
27
+ </div>
26
28
  {% else %}
27
29
  <h2>
28
30
  {% trans "No map found." %}
@@ -32,7 +34,9 @@
32
34
  <h2>
33
35
  {% trans "Latest created maps" %}
34
36
  </h2>
35
- {% include "umap/map_list.html" with prefix="search_map" %}
37
+ <div class="grid-container">
38
+ {% include "umap/map_list.html" with prefix="search_map" %}
39
+ </div>
36
40
  {% endif %}
37
41
  </div>
38
42
  </div>
@@ -4,17 +4,19 @@
4
4
  {% trans "Search maps" as default_placeholder %}
5
5
  <div class="wrapper search_wrapper">
6
6
  <div class="row">
7
- <form action="{% firstof action search_url %}" method="get">
8
- <div class="col two-third mwide">
9
- <input name="q"
10
- type="search"
11
- placeholder="{% firstof placeholder default_placeholder %}"
12
- aria-label="{% firstof placeholder default_placeholder %}"
13
- value="{{ request.GET.q|default:"" }}" />
14
- </div>
15
- <div class="col third mwide">
16
- <input type="submit" value="{% trans "Search" %}" class="neutral" />
17
- </div>
7
+ <form class="search-form flex-break" action="{% firstof action search_url %}" method="get">
8
+ <input name="q"
9
+ type="search"
10
+ placeholder="{% firstof placeholder default_placeholder %}"
11
+ aria-label="{% firstof placeholder default_placeholder %}"
12
+ value="{{ request.GET.q|default:"" }}" />
13
+ <select name="tags">
14
+ <option value="">{% trans "Any category" %}</option>
15
+ {% for value, label in UMAP_TAGS %}
16
+ <option value="{{ value }}" {% if request.GET.tags == value %}selected{% endif %}>{{ label }}</option>
17
+ {% endfor %}
18
+ </select>
19
+ <input type="submit" value="{% trans "Search" %}" />
18
20
  </form>
19
21
  </div>
20
22
  </div>
@@ -18,7 +18,7 @@
18
18
  {% endif %}
19
19
  </div>
20
20
  </div>
21
- <div class="map_list row">
21
+ <div class="grid-container row">
22
22
  {% if maps %}
23
23
  {% include "umap/map_list.html" %}
24
24
  {% else %}