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.
- umap/__init__.py +1 -1
- umap/decorators.py +3 -1
- umap/locale/ar/LC_MESSAGES/django.mo +0 -0
- umap/locale/ar/LC_MESSAGES/django.po +45 -30
- umap/locale/br/LC_MESSAGES/django.mo +0 -0
- umap/locale/br/LC_MESSAGES/django.po +49 -34
- umap/locale/ca/LC_MESSAGES/django.mo +0 -0
- umap/locale/ca/LC_MESSAGES/django.po +45 -30
- umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
- umap/locale/cs_CZ/LC_MESSAGES/django.po +52 -37
- umap/locale/da/LC_MESSAGES/django.mo +0 -0
- umap/locale/da/LC_MESSAGES/django.po +45 -30
- umap/locale/de/LC_MESSAGES/django.mo +0 -0
- umap/locale/de/LC_MESSAGES/django.po +45 -30
- umap/locale/el/LC_MESSAGES/django.mo +0 -0
- umap/locale/el/LC_MESSAGES/django.po +45 -30
- umap/locale/en/LC_MESSAGES/django.po +44 -29
- umap/locale/es/LC_MESSAGES/django.mo +0 -0
- umap/locale/es/LC_MESSAGES/django.po +45 -30
- umap/locale/et/LC_MESSAGES/django.mo +0 -0
- umap/locale/et/LC_MESSAGES/django.po +45 -30
- umap/locale/eu/LC_MESSAGES/django.mo +0 -0
- umap/locale/eu/LC_MESSAGES/django.po +65 -50
- umap/locale/fa_IR/LC_MESSAGES/django.mo +0 -0
- umap/locale/fa_IR/LC_MESSAGES/django.po +45 -30
- umap/locale/fr/LC_MESSAGES/django.mo +0 -0
- umap/locale/fr/LC_MESSAGES/django.po +45 -30
- umap/locale/gl/LC_MESSAGES/django.mo +0 -0
- umap/locale/gl/LC_MESSAGES/django.po +45 -30
- umap/locale/he/LC_MESSAGES/django.mo +0 -0
- umap/locale/he/LC_MESSAGES/django.po +45 -30
- umap/locale/hu/LC_MESSAGES/django.mo +0 -0
- umap/locale/hu/LC_MESSAGES/django.po +45 -30
- umap/locale/is/LC_MESSAGES/django.mo +0 -0
- umap/locale/is/LC_MESSAGES/django.po +45 -30
- umap/locale/it/LC_MESSAGES/django.mo +0 -0
- umap/locale/it/LC_MESSAGES/django.po +45 -30
- umap/locale/ja/LC_MESSAGES/django.mo +0 -0
- umap/locale/ja/LC_MESSAGES/django.po +45 -30
- umap/locale/ko/LC_MESSAGES/django.mo +0 -0
- umap/locale/ko/LC_MESSAGES/django.po +45 -30
- umap/locale/lt/LC_MESSAGES/django.mo +0 -0
- umap/locale/lt/LC_MESSAGES/django.po +45 -30
- umap/locale/ms/LC_MESSAGES/django.mo +0 -0
- umap/locale/ms/LC_MESSAGES/django.po +45 -30
- umap/locale/nl/LC_MESSAGES/django.mo +0 -0
- umap/locale/nl/LC_MESSAGES/django.po +45 -30
- umap/locale/pl/LC_MESSAGES/django.mo +0 -0
- umap/locale/pl/LC_MESSAGES/django.po +45 -30
- umap/locale/pt/LC_MESSAGES/django.mo +0 -0
- umap/locale/pt/LC_MESSAGES/django.po +45 -30
- umap/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
- umap/locale/pt_BR/LC_MESSAGES/django.po +45 -30
- umap/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
- umap/locale/pt_PT/LC_MESSAGES/django.po +45 -30
- umap/locale/ru/LC_MESSAGES/django.mo +0 -0
- umap/locale/ru/LC_MESSAGES/django.po +45 -30
- umap/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
- umap/locale/sk_SK/LC_MESSAGES/django.po +45 -30
- umap/locale/sl/LC_MESSAGES/django.mo +0 -0
- umap/locale/sl/LC_MESSAGES/django.po +45 -30
- umap/locale/sr/LC_MESSAGES/django.mo +0 -0
- umap/locale/sr/LC_MESSAGES/django.po +45 -30
- umap/locale/sv/LC_MESSAGES/django.mo +0 -0
- umap/locale/sv/LC_MESSAGES/django.po +45 -30
- umap/locale/th_TH/LC_MESSAGES/django.mo +0 -0
- umap/locale/th_TH/LC_MESSAGES/django.po +45 -30
- umap/locale/tr/LC_MESSAGES/django.mo +0 -0
- umap/locale/tr/LC_MESSAGES/django.po +45 -30
- umap/locale/uk_UA/LC_MESSAGES/django.mo +0 -0
- umap/locale/uk_UA/LC_MESSAGES/django.po +45 -30
- umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
- umap/locale/zh_TW/LC_MESSAGES/django.po +50 -35
- umap/settings/local_s3.py +45 -0
- umap/static/umap/content.css +18 -13
- umap/static/umap/css/bar.css +4 -0
- umap/static/umap/css/form.css +3 -0
- umap/static/umap/img/logo_lightcyan.svg +4 -0
- umap/static/umap/js/modules/caption.js +73 -73
- umap/static/umap/js/modules/data/features.js +20 -5
- umap/static/umap/js/modules/data/layer.js +17 -14
- umap/static/umap/js/modules/drop.js +55 -0
- umap/static/umap/js/modules/importer.js +20 -10
- umap/static/umap/js/modules/rendering/icon.js +2 -1
- umap/static/umap/js/modules/rendering/map.js +9 -8
- umap/static/umap/js/modules/rendering/popup.js +9 -10
- umap/static/umap/js/modules/rendering/template.js +53 -9
- umap/static/umap/js/modules/rendering/ui.js +6 -2
- umap/static/umap/js/modules/request.js +2 -2
- umap/static/umap/js/modules/schema.js +1 -0
- umap/static/umap/js/modules/sync/engine.js +56 -13
- umap/static/umap/js/modules/sync/updaters.js +4 -1
- umap/static/umap/js/modules/sync/websocket.js +47 -2
- umap/static/umap/js/modules/ui/bar.js +1 -1
- umap/static/umap/js/modules/ui/dialog.js +5 -0
- umap/static/umap/js/modules/umap.js +62 -25
- umap/static/umap/js/modules/utils.js +2 -0
- umap/static/umap/js/umap.controls.js +8 -55
- umap/static/umap/js/umap.forms.js +44 -0
- umap/static/umap/locale/cs_CZ.js +13 -11
- umap/static/umap/locale/cs_CZ.json +13 -11
- umap/static/umap/locale/en.js +2 -1
- umap/static/umap/locale/en.json +2 -1
- umap/static/umap/locale/fr.js +2 -1
- umap/static/umap/locale/fr.json +2 -1
- umap/static/umap/locale/zh_TW.js +13 -11
- umap/static/umap/locale/zh_TW.json +13 -11
- umap/static/umap/map.css +34 -166
- umap/static/umap/unittests/sync.js +4 -1
- umap/static/umap/vars.css +0 -1
- umap/templates/403.html +12 -0
- umap/templates/404.html +4 -13
- umap/templates/40x.html +9 -0
- umap/templates/base.html +2 -0
- umap/templates/umap/components/alerts/alert.html +4 -0
- umap/templates/umap/css.html +3 -0
- umap/templates/umap/js.html +2 -0
- umap/templates/umap/map_init.html +2 -0
- umap/templates/umap/user_dashboard.html +2 -0
- umap/tests/fixtures/test_upload_simple_marker.json +19 -0
- umap/tests/integration/conftest.py +3 -3
- umap/tests/integration/test_edit_datalayer.py +11 -0
- umap/tests/integration/test_import.py +20 -1
- umap/tests/integration/test_websocket_sync.py +69 -0
- umap/tests/test_dashboard.py +82 -0
- umap/tests/test_team_views.py +35 -1
- umap/tests/test_views.py +0 -74
- umap/views.py +5 -1
- umap/websocket_server.py +8 -1
- {umap_project-2.8.0a2.dist-info → umap_project-2.8.1.dist-info}/METADATA +5 -5
- {umap_project-2.8.0a2.dist-info → umap_project-2.8.1.dist-info}/RECORD +134 -127
- {umap_project-2.8.0a2.dist-info → umap_project-2.8.1.dist-info}/WHEEL +0 -0
- {umap_project-2.8.0a2.dist-info → umap_project-2.8.1.dist-info}/entry_points.txt +0 -0
- {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}}}": "
|
|
187
|
-
"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}}}": "
|
|
190
|
-
"Image with custom width (in px): {{https://image.url.com|width}}": "
|
|
191
|
-
"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]]": "
|
|
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]]": "
|
|
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": "
|
|
521
|
-
"Import helpers will fill the URL field for you.": "
|
|
522
|
-
"Wikipedia": "
|
|
523
|
-
"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
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
}
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
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
|
-
|
|
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
umap/templates/403.html
ADDED
|
@@ -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 "
|
|
1
|
+
{% extends "40x.html" %}
|
|
2
2
|
|
|
3
3
|
{% load i18n static %}
|
|
4
4
|
|
|
5
5
|
{% block content %}
|
|
6
|
-
<div class="
|
|
7
|
-
<
|
|
8
|
-
|
|
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 %}
|
umap/templates/40x.html
ADDED
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 %}
|
umap/templates/umap/css.html
CHANGED
|
@@ -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 %}
|
umap/templates/umap/js.html
CHANGED
|
@@ -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 %}
|
|
@@ -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) => {
|
|
@@ -51,12 +51,12 @@ def page(new_page):
|
|
|
51
51
|
|
|
52
52
|
|
|
53
53
|
@pytest.fixture
|
|
54
|
-
def login(
|
|
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 =
|
|
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)
|