Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • konstantin/akplanning
  • matedealer/akplanning
  • kif/akplanning
  • mirco/akplanning
  • lordofthevoid/akplanning
  • voidptr/akplanning
  • xayomer/akplanning-fork
  • mollux/akplanning
  • neumantm/akplanning
  • mmarx/akplanning
  • nerf/akplanning
  • felix_bonn/akplanning
  • sebastian.uschmann/akplanning
13 results
Show changes
Commits on Source (26)
Showing
with 848 additions and 128 deletions
......@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-11-03 17:40+0000\n"
"POT-Creation-Date: 2021-04-29 22:48+0000\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"
......
......@@ -3,7 +3,7 @@ from django.contrib import admin
from django.contrib.admin import SimpleListFilter
from django.db.models import Count, F
from django import forms
from django.shortcuts import render
from django.shortcuts import render, redirect
from django.urls import path, reverse_lazy
from django.utils import timezone
from django.utils.html import format_html
......@@ -16,7 +16,9 @@ from AKModel.availability.forms import AvailabilitiesFormMixin
from AKModel.availability.models import Availability
from AKModel.models import Event, AKOwner, AKCategory, AKTrack, AKTag, AKRequirement, AK, AKSlot, Room, AKOrgaMessage, \
ConstraintViolation
from AKModel.views import EventStatusView, AKCSVExportView, AKWikiExportView, AKMessageDeleteView
from AKModel.views import EventStatusView, AKCSVExportView, AKWikiExportView, AKMessageDeleteView, AKRequirementOverview, \
NewEventWizardStartView, NewEventWizardSettingsView, NewEventWizardPrepareImportView, NewEventWizardFinishView, \
NewEventWizardImportView, NewEventWizardActivateView
@admin.register(Event)
......@@ -27,10 +29,31 @@ class EventAdmin(admin.ModelAdmin):
list_editable = ['active']
ordering = ['-start']
def add_view(self, request, form_url='', extra_context=None):
# Always use wizard to create new events
# (the built-in form wouldn't work anyways since the timezone cannot be specified before starting to fill the form)
return redirect("admin:new_event_wizard_start")
def get_urls(self):
urls = super().get_urls()
custom_urls = [
path('add/wizard/start/', self.admin_site.admin_view(NewEventWizardStartView.as_view()),
name="new_event_wizard_start"),
path('add/wizard/settings/', self.admin_site.admin_view(NewEventWizardSettingsView.as_view()),
name="new_event_wizard_settings"),
path('add/wizard/created/<slug:event_slug>/', self.admin_site.admin_view(NewEventWizardPrepareImportView.as_view()),
name="new_event_wizard_prepare_import"),
path('add/wizard/import/<slug:event_slug>/from/<slug:import_slug>/',
self.admin_site.admin_view(NewEventWizardImportView.as_view()),
name="new_event_wizard_import"),
path('add/wizard/activate/<slug:slug>/',
self.admin_site.admin_view(NewEventWizardActivateView.as_view()),
name="new_event_wizard_activate"),
path('add/wizard/finish/<slug:slug>/',
self.admin_site.admin_view(NewEventWizardFinishView.as_view()),
name="new_event_wizard_finish"),
path('<slug:slug>/status/', self.admin_site.admin_view(EventStatusView.as_view()), name="event_status"),
path('<slug:event_slug>/requirements/', self.admin_site.admin_view(AKRequirementOverview.as_view()), name="event_requirement_overview"),
path('<slug:event_slug>/ak-csv-export/', self.admin_site.admin_view(AKCSVExportView.as_view()), name="ak_csv_export"),
path('<slug:event_slug>/ak-wiki-export/', self.admin_site.admin_view(AKWikiExportView.as_view()), name="ak_wiki_export"),
path('<slug:slug>/delete-orga-messages/', self.admin_site.admin_view(AKMessageDeleteView.as_view()),
......@@ -45,11 +68,7 @@ class EventAdmin(admin.ModelAdmin):
def get_form(self, request, obj=None, change=False, **kwargs):
# Use timezone of event
if obj is not None and obj.timezone:
timezone.activate(obj.timezone)
# No timezone available? Use UTC
else:
timezone.activate("UTC")
timezone.activate(obj.timezone)
return super().get_form(request, obj, change, **kwargs)
......@@ -94,6 +113,18 @@ class AKTrackAdmin(admin.ModelAdmin):
kwargs['initial'] = Event.get_next_active()
return super(AKTrackAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
def get_urls(self):
urls = super().get_urls()
custom_urls = []
if apps.is_installed("AKScheduling"):
from AKScheduling.views import TrackAdminView
custom_urls.extend([
path('<slug:event_slug>/manage/', self.admin_site.admin_view(TrackAdminView.as_view()),
name="tracks_manage"),
])
return custom_urls + urls
@admin.register(AKTag)
class AKTagAdmin(admin.ModelAdmin):
......@@ -138,6 +169,24 @@ class WishFilter(SimpleListFilter):
return queryset
class AKAdminForm(forms.ModelForm):
class Meta:
widgets = {
'requirements': forms.CheckboxSelectMultiple,
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Filter possible values for foreign keys & m2m when event is specified
if hasattr(self.instance, "event") and self.instance.event is not None:
self.fields["category"].queryset = AKCategory.objects.filter(event=self.instance.event)
self.fields["track"].queryset = AKTrack.objects.filter(event=self.instance.event)
self.fields["owners"].queryset = AKOwner.objects.filter(event=self.instance.event)
self.fields["requirements"].queryset = AKRequirement.objects.filter(event=self.instance.event)
self.fields["conflicts"].queryset = AK.objects.filter(event=self.instance.event)
self.fields["prerequisites"].queryset = AK.objects.filter(event=self.instance.event)
@admin.register(AK)
class AKAdmin(SimpleHistoryAdmin):
model = AK
......@@ -146,6 +195,7 @@ class AKAdmin(SimpleHistoryAdmin):
list_editable = ['short_name', 'track', 'interest']
ordering = ['pk']
actions = ['wiki_export']
form = AKAdminForm
def is_wish(self, obj):
return obj.wish
......@@ -182,6 +232,10 @@ class RoomForm(AvailabilitiesFormMixin, forms.ModelForm):
kwargs['initial'] = dict()
super().__init__(*args, **kwargs)
self.initial = {**self.initial, **kwargs['initial']}
# Filter possible values for m2m when event is specified
if hasattr(self.instance, "event") and self.instance.event is not None:
self.fields["properties"].queryset = AKRequirement.objects.filter(event=self.instance.event)
@admin.register(Room)
......@@ -206,15 +260,23 @@ class RoomAdmin(admin.ModelAdmin):
)
class AKSlotAdminForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Filter possible values for foreign keys when event is specified
if hasattr(self.instance, "event") and self.instance.event is not None:
self.fields["ak"].queryset = AK.objects.filter(event=self.instance.event)
self.fields["room"].queryset = Room.objects.filter(event=self.instance.event)
@admin.register(AKSlot)
class AKSlotAdmin(admin.ModelAdmin):
model = AKSlot
list_display = ['id', 'ak', 'room', 'start', 'duration', 'event']
list_filter = ['room', 'event']
list_editable = ['ak', 'room', 'start', 'duration']
ordering = ['start']
readonly_fields = ['ak_details_link', 'updated']
form = AKSlotAdminForm
def get_urls(self):
urls = super().get_urls()
......@@ -271,8 +333,22 @@ class AKOrgaMessageAdmin(admin.ModelAdmin):
readonly_fields = ['timestamp', 'ak', 'text']
class ConstraintViolationAdminForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Filter possible values for foreign keys & m2m when event is specified
if hasattr(self.instance, "event") and self.instance.event is not None:
self.fields["ak_owner"].queryset = AKOwner.objects.filter(event=self.instance.event)
self.fields["room"].queryset = Room.objects.filter(event=self.instance.event)
self.fields["requirement"].queryset = AKRequirement.objects.filter(event=self.instance.event)
self.fields["category"].queryset = AKCategory.objects.filter(event=self.instance.event)
self.fields["aks"].queryset = AK.objects.filter(event=self.instance.event)
self.fields["ak_slots"].queryset = AKSlot.objects.filter(event=self.instance.event)
@admin.register(ConstraintViolation)
class ConstraintViolationAdmin(admin.ModelAdmin):
list_display = ['type', 'level', 'get_details']
list_filter = ['event']
readonly_fields = ['timestamp']
form = ConstraintViolationAdminForm
from bootstrap_datepicker_plus import DateTimePickerInput
from django import forms
from django.forms.utils import ErrorList
from django.utils.translation import ugettext_lazy as _
from AKModel.models import Event, AKCategory, AKRequirement
class NewEventWizardStartForm(forms.ModelForm):
class Meta:
model = Event
fields = ['name', 'slug', 'timezone']
is_init = forms.BooleanField(initial=True, widget=forms.HiddenInput)
class NewEventWizardSettingsForm(forms.ModelForm):
class Meta:
model = Event
exclude = []
widgets = {
'name': forms.HiddenInput(),
'slug': forms.HiddenInput(),
'timezone': forms.HiddenInput(),
'active': forms.HiddenInput(),
'plan_hidden': forms.HiddenInput(),
'start': DateTimePickerInput(options={"format": "YYYY-MM-DD HH:mm"}),
'end': DateTimePickerInput(options={"format": "YYYY-MM-DD HH:mm"}),
'reso_deadline': DateTimePickerInput(options={"format": "YYYY-MM-DD HH:mm"}),
}
class NewEventWizardPrepareImportForm(forms.Form):
import_event = forms.ModelChoiceField(
queryset=Event.objects.all(),
label=_("Copy ak requirements and ak categories of existing event"),
help_text=_("You can choose what to copy in the next step")
)
class NewEventWizardImportForm(forms.Form):
import_categories = forms.ModelMultipleChoiceField(
queryset=AKCategory.objects.all(),
widget=forms.CheckboxSelectMultiple,
label=_("Copy ak categories"),
required=False,
)
import_requirements = forms.ModelMultipleChoiceField(
queryset=AKRequirement.objects.all(),
widget=forms.CheckboxSelectMultiple,
label=_("Copy ak requirements"),
required=False,
)
def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=ErrorList,
label_suffix=None, empty_permitted=False, field_order=None, use_required_attribute=None,
renderer=None):
super().__init__(data, files, auto_id, prefix, initial, error_class, label_suffix, empty_permitted, field_order,
use_required_attribute, renderer)
self.fields["import_categories"].queryset = self.fields["import_categories"].queryset.filter(event=self.initial["import_event"])
self.fields["import_requirements"].queryset = self.fields["import_requirements"].queryset.filter(event=self.initial["import_event"])
class NewEventWizardActivateForm(forms.ModelForm):
class Meta:
fields = ["active"]
model = Event
# Generated by Django 3.1.5 on 2021-01-29 15:43
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('AKModel', '0042_akslot_fixed'),
]
operations = [
migrations.AlterField(
model_name='akslot',
name='fixed',
field=models.BooleanField(default=False, help_text='Length and time of this AK should not be changed', verbose_name='Scheduling fixed'),
),
]
# Generated by Django 3.1.5 on 2021-01-29 15:44
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('AKModel', '0043_akslot_fixed_improve_verbose_name'),
]
operations = [
migrations.RemoveField(
model_name='historicalak',
name='interest_counter',
),
]
This diff is collapsed.
......@@ -233,7 +233,7 @@ class AK(models.Model):
event = models.ForeignKey(to=Event, on_delete=models.CASCADE, verbose_name=_('Event'),
help_text=_('Associated event'))
history = HistoricalRecords()
history = HistoricalRecords(excluded_fields=['interest_counter'])
class Meta:
verbose_name = _('AK')
......@@ -266,13 +266,19 @@ class AK(models.Model):
def durations_list(self):
return ", ".join(str(slot.duration) for slot in self.akslot_set.all())
@property
def tags_list(self):
return ", ".join(str(tag) for tag in self.tags.all())
@property
def wish(self):
return self.owners.count() == 0
def increment_interest(self):
self.interest_counter += 1
self.skip_history_when_saving = True
self.save()
del self.skip_history_when_saving
@property
def availabilities(self):
......@@ -342,7 +348,7 @@ class AKSlot(models.Model):
Display duration of slot in format hours:minutes, e.g. 1.5 -> "1:30"
"""
hours, minutes = divmod(self.duration * 60, 60)
return f"{hours}:{minutes:2.0f}"
return f"{int(hours)}:{int(minutes):02}"
@property
def start_simplified(self):
......
{% extends "admin/base_site.html" %}
{% load tags_AKModel %}
{% load i18n %}
{% load bootstrap4 %}
{% load fontawesome_5 %}
{% load tz %}
{% block title %}{% trans "New event wizard" %}: {{ wizard_step_text }}{% endblock %}
{% block content %}
{% include "admin/AKModel/event_wizard/wizard_steps.html" %}
<div class="text-center btn-success disabled mt-3 mb-3" style="font-size: 8em;">
{% fa5_icon "copy" "fas" %}
</div>
<h5 class="mb-3">{% trans "Successfully imported.<br><br>Do you want to activate your event now?" %}</h5>
{{ form.media }}
<form method="post">{% csrf_token %}
{% bootstrap_form form %}
<div class="float-right">
<button type="submit" class="save btn btn-success" value="Submit">
{% fa5_icon "check" 'fas' %} {% trans "Finish" %}
</button>
</div>
<a href="{% url 'admin:event_status' event.slug %}" class="btn btn-info">
{% fa5_icon "info" 'fas' %} {% trans "Status" %}
</a>
</form>
{% endblock %}
{% extends "admin/base_site.html" %}
{% load tags_AKModel %}
{% load i18n %}
{% load bootstrap4 %}
{% load fontawesome_5 %}
{% load tz %}
{% block title %}{% trans "New event wizard" %}: {{ wizard_step_text }}{% endblock %}
{% block content %}
{% include "admin/AKModel/event_wizard/wizard_steps.html" %}
{% timezone event.timezone %}
<div class="card border-success mt-3 mb-3" style="max-width: 100%;">
<div class="card-header">{% trans "New event:" %}</div>
<div class="card-body">
<h4 class="card-title">{{event}}</h4>
<p class="card-text">{{ event.start }} - {{ event.end }}</p>
</div>
</div>
{% endtimezone %}
<div class="text-center btn-success disabled mb-3" style="font-size: 8em;">
{% fa5_icon "calendar-plus" "fas" %}
</div>
<h5 class="mb-3">{% trans "Your event was created and can now be further configured." %}</h5>
{{ form.media }}
<form method="post">{% csrf_token %}
{% bootstrap_form form %}
<div class="float-right">
<a href="{% url 'admin:new_event_wizard_activate' event.slug %}" class="btn btn-info">
{% fa5_icon "forward" 'fas' %} {% trans "Skip Import" %}
</a>
<button type="submit" class="save btn btn-success" value="Submit">
{% fa5_icon "check" 'fas' %} {% trans "Continue" %}
</button>
</div>
<a href="{% url 'admin:event_status' event.slug %}" class="btn btn-info">
{% fa5_icon "info" 'fas' %} {% trans "Status" %}
</a>
</form>
{% endblock %}
{% extends "admin/base_site.html" %}
{% load tags_AKModel %}
{% load i18n %}
{% load bootstrap4 %}
{% load fontawesome_5 %}
{% load tz %}
{% block title %}{% trans "New event wizard" %}: {{ wizard_step_text }}{% endblock %}
{% block content %}
{% include "admin/AKModel/event_wizard/wizard_steps.html" %}
<div class="text-center btn-success disabled mt-3 mb-3" style="font-size: 8em;">
{% fa5_icon "check-circle" "fas" %}
</div>
<h5>{% trans "Congratulations. Everything is set up!" %}</h5>
<a href="{% url 'admin:event_status' event.slug %}" class="btn btn-info float-right">
{% fa5_icon "info" 'fas' %}&nbsp;{% trans "Status" %}
</a>
{% endblock %}
{% extends "admin/base_site.html" %}
{% load tags_AKModel %}
{% load i18n %}
{% load bootstrap4 %}
{% load fontawesome_5 %}
{% load tz %}
{% block title %}{% trans "New event wizard" %}: {{ wizard_step_text }}{% endblock %}
{% block content %}
{% include "admin/AKModel/event_wizard/wizard_steps.html" %}
{{ form.media }}
<form method="post">{% csrf_token %}
{% bootstrap_form form %}
<button type="submit" class="save btn btn-success float-right" value="Submit">
{% fa5_icon "check" 'fas' %} {% trans "Continue" %}
</button>
<a href="{% url 'admin:index' %}" class="btn btn-info">
{% fa5_icon "times" 'fas' %} {% trans "Cancel" %}
</a>
</form>
{% endblock %}
{% extends "admin/base_site.html" %}
{% load tags_AKModel %}
{% load i18n %}
{% load bootstrap4 %}
{% load fontawesome_5 %}
{% load tz %}
{% block title %}{% trans "New event wizard" %}: {{ wizard_step_text }}{% endblock %}
{% block content %}
{% include "admin/AKModel/event_wizard/wizard_steps.html" %}
{{ form.media }}
{% timezone timezone %}
<form method="post">{% csrf_token %}
{% bootstrap_form form %}
<button type="submit" class="save btn btn-success float-right" value="Submit">
{% fa5_icon "check" 'fas' %} {% trans "Continue" %}
</button>
<a href="{% url 'admin:new_event_wizard_start' %}" class="btn btn-info">
{% fa5_icon "chevron-left" 'fas' %} {% trans "Back" %}
</a>
<a href="{% url 'admin:index' %}" class="btn btn-warning">
{% fa5_icon "times" 'fas' %} {% trans "Cancel" %}
</a>
</form>
{% endtimezone %}
{% endblock %}
{% extends "admin/base_site.html" %}
{% load tags_AKModel %}
{% load i18n %}
{% load bootstrap4 %}
{% load fontawesome_5 %}
{% block title %}{% trans "New event wizard" %}: {{ wizard_step_text }}{% endblock %}
{% block content %}
{% include "admin/AKModel/event_wizard/wizard_steps.html" %}
{% trans "Add a new event. Please start by filling these basic properties. You can specify more settings later." %}
<form method="post" action="{% url 'admin:new_event_wizard_settings' %}">{% csrf_token %}
{% bootstrap_form form %}
<button type="submit" class="save btn btn-success float-right" value="Submit">
{% fa5_icon "check" 'fas' %} {% trans "Continue" %}
</button>
<a href="{% url 'admin:index' %}" class="btn btn-info">
{% fa5_icon "times" 'fas' %} {% trans "Cancel" %}
</a>
</form>
{% endblock %}
{% load i18n %}
<h2>{% trans "New event wizard" %}</h2>
<div>
<ul class="pagination pagination-sm">
{% for step in wizard_steps %}
<li class="page-item {% if forloop.counter == wizard_step %}active{% else %}disabled{% endif %}">
<a class="page-link" href="#">{{ step }}</a>
</li>
{% endfor %}
</ul>
</div>
<h3>{% trans "Step" %} {{ wizard_step }}: {{ wizard_step_text }}</h3>
{% extends "admin/base_site.html" %}
{% load tags_AKModel %}
{% load i18n %}
{% load tz %}
{% load fontawesome_5 %}
{% block title %}{% trans "Status" %}: {{event}}{% endblock %}
{% block content %}
{% timezone event.timezone %}
<h2><a href="{% url 'admin:AKModel_event_change' event.pk %}">{{event}}</a> - {% trans "Requirements Overview" %}</h2>
<h5>{{ event.start }} - {{ event.end }}</h5>
<div class="row mt-4">
{% for requirement in requirements %}
<div class="col-md-4">
<h4>{{ requirement }}</h4>
<table class="table table-striped">
{% for ak in requirement.ak_set.all %}
<tr>
<td>{{ ak }}</td>
{% if "AKSubmission"|check_app_installed %}
<td class="text-right">
<a href="{% url 'submit:ak_detail' event_slug=ak.event.slug pk=ak.pk %}" data-toggle="tooltip"
title="{% trans 'Details' %}"
class="btn btn-primary">{% fa5_icon 'info' 'fas' %}</a>
{% if event.active %}
<a href="{% url 'submit:ak_edit' event_slug=event.slug pk=ak.pk %}" data-toggle="tooltip"
title="{% trans 'Edit' %}"
class="btn btn-success">{% fa5_icon 'pencil-alt' 'fas' %}</a>
{% endif %}
{% endif %}
</td>
</tr>
{% empty %}
<tr><td>{% trans "No AKs with this requirement" %}</td></tr>
{% endfor %}
</table>
</div>
{% endfor %}
</div>
<a class="btn btn-success" href="{% url 'admin:AKModel_akrequirement_add' %}">{% trans "Add Requirement" %}</a>
{% endtimezone %}
{% endblock %}
......@@ -74,6 +74,8 @@
<a class="btn btn-success"
href="{% url 'admin:schedule' event_slug=event.slug %}">{% trans "Scheduling" %}</a>
<a class="btn btn-success"
href="{% url 'admin:tracks_manage' event_slug=event.slug %}">{% trans "Manage ak tracks" %}</a>
<a class="btn btn-success"
href="{% url 'admin:ak_csv_export' event_slug=event.slug %}">{% trans "Export AKs as CSV" %}</a>
<a class="btn btn-success"
......@@ -95,6 +97,7 @@
{% endfor %}
</p>
{% endif %}
<a class="btn btn-success" href="{% url 'admin:event_requirement_overview' event.slug %}">{% trans "Show AKs for requirements" %}</a>
<a class="btn btn-success" href="{% url 'admin:AKModel_akrequirement_add' %}">{% trans "Add Requirement" %}</a>
</div>
<div class="col-md-4">
......
from django.contrib import admin, messages
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404
from django.shortcuts import get_object_or_404, redirect
from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _
from django.views.generic import TemplateView, DetailView, ListView, DeleteView
from django.views.generic import TemplateView, DetailView, ListView, DeleteView, CreateView, FormView, UpdateView
from rest_framework import viewsets, permissions, mixins
from AKModel.models import Event, AK, AKSlot, Room, AKTrack, AKCategory, AKOwner, AKOrgaMessage
from AKModel.forms import NewEventWizardStartForm, NewEventWizardSettingsForm, NewEventWizardPrepareImportForm, \
NewEventWizardImportForm, NewEventWizardActivateForm
from AKModel.models import Event, AK, AKSlot, Room, AKTrack, AKCategory, AKOwner, AKOrgaMessage, AKRequirement
from AKModel.serializers import AKSerializer, AKSlotSerializer, RoomSerializer, AKTrackSerializer, AKCategorySerializer, \
AKOwnerSerializer
......@@ -38,6 +39,11 @@ class EventSlugMixin:
self._load_event()
return super().create(request, *args, **kwargs)
def dispatch(self, request, *args, **kwargs):
if self.event is None:
self._load_event()
return super().dispatch(request, *args, **kwargs)
def get_context_data(self, *, object_list=None, **kwargs):
context = super().get_context_data(object_list=object_list, **kwargs)
# Add event to context (to make it accessible in templates)
......@@ -87,7 +93,7 @@ class AKCategoryViewSet(EventSlugMixin, mixins.RetrieveModelMixin, mixins.ListMo
return AKCategory.objects.filter(event=self.event)
class AKTrackViewSet(EventSlugMixin, mixins.RetrieveModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet):
class AKTrackViewSet(EventSlugMixin, mixins.RetrieveModelMixin, mixins.CreateModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet):
permission_classes = (permissions.DjangoModelPermissionsOrAnonReadOnly,)
serializer_class = AKTrackSerializer
......@@ -95,7 +101,7 @@ class AKTrackViewSet(EventSlugMixin, mixins.RetrieveModelMixin, mixins.ListModel
return AKTrack.objects.filter(event=self.event)
class AKViewSet(EventSlugMixin, mixins.RetrieveModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet):
class AKViewSet(EventSlugMixin, mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet):
permission_classes = (permissions.DjangoModelPermissionsOrAnonReadOnly,)
serializer_class = AKSerializer
......@@ -137,6 +143,19 @@ class EventStatusView(AdminViewMixin, DetailView):
return context
class AKRequirementOverview(AdminViewMixin, FilterByEventSlugMixin, ListView):
model = AKRequirement
context_object_name = "requirements"
title = _("Requirements for Event")
template_name = "admin/AKModel/requirements_overview.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["event"] = self.event
context["site_url"] = reverse_lazy("dashboard:dashboard_event", kwargs={'slug': context["event"].slug})
return context
class AKCSVExportView(AdminViewMixin, FilterByEventSlugMixin, ListView):
template_name = "admin/AKModel/ak_csv_export.html"
model = AKSlot
......@@ -177,3 +196,94 @@ class AKMessageDeleteView(AdminViewMixin, DeleteView):
self.get_orga_messages_for_event(self.get_object()).delete()
messages.add_message(self.request, messages.SUCCESS, _("AK Orga Messages successfully deleted"))
return HttpResponseRedirect(reverse_lazy('admin:event_status', kwargs={'slug': self.get_object().slug}))
class WizardViewMixin:
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["wizard_step"] = self.wizard_step
context["wizard_steps"] = [
_("Start"),
_("Settings"),
_("Event created, Prepare Import"),
_("Import categories & requirements"),
_("Activate?"),
_("Finish")
]
context["wizard_step_text"] = context["wizard_steps"][self.wizard_step - 1]
context["wizard_steps_total"] = len(context["wizard_steps"])
return context
class NewEventWizardStartView(AdminViewMixin, WizardViewMixin, CreateView):
model = Event
form_class = NewEventWizardStartForm
template_name = "admin/AKModel/event_wizard/start.html"
wizard_step = 1
class NewEventWizardSettingsView(AdminViewMixin, WizardViewMixin, CreateView):
model = Event
form_class = NewEventWizardSettingsForm
template_name = "admin/AKModel/event_wizard/settings.html"
wizard_step = 2
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["timezone"] = context["form"].cleaned_data["timezone"]
return context
def get_success_url(self):
return reverse_lazy("admin:new_event_wizard_prepare_import", kwargs={"event_slug": self.object.slug})
class NewEventWizardPrepareImportView(WizardViewMixin, EventSlugMixin, FormView):
form_class = NewEventWizardPrepareImportForm
template_name = "admin/AKModel/event_wizard/created_prepare_import.html"
wizard_step = 3
def form_valid(self, form):
# Selected a valid event to import from? Use this to go to next step of wizard
return redirect("admin:new_event_wizard_import", event_slug=self.event.slug, import_slug=form.cleaned_data["import_event"].slug)
class NewEventWizardImportView(EventSlugMixin, WizardViewMixin, FormView):
form_class = NewEventWizardImportForm
template_name = "admin/AKModel/event_wizard/import.html"
wizard_step = 4
def get_initial(self):
initial = super().get_initial()
initial["import_event"] = Event.objects.get(slug=self.kwargs["import_slug"])
return initial
def form_valid(self, form):
for import_type in ["import_categories", "import_requirements"]:
for import_obj in form.cleaned_data.get(import_type):
# clone existing entry
try:
import_obj.event = self.event
import_obj.pk = None
import_obj.save()
messages.add_message(self.request, messages.SUCCESS, _("Copied '%(obj)s'" % {'obj': import_obj}))
except BaseException as e:
messages.add_message(self.request, messages.ERROR, _("Could not copy '%(obj)s' (%(error)s)" % {'obj': import_obj, "error": str(e)}))
return redirect("admin:new_event_wizard_activate", slug=self.event.slug)
class NewEventWizardActivateView(WizardViewMixin, UpdateView):
model = Event
template_name = "admin/AKModel/event_wizard/activate.html"
form_class = NewEventWizardActivateForm
wizard_step = 5
def get_success_url(self):
return reverse_lazy("admin:new_event_wizard_finish", kwargs={"slug": self.object.slug})
class NewEventWizardFinishView(WizardViewMixin, DetailView):
model = Event
template_name = "admin/AKModel/event_wizard/finish.html"
wizard_step = 6
......@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-11-03 17:40+0000\n"
"POT-Creation-Date: 2021-04-29 22:48+0000\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"
......@@ -23,7 +23,7 @@ msgstr ""
msgid "Plan"
msgstr "Plan"
#: AKPlan/templates/AKPlan/plan_base.html:28
#: AKPlan/templates/AKPlan/plan_base.html:21
msgid "Write to organizers of this event for questions and comments"
msgstr "Fragen oder Kommentare? Schreib den Orgas dieses Events eine Mail"
......@@ -38,7 +38,7 @@ msgstr "Veranstaltung"
#: AKPlan/templates/AKPlan/plan_index.html:53
#: AKPlan/templates/AKPlan/plan_room.html:13
#: AKPlan/templates/AKPlan/plan_room.html:59
#: AKPlan/templates/AKPlan/plan_wall.html:57
#: AKPlan/templates/AKPlan/plan_wall.html:50
msgid "Room"
msgstr "Raum"
......@@ -63,12 +63,12 @@ msgid "AK Wall"
msgstr "AK-Wall"
#: AKPlan/templates/AKPlan/plan_index.html:124
#: AKPlan/templates/AKPlan/plan_wall.html:86
#: AKPlan/templates/AKPlan/plan_wall.html:79
msgid "Current AKs"
msgstr "Aktuelle AKs"
#: AKPlan/templates/AKPlan/plan_index.html:131
#: AKPlan/templates/AKPlan/plan_wall.html:91
#: AKPlan/templates/AKPlan/plan_wall.html:84
msgid "Next AKs"
msgstr "Nächste AKs"
......
......@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-11-03 17:40+0000\n"
"POT-Creation-Date: 2021-04-29 22:48+0000\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"
......@@ -17,10 +17,10 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: AKPlanning/settings.py:131
#: AKPlanning/settings.py:134
msgid "German"
msgstr "Deutsch"
#: AKPlanning/settings.py:132
#: AKPlanning/settings.py:135
msgid "English"
msgstr "Englisch"