Compare commits

..

1 Commits

Author SHA1 Message Date
Richard Schreiber
f8a562ed7c [A11y] fix waitinglist-link not being recognizable as a link 2025-05-19 11:50:19 +02:00
30 changed files with 12412 additions and 10031 deletions

View File

@@ -101,7 +101,6 @@ ALL_LANGUAGES = [
('fi', _('Finnish')),
('gl', _('Galician')),
('el', _('Greek')),
('he', _('Hebrew')),
('id', _('Indonesian')),
('it', _('Italian')),
('ja', _('Japanese')),
@@ -123,7 +122,7 @@ LANGUAGES_OFFICIAL = {
}
LANGUAGES_RTL = {
# When adding more right-to-left languages, also update pretix/static/pretixbase/scss/_rtl.scss
'ar', 'he'
'ar', 'hw'
}
LANGUAGES_INCUBATING = {
'pt-br', 'gl',

View File

@@ -1,18 +0,0 @@
# Generated by Django 4.2.20 on 2025-05-14 14:58
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('pretixbase', '0279_discount_event_date_from_discount_event_date_until'),
]
operations = [
migrations.AddField(
model_name='cartposition',
name='max_extend',
field=models.DateTimeField(null=True),
),
]

View File

@@ -3098,10 +3098,7 @@ class CartPosition(AbstractPosition):
verbose_name=_("Expiration date"),
db_index=True
)
max_extend = models.DateTimeField(
verbose_name=_("Limit for extending expiration date"),
null=True
)
tax_rate = models.DecimalField(
max_digits=7, decimal_places=2, default=Decimal('0.00'),
verbose_name=_('Tax rate')

View File

@@ -45,7 +45,6 @@ from django.conf import settings
from django.core.exceptions import ValidationError
from django.db import DatabaseError, transaction
from django.db.models import Count, Exists, IntegerField, OuterRef, Q, Value
from django.db.models.aggregates import Min
from django.dispatch import receiver
from django.utils.timezone import make_aware, now
from django.utils.translation import (
@@ -276,10 +275,7 @@ class CartManager:
}
def __init__(self, event: Event, cart_id: str, sales_channel: SalesChannel,
invoice_address: InvoiceAddress=None, widget_data=None, reservation_time: timedelta=None):
"""
Creates a new CartManager for an event.
"""
invoice_address: InvoiceAddress=None, widget_data=None, expiry=None):
self.event = event
self.cart_id = cart_id
self.real_now_dt = now()
@@ -290,17 +286,11 @@ class CartManager:
self._subevents_cache = {}
self._variations_cache = {}
self._seated_cache = {}
self._expiry = None
self._explicit_expiry = expiry
self.invoice_address = invoice_address
self._widget_data = widget_data or {}
self._sales_channel = sales_channel
self.num_extended_positions = 0
if reservation_time:
self._reservation_time = reservation_time
else:
self._reservation_time = timedelta(minutes=self.event.settings.get('reservation_time', as_type=int))
self._expiry = self.real_now_dt + self._reservation_time
self._max_expiry_extend = self.real_now_dt + (self._reservation_time * 11)
@property
def positions(self):
@@ -315,6 +305,14 @@ class CartManager:
self._seated_cache[item, subevent] = item.seat_category_mappings.filter(subevent=subevent).exists()
return self._seated_cache[item, subevent]
def _calculate_expiry(self):
if self._explicit_expiry:
self._expiry = self._explicit_expiry
else:
self._expiry = self.real_now_dt + timedelta(
minutes=self.event.settings.get('reservation_time', as_type=int)
)
def _check_presale_dates(self):
if self.event.presale_start and time_machine_now(self.real_now_dt) < self.event.presale_start:
raise CartError(error_messages['not_started'])
@@ -331,27 +329,9 @@ class CartManager:
raise CartError(error_messages['payment_ended'])
def _extend_expiry_of_valid_existing_positions(self):
# real_now_dt is initialized at CartManager instantiation, so it's slightly in the past. Add a small
# delta to reduce risk of extending already expired CartPositions.
padded_now_dt = self.real_now_dt + timedelta(seconds=5)
# Make sure we do not extend past the max_extend timestamp, allowing users to extend their valid positions up
# to 11 times the reservation time. If we add new positions to the cart while valid positions exist, the new
# positions' reservation will also be limited to max_extend of the oldest position.
# Only after all positions expire, an ExtendOperation may reset max_extend to another 11x reservation_time.
max_extend_existing = self.positions.filter(expires__gt=padded_now_dt).aggregate(m=Min('max_extend'))['m']
if max_extend_existing:
self._expiry = min(self._expiry, max_extend_existing)
self._max_expiry_extend = max_extend_existing
# Extend this user's cart session to ensure all items in the cart expire at the same time
# We can extend the reservation of items which are not yet expired without risk
if self._expiry > padded_now_dt:
self.num_extended_positions += self.positions.filter(
expires__gt=padded_now_dt, expires__lt=self._expiry,
).update(
expires=self._expiry,
)
self.positions.filter(expires__gt=self.real_now_dt).update(expires=self._expiry)
def _delete_out_of_timeframe(self):
err = None
@@ -1266,7 +1246,6 @@ class CartManager:
item=op.item,
variation=op.variation,
expires=self._expiry,
max_extend=self._max_expiry_extend,
cart_id=self.cart_id,
voucher=op.voucher,
addon_to=op.addon_to if op.addon_to else None,
@@ -1315,9 +1294,7 @@ class CartManager:
event=self.event,
item=b.item,
variation=b.variation,
expires=self._expiry,
max_extend=self._max_expiry_extend,
cart_id=self.cart_id,
expires=self._expiry, cart_id=self.cart_id,
voucher=None,
addon_to=cp,
subevent=b.subevent,
@@ -1344,14 +1321,12 @@ class CartManager:
op.position.delete()
elif available_count == 1:
op.position.expires = self._expiry
op.position.max_extend = self._max_expiry_extend
op.position.listed_price = op.listed_price
op.position.price_after_voucher = op.price_after_voucher
# op.position.price will be updated by recompute_final_prices_and_taxes()
if op.position.pk not in deleted_positions:
try:
op.position.save(force_update=True, update_fields=['expires', 'max_extend', 'listed_price', 'price_after_voucher'])
self.num_extended_positions += 1
op.position.save(force_update=True, update_fields=['expires', 'listed_price', 'price_after_voucher'])
except DatabaseError:
# Best effort... The position might have been deleted in the meantime!
pass
@@ -1441,11 +1416,14 @@ class CartManager:
def commit(self):
self._check_presale_dates()
self._check_max_cart_size()
self._calculate_expiry()
err = self._delete_out_of_timeframe()
err = self.extend_expired_positions() or err
err = err or self._check_min_per_voucher()
self.real_now_dt = now()
self._extend_expiry_of_valid_existing_positions()
err = self._perform_operations() or err
self.recompute_final_prices_and_taxes()
@@ -1654,31 +1632,6 @@ def clear_cart(self, event: Event, cart_id: str=None, locale='en', sales_channel
raise CartError(error_messages['busy'])
@app.task(base=ProfiledEventTask, bind=True, max_retries=5, default_retry_delay=1, throws=(CartError,))
def extend_cart_reservation(self, event: Event, cart_id: str=None, locale='en', sales_channel='web', override_now_dt: datetime=None) -> None:
"""
Resets the expiry time of a cart to the configured reservation time of this event.
Limited to 11x the reservation time.
:param event: The event ID in question
:param cart_id: The cart ID of the cart to modify
"""
with language(locale), time_machine_now_assigned(override_now_dt):
try:
sales_channel = event.organizer.sales_channels.get(identifier=sales_channel)
except SalesChannel.DoesNotExist:
raise CartError("Invalid sales channel.")
try:
try:
cm = CartManager(event=event, cart_id=cart_id, sales_channel=sales_channel)
cm.commit()
return cm.num_extended_positions
except LockTimeoutException:
self.retry()
except (MaxRetriesExceededError, LockTimeoutException):
raise CartError(error_messages['busy'])
@app.task(base=ProfiledEventTask, bind=True, max_retries=5, default_retry_delay=1, throws=(CartError,))
def set_cart_addons(self, event: Event, addons: List[dict], add_to_cart_items: List[dict], cart_id: str=None, locale='en',
invoice_address: int=None, sales_channel='web', override_now_dt: datetime=None) -> None:

View File

@@ -1,60 +0,0 @@
#
# This file is part of pretix (Community Edition).
#
# Copyright (C) 2014-2020 Raphael Michel and contributors
# Copyright (C) 2020-2021 rami.io GmbH and contributors
#
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
# Public License as published by the Free Software Foundation in version 3 of the License.
#
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
# this file, see <https://pretix.eu/about/en/license>.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
from django import template
from django.utils.html import format_html
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _ # NOQA
register = template.Library()
@register.simple_tag
def dialog(html_id, label, description, *args, **kwargs):
format_kwargs = {
"id": html_id,
"label": label,
"description": description,
"icon": format_html('<div class="modal-card-icon"><span class="fa fa-{}" aria-hidden="true"></span></div>', kwargs["icon"]) if "icon" in kwargs else "",
"alert": mark_safe('role="alertdialog"') if kwargs.get("alert", "False") != "False" else "",
}
result = """
<dialog {alert}
id="{id}"
aria-labelledby="{id}-label"
aria-describedby="{id}-description">
<form method="dialog" class="modal-card form-horizontal">
{icon}
<div class="modal-card-content">
<h2 id="{id}-label">{label}</h2>
<p id="{id}-description">{description}</p>
"""
return format_html(result, **format_kwargs)
@register.simple_tag
def enddialog(*args, **kwargs):
return mark_safe("""
</div>
</form>
</dialog>
""")

View File

@@ -8,16 +8,16 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-28 11:06+0000\n"
"PO-Revision-Date: 2025-05-16 17:00+0000\n"
"Last-Translator: David <davemachala@gmail.com>\n"
"Language-Team: Czech <https://translate.pretix.eu/projects/pretix/pretix/cs/>"
"\n"
"PO-Revision-Date: 2025-02-19 17:00+0000\n"
"Last-Translator: Petr Čermák <pcermak@live.com>\n"
"Language-Team: Czech <https://translate.pretix.eu/projects/pretix/pretix/cs/"
">\n"
"Language: cs\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
"X-Generator: Weblate 5.11.4\n"
"X-Generator: Weblate 5.10\n"
#: pretix/_base_settings.py:87
msgid "English"
@@ -57,7 +57,7 @@ msgstr "Čeština"
#: pretix/_base_settings.py:96
msgid "Croatian"
msgstr "Chorvatština"
msgstr ""
#: pretix/_base_settings.py:97
msgid "Danish"
@@ -2971,9 +2971,12 @@ msgid "Repeat password"
msgstr "Opakovat heslo"
#: pretix/base/forms/questions.py:134 pretix/base/forms/questions.py:256
#, fuzzy
#| msgctxt "subevent"
#| msgid "No date was specified."
msgctxt "name_salutation"
msgid "not specified"
msgstr "neuvedeno"
msgstr "Nebylo uvedeno žádné datum."
#: pretix/base/forms/questions.py:219
msgid "Please do not use special characters in names."
@@ -4224,14 +4227,20 @@ msgstr ""
"automatická sleva poskytnuta i nadále."
#: pretix/base/models/discount.py:177
#, fuzzy
#| msgctxt "subevent"
#| msgid "All dates starting before"
msgctxt "subevent"
msgid "Available for dates starting from"
msgstr "Dostupné pro termíny začínající od"
msgstr "Všechny termíny začínající před"
#: pretix/base/models/discount.py:182
#, fuzzy
#| msgctxt "subevent"
#| msgid "All dates starting before"
msgctxt "subevent"
msgid "Available for dates starting until"
msgstr "Dostupné pro termíny začínající do"
msgstr "Všechny termíny začínající před"
#: pretix/base/models/discount.py:214
msgid ""
@@ -13465,7 +13474,7 @@ msgstr "Schváleno, čeká se na platbu"
#: pretix/plugins/reports/exporters.py:380
#: pretix/presale/templates/pretixpresale/event/fragment_order_status.html:7
msgid "Approval pending"
msgstr "Čeká na schválení"
msgstr "Čeká se na schválení"
#: pretix/control/forms/filter.py:241
#, fuzzy
@@ -18840,7 +18849,7 @@ msgstr "Kontrola"
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html:50
#: pretix/control/templates/pretixcontrol/organizers/logs.html:80
msgid "No results"
msgstr "Žádné výsledky"
msgstr "Bez výsledků"
#: pretix/control/templates/pretixcontrol/event/mail.html:7
#: pretix/control/templates/pretixcontrol/organizers/mail.html:11

View File

@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-28 11:08+0000\n"
"PO-Revision-Date: 2025-05-16 17:00+0000\n"
"Last-Translator: David <davemachala@gmail.com>\n"
"PO-Revision-Date: 2025-02-19 17:00+0000\n"
"Last-Translator: Petr Čermák <pcermak@live.com>\n"
"Language-Team: Czech <https://translate.pretix.eu/projects/pretix/pretix-js/"
"cs/>\n"
"Language: cs\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
"X-Generator: Weblate 5.11.4\n"
"X-Generator: Weblate 5.10\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
@@ -237,11 +237,11 @@ msgstr "Zrušeno"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:46
msgid "Confirmed"
msgstr "Potvrzeno"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:47
msgid "Approval pending"
msgstr "Čeká na schválení"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48
msgid "Redeemed"
@@ -440,7 +440,7 @@ msgstr "je po"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:40
msgid "="
msgstr "="
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:99
msgid "Product"
@@ -452,7 +452,7 @@ msgstr "Varianta produktu"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:107
msgid "Gate"
msgstr "Brána"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:111
msgid "Current date and time"
@@ -557,12 +557,12 @@ msgstr "Duplikát"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:193
msgctxt "entry_status"
msgid "present"
msgstr "přítomen"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:194
msgctxt "entry_status"
msgid "absent"
msgstr "nepřítomen"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:171
msgid "Check-in QR"
@@ -692,8 +692,10 @@ msgid "Calculating default price…"
msgstr "Výpočet standardní ceny…"
#: pretix/static/pretixcontrol/js/ui/plugins.js:69
#, fuzzy
#| msgid "Search results"
msgid "No results"
msgstr "Žádné výsledky"
msgstr "Vyhledat výsledky"
#: pretix/static/pretixcontrol/js/ui/question.js:42
msgid "Others"
@@ -762,57 +764,64 @@ msgid "Your local time:"
msgstr "Místní čas:"
#: pretix/static/pretixpresale/js/walletdetection.js:39
#, fuzzy
#| msgid "Apple Pay"
msgid "Google Pay"
msgstr "Google Pay"
msgstr "Apple Pay"
#: pretix/static/pretixpresale/js/widget/widget.js:16
msgctxt "widget"
msgid "Quantity"
msgstr "Počet"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:17
msgctxt "widget"
msgid "Decrease quantity"
msgstr "Snížit počet"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:18
msgctxt "widget"
msgid "Increase quantity"
msgstr "Zvýšit počet"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:19
msgctxt "widget"
msgid "Price"
msgstr "Cena"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:20
#, javascript-format
msgctxt "widget"
msgid "Original price: %s"
msgstr "Původní cena: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:21
#, javascript-format
msgctxt "widget"
msgid "New price: %s"
msgstr "Nová cena: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:22
#, fuzzy
#| msgid "Selected only"
msgctxt "widget"
msgid "Select"
msgstr "Vybrat"
msgstr "Pouze vybra"
#: pretix/static/pretixpresale/js/widget/widget.js:23
#, javascript-format
#, fuzzy, javascript-format
#| msgid "Selected only"
msgctxt "widget"
msgid "Select %s"
msgstr "Vybrat %s"
msgstr "Pouze vybrané"
#: pretix/static/pretixpresale/js/widget/widget.js:24
#, javascript-format
#, fuzzy, javascript-format
#| msgctxt "widget"
#| msgid "See variations"
msgctxt "widget"
msgid "Select variant %s"
msgstr "Vybrat variantu %s"
msgstr "Zobrazit možnosti"
#: pretix/static/pretixpresale/js/widget/widget.js:25
msgctxt "widget"
@@ -848,7 +857,7 @@ msgstr "od %(currency)s %(price)s"
#, javascript-format
msgctxt "widget"
msgid "Image of %s"
msgstr "Obrázek%s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:32
msgctxt "widget"
@@ -883,19 +892,24 @@ msgstr "K dispozici pouze s poukazem"
#: pretix/static/pretixpresale/js/widget/widget.js:38
#: pretix/static/pretixpresale/js/widget/widget.js:41
#, fuzzy
#| msgid "Payment method unavailable"
msgctxt "widget"
msgid "Not yet available"
msgstr "Zatím není k dispozici"
msgstr "Způsob platby není k dispozici"
#: pretix/static/pretixpresale/js/widget/widget.js:39
msgctxt "widget"
msgid "Not available anymore"
msgstr "Již není k dispozici"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:40
#, fuzzy
#| msgctxt "widget"
#| msgid "currently available: %s"
msgctxt "widget"
msgid "Currently not available"
msgstr "Momentálně není k dispozici."
msgstr "aktuálně k dispozici: %s"
#: pretix/static/pretixpresale/js/widget/widget.js:42
#, javascript-format
@@ -928,9 +942,12 @@ msgid "Open ticket shop"
msgstr "Obchod vstupenek otevřit"
#: pretix/static/pretixpresale/js/widget/widget.js:48
#, fuzzy
#| msgctxt "widget"
#| msgid "Resume checkout"
msgctxt "widget"
msgid "Checkout"
msgstr "Checkout"
msgstr "Obnovit checkout"
#: pretix/static/pretixpresale/js/widget/widget.js:49
msgctxt "widget"
@@ -992,14 +1009,20 @@ msgid "Continue"
msgstr "Pokračovat"
#: pretix/static/pretixpresale/js/widget/widget.js:61
#, fuzzy
#| msgctxt "widget"
#| msgid "See variations"
msgctxt "widget"
msgid "Show variants"
msgstr "Zobrazit možnosti"
#: pretix/static/pretixpresale/js/widget/widget.js:62
#, fuzzy
#| msgctxt "widget"
#| msgid "See variations"
msgctxt "widget"
msgid "Hide variants"
msgstr "Skrýt možnosti"
msgstr "Zobrazit možnosti"
#: pretix/static/pretixpresale/js/widget/widget.js:63
msgctxt "widget"
@@ -1087,31 +1110,31 @@ msgstr "Ne"
#: pretix/static/pretixpresale/js/widget/widget.js:81
msgid "Monday"
msgstr "Pondělí"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:82
msgid "Tuesday"
msgstr "Úterý"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:83
msgid "Wednesday"
msgstr "Středa"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:84
msgid "Thursday"
msgstr "Čtvrtek"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:85
msgid "Friday"
msgstr "Pátek"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:86
msgid "Saturday"
msgstr "Sobota"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:87
msgid "Sunday"
msgstr "Neděle"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:90
msgid "January"

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-28 11:06+0000\n"
"PO-Revision-Date: 2025-05-17 18:00+0000\n"
"PO-Revision-Date: 2025-04-14 23:00+0000\n"
"Last-Translator: Patrick Chilton <chpatrick@gmail.com>\n"
"Language-Team: Hungarian <https://translate.pretix.eu/projects/pretix/pretix/"
"hu/>\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.11.4\n"
"X-Generator: Weblate 5.10.4\n"
#: pretix/_base_settings.py:87
msgid "English"
@@ -14670,7 +14670,7 @@ msgstr "A kiválasztott \"{seat}\" ülés nem elérhető."
#: pretix/control/logdisplay.py:406 pretix/control/views/orders.py:1573
#: pretix/presale/views/order.py:1047
msgid "The order has been canceled."
msgstr "A megrendelés sztornózva lett."
msgstr ""
#: pretix/control/logdisplay.py:414
#, python-brace-format

File diff suppressed because it is too large Load Diff

View File

@@ -8,17 +8,17 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-28 11:08+0000\n"
"PO-Revision-Date: 2025-05-16 17:00+0000\n"
"Last-Translator: bstramsek <stramsek.borut+pretix-translate@gmail.com>\n"
"Language-Team: Slovenian <https://translate.pretix.eu/projects/pretix/"
"pretix-js/sl/>\n"
"PO-Revision-Date: 2019-08-27 08:00+0000\n"
"Last-Translator: Bostjan Marusic <bostjan@brokenbones.si>\n"
"Language-Team: Slovenian <https://translate.pretix.eu/projects/pretix/pretix-"
"js/sl/>\n"
"Language: sl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || "
"n%100==4 ? 2 : 3;\n"
"X-Generator: Weblate 5.11.4\n"
"X-Generator: Weblate 3.5.1\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
@@ -32,7 +32,7 @@ msgstr "Komentar:"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:34
msgid "PayPal"
msgstr "PayPal"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:35
msgid "Venmo"

View File

@@ -1,4 +1,5 @@
{% load i18n %}
{% load icon %}
{% load eventurl %}
{% if item.current_unavailability_reason == 'require_voucher' %}
@@ -20,14 +21,15 @@
{% elif avail <= 10 %}
<div class="col-md-2 col-sm-3 col-xs-6 availability-box gone">
{% if price or original_price %}
<strong>{% trans "SOLD OUT" %}</strong>
<strong>{% icon "ban" %} {% trans "SOLD OUT" %}</strong>
{% else %}
<strong>{% trans "FULLY BOOKED" %}</strong>
<strong>{% icon "ban" %} {% trans "FULLY BOOKED" %}</strong>
{% endif %}
</span>
{% if allow_waitinglist and item.allow_waitinglist %}
<br/>
<a href="{% eventurl event "presale:event.waitinglist" cart_namespace=cart_namespace|default_if_none:"" %}?item={{ item.pk }}{% if var %}&var={{ var.pk }}{% endif %}{% if subevent %}&subevent={{ subevent.pk }}{% endif %}">
<span class="fa fa-plus-circle" aria-hidden="true"></span>
<a href="{% eventurl event "presale:event.waitinglist" cart_namespace=cart_namespace|default_if_none:"" %}?item={{ item.pk }}{% if var %}&var={{ var.pk }}{% endif %}{% if subevent %}&subevent={{ subevent.pk }}{% endif %}" class="btn btn-default btn-xs">
{% icon "plus-circle" %}
{% trans "Waiting list" %}
</a>
{% endif %}

View File

@@ -492,21 +492,15 @@
<div class="row">
<div class="col-md-12">
{% if not cart.is_ordered %}
<form class="text-muted"
method="post" data-asynctask action="{% eventurl request.event "presale:event.cart.extend" cart_namespace=cart_namespace %}">
{% csrf_token %}
<span id="cart-deadline" data-expires="{{ cart.first_expiry|date:"Y-m-d H:i:sO" }}">
{% if cart.minutes_left > 0 or cart.seconds_left > 0 %}
{% blocktrans trimmed with minutes=cart.minutes_left %}
The items in your cart are reserved for you for {{ minutes }} minutes.
{% endblocktrans %}
{% else %}
{% trans "The items in your cart are no longer reserved for you. You can still complete your order as long as theyre available." %}
{% endif %}
</span>
<button class="btn btn-link" type="submit" id="cart-extend-button">
<i class="fa fa-refresh" aria-hidden="true"></i> {% trans "Extend" %}</button>
</form>
<p class="text-muted" id="cart-deadline" data-expires="{{ cart.first_expiry|date:"Y-m-d H:i:sO" }}">
{% if cart.minutes_left > 0 or cart.seconds_left > 0 %}
{% blocktrans trimmed with minutes=cart.minutes_left %}
The items in your cart are reserved for you for {{ minutes }} minutes.
{% endblocktrans %}
{% else %}
{% trans "The items in your cart are no longer reserved for you. You can still complete your order as long as theyre available." %}
{% endif %}
</p>
{% else %}
<p class="sr-only" id="cart-description">{% trans "Overview of your ordered products." %}</p>
{% endif %}

View File

@@ -1,4 +1,5 @@
{% load i18n %}
{% load icon %}
{% load l10n %}
{% load eventurl %}
{% load money %}
@@ -82,9 +83,9 @@
{% if not event.settings.show_variations_expanded %}
{% if item.best_variation_availability <= 10 %}
{% if not item.min_price %}
<strong class="gone">{% trans "FULLY BOOKED" %}</strong>
<strong class="gone">{% icon "ban" %} {% trans "FULLY BOOKED" %}</strong>
{% else %}
<strong class="gone">{% trans "SOLD OUT" %}</strong>
<strong class="gone">{% icon "ban" %} {% trans "SOLD OUT" %}</strong>
{% endif %}
{% if allow_waitinglist and item.allow_waitinglist %}
<br/>

View File

@@ -7,8 +7,6 @@
{% load thumb %}
{% load eventsignal %}
{% load rich_text %}
{% load icon %}
{% load dialog %}
{% block title %}
{% if "year" in request.GET %}
@@ -242,13 +240,6 @@
</div>
{% endif %}
</form>
{% if ev.presale_is_running and display_add_to_cart %}
{% trans "You didnt select any ticket." as label_nothing_to_add %}
{% trans "Please tick a checkbox or enter a quantity for one of the ticket types to add to the cart." as description_nothing_to_add %}
{% dialog "dialog-nothing-to-add" label_nothing_to_add description_nothing_to_add icon="exclamation-circle" %}
<p class="modal-card-confirm"><button class="btn btn-primary">{% trans "OK" %}</button></p>
{% enddialog %}
{% endif %}
{% endif %}
{% endif %}
</main>

View File

@@ -2,8 +2,6 @@
{% load rich_text %}
{% load safelink %}
{% load escapejson %}
{% load icon %}
{% load dialog %}
<div id="ajaxerr">
</div>
<div id="popupmodal" hidden aria-live="polite">
@@ -52,74 +50,93 @@
{{ cookie_consent_from_widget|json_script:"cookie-consent-from-widget" }}
{% endif %}
{% if cookie_providers %}
{% with request.event|default:request.organizer as sh %}
{% dialog "cookie-consent-modal" sh.settings.cookie_consent_dialog_title sh.settings.cookie_consent_dialog_text|rich_text icon="shield" %}
{% if sh.settings.cookie_consent_dialog_text_secondary %}
<div class="text-muted">
{{ sh.settings.cookie_consent_dialog_text_secondary|rich_text }}
</div>
{% endif %}
<details id="cookie-consent-details">
<summary>
<span class="fa fa-fw chevron"></span>
{% trans "Adjust settings in detail" %}
</summary>
<div class="checkbox">
<label>
<input type="checkbox" disabled checked="" aira-describedby="cookie-consent-checkbox-required-description">
{% trans "Required cookies" %}
</label>
</div>
<div class="help-block" id="cookie-consent-checkbox-required-description">
<p>{% trans "Functional cookies (e.g. shopping cart, login, payment, language preference) and technical cookies (e.g. security purposes)" %}</p>
</div>
{% for cp in cookie_providers %}
<div class="checkbox">
<label>
<input type="checkbox" name="{{ cp.identifier }}" aira-describedby="cookie-consent-checkbox-{{ cp.identifier }}-description">
{{ cp.provider_name }}
</label>
</div>
<div class="help-block" id="cookie-consent-checkbox-{{ cp.identifier }}-description">
<p>
{% for c in cp.usage_classes %}
{% if forloop.counter0 > 0 %}&middot; {% endif %}
{% if c.value == 1 %}
{% trans "Functionality" context "cookie_usage" %}
{% elif c.value == 2 %}
{% trans "Analytics" context "cookie_usage" %}
{% elif c.value == 3 %}
{% trans "Marketing" context "cookie_usage" %}
{% elif c.value == 4 %}
{% trans "Social features" context "cookie_usage" %}
{% endif %}
{% endfor %}
{% if cp.privacy_url %}
&middot;
<a href="{% safelink cp.privacy_url %}" target="_blank">
{% trans "Privacy policy" %}
</a>
<div id="cookie-consent-modal" aria-live="polite">
<div class="modal-card">
<div class="modal-card-content">
<h3 id="cookie-consent-modal-label"></h3>
<div id="cookie-consent-modal-description">
<form class="form-horizontal">
{% with request.event|default:request.organizer as sh %}
<h3>{{ sh.settings.cookie_consent_dialog_title }}</h3>
{{ sh.settings.cookie_consent_dialog_text|rich_text }}
{% if sh.settings.cookie_consent_dialog_text_secondary %}
<div class="text-muted">
{{ sh.settings.cookie_consent_dialog_text_secondary|rich_text }}
</div>
{% endif %}
</p>
</div>
{% endfor %}
</details>
<p class="modal-card-confirm modal-card-confirm-spread">
<button class="btn btn-lg btn-default" id="cookie-consent-button-no" value="no" autofocus="true"
data-summary-text="{{ sh.settings.cookie_consent_dialog_button_no }}"
data-detail-text="{% trans "Save selection" %}">
{{ sh.settings.cookie_consent_dialog_button_no }}
</button>
<button class="btn btn-lg btn-primary" id="cookie-consent-button-yes" value="yes">
{{ sh.settings.cookie_consent_dialog_button_yes }}
</button>
</p>
{% if sh.settings.privacy_url %}
<p class="text-center">
<small><a href="{% safelink sh.settings.privacy_url %}" target="_blank" rel="noopener">{% trans "Privacy policy" %}</a></small>
</p>
{% endif %}
{% enddialog %}
{% endwith %}
<details id="cookie-consent-details">
<summary>
<span class="fa fa-fw chevron"></span>
{% trans "Adjust settings in detail" %}
</summary>
<div class="checkbox">
<label>
<input type="checkbox" disabled checked="" aira-describedby="cookie-consent-checkbox-required-description">
{% trans "Required cookies" %}
</label>
</div>
<div class="help-block" id="cookie-consent-checkbox-required-description">
<p>{% trans "Functional cookies (e.g. shopping cart, login, payment, language preference) and technical cookies (e.g. security purposes)" %}</p>
</div>
{% for cp in cookie_providers %}
<div class="checkbox">
<label>
<input type="checkbox" name="{{ cp.identifier }}" aira-describedby="cookie-consent-checkbox-{{ cp.identifier }}-description">
{{ cp.provider_name }}
</label>
</div>
<div class="help-block" id="cookie-consent-checkbox-{{ cp.identifier }}-description">
<p>
{% for c in cp.usage_classes %}
{% if forloop.counter0 > 0 %}&middot; {% endif %}
{% if c.value == 1 %}
{% trans "Functionality" context "cookie_usage" %}
{% elif c.value == 2 %}
{% trans "Analytics" context "cookie_usage" %}
{% elif c.value == 3 %}
{% trans "Marketing" context "cookie_usage" %}
{% elif c.value == 4 %}
{% trans "Social features" context "cookie_usage" %}
{% endif %}
{% endfor %}
{% if cp.privacy_url %}
&middot;
<a href="{% safelink cp.privacy_url %}" target="_blank">
{% trans "Privacy policy" %}
</a>
{% endif %}
</p>
</div>
{% endfor %}
</details>
<div class="row">
<div class="col-xs-12 col-md-6">
<p>
<button type="button" class="btn btn-lg btn-block btn-primary" id="cookie-consent-button-no"
data-summary-text="{{ sh.settings.cookie_consent_dialog_button_no }}"
data-detail-text="{% trans "Save selection" %}">
{{ sh.settings.cookie_consent_dialog_button_no }}
</button>
</p>
</div>
<div class="col-xs-12 col-md-6">
<p>
<button type="button" class="btn btn-lg btn-block btn-primary" id="cookie-consent-button-yes">
{{ sh.settings.cookie_consent_dialog_button_yes }}
</button>
</p>
</div>
</div>
{% if sh.settings.privacy_url %}
<p class="text-center">
<a href="{% safelink sh.settings.privacy_url %}" target="_blank" rel="noopener">{% trans "Privacy policy" %}</a>
</p>
{% endif %}
{% endwith %}
<form>
</div>
</div>
</div>
</div>
{% endif %}
{% endif %}

View File

@@ -49,7 +49,7 @@
<div class="event-list full-width-list alternating-rows">
{% for e in events %}{% eventurl e "presale:event.index" as url %}
<article class="row" aria-labelledby="event-{{ e.pk }}-label" aria-describedby="event-{{ e.pk }}-desc">
<h3 class="col-md-4 col-xs-12"><a href="{{ url }}" id="event-{{ e.pk }}-label" class="no-underline">{{ e.name }}</a></h3>
<h3 class="col-md-4 col-xs-12"><a href="{{ url }}" id="event-{{ e.pk }}-label">{{ e.name }}</a></h3>
<p class="col-md-3 col-xs-12" id="event-{{ e.pk }}-desc">
{% if e.settings.show_dates_on_frontpage %}
{% if e.has_subevents %}

View File

@@ -56,7 +56,6 @@ frame_wrapped_urls = [
re_path(r'^cart/remove$', pretix.presale.views.cart.CartRemove.as_view(), name='event.cart.remove'),
re_path(r'^cart/voucher$', pretix.presale.views.cart.CartApplyVoucher.as_view(), name='event.cart.voucher'),
re_path(r'^cart/clear$', pretix.presale.views.cart.CartClear.as_view(), name='event.cart.clear'),
re_path(r'^cart/extend$', pretix.presale.views.cart.CartExtendReservation.as_view(), name='event.cart.extend'),
re_path(r'^cart/answer/(?P<answer>[^/]+)/$',
pretix.presale.views.cart.AnswerDownload.as_view(),
name='event.cart.download.answer'),

View File

@@ -62,7 +62,7 @@ from pretix.base.models import (
)
from pretix.base.services.cart import (
CartError, add_items_to_cart, apply_voucher, clear_cart, error_messages,
extend_cart_reservation, remove_cart_position,
remove_cart_position,
)
from pretix.base.timemachine import time_machine_now
from pretix.base.views.tasks import AsyncAction
@@ -537,20 +537,6 @@ class CartClear(EventViewMixin, CartActionMixin, AsyncAction, View):
request.sales_channel.identifier, time_machine_now(default=None))
@method_decorator(allow_frame_if_namespaced, 'dispatch')
class CartExtendReservation(EventViewMixin, CartActionMixin, AsyncAction, View):
task = extend_cart_reservation
known_errortypes = ['CartError']
def get_success_message(self, value):
if value > 0:
return _('Your cart timeout was extended.')
def post(self, request, *args, **kwargs):
return self.do(self.request.event.id, get_or_create_cart_id(self.request), translation.get_language(),
request.sales_channel.identifier, time_machine_now(default=None))
@method_decorator(allow_cors_if_namespaced, 'dispatch')
@method_decorator(allow_frame_if_namespaced, 'dispatch')
@method_decorator(iframe_entry_view_wrapper, 'dispatch')

Binary file not shown.

Before

Width:  |  Height:  |  Size: 587 B

View File

@@ -49,7 +49,7 @@ html.rtl {
}
input[lang=ar], textarea[lang=ar], div[lang=ar], pre[lang=ar],
input[lang=he], textarea[lang=he], div[lang=he], pre[lang=he] {
input[lang=hw], textarea[lang=hw], div[lang=hw], pre[lang=hw] {
/* Keep list of languages in sync with pretix._base_settings.LANGUAGES_RTL */
direction: rtl;
}
}

View File

@@ -262,95 +262,3 @@ svg.svg-icon {
@include table-row-variant('info', var(--pretix-brand-info-success-lighten-30), var(--pretix-brand-info-success-lighten-25));
@include table-row-variant('warning', var(--pretix-brand-warning-lighten-40), var(--pretix-brand-warning-lighten-35));
@include table-row-variant('danger', var(--pretix-brand-danger-lighten-30), var(--pretix-brand-danger-lighten-25));
dialog {
border: none;
width: 80%;
max-width: 43em;
padding: 0;
box-shadow: 0 7px 14px 0 rgba(78, 50, 92, 0.1),0 3px 6px 0 rgba(0,0,0,.07);
background: white;
border-radius: $border-radius-large;
opacity: 0;
transition: opacity .5s allow-discrete;
.modal-card {
display: flex;
flex-direction: column;
align-content: stretch;
}
.modal-card-icon {
background: $brand-primary;
font-size: 2em;
color: white;
text-align: center;
padding: 3px;
}
.modal-card-content {
padding: 1.5em;
}
.modal-card-content>*:last-child {
margin-bottom: 0;
}
.modal-card-content>*:first-child {
margin-top: 0;
}
.modal-card-confirm {
margin-top: 2em;
display: flex;
justify-content: flex-end;
gap: 1em;
align-items: center;
}
.modal-card-confirm-spread {
justify-content: space-between;
}
}
dialog::backdrop {
background-color: rgba(255, 255, 255, .5);
opacity: 0;
transition: opacity .5s allow-discrete;
}
dialog[open], dialog[open]::backdrop {
opacity: 1;
}
@starting-style {
dialog[open], dialog[open]::backdrop {
opacity: 0;
}
}
@media screen and (min-width: $screen-sm-min) {
dialog {
.modal-card:has(.modal-card-icon) {
flex-direction: row;
}
.modal-card-content {
padding: 2em;
}
.modal-card-icon {
font-size: 4em;
padding: 6px 16px;
}
}
}
.shake-once {
animation: shake .2s;
transform: translate3d(0, 0, 0);
backface-visibility: hidden;
}
@keyframes shake {
0% { transform: skewX(0deg); }
20% { transform: skewX(-5deg); }
40% { transform: skewX(5deg); }
60% { transform: skewX(-5deg); }
80% { transform: skewX(5deg); }
100% { transform: skewX(0deg); }
}

View File

@@ -160,7 +160,7 @@ pre[lang=ht], input[lang=ht], textarea[lang=ht], div[lang=ht] { background-image
pre[lang=hu], input[lang=hu], textarea[lang=hu], div[lang=hu] { background-image: url(static('pretixbase/img/flags/hu.png')); }
pre[lang=id], input[lang=id], textarea[lang=id], div[lang=id] { background-image: url(static('pretixbase/img/flags/id.png')); }
pre[lang=ie], input[lang=ie], textarea[lang=ie], div[lang=ie] { background-image: url(static('pretixbase/img/flags/ie.png')); }
pre[lang=he], input[lang=he], textarea[lang=he], div[lang=he] { background-image: url(static('pretixbase/img/flags/il.png')); }
pre[lang=il], input[lang=il], textarea[lang=il], div[lang=il] { background-image: url(static('pretixbase/img/flags/il.png')); }
pre[lang=in], input[lang=in], textarea[lang=in], div[lang=in] { background-image: url(static('pretixbase/img/flags/in.png')); }
pre[lang=io], input[lang=io], textarea[lang=io], div[lang=io] { background-image: url(static('pretixbase/img/flags/io.png')); }
pre[lang=iq], input[lang=iq], textarea[lang=iq], div[lang=iq] { background-image: url(static('pretixbase/img/flags/iq.png')); }
@@ -306,4 +306,3 @@ pre[lang=za], input[lang=za], textarea[lang=za], div[lang=za] { background-image
pre[lang=zm], input[lang=zm], textarea[lang=zm], div[lang=zm] { background-image: url(static('pretixbase/img/flags/zm.png')); }
pre[lang=zw], input[lang=zw], textarea[lang=zw], div[lang=zw] { background-image: url(static('pretixbase/img/flags/zw.png')); }
pre[lang=en], input[lang=en], textarea[lang=en], div[lang=en] { background-image: url(static('pretixbase/img/flags/gb.png')); }
pre[lang=eu], input[lang=eu], textarea[lang=eu], div[lang=eu] { background-image: url(static('pretixbase/img/flags/basque.png')); }

View File

@@ -55,7 +55,6 @@ var cart = {
pad(diff_minutes.toString(), 2) + ':' + pad(diff_seconds.toString(), 2)
);
}
$("#cart-extend-button").toggle(diff_minutes < 3);
},
init: function () {

View File

@@ -6,7 +6,7 @@ $(function () {
var storage_key = $("#cookie-consent-storage-key").text();
var widget_consent = $("#cookie-consent-from-widget").text();
var consent_checkboxes = $("#cookie-consent-details input[type=checkbox][name]");
var consent_modal = document.getElementById("cookie-consent-modal");
var consent_modal = $("#cookie-consent-modal");
function update_consent(consent, sessionOnly) {
if (storage_key && window.sessionStorage && sessionOnly) {
@@ -108,32 +108,25 @@ $(function () {
_set_button_text();
if (show_dialog) {
consent_modal.showModal();
consent_modal.addEventListener("cancel", function() {
// Dialog was initially shown, interpret Escape as „do not consent to new providers“
var consent = {};
consent_checkboxes.each(function () {
consent[this.name] = storage_val[this.name] || false;
});
update_consent(consent, false);
}, {once : true});
// We use .css() instead of .show() because of some weird issue that only occurs in Firefox
// and only within the widget.
consent_modal.css("display", "block");
}
consent_modal.addEventListener("close", function () {
if (!consent_modal.returnValue) {// ESC, do not save
return;
}
$("#cookie-consent-button-yes, #cookie-consent-button-no").on("click", function () {
consent_modal.hide();
var consent = {};
var consent_all = consent_modal.returnValue == "yes";
var consent_all = this.id == "cookie-consent-button-yes";
consent_checkboxes.each(function () {
consent[this.name] = this.checked = consent_all || this.checked;
});
if (consent_all) _set_button_text();
// Always save explicit consent to permanent storage
update_consent(consent, false);
});
consent_checkboxes.on("change", _set_button_text);
$("#cookie-consent-reopen").on("click", function (e) {
consent_modal.showModal()
consent_modal.show()
e.preventDefault()
return true
})

View File

@@ -390,13 +390,6 @@ $(function () {
sessionStorage.removeItem('scrollpos');
}
$("dialog").on("mousedown", function (e) {
if (e.target == this) {
// dialog has no padding, so this triggers only onclick on backdrop
this.close();
}
});
$(".accordion-radio").click(function() {
var $input = $("input", this);
if (!$input.prop("checked")) $input.prop('checked', true).trigger("change");
@@ -485,21 +478,33 @@ $(function () {
sessionStorage.setItem('scrollpos', window.scrollY);
});
}
$("form:has(#btn-add-to-cart)").on("submit", function(e) {
if (
(this.classList.contains("has-seating") && this.querySelector("pretix-seating-checkout-button button")) ||
this.querySelector("input[type=checkbox]:checked") ||
[...this.querySelectorAll(".input-item-count[type=text]")].some(input => input.value && input.value !== "0") // TODO: seating hat noch einen seating-dummy-item-count, das ist Mist!
) {
// okay, let the submit-event bubble to async-task
return;
var update_cart_form = function () {
var is_enabled = $(".product-row input[type=checkbox]:checked, .variations input[type=checkbox]:checked, .product-row input[type=radio]:checked, .variations input[type=radio]:checked").length;
if (!is_enabled) {
$(".input-item-count").each(function () {
if ($(this).val() && $(this).val() !== "0") {
is_enabled = true;
}
});
$(".input-seat-selection option").each(function() {
if ($(this).val() && $(this).val() !== "" && $(this).prop('selected')) {
is_enabled = true;
}
});
}
e.preventDefault();
e.stopPropagation();
document.querySelector("#dialog-nothing-to-add").showModal();
});
if (!is_enabled && (!$(".has-seating").length || $("#seating-dummy-item-count").length)) {
$("#btn-add-to-cart").prop("disabled", !is_enabled).popover({
'content': function () { return gettext("Please enter a quantity for one of the ticket types.") },
'placement': 'top',
'trigger': 'hover focus'
});
} else {
$("#btn-add-to-cart").prop("disabled", false).popover("destroy")
}
};
update_cart_form();
$(".product-row input[type=checkbox], .variations input[type=checkbox], .product-row input[type=radio], .variations input[type=radio], .input-item-count, .input-seat-selection")
.on("change mouseup keyup", update_cart_form);
$(".table-calendar td.has-events").click(function () {
var $grid = $(this).closest("[role='grid']");

View File

@@ -471,7 +471,7 @@ Vue.component('variation', {
// Variation description
+ '<div class="pretix-widget-item-info-col">'
+ '<div class="pretix-widget-item-title-and-description">'
+ '<strong :id="variation_label_id" class="pretix-widget-item-title" role="heading" v-bind:aria-level="headingLevel">{{ variation.value }}</strong>'
+ '<strong :id="variation_label_id" class="pretix-widget-item-title">{{ variation.value }}</strong>'
+ '<div :id="variation_desc_id" class="pretix-widget-item-description" v-if="variation.description" v-html="variation.description"></div>'
+ '<p class="pretix-widget-item-meta" '
+ ' v-if="!variation.has_variations && variation.avail[1] !== null && variation.avail[0] === 100">'
@@ -500,7 +500,6 @@ Vue.component('variation', {
props: {
variation: Object,
item: Object,
category: Object,
},
computed: {
orig_price: function () {
@@ -524,9 +523,6 @@ Vue.component('variation', {
aria_labelledby: function () {
return [this.variation_label_id, this.variation_price_id].join(" ");
},
headingLevel: function () {
return this.category.name ? '5' : '4';
},
}
});
Vue.component('item', {
@@ -537,12 +533,12 @@ Vue.component('item', {
+ '<div class="pretix-widget-item-info-col">'
+ '<a :href="item.picture_fullsize" v-if="item.picture" class="pretix-widget-item-picture-link" @click.prevent.stop="lightbox"><img :src="item.picture" class="pretix-widget-item-picture" :alt="picture_alt_text"></a>'
+ '<div class="pretix-widget-item-title-and-description">'
+ '<a v-if="item.has_variations && show_toggle" :id="item_label_id" role="heading" v-bind:aria-level="headingLevel" class="pretix-widget-item-title" :href="\'#\' + item.id + \'-variants\'"'
+ '<a v-if="item.has_variations && show_toggle" :id="item_label_id" class="pretix-widget-item-title" :href="\'#\' + item.id + \'-variants\'"'
+ ' @click.prevent.stop="expand"'
+ '>'
+ '{{ item.name }}'
+ '</a>'
+ '<strong v-else class="pretix-widget-item-title" :id="item_label_id" role="heading" v-bind:aria-level="headingLevel">{{ item.name }}</strong>'
+ '<strong v-else class="pretix-widget-item-title" :id="item_label_id">{{ item.name }}</strong>'
+ '<div class="pretix-widget-item-description" :id="item_desc_id" v-if="item.description" v-html="item.description"></div>'
+ '<p class="pretix-widget-item-meta" v-if="item.order_min && item.order_min > 1">'
+ '<small>{{ min_order_str }}</small>'
@@ -576,14 +572,13 @@ Vue.component('item', {
// Variations
+ '<div :class="varClasses" v-if="item.has_variations" :id="item.id + \'-variants\'" ref="variations">'
+ '<variation v-for="variation in item.variations" :variation="variation" :item="item" :category="category" :key="variation.id">'
+ '<variation v-for="variation in item.variations" :variation="variation" :item="item" :key="variation.id">'
+ '</variation>'
+ '</div>'
+ '</div>'),
props: {
item: Object,
category: Object,
},
data: function () {
return {
@@ -641,9 +636,6 @@ Vue.component('item', {
picture_alt_text: function () {
return django.interpolate(strings["image_of"], [this.item.name]);
},
headingLevel: function () {
return this.category.name ? '4' : '3';
},
item_label_id: function () {
return this.$root.html_id + '-item-label-' + this.item.id;
},
@@ -695,7 +687,7 @@ Vue.component('category', {
+ '<div class="pretix-widget-category-description" v-if="category.description" v-html="category.description">'
+ '</div>'
+ '<div class="pretix-widget-category-items">'
+ '<item v-for="item in category.items" :category="category" :item="item" :key="item.id"></item>'
+ '<item v-for="item in category.items" :item="item" :key="item.id"></item>'
+ '</div>'
+ '</div>'),
props: {
@@ -1010,7 +1002,7 @@ Vue.component('pretix-widget-event-form', {
// Event name
+ '<div class="pretix-widget-event-header" v-if="display_event_info">'
+ '<strong role="heading" aria-level="2">{{ $root.name }}</strong>'
+ '<strong>{{ $root.name }}</strong>'
+ '</div>'
// Date range

View File

@@ -23,7 +23,7 @@
text-align: center;
&.gone, .gone {
color: $alert-danger-text;
color: $brand-danger;
}
&.unavailable, .unavailable {
color: $alert-warning-text;

View File

@@ -76,7 +76,6 @@ html {
clip: auto;
}
#skip-to-main {
z-index: 9999;
/* padding is needed to make focus-outline visible */
padding: 8px;
background-color: inherit;
@@ -157,7 +156,6 @@ button:focus, a:focus, .btn:focus, summary:focus, div:focus,
button:active:focus, a:active:focus, .btn:active:focus, summary:active:focus, div:active:focus,
button.active:focus, a.active:focus, .btn.active:focus,
input:focus, .form-control:focus, .btn-checkbox:has(input:focus),
input[type="file"]:focus, input[type="radio"]:focus, input[type="checkbox"]:focus,
.input-item-count-group:has(input:focus), .input-group-price:has(input:focus) {
outline: 2px solid $link-hover-color;
outline-offset: 2px;
@@ -291,7 +289,7 @@ body.loading .container {
font-size: 120px;
color: $brand-primary;
}
#loadingmodal, #ajaxerr, #popupmodal {
#loadingmodal, #ajaxerr, #cookie-consent-modal, #popupmodal {
position: fixed;
top: 0;
left: 0;
@@ -361,7 +359,7 @@ body.loading .container {
}
}
@media (max-width: 700px) {
#loadingmodal, #ajaxerr, #popupmodal {
#loadingmodal, #ajaxerr, #cookie-consent-modal, #popupmodal {
.modal-card {
margin: 25px auto 0;
max-height: calc(100vh - 50px - 20px);

File diff suppressed because it is too large Load Diff