mirror of
https://github.com/pretix/pretix.git
synced 2026-05-05 15:14:04 +00:00
Add public filters based on meta data (#3673)
* Add public filters based on meta data * Fix licenseheaders * ignore empty values * Fix tests * Full non-widget implementation * Widget support * Add a few tests * Allow to reorder properties * Fix isort * Allow to opt-out for specific events * Fix name clash between new and old field to make migration feasible
This commit is contained in:
@@ -1093,6 +1093,46 @@ Vue.component('pretix-widget-event-form', {
|
||||
}
|
||||
});
|
||||
|
||||
Vue.component('pretix-widget-event-list-filter-field', {
|
||||
template: ('<div class="pretix-widget-event-list-filter-field">'
|
||||
+ '<label :for="id">{{ field.label }}</label>'
|
||||
+ '<select :id="id" :name="field.key" @change="onChange($event)" :value="currentValue">'
|
||||
+ '<option v-for="choice in field.choices" :value="choice[0]">{{ choice[1] }}</option>'
|
||||
+ '</select>'
|
||||
+ '</div>'),
|
||||
props: {
|
||||
field: Object
|
||||
},
|
||||
methods: {
|
||||
onChange: function(event) {
|
||||
var filterParams = new URLSearchParams(this.$root.filter);
|
||||
if (event.target.value) {
|
||||
filterParams.set(this.field.key, event.target.value);
|
||||
} else {
|
||||
filterParams.delete(this.field.key);
|
||||
}
|
||||
this.$root.filter = filterParams.toString();
|
||||
this.$root.loading++;
|
||||
this.$root.reload();
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
id: function () {
|
||||
return widget_id + "_" + this.field.key;
|
||||
},
|
||||
currentValue: function () {
|
||||
var filterParams = new URLSearchParams(this.$root.filter);
|
||||
return filterParams.get(this.field.key) || "";
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Vue.component('pretix-widget-event-list-filter-form', {
|
||||
template: ('<div class="pretix-widget-event-list-filter-form">'
|
||||
+ '<pretix-widget-event-list-filter-field v-for="field in $root.meta_filter_fields" :field="field" :key="field.key"></pretix-widget-event-list-filter-field>'
|
||||
+ '</div>'),
|
||||
});
|
||||
|
||||
Vue.component('pretix-widget-event-list-entry', {
|
||||
template: ('<a :class="classObject" @click.prevent.stop="select">'
|
||||
+ '<div class="pretix-widget-event-list-entry-name">{{ event.name }}</div>'
|
||||
@@ -1142,6 +1182,7 @@ Vue.component('pretix-widget-event-list', {
|
||||
+ '<strong>{{ $root.name }}</strong>'
|
||||
+ '</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-filter-form v-if="!$root.disable_filters && $root.meta_filter_fields.length > 0"></pretix-widget-event-list-filter-form>'
|
||||
+ '<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.stop="load_more">'+strings.load_more+'</button></p>'
|
||||
+ '</div>'),
|
||||
@@ -1360,6 +1401,9 @@ Vue.component('pretix-widget-event-calendar', {
|
||||
+ '</div>'
|
||||
+ '<div class="pretix-widget-event-description" v-if="$root.parent_stack.length > 0 && $root.frontpage_text" v-html="$root.frontpage_text"></div>'
|
||||
|
||||
// Filter
|
||||
+ '<pretix-widget-event-list-filter-form v-if="!$root.disable_filters && $root.meta_filter_fields.length > 0"></pretix-widget-event-list-filter-form>'
|
||||
|
||||
// Calendar navigation
|
||||
+ '<div class="pretix-widget-event-calendar-head">'
|
||||
+ '<a class="pretix-widget-event-calendar-previous-month" href="#" @click.prevent.stop="prevmonth" role="button">« '
|
||||
@@ -1442,6 +1486,9 @@ Vue.component('pretix-widget-event-week-calendar', {
|
||||
+ '<strong>{{ $root.name }}</strong>'
|
||||
+ '</div>'
|
||||
|
||||
// Filter
|
||||
+ '<pretix-widget-event-list-filter-form v-if="!$root.disable_filters && $root.meta_filter_fields.length > 0"></pretix-widget-event-list-filter-form>'
|
||||
|
||||
// Calendar navigation
|
||||
+ '<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-calendar-head">'
|
||||
@@ -1671,6 +1718,7 @@ var shared_root_methods = {
|
||||
root.view = "weeks";
|
||||
root.name = data.name;
|
||||
root.frontpage_text = data.frontpage_text;
|
||||
root.meta_filter_fields = data.meta_filter_fields;
|
||||
} else if (data.days !== undefined) {
|
||||
root.days = data.days;
|
||||
root.date = null;
|
||||
@@ -1679,6 +1727,7 @@ var shared_root_methods = {
|
||||
root.view = "days";
|
||||
root.name = data.name;
|
||||
root.frontpage_text = data.frontpage_text;
|
||||
root.meta_filter_fields = data.meta_filter_fields;
|
||||
} else if (data.events !== undefined) {
|
||||
root.events = root.append_events && root.events ? root.events.concat(data.events) : data.events;
|
||||
root.append_events = false;
|
||||
@@ -1687,6 +1736,7 @@ var shared_root_methods = {
|
||||
root.name = data.name;
|
||||
root.frontpage_text = data.frontpage_text;
|
||||
root.has_more_events = data.has_more_events;
|
||||
root.meta_filter_fields = data.meta_filter_fields;
|
||||
} else {
|
||||
root.view = "event";
|
||||
root.name = data.name;
|
||||
@@ -1917,6 +1967,7 @@ var create_widget = function (element) {
|
||||
var skip_ssl = element.attributes["skip-ssl-check"] ? true : false;
|
||||
var disable_iframe = element.attributes["disable-iframe"] ? true : false;
|
||||
var disable_vouchers = element.attributes["disable-vouchers"] ? true : false;
|
||||
var disable_filters = element.attributes["disable-filters"] ? true : false;
|
||||
var widget_data = JSON.parse(JSON.stringify(window.PretixWidget.widget_data));
|
||||
var filter = element.attributes.filter ? element.attributes.filter.value : null;
|
||||
var items = element.attributes.items ? element.attributes.items.value : null;
|
||||
@@ -1990,12 +2041,14 @@ var create_widget = function (element) {
|
||||
widget_id: 'pretix-widget-' + widget_id,
|
||||
vouchers_exist: false,
|
||||
disable_vouchers: disable_vouchers,
|
||||
disable_filters: disable_filters,
|
||||
cart_exists: false,
|
||||
itemcount: 0,
|
||||
overlay: null,
|
||||
poweredby: "",
|
||||
has_seating_plan: false,
|
||||
has_seating_plan_waitinglist: false,
|
||||
meta_filter_fields: [],
|
||||
}
|
||||
},
|
||||
created: function () {
|
||||
|
||||
@@ -139,6 +139,41 @@
|
||||
}
|
||||
}
|
||||
|
||||
.event-list-filter-form {
|
||||
.event-list-filter-form-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: end;
|
||||
.form-group {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin: 0 15px 0 0;
|
||||
}
|
||||
|
||||
button {
|
||||
flex: 0;
|
||||
white-space: nowrap;
|
||||
/* Visual alignment with the selects */
|
||||
padding-top: 7px;
|
||||
padding-bottom: 7px;
|
||||
}
|
||||
}
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
@media (max-width: $screen-xs-max) {
|
||||
.event-list-filter-form {
|
||||
.event-list-filter-form-row {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
.form-group {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin: 0 0 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
input:checked + .pretix-widget-icon-cart {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4.534 3.097a.317.317 0 0 1-.067.197L3.56 4.42a.207.207 0 0 1-.16.084.207.207 0 0 1-.159-.084l-.907-1.126a.317.317 0 0 1-.067-.197c0-.154.103-.282.227-.282.06 0 .117.031.159.084l.521.642V2.252c0-.154.102-.281.226-.281.124 0 .227.127.227.281v1.289l.521-.642a.205.205 0 0 1 .159-.084c.124 0 .227.128.227.282ZM2.267 6.756c0-.312-.202-.563-.453-.563-.252 0-.454.251-.454.563 0 .312.202.563.454.563.251 0 .453-.251.453-.563Zm3.174 0c0-.312-.202-.563-.454-.563-.251 0-.453.251-.453.563 0 .312.202.563.453.563.252 0 .454-.251.454-.563Zm.453-4.785c0-.154-.103-.282-.227-.282H1.413c-.035-.211-.039-.563-.28-.563H.227c-.124 0-.227.128-.227.282 0 .153.103.281.227.281h.722l.627 3.62c-.049.127-.216.466-.216.603 0 .153.103.281.227.281h3.627c.124 0 .227-.128.227-.281 0-.154-.103-.282-.227-.282H1.955c.036-.088.085-.18.085-.281 0-.102-.032-.212-.046-.308l3.698-.537c.117-.018.202-.141.202-.281V1.971Z' transform='matrix(2.52069 0 0 2.02994 -.035 -.523)'/%3E%3C/svg%3E%0A");
|
||||
}
|
||||
input[type="text"], input[type="number"] {
|
||||
input[type="text"], input[type="number"], select {
|
||||
line-height: normal;
|
||||
border: 1px solid $input-border;
|
||||
border-radius: $input-border-radius;
|
||||
@@ -640,6 +640,42 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.pretix-widget-event-list-filter-form {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: end;
|
||||
margin-bottom: 15px;
|
||||
|
||||
.pretix-widget-event-list-filter-field {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin: 0 15px 0 0;
|
||||
|
||||
label {
|
||||
display: inline-block;
|
||||
font-weight: bold;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
select {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.pretix-widget-event-list-filter-field:last-child {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
.pretix-widget.pretix-widget-mobile .pretix-widget-event-list-filter-form {
|
||||
display: block;
|
||||
|
||||
.pretix-widget-event-list-filter-field {
|
||||
display: block;
|
||||
margin: 0 0 5px;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes pretix-widget-bounce-in {
|
||||
0% {
|
||||
transform: scale(0);
|
||||
|
||||
Reference in New Issue
Block a user