umap-project 1.14.0a5__py3-none-any.whl → 2.0.0a0__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 +0 -14
- umap/locale/br/LC_MESSAGES/django.mo +0 -0
- umap/locale/br/LC_MESSAGES/django.po +137 -85
- umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
- umap/locale/cs_CZ/LC_MESSAGES/django.po +136 -84
- umap/locale/el/LC_MESSAGES/django.mo +0 -0
- umap/locale/el/LC_MESSAGES/django.po +136 -84
- umap/locale/en/LC_MESSAGES/django.po +128 -88
- umap/locale/es/LC_MESSAGES/django.mo +0 -0
- umap/locale/es/LC_MESSAGES/django.po +136 -84
- umap/locale/fr/LC_MESSAGES/django.mo +0 -0
- umap/locale/fr/LC_MESSAGES/django.po +131 -91
- umap/locale/hu/LC_MESSAGES/django.mo +0 -0
- umap/locale/hu/LC_MESSAGES/django.po +137 -85
- umap/locale/it/LC_MESSAGES/django.mo +0 -0
- umap/locale/it/LC_MESSAGES/django.po +136 -84
- umap/locale/ms/LC_MESSAGES/django.mo +0 -0
- umap/locale/ms/LC_MESSAGES/django.po +136 -84
- umap/locale/pl/LC_MESSAGES/django.mo +0 -0
- umap/locale/pl/LC_MESSAGES/django.po +136 -84
- umap/locale/sv/LC_MESSAGES/django.mo +0 -0
- umap/locale/sv/LC_MESSAGES/django.po +135 -83
- umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
- umap/locale/zh_TW/LC_MESSAGES/django.po +143 -91
- umap/models.py +23 -1
- umap/settings/__init__.py +1 -4
- umap/settings/base.py +1 -0
- umap/static/umap/base.css +5 -0
- umap/static/umap/content.css +185 -13
- umap/static/umap/favicons/icon.svg +2 -2
- umap/static/umap/img/edit.svg +3 -3
- umap/static/umap/img/icon-delete.svg +4 -0
- umap/static/umap/img/icon-download.svg +13 -0
- umap/static/umap/img/icon-duplicate.svg +5 -0
- umap/static/umap/img/icon-edit.svg +12 -0
- umap/static/umap/img/icon-share.svg +11 -0
- umap/static/umap/img/icon-view.svg +12 -0
- umap/static/umap/img/logo.svg +2 -2
- umap/static/umap/img/logo_small.svg +2 -2
- umap/static/umap/img/marker.svg +4 -0
- umap/static/umap/img/opensource.svg +2 -2
- umap/static/umap/img/osm.svg +2 -2
- umap/static/umap/js/components/fragment.js +1 -1
- umap/static/umap/js/modules/browser.js +159 -0
- umap/static/umap/js/modules/global.js +3 -1
- umap/static/umap/js/modules/request.js +155 -0
- umap/static/umap/js/umap.autocomplete.js +28 -38
- umap/static/umap/js/umap.controls.js +73 -58
- umap/static/umap/js/umap.core.js +4 -9
- umap/static/umap/js/umap.datalayer.permissions.js +13 -12
- umap/static/umap/js/umap.features.js +51 -49
- umap/static/umap/js/umap.forms.js +19 -19
- umap/static/umap/js/umap.icon.js +17 -17
- umap/static/umap/js/umap.importer.js +2 -1
- umap/static/umap/js/umap.js +242 -291
- umap/static/umap/js/umap.layer.js +173 -141
- umap/static/umap/js/umap.permissions.js +24 -25
- umap/static/umap/js/umap.popup.js +14 -14
- umap/static/umap/js/umap.share.js +4 -4
- umap/static/umap/js/umap.slideshow.js +4 -4
- umap/static/umap/js/umap.tableeditor.js +2 -2
- umap/static/umap/js/umap.ui.js +1 -1
- umap/static/umap/locale/am_ET.js +1 -11
- umap/static/umap/locale/am_ET.json +1 -11
- umap/static/umap/locale/ar.js +1 -11
- umap/static/umap/locale/ar.json +1 -11
- umap/static/umap/locale/ast.js +1 -11
- umap/static/umap/locale/ast.json +1 -11
- umap/static/umap/locale/bg.js +1 -11
- umap/static/umap/locale/bg.json +1 -11
- umap/static/umap/locale/br.js +1 -11
- umap/static/umap/locale/br.json +1 -11
- umap/static/umap/locale/ca.js +1 -11
- umap/static/umap/locale/ca.json +1 -11
- umap/static/umap/locale/cs_CZ.js +1 -11
- umap/static/umap/locale/cs_CZ.json +1 -11
- umap/static/umap/locale/da.js +1 -11
- umap/static/umap/locale/da.json +1 -11
- umap/static/umap/locale/de.js +1 -11
- umap/static/umap/locale/de.json +1 -11
- umap/static/umap/locale/el.js +1 -11
- umap/static/umap/locale/el.json +1 -11
- umap/static/umap/locale/en.js +1 -11
- umap/static/umap/locale/en.json +1 -11
- umap/static/umap/locale/en_US.json +1 -11
- umap/static/umap/locale/es.js +1 -11
- umap/static/umap/locale/es.json +1 -11
- umap/static/umap/locale/et.js +1 -11
- umap/static/umap/locale/et.json +1 -11
- umap/static/umap/locale/fa_IR.js +6 -16
- umap/static/umap/locale/fa_IR.json +6 -16
- umap/static/umap/locale/fi.js +1 -11
- umap/static/umap/locale/fi.json +1 -11
- umap/static/umap/locale/fr.js +1 -11
- umap/static/umap/locale/fr.json +1 -11
- umap/static/umap/locale/gl.js +1 -11
- umap/static/umap/locale/gl.json +1 -11
- umap/static/umap/locale/he.js +1 -11
- umap/static/umap/locale/he.json +1 -11
- umap/static/umap/locale/hr.js +1 -11
- umap/static/umap/locale/hr.json +1 -11
- umap/static/umap/locale/hu.js +1 -11
- umap/static/umap/locale/hu.json +1 -11
- umap/static/umap/locale/id.js +1 -11
- umap/static/umap/locale/id.json +1 -11
- umap/static/umap/locale/is.js +1 -11
- umap/static/umap/locale/is.json +1 -11
- umap/static/umap/locale/it.js +1 -11
- umap/static/umap/locale/it.json +1 -11
- umap/static/umap/locale/ja.js +1 -11
- umap/static/umap/locale/ja.json +1 -11
- umap/static/umap/locale/ko.js +1 -11
- umap/static/umap/locale/ko.json +1 -11
- umap/static/umap/locale/lt.js +1 -11
- umap/static/umap/locale/lt.json +1 -11
- umap/static/umap/locale/ms.js +1 -11
- umap/static/umap/locale/ms.json +1 -11
- umap/static/umap/locale/nl.js +1 -11
- umap/static/umap/locale/nl.json +1 -11
- umap/static/umap/locale/no.js +1 -11
- umap/static/umap/locale/no.json +1 -11
- umap/static/umap/locale/pl.js +1 -11
- umap/static/umap/locale/pl.json +1 -11
- umap/static/umap/locale/pl_PL.json +1 -11
- umap/static/umap/locale/pt.js +1 -11
- umap/static/umap/locale/pt.json +1 -11
- umap/static/umap/locale/pt_BR.js +1 -11
- umap/static/umap/locale/pt_BR.json +1 -11
- umap/static/umap/locale/pt_PT.js +1 -11
- umap/static/umap/locale/pt_PT.json +1 -11
- umap/static/umap/locale/ro.js +1 -11
- umap/static/umap/locale/ro.json +1 -11
- umap/static/umap/locale/ru.js +1 -11
- umap/static/umap/locale/ru.json +1 -11
- umap/static/umap/locale/sk_SK.js +1 -11
- umap/static/umap/locale/sk_SK.json +1 -11
- umap/static/umap/locale/sl.js +1 -11
- umap/static/umap/locale/sl.json +1 -11
- umap/static/umap/locale/sr.js +1 -11
- umap/static/umap/locale/sr.json +1 -11
- umap/static/umap/locale/sv.js +1 -11
- umap/static/umap/locale/sv.json +1 -11
- umap/static/umap/locale/th_TH.js +1 -11
- umap/static/umap/locale/th_TH.json +1 -11
- umap/static/umap/locale/tr.js +1 -11
- umap/static/umap/locale/tr.json +1 -11
- umap/static/umap/locale/uk_UA.js +1 -11
- umap/static/umap/locale/uk_UA.json +1 -11
- umap/static/umap/locale/vi.js +1 -11
- umap/static/umap/locale/vi.json +1 -11
- umap/static/umap/locale/vi_VN.json +1 -11
- umap/static/umap/locale/zh.js +1 -11
- umap/static/umap/locale/zh.json +1 -11
- umap/static/umap/locale/zh_CN.json +1 -11
- umap/static/umap/locale/zh_TW.Big5.json +1 -11
- umap/static/umap/locale/zh_TW.js +17 -27
- umap/static/umap/locale/zh_TW.json +17 -27
- umap/static/umap/map.css +2 -2
- umap/static/umap/nav.css +2 -1
- umap/static/umap/test/.eslintrc +0 -1
- umap/static/umap/test/Choropleth.js +29 -27
- umap/static/umap/test/DataLayer.js +207 -239
- umap/static/umap/test/Feature.js +33 -58
- umap/static/umap/test/Map.Export.js +11 -11
- umap/static/umap/test/Map.js +66 -67
- umap/static/umap/test/Marker.js +36 -32
- umap/static/umap/test/Polygon.js +95 -95
- umap/static/umap/test/Polyline.js +31 -31
- umap/static/umap/test/TableEditor.js +29 -25
- umap/static/umap/test/_pre.js +2 -7
- umap/static/umap/test/index.html +4 -4
- umap/static/umap/vendors/contextmenu/leaflet.contextmenu.css +54 -0
- umap/static/umap/vendors/contextmenu/leaflet.contextmenu.js +586 -0
- umap/static/umap/vendors/csv2geojson/index.js +259 -0
- umap/static/umap/vendors/dompurify/purify.js +1633 -0
- umap/static/umap/vendors/locatecontrol/L.Control.Locate.css +63 -0
- umap/static/umap/vendors/locatecontrol/L.Control.Locate.js +950 -0
- umap/static/umap/vendors/minimap/Control.MiniMap.css +88 -0
- umap/static/umap/vendors/minimap/Control.MiniMap.js +352 -0
- umap/static/umap/vendors/togeojson/togeojson.js +2 -0
- umap/templates/auth/user_form.html +3 -2
- umap/templates/base.html +1 -0
- umap/templates/registration/login.html +51 -36
- umap/templates/umap/about_summary.html +1 -1
- umap/templates/umap/branding.html +3 -0
- umap/templates/umap/content.html +15 -39
- umap/templates/umap/header.html +0 -0
- umap/templates/umap/home.html +4 -2
- umap/templates/umap/js.html +0 -1
- umap/templates/umap/map_detail.html +9 -0
- umap/templates/umap/map_init.html +1 -1
- umap/templates/umap/map_messages.html +4 -2
- umap/templates/umap/map_table.html +130 -69
- umap/templates/umap/navigation.html +2 -4
- umap/templates/umap/user_dashboard.html +29 -6
- umap/tests/base.py +1 -1
- umap/tests/integration/conftest.py +18 -0
- umap/tests/integration/test_anonymous_owned_map.py +6 -3
- umap/tests/integration/test_browser.py +166 -6
- umap/tests/integration/test_collaborative_editing.py +23 -5
- umap/tests/integration/test_dashboard.py +17 -0
- umap/tests/integration/test_edit_datalayer.py +4 -3
- umap/tests/integration/test_export_map.py +1 -1
- umap/tests/integration/test_import.py +9 -4
- umap/tests/integration/test_map.py +64 -0
- umap/tests/integration/test_map_preview.py +75 -0
- umap/tests/integration/test_owned_map.py +11 -25
- umap/tests/integration/test_picto.py +3 -3
- umap/tests/integration/test_querystring.py +52 -0
- umap/tests/integration/test_share.py +22 -0
- umap/tests/test_map_views.py +157 -14
- umap/tests/test_views.py +50 -11
- umap/urls.py +6 -12
- umap/views.py +170 -47
- {umap_project-1.14.0a5.dist-info → umap_project-2.0.0a0.dist-info}/METADATA +13 -15
- {umap_project-1.14.0a5.dist-info → umap_project-2.0.0a0.dist-info}/RECORD +220 -199
- umap/static/umap/js/umap.browser.js +0 -148
- umap/static/umap/js/umap.xhr.js +0 -304
- umap/static/umap/test/Controls.js +0 -100
- umap/static/umap/test/Map.Init.js +0 -46
- {umap_project-1.14.0a5.dist-info → umap_project-2.0.0a0.dist-info}/WHEEL +0 -0
- {umap_project-1.14.0a5.dist-info → umap_project-2.0.0a0.dist-info}/entry_points.txt +0 -0
- {umap_project-1.14.0a5.dist-info → umap_project-2.0.0a0.dist-info}/licenses/LICENSE +0 -0
umap/templates/umap/home.html
CHANGED
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
</div>
|
|
11
11
|
{% endif %}
|
|
12
12
|
<div class="wrapper">
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
{% if maps %}
|
|
14
|
+
<h2 class="section">{% blocktrans %}Get inspired, browse maps{% endblocktrans %}</h2>
|
|
15
|
+
<div class="map_list row">{% include "umap/map_list.html" %}</div>
|
|
16
|
+
{% endif %}
|
|
15
17
|
</div>
|
|
16
18
|
{% endblock maincontent %}
|
umap/templates/umap/js.html
CHANGED
|
@@ -36,7 +36,6 @@
|
|
|
36
36
|
<script src="{% static 'umap/js/umap.core.js' %}" defer></script>
|
|
37
37
|
<script src="{% static 'umap/js/umap.autocomplete.js' %}" defer></script>
|
|
38
38
|
<script src="{% static 'umap/js/umap.popup.js' %}" defer></script>
|
|
39
|
-
<script src="{% static 'umap/js/umap.xhr.js' %}" defer></script>
|
|
40
39
|
<script src="{% static 'umap/js/umap.forms.js' %}" defer></script>
|
|
41
40
|
<script src="{% static 'umap/js/umap.icon.js' %}" defer></script>
|
|
42
41
|
<script src="{% static 'umap/js/umap.features.js' %}" defer></script>
|
|
@@ -7,9 +7,18 @@
|
|
|
7
7
|
map_detail
|
|
8
8
|
{% endblock body_class %}
|
|
9
9
|
{% block extra_head %}
|
|
10
|
+
{% if preconnect_domains %}
|
|
11
|
+
{% for domain in preconnect_domains %}
|
|
12
|
+
<link rel="preconnect" href="{{ domain }}" />
|
|
13
|
+
{% endfor %}
|
|
14
|
+
{% endif %}
|
|
10
15
|
{% umap_css %}
|
|
16
|
+
{{ block.super }}
|
|
11
17
|
{% umap_js locale=locale %}
|
|
12
18
|
{% if object.share_status != object.PUBLIC %}<meta name="robots" content="noindex">{% endif %}
|
|
19
|
+
<link rel="alternate" type="application/json+oembed"
|
|
20
|
+
href="{{ oembed_absolute_uri }}?url={{ absolute_uri|urlencode }}&format=json"
|
|
21
|
+
title="{{ map.name }} oEmbed URL" />
|
|
13
22
|
{% endblock extra_head %}
|
|
14
23
|
{% block content %}
|
|
15
24
|
{% block map_init %}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
<script type="text/javascript">
|
|
2
|
-
|
|
2
|
+
window.addEventListener('DOMContentLoaded', (event) => {
|
|
3
|
+
{% for m in messages %}
|
|
3
4
|
{# We have just one, but we need to loop, as for messages API #}
|
|
4
|
-
|
|
5
|
+
MAP.ui.alert({
|
|
5
6
|
content: "{{ m }}",
|
|
6
7
|
level: "{{ m.tags }}",
|
|
7
8
|
duration: 100000
|
|
8
9
|
})
|
|
9
10
|
{% endfor %}
|
|
11
|
+
})
|
|
10
12
|
</script>
|
|
@@ -1,73 +1,134 @@
|
|
|
1
1
|
{% load umap_tags i18n %}
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
<
|
|
5
|
-
<
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
<
|
|
19
|
-
<
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
<
|
|
23
|
-
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
|
|
2
|
+
<div class="table-wrapper">
|
|
3
|
+
<table>
|
|
4
|
+
<thead>
|
|
5
|
+
<tr>
|
|
6
|
+
<th>{% blocktrans %}Name{% endblocktrans %}</th>
|
|
7
|
+
<th>{% blocktrans %}Preview{% endblocktrans %}</th>
|
|
8
|
+
<th>{% blocktrans %}Who can see{% endblocktrans %}</th>
|
|
9
|
+
<th>{% blocktrans %}Who can edit{% endblocktrans %}</th>
|
|
10
|
+
<th>{% blocktrans %}Last save{% endblocktrans %}</th>
|
|
11
|
+
<th>{% blocktrans %}Owner{% endblocktrans %}</th>
|
|
12
|
+
<th>{% blocktrans %}Actions{% endblocktrans %}</th>
|
|
13
|
+
</tr>
|
|
14
|
+
</thead>
|
|
15
|
+
<tbody>
|
|
16
|
+
{% for map_inst in maps %}
|
|
17
|
+
{% with unique_id="map_"|addstr:map_inst.pk %}
|
|
18
|
+
<tr>
|
|
19
|
+
<td>
|
|
20
|
+
<a href="{{ map_inst.get_absolute_url }}">{{ map_inst.name }}</a>
|
|
21
|
+
</td>
|
|
22
|
+
<td>
|
|
23
|
+
{{ map_inst.preview_settings|json_script:unique_id }}
|
|
24
|
+
<button class="map-icon map-opener" data-map-id="{{ unique_id }}"
|
|
25
|
+
title="{% translate "Open preview" %}">
|
|
26
|
+
<span class="icon-dashboard icon-view"></span>
|
|
27
|
+
<span class="sr-only">{% translate "Open preview" %}</span>
|
|
28
|
+
</button>
|
|
29
|
+
<dialog>
|
|
30
|
+
<form method="dialog">
|
|
31
|
+
<div id="{{ unique_id }}_target" class="map_fragment"></div>
|
|
32
|
+
<p class="close-dialog">
|
|
33
|
+
<button class="button" type="submit">Close</button>
|
|
34
|
+
</p>
|
|
35
|
+
</form>
|
|
36
|
+
</dialog>
|
|
37
|
+
</td>
|
|
38
|
+
<td>{{ map_inst.get_share_status_display }}</td>
|
|
39
|
+
<td>{{ map_inst.get_edit_status_display }}</td>
|
|
40
|
+
<td>{{ map_inst.modified_at }}</td>
|
|
41
|
+
<td>
|
|
42
|
+
<a href="{{ map_inst.owner.get_url }}">{{ map_inst.owner }}</a>
|
|
43
|
+
</td>
|
|
44
|
+
<td>
|
|
45
|
+
<a href="{{ map_inst.get_absolute_url }}?share" class="icon-link"
|
|
46
|
+
title="{% translate "Share" %}">
|
|
47
|
+
<span class="icon-dashboard icon-share"></span>
|
|
48
|
+
<span class="sr-only">{% translate "Share" %}</span>
|
|
49
|
+
</a>
|
|
50
|
+
<a href="{{ map_inst.get_absolute_url }}?edit" class="icon-link"
|
|
51
|
+
title="{% translate "Edit" %}">
|
|
52
|
+
<span class="icon-dashboard icon-edit"></span>
|
|
53
|
+
<span class="sr-only">{% translate "Edit" %}</span>
|
|
54
|
+
</a>
|
|
55
|
+
<a href="{% url 'map_download' map_inst.pk %}" class="icon-link"
|
|
56
|
+
title="{% translate "Download" %}">
|
|
57
|
+
<span class="icon-dashboard icon-download"></span>
|
|
58
|
+
<span class="sr-only">{% translate "Download" %}</span>
|
|
59
|
+
</a>
|
|
60
|
+
<form action="{% url 'map_clone' map_inst.pk %}" method="post">
|
|
61
|
+
{% csrf_token %}
|
|
62
|
+
<button class="map-icon" type="submit"
|
|
63
|
+
title="{% translate "Clone" %}">
|
|
64
|
+
<span class="icon-dashboard icon-duplicate"></span>
|
|
65
|
+
<span class="sr-only">{% translate "Clone" %}</span>
|
|
66
|
+
</button>
|
|
29
67
|
</form>
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
</
|
|
42
|
-
|
|
43
|
-
{%
|
|
44
|
-
|
|
45
|
-
</
|
|
46
|
-
</
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
{
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
68
|
+
<form action="{% url 'map_delete' map_inst.pk %}"
|
|
69
|
+
method="post" class="map-delete">
|
|
70
|
+
{% csrf_token %}
|
|
71
|
+
<input type="hidden" name="next" value="{% url 'user_dashboard' %}">
|
|
72
|
+
<button class="map-icon" type="submit"
|
|
73
|
+
title="{% translate "Delete" %}">
|
|
74
|
+
<span class="icon-dashboard icon-delete"></span>
|
|
75
|
+
<span class="sr-only">{% translate "Delete" %}</span>
|
|
76
|
+
</button>
|
|
77
|
+
</form>
|
|
78
|
+
</td>
|
|
79
|
+
</tr>
|
|
80
|
+
{% endwith %}
|
|
81
|
+
{% endfor %}
|
|
82
|
+
</tbody>
|
|
83
|
+
</table>
|
|
84
|
+
</div>
|
|
85
|
+
{% if maps.has_other_pages %}
|
|
86
|
+
<div class="pagination">
|
|
87
|
+
{% if maps.has_previous %}
|
|
88
|
+
<a href="?p=1{% if q %}&q={{ q }}{% endif %}">« {% translate "first" %}</a>
|
|
89
|
+
<a href="?p={{ maps.previous_page_number }}{% if q %}&q={{ q }}{% endif %}">‹ {% translate "previous" %}</a>
|
|
90
|
+
{% else %}
|
|
91
|
+
{# djlint:off #}
|
|
92
|
+
<span></span>
|
|
93
|
+
<span></span>
|
|
94
|
+
{# djlint:on #}
|
|
95
|
+
{% endif %}
|
|
57
96
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
97
|
+
<span class="current">
|
|
98
|
+
{% blocktranslate with maps_number=maps.number num_pages=maps.paginator.num_pages trimmed %}
|
|
99
|
+
Page {{ maps_number }} of {{ num_pages }}
|
|
100
|
+
{% endblocktranslate %}
|
|
101
|
+
</span>
|
|
63
102
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
103
|
+
{% if maps.has_next %}
|
|
104
|
+
<a href="?p={{ maps.next_page_number }}{% if q %}&q={{ q }}{% endif %}">{% translate "next" %} ›</a>
|
|
105
|
+
<a href="?p={{ maps.paginator.num_pages }}{% if q %}&q={{ q }}{% endif %}">{% translate "last" %} »</a>
|
|
106
|
+
{% else %}
|
|
107
|
+
{# djlint:off #}
|
|
108
|
+
<span></span>
|
|
109
|
+
<span></span>
|
|
110
|
+
{# djlint:on #}
|
|
111
|
+
{% endif %}
|
|
112
|
+
<span>
|
|
113
|
+
{% blocktranslate with per_page=maps.paginator.per_page trimmed %}
|
|
114
|
+
Lines per page: {{ per_page }}
|
|
115
|
+
{% endblocktranslate %}
|
|
116
|
+
</span>
|
|
117
|
+
<span>
|
|
118
|
+
{% blocktranslate with count=maps.paginator.count trimmed %}
|
|
119
|
+
{{ count }} maps
|
|
120
|
+
{% endblocktranslate %}
|
|
121
|
+
</span>
|
|
122
|
+
</div>
|
|
123
|
+
{% endif %}
|
|
124
|
+
<script>
|
|
125
|
+
!(function () {
|
|
126
|
+
for (const deleteForm of document.querySelectorAll('table.maps form.map-delete')) {
|
|
127
|
+
deleteForm.addEventListener('submit', (event) => {
|
|
128
|
+
if (!confirm(L._('Are you sure you want to delete this map?'))) {
|
|
129
|
+
event.preventDefault()
|
|
130
|
+
}
|
|
131
|
+
})
|
|
132
|
+
}
|
|
133
|
+
})()
|
|
134
|
+
</script>
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
{% load i18n %}
|
|
2
2
|
<nav class="umap-nav">
|
|
3
3
|
<section>
|
|
4
|
-
|
|
5
|
-
<a href="{% url "home" %}">{{ title }}</a>
|
|
6
|
-
</h1>
|
|
4
|
+
{% include "umap/branding.html" %}
|
|
7
5
|
</section>
|
|
8
6
|
<section>
|
|
9
7
|
<ul>
|
|
@@ -39,7 +37,7 @@
|
|
|
39
37
|
</section>
|
|
40
38
|
<section>
|
|
41
39
|
{% if not UMAP_READONLY %}
|
|
42
|
-
<a href="{% url "map_new" %}" class="button">{% trans "Create a map" %}</a>
|
|
40
|
+
<a href="{% url "map_new" %}" class="button button-primary">{% trans "Create a map" %}</a>
|
|
43
41
|
{% endif %}
|
|
44
42
|
</section>
|
|
45
43
|
</nav>
|
|
@@ -5,15 +5,37 @@
|
|
|
5
5
|
{% endblock head_title %}
|
|
6
6
|
{% block maincontent %}
|
|
7
7
|
{% trans "Search my maps" as placeholder %}
|
|
8
|
-
<div class="
|
|
8
|
+
<div class="row">
|
|
9
9
|
<h2 class="section tabs">
|
|
10
|
-
<a class="selected" href="{% url 'user_dashboard' %}"
|
|
10
|
+
<a class="selected" href="{% url 'user_dashboard' %}"
|
|
11
|
+
>{% blocktranslate with count=maps.paginator.count %}My Maps ({{ count }}){% endblocktranslate %}
|
|
12
|
+
</a>
|
|
13
|
+
<a href="{% url 'user_profile' %}">{% trans "My profile" %}</a>
|
|
11
14
|
</h2>
|
|
12
|
-
{% include "umap/search_bar.html" with action=request.get_full_path placeholder=placeholder %}
|
|
13
15
|
</div>
|
|
14
16
|
<div class="wrapper">
|
|
15
17
|
<div class="row">
|
|
16
|
-
|
|
18
|
+
<div class="table-header">
|
|
19
|
+
<form action="{{ request.get_full_path }}" method="get">
|
|
20
|
+
<span>
|
|
21
|
+
<label class="sr-only" for="q">{% translate "Map’s title" %}</label>
|
|
22
|
+
<input id="q" name="q" type="search"
|
|
23
|
+
placeholder="{% translate "Map’s title" %}"
|
|
24
|
+
value="{{ request.GET.q|default:"" }}" />
|
|
25
|
+
</span>
|
|
26
|
+
<input type="submit" value="{% trans "Search my maps" %}" />
|
|
27
|
+
</form>
|
|
28
|
+
{% if maps.object_list|length > 1 %}
|
|
29
|
+
<a href="{% url 'user_download' %}?{% spaceless %}
|
|
30
|
+
{% for map_inst in maps %}map_id={{ map_inst.pk }}{% if not forloop.last %}&{% endif %}{% endfor %}
|
|
31
|
+
{% endspaceless %}" class="button button-download"
|
|
32
|
+
>{% blocktranslate with count=maps.object_list|length trimmed %}
|
|
33
|
+
Download {{ count }} maps
|
|
34
|
+
{% endblocktranslate %}
|
|
35
|
+
</a>
|
|
36
|
+
{% endif %}
|
|
37
|
+
</div>
|
|
38
|
+
{% if maps or request.GET.q %}
|
|
17
39
|
{% include "umap/map_table.html" %}
|
|
18
40
|
{% else %}
|
|
19
41
|
<div>
|
|
@@ -31,8 +53,9 @@
|
|
|
31
53
|
const CACHE = {}
|
|
32
54
|
for (const mapOpener of document.querySelectorAll("button.map-opener")) {
|
|
33
55
|
mapOpener.addEventListener('click', (event) => {
|
|
34
|
-
event.target.
|
|
35
|
-
|
|
56
|
+
const button = event.target.closest('button')
|
|
57
|
+
button.nextElementSibling.showModal()
|
|
58
|
+
const mapId = button.dataset.mapId
|
|
36
59
|
if (!document.querySelector(`#${mapId}_target`).hasChildNodes()) {
|
|
37
60
|
const previewSettings = JSON.parse(document.getElementById(mapId).textContent)
|
|
38
61
|
const map = new L.U.Map(`${mapId}_target`, previewSettings)
|
umap/tests/base.py
CHANGED
|
@@ -81,7 +81,7 @@ class MapFactory(factory.django.DjangoModelFactory):
|
|
|
81
81
|
"attribution": "\xa9 OSM Contributors",
|
|
82
82
|
"maxZoom": 18,
|
|
83
83
|
"minZoom": 0,
|
|
84
|
-
"url_template": "https://
|
|
84
|
+
"url_template": "https://a.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png",
|
|
85
85
|
},
|
|
86
86
|
"tilelayersControl": True,
|
|
87
87
|
"zoom": 7,
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
@pytest.fixture
|
|
5
|
+
def login(context, settings, live_server):
|
|
6
|
+
def do_login(user):
|
|
7
|
+
# TODO use storage state to do login only once per session
|
|
8
|
+
# https://playwright.dev/python/docs/auth
|
|
9
|
+
settings.ENABLE_ACCOUNT_LOGIN = True
|
|
10
|
+
page = context.new_page()
|
|
11
|
+
page.goto(f"{live_server.url}/en/")
|
|
12
|
+
page.locator(".login").click()
|
|
13
|
+
page.get_by_placeholder("Username").fill(user.username)
|
|
14
|
+
page.get_by_placeholder("Password").fill("123123")
|
|
15
|
+
page.locator('#login_form input[type="submit"]').click()
|
|
16
|
+
return page
|
|
17
|
+
|
|
18
|
+
return do_login
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import re
|
|
2
|
-
from time import sleep
|
|
3
2
|
|
|
4
3
|
import pytest
|
|
5
4
|
from django.core.signing import get_cookie_signer
|
|
@@ -126,10 +125,14 @@ def test_anonymous_can_add_marker_on_editable_layer(
|
|
|
126
125
|
|
|
127
126
|
def test_can_change_perms_after_create(tilelayer, live_server, page):
|
|
128
127
|
page.goto(f"{live_server.url}/en/map/new")
|
|
128
|
+
# Create a layer
|
|
129
|
+
page.get_by_title("Manage layers").click()
|
|
130
|
+
page.get_by_role("button", name="Add a layer").click()
|
|
131
|
+
page.locator("input[name=name]").fill("Layer 1")
|
|
129
132
|
save = page.get_by_role("button", name="Save")
|
|
130
133
|
expect(save).to_be_visible()
|
|
131
|
-
|
|
132
|
-
|
|
134
|
+
with page.expect_response(re.compile(r".*/datalayer/create/.*")):
|
|
135
|
+
save.click()
|
|
133
136
|
edit_permissions = page.get_by_title("Update permissions and editors")
|
|
134
137
|
expect(edit_permissions).to_be_visible()
|
|
135
138
|
edit_permissions.click()
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
from copy import deepcopy
|
|
1
2
|
from time import sleep
|
|
2
3
|
|
|
3
4
|
import pytest
|
|
4
5
|
from playwright.sync_api import expect
|
|
5
6
|
|
|
7
|
+
from umap.models import Map
|
|
8
|
+
|
|
6
9
|
from ..base import DataLayerFactory
|
|
7
10
|
|
|
8
11
|
pytestmark = pytest.mark.django_db
|
|
@@ -13,12 +16,12 @@ DATALAYER_DATA = {
|
|
|
13
16
|
"features": [
|
|
14
17
|
{
|
|
15
18
|
"type": "Feature",
|
|
16
|
-
"properties": {"name": "one point in france"},
|
|
19
|
+
"properties": {"name": "one point in france", "foo": "point"},
|
|
17
20
|
"geometry": {"type": "Point", "coordinates": [3.339844, 46.920255]},
|
|
18
21
|
},
|
|
19
22
|
{
|
|
20
23
|
"type": "Feature",
|
|
21
|
-
"properties": {"name": "one polygon in greenland"},
|
|
24
|
+
"properties": {"name": "one polygon in greenland", "foo": "polygon"},
|
|
22
25
|
"geometry": {
|
|
23
26
|
"type": "Polygon",
|
|
24
27
|
"coordinates": [
|
|
@@ -34,7 +37,7 @@ DATALAYER_DATA = {
|
|
|
34
37
|
},
|
|
35
38
|
{
|
|
36
39
|
"type": "Feature",
|
|
37
|
-
"properties": {"name": "one line in new zeland"},
|
|
40
|
+
"properties": {"name": "one line in new zeland", "foo": "line"},
|
|
38
41
|
"geometry": {
|
|
39
42
|
"type": "LineString",
|
|
40
43
|
"coordinates": [
|
|
@@ -71,15 +74,32 @@ def test_data_browser_should_be_open(live_server, page, bootstrap, map):
|
|
|
71
74
|
|
|
72
75
|
def test_data_browser_should_be_filterable(live_server, page, bootstrap, map):
|
|
73
76
|
page.goto(f"{live_server.url}{map.get_absolute_url()}")
|
|
77
|
+
expect(page.get_by_title("Features in this layer: 3")).to_be_visible()
|
|
74
78
|
markers = page.locator(".leaflet-marker-icon")
|
|
79
|
+
paths = page.locator(".leaflet-overlay-pane path")
|
|
75
80
|
expect(markers).to_have_count(1)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
81
|
+
expect(paths).to_have_count(2)
|
|
82
|
+
filter_ = page.locator("input[name='filter']")
|
|
83
|
+
expect(filter_).to_be_visible()
|
|
84
|
+
filter_.type("poly")
|
|
85
|
+
expect(page.get_by_title("Features in this layer: 1/3")).to_be_visible()
|
|
86
|
+
expect(page.get_by_title("Features in this layer: 1/3")).to_have_text("1/3")
|
|
79
87
|
expect(page.get_by_text("one point in france")).to_be_hidden()
|
|
80
88
|
expect(page.get_by_text("one line in new zeland")).to_be_hidden()
|
|
81
89
|
expect(page.get_by_text("one polygon in greenland")).to_be_visible()
|
|
82
90
|
expect(markers).to_have_count(0) # Hidden by filter
|
|
91
|
+
expect(paths).to_have_count(1) # Only polygon
|
|
92
|
+
# Empty the filter
|
|
93
|
+
filter_.fill("")
|
|
94
|
+
filter_.blur()
|
|
95
|
+
expect(markers).to_have_count(1)
|
|
96
|
+
expect(paths).to_have_count(2)
|
|
97
|
+
filter_.type("point")
|
|
98
|
+
expect(page.get_by_text("one point in france")).to_be_visible()
|
|
99
|
+
expect(page.get_by_text("one line in new zeland")).to_be_hidden()
|
|
100
|
+
expect(page.get_by_text("one polygon in greenland")).to_be_hidden()
|
|
101
|
+
expect(markers).to_have_count(1)
|
|
102
|
+
expect(paths).to_have_count(0)
|
|
83
103
|
|
|
84
104
|
|
|
85
105
|
def test_data_browser_can_show_only_visible_features(live_server, page, bootstrap, map):
|
|
@@ -131,3 +151,143 @@ def test_data_browser_bbox_limit_should_be_dynamic(live_server, page, bootstrap,
|
|
|
131
151
|
expect(page.get_by_text("one point in france")).to_be_visible()
|
|
132
152
|
expect(page.get_by_text("one polygon in greenland")).to_be_visible()
|
|
133
153
|
expect(page.get_by_text("one line in new zeland")).to_be_hidden()
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def test_data_browser_bbox_filter_should_be_persistent(
|
|
157
|
+
live_server, page, bootstrap, map
|
|
158
|
+
):
|
|
159
|
+
# Zoom on Europe
|
|
160
|
+
page.goto(f"{live_server.url}{map.get_absolute_url()}#6/51.000/2.000")
|
|
161
|
+
el = page.get_by_text("Current map view")
|
|
162
|
+
expect(el).to_be_visible()
|
|
163
|
+
el.click()
|
|
164
|
+
browser = page.locator("#umap-ui-container")
|
|
165
|
+
expect(browser.get_by_text("one point in france")).to_be_visible()
|
|
166
|
+
expect(browser.get_by_text("one line in new zeland")).to_be_hidden()
|
|
167
|
+
expect(browser.get_by_text("one polygon in greenland")).to_be_hidden()
|
|
168
|
+
# Close and reopen the browser to make sure this settings is persistent
|
|
169
|
+
close = browser.get_by_text("Close")
|
|
170
|
+
close.click()
|
|
171
|
+
expect(browser).to_be_hidden()
|
|
172
|
+
sleep(0.5)
|
|
173
|
+
expect(browser.get_by_text("one point in france")).to_be_hidden()
|
|
174
|
+
expect(browser.get_by_text("one line in new zeland")).to_be_hidden()
|
|
175
|
+
expect(browser.get_by_text("one polygon in greenland")).to_be_hidden()
|
|
176
|
+
page.get_by_title("See data layers").click()
|
|
177
|
+
page.get_by_role("button", name="Browse data").click()
|
|
178
|
+
expect(browser.get_by_text("one point in france")).to_be_visible()
|
|
179
|
+
expect(browser.get_by_text("one line in new zeland")).to_be_hidden()
|
|
180
|
+
expect(browser.get_by_text("one polygon in greenland")).to_be_hidden()
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def test_data_browser_bbox_filtered_is_clickable(live_server, page, bootstrap, map):
|
|
184
|
+
popup = page.locator(".leaflet-popup")
|
|
185
|
+
# Zoom on Europe
|
|
186
|
+
page.goto(f"{live_server.url}{map.get_absolute_url()}#6/51.000/2.000")
|
|
187
|
+
el = page.get_by_text("Current map view")
|
|
188
|
+
expect(el).to_be_visible()
|
|
189
|
+
el.click()
|
|
190
|
+
browser = page.locator("#umap-ui-container")
|
|
191
|
+
expect(browser.get_by_text("one point in france")).to_be_visible()
|
|
192
|
+
expect(browser.get_by_text("one line in new zeland")).to_be_hidden()
|
|
193
|
+
expect(browser.get_by_text("one polygon in greenland")).to_be_hidden()
|
|
194
|
+
expect(popup).to_be_hidden()
|
|
195
|
+
browser.get_by_text("one point in france").click()
|
|
196
|
+
expect(popup).to_be_visible()
|
|
197
|
+
expect(popup.get_by_text("one point in france")).to_be_visible()
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def test_data_browser_with_variable_in_name(live_server, page, bootstrap, map):
|
|
201
|
+
# Include a variable
|
|
202
|
+
map.settings["properties"]["labelKey"] = "{name} ({foo})"
|
|
203
|
+
map.save()
|
|
204
|
+
page.goto(f"{live_server.url}{map.get_absolute_url()}")
|
|
205
|
+
expect(page.get_by_text("one point in france (point)")).to_be_visible()
|
|
206
|
+
expect(page.get_by_text("one line in new zeland (line)")).to_be_visible()
|
|
207
|
+
expect(page.get_by_text("one polygon in greenland (polygon)")).to_be_visible()
|
|
208
|
+
filter_ = page.locator("input[name='filter']")
|
|
209
|
+
expect(filter_).to_be_visible()
|
|
210
|
+
filter_.type("foobar") # Hide all
|
|
211
|
+
expect(page.get_by_text("one point in france (point)")).to_be_hidden()
|
|
212
|
+
expect(page.get_by_text("one line in new zeland (line)")).to_be_hidden()
|
|
213
|
+
expect(page.get_by_text("one polygon in greenland (polygon)")).to_be_hidden()
|
|
214
|
+
# Empty back the filter
|
|
215
|
+
filter_.fill("")
|
|
216
|
+
filter_.blur()
|
|
217
|
+
expect(page.get_by_text("one point in france (point)")).to_be_visible()
|
|
218
|
+
expect(page.get_by_text("one line in new zeland (line)")).to_be_visible()
|
|
219
|
+
expect(page.get_by_text("one polygon in greenland (polygon)")).to_be_visible()
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def test_can_open_databrowser_from_layers_list(live_server, map, page, bootstrap):
|
|
223
|
+
page.goto(f"{live_server.url}{map.get_absolute_url()}")
|
|
224
|
+
page.get_by_title("See data layers").click()
|
|
225
|
+
page.get_by_role("button", name="Browse data").click()
|
|
226
|
+
browser = page.locator(".umap-browse-data")
|
|
227
|
+
expect(browser).to_be_visible()
|
|
228
|
+
expect(browser.get_by_text("test datalayer")).to_be_visible()
|
|
229
|
+
expect(browser.get_by_text("one point in france")).to_be_visible()
|
|
230
|
+
expect(browser.get_by_text("one line in new zeland")).to_be_visible()
|
|
231
|
+
expect(browser.get_by_text("one polygon in greenland")).to_be_visible()
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def test_should_sort_features_in_natural_order(live_server, map, page):
|
|
235
|
+
map.settings["properties"]["onLoadPanel"] = "databrowser"
|
|
236
|
+
map.save()
|
|
237
|
+
datalayer_data = deepcopy(DATALAYER_DATA)
|
|
238
|
+
datalayer_data["features"][0]["properties"]["name"] = "9. a marker"
|
|
239
|
+
datalayer_data["features"][1]["properties"]["name"] = "1. a poly"
|
|
240
|
+
datalayer_data["features"][2]["properties"]["name"] = "100. a line"
|
|
241
|
+
DataLayerFactory(map=map, data=datalayer_data)
|
|
242
|
+
page.goto(f"{live_server.url}{map.get_absolute_url()}")
|
|
243
|
+
features = page.locator(".umap-browse-data li")
|
|
244
|
+
expect(features).to_have_count(3)
|
|
245
|
+
expect(features.nth(0)).to_have_text("1. a poly")
|
|
246
|
+
expect(features.nth(1)).to_have_text("9. a marker")
|
|
247
|
+
expect(features.nth(2)).to_have_text("100. a line")
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def test_should_redraw_list_on_feature_delete(live_server, map, page, bootstrap):
|
|
251
|
+
map.edit_status = Map.ANONYMOUS
|
|
252
|
+
map.save()
|
|
253
|
+
page.goto(f"{live_server.url}{map.get_absolute_url()}")
|
|
254
|
+
# Enable edit
|
|
255
|
+
page.get_by_role("button", name="Edit").click()
|
|
256
|
+
buttons = page.locator(".umap-browse-data li .feature-delete")
|
|
257
|
+
expect(buttons).to_have_count(3)
|
|
258
|
+
page.on("dialog", lambda dialog: dialog.accept())
|
|
259
|
+
buttons.nth(0).click()
|
|
260
|
+
expect(buttons).to_have_count(2)
|
|
261
|
+
page.get_by_role("button", name="Cancel edits").click()
|
|
262
|
+
expect(buttons).to_have_count(3)
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def test_should_show_header_for_display_on_load_false(
|
|
266
|
+
live_server, page, bootstrap, map, datalayer
|
|
267
|
+
):
|
|
268
|
+
datalayer.settings["displayOnLoad"] = False
|
|
269
|
+
datalayer.settings["name"] = "This layer is not loaded"
|
|
270
|
+
datalayer.save()
|
|
271
|
+
page.goto(f"{live_server.url}{map.get_absolute_url()}")
|
|
272
|
+
browser = page.locator(".umap-browse-data")
|
|
273
|
+
expect(browser).to_be_visible()
|
|
274
|
+
expect(browser.get_by_text("This layer is not loaded")).to_be_visible()
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def test_should_use_color_variable(live_server, map, page):
|
|
278
|
+
map.settings["properties"]["onLoadPanel"] = "databrowser"
|
|
279
|
+
map.settings["properties"]["color"] = "{mycolor}"
|
|
280
|
+
map.save()
|
|
281
|
+
datalayer_data = deepcopy(DATALAYER_DATA)
|
|
282
|
+
datalayer_data["features"][0]["properties"]["mycolor"] = "DarkRed"
|
|
283
|
+
datalayer_data["features"][2]["properties"]["mycolor"] = "DarkGreen"
|
|
284
|
+
DataLayerFactory(map=map, data=datalayer_data)
|
|
285
|
+
page.goto(f"{live_server.url}{map.get_absolute_url()}")
|
|
286
|
+
features = page.locator(".umap-browse-data li .feature-color")
|
|
287
|
+
expect(features).to_have_count(3)
|
|
288
|
+
# DarkGreen
|
|
289
|
+
expect(features.nth(0)).to_have_css("background-color", "rgb(0, 100, 0)")
|
|
290
|
+
# DarkRed
|
|
291
|
+
expect(features.nth(1)).to_have_css("background-color", "rgb(139, 0, 0)")
|
|
292
|
+
# DarkBlue (default color)
|
|
293
|
+
expect(features.nth(2)).to_have_css("background-color", "rgb(0, 0, 139)")
|