diff --git a/src/backoffice/locale/de/LC_MESSAGES/django.po b/src/backoffice/locale/de/LC_MESSAGES/django.po index 3624aaca34315cc12db64c588cff90bdd0b981ac..cbe5fdbb32759f1883961f6aa1c60db3e1f41672 100644 --- a/src/backoffice/locale/de/LC_MESSAGES/django.po +++ b/src/backoffice/locale/de/LC_MESSAGES/django.po @@ -819,6 +819,9 @@ msgstr "Karte" msgid "nav_moderation" msgstr "Moderation" +msgid "nav_conference_admin" +msgstr "Konferenz" + msgid "nav_wiki" msgstr "Wiki" @@ -852,6 +855,45 @@ msgstr "alle" msgid "backoffice__not_a_conference_member" msgstr "Das Nutzerkonto, mit dem du gerade angemeldet bist, ist zur Zeit nicht mit einem Veranstaltungsticket verknüpft. Wenn Du gerade beim Aufbau hilfst, ist das kein Problem. Denk aber bitte daran, rechtzeitig ein Ticket zu kaufen und dies kurz vor Veranstaltungsbeginn mit deinem Nutzerkonto zu verknüpfen. Ansonsten kannst Du mit diesem Nutzerkonto nicht an der Veranstaltung teilnehmen." +msgid "create" +msgstr "Erstellen" + +msgid "Conference__recall__warning__header" +msgstr "Konferenz wirklich zurücknehmen?" + +msgid "Conference__recall__warning__text" +msgstr "Mit dieser Aktion wird die Konferenz zurückgenommen und ist ab diesem Zeitpunkt nicht mehr öffentlich sichtbar!" + +msgid "Conference__recall__submit" +msgstr "Konferenz zurücknehmen" + +msgid "Conference__publish__warning__header" +msgstr "Konferenz wirklich veröffentlichen?" + +msgid "Conference__publish__warning__text" +msgstr "Bitte stelle sicher, dass alle Informationen der Konferenz korrekt sind. Mit dieser Aktion wird die Konferenz für die Öffentlichkeit sichtbar!" + +msgid "Conference__publish__submit" +msgstr "Konferenz veröffentlichen" + +msgid "create conference" +msgstr "Konferenz erstellen" + +msgid "edit conference" +msgstr "Konferenz bearbeiten" + +msgid "Conference__recall__introduction" +msgstr "Die Konferenz ist aktuell sichtbar und du kannst es mittels des Öffentlichen Links besuchen. Zusätzlich kannst du die Veranstaltung auch wieder zurücknehmen." + +msgid "Conference__publish__introduction" +msgstr "Die Konferenz ist aktuell noch nicht öffentlich! Mit der Veröffentlichung wird diese Konferenz für alle sichtbar. Bitte kontrolliere vorher alle Daten!" + +msgid "Conference__edit-metadata" +msgstr "Konferenz-Daten" + +msgid "Conference__submit" +msgstr "Konferenz speichern" + msgid "Conferences__selection__header" msgstr "Konferenz auswählen" @@ -1177,9 +1219,6 @@ msgstr "Self-organized Projekte" msgid "Project__So__create" msgstr "Self-organized Projekt erstellen" -msgid "create" -msgstr "Erstellen" - msgid "Project__recall__warning__header" msgstr "Projekt wirklich zurücknehmen?" @@ -1829,6 +1868,30 @@ msgstr "abgelehnt" msgid "nav_channels_hidden" msgstr "versteckt" +msgid "nav_conference" +msgstr "Konferenz" + +msgid "Conference__Publication" +msgstr "Veröffentlichung" + +msgid "Conference__publish__success" +msgstr "Die Konferenz wurde erfolgreich veröffentlicht! Viel Spaß!" + +msgid "Conference__recall__success" +msgstr "Die Konferenz wurde erfolgreich zurückgenommen." + +msgid "Conference__create__success" +msgstr "Die Konferenz wurde erfolgreich angelegt!" + +msgid "Conference__update__success" +msgstr "Die Veröffentlichungsinformationen der Konferenz wurden angepasst." + +msgid "Conference__publish__failed" +msgstr "Beim veröffentlichen der Konferenz ist ein Fehler aufgetreten" + +msgid "Conference__form__invalid" +msgstr "Die angegebenen Daten zur Konferenz sind fehlerhaft!" + #, python-format msgid "Event__publish__failed %(event_type)s" msgstr "Fehler beim veröffentlichen der %(event_type)s!" diff --git a/src/backoffice/locale/en/LC_MESSAGES/django.po b/src/backoffice/locale/en/LC_MESSAGES/django.po index 1ce5dc96d2dbe033cadd85f826756d61044dcbc1..9b36b74b224e47ac947cb0bd56aac286e5dec2ac 100644 --- a/src/backoffice/locale/en/LC_MESSAGES/django.po +++ b/src/backoffice/locale/en/LC_MESSAGES/django.po @@ -818,6 +818,9 @@ msgstr "map" msgid "nav_moderation" msgstr "moderation" +msgid "nav_conference_admin" +msgstr "Conference" + msgid "nav_wiki" msgstr "Wiki" @@ -851,6 +854,45 @@ msgstr "all" msgid "backoffice__not_a_conference_member" msgstr "The user account you are currently logged in with is not linked to an valid event ticket. If you are helping with the set-up, this is not a problem. But please remember to buy a ticket in time and link it to your user account. Otherwise you will not be able to participate in the event with this user account. Linking the ticket to the user account will be available directly before the event." +msgid "create" +msgstr "" + +msgid "Conference__recall__warning__header" +msgstr "Do you really want to recall the conference?" + +msgid "Conference__recall__warning__text" +msgstr "With this action, the conference is recalled and is no longer publicly visible from this point on!" + +msgid "Conference__recall__submit" +msgstr "Recall conference" + +msgid "Conference__publish__warning__header" +msgstr "Really publish conference?" + +msgid "Conference__publish__warning__text" +msgstr "Please make sure that all conference information is correct. This action will make the conference visible to the public!" + +msgid "Conference__publish__submit" +msgstr "Publish conference" + +msgid "create conference" +msgstr "Create Conference" + +msgid "edit conference" +msgstr "Edit Conference" + +msgid "Conference__recall__introduction" +msgstr "The conference is currently visible and you can visit it using the public link. You can also cancel the conference again." + +msgid "Conference__publish__introduction" +msgstr "The conference is currently not yet public! With the publication this conference will be visible for everyone. Please check all data beforehand!" + +msgid "Conference__edit-metadata" +msgstr "conference data" + +msgid "Conference__submit" +msgstr "Recall conference" + msgid "Conferences__selection__header" msgstr "Select Conference" @@ -1184,9 +1226,6 @@ msgstr "Self-organized project" msgid "Project__So__create" msgstr "Create self-organized project" -msgid "create" -msgstr "" - msgid "Project__recall__warning__header" msgstr "Do you really recall the event?" @@ -1836,6 +1875,30 @@ msgstr "rejected" msgid "nav_channels_hidden" msgstr "hidden" +msgid "nav_conference" +msgstr "Conference" + +msgid "Conference__Publication" +msgstr "Publication Settings" + +msgid "Conference__publish__success" +msgstr "Conference was successfully published! Have fun!" + +msgid "Conference__recall__success" +msgstr "Conference was successfully recalled." + +msgid "Conference__create__success" +msgstr "Conference was successfully crewated." + +msgid "Conference__update__success" +msgstr "Conference was successfully updated." + +msgid "Conference__publish__failed" +msgstr "Failed to publish the conference!" + +msgid "Conference__form__invalid" +msgstr "Conference data you entered is invalid!" + #, python-format msgid "Event__publish__failed %(event_type)s" msgstr "Error while publishing the %(event_type)s" @@ -1968,8 +2031,3 @@ msgstr "sessions" msgid "wa_textures" msgstr "textures" - -#, fuzzy -#~| msgid "Conference" -#~ msgid "nav_conference" -#~ msgstr "Conference" diff --git a/src/backoffice/templates/backoffice/base.html b/src/backoffice/templates/backoffice/base.html index 71b80a48ece412d4546d89cc5342863012f1bad6..922d681b962e8661184e9a5941f6582bc34c342d 100644 --- a/src/backoffice/templates/backoffice/base.html +++ b/src/backoffice/templates/backoffice/base.html @@ -54,6 +54,11 @@ <a class="nav-link{% if active_page == 'moderation' %} active{% endif %}" href="{% url 'backoffice:moderation' %}">{% trans "nav_moderation" %}{% if active_page == 'moderation' %} <span class="visually-hidden">{{ activetab_srmarker }}</span>{% endif %}</a> </li> {% endif %} + {% if has_conference_admin %} + <li class="nav-item"> + <a class="nav-link{% if active_page == 'conference_admin' %} active{% endif %}" href="{% url 'backoffice:conference-publication' conference.id %}">{% trans "nav_conference_admin" %}{% if active_page == 'conference_admin' %} <span class="visually-hidden">{{ activetab_srmarker }}</span>{% endif %}</a> + </li> + {% endif %} {% if has_pages %} <li class="nav-item"> <a class="nav-link{% if active_page == 'wiki' %} active{% endif %}" href="{% url 'backoffice:wiki' %}">{% trans "nav_wiki" %}{% if active_page == 'wiki' %} <span class="visually-hidden">{{ activetab_srmarker }}</span>{% endif %}</a> diff --git a/src/backoffice/templates/backoffice/conferences/publication_edit.html b/src/backoffice/templates/backoffice/conferences/publication_edit.html new file mode 100644 index 0000000000000000000000000000000000000000..760369f3481bb2569b83b3ed8c903f2d5676f5c3 --- /dev/null +++ b/src/backoffice/templates/backoffice/conferences/publication_edit.html @@ -0,0 +1,120 @@ +{% extends 'backoffice/base.html' %} +{% load django_bootstrap5 %} +{% load i18n %} +{% load static %} +{% block title %} + {% if form.create %} + {% trans 'create' %} + {% else %} + {{ form.instance.name }} + {% endif %} +{% endblock title %} +{% block scripts %} + <script src="{% static "backoffice/modal.js" %}"></script> + <script> + $(document).ready(() => { + showModal = registerModal() + publishConference = document.getElementById('publishConference'); + if(publishConference){ + document.getElementById('publishConference').addEventListener('click', (e) => { + e.preventDefault(); + if (document.getElementById('id_is_public').value === "True"){ + showModal( + () => { + form = document.getElementById('ConferenceForm'); + form.action = publishConference.formAction + form.submit() + }, + 'warning', + '{% trans "Conference__recall__warning__header" %}', + '{% trans "Conference__recall__warning__text" %}', + '{% trans "Conference__recall__submit" %}') + } else { + showModal( + () => { + form = document.getElementById('ConferenceForm'); + form.action = publishConference.formAction + form.submit() + }, + 'warning', + '{% trans "Conference__publish__warning__header" %}', + '{% trans "Conference__publish__warning__text" %}', + '{% trans "Conference__publish__submit" %}') + } + }) + }; + }); + </script> +{% endblock scripts %} +{% block content %} + {% url 'backoffice:conference-publication' pk=form.instance.id assembly=form.instance.assembly.id as edit_url %} + <form method="POST" enctype="multipart/form-data" id="ConferenceForm"> + {% csrf_token %} + <div class="card border-default"> + <div class="card-header bg-default"> + {% if form.create %} + {% blocktrans %}create conference{% endblocktrans %} + {% else %} + {% blocktrans %}edit conference{% endblocktrans %} + {% endif %} + </div> + <div class="card-body"> + {% if has_form_perms and form.instance.is_public and not form.create %} + <div class="alert alert-success d-flex"> + <div class="flex-grow-0 pe-3"> + <i class="bi bi-megaphone fs-1"></i> + </div> + <div class="flex-grow-1 px-3">{% blocktrans %}Conference__recall__introduction{% endblocktrans %}</div> + <div class="d-inline-flex gap-2 align-items-start"> + <a class="float-end btn btn-info me-2" + href="{% url 'plainui:index' %}">{% trans 'public_link' %}</a> + <button class="btn btn-warning float-end" + id="publishConference" + formaction="{{ edit_url }}?recall=true">{% trans "Conference__recall__submit" %}</button> + </div> + </div> + {% elif has_form_perms and not form.create %} + <div class="alert alert-warning d-flex"> + <div class="flex-grow-0 pe-3"> + <i class="bi bi-eye-slash fs-1"></i> + </div> + <div class="flex-grow-1 px-3">{% blocktrans %}Conference__publish__introduction{% endblocktrans %}</div> + <div class="d-inline-flex gap-2 align-items-start"> + <button class="btn btn-primary float-end" + id="publishConference" + formaction="{{ edit_url }}?publish=true" + {% if publication_errors %}disabled{% endif %}>{% trans "Conference__publish__submit" %}</button> + </div> + </div> + {% endif %} + {% if form.errors %}<div class="alert alert-danger">{{ form.errors }}</div>{% endif %} + + <input id="id_is_public" + type="hidden" + name="{{ form.is_public.name }}" + value="{{ form.is_public.value }}"> + + <p class="fw-bold border-bottom mb-3">{% trans "Conference__edit-metadata" %}</p> + <div class="row mb-3"> + <div class="col-md-4">{% bootstrap_field form.name %}</div> + <div class="col-md-4">{% bootstrap_field form.slug %}</div> + <div class="col-md-4">{% bootstrap_field form.timezone %}</div> + </div> + <div class="row mb-3"> + <div class="col-md-4">{% bootstrap_field form.start %}</div> + <div class="col-md-4">{% bootstrap_field form.end %}</div> + <div class="col-md-4">{% bootstrap_field form.publication_date %}</div> + </div> + <div class="row mb-3"> + <div class="col-md-12">{% bootstrap_field form.global_notification %}</div> + </div> + </div> + {% if has_form_perms %} + {% trans 'Conference__submit' as button_text %} + <div class="card-footer"> + {% bootstrap_button button_text button_type="submit" button_class="btn-primary float-end" %} + </div> + {% endif %} + </div> + </form> +{% endblock content %} diff --git a/src/backoffice/urls.py b/src/backoffice/urls.py index 748dfa12c6191b0d7527377d21f97450c31732da..02d825e119847531a65d9cb3b2d911e3e24ec0da 100644 --- a/src/backoffice/urls.py +++ b/src/backoffice/urls.py @@ -1,7 +1,10 @@ from django.urls import path, re_path from django.views.generic import RedirectView -from backoffice.views.conferences import ConferenceSelectionView +from backoffice.views.conferences import ( + ConferencePublicationView, + ConferenceSelectionView, +) from backoffice.views.map import ( FloorCreateView, FloorListView, @@ -49,6 +52,7 @@ urlpatterns = [ path('logout', auth.LogoutView.as_view(), name='logout'), path('auth_debug', auth.AuthDebugView.as_view()), path('conferences', ConferenceSelectionView.as_view(), name='conferences'), + path('conference/<uuid:pk>', ConferencePublicationView.as_view(), name='conference-publication'), path('wiki', wiki.WikiOverviewView.as_view(), name='wiki'), path('wiki/namespaces', wiki.NamespaceListView.as_view(), name='wiki-namespaces'), path('wiki/locks', wiki.LockListView.as_view(), name='wiki-locks'), diff --git a/src/backoffice/views/conferences.py b/src/backoffice/views/conferences.py index facd80268f81f0893e674b77e2c10595365dcb5d..8a1c7c2ff2e4020f6bd84b4792b6c4f6e057f4db 100644 --- a/src/backoffice/views/conferences.py +++ b/src/backoffice/views/conferences.py @@ -1,10 +1,22 @@ +import logging +from typing import Any + +from django.contrib import messages +from django.core.exceptions import PermissionDenied +from django.forms.forms import BaseForm +from django.http import HttpRequest, HttpResponse, HttpResponseRedirect from django.shortcuts import redirect -from django.views.generic.edit import FormView +from django.urls import reverse +from django.utils.translation import gettext_lazy as _ +from django.views.generic.edit import FormView, UpdateView -from core.models import Conference +from core.forms import ConferencePublicationForm +from core.models import Conference, ConferenceMember from backoffice.forms import ConferenceSelectionForm -from backoffice.views.mixins import LoginRequiredMixin +from backoffice.views.mixins import ConferenceRequiredMixin, LoginRequiredMixin + +logger = logging.getLogger(__name__) class ConferenceSelectionView(LoginRequiredMixin, FormView): @@ -48,3 +60,104 @@ class ConferenceSelectionView(LoginRequiredMixin, FormView): 'conferences': Conference.objects.accessible_by_user(self.request.user), 'active_page': self.active_page, } + + +class ConferenceFormMixin(ConferenceRequiredMixin, FormView): + object: Conference | None + model = Conference + context_object_name = 'conference' + permission_required = ['core.conference_admin', 'core.assembly_registration_admin'] + require_all_permissions = False + require_staff = True + form_permissions_required = [] + sidebar_caption = _('nav_conference') + active_page: str + + def get_context_data(self, *args, **kwargs): + return { + **super().get_context_data(*args, **kwargs), + 'has_form_perms': self.request.user.has_conference_staff_permission(self.conference, *self.form_permissions_required), + 'active_page': self.active_page, + 'sidebar': { + 'title': self.sidebar_caption, + 'items': [ + { + 'caption': _('Conference__Publication'), + 'link': reverse( + 'backoffice:conference-publication', + kwargs={'pk': self.conference.pk}, + ), + }, + ], + }, + } + + def get_form(self, form_class: type | None = None) -> ConferencePublicationForm | BaseForm: + form = super().get_form(form_class) + member = ConferenceMember.objects.filter(user=self.request.user, conference=self.object).first() + if member and member.has_perms(*self.form_permissions_required, require_staff=self.require_staff): + return form + for field in form.fields: + form.fields[field].disabled = True + return form + + def post(self, request: HttpRequest, *args: str, **kwargs: Any) -> HttpResponse: + if not self.request.user.has_conference_staff_permission(self.conference, *self.form_permissions_required): + raise PermissionDenied + return super().post(request, *args, **kwargs) + + +class ConferencePublicationView(ConferenceFormMixin, UpdateView): + """ + An UpdateView to change the publication settings of the current :model:`core.conference`. + """ + + form_class = ConferencePublicationForm + template_name = 'backoffice/conferences/publication_edit.html' + active_page = 'conference' + form_permissions_required = ['core.conference_admin'] + + def get_form_kwargs(self, *args, **kwargs) -> dict[str, Any]: + publish = False + if self.object: + publish = (not self.object.is_public and self.request.GET.get('publish') == 'true') or ( + self.object.is_public and self.request.GET.get('recall') == 'true' + ) + return { + **super().get_form_kwargs(*args, **kwargs), + 'publish': publish, + } + + def form_valid(self, form: ConferencePublicationForm): + # Try to safe the form before creating logs and messages + self.object = form.save() + logger.info( + 'changed publication info of "%(conference)s" by %(user)s', + { + 'conference': form.instance, + 'user': self.request.user, + }, + ) + + if form.publish and self.object.is_public: + messages.success(self.request, _('Conference__publish__success')) + elif form.publish and not self.object.is_public: + messages.success(self.request, _('Conference__recall__success')) + elif form.create: + messages.success(self.request, _('Conference__create__success')) + else: + messages.success(self.request, _('Conference__update__success')) + + return HttpResponseRedirect(self.get_success_url()) + + def form_invalid(self, form: ConferencePublicationForm): + if form.publish: + form.instance.is_public = False + messages.error(self.request, _('Conference__publish__failed')) + else: + messages.error(self.request, _('Conference__form__invalid')) + + return super().form_invalid(form) + + def get_success_url(self): + return reverse('backoffice:conference-publication', kwargs={'pk': self.object.pk}) diff --git a/src/backoffice/views/mixins.py b/src/backoffice/views/mixins.py index a56853bd8bd0795fed5968c135e269be511cce57..c7adadf123b6dbbe08337f70682fc1c615779d43 100644 --- a/src/backoffice/views/mixins.py +++ b/src/backoffice/views/mixins.py @@ -111,6 +111,7 @@ class ConferenceRequiredMixin(PermissionRequiredMixin): 'has_channel': self.is_channel_team, 'has_pages': self.conferencemember.has_perms('core.static_pages', require_staff=True), 'has_map': self.conferencemember.has_perms('core.map_edit', require_staff=True), + 'has_conference_admin': self.conferencemember.has_perms('core.conference_admin', require_staff=True), 'has_moderation': self.conferencemember.has_perms('core.moderation', require_staff=True), 'has_schedules': self.conferencemember.has_perms('core.scheduleadmin', require_staff=True), 'has_workadventure': settings.INTEGRATIONS_WORKADVENTURE @@ -124,6 +125,7 @@ class ConferenceRequiredMixin(PermissionRequiredMixin): 'has_channel': False, 'has_pages': False, 'has_map': False, + 'has_conference_admin': False, 'has_moderation': False, 'has_schedules': False, 'has_workadventure': False, diff --git a/src/core/fixtures/bootstrap_auth_groups.json b/src/core/fixtures/bootstrap_auth_groups.json index 364f79683d75958393f5fe0d62058a51167b8396..2b7b8cf1f54b25020b8b3f530da955d4c7525e58 100644 --- a/src/core/fixtures/bootstrap_auth_groups.json +++ b/src/core/fixtures/bootstrap_auth_groups.json @@ -92,6 +92,11 @@ "static_pages", "core", "conferencemember" + ], + [ + "conference_admin", + "core", + "conferencemember" ] ] } diff --git a/src/core/forms.py b/src/core/forms.py index 86a57d08fd577dec00ac0f9b1a3bafcba8ac42d7..c4cb99550cad7b7819ace3a2a2110fb56ed1b775 100644 --- a/src/core/forms.py +++ b/src/core/forms.py @@ -13,7 +13,7 @@ from django.contrib.sites.shortcuts import get_current_site from django.core.exceptions import ValidationError from django.core.mail import EmailMultiAlternatives from django.db.models import Q -from django.forms import BaseModelFormSet, CharField, ChoiceField, EmailField, EmailInput, ModelForm +from django.forms import BaseModelFormSet, CharField, ChoiceField, DateTimeInput, EmailField, EmailInput, ModelForm from django.template import loader from django.utils.encoding import force_bytes from django.utils.http import urlsafe_base64_encode @@ -21,6 +21,7 @@ from django.utils.translation import gettext_lazy as _ from core.base_forms import TranslatedFieldsForm from core.models import Assembly, ConferenceMember, Link, PlatformUser, Project, UserCommunicationChannel +from core.models.conference import Conference from core.models.tags import clean_tags from core.tokens import channel_activation_token @@ -243,6 +244,47 @@ class LinkFormSet(BaseModelFormSet): form.set_linked_object(linked_object) +class ConferencePublicationForm(TranslatedFieldsForm): + class Meta: + model = Conference + fields = [ + 'name', + 'slug', + 'start', + 'end', + 'publication_date', + 'timezone', + 'global_notification', + 'is_public', + ] + + widgets = { + 'start': DateTimeInput(attrs={'type': 'datetime-local'}, format='%Y-%m-%dT%H:%M:%S%z'), + 'end': DateTimeInput(attrs={'type': 'datetime-local'}, format='%Y-%m-%dT%H:%M:%S%z'), + 'publication_date': DateTimeInput(attrs={'type': 'datetime-local'}, format='%Y-%m-%dT%H:%M:%S%z'), + } + + def __init__( + self, + *args, + instance: Conference | None = None, + publish: bool = False, + **kwargs, + ): + self.publish = publish + self.create = instance is None + super().__init__(*args, instance=instance, **kwargs) + if not self.create: + self.fields['name'].disabled = True + self.fields['slug'].disabled = True + + def clean(self) -> dict[str, Any]: + if self.instance.is_public != self.cleaned_data['is_public']: + raise ValidationError(_('Conference__is_public__unchangeable')) + self.cleaned_data['is_public'] = not self.instance.is_public if self.publish else self.instance.is_public + return super().clean() + + class ProjectForm(TranslatedFieldsForm): class Meta: model = Project diff --git a/src/core/locale/de/LC_MESSAGES/django.po b/src/core/locale/de/LC_MESSAGES/django.po index f8d30d14df38b2a2cc43cec052fb73370a02683f..c74d549de681e78a25281c4f0ebcdcbbbb6b5525 100644 --- a/src/core/locale/de/LC_MESSAGES/django.po +++ b/src/core/locale/de/LC_MESSAGES/django.po @@ -137,6 +137,9 @@ msgstr "Zu viele Request (Rate-Limited), bitte einen Moment warten!" msgid "Registration__username__nounderscore" msgstr "Der Benutzername darf nicht mit einem Unterstrich beginnen." +msgid "Conference__is_public__unchangeable" +msgstr "Der Konferenz Veröffentlichungsstatus kann nur mittels des Veröffentlichen Buttons durchgeführt werden." + msgid "Tags" msgstr "" @@ -628,6 +631,9 @@ msgstr "Wenn du eine neue Badge akzeptierst wird sie standardmäßig mit dieser msgid "ConferenceMember__default_badge_visibility" msgstr "Sichtbarkeit neuer Badges" +msgid "ConferenceMember__permission-confernece_admin" +msgstr "Konferenz-Admin: Kann die Veröffentlichungszeitpunkte der Konferenz verwalten" + msgid "ConferenceMember__permission-assembly_team" msgstr "Assembly-Team: alle Assemblies verwaltbar, auch noch nicht fertig angelegte und abgelehnte sind sichtbar" diff --git a/src/core/locale/en/LC_MESSAGES/django.po b/src/core/locale/en/LC_MESSAGES/django.po index dc6c5f67a6bffb415ae8c584ee2124dd4578726a..b12d8610642fb8053bc9b4261be1403950905472 100644 --- a/src/core/locale/en/LC_MESSAGES/django.po +++ b/src/core/locale/en/LC_MESSAGES/django.po @@ -137,6 +137,9 @@ msgstr "Too many requests (Rate-Limited), please wait a moment!" msgid "Registration__username__nounderscore" msgstr "The username must not begin with an underscore." +msgid "Conference__is_public__unchangeable" +msgstr "The conference publication status can only be changed using the publish button." + msgid "Tags" msgstr "" @@ -628,6 +631,9 @@ msgstr " When you accept a new badge, it will be displayed with this visibility msgid "ConferenceMember__default_badge_visibility" msgstr "visibility of new badges" +msgid "ConferenceMember__permission-confernece_admin" +msgstr "Conference admin: can manage the conference's publication times" + msgid "ConferenceMember__permission-assembly_team" msgstr "assemblies team: manage all assemblies, see also incomplete and rejected registrations" diff --git a/src/core/migrations/0152_alter_conferencemember_options.py b/src/core/migrations/0152_alter_conferencemember_options.py new file mode 100644 index 0000000000000000000000000000000000000000..e616272056e1232f0b25f81547a7915e5a9fccea --- /dev/null +++ b/src/core/migrations/0152_alter_conferencemember_options.py @@ -0,0 +1,35 @@ +# Generated by Django 5.1.2 on 2024-10-27 00:54 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("core", "0151_conference_publication_date"), + ] + + operations = [ + migrations.AlterModelOptions( + name="conferencemember", + options={ + "permissions": [ + ( + "conference_admin", + "ConferenceMember__permission-confernece_admin", + ), + ("assembly_team", "ConferenceMember__permission-assembly_team"), + ("channel_team", "ConferenceMember__permission-channel_team"), + ("static_pages", "ConferenceMember__permission-static_pages"), + ("map_edit", "ConferenceMember__permission-map_edit"), + ("moderation", "Orga: Moderation"), + ("voucher_admin", "ConferenceMember__permission-voucher_admin"), + ("scheduleadmin", "ConferenceMember__permission-scheduleadmin"), + ( + "workadventure_admin", + "ConferenceMember__permission-workadventure_admin", + ), + ] + }, + ), + ] diff --git a/src/core/models/conference.py b/src/core/models/conference.py index e06c906f0036790fb484cfe13d44df785184c37f..cb2a9a8106cee6aa43add4f234ab00b5625cb38d 100644 --- a/src/core/models/conference.py +++ b/src/core/models/conference.py @@ -78,6 +78,8 @@ class ConferenceMember(models.Model): class Meta: permissions = [ + ('conference_admin', _('ConferenceMember__permission-confernece_admin')), + # Change conference settings (e.g., dates, ), update venue json. ('assembly_team', _('ConferenceMember__permission-assembly_team')), # See all assemblies, not only the accepted ones. ('channel_team', _('ConferenceMember__permission-channel_team')),