diff --git a/src/api/views/events.py b/src/api/views/events.py index 41cd544e62ca1eb770bcf8babe93d71f1b39a43f..74a2d7f12be390ce593ce533ec2d1232201afc2c 100644 --- a/src/api/views/events.py +++ b/src/api/views/events.py @@ -1,6 +1,6 @@ -from rest_framework import generics - from core.models.events import Event +from django.shortcuts import get_object_or_404 +from rest_framework import generics from ..serializers import EventSerializer from .mixins import ConferenceSlugMixin @@ -10,12 +10,14 @@ class EventList(ConferenceSlugMixin, generics.ListAPIView): serializer_class = EventSerializer def get_queryset(self, **kwargs): - return Event.objects.filter(conference=self.conference).order_by('name') + return Event.objects.filter(conference=self.conference).order_by("name") class EventDetail(ConferenceSlugMixin, generics.RetrieveAPIView): serializer_class = EventSerializer def get_object(self, **kwargs): - event_id = self.request.resolver_match.kwargs['pk'] - return Event.objects.conference_accessible(conference=self.conference).get(pk=event_id) + event_id = self.request.resolver_match.kwargs["pk"] + return get_object_or_404( + Event.objects.conference_accessible(conference=self.conference), pk=event_id + ) diff --git a/src/api/views/schedule.py b/src/api/views/schedule.py index 80ad5e8159486b53f7eef65982a98395995b70d0..60263c5457b06d26284c5a4b73aced9d934beb29 100644 --- a/src/api/views/schedule.py +++ b/src/api/views/schedule.py @@ -69,11 +69,11 @@ class ConferenceSchedule(BaseScheduleView): class AssemblySchedule(BaseScheduleView): def get_cache_id(self): - assembly_id = self.request.resolver_match.get('assembly') + assembly_id = self.request.resolver_match.kwargs.get('assembly') return f'assembly_{assembly_id}' def get_events(self): - assembly_id = self.request.resolver_match.get('assembly') + assembly_id = self.request.resolver_match.kwargs.get('assembly') return Event.objects \ .conference_accessible(conference=self.conference) \ .select_related('track', 'room') \ @@ -83,11 +83,11 @@ class AssemblySchedule(BaseScheduleView): class RoomSchedule(BaseScheduleView): def get_cache_id(self): - room_id = self.request.resolver_match.get('pk') + room_id = self.request.resolver_match.kwargs.get('pk') return f'room-{room_id}' def get_events(self): - room_id = self.request.resolver_match.get('pk') + room_id = self.request.resolver_match.kwargs.get('pk') return Event.objects \ .conference_accessible(conference=self.conference) \ .filter(room_id=room_id) \ diff --git a/src/plainui/jinja2/plainui/base.html b/src/plainui/jinja2/plainui/base.html index 93ef10d0e372b8fd789300d45f515d2373279158..09deaf6f3bfd7b9fcd4b39f7d9a74fac9a75ca34 100644 --- a/src/plainui/jinja2/plainui/base.html +++ b/src/plainui/jinja2/plainui/base.html @@ -5,7 +5,7 @@ <html lang="{{ get_language() }}" class="no-js"> <head> <meta charset="utf-8"> - <link rel="stylesheet" href="{{ static('plainui/%s.css' % (css_scope(),)) }}?v=20320816_1000"> + <link rel="stylesheet" href="{{ static('plainui/%s.css' % (css_scope(),)) }}?v=20320817_0055"> <link rel="icon" href="{{ static('plainui/img/favicon.ico') }}" type="image/x-icon"> <title>{% block title %}{% endblock %}</title> <meta name="viewport" content="width=device-width, initial-scale=1"> diff --git a/src/plainui/jinja2/plainui/components/event_info.html b/src/plainui/jinja2/plainui/components/event_info.html index c6faa238a8c1ce4cafe60fb2c1421ec56cc21534..f1fe101fae68b1364387b3cfeec5b6558f0825cf 100644 --- a/src/plainui/jinja2/plainui/components/event_info.html +++ b/src/plainui/jinja2/plainui/components/event_info.html @@ -1,3 +1,4 @@ +{% import "plainui/components/function_btns.html" as fbtns with context %} {% import "plainui/components/image.html" as imageMacro %} {% macro eventInfo(event, speakers, assembly={}) -%} @@ -15,12 +16,20 @@ {% endif %} </figure> <dl class="grid-list mb-0 p-2"> + <dd class="d-flex justify-content-end"> + {% set link = url('plainui:event', event_slug=event.slug ) %} + {{ fbtns.schedule(event.id, is_scheduled, color="primary") }} + {{ fbtns.fav(event.id, "event", is_favorite, color="primary") }} + {{ fbtns.report(link, color="primary") }} + </dd> + {% if event.kind != 'official' %} <dt class="grid-list__item grid-list__item--title">{{ _("Typ") }}</dt> <dd class="grid-list__item grid-list__item--text"> {{ _("Selforganized Session") if event.kind == 'sos' else _("Assembly-Event") }} </dd> {% endif %} + <dt class="grid-list__item grid-list__item--title">{{ _("Time") }}</dt> <dd class="grid-list__item grid-list__item--text"> {% if event.schedule_start %} diff --git a/src/plainui/jinja2/plainui/components/list_events.html b/src/plainui/jinja2/plainui/components/list_events.html index 054ef1f430aabc551e4a9d6960a78bd0a52d210e..4720be0b7b3a0785896ab3d231f9e153cc44bd9f 100644 --- a/src/plainui/jinja2/plainui/components/list_events.html +++ b/src/plainui/jinja2/plainui/components/list_events.html @@ -10,11 +10,30 @@ {% macro list(events, my_favorite_events, my_scheduled_events, assembly_slug=None, msg_none=_("No entries available.")) -%} {% if events %} <ul class="list-unstyled d-flex flex-column gap-3 mb-0"> + {# using a list here to be able to set a value in the nested block #} + {% set ns = namespace(first_now_done=false) %} + {% for event in events %} - {{ list_el( event, - faved=true if event.id | safe in my_favorite_events, - scheduled=true if event.id | safe in my_scheduled_events, - first=loop.first ) }} + {% if event.schedule_end < now %} + {% set event_when = 'past' %} + {% elif event.schedule_start > now %} + {% set event_when = 'upcoming' %} + {% else %} + {% set event_when = 'now' %} + {% endif %} + + {{ list_el( + event, + faved=true if event.id | safe in my_favorite_events, + scheduled=true if event.id | safe in my_scheduled_events, + first=loop.first, + event_when=event_when, + first_now=true if event_when == 'now' and not ns.first_now_done + ) }} + + {% if event_when == 'now' %} + {% set ns.first_now_done = true %} + {% endif %} {% endfor %} </ul> {% else %} @@ -22,18 +41,14 @@ {% endif %} {%- endmacro %} -{% macro list_el(event, faved, scheduled, first) -%} +{% macro list_el(event, faved, scheduled, first, event_when, first_now) -%} {% set link = url('plainui:event', event_slug=event.slug ) %} {% set color="transparent" if event.kind == "official" else "transparent" %} - {% set is_past = event.schedule_end < now %} - {% set is_upcomping = event.schedule_start > now %} - {% set is_now = not is_past and not is_upcomping %} <li - class="hub-event rounded-3 px-3 py-2 - {% if is_past %}hub-event--past{% endif %} - {% if is_upcomping %}hub-event--upcoming{% endif %}" - > + class="hub-event rounded-3 px-3 py-2 hub-event--{{ event_when }}" + {% if first_now %}id="now"{% endif %} + > <div class="hub-event__day"> {{ _(event.schedule_start | weekday_abbrev) }} </div> @@ -47,7 +62,7 @@ {{ event.name }} </div> </a> - {% if is_now %} + {% if event_when == 'now' %} <div class="hub-event__now"> {{ _('NOW') }} </div> diff --git a/src/plainui/jinja2/plainui/event.html b/src/plainui/jinja2/plainui/event.html index d4ab353fe5eb8e98921c6ca90501916553dd0d55..780193c5b2f991e627d3da0d1cf0278dceb6cb31 100644 --- a/src/plainui/jinja2/plainui/event.html +++ b/src/plainui/jinja2/plainui/event.html @@ -1,5 +1,5 @@ {% import "plainui/components/markdown.html" as markdownMacro %} -{% import "plainui/components/event_info.html" as eventInfoMacro %} +{% import "plainui/components/event_info.html" as eventInfoMacro with context %} {% import "plainui/components/title.html" as titleMacro %} {% import "plainui/components/tagbox.html" as tagboxMacro %} {% import "plainui/components/resourcesbox.html" as resboxMacro %} diff --git a/src/plainui/jinja2/plainui/fahrplan.html b/src/plainui/jinja2/plainui/fahrplan.html index 9b0ca95404917c3503957a8b1aca6408e4d9b1bd..a22f778b1a4c2a440e3f604f6b4a5af24e215672 100644 --- a/src/plainui/jinja2/plainui/fahrplan.html +++ b/src/plainui/jinja2/plainui/fahrplan.html @@ -29,7 +29,7 @@ <a href="#" class="btn m-2">{{ _("QR-Code") }}</a> </div> #} - <form method="GET" class="p-3 mb-2 hub-fahrplan__filter-block bg-black"> + <form method="GET" action="#now" class="p-3 mb-2 hub-fahrplan__filter-block bg-black"> <input type="hidden" name="mode" value="{{mode}}"> {% if show_day_filters %}<input type="hidden" name="show_day_filters" value="y">{% endif %} {% if show_assembly_filters %}<input type="hidden" name="show_assembly_filters" value="y">{% endif %} diff --git a/src/plainui/jinja2/plainui/static_page.html b/src/plainui/jinja2/plainui/static_page.html index c2da82261904c649b3ecccbd289e6fe36487d9e6..2d40b7e395f3d5a577fe11316d827f804a580936 100644 --- a/src/plainui/jinja2/plainui/static_page.html +++ b/src/plainui/jinja2/plainui/static_page.html @@ -13,6 +13,15 @@ <div class="alert alert-warning">{{ _("This page does not exist.") }}</div> {%- endif %} {%- else %} + {%- if revision_not_found %} + <div class="alert d-flex align-items-center gap-3 bg-danger text-black my-8 lead fw-bold" role="alert"> + <img + class="w-100px" + src="{{ static('plainui/img/cccamp23/blanco_Fisty_for_directions_actions/Pointing_outer-hand_thumb-up-black.svg') }}" + > + {{ _("This revision does not exist.") }} + </div> + {%- endif %} {{ titleMacro.title(title=page.title) }} <div class="row"> <div class="col m-2 d-flex justify-content-start"> diff --git a/src/plainui/static/plainui/img/cccamp23/blanco_Fisty_for_directions_actions/Pointing_outer-hand_thumb-up-black.svg b/src/plainui/static/plainui/img/cccamp23/blanco_Fisty_for_directions_actions/Pointing_outer-hand_thumb-up-black.svg new file mode 100644 index 0000000000000000000000000000000000000000..cc8e68bc0a594d496efda71e26e7611bf3519cd5 --- /dev/null +++ b/src/plainui/static/plainui/img/cccamp23/blanco_Fisty_for_directions_actions/Pointing_outer-hand_thumb-up-black.svg @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Generator: Adobe Illustrator 27.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> + +<svg + version="1.1" + id="Ebene_1" + x="0px" + y="0px" + viewBox="0 0 405.8 191.72532" + xml:space="preserve" + width="405.79999" + height="191.72531" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"><defs + id="defs1" /> <style + type="text/css" + id="style1"> .st0{fill:#E50076;} </style> <g + id="g1" + transform="translate(-94.1,-201.77468)" + style="fill:#000000;fill-opacity:1"> <path + class="st0" + d="m 499.9,269.7 c 0,-12.9 -15.5,-12.1 -19.2,-12.1 -20.7,-0.1 -41.4,-0.1 -62.1,-0.1 v 0 c -22.1,0 -44.2,0.2 -66.3,-0.2 -3.8,-0.1 -9.6,-2.4 -10.9,-5.2 -1.3,-2.8 0.9,-8.2 3.3,-11.2 4.6,-5.7 10.7,-10.3 15.8,-15.6 5.9,-6.1 7.5,-12.6 1,-19.3 -5.4,-5.6 -13.7,-5.8 -20.2,0.4 -26.7,25.3 -54.4,49.8 -79.3,76.6 -3.1,3.4 -5.8,6.9 -8,10.6 l -72.9,-6.4 v 48.9 l -87,-5.8 124.5,63.2 v -38.3 l 45.7,17.1 c 9,9.2 21,15.9 35.4,18.2 31.2,5 64,2.2 96,1.7 4.2,-0.1 15.2,-1.4 14.6,-12.6 0,-12.3 -14.8,-12.7 -15.9,-13.4 -2.1,-1.3 -4.7,-0.7 -5.8,-4.6 -0.1,-2.8 4.3,-4 6.9,-4.6 3.6,-0.9 7.5,-0.3 11.3,-0.5 8.1,-0.4 12.9,-4.4 13.5,-12.2 0.6,-8 -4.4,-12.2 -12,-13.6 -4.4,-0.8 -9,-0.1 -13.4,-0.9 -2.2,-0.4 -5.8,-1.3 -6.2,-4.1 0.4,-3.3 4.2,-4.5 6.5,-4.7 7.2,-0.7 14.5,-0.2 21.7,-0.4 9.9,-0.3 16.2,-5.3 16.5,-12.9 0.3,-7.1 -6.5,-13.4 -15.8,-14 -5.5,-0.4 -11.1,0.4 -16.5,-0.4 -4.3,-0.6 -12.6,-0.7 -12.5,-4 -0.2,-2.9 8.6,-4.4 13,-4.6 16.5,-0.6 33.1,-0.1 49.7,-0.3 12.4,-0.1 25,0.3 37.2,-1.3 4.6,-0.5 11.4,-1.7 11.4,-13.4" + id="path1" + style="fill:#000000;fill-opacity:1" /> </g> </svg> diff --git a/src/plainui/styles/hub.scss b/src/plainui/styles/hub.scss index 7426d6812a1cb08aa957afd4940a9c7aace156cd..f71b6d94757c7c13b9cb303935840f82c84c5d6c 100644 --- a/src/plainui/styles/hub.scss +++ b/src/plainui/styles/hub.scss @@ -128,3 +128,7 @@ table.diff { } } } + +.w-100px { + width: 6.25rem; +} diff --git a/src/plainui/styles/variables/_colors.scss b/src/plainui/styles/variables/_colors.scss index f916f26728ef2628bf53b61fd415a7c9b3b63cce..de404a1b6bb8fef236fd7a0abb6775b3b940203b 100644 --- a/src/plainui/styles/variables/_colors.scss +++ b/src/plainui/styles/variables/_colors.scss @@ -19,8 +19,8 @@ $black: #000; // Colors $teal: #77CDDC; -$red: #fb48c4; -$purple: $red; +$red: #dc2626; +$purple: #fb48c4; $yellow: #e4c662; $green: #3fff21; $cyan: #1cabc4; diff --git a/src/plainui/views.py b/src/plainui/views.py index 88c96f6414b804148057e4db715d58870616bad4..5a1e9f46d2276b76044bf4b00efd84db18fa8dbc 100644 --- a/src/plainui/views.py +++ b/src/plainui/views.py @@ -17,9 +17,10 @@ from django.contrib.sites.shortcuts import get_current_site from django.core.exceptions import PermissionDenied, ValidationError, ImproperlyConfigured from django.core import signing from django.core.mail import EmailMessage +from django.core.exceptions import SuspiciousOperation from django.db import transaction, connection from django.db.models import Q, F, Prefetch -from django.http import Http404, HttpResponseBadRequest, HttpResponseRedirect, HttpResponseNotFound, HttpResponse, HttpResponseForbidden +from django.http import Http404, HttpResponseRedirect, HttpResponseNotFound, HttpResponse, HttpResponseForbidden from django.shortcuts import redirect, get_object_or_404 from django.template.loader import render_to_string from django.urls import reverse, reverse_lazy, translate_url, NoReverseMatch @@ -488,12 +489,18 @@ class StaticPageView(ConferenceRequiredMixin, TemplateView): context['page_can_create'] = False revision = self.request.GET.get('rev') if revision: - static_page_revision = static_page.revisions.get(revision=revision) - page_body = render_markdown(static_page_revision.body) - if can_edit: - context['edit_url'] = reverse('plainui:static_page_edit', kwargs={'page_slug': page_slug}) + ('?rev=' + revision if revision else '') - else: - context['edit_url'] = None + try: + static_page_revision = static_page.revisions.get(revision=revision) + page_body = render_markdown(static_page_revision.body) + if can_edit: + context["edit_url"] = reverse( + "plainui:static_page_edit", kwargs={"page_slug": page_slug} + ) + ("?rev=" + revision if revision else "") + else: + context["edit_url"] = None + except StaticPageRevision.DoesNotExist: + context["revision_not_found"] = True + page_body = static_page.body_html else: page_body = static_page.body_html context['edit_url'] = reverse('plainui:static_page_edit', kwargs={'page_slug': page_slug}) if can_edit else None @@ -694,13 +701,13 @@ class StaticPageDiffView(ConferenceRequiredMixin, TemplateView): rev2_id = self.request.GET.get('rev2') if rev1_id is None or rev2_id is None: - return HttpResponseBadRequest() + raise SuspiciousOperation("Only one revision given, need two") try: rev1 = self.static_page.revisions.get(revision=rev1_id) rev2 = self.static_page.revisions.get(revision=rev2_id) except StaticPageRevision.DoesNotExist: - return HttpResponseNotFound() + raise Http404("One of the selected revisions was not found") differ = StaticPageDiff(tabsize=4) diff = differ.make_table(rev1.body.splitlines(keepends=True), rev2.body.splitlines(keepends=True), context=True, numlines=3) @@ -1740,6 +1747,7 @@ def _event_filter( filters['room__is_public_fahrplan'] = public_fahrplan events = Event.objects.conference_accessible(conf) + events = events.filter(schedule_start__isnull=False, schedule_end__isnull=False) if upcoming: now = timezone.now() events = events.filter(Q(schedule_start__lt=now, schedule_end__gte=now) | Q(schedule_start__gte=now, schedule_start__lt=now + UPCOMING_WINDOW))