commit
79da2a7956
11 changed files with 235 additions and 105 deletions
|
@ -282,6 +282,29 @@ ul.umap-autocomplete {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* **************************** */
|
||||||
|
/* Dashboard */
|
||||||
|
/* **************************** */
|
||||||
|
table.maps {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
table.maps .map_fragment {
|
||||||
|
height: 100px;
|
||||||
|
width: 100%;
|
||||||
|
min-width: 200px;
|
||||||
|
}
|
||||||
|
table.maps tbody tr:nth-child(odd) {
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
}
|
||||||
|
table.maps td {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
table.maps thead tr {
|
||||||
|
line-height: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* **************************** */
|
/* **************************** */
|
||||||
/* Override Leaflet.Storage */
|
/* Override Leaflet.Storage */
|
||||||
/* **************************** */
|
/* **************************** */
|
||||||
|
|
|
@ -1019,6 +1019,39 @@ L.U.Map.include({
|
||||||
this.ui.openPanel({ data: { html: container }, actions: actions })
|
this.ui.openPanel({ data: { html: container }, actions: actions })
|
||||||
},
|
},
|
||||||
|
|
||||||
|
EXPORT_TYPES: {
|
||||||
|
geojson: {
|
||||||
|
formatter: function (map) {
|
||||||
|
return JSON.stringify(map.toGeoJSON(), null, 2)
|
||||||
|
},
|
||||||
|
ext: '.geojson',
|
||||||
|
filetype: 'application/json',
|
||||||
|
},
|
||||||
|
gpx: {
|
||||||
|
formatter: function (map) {
|
||||||
|
return togpx(map.toGeoJSON())
|
||||||
|
},
|
||||||
|
ext: '.gpx',
|
||||||
|
filetype: 'application/xml',
|
||||||
|
},
|
||||||
|
kml: {
|
||||||
|
formatter: function (map) {
|
||||||
|
return tokml(map.toGeoJSON())
|
||||||
|
},
|
||||||
|
ext: '.kml',
|
||||||
|
filetype: 'application/vnd.google-earth.kml+xml',
|
||||||
|
},
|
||||||
|
umap: {
|
||||||
|
name: L._('Full map data'),
|
||||||
|
formatter: function (map) {
|
||||||
|
return map.serialize()
|
||||||
|
},
|
||||||
|
ext: '.umap',
|
||||||
|
filetype: 'application/json',
|
||||||
|
selected: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
renderShareBox: function () {
|
renderShareBox: function () {
|
||||||
const container = L.DomUtil.create('div', 'umap-share')
|
const container = L.DomUtil.create('div', 'umap-share')
|
||||||
const embedTitle = L.DomUtil.add('h4', '', container, L._('Embed the map'))
|
const embedTitle = L.DomUtil.add('h4', '', container, L._('Embed the map'))
|
||||||
|
@ -1091,65 +1124,35 @@ L.U.Map.include({
|
||||||
else exportCaveat.style.display = 'inherit'
|
else exportCaveat.style.display = 'inherit'
|
||||||
}
|
}
|
||||||
L.DomEvent.on(typeInput, 'change', toggleCaveat)
|
L.DomEvent.on(typeInput, 'change', toggleCaveat)
|
||||||
const types = {
|
for (const key in this.EXPORT_TYPES) {
|
||||||
geojson: {
|
if (this.EXPORT_TYPES.hasOwnProperty(key)) {
|
||||||
formatter: function (map) {
|
|
||||||
return JSON.stringify(map.toGeoJSON(), null, 2)
|
|
||||||
},
|
|
||||||
ext: '.geojson',
|
|
||||||
filetype: 'application/json',
|
|
||||||
},
|
|
||||||
gpx: {
|
|
||||||
formatter: function (map) {
|
|
||||||
return togpx(map.toGeoJSON())
|
|
||||||
},
|
|
||||||
ext: '.gpx',
|
|
||||||
filetype: 'application/xml',
|
|
||||||
},
|
|
||||||
kml: {
|
|
||||||
formatter: function (map) {
|
|
||||||
return tokml(map.toGeoJSON())
|
|
||||||
},
|
|
||||||
ext: '.kml',
|
|
||||||
filetype: 'application/vnd.google-earth.kml+xml',
|
|
||||||
},
|
|
||||||
umap: {
|
|
||||||
name: L._('Full map data'),
|
|
||||||
formatter: function (map) {
|
|
||||||
return map.serialize()
|
|
||||||
},
|
|
||||||
ext: '.umap',
|
|
||||||
filetype: 'application/json',
|
|
||||||
selected: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for (const key in types) {
|
|
||||||
if (types.hasOwnProperty(key)) {
|
|
||||||
option = L.DomUtil.create('option', '', typeInput)
|
option = L.DomUtil.create('option', '', typeInput)
|
||||||
option.value = key
|
option.value = key
|
||||||
option.textContent = types[key].name || key
|
option.textContent = this.EXPORT_TYPES[key].name || key
|
||||||
if (types[key].selected) option.selected = true
|
if (this.EXPORT_TYPES[key].selected) option.selected = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
toggleCaveat()
|
toggleCaveat()
|
||||||
const download = L.DomUtil.create('a', 'button', container)
|
const download = L.DomUtil.create('a', 'button', container)
|
||||||
download.textContent = L._('Download data')
|
download.textContent = L._('Download data')
|
||||||
L.DomEvent.on(
|
L.DomEvent.on(download, 'click', () => this.download(typeInput.value), this)
|
||||||
download,
|
this.ui.openPanel({ data: { html: container } })
|
||||||
'click',
|
},
|
||||||
() => {
|
|
||||||
const type = types[typeInput.value]
|
download: function (mode) {
|
||||||
|
const type = this.EXPORT_TYPES[mode || 'umap']
|
||||||
const content = type.formatter(this)
|
const content = type.formatter(this)
|
||||||
let name = this.options.name || 'data'
|
let name = this.options.name || 'data'
|
||||||
name = name.replace(/[^a-z0-9]/gi, '_').toLowerCase()
|
name = name.replace(/[^a-z0-9]/gi, '_').toLowerCase()
|
||||||
download.download = name + type.ext
|
|
||||||
window.URL = window.URL || window.webkitURL
|
window.URL = window.URL || window.webkitURL
|
||||||
const blob = new Blob([content], { type: type.filetype })
|
const blob = new Blob([content], { type: type.filetype })
|
||||||
download.href = window.URL.createObjectURL(blob)
|
const el = document.createElement('a')
|
||||||
},
|
el.download = name + type.ext
|
||||||
this
|
el.href = window.URL.createObjectURL(blob)
|
||||||
)
|
el.style.display = 'none'
|
||||||
this.ui.openPanel({ data: { html: container } })
|
document.body.appendChild(el)
|
||||||
|
el.click()
|
||||||
|
document.body.removeChild(el)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -91,12 +91,8 @@ L.U.Map.include({
|
||||||
|
|
||||||
this.ui = new L.U.UI(this._container)
|
this.ui = new L.U.UI(this._container)
|
||||||
this.xhr = new L.U.Xhr(this.ui)
|
this.xhr = new L.U.Xhr(this.ui)
|
||||||
this.xhr.on('dataloding', function (e) {
|
this.xhr.on('dataloading', (e) => this.fire('dataloading', e))
|
||||||
this.fire('dataloding', e)
|
this.xhr.on('dataload', (e) => this.fire('dataload', e))
|
||||||
})
|
|
||||||
this.xhr.on('datalaod', function (e) {
|
|
||||||
this.fire('datalaod', e)
|
|
||||||
})
|
|
||||||
|
|
||||||
this.initLoader()
|
this.initLoader()
|
||||||
this.name = this.options.name
|
this.name = this.options.name
|
||||||
|
@ -255,13 +251,16 @@ L.U.Map.include({
|
||||||
}
|
}
|
||||||
this.initShortcuts()
|
this.initShortcuts()
|
||||||
this.onceDatalayersLoaded(function () {
|
this.onceDatalayersLoaded(function () {
|
||||||
if (this.options.onLoadPanel === 'databrowser') this.openBrowser()
|
if (L.Util.queryString('share')) this.renderShareBox()
|
||||||
|
else if (this.options.onLoadPanel === 'databrowser') this.openBrowser()
|
||||||
else if (this.options.onLoadPanel === 'caption') this.displayCaption()
|
else if (this.options.onLoadPanel === 'caption') this.displayCaption()
|
||||||
else if (this.options.onLoadPanel === 'datafilters') this.openFilter()
|
else if (this.options.onLoadPanel === 'datafilters') this.openFilter()
|
||||||
})
|
})
|
||||||
this.onceDataLoaded(function () {
|
this.onceDataLoaded(function () {
|
||||||
const slug = L.Util.queryString('feature')
|
const slug = L.Util.queryString('feature')
|
||||||
if (slug && this.features_index[slug]) this.features_index[slug].view()
|
if (slug && this.features_index[slug]) this.features_index[slug].view()
|
||||||
|
if (L.Util.queryString('edit')) this.enableEdit()
|
||||||
|
if (L.Util.queryString('download')) this.download()
|
||||||
})
|
})
|
||||||
|
|
||||||
window.onbeforeunload = (e) => {
|
window.onbeforeunload = (e) => {
|
||||||
|
|
41
umap/templates/umap/map_table.html
Normal file
41
umap/templates/umap/map_table.html
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
{% load umap_tags umap_tags i18n %}
|
||||||
|
<table class="maps">
|
||||||
|
{% if not is_ajax %}
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{% blocktrans %}Map{% endblocktrans %}</th>
|
||||||
|
<th>{% blocktrans %}Name{% endblocktrans %}</th>
|
||||||
|
<th>{% blocktrans %}Status{% endblocktrans %}</th>
|
||||||
|
<th>{% blocktrans %}Last save{% endblocktrans %}</th>
|
||||||
|
<th>{% blocktrans %}Owner{% endblocktrans %}</th>
|
||||||
|
<th>{% blocktrans %}Actions{% endblocktrans %}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
{% endif %}
|
||||||
|
<tbody>
|
||||||
|
{% for map_inst in maps %}
|
||||||
|
<tr>
|
||||||
|
<td>{% map_fragment map_inst prefix=prefix page=request.GET.p %}</td>
|
||||||
|
<td>
|
||||||
|
<a href="{{ map_inst.get_absolute_url }}">{{ map_inst.name }}</a>
|
||||||
|
</td>
|
||||||
|
<td>{{ map_inst.get_edit_status_display }}</td>
|
||||||
|
<td>{{ map_inst.modified_at }}</td>
|
||||||
|
<td>
|
||||||
|
<a href="{{ map_inst.owner.get_url }}">{{ map_inst.owner }}</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="{{ map_inst.get_absolute_url }}?share">{% translate "Share" %}</a>
|
||||||
|
<a href="{{ map_inst.get_absolute_url }}?edit">{% translate "Edit" %}</a>
|
||||||
|
<a href="{{ map_inst.get_absolute_url }}?download">{% translate "Download" %}</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% if maps.has_next %}
|
||||||
|
<div class="col wide">
|
||||||
|
<a href="?{% paginate_querystring maps.next_page_number %}"
|
||||||
|
class="button more_button neutral">{% trans "More" %}</a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
|
@ -9,7 +9,7 @@
|
||||||
<ul>
|
<ul>
|
||||||
{% if user.is_authenticated %}
|
{% if user.is_authenticated %}
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ user.get_url }}">{% trans "My maps" %} ({{ user }})</a>
|
<a href="{% url 'user_dashboard' %}">{% trans "My maps" %} ({{ user }})</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ user.get_stars_url }}">{% trans "Starred maps" %}</a>
|
<a href="{{ user.get_stars_url }}">{% trans "Starred maps" %}</a>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
{% include "umap/search_bar.html" %}
|
{% include "umap/search_bar.html" %}
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<div class="map_list row">
|
<div class="map_list row">
|
||||||
{% if q %}
|
{% if request.GET.q %}
|
||||||
{% if maps %}
|
{% if maps %}
|
||||||
<h2>
|
<h2>
|
||||||
{% blocktranslate trimmed count counter=count %}
|
{% blocktranslate trimmed count counter=count %}
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
{% url "search" as search_url %}
|
||||||
|
{% trans "Search maps" as default_placeholder %}
|
||||||
<div class="wrapper search_wrapper">
|
<div class="wrapper search_wrapper">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<form action="{% url "search" %}" method="get">
|
<form action="{% firstof action search_url %}" method="get">
|
||||||
<div class="col two-third mwide">
|
<div class="col two-third mwide">
|
||||||
<input name="q"
|
<input name="q"
|
||||||
type="search"
|
type="search"
|
||||||
placeholder="{% trans "Search maps" %}"
|
placeholder="{% firstof placeholder default_placeholder %}"
|
||||||
value="{{ q|default:"" }}" />
|
value="{{ request.GET.q|default:"" }}" />
|
||||||
</div>
|
</div>
|
||||||
<div class="col third mwide">
|
<div class="col third mwide">
|
||||||
<input type="submit" value="{% trans "Search" %}" class="neutral" />
|
<input type="submit" value="{% trans "Search" %}" class="neutral" />
|
||||||
|
|
25
umap/templates/umap/user_dashboard.html
Normal file
25
umap/templates/umap/user_dashboard.html
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
{% extends "umap/content.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block head_title %}
|
||||||
|
{{ SITE_NAME }} - {% trans "My dashboard" %}
|
||||||
|
{% endblock head_title %}
|
||||||
|
|
||||||
|
{% block maincontent %}
|
||||||
|
{% trans "Search my maps" as placeholder %}
|
||||||
|
<div class="col wide">
|
||||||
|
<h2 class="section">{% trans "My dashboard" %}</h2>
|
||||||
|
{% include "umap/search_bar.html" with action=request.get_full_path placeholder=placeholder %}
|
||||||
|
</div>
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="row">
|
||||||
|
{% if maps %}
|
||||||
|
{% include "umap/map_table.html" %}
|
||||||
|
{% else %}
|
||||||
|
<div>
|
||||||
|
{% blocktrans %}You have no map yet.{% endblocktrans %} <a href="{% url 'map_new' %}">{% translate "Create a map" %}</a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock maincontent %}
|
|
@ -240,3 +240,22 @@ def test_change_user_slug(client, user, settings):
|
||||||
settings.USER_URL_FIELD = "pk"
|
settings.USER_URL_FIELD = "pk"
|
||||||
response = client.get(reverse("home"))
|
response = client.get(reverse("home"))
|
||||||
assert f"/en/user/{user.pk}/" in response.content.decode()
|
assert f"/en/user/{user.pk}/" in response.content.decode()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_user_dashboard_is_restricted_to_logged_in(client):
|
||||||
|
response = client.get(reverse("user_dashboard"))
|
||||||
|
assert response.status_code == 302
|
||||||
|
assert response["Location"] == "/en/login/?next=/en/me"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_user_dashboard_display_user_maps(client, map):
|
||||||
|
client.login(username=map.owner.username, password="123123")
|
||||||
|
response = client.get(reverse("user_dashboard"))
|
||||||
|
assert response.status_code == 200
|
||||||
|
body = response.content.decode()
|
||||||
|
assert map.name in body
|
||||||
|
assert f"{map.get_absolute_url()}?edit" in body
|
||||||
|
assert f"{map.get_absolute_url()}?share" in body
|
||||||
|
assert f"{map.get_absolute_url()}?download" in body
|
||||||
|
|
|
@ -98,6 +98,11 @@ i18n_urls += decorated_patterns(
|
||||||
views.ToggleMapStarStatus.as_view(),
|
views.ToggleMapStarStatus.as_view(),
|
||||||
name="map_star",
|
name="map_star",
|
||||||
),
|
),
|
||||||
|
re_path(
|
||||||
|
r"^me$",
|
||||||
|
views.user_dashboard,
|
||||||
|
name="user_dashboard",
|
||||||
|
),
|
||||||
)
|
)
|
||||||
map_urls = [
|
map_urls = [
|
||||||
re_path(
|
re_path(
|
||||||
|
|
|
@ -77,7 +77,7 @@ PRIVATE_IP = re.compile(
|
||||||
ANONYMOUS_COOKIE_MAX_AGE = 60 * 60 * 24 * 30 # One month
|
ANONYMOUS_COOKIE_MAX_AGE = 60 * 60 * 24 * 30 # One month
|
||||||
|
|
||||||
|
|
||||||
class PaginatorMixin(object):
|
class PaginatorMixin:
|
||||||
per_page = 5
|
per_page = 5
|
||||||
|
|
||||||
def paginate(self, qs, per_page=None):
|
def paginate(self, qs, per_page=None):
|
||||||
|
@ -94,9 +94,20 @@ class PaginatorMixin(object):
|
||||||
qs = paginator.page(paginator.num_pages)
|
qs = paginator.page(paginator.num_pages)
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
kwargs.update({"is_ajax": is_ajax(self.request)})
|
||||||
|
return super().get_context_data(**kwargs)
|
||||||
|
|
||||||
|
def get_template_names(self):
|
||||||
|
"""
|
||||||
|
Dispatch template according to the kind of request: ajax or normal.
|
||||||
|
"""
|
||||||
|
if is_ajax(self.request):
|
||||||
|
return [self.list_template_name]
|
||||||
|
return super().get_template_names()
|
||||||
|
|
||||||
|
|
||||||
class PublicMapsMixin(object):
|
class PublicMapsMixin(object):
|
||||||
|
|
||||||
def get_public_maps(self):
|
def get_public_maps(self):
|
||||||
qs = Map.public
|
qs = Map.public
|
||||||
if (
|
if (
|
||||||
|
@ -109,7 +120,7 @@ class PublicMapsMixin(object):
|
||||||
return maps
|
return maps
|
||||||
|
|
||||||
|
|
||||||
class Home(TemplateView, PublicMapsMixin, PaginatorMixin):
|
class Home(PaginatorMixin, TemplateView, PublicMapsMixin):
|
||||||
template_name = "umap/home.html"
|
template_name = "umap/home.html"
|
||||||
list_template_name = "umap/map_list.html"
|
list_template_name = "umap/map_list.html"
|
||||||
|
|
||||||
|
@ -142,15 +153,6 @@ class Home(TemplateView, PublicMapsMixin, PaginatorMixin):
|
||||||
"showcase_map": showcase_map,
|
"showcase_map": showcase_map,
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_template_names(self):
|
|
||||||
"""
|
|
||||||
Dispatch template according to the kind of request: ajax or normal.
|
|
||||||
"""
|
|
||||||
if is_ajax(self.request):
|
|
||||||
return [self.list_template_name]
|
|
||||||
else:
|
|
||||||
return [self.template_name]
|
|
||||||
|
|
||||||
|
|
||||||
home = Home.as_view()
|
home = Home.as_view()
|
||||||
|
|
||||||
|
@ -162,7 +164,7 @@ class About(Home):
|
||||||
about = About.as_view()
|
about = About.as_view()
|
||||||
|
|
||||||
|
|
||||||
class UserMaps(DetailView, PaginatorMixin):
|
class UserMaps(PaginatorMixin, DetailView):
|
||||||
model = User
|
model = User
|
||||||
slug_url_kwarg = "identifier"
|
slug_url_kwarg = "identifier"
|
||||||
slug_field = settings.USER_URL_FIELD
|
slug_field = settings.USER_URL_FIELD
|
||||||
|
@ -190,15 +192,6 @@ class UserMaps(DetailView, PaginatorMixin):
|
||||||
kwargs.update({"maps": self.paginate(self.get_maps(), self.per_page)})
|
kwargs.update({"maps": self.paginate(self.get_maps(), self.per_page)})
|
||||||
return super().get_context_data(**kwargs)
|
return super().get_context_data(**kwargs)
|
||||||
|
|
||||||
def get_template_names(self):
|
|
||||||
"""
|
|
||||||
Dispatch template according to the kind of request: ajax or normal.
|
|
||||||
"""
|
|
||||||
if is_ajax(self.request):
|
|
||||||
return [self.list_template_name]
|
|
||||||
else:
|
|
||||||
return super(UserMaps, self).get_template_names()
|
|
||||||
|
|
||||||
|
|
||||||
user_maps = UserMaps.as_view()
|
user_maps = UserMaps.as_view()
|
||||||
|
|
||||||
|
@ -216,37 +209,34 @@ class UserStars(UserMaps):
|
||||||
user_stars = UserStars.as_view()
|
user_stars = UserStars.as_view()
|
||||||
|
|
||||||
|
|
||||||
class Search(TemplateView, PublicMapsMixin, PaginatorMixin):
|
class SearchMixin:
|
||||||
template_name = "umap/search.html"
|
def get_search_queryset(self, **kwargs):
|
||||||
list_template_name = "umap/map_list.html"
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
q = self.request.GET.get("q")
|
q = self.request.GET.get("q")
|
||||||
qs_count = 0
|
|
||||||
results = []
|
|
||||||
if q:
|
if q:
|
||||||
vector = SearchVector("name", config=settings.UMAP_SEARCH_CONFIGURATION)
|
vector = SearchVector("name", config=settings.UMAP_SEARCH_CONFIGURATION)
|
||||||
query = SearchQuery(
|
query = SearchQuery(
|
||||||
q, config=settings.UMAP_SEARCH_CONFIGURATION, search_type="websearch"
|
q, config=settings.UMAP_SEARCH_CONFIGURATION, search_type="websearch"
|
||||||
)
|
)
|
||||||
qs = Map.objects.annotate(search=vector).filter(search=query)
|
return Map.objects.annotate(search=vector).filter(search=query)
|
||||||
|
|
||||||
|
|
||||||
|
class Search(PaginatorMixin, TemplateView, PublicMapsMixin, SearchMixin):
|
||||||
|
template_name = "umap/search.html"
|
||||||
|
list_template_name = "umap/map_list.html"
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
qs = self.get_search_queryset()
|
||||||
|
qs_count = 0
|
||||||
|
results = []
|
||||||
|
if qs is not None:
|
||||||
qs = qs.filter(share_status=Map.PUBLIC).order_by("-modified_at")
|
qs = qs.filter(share_status=Map.PUBLIC).order_by("-modified_at")
|
||||||
qs_count = qs.count()
|
qs_count = qs.count()
|
||||||
results = self.paginate(qs)
|
results = self.paginate(qs)
|
||||||
else:
|
else:
|
||||||
results = self.get_public_maps()[:settings.UMAP_MAPS_PER_SEARCH]
|
results = self.get_public_maps()[: settings.UMAP_MAPS_PER_SEARCH]
|
||||||
kwargs.update({"maps": results, "count": qs_count, "q": q})
|
kwargs.update({"maps": results, "count": qs_count})
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
def get_template_names(self):
|
|
||||||
"""
|
|
||||||
Dispatch template according to the kind of request: ajax or normal.
|
|
||||||
"""
|
|
||||||
if is_ajax(self.request):
|
|
||||||
return [self.list_template_name]
|
|
||||||
else:
|
|
||||||
return super(Search, self).get_template_names()
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def per_page(self):
|
def per_page(self):
|
||||||
return settings.UMAP_MAPS_PER_SEARCH
|
return settings.UMAP_MAPS_PER_SEARCH
|
||||||
|
@ -255,6 +245,29 @@ class Search(TemplateView, PublicMapsMixin, PaginatorMixin):
|
||||||
search = Search.as_view()
|
search = Search.as_view()
|
||||||
|
|
||||||
|
|
||||||
|
class UserDashboard(PaginatorMixin, DetailView, SearchMixin):
|
||||||
|
model = User
|
||||||
|
template_name = "umap/user_dashboard.html"
|
||||||
|
list_template_name = "umap/map_table.html"
|
||||||
|
|
||||||
|
def get_object(self):
|
||||||
|
return self.get_queryset().get(pk=self.request.user.pk)
|
||||||
|
|
||||||
|
def get_maps(self):
|
||||||
|
qs = self.get_search_queryset() or Map.objects.all()
|
||||||
|
qs = qs.filter(Q(owner=self.object) | Q(editors=self.object))
|
||||||
|
return qs.order_by("-modified_at")
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
kwargs.update(
|
||||||
|
{"maps": self.paginate(self.get_maps(), settings.UMAP_MAPS_PER_PAGE_OWNER)}
|
||||||
|
)
|
||||||
|
return super().get_context_data(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
user_dashboard = UserDashboard.as_view()
|
||||||
|
|
||||||
|
|
||||||
class MapsShowCase(View):
|
class MapsShowCase(View):
|
||||||
def get(self, *args, **kwargs):
|
def get(self, *args, **kwargs):
|
||||||
maps = Map.public.filter(center__distance_gt=(DEFAULT_CENTER, D(km=1)))
|
maps = Map.public.filter(center__distance_gt=(DEFAULT_CENTER, D(km=1)))
|
||||||
|
@ -436,7 +449,7 @@ class MapDetailMixin:
|
||||||
properties["user"] = {
|
properties["user"] = {
|
||||||
"id": user.pk,
|
"id": user.pk,
|
||||||
"name": str(user),
|
"name": str(user),
|
||||||
"url": user.get_url(),
|
"url": reverse("user_dashboard"),
|
||||||
}
|
}
|
||||||
map_settings = self.get_geojson()
|
map_settings = self.get_geojson()
|
||||||
if "properties" not in map_settings:
|
if "properties" not in map_settings:
|
||||||
|
|
Loading…
Reference in a new issue