Event list: Autocomplete meta values

This commit is contained in:
Raphael Michel
2019-10-28 22:35:16 +01:00
parent cc970caad8
commit 3d31b95201
4 changed files with 98 additions and 2 deletions

View File

@@ -1,4 +1,5 @@
from datetime import datetime, time
from urllib.parse import urlencode
from django import forms
from django.apps import apps
@@ -583,7 +584,16 @@ class EventFilterForm(FilterForm):
continue
seen.add(p.name)
self.fields['meta_{}'.format(p.name)] = forms.CharField(
label=p.name, required=False
label=p.name,
required=False,
widget=forms.TextInput(
attrs={
'data-typeahead-url': reverse('control:events.meta.typeahead') + '?' + urlencode({
'property': p.name,
'organizer': self.organizer.slug if self.organizer else ''
})
}
)
)
if self.organizer:
del self.fields['organizer']

View File

@@ -108,6 +108,7 @@ urlpatterns = [
url(r'^events/$', main.EventList.as_view(), name='events'),
url(r'^events/add$', main.EventWizard.as_view(), name='events.add'),
url(r'^events/typeahead/$', typeahead.event_list, name='events.typeahead'),
url(r'^events/typeahead/meta/$', typeahead.meta_values, name='events.meta.typeahead'),
url(r'^search/orders/$', search.OrderSearch.as_view(), name='search.orders'),
url(r'^event/(?P<organizer>[^/]+)/(?P<event>[^/]+)/', include([
url(r'^$', dashboards.event_index, name='event.index'),

View File

@@ -6,12 +6,16 @@ from django.core.exceptions import PermissionDenied
from django.db.models import Max, Min, Q
from django.db.models.functions import Coalesce, Greatest
from django.http import JsonResponse
from django.shortcuts import get_object_or_404
from django.urls import reverse
from django.utils.formats import get_format
from django.utils.timezone import make_aware
from django.utils.translation import pgettext, ugettext as _
from pretix.base.models import Order, Organizer, SubEvent, User, Voucher
from pretix.base.models import (
EventMetaProperty, EventMetaValue, Order, Organizer, SubEvent, User,
Voucher,
)
from pretix.control.forms.event import EventWizardCopyForm
from pretix.control.permissions import event_permission_required
from pretix.helpers.daterange import daterange
@@ -547,3 +551,52 @@ def users_select2(request):
}
return JsonResponse(doc)
def meta_values(request):
q = request.GET.get('q')
propname = request.GET.get('property')
organizer = request.GET.get('organizer')
matches = EventMetaValue.objects.filter(
value__icontains=q,
property__name=propname
)
defaults = EventMetaProperty.objects.filter(
name=propname,
default__icontains=q
)
if organizer:
organizer = get_object_or_404(Organizer, slug=organizer)
if not request.user.has_organizer_permission(organizer, request=request):
raise PermissionDenied()
defaults = defaults.filter(organizer_id=organizer.pk)
matches = matches.filter(event__organizer_id=organizer.pk)
all_access = (
(request and request.user.has_active_staff_session(request.session.session_key))
or request.user.teams.filter(all_events=True, organizer=organizer).exists()
)
if not all_access:
matches = matches.filter(event__id__in=request.user.teams.values_list('limit_events__id', flat=True))
else:
# We ignore superuser permissions here. This is intentional we do not want to show super
# users a form with all meta properties ever assigned.
defaults = defaults.filter(
organizer_id__in=request.user.teams.values_list('organizer', flat=True),
)
if not (request and request.user.has_active_staff_session(request.session.session_key)):
matches = matches.filter(
Q(event__organizer_id__in=request.user.teams.filter(all_events=True).values_list('organizer', flat=True))
| Q(event__id__in=request.user.teams.values_list('limit_events__id', flat=True))
)
return JsonResponse({
'results': [
{'name': v, 'id': v}
for v in sorted(set(defaults.values_list('default', flat=True)[:10]) | set(matches.values_list('value', flat=True)[:10]))
]
})

View File

@@ -373,6 +373,38 @@ var form_handlers = function (el) {
language: $("body").attr("data-select2-locale"),
});
el.find('input[data-typeahead-url]').each(function () {
var $inp = $(this);
$inp.typeahead(null, {
minLength: 1,
highlight: true,
source: new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: $inp.attr("data-typeahead-url"),
prepare: function (query, settings) {
var sep = (settings.url.indexOf('?') > 0) ? '&' : '?';
settings.url = settings.url + sep + 'q=' + encodeURIComponent(query);
return settings;
},
transform: function (object) {
var results = object.results;
var suggs = [];
var reslen = results.length;
for (var i = 0; i < reslen; i++) {
suggs.push(results[i]);
}
return suggs;
}
}
}),
display: function (obj) {
return obj.name;
},
});
});
el.find('[data-model-select2=generic]').each(function () {
var $s = $(this);
$s.select2({