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
Select Git revision
  • koma/feature/preference-polling-form
  • main
  • renovate/django-5.x
3 results

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
Select Git revision
  • 520-akowner
  • 520-fix-event-wizard-datepicker
  • 520-fix-scheduling
  • 520-improve-scheduling
  • 520-improve-scheduling-2
  • 520-improve-submission
  • 520-improve-trackmanager
  • 520-improve-wall
  • 520-message-resolved
  • 520-status
  • 520-upgrades
  • add_express_interest_to_ak_overview
  • admin-production-color
  • bugfixes
  • csp
  • featire-ical-export
  • feature-ak-requirement-lists
  • feature-akslide-export-better-filename
  • feature-akslides
  • feature-better-admin
  • feature-better-cv-list
  • feature-colors
  • feature-constraint-checking
  • feature-constraint-checking-wip
  • feature-dashboard-history-button
  • feature-event-status
  • feature-event-wizard
  • feature-export-flag
  • feature-improve-admin
  • feature-improve-filters
  • feature-improved-user-creation-workflow
  • feature-interest-view
  • feature-mails
  • feature-modular-status
  • feature-plan-autoreload
  • feature-present-default
  • feature-register-link
  • feature-remaining-constraint-validation
  • feature-room-import
  • feature-scheduler-improve
  • feature-scheduling-2.0
  • feature-special-attention
  • feature-time-input
  • feature-tracker
  • feature-wiki-wishes
  • feature-wish-slots
  • feature-wizard-buttons
  • features-availabilities
  • fix-ak-times-above-folg
  • fix-api
  • fix-constraint-violation-string
  • fix-cv-checking
  • fix-default-slot-length
  • fix-default-slot-localization
  • fix-doc-minor
  • fix-duration-display
  • fix-event-tz-pytz-update
  • fix-history-interest
  • fix-interest-view
  • fix-js
  • fix-pipeline
  • fix-plan-timezone-now
  • fix-room-add
  • fix-scheduling-drag
  • fix-slot-defaultlength
  • fix-timezone
  • fix-translation-scheduling
  • fix-virtual-room-admin
  • fix-wizard-csp
  • font-locally
  • improve-admin
  • improve-online
  • improve-slides
  • improve-submission-coupling
  • interest_restriction
  • main
  • master
  • meta-debug-toolbar
  • meta-export
  • meta-makemessages
  • meta-performance
  • meta-tests
  • meta-tests-gitlab-test
  • meta-upgrades
  • mollux-master-patch-02906
  • port-availabilites-fullcalendar
  • qs
  • remove-tags
  • renovate/configure
  • renovate/django-4.x
  • renovate/django-5.x
  • renovate/django-bootstrap-datepicker-plus-5.x
  • renovate/django-bootstrap5-23.x
  • renovate/django-bootstrap5-24.x
  • renovate/django-compressor-4.x
  • renovate/django-debug-toolbar-4.x
  • renovate/django-registration-redux-2.x
  • renovate/django-simple-history-3.x
  • renovate/django-split-settings-1.x
  • renovate/django-timezone-field-5.x
100 results
Show changes
Showing
with 631 additions and 130 deletions
...@@ -7,6 +7,11 @@ ...@@ -7,6 +7,11 @@
{% block title %}{% trans "New event wizard" %}: {{ wizard_step_text }}{% endblock %} {% block title %}{% trans "New event wizard" %}: {{ wizard_step_text }}{% endblock %}
{% block extrahead %}
{{ block.super }}
{{ form.media }}
{% endblock %}
{% block content %} {% block content %}
{% include "admin/AKModel/event_wizard/wizard_steps.html" %} {% include "admin/AKModel/event_wizard/wizard_steps.html" %}
......
...@@ -19,6 +19,10 @@ ...@@ -19,6 +19,10 @@
\faUser~ {{ translations.who }} \faUser~ {{ translations.who }}
{% if show_types %}
\faList~ {{ translations.types }}
{% endif %}
\faClock~ {{ translations.duration }} \faClock~ {{ translations.duration }}
\faScroll~{{ translations.reso }} \faScroll~{{ translations.reso }}
...@@ -45,6 +49,10 @@ ...@@ -45,6 +49,10 @@
\faUser~ {{ ak.owners_list | latex_escape }} \faUser~ {{ ak.owners_list | latex_escape }}
{% if show_types %}
\faList~ {{ak.types_list }}
{% endif %}
{% if not result_presentation_mode %} {% if not result_presentation_mode %}
\faClock~ {{ak.durations_list}} \faClock~ {{ak.durations_list}}
{% endif %} {% endif %}
......
{% load tz %} {% load tz %}
{% load fontawesome_6 %}
{% timezone event.timezone %} {% timezone event.timezone %}
<table class="table table-striped"> <table class="table table-striped">
...@@ -7,7 +8,10 @@ ...@@ -7,7 +8,10 @@
<span class="text-secondary float-end"> <span class="text-secondary float-end">
{{ message.timestamp|date:"Y-m-d H:i:s" }} {{ message.timestamp|date:"Y-m-d H:i:s" }}
</span> </span>
<h5><a href="{{ message.ak.detail_url }}">{{ message.ak }}</a></h5> <h5><a href="{{ message.ak.detail_url }}">
{% if message.resolved %}{% fa6_icon "check-circle" %} {% endif %}
{{ message.ak }}
</a></h5>
<p>{{ message.text }}</p> <p>{{ message.text }}</p>
</td></tr> </td></tr>
{% endfor %} {% endfor %}
......
...@@ -3,8 +3,11 @@ from django.apps import apps ...@@ -3,8 +3,11 @@ from django.apps import apps
from django.conf import settings from django.conf import settings
from django.utils.html import format_html, mark_safe, conditional_escape from django.utils.html import format_html, mark_safe, conditional_escape
from django.templatetags.static import static from django.templatetags.static import static
from django.template.defaultfilters import date
from fontawesome_6.app_settings import get_css from fontawesome_6.app_settings import get_css
from AKModel.models import Event
register = template.Library() register = template.Library()
...@@ -55,8 +58,7 @@ def wiki_owners_export(owners, event): ...@@ -55,8 +58,7 @@ def wiki_owners_export(owners, event):
but external links when owner specified a non-wikilink. This is applied to the full list of owners but external links when owner specified a non-wikilink. This is applied to the full list of owners
:param owners: list of owners :param owners: list of owners
:param event: event this owner belongs to and that is currently exported :param event: event this owner belongs to and that is currently exported (specifying this directly prevents unnecessary database lookups) #pylint: disable=line-too-long
(specifying this directly prevents unnecesary database lookups)
:return: linkified owners list in wiki syntax :return: linkified owners list in wiki syntax
:rtype: str :rtype: str
""" """
...@@ -72,6 +74,21 @@ def wiki_owners_export(owners, event): ...@@ -72,6 +74,21 @@ def wiki_owners_export(owners, event):
return ", ".join(to_link(owner) for owner in owners.all()) return ", ".join(to_link(owner) for owner in owners.all())
@register.filter
def event_month_year(event:Event):
"""
Print rough event date (month and year)
:param event: event to print the date for
:return: string containing rough date information for event
"""
if event.start.month == event.end.month:
return f"{date(event.start, 'F')} {event.start.year}"
event_start_string = date(event.start, 'F')
if event.start.year != event.end.year:
event_start_string = f"{event_start_string} {event.start.year}"
return f"{event_start_string} - {date(event.end, 'F')} {event.end.year}"
# get list of relevant css fontawesome css files for this instance # get list of relevant css fontawesome css files for this instance
css = get_css() css = get_css()
......
...@@ -5,10 +5,21 @@ from django.contrib.auth import get_user_model ...@@ -5,10 +5,21 @@ from django.contrib.auth import get_user_model
from django.contrib.messages import get_messages from django.contrib.messages import get_messages
from django.contrib.messages.storage.base import Message from django.contrib.messages.storage.base import Message
from django.test import TestCase from django.test import TestCase
from django.urls import reverse_lazy, reverse from django.urls import reverse, reverse_lazy
from AKModel.models import Event, AKOwner, AKCategory, AKTrack, AKRequirement, AK, Room, AKSlot, AKOrgaMessage, \ from AKModel.models import (
ConstraintViolation, DefaultSlot AK,
AKCategory,
AKOrgaMessage,
AKOwner,
AKRequirement,
AKSlot,
AKTrack,
ConstraintViolation,
DefaultSlot,
Event,
Room,
)
class BasicViewTests: class BasicViewTests:
...@@ -29,9 +40,10 @@ class BasicViewTests: ...@@ -29,9 +40,10 @@ class BasicViewTests:
since the test framework does not understand the concept of abstract test definitions and would handle this class since the test framework does not understand the concept of abstract test definitions and would handle this class
as real test case otherwise, distorting the test results. as real test case otherwise, distorting the test results.
""" """
# pylint: disable=no-member # pylint: disable=no-member
VIEWS = [] VIEWS = []
APP_NAME = '' APP_NAME = ""
VIEWS_STAFF_ONLY = [] VIEWS_STAFF_ONLY = []
EDIT_TESTCASES = [] EDIT_TESTCASES = []
...@@ -41,16 +53,26 @@ class BasicViewTests: ...@@ -41,16 +53,26 @@ class BasicViewTests:
""" """
user_model = get_user_model() user_model = get_user_model()
self.staff_user = user_model.objects.create( self.staff_user = user_model.objects.create(
username='Test Staff User', email='teststaff@example.com', password='staffpw', username="Test Staff User",
is_staff=True, is_active=True email="teststaff@example.com",
password="staffpw",
is_staff=True,
is_active=True,
) )
self.admin_user = user_model.objects.create( self.admin_user = user_model.objects.create(
username='Test Admin User', email='testadmin@example.com', password='adminpw', username="Test Admin User",
is_staff=True, is_superuser=True, is_active=True email="testadmin@example.com",
password="adminpw",
is_staff=True,
is_superuser=True,
is_active=True,
) )
self.deactivated_user = user_model.objects.create( self.deactivated_user = user_model.objects.create(
username='Test Deactivated User', email='testdeactivated@example.com', password='deactivatedpw', username="Test Deactivated User",
is_staff=True, is_active=False email="testdeactivated@example.com",
password="deactivatedpw",
is_staff=True,
is_active=False,
) )
def _name_and_url(self, view_name): def _name_and_url(self, view_name):
...@@ -62,7 +84,9 @@ class BasicViewTests: ...@@ -62,7 +84,9 @@ class BasicViewTests:
:return: full view name with prefix if applicable, url of the view :return: full view name with prefix if applicable, url of the view
:rtype: str, str :rtype: str, str
""" """
view_name_with_prefix = f"{self.APP_NAME}:{view_name[0]}" if self.APP_NAME != "" else view_name[0] view_name_with_prefix = (
f"{self.APP_NAME}:{view_name[0]}" if self.APP_NAME != "" else view_name[0]
)
url = reverse(view_name_with_prefix, kwargs=view_name[1]) url = reverse(view_name_with_prefix, kwargs=view_name[1])
return view_name_with_prefix, url return view_name_with_prefix, url
...@@ -95,10 +119,16 @@ class BasicViewTests: ...@@ -95,10 +119,16 @@ class BasicViewTests:
view_name_with_prefix, url = self._name_and_url(view_name) view_name_with_prefix, url = self._name_and_url(view_name)
try: try:
response = self.client.get(url) response = self.client.get(url)
self.assertEqual(response.status_code, 200, msg=f"{view_name_with_prefix} ({url}) broken") self.assertEqual(
response.status_code,
200,
msg=f"{view_name_with_prefix} ({url}) broken",
)
except Exception: # pylint: disable=broad-exception-caught except Exception: # pylint: disable=broad-exception-caught
self.fail(f"An error occurred during rendering of {view_name_with_prefix} ({url}):" self.fail(
f"\n\n{traceback.format_exc()}") f"An error occurred during rendering of {view_name_with_prefix} ({url}):"
f"\n\n{traceback.format_exc()}"
)
def test_access_control_staff_only(self): def test_access_control_staff_only(self):
""" """
...@@ -107,11 +137,16 @@ class BasicViewTests: ...@@ -107,11 +137,16 @@ class BasicViewTests:
# Not logged in? Views should not be visible # Not logged in? Views should not be visible
self.client.logout() self.client.logout()
for view_name_info in self.VIEWS_STAFF_ONLY: for view_name_info in self.VIEWS_STAFF_ONLY:
expected_response_code = 302 if len(view_name_info) == 2 else view_name_info[2] expected_response_code = (
302 if len(view_name_info) == 2 else view_name_info[2]
)
view_name_with_prefix, url = self._name_and_url(view_name_info) view_name_with_prefix, url = self._name_and_url(view_name_info)
response = self.client.get(url) response = self.client.get(url)
self.assertEqual(response.status_code, expected_response_code, self.assertEqual(
msg=f"{view_name_with_prefix} ({url}) accessible by non-staff") response.status_code,
expected_response_code,
msg=f"{view_name_with_prefix} ({url}) accessible by non-staff",
)
# Logged in? Views should be visible # Logged in? Views should be visible
self.client.force_login(self.staff_user) self.client.force_login(self.staff_user)
...@@ -119,20 +154,30 @@ class BasicViewTests: ...@@ -119,20 +154,30 @@ class BasicViewTests:
view_name_with_prefix, url = self._name_and_url(view_name_info) view_name_with_prefix, url = self._name_and_url(view_name_info)
try: try:
response = self.client.get(url) response = self.client.get(url)
self.assertEqual(response.status_code, 200, self.assertEqual(
msg=f"{view_name_with_prefix} ({url}) should be accessible for staff (but isn't)") response.status_code,
200,
msg=f"{view_name_with_prefix} ({url}) should be accessible for staff (but isn't)",
)
except Exception: # pylint: disable=broad-exception-caught except Exception: # pylint: disable=broad-exception-caught
self.fail(f"An error occurred during rendering of {view_name_with_prefix} ({url}):" self.fail(
f"\n\n{traceback.format_exc()}") f"An error occurred during rendering of {view_name_with_prefix} ({url}):"
f"\n\n{traceback.format_exc()}"
)
# Disabled user? Views should not be visible # Disabled user? Views should not be visible
self.client.force_login(self.deactivated_user) self.client.force_login(self.deactivated_user)
for view_name_info in self.VIEWS_STAFF_ONLY: for view_name_info in self.VIEWS_STAFF_ONLY:
expected_response_code = 302 if len(view_name_info) == 2 else view_name_info[2] expected_response_code = (
302 if len(view_name_info) == 2 else view_name_info[2]
)
view_name_with_prefix, url = self._name_and_url(view_name_info) view_name_with_prefix, url = self._name_and_url(view_name_info)
response = self.client.get(url) response = self.client.get(url)
self.assertEqual(response.status_code, expected_response_code, self.assertEqual(
msg=f"{view_name_with_prefix} ({url}) still accessible for deactivated user") response.status_code,
expected_response_code,
msg=f"{view_name_with_prefix} ({url}) still accessible for deactivated user",
)
def _to_sendable_value(self, val): def _to_sendable_value(self, val):
""" """
...@@ -182,16 +227,26 @@ class BasicViewTests: ...@@ -182,16 +227,26 @@ class BasicViewTests:
self.client.logout() self.client.logout()
response = self.client.get(url) response = self.client.get(url)
self.assertEqual(response.status_code, 200, msg=f"{name}: Could not load edit form via GET ({url})") self.assertEqual(
response.status_code,
200,
msg=f"{name}: Could not load edit form via GET ({url})",
)
form = response.context[form_name] form = response.context[form_name]
data = {k: self._to_sendable_value(v) for k, v in form.initial.items()} data = {k: self._to_sendable_value(v) for k, v in form.initial.items()}
response = self.client.post(url, data=data) response = self.client.post(url, data=data)
if expected_code == 200: if expected_code == 200:
self.assertEqual(response.status_code, 200, msg=f"{name}: Did not return 200 ({url}") self.assertEqual(
response.status_code, 200, msg=f"{name}: Did not return 200 ({url}"
)
elif expected_code == 302: elif expected_code == 302:
self.assertRedirects(response, target_url, msg_prefix=f"{name}: Did not redirect ({url} -> {target_url}") self.assertRedirects(
response,
target_url,
msg_prefix=f"{name}: Did not redirect ({url} -> {target_url}",
)
if expected_message != "": if expected_message != "":
self._assert_message(response, expected_message, msg_prefix=f"{name}") self._assert_message(response, expected_message, msg_prefix=f"{name}")
...@@ -200,30 +255,42 @@ class ModelViewTests(BasicViewTests, TestCase): ...@@ -200,30 +255,42 @@ class ModelViewTests(BasicViewTests, TestCase):
""" """
Basic view test cases for views from AKModel plus some custom tests Basic view test cases for views from AKModel plus some custom tests
""" """
fixtures = ['model.json']
fixtures = ["model.json"]
ADMIN_MODELS = [ ADMIN_MODELS = [
(Event, 'event'), (AKOwner, 'akowner'), (AKCategory, 'akcategory'), (AKTrack, 'aktrack'), (Event, "event"),
(AKRequirement, 'akrequirement'), (AK, 'ak'), (Room, 'room'), (AKSlot, 'akslot'), (AKOwner, "akowner"),
(AKOrgaMessage, 'akorgamessage'), (ConstraintViolation, 'constraintviolation'), (AKCategory, "akcategory"),
(DefaultSlot, 'defaultslot') (AKTrack, "aktrack"),
(AKRequirement, "akrequirement"),
(AK, "ak"),
(Room, "room"),
(AKSlot, "akslot"),
(AKOrgaMessage, "akorgamessage"),
(ConstraintViolation, "constraintviolation"),
(DefaultSlot, "defaultslot"),
] ]
VIEWS_STAFF_ONLY = [ VIEWS_STAFF_ONLY = [
('admin:index', {}), ("admin:index", {}),
('admin:event_status', {'event_slug': 'kif42'}), ("admin:event_status", {"event_slug": "kif42"}),
('admin:event_requirement_overview', {'event_slug': 'kif42'}), ("admin:event_requirement_overview", {"event_slug": "kif42"}),
('admin:ak_csv_export', {'event_slug': 'kif42'}), ("admin:ak_csv_export", {"event_slug": "kif42"}),
('admin:ak_wiki_export', {'slug': 'kif42'}), ("admin:ak_wiki_export", {"slug": "kif42"}),
('admin:ak_delete_orga_messages', {'event_slug': 'kif42'}), ("admin:ak_delete_orga_messages", {"event_slug": "kif42"}),
('admin:ak_slide_export', {'event_slug': 'kif42'}), ("admin:ak_slide_export", {"event_slug": "kif42"}),
('admin:default-slots-editor', {'event_slug': 'kif42'}), ("admin:default-slots-editor", {"event_slug": "kif42"}),
('admin:room-import', {'event_slug': 'kif42'}), ("admin:room-import", {"event_slug": "kif42"}),
('admin:new_event_wizard_start', {}), ("admin:new_event_wizard_start", {}),
] ]
EDIT_TESTCASES = [ EDIT_TESTCASES = [
{'view': 'admin:default-slots-editor', 'kwargs': {'event_slug': 'kif42'}, "admin": True}, {
"view": "admin:default-slots-editor",
"kwargs": {"event_slug": "kif42"},
"admin": True,
},
] ]
def test_admin(self): def test_admin(self):
...@@ -234,24 +301,32 @@ class ModelViewTests(BasicViewTests, TestCase): ...@@ -234,24 +301,32 @@ class ModelViewTests(BasicViewTests, TestCase):
for model in self.ADMIN_MODELS: for model in self.ADMIN_MODELS:
# Special treatment for a subset of views (where we exchanged default functionality, e.g., create views) # Special treatment for a subset of views (where we exchanged default functionality, e.g., create views)
if model[1] == "event": if model[1] == "event":
_, url = self._name_and_url(('admin:new_event_wizard_start', {})) _, url = self._name_and_url(("admin:new_event_wizard_start", {}))
elif model[1] == "room": elif model[1] == "room":
_, url = self._name_and_url(('admin:room-new', {})) _, url = self._name_and_url(("admin:room-new", {}))
# Otherwise, just call the creation form view # Otherwise, just call the creation form view
else: else:
_, url = self._name_and_url((f'admin:AKModel_{model[1]}_add', {})) _, url = self._name_and_url((f"admin:AKModel_{model[1]}_add", {}))
response = self.client.get(url) response = self.client.get(url)
self.assertEqual(response.status_code, 200, msg=f"Add form for model {model[1]} ({url}) broken") self.assertEqual(
response.status_code,
200,
msg=f"Add form for model {model[1]} ({url}) broken",
)
for model in self.ADMIN_MODELS: for model in self.ADMIN_MODELS:
# Test the update view using the first existing instance of each model # Test the update view using the first existing instance of each model
m = model[0].objects.first() m = model[0].objects.first()
if m is not None: if m is not None:
_, url = self._name_and_url( _, url = self._name_and_url(
(f'admin:AKModel_{model[1]}_change', {'object_id': m.pk}) (f"admin:AKModel_{model[1]}_change", {"object_id": m.pk})
) )
response = self.client.get(url) response = self.client.get(url)
self.assertEqual(response.status_code, 200, msg=f"Edit form for model {model[1]} ({url}) broken") self.assertEqual(
response.status_code,
200,
msg=f"Edit form for model {model[1]} ({url}) broken",
)
def test_wiki_export(self): def test_wiki_export(self):
""" """
...@@ -260,17 +335,27 @@ class ModelViewTests(BasicViewTests, TestCase): ...@@ -260,17 +335,27 @@ class ModelViewTests(BasicViewTests, TestCase):
""" """
self.client.force_login(self.admin_user) self.client.force_login(self.admin_user)
export_url = reverse_lazy("admin:ak_wiki_export", kwargs={'slug': 'kif42'}) export_url = reverse_lazy("admin:ak_wiki_export", kwargs={"slug": "kif42"})
response = self.client.get(export_url) response = self.client.get(export_url)
self.assertEqual(response.status_code, 200, "Export not working at all") self.assertEqual(response.status_code, 200, "Export not working at all")
export_count = 0 export_count = 0
for _, aks in response.context["categories_with_aks"]: for _, aks in response.context["categories_with_aks"]:
for ak in aks: for ak in aks:
self.assertEqual(ak.include_in_export, True, self.assertEqual(
f"AK with export flag set to False (pk={ak.pk}) included in export") ak.include_in_export,
self.assertNotEqual(ak.pk, 1, "AK known to be excluded from export (PK 1) included in export") True,
f"AK with export flag set to False (pk={ak.pk}) included in export",
)
self.assertNotEqual(
ak.pk,
1,
"AK known to be excluded from export (PK 1) included in export",
)
export_count += 1 export_count += 1
self.assertEqual(export_count, AK.objects.filter(event_id=2, include_in_export=True).count(), self.assertEqual(
"Wiki export contained the wrong number of AKs") export_count,
AK.objects.filter(event_id=2, include_in_export=True).count(),
"Wiki export contained the wrong number of AKs",
)
...@@ -4,10 +4,11 @@ from django.urls import include, path ...@@ -4,10 +4,11 @@ from django.urls import include, path
from rest_framework.routers import DefaultRouter from rest_framework.routers import DefaultRouter
import AKModel.views.api import AKModel.views.api
from AKModel.views.manage import ExportSlidesView, PlanPublishView, PlanUnpublishView, DefaultSlotEditorView from AKModel.views.ak import AKCSVExportView, AKMessageDeleteView, AKRequirementOverview, AKWikiExportView
from AKModel.views.ak import AKRequirementOverview, AKCSVExportView, AKWikiExportView, AKMessageDeleteView from AKModel.views.event_wizard import NewEventWizardActivateView, NewEventWizardFinishView, NewEventWizardImportView, \
from AKModel.views.event_wizard import NewEventWizardStartView, NewEventWizardPrepareImportView, \ NewEventWizardPrepareImportView, NewEventWizardSettingsView, NewEventWizardStartView
NewEventWizardImportView, NewEventWizardActivateView, NewEventWizardFinishView, NewEventWizardSettingsView from AKModel.views.manage import AKsByUserView, DefaultSlotEditorView, ExportSlidesView, PlanPublishView, \
PlanUnpublishView, PollPublishView, PollUnpublishView
from AKModel.views.room import RoomBatchCreationView from AKModel.views.room import RoomBatchCreationView
from AKModel.views.status import EventStatusView from AKModel.views.status import EventStatusView
...@@ -43,6 +44,11 @@ if apps.is_installed("AKSubmission"): ...@@ -43,6 +44,11 @@ if apps.is_installed("AKSubmission"):
from AKSubmission.api import increment_interest_counter from AKSubmission.api import increment_interest_counter
extra_paths.append(path('api/ak/<pk>/indicate-interest/', increment_interest_counter, name='submission-ak-indicate-interest')) extra_paths.append(path('api/ak/<pk>/indicate-interest/', increment_interest_counter, name='submission-ak-indicate-interest'))
# If AKSolverInterface is active, register additional API endpoints
if apps.is_installed("AKSolverInterface"):
from AKSolverInterface.api import ExportEventForSolverViewSet
api_router.register("solver-export", ExportEventForSolverViewSet, basename="solver-export")
event_specific_paths = [ event_specific_paths = [
path('api/', include(api_router.urls), name='api'), path('api/', include(api_router.urls), name='api'),
] ]
...@@ -67,7 +73,9 @@ def get_admin_urls_event_wizard(admin_site): ...@@ -67,7 +73,9 @@ def get_admin_urls_event_wizard(admin_site):
return [ return [
path('add/wizard/start/', admin_site.admin_view(NewEventWizardStartView.as_view()), path('add/wizard/start/', admin_site.admin_view(NewEventWizardStartView.as_view()),
name="new_event_wizard_start"), name="new_event_wizard_start"),
path('add/wizard/settings/', csp_update(FONT_SRC=["maxcdn.bootstrapcdn.com"], SCRIPT_SRC=["cdnjs.cloudflare.com"], STYLE_SRC=["cdnjs.cloudflare.com"])(admin_site.admin_view(NewEventWizardSettingsView.as_view())), path('add/wizard/settings/', csp_update(
{"font-src": ["maxcdn.bootstrapcdn.com"], "script-src": ["cdnjs.cloudflare.com"],
"style-src": ["cdnjs.cloudflare.com"]})(admin_site.admin_view(NewEventWizardSettingsView.as_view())),
name="new_event_wizard_settings"), name="new_event_wizard_settings"),
path('add/wizard/created/<slug:event_slug>/', admin_site.admin_view(NewEventWizardPrepareImportView.as_view()), path('add/wizard/created/<slug:event_slug>/', admin_site.admin_view(NewEventWizardPrepareImportView.as_view()),
name="new_event_wizard_prepare_import"), name="new_event_wizard_prepare_import"),
...@@ -91,6 +99,8 @@ def get_admin_urls_event(admin_site): ...@@ -91,6 +99,8 @@ def get_admin_urls_event(admin_site):
path('<slug:event_slug>/status/', admin_site.admin_view(EventStatusView.as_view()), name="event_status"), path('<slug:event_slug>/status/', admin_site.admin_view(EventStatusView.as_view()), name="event_status"),
path('<slug:event_slug>/requirements/', admin_site.admin_view(AKRequirementOverview.as_view()), path('<slug:event_slug>/requirements/', admin_site.admin_view(AKRequirementOverview.as_view()),
name="event_requirement_overview"), name="event_requirement_overview"),
path('<slug:event_slug>/aks/owner/<pk>/', admin_site.admin_view(AKsByUserView.as_view()),
name="aks_by_owner"),
path('<slug:event_slug>/ak-csv-export/', admin_site.admin_view(AKCSVExportView.as_view()), path('<slug:event_slug>/ak-csv-export/', admin_site.admin_view(AKCSVExportView.as_view()),
name="ak_csv_export"), name="ak_csv_export"),
path('<slug:slug>/ak-wiki-export/', admin_site.admin_view(AKWikiExportView.as_view()), path('<slug:slug>/ak-wiki-export/', admin_site.admin_view(AKWikiExportView.as_view()),
...@@ -100,6 +110,8 @@ def get_admin_urls_event(admin_site): ...@@ -100,6 +110,8 @@ def get_admin_urls_event(admin_site):
path('<slug:event_slug>/ak-slide-export/', admin_site.admin_view(ExportSlidesView.as_view()), name="ak_slide_export"), path('<slug:event_slug>/ak-slide-export/', admin_site.admin_view(ExportSlidesView.as_view()), name="ak_slide_export"),
path('plan/publish/', admin_site.admin_view(PlanPublishView.as_view()), name="plan-publish"), path('plan/publish/', admin_site.admin_view(PlanPublishView.as_view()), name="plan-publish"),
path('plan/unpublish/', admin_site.admin_view(PlanUnpublishView.as_view()), name="plan-unpublish"), path('plan/unpublish/', admin_site.admin_view(PlanUnpublishView.as_view()), name="plan-unpublish"),
path('poll/publish/', admin_site.admin_view(PollPublishView.as_view()), name="poll-publish"),
path('poll/unpublish/', admin_site.admin_view(PollUnpublishView.as_view()), name="poll-unpublish"),
path('<slug:event_slug>/defaultSlots/', admin_site.admin_view(DefaultSlotEditorView.as_view()), path('<slug:event_slug>/defaultSlots/', admin_site.admin_view(DefaultSlotEditorView.as_view()),
name="default-slots-editor"), name="default-slots-editor"),
path('<slug:event_slug>/importRooms/', admin_site.admin_view(RoomBatchCreationView.as_view()), path('<slug:event_slug>/importRooms/', admin_site.admin_view(RoomBatchCreationView.as_view()),
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -51,6 +51,8 @@ ...@@ -51,6 +51,8 @@
start: '{{ start | timezone:event.timezone | date:"Y-m-d H:i:s" }}', start: '{{ start | timezone:event.timezone | date:"Y-m-d H:i:s" }}',
end: '{{ end | timezone:event.timezone | date:"Y-m-d H:i:s"}}', end: '{{ end | timezone:event.timezone | date:"Y-m-d H:i:s"}}',
}, },
slotMinTime: '{{ earliest_start_hour }}:00:00',
slotMaxTime: '{{ latest_end_hour }}:00:00',
eventDidMount: function(info) { eventDidMount: function(info) {
$(info.el).tooltip({title: info.event.extendedProps.description}); $(info.el).tooltip({title: info.event.extendedProps.description});
}, },
......
from django.test import TestCase from django.test import TestCase
from AKModel.tests import BasicViewTests from AKModel.tests.test_views import BasicViewTests
class PlanViewTests(BasicViewTests, TestCase): class PlanViewTests(BasicViewTests, TestCase):
......
from csp.decorators import csp_replace from csp.decorators import csp_replace
from django.urls import path, include from django.urls import include, path
from . import views from . import views
...@@ -10,7 +10,8 @@ urlpatterns = [ ...@@ -10,7 +10,8 @@ urlpatterns = [
'<slug:event_slug>/plan/', '<slug:event_slug>/plan/',
include([ include([
path('', views.PlanIndexView.as_view(), name='plan_overview'), path('', views.PlanIndexView.as_view(), name='plan_overview'),
path('wall/', csp_replace(FRAME_ANCESTORS="*")(views.PlanScreenView.as_view()), name='plan_wall'), path('wall/', csp_replace({"frame-ancestors": ("*",)})(views.PlanScreenView.as_view()),
name='plan_wall'),
path('room/<int:pk>/', views.PlanRoomView.as_view(), name='plan_room'), path('room/<int:pk>/', views.PlanRoomView.as_view(), name='plan_room'),
path('track/<int:pk>/', views.PlanTrackView.as_view(), name='plan_track'), path('track/<int:pk>/', views.PlanTrackView.as_view(), name='plan_track'),
]) ])
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.