From fbfbd702d39fecb8648ff06bf90bdc5a98f4ee07 Mon Sep 17 00:00:00 2001 From: Felix Rindt Date: Sun, 22 Dec 2024 11:43:35 +0100 Subject: [PATCH 1/6] show-participant-data and API --- ephios/api/filters.py | 22 ++++- ephios/core/forms/events.py | 2 +- .../0033_eventtype_show_participant_data.py | 26 ++++++ ephios/core/models/events.py | 10 +++ tests/api/test_participation_list.py | 84 ++++++++++++++++++- 5 files changed, 140 insertions(+), 4 deletions(-) create mode 100644 ephios/core/migrations/0033_eventtype_show_participant_data.py diff --git a/ephios/api/filters.py b/ephios/api/filters.py index d567161ba..ca5d945cc 100644 --- a/ephios/api/filters.py +++ b/ephios/api/filters.py @@ -11,9 +11,27 @@ class ParticipationPermissionFilter(BaseFilterBackend): def filter_queryset(self, request, queryset, view): # to view public participation information (excl. email) you need to - # be able to see the event + # * be able to see the event AND + # * the event types' show_participation_data mode must fit viewable_events = get_objects_for_user(request.user, "core.view_event") - return queryset.filter(shift__event__in=viewable_events) + editable_events = get_objects_for_user(request.user, "core.change_event") + participating_events = Event.objects.filter( + shifts__participations__in=request.user.participations.filter( + state=AbstractParticipation.States.CONFIRMED + ) + ) + qs = queryset.filter(shift__event__in=viewable_events).filter( + Q( + shift__event__type__show_participant_data=EventType.ShowParticipantDataChoices.EVERYONE + ) + | Q( + shift__event__type__show_participant_data=EventType.ShowParticipantDataChoices.CONFIRMED, + shift__event__in=participating_events, + ) + | Q(shift__event__in=editable_events) + | Q(localparticipation__user=request.user) + ) + return qs.distinct() class UserinfoParticipationPermissionFilter(ParticipationPermissionFilter): diff --git a/ephios/core/forms/events.py b/ephios/core/forms/events.py index e907adf96..8f9ae291e 100644 --- a/ephios/core/forms/events.py +++ b/ephios/core/forms/events.py @@ -267,7 +267,7 @@ def __init__(self, *args, **kwargs): class EventTypeForm(forms.ModelForm): class Meta: model = EventType - fields = ["title", "color"] + fields = ["title", "color", "show_participant_data"] widgets = {"color": ColorInput()} def clean_color(self): diff --git a/ephios/core/migrations/0033_eventtype_show_participant_data.py b/ephios/core/migrations/0033_eventtype_show_participant_data.py new file mode 100644 index 000000000..6be9eae42 --- /dev/null +++ b/ephios/core/migrations/0033_eventtype_show_participant_data.py @@ -0,0 +1,26 @@ +# Generated by Django 5.0.9 on 2024-12-22 09:57 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("core", "0032_shift_label"), + ] + + operations = [ + migrations.AddField( + model_name="eventtype", + name="show_participant_data", + field=models.SmallIntegerField( + choices=[ + (0, "to everyone"), + (1, "to confirmed participants"), + (2, "only to responsible users"), + ], + default=0, + verbose_name="show participant data", + ), + ), + ] diff --git a/ephios/core/models/events.py b/ephios/core/models/events.py index d8d1375b0..8787b7729 100644 --- a/ephios/core/models/events.py +++ b/ephios/core/models/events.py @@ -45,8 +45,18 @@ def get_queryset(self): class EventType(Model): + class ShowParticipantDataChoices(models.IntegerChoices): + EVERYONE = 0, _("to everyone") + CONFIRMED = 1, _("to confirmed participants") + RESPONSIBLES = 2, _("only to responsible users") + title = CharField(_("title"), max_length=254) color = CharField(_("color"), max_length=7, default="#343a40") + show_participant_data = models.SmallIntegerField( + verbose_name=_("show participant data"), + choices=ShowParticipantDataChoices.choices, + default=ShowParticipantDataChoices.EVERYONE, + ) class Meta: verbose_name = _("event type") diff --git a/tests/api/test_participation_list.py b/tests/api/test_participation_list.py index 841af9024..75c8e2e86 100644 --- a/tests/api/test_participation_list.py +++ b/tests/api/test_participation_list.py @@ -1,6 +1,88 @@ from django.urls import reverse -from ephios.core.models import AbstractParticipation, LocalParticipation +from ephios.core.models import AbstractParticipation, EventType, LocalParticipation + + +def test_show_participation_data_filter(django_app, volunteer, event, planner): + LocalParticipation.objects.create( + user=planner, shift=event.shifts.first(), state=AbstractParticipation.States.CONFIRMED + ) + assert ( + django_app.get( + reverse("api:participations-list"), + user=volunteer, + ).json["count"] + == 1 + ) + + event.type.show_participant_data = EventType.ShowParticipantDataChoices.CONFIRMED + event.type.save() + assert ( + django_app.get( + reverse("api:participations-list"), + user=volunteer, + ).json["count"] + == 0 + ) + assert ( + django_app.get( + reverse("api:participations-list"), + user=planner, + ).json["count"] + == 1 + ) + + event.type.show_participant_data = EventType.ShowParticipantDataChoices.RESPONSIBLES + event.type.save() + assert ( + django_app.get( + reverse("api:participations-list"), + user=volunteer, + ).json["count"] + == 0 + ) + assert ( + django_app.get( + reverse("api:participations-list"), + user=planner, + ).json["count"] + == 1 + ) + + LocalParticipation.objects.create( + user=volunteer, shift=event.shifts.first(), state=AbstractParticipation.States.CONFIRMED + ) + assert ( + django_app.get( + reverse("api:participations-list"), + user=volunteer, + ).json["count"] + == 1 + ) + assert ( + django_app.get( + reverse("api:participations-list"), + user=planner, + ).json["count"] + == 2 + ) + + event.type.show_participant_data = EventType.ShowParticipantDataChoices.CONFIRMED + event.type.save() + assert ( + django_app.get( + reverse("api:participations-list"), + user=volunteer, + ).json["count"] + == 2 + ) + assert ( + django_app.get( + reverse("api:participations-list"), + user=planner, + ).json["count"] + == 2 + ) def test_participation_permissions(django_app, volunteer, event, planner, manager, groups): From 6a221fca90b5db2c76ffcdc0ce38b80239af7551 Mon Sep 17 00:00:00 2001 From: Felix Rindt Date: Sun, 22 Dec 2024 12:20:23 +0100 Subject: [PATCH 2/6] hide data in frontend --- ephios/api/filters.py | 20 +--------- ephios/api/views/users.py | 8 ++-- ephios/core/models/events.py | 38 +++++++++++++++---- ephios/core/views/event.py | 18 ++++++++- .../participation_card_inline.html | 27 +++++++++---- 5 files changed, 71 insertions(+), 40 deletions(-) diff --git a/ephios/api/filters.py b/ephios/api/filters.py index ca5d945cc..9d210f9b6 100644 --- a/ephios/api/filters.py +++ b/ephios/api/filters.py @@ -13,25 +13,7 @@ def filter_queryset(self, request, queryset, view): # to view public participation information (excl. email) you need to # * be able to see the event AND # * the event types' show_participation_data mode must fit - viewable_events = get_objects_for_user(request.user, "core.view_event") - editable_events = get_objects_for_user(request.user, "core.change_event") - participating_events = Event.objects.filter( - shifts__participations__in=request.user.participations.filter( - state=AbstractParticipation.States.CONFIRMED - ) - ) - qs = queryset.filter(shift__event__in=viewable_events).filter( - Q( - shift__event__type__show_participant_data=EventType.ShowParticipantDataChoices.EVERYONE - ) - | Q( - shift__event__type__show_participant_data=EventType.ShowParticipantDataChoices.CONFIRMED, - shift__event__in=participating_events, - ) - | Q(shift__event__in=editable_events) - | Q(localparticipation__user=request.user) - ) - return qs.distinct() + return queryset.viewable_by(request.user) class UserinfoParticipationPermissionFilter(ParticipationPermissionFilter): diff --git a/ephios/api/views/users.py b/ephios/api/views/users.py index d07eab3b9..08f615692 100644 --- a/ephios/api/views/users.py +++ b/ephios/api/views/users.py @@ -22,7 +22,7 @@ UserinfoParticipationSerializer, UserProfileSerializer, ) -from ephios.core.models import LocalParticipation, UserProfile +from ephios.core.models import AbstractParticipation, LocalParticipation, UserProfile class UserProfileMeView(RetrieveAPIView): @@ -81,6 +81,6 @@ class UserParticipationView(viewsets.ReadOnlyModelViewSet): required_scopes = ["CONFIDENTIAL_READ"] def get_queryset(self): - return LocalParticipation.objects.filter(user=self.kwargs.get("user")).select_related( - "shift", "shift__event", "shift__event__type" - ) + return AbstractParticipation.objects.filter( + localparticipation__user=self.kwargs.get("user") + ).select_related("shift", "shift__event", "shift__event__type") diff --git a/ephios/core/models/events.py b/ephios/core/models/events.py index 8787b7729..e25d6002d 100644 --- a/ephios/core/models/events.py +++ b/ephios/core/models/events.py @@ -12,6 +12,7 @@ JSONField, Manager, Model, + Q, SlugField, TextField, ) @@ -23,9 +24,10 @@ from django.utils.translation import gettext_lazy as _ from django.utils.translation import pgettext from dynamic_preferences.models import PerInstancePreferenceModel -from guardian.shortcuts import assign_perm +from guardian.shortcuts import assign_perm, get_objects_for_user from polymorphic.managers import PolymorphicManager from polymorphic.models import PolymorphicModel +from polymorphic.query import PolymorphicQuerySet from ephios.core.signup.stats import SignupStats from ephios.extra.json import CustomJSONDecoder, CustomJSONEncoder @@ -138,15 +140,35 @@ def activate(self): register_model_for_logging(Event, ModelFieldsLogConfig()) +class ParticipationQuerySet(PolymorphicQuerySet): + + def viewable_by(self, user): + viewable_events = get_objects_for_user(user, "core.view_event") + editable_events = get_objects_for_user(user, "core.change_event") + participating_events = Event.objects.filter( + shifts__participations__in=user.participations.filter( + state=AbstractParticipation.States.CONFIRMED + ) + ) + qs = self.filter(shift__event__in=viewable_events).filter( + Q( + shift__event__type__show_participant_data=EventType.ShowParticipantDataChoices.EVERYONE + ) + | Q( + shift__event__type__show_participant_data=EventType.ShowParticipantDataChoices.CONFIRMED, + shift__event__in=participating_events, + ) + | Q(shift__event__in=editable_events) + | Q(localparticipation__user=user) + ) + return qs.distinct() + + class ParticipationManager(PolymorphicManager): def get_queryset(self): - return ( - super() - .get_queryset() - .annotate( - start_time=Coalesce("individual_start_time", "shift__start_time"), - end_time=Coalesce("individual_end_time", "shift__end_time"), - ) + return ParticipationQuerySet(self.model, using=self._db).annotate( + start_time=Coalesce("individual_start_time", "shift__start_time"), + end_time=Coalesce("individual_end_time", "shift__end_time"), ) diff --git a/ephios/core/views/event.py b/ephios/core/views/event.py index 5a9c56096..d03dd9aa6 100644 --- a/ephios/core/views/event.py +++ b/ephios/core/views/event.py @@ -446,7 +446,23 @@ def get_queryset(self): base = Event.objects.all() if self.request.user.has_perm("core.add_event"): base = Event.all_objects.all() - return base.prefetch_related("shifts", "shifts__participations") + return base.prefetch_related("shifts").prefetch_related( + Prefetch( + "shifts__participations", + queryset=AbstractParticipation.objects.all().annotate( + show_participant_data=Case( + When( + id__in=AbstractParticipation.objects.all().viewable_by( + self.request.user + ), + then=True, + ), + default=False, + output_field=BooleanField(), + ) + ), + ) + ) def get_context_data(self, **kwargs): kwargs["can_change_event"] = self.request.user.has_perm("core.change_event", self.object) diff --git a/ephios/plugins/baseshiftstructures/templates/baseshiftstructures/participation_card_inline.html b/ephios/plugins/baseshiftstructures/templates/baseshiftstructures/participation_card_inline.html index 0cabea196..1fc5b8f18 100644 --- a/ephios/plugins/baseshiftstructures/templates/baseshiftstructures/participation_card_inline.html +++ b/ephios/plugins/baseshiftstructures/templates/baseshiftstructures/participation_card_inline.html @@ -2,9 +2,14 @@ {% load user_extras %} {% load i18n %} +
{{ participation.participant.icon }} - {{ participation.participant }} + {% if participation.show_participant_data %} + {{ participation.participant }} + {% else %} + {% translate "Anonymous" %} + {% endif %}
@@ -23,12 +28,14 @@ {% endif %} {% endif %}
- {% if participation.participant.is_minor %} - {% translate "Minor" %} + {% if participation.show_participant_data %} + {% if participation.participant.is_minor %} + {% translate "Minor" %} + {% endif %} + {% for abbreviation in participation.participant.qualifications|qualifications_to_essential_abbreviations %} + {{ abbreviation }} + {% endfor %} {% endif %} - {% for abbreviation in participation.participant.qualifications|qualifications_to_essential_abbreviations %} - {{ abbreviation }} - {% endfor %}
@@ -53,5 +60,9 @@ {% else %} {% endif %} - {{ participation.participant }} - \ No newline at end of file + {% if participation.show_participant_data %} + {{ participation.participant }} + {% else %} + + {% endif %} + From 17aebea4b55515d501c5cc0ba3277417b9248340 Mon Sep 17 00:00:00 2001 From: Felix Rindt Date: Sun, 22 Dec 2024 12:27:35 +0100 Subject: [PATCH 3/6] docs and translate --- docs/user/events/events.rst | 15 +- ephios/locale/de/LC_MESSAGES/django.po | 263 ++++++++++++++----------- 2 files changed, 155 insertions(+), 123 deletions(-) diff --git a/docs/user/events/events.rst b/docs/user/events/events.rst index 9e860554e..2c03cbcd5 100644 --- a/docs/user/events/events.rst +++ b/docs/user/events/events.rst @@ -7,8 +7,8 @@ Shifts can be continuous and overlapping. While permissions are managed on event level, signup settings are configured on shift level. -Responsibles and visibility ---------------------------- +Responsibles and event visibility +--------------------------------- Single users and groups can be made responsible for an event. That allows them to edit event details, shift settings and do the disposition for the event's shifts. @@ -22,7 +22,16 @@ Event types ----------- Event types are used for organizing events into different categories. They can be used in filters -and come with defaults for visibility and responsibility settings. +and come with defaults for event visibility and responsibility settings. + +Showing participant data +------------------------ + +For every event type you can configure who can view the names of +participants in events of that type. +By default, participant data is visible to everyone. +You can restrict it to people who have a confirmed participation in any of the event's shift. +The most strict option is to only show participant data to the event's responsibles. Settings -------- diff --git a/ephios/locale/de/LC_MESSAGES/django.po b/ephios/locale/de/LC_MESSAGES/django.po index 5e2992fdc..0c8ded782 100644 --- a/ephios/locale/de/LC_MESSAGES/django.po +++ b/ephios/locale/de/LC_MESSAGES/django.po @@ -2,13 +2,13 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. -# +# msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-11-29 09:24+0100\n" -"PO-Revision-Date: 2024-11-28 12:21+0100\n" +"POT-Creation-Date: 2024-12-22 12:25+0100\n" +"PO-Revision-Date: 2024-12-22 12:27+0100\n" "Last-Translator: Felix Rindt \n" "Language-Team: German \n" @@ -50,11 +50,11 @@ msgstr "Token ist zu alt, um angezeigt werden zu können." msgid "Token was revoked." msgstr "Token wurde entfernt." -#: ephios/api/filters.py:44 ephios/core/models/events.py:257 +#: ephios/api/filters.py:44 ephios/core/models/events.py:289 msgid "start time" msgstr "Beginn" -#: ephios/api/filters.py:45 ephios/core/models/events.py:258 +#: ephios/api/filters.py:45 ephios/core/models/events.py:290 msgid "end time" msgstr "Ende" @@ -69,8 +69,8 @@ msgid "start time less than equals (deprecated, use start_time_before instead)" msgstr "" "Startzeit kleiner-gleich (deprecated, stattdessen start_time_before nutzen)" -#: ephios/api/filters.py:61 ephios/core/models/events.py:52 -#: ephios/core/models/events.py:64 ephios/core/views/event.py:59 +#: ephios/api/filters.py:61 ephios/core/models/events.py:64 +#: ephios/core/models/events.py:76 ephios/core/views/event.py:60 msgid "event type" msgstr "Veranstaltungstyp" @@ -116,7 +116,7 @@ msgstr "API Token hinzufügen" #: ephios/api/templates/oauth2_provider/application_form.html:27 #: ephios/core/forms/users.py:197 ephios/core/forms/users.py:440 #: ephios/core/templates/core/disposition/disposition.html:125 -#: ephios/core/templates/core/event_detail.html:29 +#: ephios/core/templates/core/event_detail.html:25 #: ephios/core/templates/core/event_form.html:65 #: ephios/core/templates/core/eventtype_form.html:20 #: ephios/core/templates/core/identityprovider_form.html:16 @@ -237,9 +237,10 @@ msgstr "" #: ephios/api/templates/api/access_token_reveal.html:26 #: ephios/api/templates/oauth2_provider/application_detail.html:15 #: ephios/api/templates/oauth2_provider/application_detail.html:34 +#: ephios/core/templates/core/event_copy.html:31 #: ephios/core/templates/core/fragments/shift_header.html:62 #: ephios/core/templates/core/settings/settings_calendar.html:19 -#: ephios/extra/templates/extra/widgets/recurrence_picker.html:218 +#: ephios/core/templates/core/shift_copy.html:34 #: ephios/plugins/federation/templates/federation/invitecode_reveal.html:27 #: ephios/plugins/federation/templates/federation/invitecode_reveal.html:38 msgid "Copy" @@ -346,11 +347,13 @@ msgstr "Benutzer" #: ephios/api/templates/oauth2_provider/application_form.html:25 #: ephios/core/templates/core/event_bulk_delete.html:23 #: ephios/core/templates/core/event_confirm_delete.html:16 +#: ephios/core/templates/core/event_copy.html:29 #: ephios/core/templates/core/event_form.html:64 #: ephios/core/templates/core/eventtype_confirm_delete.html:8 #: ephios/core/templates/core/group_confirm_delete.html:18 #: ephios/core/templates/core/identityprovider_confirm_delete.html:13 #: ephios/core/templates/core/shift_confirm_delete.html:16 +#: ephios/core/templates/core/shift_copy.html:32 #: ephios/core/templates/core/userprofile_confirm_delete.html:20 #: ephios/core/templates/core/userprofile_confirm_password_reset.html:19 #: ephios/core/templates/core/userprofile_confirm_password_token_revokation.html:21 @@ -447,8 +450,8 @@ msgstr "Föderation verwalten" #: ephios/api/templates/oauth2_provider/application_list.html:46 #: ephios/core/templates/core/event_form.html:20 -#: ephios/core/templates/core/home.html:60 -#: ephios/core/templates/core/home.html:105 +#: ephios/core/templates/core/home.html:58 +#: ephios/core/templates/core/home.html:102 #: ephios/core/templates/core/workinghours_list.html:42 #: ephios/plugins/pages/templates/pages/page_list.html:21 msgid "View" @@ -627,7 +630,7 @@ msgstr "Verantwortliche" #: ephios/core/pdf.py:137 ephios/core/pdf.py:183 #: ephios/core/templates/core/fragments/shift_box_small.html:22 #: ephios/core/templates/core/userprofile_workinghours.html:25 -#: ephios/core/views/event.py:67 ephios/core/views/event.py:76 +#: ephios/core/views/event.py:68 ephios/core/views/event.py:77 #: ephios/core/views/log.py:35 msgid "Date" msgstr "Datum" @@ -861,140 +864,156 @@ msgstr "Dienst" msgid "Training" msgstr "Ausbildung" -#: ephios/core/models/events.py:48 ephios/core/models/events.py:61 +#: ephios/core/models/events.py:51 +msgid "to everyone" +msgstr "jedem" + +#: ephios/core/models/events.py:52 +msgid "to confirmed participants" +msgstr "bestätigten Teilnehmenden" + +#: ephios/core/models/events.py:53 +msgid "only to responsible users" +msgstr "nur verantwortlichen Personen" + +#: ephios/core/models/events.py:55 ephios/core/models/events.py:73 #: ephios/core/models/users.py:247 ephios/core/models/users.py:274 msgid "title" msgstr "Titel" -#: ephios/core/models/events.py:49 +#: ephios/core/models/events.py:56 msgid "color" msgstr "Farbe" -#: ephios/core/models/events.py:53 +#: ephios/core/models/events.py:58 +msgid "show participant data" +msgstr "Zeige Teilnehmendeninformationen" + +#: ephios/core/models/events.py:65 msgid "event types" msgstr "Veranstaltungstypen" -#: ephios/core/models/events.py:62 +#: ephios/core/models/events.py:74 msgid "description" msgstr "Beschreibung" -#: ephios/core/models/events.py:63 +#: ephios/core/models/events.py:75 msgid "location" msgstr "Ort" -#: ephios/core/models/events.py:65 +#: ephios/core/models/events.py:77 msgid "active" msgstr "aktiv" -#: ephios/core/models/events.py:71 ephios/core/models/events.py:254 +#: ephios/core/models/events.py:83 ephios/core/models/events.py:286 msgid "event" msgstr "Veranstaltung" -#: ephios/core/models/events.py:72 +#: ephios/core/models/events.py:84 msgid "events" msgstr "Veranstaltungen" -#: ephios/core/models/events.py:173 +#: ephios/core/models/events.py:205 msgid "requested" msgstr "angefragt" -#: ephios/core/models/events.py:174 ephios/core/views/event.py:86 +#: ephios/core/models/events.py:206 ephios/core/views/event.py:87 msgid "confirmed" msgstr "bestätigt" -#: ephios/core/models/events.py:175 +#: ephios/core/models/events.py:207 msgid "declined by user" msgstr "abgesagt durch helfende Person" -#: ephios/core/models/events.py:176 +#: ephios/core/models/events.py:208 msgid "rejected by responsible" msgstr "abgelehnt durch verantwortliche Person" -#: ephios/core/models/events.py:177 +#: ephios/core/models/events.py:209 msgid "getting dispatched" msgstr "in Zuteilung" -#: ephios/core/models/events.py:190 ephios/core/models/events.py:278 +#: ephios/core/models/events.py:222 ephios/core/models/events.py:310 msgid "shift" msgstr "Schicht" -#: ephios/core/models/events.py:193 +#: ephios/core/models/events.py:225 msgid "state" msgstr "Status" -#: ephios/core/models/events.py:196 +#: ephios/core/models/events.py:228 msgid "Data on where this participation lives in the shift structure" msgstr "Daten zur Positionierung der Teilnahme in der Schicht-Struktur" -#: ephios/core/models/events.py:202 +#: ephios/core/models/events.py:234 msgid "individual start time" msgstr "Individueller Beginn" -#: ephios/core/models/events.py:203 +#: ephios/core/models/events.py:235 msgid "individual end time" msgstr "Individuelles Ende" -#: ephios/core/models/events.py:206 +#: ephios/core/models/events.py:238 msgid "Comment" msgstr "Kommentar" -#: ephios/core/models/events.py:212 +#: ephios/core/models/events.py:244 msgid "finished" msgstr "abgeschlossen" -#: ephios/core/models/events.py:256 +#: ephios/core/models/events.py:288 msgid "meeting time" msgstr "Treffpunkt" -#: ephios/core/models/events.py:260 +#: ephios/core/models/events.py:292 msgctxt "shift label" msgid "label" msgstr "Label" -#: ephios/core/models/events.py:263 +#: ephios/core/models/events.py:295 msgid "Optional label to help differentiate multiple shifts in an event." msgstr "" "Optionales Label zur Unterscheidung mehrerer Schichten einer Veranstaltung." -#: ephios/core/models/events.py:265 +#: ephios/core/models/events.py:297 msgid "signup flow" msgstr "Anmeldeverfahren" -#: ephios/core/models/events.py:270 +#: ephios/core/models/events.py:302 msgid "structure" msgstr "Struktur" -#: ephios/core/models/events.py:279 +#: ephios/core/models/events.py:311 msgid "shifts" msgstr "Schichten" -#: ephios/core/models/events.py:396 +#: ephios/core/models/events.py:428 #: ephios/core/templates/core/fragments/shift_box_small.html:26 msgid "Signup flow" msgstr "Anmeldeverfahren" -#: ephios/core/models/events.py:397 +#: ephios/core/models/events.py:429 #: ephios/core/templates/core/shift_form.html:46 msgid "Structure" msgstr "Struktur" -#: ephios/core/models/events.py:410 +#: ephios/core/models/events.py:442 msgid "Participant" msgstr "Teilnehmende Person" -#: ephios/core/models/events.py:431 +#: ephios/core/models/events.py:463 msgid "participation" msgstr "Teilnahme" -#: ephios/core/models/events.py:432 +#: ephios/core/models/events.py:464 msgid "participations" msgstr "Teilnahmen" -#: ephios/core/models/events.py:457 +#: ephios/core/models/events.py:489 msgid "placeholder participation" msgstr "Platzhalter-Teilnahme" -#: ephios/core/models/events.py:458 +#: ephios/core/models/events.py:490 msgid "placeholder participations" msgstr "Platzhalter-Teilnahmen" @@ -1130,7 +1149,7 @@ msgstr "fehlgeschlagen" msgid "denied" msgstr "abgelehnt" -#: ephios/core/models/users.py:401 ephios/core/views/event.py:81 +#: ephios/core/models/users.py:401 ephios/core/views/event.py:82 msgid "State" msgstr "Status" @@ -1601,7 +1620,7 @@ msgstr "" #: ephios/core/services/notifications/types.py:375 #: ephios/core/templates/core/disposition/disposition.html:8 #: ephios/core/templates/core/fragments/shift_box_big.html:86 -#: ephios/core/templates/core/home.html:109 +#: ephios/core/templates/core/home.html:106 msgid "Disposition" msgstr "Disposition" @@ -1909,7 +1928,7 @@ msgid "%(participant)s already participates in %(conflicts)s at the same time." msgstr "%(participant)s nimmt zur selben Zeit bereits an %(conflicts)s teil." #: ephios/core/templates/core/disposition/fragment_participation.html:25 -#: ephios/plugins/baseshiftstructures/templates/baseshiftstructures/participation_card_inline.html:27 +#: ephios/plugins/baseshiftstructures/templates/baseshiftstructures/participation_card_inline.html:33 msgid "Minor" msgstr "Minderjährig" @@ -1924,7 +1943,7 @@ msgstr "Möchten Sie die folgenden Veranstaltungen wirklich löschen?" #: ephios/core/templates/core/event_confirm_delete.html:6 #: ephios/core/templates/core/event_confirm_delete.html:11 -#: ephios/core/templates/core/event_detail.html:64 +#: ephios/core/templates/core/event_detail.html:60 msgid "Delete event" msgstr "Veranstaltung löschen" @@ -1935,11 +1954,11 @@ msgstr "Möchten Sie die Veranstaltung \"%(object)s\" wirklich löschen?" #: ephios/core/templates/core/event_copy.html:7 #: ephios/core/templates/core/event_copy.html:21 -#: ephios/core/templates/core/event_detail.html:73 +#: ephios/core/templates/core/event_detail.html:69 msgid "Copy event" msgstr "Veranstaltung kopieren" -#: ephios/core/templates/core/event_detail.html:28 +#: ephios/core/templates/core/event_detail.html:24 msgid "" "This event has not been saved! If you are done editing the event, you can " "save it." @@ -1947,37 +1966,37 @@ msgstr "" "Diese Veranstaltung wurde noch nicht gespeichert! Wenn Sie mit dem " "Bearbeiten der Veranstaltung fertig sind, können Sie sie speichern." -#: ephios/core/templates/core/event_detail.html:35 +#: ephios/core/templates/core/event_detail.html:31 msgid "This event has not been saved! Please add a shift to save this event." msgstr "" "Diese Veranstaltung wurde noch nicht gespeichert! Bitte fügen Sie eine " "Schicht hinzu, um sie zu speichern." -#: ephios/core/templates/core/event_detail.html:53 +#: ephios/core/templates/core/event_detail.html:49 #: ephios/core/templates/core/event_form.html:10 #: ephios/core/templates/core/event_form.html:26 msgid "Edit event" msgstr "Veranstaltung bearbeiten" -#: ephios/core/templates/core/event_detail.html:58 +#: ephios/core/templates/core/event_detail.html:54 #: ephios/core/templates/core/shift_form.html:82 msgid "Add another shift" msgstr "Weitere Schicht hinzufügen" -#: ephios/core/templates/core/event_detail.html:79 +#: ephios/core/templates/core/event_detail.html:75 msgid "Download PDF" msgstr "PDF herunterladen" -#: ephios/core/templates/core/event_detail.html:84 +#: ephios/core/templates/core/event_detail.html:80 msgid "Send notifications" msgstr "Benachrichtigungen senden" -#: ephios/core/templates/core/event_detail.html:91 +#: ephios/core/templates/core/event_detail.html:87 msgid "View edit history" msgstr "Änderungsverlauf" -#: ephios/core/templates/core/event_detail.html:117 -#: ephios/core/templates/core/fragments/event_list_list_mode.html:93 +#: ephios/core/templates/core/event_detail.html:113 +#: ephios/core/templates/core/fragments/event_list_list_mode.html:95 #: ephios/core/templates/core/mails/new_event.html:18 #: ephios/core/templates/core/workinghours_list.html:18 #: ephios/plugins/federation/templates/federation/external_event_list.html:66 @@ -1985,7 +2004,7 @@ msgstr "Änderungsverlauf" msgid "to" msgstr "bis" -#: ephios/core/templates/core/event_detail.html:142 +#: ephios/core/templates/core/event_detail.html:138 msgid "No shifts" msgstr "Keine Schichten" @@ -2082,8 +2101,8 @@ msgid "Add %(title)s" msgstr "%(title)s hinzufügen" #: ephios/core/templates/core/fragments/event_list_day_mode.html:52 -#: ephios/core/templates/core/fragments/event_list_list_mode.html:109 -#: ephios/plugins/federation/templates/federation/external_event_list.html:81 +#: ephios/core/templates/core/fragments/event_list_list_mode.html:108 +#: ephios/plugins/federation/templates/federation/external_event_list.html:78 msgid "No results" msgstr "Keine Ergebnisse" @@ -2091,16 +2110,11 @@ msgstr "Keine Ergebnisse" msgid "Delete selected" msgstr "Ausgewählte löschen" -#: ephios/core/templates/core/fragments/event_list_list_mode.html:99 -#: ephios/plugins/federation/templates/federation/external_event_list.html:72 -msgid "Show" -msgstr "Anzeigen" - #: ephios/core/templates/core/fragments/pending_consequences.html:8 msgid "Your requests" msgstr "Ihre Anfragen" -#: ephios/core/templates/core/fragments/shift_box_big.html:95 +#: ephios/core/templates/core/fragments/shift_box_big.html:96 msgid "Signup ends" msgstr "Anmeldung endet" @@ -2220,25 +2234,25 @@ msgstr "Willkommen bei %(organization_name)s!" msgid "Your upcoming events" msgstr "Anstehende Schichten" -#: ephios/core/templates/core/home.html:66 +#: ephios/core/templates/core/home.html:64 msgctxt "empty list of upcoming shifts" msgid "None yet" msgstr "Noch keine" -#: ephios/core/templates/core/home.html:67 +#: ephios/core/templates/core/home.html:66 msgid "View events" msgstr "Veranstaltungen ansehen" -#: ephios/core/templates/core/home.html:79 +#: ephios/core/templates/core/home.html:78 msgid "Events with requested participations" msgstr "Veranstaltungen mit angefragten Teilnahmen" -#: ephios/core/templates/core/home.html:127 +#: ephios/core/templates/core/home.html:124 #: ephios/core/templates/core/logentry_list.html:16 msgid "Edit history" msgstr "Änderungsverlauf" -#: ephios/core/templates/core/home.html:130 +#: ephios/core/templates/core/home.html:127 msgid "View everything" msgstr "Alles ansehen" @@ -2498,7 +2512,7 @@ msgid "You are not a member of any group." msgstr "Sie sind in keiner Gruppe Mitglied." #: ephios/core/templates/core/settings/settings_personal_data.html:37 -#: ephios/extra/templates/extra/widgets/recurrence_picker.html:159 +#: ephios/extra/templates/extra/widgets/recurrence_picker.html:154 msgid "until" msgstr "bis" @@ -2750,7 +2764,7 @@ msgid "No entries" msgstr "Keine Einträge" #: ephios/core/views/accounts.py:39 ephios/core/views/accounts.py:40 -#: ephios/core/views/event.py:54 ephios/core/views/event.py:55 +#: ephios/core/views/event.py:55 ephios/core/views/event.py:56 msgid "Search for…" msgstr "Suche nach…" @@ -2843,50 +2857,50 @@ msgstr "" "Laden der OIDC-Konfiguration für die angegebene URL fehlgeschlagen. Eine " "manuelle Einrichtung kann unten vorgenommen werden." -#: ephios/core/views/bulk.py:19 +#: ephios/core/views/bulk.py:21 ephios/core/views/bulk.py:30 msgid "No events were selected for deletion." msgstr "Es wurden keine Veranstaltungen zum Löschen ausgewählt." -#: ephios/core/views/bulk.py:23 +#: ephios/core/views/bulk.py:34 msgid "The selected events have been deleted." msgstr "Die ausgewählten Veranstaltungen wurden gelöscht." -#: ephios/core/views/event.py:70 +#: ephios/core/views/event.py:71 msgctxt "event date filter" msgid "until" msgstr "bis zum" -#: ephios/core/views/event.py:71 +#: ephios/core/views/event.py:72 msgctxt "event date filter" msgid "from" msgstr "ab dem" -#: ephios/core/views/event.py:84 +#: ephios/core/views/event.py:85 msgid "all" msgstr "alle" -#: ephios/core/views/event.py:85 +#: ephios/core/views/event.py:86 msgid "no response" msgstr "ohne Rückmeldung" -#: ephios/core/views/event.py:87 +#: ephios/core/views/event.py:88 msgid "requested or confirmed" msgstr "angefragt oder bestätigt" -#: ephios/core/views/event.py:88 +#: ephios/core/views/event.py:89 msgid "disposition to do" msgstr "Disposition offen" -#: ephios/core/views/event.py:519 ephios/core/views/shift.py:120 +#: ephios/core/views/event.py:540 ephios/core/views/shift.py:122 #, python-brace-format msgid "The event {title} has been saved." msgstr "Die Veranstaltung {title} wurde gespeichert." -#: ephios/core/views/event.py:610 +#: ephios/core/views/event.py:637 msgid "Event copied successfully." msgstr "Veranstaltung erfolgreich kopiert." -#: ephios/core/views/event.py:643 +#: ephios/core/views/event.py:670 msgid "Notifications sent succesfully." msgstr "Benachrichtigungen erfolgreich gesendet." @@ -2945,32 +2959,32 @@ msgstr "Einstellungen erfolgreich gespeichert." msgid "Password changed successfully." msgstr "Passwort erfolgreich geändert." -#: ephios/core/views/shift.py:65 +#: ephios/core/views/shift.py:67 msgid "You must enable plugins providing signup flows to continue." msgstr "" "Um fortzufahren, müssen Sie Plugins aktivieren, die Anmeldeverfahren " "bereitstellen." -#: ephios/core/views/shift.py:70 +#: ephios/core/views/shift.py:72 msgid "You must enable plugins providing shift structures to continue." msgstr "" "Um fortzufahren, müssen Sie Plugins aktivieren, die Schicht-Strukturen " "bereitstellen." -#: ephios/core/views/shift.py:256 +#: ephios/core/views/shift.py:258 #, python-brace-format msgid "The shift {shift} has been saved." msgstr "Die Schicht {shift} wurde gespeichert." -#: ephios/core/views/shift.py:279 +#: ephios/core/views/shift.py:281 msgid "You cannot delete the last shift!" msgstr "Sie können die letzte Schicht nicht löschen!" -#: ephios/core/views/shift.py:284 +#: ephios/core/views/shift.py:286 msgid "The shift has been deleted." msgstr "Die Schicht wurde gelöscht." -#: ephios/core/views/shift.py:323 +#: ephios/core/views/shift.py:330 msgid "Shift copied successfully." msgstr "Schicht erfolgreich kopiert." @@ -3023,7 +3037,7 @@ msgid "Yearly" msgstr "jährlich" #: ephios/extra/templates/extra/widgets/recurrence_picker.html:37 -#: ephios/extra/templates/extra/widgets/recurrence_picker.html:204 +#: ephios/extra/templates/extra/widgets/recurrence_picker.html:181 #: ephios/plugins/complexsignup/templates/complexsignup/vue_editor.html:62 #: ephios/plugins/complexsignup/templates/complexsignup/vue_editor.html:78 #: ephios/plugins/complexsignup/templates/complexsignup/vue_editor.html:182 @@ -3037,64 +3051,66 @@ msgstr "Entfernen" msgid "Repeat every" msgstr "Wiederholen alle" -#: ephios/extra/templates/extra/widgets/recurrence_picker.html:49 +#: ephios/extra/templates/extra/widgets/recurrence_picker.html:46 msgid "on" msgstr "am" -#: ephios/extra/templates/extra/widgets/recurrence_picker.html:83 -#: ephios/extra/templates/extra/widgets/recurrence_picker.html:127 +#: ephios/extra/templates/extra/widgets/recurrence_picker.html:80 +#: ephios/extra/templates/extra/widgets/recurrence_picker.html:124 msgid "First" msgstr "ersten" -#: ephios/extra/templates/extra/widgets/recurrence_picker.html:84 -#: ephios/extra/templates/extra/widgets/recurrence_picker.html:128 +#: ephios/extra/templates/extra/widgets/recurrence_picker.html:81 +#: ephios/extra/templates/extra/widgets/recurrence_picker.html:125 msgid "Second" msgstr "zweiten" -#: ephios/extra/templates/extra/widgets/recurrence_picker.html:85 -#: ephios/extra/templates/extra/widgets/recurrence_picker.html:129 +#: ephios/extra/templates/extra/widgets/recurrence_picker.html:82 +#: ephios/extra/templates/extra/widgets/recurrence_picker.html:126 msgid "Third" msgstr "dritten" -#: ephios/extra/templates/extra/widgets/recurrence_picker.html:86 -#: ephios/extra/templates/extra/widgets/recurrence_picker.html:130 +#: ephios/extra/templates/extra/widgets/recurrence_picker.html:83 +#: ephios/extra/templates/extra/widgets/recurrence_picker.html:127 msgid "Fourth" msgstr "vierten" -#: ephios/extra/templates/extra/widgets/recurrence_picker.html:87 -#: ephios/extra/templates/extra/widgets/recurrence_picker.html:131 +#: ephios/extra/templates/extra/widgets/recurrence_picker.html:84 +#: ephios/extra/templates/extra/widgets/recurrence_picker.html:128 msgid "Last" msgstr "letzten" -#: ephios/extra/templates/extra/widgets/recurrence_picker.html:141 +#: ephios/extra/templates/extra/widgets/recurrence_picker.html:138 msgctxt "month" msgid "in" msgstr "im" -#: ephios/extra/templates/extra/widgets/recurrence_picker.html:179 +#: ephios/extra/templates/extra/widgets/recurrence_picker.html:166 msgid "for" msgstr "für" -#: ephios/extra/templates/extra/widgets/recurrence_picker.html:187 +#: ephios/extra/templates/extra/widgets/recurrence_picker.html:170 msgid "occurrences" msgstr "Mal" -#: ephios/extra/templates/extra/widgets/recurrence_picker.html:212 +#: ephios/extra/templates/extra/widgets/recurrence_picker.html:188 msgid "Add rule" msgstr "Regel hinzufügen" -#: ephios/extra/templates/extra/widgets/recurrence_picker.html:215 +#: ephios/extra/templates/extra/widgets/recurrence_picker.html:191 msgid "Add date" msgstr "Datum hinzufügen" -#: ephios/extra/templates/extra/widgets/recurrence_picker.html:225 +#: ephios/extra/templates/extra/widgets/recurrence_picker.html:199 msgid "Selected dates" msgstr "Ausgewählte Daten" -#: ephios/extra/templates/extra/widgets/recurrence_picker.html:232 +#: ephios/extra/templates/extra/widgets/recurrence_picker.html:206 msgid "" "No dates selected yet. Add dates and rules using the controls on the left." -msgstr "Keine Daten ausgewählt. Fügen Sie Daten und Regeln mit den Knöpfen auf der linken Seite hinzu." +msgstr "" +"Keine Daten ausgewählt. Fügen Sie Daten und Regeln mit den Knöpfen auf der " +"linken Seite hinzu." #: ephios/extra/utils.py:36 msgid "None" @@ -3113,11 +3129,11 @@ msgstr "Änderungseintrag" msgid "Log entries" msgstr "Änderungseinträge" -#: ephios/modellogging/recorders.py:254 ephios/modellogging/recorders.py:360 +#: ephios/modellogging/recorders.py:252 ephios/modellogging/recorders.py:362 msgid "added" msgstr "hinzugefügt" -#: ephios/modellogging/recorders.py:254 ephios/modellogging/recorders.py:360 +#: ephios/modellogging/recorders.py:252 ephios/modellogging/recorders.py:362 msgid "removed" msgstr "entfernt" @@ -3326,6 +3342,10 @@ msgstr "Team hinzufügen" msgid "prefers" msgstr "bevorzugt" +#: ephios/plugins/baseshiftstructures/templates/baseshiftstructures/participation_card_inline.html:11 +msgid "Anonymous" +msgstr "Anonym" + #: ephios/plugins/basesignupflows/apps.py:10 msgid "Base Signup Flows" msgstr "Grundlegende Anmeldeverfahren" @@ -3334,31 +3354,31 @@ msgstr "Grundlegende Anmeldeverfahren" msgid "This plugins adds the standard signup flows." msgstr "Dieses Plugin fügt grundlegende Anmeldeverfahren hinzu." -#: ephios/plugins/basesignupflows/flow/coupled.py:23 +#: ephios/plugins/basesignupflows/flow/coupled.py:28 msgid "Participation is coupled to {}." msgstr "Teilnahme ist gekoppelt an {}." -#: ephios/plugins/basesignupflows/flow/coupled.py:26 +#: ephios/plugins/basesignupflows/flow/coupled.py:36 msgid "" "Participation is coupled to another shift, but the leading shift is missing." msgstr "" "Teilnahmen waren an eine andere Schicht gekoppelt, aber diese Schicht fehlt " "jetzt." -#: ephios/plugins/basesignupflows/flow/coupled.py:32 +#: ephios/plugins/basesignupflows/flow/coupled.py:42 msgid "shift to mirror participation from" msgstr "Teilnahmen werden gespiegelt von" -#: ephios/plugins/basesignupflows/flow/coupled.py:50 +#: ephios/plugins/basesignupflows/flow/coupled.py:60 msgctxt "coupled signup leader shift" msgid "missing" msgstr "fehlt" -#: ephios/plugins/basesignupflows/flow/coupled.py:55 +#: ephios/plugins/basesignupflows/flow/coupled.py:65 msgid "coupled to another shift" msgstr "an andere Schicht gekoppelt" -#: ephios/plugins/basesignupflows/flow/coupled.py:56 +#: ephios/plugins/basesignupflows/flow/coupled.py:66 msgid "This method mirrors signup from another shift." msgstr "" "Dieses Anmeldeverfahren spiegelt die Anmeldungen einer anderen Schicht." @@ -4761,6 +4781,9 @@ msgstr "Passwort erfolgreich zurückgesetzt" msgid "Please check your mailbox for further instructions." msgstr "Bitte prüfen Sie Ihren E-Mail-Posteingang für weitere Anweisungen." +#~ msgid "Show" +#~ msgstr "Anzeigen" + #~ msgid "" #~ "This date will be used as the start date for recurring events that you " #~ "create below, e.g. daily events will be created from this date onwards." From 0ddcdd6b9cc0ec6796f024858a933ea901b95418 Mon Sep 17 00:00:00 2001 From: Felix Rindt Date: Mon, 23 Dec 2024 21:32:20 +0100 Subject: [PATCH 4/6] show participant info to users with view_userprofile permissions --- ephios/core/models/events.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ephios/core/models/events.py b/ephios/core/models/events.py index e25d6002d..28d300ffa 100644 --- a/ephios/core/models/events.py +++ b/ephios/core/models/events.py @@ -144,6 +144,7 @@ class ParticipationQuerySet(PolymorphicQuerySet): def viewable_by(self, user): viewable_events = get_objects_for_user(user, "core.view_event") + viewable_userprofiles = get_objects_for_user(user, "core.view_userprofile") editable_events = get_objects_for_user(user, "core.change_event") participating_events = Event.objects.filter( shifts__participations__in=user.participations.filter( @@ -160,6 +161,7 @@ def viewable_by(self, user): ) | Q(shift__event__in=editable_events) | Q(localparticipation__user=user) + | Q(localparticipation__user__in=viewable_userprofiles) ) return qs.distinct() From d239a555838fca8130e0176813950b6a34000ab7 Mon Sep 17 00:00:00 2001 From: Felix Rindt Date: Fri, 3 Jan 2025 20:11:59 +0100 Subject: [PATCH 5/6] use blur and hide popover --- ephios/core/models/events.py | 3 + ephios/locale/de/LC_MESSAGES/django.po | 107 ++++++++++-------- .../participation_card_inline.html | 59 +++++----- ephios/static/ephios/scss/ephios_custom.scss | 7 +- 4 files changed, 99 insertions(+), 77 deletions(-) diff --git a/ephios/core/models/events.py b/ephios/core/models/events.py index 28d300ffa..c425e8ee6 100644 --- a/ephios/core/models/events.py +++ b/ephios/core/models/events.py @@ -56,6 +56,9 @@ class ShowParticipantDataChoices(models.IntegerChoices): color = CharField(_("color"), max_length=7, default="#343a40") show_participant_data = models.SmallIntegerField( verbose_name=_("show participant data"), + help_text=_( + "If you restrict who can see participant data, others will only be able to see that there is a participation, but not from whom." + ), choices=ShowParticipantDataChoices.choices, default=ShowParticipantDataChoices.EVERYONE, ) diff --git a/ephios/locale/de/LC_MESSAGES/django.po b/ephios/locale/de/LC_MESSAGES/django.po index 0c8ded782..cf951c0e1 100644 --- a/ephios/locale/de/LC_MESSAGES/django.po +++ b/ephios/locale/de/LC_MESSAGES/django.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-12-22 12:25+0100\n" -"PO-Revision-Date: 2024-12-22 12:27+0100\n" +"POT-Creation-Date: 2025-01-03 20:07+0100\n" +"PO-Revision-Date: 2025-01-03 20:08+0100\n" "Last-Translator: Felix Rindt \n" "Language-Team: German \n" @@ -50,11 +50,11 @@ msgstr "Token ist zu alt, um angezeigt werden zu können." msgid "Token was revoked." msgstr "Token wurde entfernt." -#: ephios/api/filters.py:44 ephios/core/models/events.py:289 +#: ephios/api/filters.py:44 ephios/core/models/events.py:292 msgid "start time" msgstr "Beginn" -#: ephios/api/filters.py:45 ephios/core/models/events.py:290 +#: ephios/api/filters.py:45 ephios/core/models/events.py:293 msgid "end time" msgstr "Ende" @@ -69,8 +69,8 @@ msgid "start time less than equals (deprecated, use start_time_before instead)" msgstr "" "Startzeit kleiner-gleich (deprecated, stattdessen start_time_before nutzen)" -#: ephios/api/filters.py:61 ephios/core/models/events.py:64 -#: ephios/core/models/events.py:76 ephios/core/views/event.py:60 +#: ephios/api/filters.py:61 ephios/core/models/events.py:65 +#: ephios/core/models/events.py:77 ephios/core/views/event.py:60 msgid "event type" msgstr "Veranstaltungstyp" @@ -866,17 +866,17 @@ msgstr "Ausbildung" #: ephios/core/models/events.py:51 msgid "to everyone" -msgstr "jedem" +msgstr "alle Personen" #: ephios/core/models/events.py:52 msgid "to confirmed participants" -msgstr "bestätigten Teilnehmenden" +msgstr "bestätigte Teilnehmende" #: ephios/core/models/events.py:53 msgid "only to responsible users" -msgstr "nur verantwortlichen Personen" +msgstr "nur verantwortliche Personen" -#: ephios/core/models/events.py:55 ephios/core/models/events.py:73 +#: ephios/core/models/events.py:55 ephios/core/models/events.py:74 #: ephios/core/models/users.py:247 ephios/core/models/users.py:274 msgid "title" msgstr "Titel" @@ -887,133 +887,141 @@ msgstr "Farbe" #: ephios/core/models/events.py:58 msgid "show participant data" -msgstr "Zeige Teilnehmendeninformationen" +msgstr "Teilnehmendeninformationen sichtbar machen für" -#: ephios/core/models/events.py:65 +#: ephios/core/models/events.py:59 +msgid "" +"If you restrict who can see participant data, others will only be able to " +"see that there is a participation, but not from whom." +msgstr "" +"Wenn Sie dies einschränken, werden andere nur sehen, dass es eine Teilnahme " +"gibt, aber nicht von wem." + +#: ephios/core/models/events.py:66 msgid "event types" msgstr "Veranstaltungstypen" -#: ephios/core/models/events.py:74 +#: ephios/core/models/events.py:75 msgid "description" msgstr "Beschreibung" -#: ephios/core/models/events.py:75 +#: ephios/core/models/events.py:76 msgid "location" msgstr "Ort" -#: ephios/core/models/events.py:77 +#: ephios/core/models/events.py:78 msgid "active" msgstr "aktiv" -#: ephios/core/models/events.py:83 ephios/core/models/events.py:286 +#: ephios/core/models/events.py:84 ephios/core/models/events.py:289 msgid "event" msgstr "Veranstaltung" -#: ephios/core/models/events.py:84 +#: ephios/core/models/events.py:85 msgid "events" msgstr "Veranstaltungen" -#: ephios/core/models/events.py:205 +#: ephios/core/models/events.py:208 msgid "requested" msgstr "angefragt" -#: ephios/core/models/events.py:206 ephios/core/views/event.py:87 +#: ephios/core/models/events.py:209 ephios/core/views/event.py:87 msgid "confirmed" msgstr "bestätigt" -#: ephios/core/models/events.py:207 +#: ephios/core/models/events.py:210 msgid "declined by user" msgstr "abgesagt durch helfende Person" -#: ephios/core/models/events.py:208 +#: ephios/core/models/events.py:211 msgid "rejected by responsible" msgstr "abgelehnt durch verantwortliche Person" -#: ephios/core/models/events.py:209 +#: ephios/core/models/events.py:212 msgid "getting dispatched" msgstr "in Zuteilung" -#: ephios/core/models/events.py:222 ephios/core/models/events.py:310 +#: ephios/core/models/events.py:225 ephios/core/models/events.py:313 msgid "shift" msgstr "Schicht" -#: ephios/core/models/events.py:225 +#: ephios/core/models/events.py:228 msgid "state" msgstr "Status" -#: ephios/core/models/events.py:228 +#: ephios/core/models/events.py:231 msgid "Data on where this participation lives in the shift structure" msgstr "Daten zur Positionierung der Teilnahme in der Schicht-Struktur" -#: ephios/core/models/events.py:234 +#: ephios/core/models/events.py:237 msgid "individual start time" msgstr "Individueller Beginn" -#: ephios/core/models/events.py:235 +#: ephios/core/models/events.py:238 msgid "individual end time" msgstr "Individuelles Ende" -#: ephios/core/models/events.py:238 +#: ephios/core/models/events.py:241 msgid "Comment" msgstr "Kommentar" -#: ephios/core/models/events.py:244 +#: ephios/core/models/events.py:247 msgid "finished" msgstr "abgeschlossen" -#: ephios/core/models/events.py:288 +#: ephios/core/models/events.py:291 msgid "meeting time" msgstr "Treffpunkt" -#: ephios/core/models/events.py:292 +#: ephios/core/models/events.py:295 msgctxt "shift label" msgid "label" msgstr "Label" -#: ephios/core/models/events.py:295 +#: ephios/core/models/events.py:298 msgid "Optional label to help differentiate multiple shifts in an event." msgstr "" "Optionales Label zur Unterscheidung mehrerer Schichten einer Veranstaltung." -#: ephios/core/models/events.py:297 +#: ephios/core/models/events.py:300 msgid "signup flow" msgstr "Anmeldeverfahren" -#: ephios/core/models/events.py:302 +#: ephios/core/models/events.py:305 msgid "structure" msgstr "Struktur" -#: ephios/core/models/events.py:311 +#: ephios/core/models/events.py:314 msgid "shifts" msgstr "Schichten" -#: ephios/core/models/events.py:428 +#: ephios/core/models/events.py:431 #: ephios/core/templates/core/fragments/shift_box_small.html:26 msgid "Signup flow" msgstr "Anmeldeverfahren" -#: ephios/core/models/events.py:429 +#: ephios/core/models/events.py:432 #: ephios/core/templates/core/shift_form.html:46 msgid "Structure" msgstr "Struktur" -#: ephios/core/models/events.py:442 +#: ephios/core/models/events.py:445 msgid "Participant" msgstr "Teilnehmende Person" -#: ephios/core/models/events.py:463 +#: ephios/core/models/events.py:466 msgid "participation" msgstr "Teilnahme" -#: ephios/core/models/events.py:464 +#: ephios/core/models/events.py:467 msgid "participations" msgstr "Teilnahmen" -#: ephios/core/models/events.py:489 +#: ephios/core/models/events.py:492 msgid "placeholder participation" msgstr "Platzhalter-Teilnahme" -#: ephios/core/models/events.py:490 +#: ephios/core/models/events.py:493 msgid "placeholder participations" msgstr "Platzhalter-Teilnahmen" @@ -1928,7 +1936,7 @@ msgid "%(participant)s already participates in %(conflicts)s at the same time." msgstr "%(participant)s nimmt zur selben Zeit bereits an %(conflicts)s teil." #: ephios/core/templates/core/disposition/fragment_participation.html:25 -#: ephios/plugins/baseshiftstructures/templates/baseshiftstructures/participation_card_inline.html:33 +#: ephios/plugins/baseshiftstructures/templates/baseshiftstructures/participation_card_inline.html:29 msgid "Minor" msgstr "Minderjährig" @@ -3342,9 +3350,10 @@ msgstr "Team hinzufügen" msgid "prefers" msgstr "bevorzugt" -#: ephios/plugins/baseshiftstructures/templates/baseshiftstructures/participation_card_inline.html:11 -msgid "Anonymous" -msgstr "Anonym" +#: ephios/plugins/baseshiftstructures/templates/baseshiftstructures/participation_card_inline.html:65 +msgctxt "blurred participant name" +msgid "Redacted Name" +msgstr "Zensierter Name" #: ephios/plugins/basesignupflows/apps.py:10 msgid "Base Signup Flows" @@ -4781,6 +4790,12 @@ msgstr "Passwort erfolgreich zurückgesetzt" msgid "Please check your mailbox for further instructions." msgstr "Bitte prüfen Sie Ihren E-Mail-Posteingang für weitere Anweisungen." +#~ msgid "Everyone else will only be able to see anonymized data." +#~ msgstr "Jeder andere wird nur anonymisierte Daten sehen." + +#~ msgid "Anonymous" +#~ msgstr "Anonym" + #~ msgid "Show" #~ msgstr "Anzeigen" diff --git a/ephios/plugins/baseshiftstructures/templates/baseshiftstructures/participation_card_inline.html b/ephios/plugins/baseshiftstructures/templates/baseshiftstructures/participation_card_inline.html index 1fc5b8f18..f4314926f 100644 --- a/ephios/plugins/baseshiftstructures/templates/baseshiftstructures/participation_card_inline.html +++ b/ephios/plugins/baseshiftstructures/templates/baseshiftstructures/participation_card_inline.html @@ -2,54 +2,53 @@ {% load user_extras %} {% load i18n %} +{% if participation.show_participant_data %} -
- {{ participation.participant.icon }} - {% if participation.show_participant_data %} +
+ {{ participation.participant.icon }} {{ participation.participant }} - {% else %} - {% translate "Anonymous" %} - {% endif %} -
+
-
- {% if participation.individual_start_time or participation.individual_end_time %} -
- - {{ participation.get_time_display }} -
- {% endif %} - {% if participation.comment %} - {% if show_comments or participation == own_participation %} +
+ {% if participation.individual_start_time or participation.individual_end_time %}
- - {{ participation.comment }} + + {{ participation.get_time_display }}
{% endif %} - {% endif %} -
- {% if participation.show_participant_data %} + {% if participation.comment %} + {% if show_comments or participation == own_participation %} +
+ + {{ participation.comment }} +
+ {% endif %} + {% endif %} +
{% if participation.participant.is_minor %} {% translate "Minor" %} {% endif %} {% for abbreviation in participation.participant.qualifications|qualifications_to_essential_abbreviations %} {{ abbreviation }} {% endfor %} - {% endif %} +
-
+{% endif %} + {% if participation.state == participation.States.CONFIRMED %} {% if participation.has_customized_signup %} @@ -63,6 +62,6 @@ {% if participation.show_participant_data %} {{ participation.participant }} {% else %} - + {% translate "Redacted Name" context "blurred participant name" %} {% endif %} diff --git a/ephios/static/ephios/scss/ephios_custom.scss b/ephios/static/ephios/scss/ephios_custom.scss index fb50c75e8..9b5d173e9 100644 --- a/ephios/static/ephios/scss/ephios_custom.scss +++ b/ephios/static/ephios/scss/ephios_custom.scss @@ -61,7 +61,12 @@ footer { } -/* mannequins */ +/* event detail and mannequin */ + +.participant-anon { + filter: blur(3px); + padding-left: 0.1rem; +} .mannequin { border-radius: $card-border-radius; From ce6964d6371653ed97aaa4060c51e79e5fb1e395 Mon Sep 17 00:00:00 2001 From: Felix Rindt Date: Fri, 3 Jan 2025 20:18:57 +0100 Subject: [PATCH 6/6] update migration --- ephios/core/migrations/0033_eventtype_show_participant_data.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ephios/core/migrations/0033_eventtype_show_participant_data.py b/ephios/core/migrations/0033_eventtype_show_participant_data.py index 6be9eae42..cfad5e869 100644 --- a/ephios/core/migrations/0033_eventtype_show_participant_data.py +++ b/ephios/core/migrations/0033_eventtype_show_participant_data.py @@ -1,4 +1,4 @@ -# Generated by Django 5.0.9 on 2024-12-22 09:57 +# Generated by Django 5.0.9 on 2025-01-03 19:18 from django.db import migrations, models @@ -20,6 +20,7 @@ class Migration(migrations.Migration): (2, "only to responsible users"), ], default=0, + help_text="If you restrict who can see participant data, others will only be able to see that there is a participation, but not from whom.", verbose_name="show participant data", ), ),