Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eventyay Common: Create an event dashboard #505

Merged
merged 24 commits into from
Jan 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{% load i18n %}
<div class="navigation-button">
{% if request.organizer and request.event %}
<a href='{% url "eventyay_common:event.update" organizer=request.organizer.slug event=request.event.slug %}' class="header-nav btn btn-outline-success">
<a href='{% url "eventyay_common:event.index" organizer=request.organizer.slug event=request.event.slug %}' class="header-nav btn btn-outline-success">
<i class="fa fa-home"></i> {% trans "Home" %}
</a>
<a href="#" class="header-nav btn btn-outline-success active">
<i class="fa fa-ticket"></i> {% trans "Tickets" %}
</a>
{% if is_talk_event_created %}
<a href="{{ talk_edit_url }}" class="header-nav btn btn-outline-success">
<a href="{{ request.event.talk_dashboard_url }}" class="header-nav btn btn-outline-success">
<i class="fa fa-group"></i> {% trans "Talk" %}
</a>
{% endif %}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
{% load i18n %}
<div class="panel-heading">
<h3 class="panel-title">
{% trans "Event organizer" %}
</h3>
</div>
<div class="panel-body timeline">
<div class="info-row">
{% trans "This event is organized by" %} <strong><a href="{% url 'control:organizer' request.organizer.slug %}">{{ request.organizer }}</a></strong>
<div class="panel panel-default items widget-container widget-small no-padding last-column">
<div class="panel-heading">
<h3 class="panel-title">
{% trans "Event organizer" %}
</h3>
</div>
<div class="info-row">
{% trans "Teams of the organizer are" %}
<span></span>
{% for id, name in organizer_teams %}
<strong><a href="{% url 'control:organizer.team' request.organizer.slug id %}">{{ name }}</a></strong>
{% if not forloop.last %}, {% endif %}
{% endfor %}
<div class="panel-body timeline overide-panel-body">
<div class="info-row">
{% trans "This event is organized by" %} <strong><a href="{% url 'control:organizer' request.organizer.slug %}">{{ request.organizer }}</a></strong>
</div>
<div class="info-row">
{% trans "Teams of the organizer are" %}
<span></span>
{% for id, name in organizer_teams %}
<strong><a href="{% url 'control:organizer.team' request.organizer.slug id %}">{{ name }}</a></strong>
{% if not forloop.last %}, {% endif %}
{% endfor %}
</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -1,34 +1,36 @@
{% load i18n %}
<div class="panel-heading">
<h3 class="panel-title">
{% trans "Your timeline" %}
</h3>
</div>
<div class="panel-body timeline">
{% regroup timeline by date as tl_list %}
{% for day in tl_list %}
<div class="row {% if day.grouper < today %}text-muted{% endif %}">
<div class="col-date">
<strong>{{ day.grouper|date:"SHORT_DATE_FORMAT" }}</strong>
</div>
<div class="col-event">
{% for e in day.list %}
<strong class="">{{ e.time|date:"TIME_FORMAT" }}</strong>
&nbsp;
<span class="{% if e.time < nearly_now %}text-muted{% endif %}">
{{ e.entry.description }}
</span>
{% if e.entry.edit_url %}
<div class="panel panel-default items widget-container widget-small no-padding column">
<div class="panel-heading">
<h3 class="panel-title">
{% trans "Your timeline" %}
</h3>
</div>
<div class="panel-body timeline overide-panel-body">
{% regroup timeline by date as tl_list %}
{% for day in tl_list %}
<div class="row {% if day.grouper < today %}text-muted{% endif %}">
<div class="col-date">
<strong>{{ day.grouper|date:"SHORT_DATE_FORMAT" }}</strong>
</div>
<div class="col-event">
{% for e in day.list %}
<strong class="">{{ e.time|date:"TIME_FORMAT" }}</strong>
&nbsp;
<a href="{{ e.entry.edit_url }}" class="text-muted">
<span class="fa fa-edit"></span>
</a>
{% endif %}
{% if forloop.revcounter > 1 %}
<br/>
{% endif %}
{% endfor %}
<span class="{% if e.time < nearly_now %}text-muted{% endif %}">
{{ e.entry.description }}
</span>
{% if e.entry.edit_url %}
&nbsp;
<a href="{{ e.entry.edit_url }}" class="text-muted">
<span class="fa fa-edit"></span>
</a>
{% endif %}
{% if forloop.revcounter > 1 %}
<br/>
{% endif %}
{% endfor %}
</div>
</div>
</div>
{% endfor %}
{% endfor %}
</div>
</div>
8 changes: 2 additions & 6 deletions src/pretix/control/templates/pretixcontrol/event/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,9 @@ <h3 class="panel-title">
{% endif %}
<div class="dashboard custom">
{% if not request.event.has_subevents or subevent %}
<div class="panel panel-default items widget-container widget-small no-padding column"">
{% include "pretixcontrol/event/fragment_timeline.html" %}
</div>
{% include "pretixcontrol/event/fragment_timeline.html" %}
{% endif %}
<div class="panel panel-default items widget-container widget-small no-padding last-column"">
{% include "pretixcontrol/event/fragment_info_box.html" %}
</div>
{% include "pretixcontrol/event/fragment_info_box.html" %}
</div>
<div class="dashboard">
{% for w in widgets %}
Expand Down
164 changes: 93 additions & 71 deletions src/pretix/eventyay_common/context.py
Original file line number Diff line number Diff line change
@@ -1,98 +1,120 @@
from importlib import import_module
import logging
from urllib.parse import urljoin

from django.conf import settings
from django.db.models import Q
from django.urls import Resolver404, get_script_prefix, resolve, reverse
from django.utils.translation import gettext_lazy as _
from django.http import HttpRequest
from django.urls import Resolver404, get_script_prefix, resolve
from django_scopes import scope

from pretix.base.models.auth import StaffSession
from pretix.base.settings import GlobalSettingsObject
from pretix.control.navigation import merge_in
from pretix.control.signals import nav_global
from pretix.eventyay_common.navigation import (
get_event_navigation, get_global_navigation,
)

SessionStore = import_module(settings.SESSION_ENGINE).SessionStore
from ..helpers.plugin_enable import is_video_enabled
from ..multidomain.urlreverse import get_event_domain
from .views.event import EventCreatedFor

logger = logging.getLogger(__name__)

def contextprocessor(request):
"""
Adds data to all template contexts
"""
if not hasattr(request, '_eventyay_common_default_context'):

def contextprocessor(request: HttpRequest):
if not hasattr(request, "_eventyay_common_default_context"):
request._eventyay_common_default_context = _default_context(request)
return request._eventyay_common_default_context


def _default_context(request):
def _default_context(request: HttpRequest):
try:
url = resolve(request.path_info)
except Resolver404:
return {}

if not request.path.startswith(get_script_prefix() + 'common'):
if not request.path.startswith(f"{get_script_prefix()}common"):
return {}
ctx = {
'url_name': url.url_name,
'settings': settings,
'django_settings': settings,
'DEBUG': settings.DEBUG,
"url_name": url.url_name,
"settings": settings,
"django_settings": settings,
"DEBUG": settings.DEBUG,
"talk_hostname": settings.TALK_HOSTNAME,
}
if getattr(request, 'event', None) and hasattr(request, 'organizer') and request.user.is_authenticated:
ctx['nav_items'] = get_global_navigation(request)

elif request.user.is_authenticated:
ctx['nav_items'] = get_global_navigation(request)

gs = GlobalSettingsObject()
ctx['global_settings'] = gs.settings

if request.user.is_authenticated:
ctx['staff_session'] = request.user.has_active_staff_session(request.session.session_key)
ctx['staff_need_to_explain'] = (
StaffSession.objects.filter(user=request.user, date_end__isnull=False).filter(
Q(comment__isnull=True) | Q(comment="")
ctx["global_settings"] = gs.settings

if not request.user.is_authenticated:
return ctx

ctx["nav_items"] = get_global_navigation(request)
ctx["staff_session"] = request.user.has_active_staff_session(
request.session.session_key
)
ctx["staff_need_to_explain"] = (
StaffSession.objects.filter(user=request.user, date_end__isnull=False).filter(
Q(comment__isnull=True) | Q(comment="")
)
if request.user.is_staff and settings.PRETIX_ADMIN_AUDIT_COMMENTS
else StaffSession.objects.none()
)

# Verify if the request includes an event
event = getattr(request, "event", None)
if not event:
return ctx

ctx["talk_edit_url"] = urljoin(settings.TALK_HOSTNAME, f"orga/event/{event.slug}")
ctx["is_video_enabled"] = is_video_enabled(event)
ctx["is_talk_event_created"] = False
if (
event.settings.create_for == EventCreatedFor.BOTH.value
or event.settings.talk_schedule_public is not None
):
ctx["is_talk_event_created"] = True

# Verify if the request includes an organizer
organizer = getattr(request, "organizer", None)
if not organizer:
return ctx

ctx["nav_items"] = get_event_navigation(request, event)
ctx["has_domain"] = get_event_domain(event, fallback=True) is not None
if not event.testmode:
with scope(organizer=organizer):
complain_testmode_orders = event.cache.get("complain_testmode_orders")
if complain_testmode_orders is None:
complain_testmode_orders = event.orders.filter(testmode=True).exists()
event.cache.set(
"complain_testmode_orders", complain_testmode_orders, 30
)
ctx["complain_testmode_orders"] = (
complain_testmode_orders
and request.user.has_event_permission(
organizer, event, "can_view_orders", request=request
)
if request.user.is_staff and settings.PRETIX_ADMIN_AUDIT_COMMENTS else StaffSession.objects.none()
)

ctx['talk_hostname'] = settings.TALK_HOSTNAME
else:
ctx["complain_testmode_orders"] = False

if not event.live and ctx["has_domain"]:
child_sess_key = f"child_session_{event.pk}"
child_sess = request.session.get(child_sess_key)

if not child_sess:
request.session[child_sess_key] = request.session.session_key
else:
ctx["new_session"] = child_sess
request.session["event_access"] = True

if request.GET.get("subevent", ""):
subevent_id = request.GET.get("subevent", "").strip()
try:
pk = int(subevent_id)
# Do not use .get() for lazy evaluation
ctx["selected_subevents"] = event.subevents.filter(pk=pk)
except ValueError as e:
logger.error("Error parsing subevent ID: %s", e)

return ctx


def get_global_navigation(request):
url = request.resolver_match
if not url:
return []
nav = [
{
'label': _('Dashboard'),
'url': reverse('eventyay_common:dashboard'),
'active': (url.url_name == 'dashboard'),
'icon': 'dashboard',
},
{
'label': _('My Events'),
'url': reverse('eventyay_common:events'),
'active': 'events' in url.url_name,
'icon': 'calendar',
},
{
'label': _('Organizers'),
'url': reverse('eventyay_common:organizers'),
'active': 'organizers' in url.url_name,
'icon': 'group',
},
{
'label': _('Account'),
'url': reverse('eventyay_common:account'),
'active': 'account' in url.url_name,
'icon': 'user',
}

]

merge_in(nav, sorted(
sum((list(a[1]) for a in nav_global.send(request, request=request)), []),
key=lambda r: (1 if r.get('parent') else 0, r['label'])
))
return nav
Loading
Loading