mirror of
https://github.com/pretix/pretix.git
synced 2026-09-14 16:24:43 +00:00
Widget: remove limit of 50 events in list-view by adding a load-more-button (#2144)
This commit is contained in:
@@ -1004,6 +1004,11 @@ class Event(EventMixin, LoggedModel):
|
|||||||
| Q(date_to__gte=now() - timedelta(hours=24))
|
| Q(date_to__gte=now() - timedelta(hours=24))
|
||||||
)
|
)
|
||||||
) # order_by doesn't make sense with I18nField
|
) # order_by doesn't make sense with I18nField
|
||||||
|
if ordering in ("date_ascending", "date_descending"):
|
||||||
|
# if primary order is by date, then order in database
|
||||||
|
# this allows to limit/slice results
|
||||||
|
return subevs.order_by(*orderfields)
|
||||||
|
|
||||||
for f in reversed(orderfields):
|
for f in reversed(orderfields):
|
||||||
if f.startswith('-'):
|
if f.startswith('-'):
|
||||||
subevs = sorted(subevs, key=attrgetter(f[1:]), reverse=True)
|
subevs = sorted(subevs, key=attrgetter(f[1:]), reverse=True)
|
||||||
|
|||||||
@@ -422,7 +422,10 @@ class WidgetAPIProductList(EventListMixin, View):
|
|||||||
data['list_type'] = list_type
|
data['list_type'] = list_type
|
||||||
|
|
||||||
if hasattr(self.request, 'event') and data['list_type'] not in ("calendar", "week"):
|
if hasattr(self.request, 'event') and data['list_type'] not in ("calendar", "week"):
|
||||||
if self.request.event.subevents.filter(date_from__gt=now()).count() > 50:
|
# only allow list-view of more than 50 subevents if ordering is by data as this can be done in the database
|
||||||
|
# ordering by name is currently not supported in database due to I18NField-JSON
|
||||||
|
ordering = self.request.event.settings.get('frontpage_subevent_ordering', default='date_ascending', as_type=str)
|
||||||
|
if ordering not in ("date_ascending", "date_descending") and self.request.event.subevents.filter(date_from__gt=now()).count() > 50:
|
||||||
if self.request.event.settings.event_list_type not in ("calendar", "week"):
|
if self.request.event.settings.event_list_type not in ("calendar", "week"):
|
||||||
self.request.event.settings.event_list_type = "calendar"
|
self.request.event.settings.event_list_type = "calendar"
|
||||||
data['list_type'] = list_type = 'calendar'
|
data['list_type'] = list_type = 'calendar'
|
||||||
@@ -537,10 +540,21 @@ class WidgetAPIProductList(EventListMixin, View):
|
|||||||
for d in data['days']:
|
for d in data['days']:
|
||||||
d['events'] = self._serialize_events(d['events'] or [])
|
d['events'] = self._serialize_events(d['events'] or [])
|
||||||
else:
|
else:
|
||||||
|
offset = int(self.request.GET.get("offset", 0))
|
||||||
|
limit = 50
|
||||||
if hasattr(self.request, 'event'):
|
if hasattr(self.request, 'event'):
|
||||||
evs = self.request.event.subevents_sorted(
|
evs = self.request.event.subevents_sorted(
|
||||||
filter_qs_by_attr(self.request.event.subevents_annotated(self.request.sales_channel.identifier), self.request)
|
filter_qs_by_attr(self.request.event.subevents_annotated(self.request.sales_channel.identifier), self.request)
|
||||||
)
|
)
|
||||||
|
ordering = self.request.event.settings.get('frontpage_subevent_ordering', default='date_ascending', as_type=str)
|
||||||
|
data['has_more_events'] = False
|
||||||
|
if ordering in ("date_ascending", "date_descending"):
|
||||||
|
# fetch one more result than needed to check if more events exist
|
||||||
|
evs = list(evs[offset:offset + limit + 1])
|
||||||
|
if len(evs) > limit:
|
||||||
|
data['has_more_events'] = True
|
||||||
|
evs = evs[:limit]
|
||||||
|
|
||||||
tz = pytz.timezone(request.event.settings.timezone)
|
tz = pytz.timezone(request.event.settings.timezone)
|
||||||
if self.request.event.settings.event_list_available_only:
|
if self.request.event.settings.event_list_available_only:
|
||||||
evs = [
|
evs = [
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ var strings = {
|
|||||||
'next_week': django.pgettext('widget', 'Next week'),
|
'next_week': django.pgettext('widget', 'Next week'),
|
||||||
'previous_week': django.pgettext('widget', 'Previous week'),
|
'previous_week': django.pgettext('widget', 'Previous week'),
|
||||||
'show_seating': django.pgettext('widget', 'Open seat selection'),
|
'show_seating': django.pgettext('widget', 'Open seat selection'),
|
||||||
|
'load_more': django.pgettext('widget', 'Load more'),
|
||||||
'days': {
|
'days': {
|
||||||
'MO': django.gettext('Mo'),
|
'MO': django.gettext('Mo'),
|
||||||
'TU': django.gettext('Tu'),
|
'TU': django.gettext('Tu'),
|
||||||
@@ -854,6 +855,8 @@ Vue.component('pretix-widget-event-form', {
|
|||||||
this.$root.target_url = this.$root.parent_stack.pop();
|
this.$root.target_url = this.$root.parent_stack.pop();
|
||||||
this.$root.error = null;
|
this.$root.error = null;
|
||||||
this.$root.subevent = null;
|
this.$root.subevent = null;
|
||||||
|
this.$root.offset = 0;
|
||||||
|
this.$root.append_events = false;
|
||||||
this.$root.trigger_load_callback();
|
this.$root.trigger_load_callback();
|
||||||
if (this.$root.events !== undefined && this.$root.events !== null) {
|
if (this.$root.events !== undefined && this.$root.events !== null) {
|
||||||
this.$root.view = "events";
|
this.$root.view = "events";
|
||||||
@@ -938,9 +941,12 @@ Vue.component('pretix-widget-event-list', {
|
|||||||
+ '</div>'
|
+ '</div>'
|
||||||
+ '<div class="pretix-widget-event-description" v-if="$root.parent_stack.length > 0 && $root.frontpage_text" v-html="$root.frontpage_text"></div>'
|
+ '<div class="pretix-widget-event-description" v-if="$root.parent_stack.length > 0 && $root.frontpage_text" v-html="$root.frontpage_text"></div>'
|
||||||
+ '<pretix-widget-event-list-entry v-for="event in $root.events" :event="event" :key="event.url"></pretix-widget-event-list-entry>'
|
+ '<pretix-widget-event-list-entry v-for="event in $root.events" :event="event" :key="event.url"></pretix-widget-event-list-entry>'
|
||||||
|
+ '<p class="pretix-widget-event-list-load-more" v-if="$root.has_more_events"><button @click.prevent="load_more">'+strings.load_more+'</button></p>'
|
||||||
+ '</div>'),
|
+ '</div>'),
|
||||||
methods: {
|
methods: {
|
||||||
back_to_calendar: function () {
|
back_to_calendar: function () {
|
||||||
|
this.$root.offset = 0;
|
||||||
|
this.$root.append_events = false;
|
||||||
if (this.$root.weeks) {
|
if (this.$root.weeks) {
|
||||||
this.$root.events = undefined;
|
this.$root.events = undefined;
|
||||||
this.$root.view = "weeks";
|
this.$root.view = "weeks";
|
||||||
@@ -953,6 +959,12 @@ Vue.component('pretix-widget-event-list', {
|
|||||||
this.$root.reload();
|
this.$root.reload();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
load_more: function () {
|
||||||
|
this.$root.append_events = true;
|
||||||
|
this.$root.offset += 50;
|
||||||
|
this.$root.loading++;
|
||||||
|
this.$root.reload();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1353,6 +1365,9 @@ var shared_root_methods = {
|
|||||||
} else {
|
} else {
|
||||||
url = this.$root.target_url + 'widget/product_list?lang=' + lang;
|
url = this.$root.target_url + 'widget/product_list?lang=' + lang;
|
||||||
}
|
}
|
||||||
|
if (this.$root.offset) {
|
||||||
|
url += '&offset=' + this.$root.offset;
|
||||||
|
}
|
||||||
if (this.$root.filter) {
|
if (this.$root.filter) {
|
||||||
url += '&' + this.$root.filter;
|
url += '&' + this.$root.filter;
|
||||||
}
|
}
|
||||||
@@ -1408,11 +1423,13 @@ var shared_root_methods = {
|
|||||||
root.name = data.name;
|
root.name = data.name;
|
||||||
root.frontpage_text = data.frontpage_text;
|
root.frontpage_text = data.frontpage_text;
|
||||||
} else if (data.events !== undefined) {
|
} else if (data.events !== undefined) {
|
||||||
root.events = data.events;
|
root.events = root.append_events && root.events ? root.events.concat(data.events) : data.events;
|
||||||
|
root.append_events = false;
|
||||||
root.weeks = undefined;
|
root.weeks = undefined;
|
||||||
root.view = "events";
|
root.view = "events";
|
||||||
root.name = data.name;
|
root.name = data.name;
|
||||||
root.frontpage_text = data.frontpage_text;
|
root.frontpage_text = data.frontpage_text;
|
||||||
|
root.has_more_events = data.has_more_events;
|
||||||
} else {
|
} else {
|
||||||
root.view = "event";
|
root.view = "event";
|
||||||
root.name = data.name;
|
root.name = data.name;
|
||||||
@@ -1647,6 +1664,9 @@ var create_widget = function (element) {
|
|||||||
currency: null,
|
currency: null,
|
||||||
name: null,
|
name: null,
|
||||||
date_range: null,
|
date_range: null,
|
||||||
|
offset: 0,
|
||||||
|
has_more_events: false,
|
||||||
|
append_events: false,
|
||||||
frontpage_text: null,
|
frontpage_text: null,
|
||||||
filter: filter,
|
filter: filter,
|
||||||
item_filter: items,
|
item_filter: items,
|
||||||
|
|||||||
@@ -172,6 +172,15 @@
|
|||||||
|
|
||||||
.pretix-widget-loading svg {
|
.pretix-widget-loading svg {
|
||||||
margin: 40px;
|
margin: 40px;
|
||||||
|
/*Fallback*/
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
margin-top: -64px;
|
||||||
|
/*Sticky*/
|
||||||
|
position: -webkit-sticky;
|
||||||
|
position: sticky;
|
||||||
|
top: Min(50vh, 50%);/* use uppercase M to use CSS-min and not SASS-min*/
|
||||||
|
|
||||||
-webkit-animation: pretix-widget-spin 6s linear infinite;
|
-webkit-animation: pretix-widget-spin 6s linear infinite;
|
||||||
-moz-animation: pretix-widget-spin 6s linear infinite;
|
-moz-animation: pretix-widget-spin 6s linear infinite;
|
||||||
animation: pretix-widget-spin 6s linear infinite;
|
animation: pretix-widget-spin 6s linear infinite;
|
||||||
@@ -699,6 +708,10 @@
|
|||||||
fill: $brand-primary;
|
fill: $brand-primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pretix-widget-event-list-load-more {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
.pretix-widget.pretix-widget-mobile {
|
.pretix-widget.pretix-widget-mobile {
|
||||||
.pretix-widget-event-week-table {
|
.pretix-widget-event-week-table {
|
||||||
display: block;
|
display: block;
|
||||||
|
|||||||
@@ -520,6 +520,7 @@ class WidgetCartTest(CartTestMixin, TestCase):
|
|||||||
'name': '30C3',
|
'name': '30C3',
|
||||||
'frontpage_text': '',
|
'frontpage_text': '',
|
||||||
'poweredby': '<a href="https://pretix.eu" target="_blank" rel="noopener">ticketing powered by pretix</a>',
|
'poweredby': '<a href="https://pretix.eu" target="_blank" rel="noopener">ticketing powered by pretix</a>',
|
||||||
|
'has_more_events': False,
|
||||||
'events': [
|
'events': [
|
||||||
{'name': 'Present', 'date_range': 'Jan. 1, 2019 11:00', 'availability': {'color': 'none', 'text': '', 'reason': 'unknown'},
|
{'name': 'Present', 'date_range': 'Jan. 1, 2019 11:00', 'availability': {'color': 'none', 'text': '', 'reason': 'unknown'},
|
||||||
'event_url': 'http://example.com/ccc/30c3/', 'subevent': se1.pk, 'location': ''},
|
'event_url': 'http://example.com/ccc/30c3/', 'subevent': se1.pk, 'location': ''},
|
||||||
|
|||||||
Reference in New Issue
Block a user