Compare commits

...

1 Commits

Author SHA1 Message Date
Mira Weller 2ac10699ea Merge categories and items list views 2026-07-08 10:12:55 +02:00
8 changed files with 97 additions and 25 deletions
-8
View File
@@ -173,14 +173,6 @@ def get_event_navigation(request: HttpRequest):
}),
'active': 'event.items.quota' in url.url_name,
},
{
'label': _('Categories'),
'url': reverse('control:event.items.categories', kwargs={
'event': request.event.slug,
'organizer': request.event.organizer.slug,
}),
'active': 'event.items.categories' in url.url_name,
},
{
'label': _('Questions'),
'url': reverse('control:event.items.questions', kwargs={
@@ -45,6 +45,9 @@
{% endif %}
</div>
<div class="form-group submit-group">
{% if category %}
<a title="{% trans "Delete" %}" href="{% url "control:event.items.categories.delete" organizer=request.event.organizer.slug event=request.event.slug category=category.id %}" class="btn btn-danger btn-lg pull-left"><i class="fa fa-trash"></i> {% trans "Delete" %}</a>
{% endif %}
<button type="submit" class="btn btn-primary btn-save">
{% trans "Save" %}
</button>
@@ -10,7 +10,7 @@
Are you sure you want to delete the category <strong>{{ name }}</strong>?
{% endblocktrans %}</p>
<div class="form-group submit-group">
<a href="{% url "control:event.items.categories" organizer=request.event.organizer.slug event=request.event.slug %}" class="btn btn-default btn-cancel">
<a href="{% url "control:event.items" organizer=request.event.organizer.slug event=request.event.slug %}" class="btn btn-default btn-cancel">
{% trans "Cancel" %}
</a>
<button type="submit" class="btn btn-danger btn-save">
@@ -2,6 +2,7 @@
{% load i18n %}
{% load money %}
{% load static %}
{% load compress %}
{% block title %}{% trans "Products" %}{% endblock %}
{% block inside %}
{% blocktrans asvar s_taxes %}taxes{% endblocktrans %}
@@ -23,19 +24,24 @@
{% if 'event.items:write' in request.eventpermset %}
<a href="{% url "control:event.items.add" organizer=request.event.organizer.slug event=request.event.slug %}"
class="btn btn-primary btn-lg"><i class="fa fa-plus"></i> {% trans "Create a new product" %}</a>
class="btn btn-primary btn-lg"><i class="fa fa-plus"></i> {% trans "Create a new product" %}</a>
<a href="{% url "control:event.items.categories.add" organizer=request.event.organizer.slug event=request.event.slug %}"
class="btn btn-default btn-lg"><i class="fa fa-plus"></i> {% trans "Create a new category" %}</a>
{% endif %}
</div>
{% else %}
{% if 'event.items:write' in request.eventpermset %}
<p>
<a href="{% url "control:event.items.add" organizer=request.event.organizer.slug event=request.event.slug %}"
class="btn btn-default"><i class="fa fa-plus"></i> {% trans "Create a new product" %}</a>
</p>
{% endif %}
<form method="post">
<form method="post" id="products_table">
{% if 'event.items:write' in request.eventpermset %}
<p>
<a href="{% url "control:event.items.add" organizer=request.event.organizer.slug event=request.event.slug %}"
class="btn btn-default"><i class="fa fa-plus"></i> {% trans "Create a new product" %}</a>
<a href="{% url "control:event.items.categories.add" organizer=request.event.organizer.slug event=request.event.slug %}"
class="btn btn-default"><i class="fa fa-plus"></i> {% trans "Create a new category" %}</a>
<button class="btn btn-default pull-right" id="btn_reorder_categories"><i class="fa fa-arrows"></i> {% trans "Reorder categories" %}</button>
</p>
{% endif %}
{% csrf_token %}
<div class="table-responsive">
<div class="table-responsive">
<table class="table table-condensed table-hover table-items">
<thead>
<tr>
@@ -182,8 +188,66 @@
</tbody>
{% endfor %}
</table>
</div>
</div>
</form>
<form method="post" id="categories_table" hidden>
<p>
<button disabled
class="btn btn-default"><i class="fa fa-plus"></i> {% trans "Create a new product" %}</button>
<a href="{% url "control:event.items.categories.add" organizer=request.event.organizer.slug event=request.event.slug %}"
class="btn btn-default"><i class="fa fa-plus"></i> {% trans "Create a new category" %}</a>
<button class="btn btn-primary pull-right" id="btn_reorder_categories_done"><i class="fa fa-check"></i> {% trans "Done reordering categories" %}</button>
</p>
{% csrf_token %}
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>{% trans "Product categories" %}</th>
<th>{% trans "Category type" %}</th>
<th class="action-col-2"></th>
</tr>
</thead>
<tbody data-dnd-url="{% url "control:event.items.categories.reorder" organizer=request.event.organizer.slug event=request.event.slug %}">
{% for c, items in cat_list %}{% if c %}
<tr data-dnd-id="{{ c.id }}">
<td>
{% if 'event.items:write' in request.eventpermset %}
<strong><a href="{% url "control:event.items.categories.edit" organizer=request.event.organizer.slug event=request.event.slug category=c.id %}">{{ c.internal_name|default:c.name }}</a></strong>
{% else %}
<strong>{{ c.internal_name|default:c.name }}</strong>
{% endif %}
<br>
<small class="text-muted">
#{{ c.pk }}
</small>
</td>
<td>
{{ c.get_category_type_display }}
</td>
<td class="text-right flip">
{% if 'event.items:write' in request.eventpermset %}
<button title="{% trans "Move up" %}" formaction="{% url "control:event.items.categories.up" organizer=request.event.organizer.slug event=request.event.slug category=c.id %}" class="btn btn-default btn-sm sortable-up"{% if forloop.counter0 == 0 and not page_obj.has_previous %} disabled{% endif %}><i class="fa fa-arrow-up"></i></button>
<button title="{% trans "Move down" %}" formaction="{% url "control:event.items.categories.down" organizer=request.event.organizer.slug event=request.event.slug category=c.id %}" class="btn btn-default btn-sm sortable-down"{% if forloop.revcounter0 == 0 and not page_obj.has_next %} disabled{% endif %}><i class="fa fa-arrow-down"></i></button>
<span class="dnd-container" title="{% trans "Click and drag this button to reorder. Double click to show buttons for reordering." %}"></span>
<a title="{% trans "Edit" %}" href="{% url "control:event.items.categories.edit" organizer=request.event.organizer.slug event=request.event.slug category=c.id %}" class="btn btn-default btn-sm"><i class="fa fa-edit"></i></a>
<a href="{% url "control:event.items.categories.add" organizer=request.event.organizer.slug event=request.event.slug %}?copy_from={{ c.id }}"
class="btn btn-sm btn-default" title="{% trans "Clone" %}" data-toggle="tooltip">
<span class="fa fa-copy"></span>
</a>
<a title="{% trans "Delete" %}" href="{% url "control:event.items.categories.delete" organizer=request.event.organizer.slug event=request.event.slug category=c.id %}" class="btn btn-danger btn-sm"><i class="fa fa-trash"></i></a>
{% endif %}
</td>
</tr>
{% endif %}{% endfor %}
</tbody>
</table>
</div>
</form>
{% include "pretixcontrol/pagination.html" %}
{% endif %}
{% compress js %}
<script type="text/javascript" src="{% static "pretixcontrol/js/ui/items.js" %}"></script>
{% endcompress %}
{% endblock %}
-1
View File
@@ -329,7 +329,6 @@ urlpatterns = [
re_path(r'^items/select2/itemvar$', typeahead.itemvar_select2, name='event.items.itemvar.select2'),
re_path(r'^items/select2/itemvars$', typeahead.itemvars_select2, name='event.items.itemvars.select2'),
re_path(r'^items/select2/variation$', typeahead.variations_select2, name='event.items.variations.select2'),
re_path(r'^categories/$', item.CategoryList.as_view(), name='event.items.categories'),
re_path(r'^categories/select2$', typeahead.category_select2, name='event.items.categories.select2'),
re_path(r'^categories/(?P<category>\d+)/delete$', item.CategoryDelete.as_view(),
name='event.items.categories.delete'),
+5 -5
View File
@@ -244,7 +244,7 @@ class CategoryDelete(EventPermissionRequiredMixin, CompatDeleteView):
return HttpResponseRedirect(success_url)
def get_success_url(self) -> str:
return reverse('control:event.items.categories', kwargs={
return reverse('control:event.items', kwargs={
'organizer': self.request.event.organizer.slug,
'event': self.request.event.slug,
})
@@ -278,7 +278,7 @@ class CategoryUpdate(EventPermissionRequiredMixin, UpdateView):
return super().form_valid(form)
def get_success_url(self) -> str:
return reverse('control:event.items.categories', kwargs={
return reverse('control:event.items', kwargs={
'organizer': self.request.event.organizer.slug,
'event': self.request.event.slug,
})
@@ -296,7 +296,7 @@ class CategoryCreate(EventPermissionRequiredMixin, CreateView):
context_object_name = 'category'
def get_success_url(self) -> str:
return reverse('control:event.items.categories', kwargs={
return reverse('control:event.items', kwargs={
'organizer': self.request.event.organizer.slug,
'event': self.request.event.slug,
})
@@ -380,7 +380,7 @@ def category_move(request, category, up=True):
@require_http_methods(["POST"])
def category_move_up(request, organizer, event, category):
category_move(request, category, up=True)
return redirect('control:event.items.categories',
return redirect('control:event.items',
organizer=request.event.organizer.slug,
event=request.event.slug)
@@ -389,7 +389,7 @@ def category_move_up(request, organizer, event, category):
@require_http_methods(["POST"])
def category_move_down(request, organizer, event, category):
category_move(request, category, up=False)
return redirect('control:event.items.categories',
return redirect('control:event.items',
organizer=request.event.organizer.slug,
event=request.event.slug)
@@ -0,0 +1,11 @@
$("#btn_reorder_categories").click(function() {
$("#products_table").attr('hidden', '');
$("#categories_table").removeAttr('hidden');
return false;
});
$("#btn_reorder_categories_done").click(function() {
//$("#products_table").removeAttr('hidden');
//$("#categories_table").attr('hidden', '');
location=location;
return false;
});
@@ -810,6 +810,9 @@ tbody[data-dnd-url] {
display: table-row;
height: 0.5em;
}
.table-items thead + tbody[data-dnd-url]:not(:has(tr))::after {
height: 0; /* no spacing before first header, if no items without category */
}
.sortable-sorting tbody:not(.sortable-dragarea) {
opacity: .4;
}