umap-project 2.8.0a2__py3-none-any.whl → 2.8.1__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 (134) hide show
  1. umap/__init__.py +1 -1
  2. umap/decorators.py +3 -1
  3. umap/locale/ar/LC_MESSAGES/django.mo +0 -0
  4. umap/locale/ar/LC_MESSAGES/django.po +45 -30
  5. umap/locale/br/LC_MESSAGES/django.mo +0 -0
  6. umap/locale/br/LC_MESSAGES/django.po +49 -34
  7. umap/locale/ca/LC_MESSAGES/django.mo +0 -0
  8. umap/locale/ca/LC_MESSAGES/django.po +45 -30
  9. umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
  10. umap/locale/cs_CZ/LC_MESSAGES/django.po +52 -37
  11. umap/locale/da/LC_MESSAGES/django.mo +0 -0
  12. umap/locale/da/LC_MESSAGES/django.po +45 -30
  13. umap/locale/de/LC_MESSAGES/django.mo +0 -0
  14. umap/locale/de/LC_MESSAGES/django.po +45 -30
  15. umap/locale/el/LC_MESSAGES/django.mo +0 -0
  16. umap/locale/el/LC_MESSAGES/django.po +45 -30
  17. umap/locale/en/LC_MESSAGES/django.po +44 -29
  18. umap/locale/es/LC_MESSAGES/django.mo +0 -0
  19. umap/locale/es/LC_MESSAGES/django.po +45 -30
  20. umap/locale/et/LC_MESSAGES/django.mo +0 -0
  21. umap/locale/et/LC_MESSAGES/django.po +45 -30
  22. umap/locale/eu/LC_MESSAGES/django.mo +0 -0
  23. umap/locale/eu/LC_MESSAGES/django.po +65 -50
  24. umap/locale/fa_IR/LC_MESSAGES/django.mo +0 -0
  25. umap/locale/fa_IR/LC_MESSAGES/django.po +45 -30
  26. umap/locale/fr/LC_MESSAGES/django.mo +0 -0
  27. umap/locale/fr/LC_MESSAGES/django.po +45 -30
  28. umap/locale/gl/LC_MESSAGES/django.mo +0 -0
  29. umap/locale/gl/LC_MESSAGES/django.po +45 -30
  30. umap/locale/he/LC_MESSAGES/django.mo +0 -0
  31. umap/locale/he/LC_MESSAGES/django.po +45 -30
  32. umap/locale/hu/LC_MESSAGES/django.mo +0 -0
  33. umap/locale/hu/LC_MESSAGES/django.po +45 -30
  34. umap/locale/is/LC_MESSAGES/django.mo +0 -0
  35. umap/locale/is/LC_MESSAGES/django.po +45 -30
  36. umap/locale/it/LC_MESSAGES/django.mo +0 -0
  37. umap/locale/it/LC_MESSAGES/django.po +45 -30
  38. umap/locale/ja/LC_MESSAGES/django.mo +0 -0
  39. umap/locale/ja/LC_MESSAGES/django.po +45 -30
  40. umap/locale/ko/LC_MESSAGES/django.mo +0 -0
  41. umap/locale/ko/LC_MESSAGES/django.po +45 -30
  42. umap/locale/lt/LC_MESSAGES/django.mo +0 -0
  43. umap/locale/lt/LC_MESSAGES/django.po +45 -30
  44. umap/locale/ms/LC_MESSAGES/django.mo +0 -0
  45. umap/locale/ms/LC_MESSAGES/django.po +45 -30
  46. umap/locale/nl/LC_MESSAGES/django.mo +0 -0
  47. umap/locale/nl/LC_MESSAGES/django.po +45 -30
  48. umap/locale/pl/LC_MESSAGES/django.mo +0 -0
  49. umap/locale/pl/LC_MESSAGES/django.po +45 -30
  50. umap/locale/pt/LC_MESSAGES/django.mo +0 -0
  51. umap/locale/pt/LC_MESSAGES/django.po +45 -30
  52. umap/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
  53. umap/locale/pt_BR/LC_MESSAGES/django.po +45 -30
  54. umap/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
  55. umap/locale/pt_PT/LC_MESSAGES/django.po +45 -30
  56. umap/locale/ru/LC_MESSAGES/django.mo +0 -0
  57. umap/locale/ru/LC_MESSAGES/django.po +45 -30
  58. umap/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
  59. umap/locale/sk_SK/LC_MESSAGES/django.po +45 -30
  60. umap/locale/sl/LC_MESSAGES/django.mo +0 -0
  61. umap/locale/sl/LC_MESSAGES/django.po +45 -30
  62. umap/locale/sr/LC_MESSAGES/django.mo +0 -0
  63. umap/locale/sr/LC_MESSAGES/django.po +45 -30
  64. umap/locale/sv/LC_MESSAGES/django.mo +0 -0
  65. umap/locale/sv/LC_MESSAGES/django.po +45 -30
  66. umap/locale/th_TH/LC_MESSAGES/django.mo +0 -0
  67. umap/locale/th_TH/LC_MESSAGES/django.po +45 -30
  68. umap/locale/tr/LC_MESSAGES/django.mo +0 -0
  69. umap/locale/tr/LC_MESSAGES/django.po +45 -30
  70. umap/locale/uk_UA/LC_MESSAGES/django.mo +0 -0
  71. umap/locale/uk_UA/LC_MESSAGES/django.po +45 -30
  72. umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
  73. umap/locale/zh_TW/LC_MESSAGES/django.po +50 -35
  74. umap/settings/local_s3.py +45 -0
  75. umap/static/umap/content.css +18 -13
  76. umap/static/umap/css/bar.css +4 -0
  77. umap/static/umap/css/form.css +3 -0
  78. umap/static/umap/img/logo_lightcyan.svg +4 -0
  79. umap/static/umap/js/modules/caption.js +73 -73
  80. umap/static/umap/js/modules/data/features.js +20 -5
  81. umap/static/umap/js/modules/data/layer.js +17 -14
  82. umap/static/umap/js/modules/drop.js +55 -0
  83. umap/static/umap/js/modules/importer.js +20 -10
  84. umap/static/umap/js/modules/rendering/icon.js +2 -1
  85. umap/static/umap/js/modules/rendering/map.js +9 -8
  86. umap/static/umap/js/modules/rendering/popup.js +9 -10
  87. umap/static/umap/js/modules/rendering/template.js +53 -9
  88. umap/static/umap/js/modules/rendering/ui.js +6 -2
  89. umap/static/umap/js/modules/request.js +2 -2
  90. umap/static/umap/js/modules/schema.js +1 -0
  91. umap/static/umap/js/modules/sync/engine.js +56 -13
  92. umap/static/umap/js/modules/sync/updaters.js +4 -1
  93. umap/static/umap/js/modules/sync/websocket.js +47 -2
  94. umap/static/umap/js/modules/ui/bar.js +1 -1
  95. umap/static/umap/js/modules/ui/dialog.js +5 -0
  96. umap/static/umap/js/modules/umap.js +62 -25
  97. umap/static/umap/js/modules/utils.js +2 -0
  98. umap/static/umap/js/umap.controls.js +8 -55
  99. umap/static/umap/js/umap.forms.js +44 -0
  100. umap/static/umap/locale/cs_CZ.js +13 -11
  101. umap/static/umap/locale/cs_CZ.json +13 -11
  102. umap/static/umap/locale/en.js +2 -1
  103. umap/static/umap/locale/en.json +2 -1
  104. umap/static/umap/locale/fr.js +2 -1
  105. umap/static/umap/locale/fr.json +2 -1
  106. umap/static/umap/locale/zh_TW.js +13 -11
  107. umap/static/umap/locale/zh_TW.json +13 -11
  108. umap/static/umap/map.css +34 -166
  109. umap/static/umap/unittests/sync.js +4 -1
  110. umap/static/umap/vars.css +0 -1
  111. umap/templates/403.html +12 -0
  112. umap/templates/404.html +4 -13
  113. umap/templates/40x.html +9 -0
  114. umap/templates/base.html +2 -0
  115. umap/templates/umap/components/alerts/alert.html +4 -0
  116. umap/templates/umap/css.html +3 -0
  117. umap/templates/umap/js.html +2 -0
  118. umap/templates/umap/map_init.html +2 -0
  119. umap/templates/umap/user_dashboard.html +2 -0
  120. umap/tests/fixtures/test_upload_simple_marker.json +19 -0
  121. umap/tests/integration/conftest.py +3 -3
  122. umap/tests/integration/test_edit_datalayer.py +11 -0
  123. umap/tests/integration/test_import.py +20 -1
  124. umap/tests/integration/test_websocket_sync.py +69 -0
  125. umap/tests/test_dashboard.py +82 -0
  126. umap/tests/test_team_views.py +35 -1
  127. umap/tests/test_views.py +0 -74
  128. umap/views.py +5 -1
  129. umap/websocket_server.py +8 -1
  130. {umap_project-2.8.0a2.dist-info → umap_project-2.8.1.dist-info}/METADATA +5 -5
  131. {umap_project-2.8.0a2.dist-info → umap_project-2.8.1.dist-info}/RECORD +134 -127
  132. {umap_project-2.8.0a2.dist-info → umap_project-2.8.1.dist-info}/WHEEL +0 -0
  133. {umap_project-2.8.0a2.dist-info → umap_project-2.8.1.dist-info}/entry_points.txt +0 -0
  134. {umap_project-2.8.0a2.dist-info → umap_project-2.8.1.dist-info}/licenses/LICENSE +0 -0
@@ -183,12 +183,12 @@
183
183
  "Icon shape": "圖示圖形",
184
184
  "Icon symbol": "圖示標誌",
185
185
  "If false, the polygon or line will act as a part of the underlying map.": "選擇「否」時,多邊形物件會被當成為底圖的一部分。",
186
- "Iframe with custom height (in px): {{{https://iframe.url.com|height}}}": "Iframe with custom height (in px): {{{https://iframe.url.com|height}}}",
187
- "Iframe with custom height and width (in px): {{{https://iframe.url.com|height*width}}}": "Iframe with custom height and width (in px): {{{https://iframe.url.com|height*width}}}",
186
+ "Iframe with custom height (in px): {{{https://iframe.url.com|height}}}": "iframe 的自訂高度 (px){{{https://iframe.url.com|height}}}",
187
+ "Iframe with custom height and width (in px): {{{https://iframe.url.com|height*width}}}": "iframe 的自訂高度與寬度 (px){{{https://iframe.url.com|height*width}}}",
188
188
  "iframe": "iframe",
189
- "Iframe: {{{https://iframe.url.com}}}": "Iframe: {{{https://iframe.url.com}}}",
190
- "Image with custom width (in px): {{https://image.url.com|width}}": "Image with custom width (in px): {{https://image.url.com|width}}",
191
- "Image: {{https://image.url.com}}": "Image: {{https://image.url.com}}",
189
+ "Iframe: {{{https://iframe.url.com}}}": "iframe:{{{https://iframe.url.com}}}",
190
+ "Image with custom width (in px): {{https://image.url.com|width}}": "圖片有自訂寬度 (px){{https://image.url.com|width}}",
191
+ "Image: {{https://image.url.com}}": "圖片:{{https://image.url.com}}",
192
192
  "Import data": "匯入資料",
193
193
  "Import in a new layer": "匯入至新圖層",
194
194
  "Imports all umap data, including layers and settings.": "匯入所有 umap 資料,包含圖層與設定。",
@@ -216,7 +216,7 @@
216
216
  "Limit bounds": "限制範圍",
217
217
  "Link to view the map": "檢視地圖的連結",
218
218
  "Link to…": "連結至...",
219
- "Link with text: [[https://example.com|text of the link]]": "Link with text: [[https://example.com|text of the link]]",
219
+ "Link with text: [[https://example.com|text of the link]]": "有文字的連結:[[https://example.com|text of the link]]",
220
220
  "Long credits": "詳細工作人員名單",
221
221
  "Longitude": "經度",
222
222
  "Make main shape": "設為主要外形",
@@ -320,7 +320,7 @@
320
320
  "Show this layer in the caption": "在標題顯示此圖層",
321
321
  "Show/hide layer": "顯示/隱藏圖層",
322
322
  "Side panel": "側邊框",
323
- "Simple link: [[https://example.com]]": "Simple link: [[https://example.com]]",
323
+ "Simple link: [[https://example.com]]": "簡單連結: [[https://example.com]]",
324
324
  "Simplify": "簡化",
325
325
  "Skipping unknown geometry.type: {type}": "略過不明的 geometry.type: {type}",
326
326
  "Slideshow": "投影片",
@@ -517,8 +517,10 @@
517
517
  "zoom to data extent": "切換至資料範圍",
518
518
  "download visible data": "下載可視資料",
519
519
  "{connectedPeers} peer(s) currently connected to this map": "這份地圖已經有 {connectedPeers} 伙伴連線",
520
- "Import helpers": "Import helpers",
521
- "Import helpers will fill the URL field for you.": "Import helpers will fill the URL field for you.",
522
- "Wikipedia": "Wikipedia",
523
- "Save draft": "Save draft"
520
+ "Import helpers": "匯入幫手",
521
+ "Import helpers will fill the URL field for you.": "匯入幫會為你填入網址",
522
+ "Wikipedia": "維基百科",
523
+ "Save draft": "儲存草稿",
524
+ "No data has been found for import": "匯入時沒有找到資料",
525
+ "Successfully imported {count} feature(s)": "成功匯入 {count} 圖徵"
524
526
  }
umap/static/umap/map.css CHANGED
@@ -924,7 +924,6 @@ a.umap-control-caption,
924
924
  width: 2px;
925
925
  }
926
926
  .umap-icon-active {
927
- z-index: var(--zindex-icon-active)!important;
928
927
  opacity: 1.0!important;
929
928
  }
930
929
  .umap-edit-enabled .readonly {
@@ -935,173 +934,42 @@ a.umap-control-caption,
935
934
  /* ********************************* */
936
935
  /* Ajax loader */
937
936
  /* ********************************* */
938
- .umap-loading .umap-loader
939
- {
940
- display: block;
941
- -webkit-animation: shift-rightwards 3s ease-in-out infinite;
942
- -moz-animation: shift-rightwards 3s ease-in-out infinite;
943
- -ms-animation: shift-rightwards 3s ease-in-out infinite;
944
- -o-animation: shift-rightwards 3s ease-in-out infinite;
945
- animation: shift-rightwards 3s ease-in-out infinite;
946
- -webkit-animation-delay: .2s;
947
- -moz-animation-delay: .2s;
948
- -o-animation-delay: .2s;
949
- animation-delay: .2s;
950
- }
951
937
  .umap-loader {
952
- position: absolute;
953
- display: none;
954
- top: 0;
955
- left: 0;
956
- right: 0;
957
- height: 4px;
958
- z-index: var(--zindex-loader);
959
- background-color: #79c1c0 !important;
960
- -webkit-transform: translateX(100%);
961
- -moz-transform: translateX(100%);
962
- -o-transform: translateX(100%);
963
- transform: translateX(100%);
964
- }
965
-
966
-
967
- @-webkit-keyframes shift-rightwards
968
- {
969
- 0%
970
- {
971
- -webkit-transform:translateX(-100%);
972
- -moz-transform:translateX(-100%);
973
- -o-transform:translateX(-100%);
974
- transform:translateX(-100%);
975
- }
976
-
977
- 40%
978
- {
979
- -webkit-transform:translateX(0%);
980
- -moz-transform:translateX(0%);
981
- -o-transform:translateX(0%);
982
- transform:translateX(0%);
983
- }
984
-
985
- 60%
986
- {
987
- -webkit-transform:translateX(0%);
988
- -moz-transform:translateX(0%);
989
- -o-transform:translateX(0%);
990
- transform:translateX(0%);
991
- }
992
-
993
- 100%
994
- {
995
- -webkit-transform:translateX(100%);
996
- -moz-transform:translateX(100%);
997
- -o-transform:translateX(100%);
998
- transform:translateX(100%);
999
- }
1000
-
1001
- }
1002
- @-moz-keyframes shift-rightwards
1003
- {
1004
- 0%
1005
- {
1006
- -webkit-transform:translateX(-100%);
1007
- -moz-transform:translateX(-100%);
1008
- -o-transform:translateX(-100%);
1009
- transform:translateX(-100%);
1010
- }
1011
-
1012
- 40%
1013
- {
1014
- -webkit-transform:translateX(0%);
1015
- -moz-transform:translateX(0%);
1016
- -o-transform:translateX(0%);
1017
- transform:translateX(0%);
1018
- }
1019
-
1020
- 60%
1021
- {
1022
- -webkit-transform:translateX(0%);
1023
- -moz-transform:translateX(0%);
1024
- -o-transform:translateX(0%);
1025
- transform:translateX(0%);
1026
- }
1027
-
1028
- 100%
1029
- {
1030
- -webkit-transform:translateX(100%);
1031
- -moz-transform:translateX(100%);
1032
- -o-transform:translateX(100%);
1033
- transform:translateX(100%);
1034
- }
1035
-
1036
- }
1037
- @-o-keyframes shift-rightwards
1038
- {
1039
- 0%
1040
- {
1041
- -webkit-transform:translateX(-100%);
1042
- -moz-transform:translateX(-100%);
1043
- -o-transform:translateX(-100%);
1044
- transform:translateX(-100%);
1045
- }
1046
-
1047
- 40%
1048
- {
1049
- -webkit-transform:translateX(0%);
1050
- -moz-transform:translateX(0%);
1051
- -o-transform:translateX(0%);
1052
- transform:translateX(0%);
1053
- }
1054
-
1055
- 60%
1056
- {
1057
- -webkit-transform:translateX(0%);
1058
- -moz-transform:translateX(0%);
1059
- -o-transform:translateX(0%);
1060
- transform:translateX(0%);
1061
- }
1062
-
1063
- 100%
1064
- {
1065
- -webkit-transform:translateX(100%);
1066
- -moz-transform:translateX(100%);
1067
- -o-transform:translateX(100%);
1068
- transform:translateX(100%);
1069
- }
1070
-
938
+ width: 100%;
939
+ height: 6px;
940
+ display: inline-block;
941
+ position: absolute;
942
+ background: var(--color-brightCyan);
943
+ overflow: hidden;
944
+ display: none;
945
+ top: 0;
946
+ left: 0;
947
+ right: 0;
948
+ height: 4px;
949
+ z-index: var(--zindex-loader);
950
+ }
951
+ .umap-loader::after {
952
+ content: '';
953
+ box-sizing: border-box;
954
+ width: 0;
955
+ height: 4.8px;
956
+ background: var(--color-darkerGray);
957
+ position: absolute;
958
+ top: 0;
959
+ left: 0;
960
+ animation: animFw 10s linear infinite;
961
+ }
962
+
963
+ @keyframes animFw {
964
+ 0% {
965
+ width: 0;
966
+ }
967
+ 100% {
968
+ width: 100%;
969
+ }
1071
970
  }
1072
- @keyframes shift-rightwards
1073
- {
1074
- 0%
1075
- {
1076
- -webkit-transform:translateX(-100%);
1077
- -moz-transform:translateX(-100%);
1078
- -o-transform:translateX(-100%);
1079
- transform:translateX(-100%);
1080
- }
1081
-
1082
- 40%
1083
- {
1084
- -webkit-transform:translateX(0%);
1085
- -moz-transform:translateX(0%);
1086
- -o-transform:translateX(0%);
1087
- transform:translateX(0%);
1088
- }
1089
-
1090
- 60%
1091
- {
1092
- -webkit-transform:translateX(0%);
1093
- -moz-transform:translateX(0%);
1094
- -o-transform:translateX(0%);
1095
- transform:translateX(0%);
1096
- }
1097
-
1098
- 100%
1099
- {
1100
- -webkit-transform:translateX(100%);
1101
- -moz-transform:translateX(100%);
1102
- -o-transform:translateX(100%);
1103
- transform:translateX(100%);
1104
- }
971
+ .umap-loading .umap-loader {
972
+ display: block;
1105
973
  }
1106
974
 
1107
975
  /* *************************** */
@@ -8,8 +8,11 @@ import { MapUpdater } from '../js/modules/sync/updaters.js'
8
8
  import { SyncEngine, Operations } from '../js/modules/sync/engine.js'
9
9
 
10
10
  describe('SyncEngine', () => {
11
+ const websocketTokenURI = 'http://localhost:8000/api/v1/maps/1/websocket_auth_token/'
12
+ const websocketURI = 'ws://localhost:8000/ws/maps/1/'
13
+
11
14
  it('should initialize methods even before start', () => {
12
- const engine = new SyncEngine({})
15
+ const engine = new SyncEngine({}, websocketTokenURI, websocketURI)
13
16
  engine.upsert()
14
17
  engine.update()
15
18
  engine.delete()
umap/static/umap/vars.css CHANGED
@@ -48,7 +48,6 @@
48
48
  --zindex-autocomplete: 470;
49
49
  --zindex-dialog: 460;
50
50
  --zindex-contextmenu: 455;
51
- --zindex-icon-active: 450;
52
51
  --zindex-tooltip: 445;
53
52
  --zindex-panels: 440;
54
53
  --zindex-controls: 430;
@@ -0,0 +1,12 @@
1
+ {% extends "40x.html" %}
2
+
3
+ {% load i18n %}
4
+
5
+ {% block content %}
6
+ <div class="content-40x">
7
+ <h1>{{ exception }}</h1>
8
+ <p>{% blocktrans %}<a href="https://discover.umap-project.org/support/faq/#map-statuses" target="_blank">Find out here the documentation</a> on how to manage map’s permissions.{% endblocktrans %}</p>
9
+ <hr>
10
+ <p><a href="{% url 'home' %}">{% trans "← Go to the homepage" %}</a></p>
11
+ </div>
12
+ {% endblock content %}
umap/templates/404.html CHANGED
@@ -1,19 +1,10 @@
1
- {% extends "base.html" %}
1
+ {% extends "40x.html" %}
2
2
 
3
3
  {% load i18n static %}
4
4
 
5
5
  {% block content %}
6
- <div class="content404">
7
- <a href="{% url "home" %}"
8
- title="{% trans "Take me to the home page" %}">
9
- <h1>
10
- 4
11
- <img alt="0" width="128px" height="128px" src="{% static "umap/img/logo.svg" %}">
12
- 4
13
- </h1>
14
- <h2>
15
- Not Found
16
- </h2>
17
- </a>
6
+ <div class="content-40x content-404">
7
+ <h1>{% trans "404 Page Not Found" %}</h1>
8
+ <p><a href="{% url 'home' %}">{% trans " Go to the homepage" %}</a></p>
18
9
  </div>
19
10
  {% endblock content %}
@@ -0,0 +1,9 @@
1
+ {% extends "base.html" %}
2
+
3
+ {% load umap_tags %}
4
+ {% block body_class %}page-40x{% endblock body_class %}
5
+ {% block extra_head %}
6
+ {% umap_css %}
7
+ {{ block.super }}
8
+ {% umap_js %}
9
+ {% endblock extra_head %}
umap/templates/base.html CHANGED
@@ -18,6 +18,7 @@
18
18
  <meta name="viewport"
19
19
  content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
20
20
  {# See https://evilmartians.com/chronicles/how-to-favicon-in-2021-six-files-that-fit-most-needs #}
21
+ {% autoescape off %}
21
22
  <link rel="icon"
22
23
  href="{% static 'umap/favicons/favicon.ico' %}"
23
24
  sizes="32x32">
@@ -28,6 +29,7 @@
28
29
  href="{% static 'umap/favicons/apple-touch-icon.png' %}">
29
30
  <!-- 180×180 -->
30
31
  <link rel="manifest" href="/manifest.webmanifest">
32
+ {% endautoescape %}
31
33
  </head>
32
34
  <body class="{% block body_class %}{% endblock body_class %}">
33
35
  {% block header %}
@@ -1,8 +1,10 @@
1
1
  {% load i18n static %}
2
2
 
3
+ {% autoescape off %}
3
4
  <style type="text/css">
4
5
  @import "{% static 'umap/js/components/alerts/alert.css' %}";
5
6
  </style>
7
+ {% endautoescape %}
6
8
  <template id="umap-alert-template">
7
9
  <div role="dialog" class="dark window umap-alert">
8
10
  <div>
@@ -97,6 +99,7 @@
97
99
  </div>
98
100
  </template>
99
101
  <umap-alert-conflict></umap-alert-conflict>
102
+ {% autoescape off %}
100
103
  <script type="module">
101
104
  import { register } from '{% static 'umap/js/components/base.js' %}'
102
105
  import {
@@ -108,3 +111,4 @@
108
111
  register(uMapAlertCreation, 'umap-alert-creation')
109
112
  register(uMapAlertConflict, 'umap-alert-conflict')
110
113
  </script>
114
+ {% endautoescape %}
@@ -1,5 +1,7 @@
1
1
  {% load static %}
2
2
 
3
+ {% autoescape off %}
4
+
3
5
  <link rel="stylesheet"
4
6
  href="{% static 'umap/vendors/leaflet/leaflet.css' %}" />
5
7
  <link rel="stylesheet"
@@ -39,3 +41,4 @@
39
41
  <link rel="stylesheet" href="{% static 'umap/css/tableeditor.css' %}" />
40
42
  <link rel="stylesheet" href="{% static 'umap/css/bar.css' %}" />
41
43
  <link rel="stylesheet" href="{% static 'umap/theme.css' %}" />
44
+ {% endautoescape %}
@@ -1,5 +1,6 @@
1
1
  {% load static %}
2
2
 
3
+ {% autoescape off %}
3
4
  <script type="module"
4
5
  src="{% static 'umap/vendors/leaflet/leaflet-src.esm.js' %}"
5
6
  defer></script>
@@ -42,3 +43,4 @@
42
43
  <script src="{% static 'umap/js/umap.forms.js' %}" defer></script>
43
44
  <script src="{% static 'umap/js/umap.controls.js' %}" defer></script>
44
45
  <script type="module" src="{% static 'umap/js/components/fragment.js' %}" defer></script>
46
+ {% endautoescape %}
@@ -5,7 +5,9 @@
5
5
  </div>
6
6
  <!-- djlint:off -->
7
7
  <script defer type="module">
8
+ {% autoescape off %}
8
9
  import Umap from '{% static "umap/js/modules/umap.js" %}'
10
+ {% endautoescape %}
9
11
  U.MAP = new Umap("map", {{ map_settings|notag|safe }})
10
12
  </script>
11
13
  <!-- djlint:on -->
@@ -46,7 +46,9 @@
46
46
  {% block bottom_js %}
47
47
  {{ block.super }}
48
48
  <script type="module">
49
+ {% autoescape off %}
49
50
  import Umap from '{% static "umap/js/modules/umap.js" %}'
51
+ {% endautoescape %}
50
52
  const CACHE = {}
51
53
  for (const mapOpener of document.querySelectorAll("button.map-opener")) {
52
54
  mapOpener.addEventListener('click', (event) => {
@@ -0,0 +1,19 @@
1
+ {
2
+ "crs": null,
3
+ "type": "FeatureCollection",
4
+ "features": [
5
+ {
6
+ "type": "Feature",
7
+ "geometry": {
8
+ "coordinates": [
9
+ -1.09314,
10
+ 50.791718
11
+ ],
12
+ "type": "Point"
13
+ },
14
+ "properties": {
15
+ "name": "Portsmouth"
16
+ }
17
+ }
18
+ ]
19
+ }
@@ -51,12 +51,12 @@ def page(new_page):
51
51
 
52
52
 
53
53
  @pytest.fixture
54
- def login(context, settings, live_server):
55
- def do_login(user):
54
+ def login(new_page, settings, live_server):
55
+ def do_login(user, **kwargs):
56
56
  # TODO use storage state to do login only once per session
57
57
  # https://playwright.dev/python/docs/auth
58
58
  settings.ENABLE_ACCOUNT_LOGIN = True
59
- page = context.new_page()
59
+ page = new_page(**kwargs)
60
60
  page.goto(f"{live_server.url}/en/")
61
61
  page.locator(".login").click()
62
62
  page.get_by_placeholder("Username").fill(user.username)
@@ -221,3 +221,14 @@ def test_deleting_datalayer_should_remove_from_caption(
221
221
  page.locator(".panel.right").get_by_title("Delete layer").click()
222
222
  page.get_by_role("button", name="OK").click()
223
223
  expect(panel.get_by_text("test datalayer")).to_be_hidden()
224
+
225
+
226
+ def test_can_edit_datalayer_name_in_list(live_server, openmap, datalayer, page):
227
+ page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
228
+ page.get_by_role("link", name="Manage layers").click()
229
+ page.get_by_text("test datalayer").click()
230
+ page.get_by_text("test datalayer").fill("test datalayer foobar")
231
+ page.get_by_role("button", name="Open browser").click()
232
+ expect(
233
+ page.locator(".panel.left").get_by_text("test datalayer foobar")
234
+ ).to_be_visible()
@@ -9,7 +9,6 @@ from playwright.sync_api import expect
9
9
 
10
10
  from umap.models import DataLayer
11
11
 
12
- from ..base import mock_tiles
13
12
  from .helpers import save_and_get_json
14
13
 
15
14
  pytestmark = pytest.mark.django_db
@@ -765,3 +764,23 @@ def test_import_georss_from_textarea(tilelayer, live_server, page):
765
764
  # A layer has been created
766
765
  expect(layers).to_have_count(1)
767
766
  expect(markers).to_have_count(1)
767
+
768
+
769
+ def test_import_from_multiple_files(live_server, page, tilelayer):
770
+ page.goto(f"{live_server.url}/map/new/")
771
+ page.get_by_title("Import data").click()
772
+ file_input = page.locator("input[type='file']")
773
+ with page.expect_file_chooser() as fc_info:
774
+ file_input.click()
775
+ file_chooser = fc_info.value
776
+ FIXTURES = Path(__file__).parent.parent / "fixtures"
777
+ paths = [
778
+ FIXTURES / "test_upload_data.json",
779
+ FIXTURES / "test_upload_simple_marker.json",
780
+ ]
781
+ file_chooser.set_files(paths)
782
+ markers = page.locator(".leaflet-marker-icon")
783
+ expect(markers).to_have_count(0)
784
+ page.get_by_role("button", name="Import data", exact=True).click()
785
+ # Two in one file, one in the other
786
+ expect(markers).to_have_count(3)
@@ -39,6 +39,9 @@ def test_websocket_connection_can_sync_markers(
39
39
  a_map_el.click(position={"x": 220, "y": 220})
40
40
  expect(a_marker_pane).to_have_count(1)
41
41
  expect(b_marker_pane).to_have_count(1)
42
+ # Peer B should not be in state dirty
43
+ expect(peerB.get_by_role("button", name="View")).to_be_visible()
44
+ expect(peerB.get_by_role("button", name="Cancel edits")).to_be_hidden()
42
45
  peerA.locator("body").type("Synced name")
43
46
  peerA.locator("body").press("Escape")
44
47
 
@@ -415,3 +418,69 @@ def test_should_sync_datalayers(new_page, live_server, websocket_server, tilelay
415
418
  peerA.get_by_role("button", name="Save").click()
416
419
 
417
420
  assert DataLayer.objects.count() == 2
421
+
422
+
423
+ @pytest.mark.xdist_group(name="websockets")
424
+ def test_create_and_sync_map(
425
+ new_page, live_server, websocket_server, tilelayer, login, user
426
+ ):
427
+ # Create a syncable map with peerA
428
+ peerA = login(user, prefix="Page A")
429
+ peerA.goto(f"{live_server.url}/en/map/new/")
430
+ with peerA.expect_response(re.compile("./map/create/.*")):
431
+ peerA.get_by_role("button", name="Save Draft").click()
432
+ peerA.get_by_role("link", name="Map advanced properties").click()
433
+ peerA.get_by_text("Real-time collaboration", exact=True).click()
434
+ peerA.get_by_text("Enable real-time").click()
435
+ peerA.get_by_role("link", name="Update permissions and editors").click()
436
+ peerA.locator('select[name="share_status"]').select_option(str(Map.PUBLIC))
437
+ with peerA.expect_response(re.compile("./update/settings/.*")):
438
+ peerA.get_by_role("button", name="Save").click()
439
+ expect(peerA.get_by_role("button", name="Cancel edits")).to_be_hidden()
440
+ # Quit edit mode
441
+ peerA.get_by_role("button", name="View").click()
442
+
443
+ # Open map and go to edit mode with peer B
444
+ peerB = new_page("Page B")
445
+ peerB.goto(peerA.url)
446
+ peerB.get_by_role("button", name="Edit").click()
447
+
448
+ # Create a marker from peerA
449
+ markersA = peerA.locator(".leaflet-marker-pane > div")
450
+ markersB = peerB.locator(".leaflet-marker-pane > div")
451
+ expect(markersA).to_have_count(0)
452
+ expect(markersB).to_have_count(0)
453
+
454
+ # Add a marker from peer A
455
+ peerA.get_by_role("button", name="Edit").click()
456
+ peerA.get_by_title("Draw a marker").click()
457
+ peerA.locator("#map").click(position={"x": 220, "y": 220})
458
+ expect(markersA).to_have_count(1)
459
+ expect(markersB).to_have_count(1)
460
+
461
+ # Save and quit edit mode again
462
+ with peerA.expect_response(re.compile("./datalayer/create/.*")):
463
+ peerA.get_by_role("button", name="Save").click()
464
+ peerA.get_by_role("button", name="View").click()
465
+ expect(markersA).to_have_count(1)
466
+ expect(markersB).to_have_count(1)
467
+ peerA.wait_for_timeout(500)
468
+ expect(markersA).to_have_count(1)
469
+ expect(markersB).to_have_count(1)
470
+
471
+ # Peer B should not be in state dirty
472
+ expect(peerB.get_by_role("button", name="View")).to_be_visible()
473
+ expect(peerB.get_by_role("button", name="Cancel edits")).to_be_hidden()
474
+
475
+ # Add a marker from peer B
476
+ peerB.get_by_title("Draw a marker").click()
477
+ peerB.locator("#map").click(position={"x": 200, "y": 200})
478
+ expect(markersB).to_have_count(2)
479
+ expect(markersA).to_have_count(1)
480
+ with peerB.expect_response(re.compile("./datalayer/update/.*")):
481
+ peerB.get_by_role("button", name="Save").click()
482
+ expect(markersB).to_have_count(2)
483
+ expect(markersA).to_have_count(1)
484
+ peerA.get_by_role("button", name="Edit").click()
485
+ expect(markersA).to_have_count(2)
486
+ expect(markersB).to_have_count(2)