From f444f3a630f2c04e0ab7556249bd95afc77bb53e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20H=C3=A4ttasch?= <benjamin.haettasch@fachschaft.informatik.tu-darmstadt.de> Date: Mon, 24 Oct 2022 00:22:58 +0200 Subject: [PATCH] Introduce intermediate page for plan publishing Use action with intermediate page instead of direct action for publishing and unpublishing of plans This allows to create a link on the events detail page and on the status page to change the plans visibility Add link to detail view Visualize plan visibility on status page and allow to toggle it from there This implements the final function of #159 --- AKModel/admin.py | 27 +- AKModel/locale/de_DE/LC_MESSAGES/django.po | 432 ++++++++++---------- AKModel/templates/admin/AKModel/status.html | 7 + AKModel/views.py | 21 + 4 files changed, 272 insertions(+), 215 deletions(-) diff --git a/AKModel/admin.py b/AKModel/admin.py index b26c9d63..6bbbee0f 100644 --- a/AKModel/admin.py +++ b/AKModel/admin.py @@ -3,7 +3,6 @@ from django.apps import apps from django.contrib import admin, messages from django.contrib.admin import SimpleListFilter, RelatedFieldListFilter, action, display from django.db.models import Count, F -from django.db.models.functions import Now from django.http import HttpResponseRedirect from django.shortcuts import render, redirect from django.urls import reverse_lazy, path @@ -20,7 +19,7 @@ from AKModel.models import Event, AKOwner, AKCategory, AKTrack, AKTag, AKRequire ConstraintViolation from AKModel.urls import get_admin_urls_event_wizard, get_admin_urls_event from AKModel.views import CVMarkResolvedView, CVSetLevelViolationView, CVSetLevelWarningView, AKResetInterestView, \ - AKResetInterestCounterView + AKResetInterestCounterView, PlanPublishView, PlanUnpublishView class EventRelatedFieldListFilter(RelatedFieldListFilter): @@ -39,7 +38,7 @@ class EventAdmin(admin.ModelAdmin): list_filter = ['active'] list_editable = ['active'] ordering = ['-start'] - readonly_fields = ['status_url', 'plan_hidden', 'plan_published_at'] + readonly_fields = ['status_url', 'plan_hidden', 'plan_published_at', 'toggle_plan_visibility'] actions = ['publish', 'unpublish'] def add_view(self, request, form_url='', extra_context=None): @@ -53,6 +52,10 @@ class EventAdmin(admin.ModelAdmin): if apps.is_installed("AKScheduling"): from AKScheduling.urls import get_admin_urls_scheduling urls.extend(get_admin_urls_scheduling(self.admin_site)) + urls.extend([ + path('plan/publish/', PlanPublishView.as_view(), name="plan-publish"), + path('plan/unpublish/', PlanUnpublishView.as_view(), name="plan-unpublish"), + ]) urls.extend(super().get_urls()) return urls @@ -61,6 +64,16 @@ class EventAdmin(admin.ModelAdmin): return format_html("<a href='{url}'>{text}</a>", url=reverse_lazy('admin:event_status', kwargs={'slug': obj.slug}), text=_("Status")) + @display(description=_("Toggle plan visibility")) + def toggle_plan_visibility(self, obj): + if obj.plan_hidden: + url = f"{reverse_lazy('admin:plan-publish')}?pks={obj.pk}" + text = _('Publish plan') + else: + url = f"{reverse_lazy('admin:plan-unpublish')}?pks={obj.pk}" + text = _('Unpublish plan') + return format_html("<a href='{url}'>{text}</a>", url=url, text=text) + def get_form(self, request, obj=None, change=False, **kwargs): # Use timezone of event timezone.activate(obj.timezone) @@ -68,13 +81,13 @@ class EventAdmin(admin.ModelAdmin): @action(description=_('Publish plan')) def publish(self, request, queryset): - queryset.update(plan_published_at=Now(), plan_hidden=False) - self.message_user(request, _('Plan published'), messages.SUCCESS) + selected = queryset.values_list('pk', flat=True) + return HttpResponseRedirect(f"{reverse_lazy('admin:plan-publish')}?pks={','.join(str(pk) for pk in selected)}") @action(description=_('Unpublish plan')) def unpublish(self, request, queryset): - queryset.update(plan_published_at=None, plan_hidden=True) - self.message_user(request, _('Plan unpublished'), messages.SUCCESS) + selected = queryset.values_list('pk', flat=True) + return HttpResponseRedirect(f"{reverse_lazy('admin:plan-unpublish')}?pks={','.join(str(pk) for pk in selected)}") @admin.register(AKOwner) diff --git a/AKModel/locale/de_DE/LC_MESSAGES/django.po b/AKModel/locale/de_DE/LC_MESSAGES/django.po index ea136ff1..08531387 100644 --- a/AKModel/locale/de_DE/LC_MESSAGES/django.po +++ b/AKModel/locale/de_DE/LC_MESSAGES/django.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-10-23 23:19+0200\n" +"POT-Creation-Date: 2022-10-24 00:20+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -11,7 +11,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: AKModel/admin.py:59 AKModel/admin.py:62 +#: AKModel/admin.py:62 AKModel/admin.py:65 #: AKModel/templates/admin/AKModel/event_wizard/activate.html:32 #: AKModel/templates/admin/AKModel/event_wizard/created_prepare_import.html:48 #: AKModel/templates/admin/AKModel/event_wizard/finish.html:21 @@ -21,63 +21,59 @@ msgstr "" msgid "Status" msgstr "Status" -#: AKModel/admin.py:69 +#: AKModel/admin.py:67 +msgid "Toggle plan visibility" +msgstr "Plansichtbarkeit ändern" + +#: AKModel/admin.py:71 AKModel/admin.py:82 AKModel/views.py:481 msgid "Publish plan" msgstr "Plan veröffentlichen" -#: AKModel/admin.py:72 -msgid "Plan published" -msgstr "Plan veröffentlicht" - -#: AKModel/admin.py:74 +#: AKModel/admin.py:74 AKModel/admin.py:87 AKModel/views.py:491 msgid "Unpublish plan" msgstr "Plan verbergen" -#: AKModel/admin.py:77 -msgid "Plan unpublished" -msgstr "Plan verborgen" - -#: AKModel/admin.py:146 +#: AKModel/admin.py:159 msgid "Wish" msgstr "AK-Wunsch" -#: AKModel/admin.py:152 +#: AKModel/admin.py:165 msgid "Is wish" msgstr "Ist ein Wunsch" -#: AKModel/admin.py:153 +#: AKModel/admin.py:166 msgid "Is not a wish" msgstr "Ist kein Wunsch" -#: AKModel/admin.py:197 +#: AKModel/admin.py:210 msgid "Export to wiki syntax" msgstr "In Wiki-Syntax exportieren" -#: AKModel/admin.py:205 +#: AKModel/admin.py:219 msgid "Cannot export AKs from more than one event at the same time." msgstr "Kann nicht AKs von mehreren Events zur selben Zeit exportieren." -#: AKModel/admin.py:220 AKModel/views.py:442 +#: AKModel/admin.py:234 AKModel/views.py:461 msgid "Reset interest in AKs" msgstr "Interesse an AKs zurücksetzen" -#: AKModel/admin.py:225 AKModel/views.py:452 +#: AKModel/admin.py:239 AKModel/views.py:471 msgid "Reset AKs' interest counters" msgstr "Interessenszähler der AKs zurücksetzen" -#: AKModel/admin.py:309 +#: AKModel/admin.py:323 msgid "AK Details" msgstr "AK-Details" -#: AKModel/admin.py:366 AKModel/views.py:412 +#: AKModel/admin.py:380 AKModel/views.py:431 msgid "Mark Constraint Violations as manually resolved" msgstr "Markiere Constraintverletzungen als manuell behoben" -#: AKModel/admin.py:371 AKModel/views.py:422 +#: AKModel/admin.py:385 AKModel/views.py:441 msgid "Set Constraint Violations to level \"violation\"" msgstr "Constraintverletzungen auf Level \"Violation\" setzen" -#: AKModel/admin.py:376 AKModel/views.py:432 +#: AKModel/admin.py:390 AKModel/views.py:451 msgid "Set Constraint Violations to level \"warning\"" msgstr "Constraintverletzungen auf Level \"Warning\" setzen" @@ -105,17 +101,17 @@ msgstr "Die eingegebene Verfügbarkeit enthält ein ungültiges Datum." msgid "Please fill in your availabilities!" msgstr "Bitte Verfügbarkeiten eintragen!" -#: AKModel/availability/models.py:38 AKModel/models.py:56 AKModel/models.py:126 -#: AKModel/models.py:181 AKModel/models.py:200 AKModel/models.py:232 -#: AKModel/models.py:286 AKModel/models.py:352 AKModel/models.py:385 -#: AKModel/models.py:456 AKModel/models.py:497 +#: AKModel/availability/models.py:38 AKModel/models.py:56 AKModel/models.py:128 +#: AKModel/models.py:183 AKModel/models.py:202 AKModel/models.py:234 +#: AKModel/models.py:288 AKModel/models.py:354 AKModel/models.py:387 +#: AKModel/models.py:458 AKModel/models.py:499 msgid "Event" msgstr "Event" -#: AKModel/availability/models.py:39 AKModel/models.py:127 -#: AKModel/models.py:182 AKModel/models.py:201 AKModel/models.py:233 -#: AKModel/models.py:287 AKModel/models.py:353 AKModel/models.py:386 -#: AKModel/models.py:457 AKModel/models.py:498 +#: AKModel/availability/models.py:39 AKModel/models.py:129 +#: AKModel/models.py:184 AKModel/models.py:203 AKModel/models.py:235 +#: AKModel/models.py:289 AKModel/models.py:355 AKModel/models.py:388 +#: AKModel/models.py:459 AKModel/models.py:500 msgid "Associated event" msgstr "Zugehöriges Event" @@ -127,8 +123,8 @@ msgstr "Person" msgid "Person whose availability this is" msgstr "Person deren Verfügbarkeit hier abgebildet wird" -#: AKModel/availability/models.py:56 AKModel/models.py:356 -#: AKModel/models.py:375 AKModel/models.py:506 +#: AKModel/availability/models.py:56 AKModel/models.py:358 +#: AKModel/models.py:377 AKModel/models.py:508 msgid "Room" msgstr "Raum" @@ -136,8 +132,8 @@ msgstr "Raum" msgid "Room whose availability this is" msgstr "Raum dessen Verfügbarkeit hier abgebildet wird" -#: AKModel/availability/models.py:65 AKModel/models.py:292 -#: AKModel/models.py:374 AKModel/models.py:451 +#: AKModel/availability/models.py:65 AKModel/models.py:294 +#: AKModel/models.py:376 AKModel/models.py:453 msgid "AK" msgstr "AK" @@ -145,8 +141,8 @@ msgstr "AK" msgid "AK whose availability this is" msgstr "Verfügbarkeiten" -#: AKModel/availability/models.py:74 AKModel/models.py:185 -#: AKModel/models.py:512 +#: AKModel/availability/models.py:74 AKModel/models.py:187 +#: AKModel/models.py:514 msgid "AK Category" msgstr "AK-Kategorie" @@ -212,9 +208,9 @@ msgstr "" "fürWünsche markieren, z.B. um während der Präsentation auf einem Touchscreen " "ausgefüllt zu werden?" -#: AKModel/models.py:18 AKModel/models.py:173 AKModel/models.py:197 -#: AKModel/models.py:216 AKModel/models.py:230 AKModel/models.py:248 -#: AKModel/models.py:344 +#: AKModel/models.py:18 AKModel/models.py:175 AKModel/models.py:199 +#: AKModel/models.py:218 AKModel/models.py:232 AKModel/models.py:250 +#: AKModel/models.py:346 msgid "Name" msgstr "Name" @@ -248,7 +244,7 @@ msgstr "Zeitzone" msgid "Time Zone where this event takes place in" msgstr "Zeitzone in der das Event stattfindet" -#: AKModel/models.py:27 AKModel/views.py:241 +#: AKModel/models.py:27 AKModel/views.py:242 msgid "Start" msgstr "Start" @@ -356,71 +352,71 @@ msgstr "" msgid "Events" msgstr "Events" -#: AKModel/models.py:121 +#: AKModel/models.py:123 msgid "Nickname" msgstr "Spitzname" -#: AKModel/models.py:121 +#: AKModel/models.py:123 msgid "Name to identify an AK owner by" msgstr "Name, durch den eine AK-Leitung identifiziert wird" -#: AKModel/models.py:122 +#: AKModel/models.py:124 msgid "Slug" msgstr "Slug" -#: AKModel/models.py:122 +#: AKModel/models.py:124 msgid "Slug for URL generation" msgstr "Slug für URL-Generierung" -#: AKModel/models.py:123 +#: AKModel/models.py:125 msgid "Institution" msgstr "Instutution" -#: AKModel/models.py:123 +#: AKModel/models.py:125 msgid "Uni etc." msgstr "Universität o.ä." -#: AKModel/models.py:124 AKModel/models.py:257 +#: AKModel/models.py:126 AKModel/models.py:259 msgid "Web Link" msgstr "Internet Link" -#: AKModel/models.py:124 +#: AKModel/models.py:126 msgid "Link to Homepage" msgstr "Link zu Homepage oder Webseite" -#: AKModel/models.py:130 AKModel/models.py:505 +#: AKModel/models.py:132 AKModel/models.py:507 msgid "AK Owner" msgstr "AK-Leitung" -#: AKModel/models.py:131 +#: AKModel/models.py:133 msgid "AK Owners" msgstr "AK-Leitungen" -#: AKModel/models.py:173 +#: AKModel/models.py:175 msgid "Name of the AK Category" msgstr "Name der AK-Kategorie" -#: AKModel/models.py:174 AKModel/models.py:198 +#: AKModel/models.py:176 AKModel/models.py:200 msgid "Color" msgstr "Farbe" -#: AKModel/models.py:174 AKModel/models.py:198 +#: AKModel/models.py:176 AKModel/models.py:200 msgid "Color for displaying" msgstr "Farbe für die Anzeige" -#: AKModel/models.py:175 AKModel/models.py:251 +#: AKModel/models.py:177 AKModel/models.py:253 msgid "Description" msgstr "Beschreibung" -#: AKModel/models.py:176 +#: AKModel/models.py:178 msgid "Short description of this AK Category" msgstr "Beschreibung der AK-Kategorie" -#: AKModel/models.py:177 +#: AKModel/models.py:179 msgid "Present by default" msgstr "Defaultmäßig präsentieren" -#: AKModel/models.py:179 +#: AKModel/models.py:181 msgid "" "Present AKs of this category by default if AK owner did not specify whether " "this AK should be presented?" @@ -428,152 +424,152 @@ msgstr "" "AKs dieser Kategorie standardmäßig vorstellen, wenn die Leitungen das für " "ihren AK nicht explizit spezifiziert haben?" -#: AKModel/models.py:186 +#: AKModel/models.py:188 msgid "AK Categories" msgstr "AK-Kategorien" -#: AKModel/models.py:197 +#: AKModel/models.py:199 msgid "Name of the AK Track" msgstr "Name des AK-Tracks" -#: AKModel/models.py:204 +#: AKModel/models.py:206 msgid "AK Track" msgstr "AK-Track" -#: AKModel/models.py:205 +#: AKModel/models.py:207 msgid "AK Tracks" msgstr "AK-Tracks" -#: AKModel/models.py:216 +#: AKModel/models.py:218 msgid "Name of the AK Tag" msgstr "Name das AK-Tags" -#: AKModel/models.py:219 +#: AKModel/models.py:221 msgid "AK Tag" msgstr "AK-Tag" -#: AKModel/models.py:220 +#: AKModel/models.py:222 msgid "AK Tags" msgstr "AK-Tags" -#: AKModel/models.py:230 +#: AKModel/models.py:232 msgid "Name of the Requirement" msgstr "Name der Anforderung" -#: AKModel/models.py:236 AKModel/models.py:509 +#: AKModel/models.py:238 AKModel/models.py:511 msgid "AK Requirement" msgstr "AK-Anforderung" -#: AKModel/models.py:237 +#: AKModel/models.py:239 msgid "AK Requirements" msgstr "AK-Anforderungen" -#: AKModel/models.py:248 +#: AKModel/models.py:250 msgid "Name of the AK" msgstr "Name des AKs" -#: AKModel/models.py:249 +#: AKModel/models.py:251 msgid "Short Name" msgstr "Kurzer Name" -#: AKModel/models.py:250 +#: AKModel/models.py:252 msgid "Name displayed in the schedule" msgstr "Name zur Anzeige im AK-Plan" -#: AKModel/models.py:251 +#: AKModel/models.py:253 msgid "Description of the AK" msgstr "Beschreibung des AKs" -#: AKModel/models.py:253 +#: AKModel/models.py:255 msgid "Owners" msgstr "Leitungen" -#: AKModel/models.py:254 +#: AKModel/models.py:256 msgid "Those organizing the AK" msgstr "Menschen, die den AK organisieren und halten" -#: AKModel/models.py:257 +#: AKModel/models.py:259 msgid "Link to wiki page" msgstr "Link zur Wiki Seite" -#: AKModel/models.py:258 +#: AKModel/models.py:260 msgid "Protocol Link" msgstr "Protokolllink" -#: AKModel/models.py:258 +#: AKModel/models.py:260 msgid "Link to protocol" msgstr "Link zum Protokoll" -#: AKModel/models.py:260 +#: AKModel/models.py:262 msgid "Category" msgstr "Kategorie" -#: AKModel/models.py:261 +#: AKModel/models.py:263 msgid "Category of the AK" msgstr "Kategorie des AKs" -#: AKModel/models.py:262 +#: AKModel/models.py:264 msgid "Tags" msgstr "Tags" -#: AKModel/models.py:262 +#: AKModel/models.py:264 msgid "Tags provided by owners" msgstr "Tags, die durch die AK-Leitung vergeben wurden" -#: AKModel/models.py:263 +#: AKModel/models.py:265 msgid "Track" msgstr "Track" -#: AKModel/models.py:264 +#: AKModel/models.py:266 msgid "Track the AK belongs to" msgstr "Track zu dem der AK gehört" -#: AKModel/models.py:266 +#: AKModel/models.py:268 msgid "Resolution Intention" msgstr "Resolutionsabsicht" -#: AKModel/models.py:267 +#: AKModel/models.py:269 msgid "Intends to submit a resolution" msgstr "Beabsichtigt eine Resolution einzureichen" -#: AKModel/models.py:268 +#: AKModel/models.py:270 msgid "Present this AK" msgstr "AK präsentieren" -#: AKModel/models.py:269 +#: AKModel/models.py:271 msgid "Present results of this AK" msgstr "Die Ergebnisse dieses AKs vorstellen" -#: AKModel/models.py:271 AKModel/templates/admin/AKModel/status.html:95 +#: AKModel/models.py:273 AKModel/templates/admin/AKModel/status.html:102 msgid "Requirements" msgstr "Anforderungen" -#: AKModel/models.py:272 +#: AKModel/models.py:274 msgid "AK's Requirements" msgstr "Anforderungen des AKs" -#: AKModel/models.py:274 +#: AKModel/models.py:276 msgid "Conflicting AKs" msgstr "AK-Konflikte" -#: AKModel/models.py:275 +#: AKModel/models.py:277 msgid "AKs that conflict and thus must not take place at the same time" msgstr "" "AKs, die Konflikte haben und deshalb nicht gleichzeitig stattfinden dürfen" -#: AKModel/models.py:276 +#: AKModel/models.py:278 msgid "Prerequisite AKs" msgstr "Vorausgesetzte AKs" -#: AKModel/models.py:277 +#: AKModel/models.py:279 msgid "AKs that should precede this AK in the schedule" msgstr "AKs die im AK-Plan vor diesem AK stattfinden müssen" -#: AKModel/models.py:279 +#: AKModel/models.py:281 msgid "Organizational Notes" msgstr "Notizen zur Organisation" -#: AKModel/models.py:280 +#: AKModel/models.py:282 msgid "" "Notes to organizers. These are public. For private notes, please use the " "button for private messages on the detail page of this AK (after creation/" @@ -583,258 +579,258 @@ msgstr "" "Anmerkungen bitte den Button für Direktnachrichten verwenden (nach dem " "Anlegen/Bearbeiten)." -#: AKModel/models.py:282 +#: AKModel/models.py:284 msgid "Interest" msgstr "Interesse" -#: AKModel/models.py:282 +#: AKModel/models.py:284 msgid "Expected number of people" msgstr "Erwartete Personenzahl" -#: AKModel/models.py:283 +#: AKModel/models.py:285 msgid "Interest Counter" msgstr "Interessenszähler" -#: AKModel/models.py:284 +#: AKModel/models.py:286 msgid "People who have indicated interest online" msgstr "Anzahl Personen, die online Interesse bekundet haben" -#: AKModel/models.py:293 AKModel/models.py:500 -#: AKModel/templates/admin/AKModel/status.html:49 -#: AKModel/templates/admin/AKModel/status.html:56 AKModel/views.py:359 +#: AKModel/models.py:295 AKModel/models.py:502 +#: AKModel/templates/admin/AKModel/status.html:56 +#: AKModel/templates/admin/AKModel/status.html:63 AKModel/views.py:360 msgid "AKs" msgstr "AKs" -#: AKModel/models.py:344 +#: AKModel/models.py:346 msgid "Name or number of the room" msgstr "Name oder Nummer des Raums" -#: AKModel/models.py:345 +#: AKModel/models.py:347 msgid "Location" msgstr "Ort" -#: AKModel/models.py:346 +#: AKModel/models.py:348 msgid "Name or number of the location" msgstr "Name oder Nummer des Ortes" -#: AKModel/models.py:347 +#: AKModel/models.py:349 msgid "Capacity" msgstr "Kapazität" -#: AKModel/models.py:348 +#: AKModel/models.py:350 msgid "Maximum number of people (-1 for unlimited)." msgstr "Maximale Personenzahl (-1 wenn unbeschränkt)." -#: AKModel/models.py:349 +#: AKModel/models.py:351 msgid "Properties" msgstr "Eigenschaften" -#: AKModel/models.py:350 +#: AKModel/models.py:352 msgid "AK requirements fulfilled by the room" msgstr "AK-Anforderungen, die dieser Raum erfüllt" -#: AKModel/models.py:357 AKModel/templates/admin/AKModel/status.html:33 +#: AKModel/models.py:359 AKModel/templates/admin/AKModel/status.html:40 msgid "Rooms" msgstr "Räume" -#: AKModel/models.py:374 +#: AKModel/models.py:376 msgid "AK being mapped" msgstr "AK, der zugeordnet wird" -#: AKModel/models.py:376 +#: AKModel/models.py:378 msgid "Room the AK will take place in" msgstr "Raum in dem der AK stattfindet" -#: AKModel/models.py:377 +#: AKModel/models.py:379 msgid "Slot Begin" msgstr "Beginn des Slots" -#: AKModel/models.py:377 +#: AKModel/models.py:379 msgid "Time and date the slot begins" msgstr "Zeit und Datum zu der der AK beginnt" -#: AKModel/models.py:379 +#: AKModel/models.py:381 msgid "Duration" msgstr "Dauer" -#: AKModel/models.py:380 +#: AKModel/models.py:382 msgid "Length in hours" msgstr "Länge in Stunden" -#: AKModel/models.py:382 +#: AKModel/models.py:384 msgid "Scheduling fixed" msgstr "Planung fix" -#: AKModel/models.py:383 +#: AKModel/models.py:385 msgid "Length and time of this AK should not be changed" msgstr "Dauer und Zeit dieses AKs sollten nicht verändert werden" -#: AKModel/models.py:388 +#: AKModel/models.py:390 msgid "Last update" msgstr "Letzte Aktualisierung" -#: AKModel/models.py:391 +#: AKModel/models.py:393 msgid "AK Slot" msgstr "AK-Slot" -#: AKModel/models.py:392 AKModel/models.py:502 +#: AKModel/models.py:394 AKModel/models.py:504 msgid "AK Slots" msgstr "AK-Slot" -#: AKModel/models.py:414 AKModel/models.py:423 +#: AKModel/models.py:416 AKModel/models.py:425 msgid "Not scheduled yet" msgstr "Noch nicht geplant" -#: AKModel/models.py:452 +#: AKModel/models.py:454 msgid "AK this message belongs to" msgstr "AK zu dem die Nachricht gehört" -#: AKModel/models.py:453 +#: AKModel/models.py:455 msgid "Message text" msgstr "Nachrichtentext" -#: AKModel/models.py:454 +#: AKModel/models.py:456 msgid "Message to the organizers. This is not publicly visible." msgstr "" "Nachricht an die Organisator*innen. Diese ist nicht öffentlich sichtbar." -#: AKModel/models.py:460 +#: AKModel/models.py:462 msgid "AK Orga Message" msgstr "AK-Organachricht" -#: AKModel/models.py:461 +#: AKModel/models.py:463 msgid "AK Orga Messages" msgstr "AK-Organachrichten" -#: AKModel/models.py:470 +#: AKModel/models.py:472 msgid "Constraint Violation" msgstr "Constraintverletzung" -#: AKModel/models.py:471 AKModel/templates/admin/AKModel/status.html:79 +#: AKModel/models.py:473 AKModel/templates/admin/AKModel/status.html:86 msgid "Constraint Violations" msgstr "Constraintverletzungen" -#: AKModel/models.py:475 +#: AKModel/models.py:477 msgid "Owner has two parallel slots" msgstr "Leitung hat zwei Slots parallel" -#: AKModel/models.py:476 +#: AKModel/models.py:478 msgid "AK Slot was scheduled outside the AK's availabilities" msgstr "AK Slot wurde außerhalb der Verfügbarkeit des AKs platziert" -#: AKModel/models.py:477 +#: AKModel/models.py:479 msgid "Room has two AK slots scheduled at the same time" msgstr "Raum hat zwei AK Slots gleichzeitig" -#: AKModel/models.py:478 +#: AKModel/models.py:480 msgid "Room does not satisfy the requirement of the scheduled AK" msgstr "Room erfüllt die Anforderungen des platzierten AKs nicht" -#: AKModel/models.py:479 +#: AKModel/models.py:481 msgid "AK Slot is scheduled at the same time as an AK listed as a conflict" msgstr "" "AK Slot wurde wurde zur gleichen Zeit wie ein Konflikt des AKs platziert" -#: AKModel/models.py:480 +#: AKModel/models.py:482 msgid "AK Slot is scheduled before an AK listed as a prerequisite" msgstr "AK Slot wurde vor einem als Voraussetzung gelisteten AK platziert" -#: AKModel/models.py:482 +#: AKModel/models.py:484 msgid "" "AK Slot for AK with intention to submit a resolution is scheduled after " "resolution deadline" msgstr "" "AK Slot eines AKs mit Resoabsicht wurde nach der Resodeadline platziert" -#: AKModel/models.py:483 +#: AKModel/models.py:485 msgid "AK Slot in a category is outside that categories availabilities" msgstr "AK Slot wurde außerhalb der Verfügbarkeiten seiner Kategorie" -#: AKModel/models.py:484 +#: AKModel/models.py:486 msgid "Two AK Slots for the same AK scheduled at the same time" msgstr "Zwei AK Slots eines AKs wurden zur selben Zeit platziert" -#: AKModel/models.py:485 +#: AKModel/models.py:487 msgid "Room does not have enough space for interest in scheduled AK Slot" msgstr "Room hat nicht genug Platz für das Interesse am geplanten AK-Slot" -#: AKModel/models.py:486 +#: AKModel/models.py:488 msgid "AK Slot is scheduled outside the event's availabilities" msgstr "AK Slot wurde außerhalb der Verfügbarkeit des Events platziert" -#: AKModel/models.py:489 +#: AKModel/models.py:491 msgid "Warning" msgstr "Warnung" -#: AKModel/models.py:490 +#: AKModel/models.py:492 msgid "Violation" msgstr "Verletzung" -#: AKModel/models.py:492 +#: AKModel/models.py:494 msgid "Type" msgstr "Art" -#: AKModel/models.py:493 +#: AKModel/models.py:495 msgid "Type of violation, i.e. what kind of constraint was violated" msgstr "Art der Verletzung, gibt an welche Art Constraint verletzt wurde" -#: AKModel/models.py:494 +#: AKModel/models.py:496 msgid "Level" msgstr "Level" -#: AKModel/models.py:495 +#: AKModel/models.py:497 msgid "Severity level of the violation" msgstr "Schweregrad der Verletzung" -#: AKModel/models.py:501 +#: AKModel/models.py:503 msgid "AK(s) belonging to this constraint" msgstr "AK(s), die zu diesem Constraint gehören" -#: AKModel/models.py:503 +#: AKModel/models.py:505 msgid "AK Slot(s) belonging to this constraint" msgstr "AK Slot(s), die zu diesem Constraint gehören" -#: AKModel/models.py:505 +#: AKModel/models.py:507 msgid "AK Owner belonging to this constraint" msgstr "AK Leitung(en), die zu diesem Constraint gehören" -#: AKModel/models.py:507 +#: AKModel/models.py:509 msgid "Room belonging to this constraint" msgstr "Raum, der zu diesem Constraint gehört" -#: AKModel/models.py:510 +#: AKModel/models.py:512 msgid "AK Requirement belonging to this constraint" msgstr "AK Anforderung, die zu diesem Constraint gehört" -#: AKModel/models.py:512 +#: AKModel/models.py:514 msgid "AK Category belonging to this constraint" msgstr "AK Kategorie, di zu diesem Constraint gehört" -#: AKModel/models.py:514 +#: AKModel/models.py:516 msgid "Comment" msgstr "Kommentar" -#: AKModel/models.py:514 +#: AKModel/models.py:516 msgid "Comment or further details for this violation" msgstr "Kommentar oder weitere Details zu dieser Vereletzung" -#: AKModel/models.py:517 +#: AKModel/models.py:519 msgid "Timestamp" msgstr "Timestamp" -#: AKModel/models.py:517 +#: AKModel/models.py:519 msgid "Time of creation" msgstr "Zeitpunkt der ERstellung" -#: AKModel/models.py:518 +#: AKModel/models.py:520 msgid "Manually Resolved" msgstr "Manuell behoben" -#: AKModel/models.py:519 +#: AKModel/models.py:521 msgid "Mark this violation manually as resolved" msgstr "Markiere diese Verletzung manuell als behoben" -#: AKModel/models.py:546 +#: AKModel/models.py:548 #: AKModel/templates/admin/AKModel/requirements_overview.html:27 msgid "Details" msgstr "Details" @@ -886,7 +882,7 @@ msgid "Successfully imported.<br><br>Do you want to activate your event now?" msgstr "Erfolgreich importiert.<br><br>Soll das Event jetzt aktiviert werden?" #: AKModel/templates/admin/AKModel/event_wizard/activate.html:27 -#: AKModel/views.py:246 +#: AKModel/views.py:247 msgid "Finish" msgstr "Abschluss" @@ -951,84 +947,88 @@ msgid "No AKs with this requirement" msgstr "Kein AK mit dieser Anforderung" #: AKModel/templates/admin/AKModel/requirements_overview.html:45 -#: AKModel/templates/admin/AKModel/status.html:111 +#: AKModel/templates/admin/AKModel/status.html:118 msgid "Add Requirement" msgstr "Anforderung hinzufügen" -#: AKModel/templates/admin/AKModel/status.html:16 +#: AKModel/templates/admin/AKModel/status.html:18 +msgid "Plan published?" +msgstr "Plan veröffentlicht?" + +#: AKModel/templates/admin/AKModel/status.html:23 msgid "Categories" msgstr "Kategorien" -#: AKModel/templates/admin/AKModel/status.html:18 +#: AKModel/templates/admin/AKModel/status.html:25 msgid "No categories yet" msgstr "Bisher keine Kategorien" -#: AKModel/templates/admin/AKModel/status.html:31 +#: AKModel/templates/admin/AKModel/status.html:38 msgid "Add category" msgstr "Kategorie hinzufügen" -#: AKModel/templates/admin/AKModel/status.html:35 +#: AKModel/templates/admin/AKModel/status.html:42 msgid "No rooms yet" msgstr "Bisher keine Räume" -#: AKModel/templates/admin/AKModel/status.html:47 +#: AKModel/templates/admin/AKModel/status.html:54 msgid "Add Room" msgstr "Raum hinzufügen" -#: AKModel/templates/admin/AKModel/status.html:51 +#: AKModel/templates/admin/AKModel/status.html:58 msgid "No AKs yet" msgstr "Bisher keine AKs" -#: AKModel/templates/admin/AKModel/status.html:59 +#: AKModel/templates/admin/AKModel/status.html:66 msgid "Slots" msgstr "Slots" -#: AKModel/templates/admin/AKModel/status.html:62 +#: AKModel/templates/admin/AKModel/status.html:69 msgid "Unscheduled Slots" msgstr "Ungeplante Slots" -#: AKModel/templates/admin/AKModel/status.html:76 +#: AKModel/templates/admin/AKModel/status.html:83 #: AKModel/templates/admin/ak_index.html:16 msgid "Scheduling" msgstr "Scheduling" -#: AKModel/templates/admin/AKModel/status.html:81 +#: AKModel/templates/admin/AKModel/status.html:88 msgid "AKs requiring special attention" msgstr "AKs, die besondere Aufmerksamkeit benötigen" -#: AKModel/templates/admin/AKModel/status.html:83 +#: AKModel/templates/admin/AKModel/status.html:90 msgid "Enter Interest" msgstr "Interesse erfassen" -#: AKModel/templates/admin/AKModel/status.html:86 +#: AKModel/templates/admin/AKModel/status.html:93 msgid "Manage ak tracks" msgstr "AK-Tracks verwalten" -#: AKModel/templates/admin/AKModel/status.html:88 +#: AKModel/templates/admin/AKModel/status.html:95 msgid "Export AKs as CSV" msgstr "AKs als CSV exportieren" -#: AKModel/templates/admin/AKModel/status.html:90 +#: AKModel/templates/admin/AKModel/status.html:97 msgid "Export AKs for Wiki" msgstr "AKs im Wiki-Format exportieren" -#: AKModel/templates/admin/AKModel/status.html:92 AKModel/views.py:329 +#: AKModel/templates/admin/AKModel/status.html:99 AKModel/views.py:330 msgid "Export AK Slides" msgstr "AK-Folien exportieren" -#: AKModel/templates/admin/AKModel/status.html:97 +#: AKModel/templates/admin/AKModel/status.html:104 msgid "No requirements yet" msgstr "Bisher keine Anforderungen" -#: AKModel/templates/admin/AKModel/status.html:110 +#: AKModel/templates/admin/AKModel/status.html:117 msgid "Show AKs for requirements" msgstr "Zu Anforderungen gehörige AKs anzeigen" -#: AKModel/templates/admin/AKModel/status.html:114 +#: AKModel/templates/admin/AKModel/status.html:121 msgid "Messages" msgstr "Nachrichten" -#: AKModel/templates/admin/AKModel/status.html:116 +#: AKModel/templates/admin/AKModel/status.html:123 msgid "Delete all messages" msgstr "Alle Nachrichten löschen" @@ -1065,120 +1065,136 @@ msgstr "Login" msgid "Register" msgstr "Registrieren" -#: AKModel/views.py:147 +#: AKModel/views.py:148 msgid "Event Status" msgstr "Eventstatus" -#: AKModel/views.py:160 +#: AKModel/views.py:161 msgid "Requirements for Event" msgstr "Anforderungen für das Event" -#: AKModel/views.py:174 +#: AKModel/views.py:175 msgid "AK CSV Export" msgstr "AK-CSV-Export" -#: AKModel/views.py:188 +#: AKModel/views.py:189 msgid "AK Wiki Export" msgstr "AK-Wiki-Export" -#: AKModel/views.py:196 AKModel/views.py:345 +#: AKModel/views.py:197 AKModel/views.py:346 msgid "Wishes" msgstr "Wünsche" -#: AKModel/views.py:217 +#: AKModel/views.py:218 msgid "Delete AK Orga Messages" msgstr "AK-Organachrichten löschen" -#: AKModel/views.py:232 +#: AKModel/views.py:233 msgid "AK Orga Messages successfully deleted" msgstr "AK-Organachrichten erfolgreich gelöscht" -#: AKModel/views.py:242 +#: AKModel/views.py:243 msgid "Settings" msgstr "Einstellungen" -#: AKModel/views.py:243 +#: AKModel/views.py:244 msgid "Event created, Prepare Import" msgstr "Event angelegt, Import vorbereiten" -#: AKModel/views.py:244 +#: AKModel/views.py:245 msgid "Import categories & requirements" msgstr "Kategorien & Anforderungen kopieren" -#: AKModel/views.py:245 +#: AKModel/views.py:246 msgid "Activate?" msgstr "Aktivieren?" -#: AKModel/views.py:304 +#: AKModel/views.py:305 #, python-format msgid "Copied '%(obj)s'" msgstr "'%(obj)s' kopiert" -#: AKModel/views.py:307 +#: AKModel/views.py:308 #, python-format msgid "Could not copy '%(obj)s' (%(error)s)" msgstr "'%(obj)s' konnte nicht kopiert werden (%(error)s)" -#: AKModel/views.py:340 +#: AKModel/views.py:341 msgid "Symbols" msgstr "Symbole" -#: AKModel/views.py:341 +#: AKModel/views.py:342 msgid "Who?" msgstr "Wer?" -#: AKModel/views.py:342 +#: AKModel/views.py:343 msgid "Duration(s)" msgstr "Dauer(n)" -#: AKModel/views.py:343 +#: AKModel/views.py:344 msgid "Reso intention?" msgstr "Resolutionsabsicht?" -#: AKModel/views.py:344 +#: AKModel/views.py:345 msgid "Category (for Wishes)" msgstr "Kategorie (für Wünsche)" -#: AKModel/views.py:414 +#: AKModel/views.py:433 msgid "The following Constraint Violations will be marked as manually resolved" msgstr "" "Die folgenden Constraintverletzungen werden als manuell behoben markiert." -#: AKModel/views.py:415 +#: AKModel/views.py:434 msgid "Constraint Violations marked as resolved" msgstr "Constraintverletzungen als manuell behoben markiert" -#: AKModel/views.py:424 +#: AKModel/views.py:443 msgid "The following Constraint Violations will be set to level 'violation'" msgstr "" "Die folgenden Constraintverletzungen werden auf das Level \"Violation\" " "gesetzt." -#: AKModel/views.py:425 +#: AKModel/views.py:444 msgid "Constraint Violations set to level 'violation'" msgstr "Constraintverletzungen auf Level \"Violation\" gesetzt" -#: AKModel/views.py:434 +#: AKModel/views.py:453 msgid "The following Constraint Violations will be set to level 'warning'" msgstr "" "Die folgenden Constraintverletzungen werden auf das Level 'warning' gesetzt." -#: AKModel/views.py:435 +#: AKModel/views.py:454 msgid "Constraint Violations set to level 'warning'" msgstr "Constraintverletzungen auf Level \"Warning\" gesetzt" -#: AKModel/views.py:444 +#: AKModel/views.py:463 msgid "Interest of the following AKs will be set to not filled (-1):" msgstr "Interesse an den folgenden AKs wird auf nicht ausgefüllt (-1) gesetzt:" -#: AKModel/views.py:445 +#: AKModel/views.py:464 msgid "Reset of interest in AKs successful." msgstr "Interesse an AKs erfolgreich zurückgesetzt." -#: AKModel/views.py:454 +#: AKModel/views.py:473 msgid "Interest counter of the following AKs will be set to 0:" msgstr "Interessensbekundungszähler der folgenden AKs wird auf 0 gesetzt:" -#: AKModel/views.py:455 +#: AKModel/views.py:474 msgid "AKs' interest counters set back to 0." msgstr "Interessenszähler der AKs zurückgesetzt" + +#: AKModel/views.py:483 +msgid "Publish the plan(s) of:" +msgstr "Den Plan/die Pläne veröffentlichen von:" + +#: AKModel/views.py:484 +msgid "Plan published" +msgstr "Plan veröffentlicht" + +#: AKModel/views.py:493 +msgid "Unpublish the plan(s) of:" +msgstr "Den Plan/die Pläne verbergen von:" + +#: AKModel/views.py:494 +msgid "Plan unpublished" +msgstr "Plan verborgen" diff --git a/AKModel/templates/admin/AKModel/status.html b/AKModel/templates/admin/AKModel/status.html index 19d753c9..d279efea 100644 --- a/AKModel/templates/admin/AKModel/status.html +++ b/AKModel/templates/admin/AKModel/status.html @@ -11,6 +11,13 @@ <h2><a href="{% url 'admin:AKModel_event_change' event.pk %}">{{event}}</a></h2> <h5>{{ event.start }} - {{ event.end }}</h5> + <div class="custom-control custom-switch mt-2 mb-2"> + <input type="checkbox" class="custom-control-input" id="planPublishedSwitch" + {% if not event.plan_hidden %}checked{% endif %} + onclick="location.href='{% if event.plan_hidden %}{% url 'admin:plan-publish' %}{% else %}{% url 'admin:plan-unpublish' %}{% endif %}?pks={{event.pk}}';"> + <label class="custom-control-label" for="planPublishedSwitch">{% trans "Plan published?" %}</label> + </div> + <div class="row"> <div class="col-md-8"> <h3 class="block-header">{% trans "Categories" %}</h3> diff --git a/AKModel/views.py b/AKModel/views.py index ea9435af..9bb8edc0 100644 --- a/AKModel/views.py +++ b/AKModel/views.py @@ -4,6 +4,7 @@ from abc import ABC, abstractmethod from itertools import zip_longest from django.contrib import admin, messages +from django.db.models.functions import Now from django.shortcuts import get_object_or_404, redirect from django.urls import reverse_lazy, reverse from django.utils.translation import gettext_lazy as _ @@ -474,3 +475,23 @@ class AKResetInterestCounterView(IntermediateAdminActionView): def action(self, form): self.entities.update(interest_counter=0) + + +class PlanPublishView(IntermediateAdminActionView): + title = _('Publish plan') + model = Event + confirmation_message = _('Publish the plan(s) of:') + success_message = _('Plan published') + + def action(self, form): + self.entities.update(plan_published_at=Now(), plan_hidden=False) + + +class PlanUnpublishView(IntermediateAdminActionView): + title = _('Unpublish plan') + model = Event + confirmation_message = _('Unpublish the plan(s) of:') + success_message = _('Plan unpublished') + + def action(self, form): + self.entities.update(plan_published_at=None, plan_hidden=True) -- GitLab