Dialog for cart renewal, async task without page refresh (#5148)

* async_task: deduplicate response handling code

* extend cart without full page reload

* update dialog markup

* fix error response from CartExtend

* refactor asynctask, make sure waitingDialog.show() re-initializes dialog contents

* add cart expiry notification

* add aria references to other dialogs

* improve error handling

* fix error if max_extend=None

* different message for expiring soon and expired carts

* refactor dialog css

* add classes to further dialog elements

* switch extend-cart-dialog and loadingmodal to <dialog>

* Backport simple_block_tag from Django 5.2

* Use simple_block_tag for {% dialog %} tag

* add alertdialog role

* Update src/pretix/static/pretixbase/scss/_dialogs.scss

Co-authored-by: Richard Schreiber <schreiber@rami.io>

* fix mobile dialog styles not being overwritten

* asynctask dialog: prevent close by escape on chrome

* remove dynamic aria-live from #cart-deadline

dynamic aria-live is generally not well supported and as we have the dialog now anyways, we can remove it

* move continue-button to right

* Update src/pretix/static/pretixpresale/js/ui/cart.js

Co-authored-by: Richard Schreiber <schreiber@rami.io>

* Fix CSS for old-style dialog

* fix heading display/level

* align dialogs at the top as they originally were

* fix </div> from merge-conflict

* fix missing grow for dialog-content

* improve cart-extend-button ui

* do not show cart-extend-dialog onload

* improve message if 0 minutes

* do not save messae in session if ajax_dont_redirect

* add ajax_dont_redirect to async_task_check_url

* improve draw_deadline to only update #cart-deadline if necessary

* add renew-confirmation-message

---------

Co-authored-by: Richard Schreiber <schreiber@rami.io>
Co-authored-by: Raphael Michel <michel@rami.io>
This commit is contained in:
luelista
2025-05-27 07:17:50 +02:00
committed by GitHub
parent fdbcffd5fd
commit 5962536a11
19 changed files with 621 additions and 556 deletions

View File

@@ -229,11 +229,13 @@ class CartMixin:
try:
first_expiry = min(p.expires for p in positions) if positions else now()
max_expiry_extend = min((p.max_extend for p in positions if p.max_extend), default=None)
total_seconds_left = max(first_expiry - now(), timedelta()).total_seconds()
minutes_left = int(total_seconds_left // 60)
seconds_left = int(total_seconds_left % 60)
except AttributeError:
first_expiry = None
max_expiry_extend = None
minutes_left = None
seconds_left = None
@@ -250,6 +252,7 @@ class CartMixin:
'minutes_left': minutes_left,
'seconds_left': seconds_left,
'first_expiry': first_expiry,
'max_expiry_extend': max_expiry_extend,
'is_ordered': bool(order),
'itemcount': sum(c.count for c in positions if not c.addon_to),
'current_selected_payments': [p for p in self.current_selected_payments(total) if p.get('multi_use_supported')]

View File

@@ -542,8 +542,14 @@ class CartExtendReservation(EventViewMixin, CartActionMixin, AsyncAction, View):
task = extend_cart_reservation
known_errortypes = ['CartError']
def _ajax_response_data(self, value):
if isinstance(value, dict):
return value
else:
return {}
def get_success_message(self, value):
if value > 0:
if value['success'] > 0:
return _('Your cart timeout was extended.')
def post(self, request, *args, **kwargs):
@@ -561,7 +567,7 @@ class CartAdd(EventViewMixin, CartActionMixin, AsyncAction, View):
def get_success_message(self, value):
return _('The products have been successfully added to your cart.')
def _ajax_response_data(self):
def _ajax_response_data(self, value):
cart_id = get_or_create_cart_id(self.request)
return {
'cart_id': cart_id,