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
  • komasolver
  • main
  • renovate/django-5.x
  • renovate/django-debug-toolbar-5.x
  • renovate/django_csp-4.x
  • renovate/djangorestframework-3.x
  • renovate/sphinxcontrib-apidoc-0.x
  • renovate/tzdata-2025.x
  • renovate/uwsgi-2.x
9 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 759 additions and 132 deletions
{% extends 'AKSubmission/submission_base.html' %}
{% load i18n %}
{% load fontawesome_6 %}
{% load tags_AKSubmission %}
{% block title %}{% trans "AKs" %}: {{ event.name }} - {% trans "AKs" %}{% endblock %}
{% block meta %}
<meta name="twitter:card" content="summary" />
<meta name="twitter:title" content="{{ event.name }} - {% trans "AKs" %}" />
{% endblock %}
{% block imports %}
{% include "AKSubmission/ak_interest_script.html" %}
{% endblock %}
{% block breadcrumbs %}
{% include "AKSubmission/submission_breadcrumbs.html" %}
<li class="breadcrumb-item"><a
href="{% url 'submit:submission_overview' event_slug=event.slug %}">{% trans "AK Submission" %}</a></li>
<li class="breadcrumb-item active">{% trans "AK List" %}</li>
{% endblock %}
{% block content %}
{% if event.active %}
<a class="btn btn-success float-end" href="{% url 'submit:submission_overview' event_slug=event.slug %}">
{% fa6_icon 'plus' 'fas' %} {% trans "Add AK" %}
</a>
{% endif %}
<h1>{% trans "AKs" %}: {{ event.name }}</h1>
{% include "AKSubmission/ak_list.html" %}
{% endblock %}
{% load i18n %}
{% load fontawesome_6 %}
{% load tags_AKSubmission %}
<table id="akTable" class="table table-striped">
<thead>
<tr>
<th>{% trans "Name" %}</th>
<th>{% trans "Who?" %}</th>
<th>{% trans 'Category' %}</th>
{% if show_types %}
<th>{% trans 'Types' %}</th>
{% endif %}
<th></th>
</tr>
</thead>
<tbody>
{% for ak in AKs %}
<tr>
<td>
<a href="{{ ak.detail_url }}"
class="text-dark text-decoration-none font-weight-bold">
{{ ak.name }}
</a>
{% if ak.present %}
<span class="badge bg-dark rounded-pill"
title="{% trans 'Present results of this AK' %}">{% fa6_icon "bullhorn" 'fas' %}</span>
{% endif %}
{% if ak.reso %}
<span class="badge bg-dark rounded-pill"
title="{% trans 'Intends to submit a resolution' %}">{% fa6_icon "scroll" 'fas' %}</span>
{% endif %}
</td>
<td>
{% if ak.wish %}
<span class="badge bg-dark rounded-pill">{% trans "AK Wish" %}</span>
{% else %}
{% include "AKSubmission/owners_list.html" with owners=ak.owners %}
{% endif %}
</td>
<td>{% category_linked_badge ak.category event.slug %}</td>
{% if show_types %}
<td>
{% for aktype in ak.types.all %}
<span class="badge bg-info">{{ aktype }}</span>
{% endfor %}
</td>
{% endif %}
<td class="text-end" style="white-space: nowrap;">
<a href="{{ ak.detail_url }}" data-bs-toggle="tooltip"
title="{% trans 'Details' %}"
class="btn btn-primary">{% fa6_icon 'info' 'fas' %}</a>
{% if ak.link %}
<a href="{{ ak.link }}" data-bs-toggle="tooltip"
title="{% trans 'Open external link' %}"
class="btn btn-info">{% fa6_icon 'external-link-alt' 'fas' %}</a>
{% endif %}
{% if event.active %}
<a href="{{ ak.edit_url }}" data-bs-toggle="tooltip"
title="{% trans 'Edit' %}"
class="btn btn-success">{% fa6_icon 'pencil-alt' 'fas' %}</a>
{% if interest_indication_active %}
<span data-ak_id="{{ ak.pk }}" data-bs-toggle="tooltip"
title="{% trans 'Show Interest' %}"
class="btn btn-primary btn-interest" style="cursor: pointer">{% fa6_icon 'thumbs-up' 'fas' %}</span>
{% endif %}
{% endif %}
</td>
</tr>
<tr>
<td colspan="5" class="small">{{ ak.description|linebreaks }}</td>
</tr>
{% empty %}
<tr>
<td colspan="5" class="small">{% trans "There are no AKs in this category yet" %}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% extends 'AKSubmission/submission_base.html' %}
{% load i18n %}
{% load django_bootstrap5 %}
{% load fontawesome_6 %}
{% block title %}{% trans "AKs" %}: {{ event.name }} -
{% trans "Add confidential message to organizers" %}{% endblock %}
{% block breadcrumbs %}
{% include "AKSubmission/submission_breadcrumbs.html" %}
<li class="breadcrumb-item"><a
href="{% url 'submit:submission_overview' event_slug=event.slug %}">{% trans "AK Submission" %}</a></li>
<li class="breadcrumb-item"><a
href="{{ ak.detail_url }}">{{ ak.short_name }}</a></li>
<li class="breadcrumb-item active">{% trans "Add confidential message to organizers" %}</li>
{% endblock %}
{% block content %}
{% block headline %}
<h2>{{ ak.name }}</h2>
<h4 class="mt-3">{% trans 'Add confidential message to organizers' %}</h4>
{% endblock %}
<form method="POST" class="post-form">{% csrf_token %}
{% bootstrap_form form %}
<button type="submit" class="save btn btn-primary float-end">
{% fa6_icon "check" 'fas' %} {% trans "Send" %}
</button>
<button type="reset" class="btn btn-danger">
{% fa6_icon "undo-alt" 'fas' %} {% trans "Reset Form" %}
</button>
<a href="{{ ak.detail_url }}" class="btn btn-secondary">
{% fa6_icon "times" 'fas' %} {% trans "Cancel" %}
</a>
</form>
{% endblock %}
{% extends 'base.html' %}
{% extends 'AKSubmission/submission_base.html' %}
{% load i18n %}
{% load bootstrap4 %}
{% load fontawesome %}
{% load django_bootstrap5 %}
{% load fontawesome_6 %}
{% block title %}{% trans "AKs" %}: {{ event.name }} - {% trans "AK Owner" %}{% endblock %}
{% block breadcrumbs %}
<li class="breadcrumb-item"><a href="#">AKPlanning</a></li>
<li class="breadcrumb-item"><a href="#">{{ event.slug }}</a></li>
{% include "AKSubmission/submission_breadcrumbs.html" %}
<li class="breadcrumb-item"><a
href="{% url 'submit:submission_overview' event_slug=event.slug %}">{% trans "AK Submission" %}</a></li>
<li class="breadcrumb-item active">{% trans "AK Owner" %}</li>
......@@ -20,17 +19,15 @@
{% endblock %}
<form method="POST" class="post-form">{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button type="reset" class="btn btn-danger">
{% fontawesome_icon "undo-alt" %} {% trans "Reset" %}
</button>
<button type="submit" class="save btn btn-primary float-end">
{% fa6_icon "check" 'fas' %} {% trans "Continue" %}
</button>
<button type="reset" class="btn btn-danger">
{% fa6_icon "undo-alt" 'fas' %} {% trans "Reset Form" %}
</button>
<a href="{% url 'submit:submission_overview' event_slug=event.slug %}" class="btn btn-secondary">
{% fontawesome_icon "times" %} {% trans "Cancel" %}
</a>
<button type="submit" class="save btn btn-primary float-right">
{% fontawesome_icon "check" %} {% trans "Continue" %}
</button>
{% endbuttons %}
<a href="{% url 'submit:submission_overview' event_slug=event.slug %}" class="btn btn-secondary">
{% fa6_icon "times" 'fas' %} {% trans "Cancel" %}
</a>
</form>
{% endblock %}
\ No newline at end of file
{% extends 'AKSubmission/submission_base.html' %}
{% load i18n %}
{% load django_bootstrap5 %}
{% load fontawesome_6 %}
{% block title %}{% trans "AKs" %}: {{ event.name }} - {% trans "AK Duration(s)" %}{% endblock %}
{% block breadcrumbs %}
{% include "AKSubmission/submission_breadcrumbs.html" %}
<li class="breadcrumb-item"><a
href="{% url 'submit:submission_overview' event_slug=event.slug %}">{% trans "AK Submission" %}</a></li>
<li class="breadcrumb-item"><a
href="{{ ak.detail_url }}">{{ ak.short_name }}</a></li>
<li class="breadcrumb-item active">{% trans "AK Duration(s)" %}</li>
{% endblock %}
{% block content %}
{% block headline %}
<h2>{% trans 'AK Duration(s)' %}</h2>
{% endblock %}
<form method="POST" class="post-form">{% csrf_token %}
{% bootstrap_form form %}
<button type="submit" class="save btn btn-primary float-end">
{% fa6_icon "check" 'fas' %} {% trans "Continue" %}
</button>
<button type="reset" class="btn btn-danger">
{% fa6_icon "undo-alt" 'fas' %} {% trans "Reset Form" %}
</button>
<a href="{{ ak.detail_url }}" class="btn btn-secondary">
{% fa6_icon "times" 'fas' %} {% trans "Cancel" %}
</a>
</form>
{% endblock %}
{% extends 'AKSubmission/submission_base.html' %}
{% load i18n %}
{% load django_bootstrap5 %}
{% load fontawesome_6 %}
{% block title %}{% trans "AKs" %}: {{ event.name }} - {% trans "AK Duration(s)" %}{% endblock %}
{% block breadcrumbs %}
{% include "AKSubmission/submission_breadcrumbs.html" %}
<li class="breadcrumb-item"><a
href="{% url 'submit:submission_overview' event_slug=event.slug %}">{% trans "AK Submission" %}</a></li>
<li class="breadcrumb-item"><a
href="{{ ak.detail_url }}">{{ ak.short_name }}</a></li>
<li class="breadcrumb-item active">{% trans "AK Duration(s)" %}</li>
{% endblock %}
{% block content %}
{% block headline %}
<h2>{% trans 'AK Duration(s)' %}</h2>
{% endblock %}
<form method="POST" class="post-form">{% csrf_token %}
<div class="alert alert-danger" style="margin-top:20px;margin-bottom: 20px;">
<h4>{% trans "Do you really want to delete this AK Slot?" %}</h4>
</div>
<table class="table">
<tbody>
<tr>
<td>{% trans "AK" %}</td>
<td>{{ akslot.ak }}</td>
</tr>
<tr>
<td>{% trans "Duration" %}</td>
<td>{{ akslot.duration }}</td>
</tr>
</tbody>
</table>
<button type="submit" class="save btn btn-danger float-end" value="Confirm">
{% fa6_icon "check" 'fas' %} {% trans "Confirm" %}
</button>
<a href="{{ ak.detail_url }}" class="btn btn-secondary">
{% fa6_icon "times" 'fas' %} {% trans "Cancel" %}
</a>
</form>
{% endblock %}
<a href="{% url 'submit:ak_list_by_category' event_slug=event_slug category_pk=category.pk %}">
<span class="badge badge-primary">{{ category }}</span>
<span class="badge bg-primary">{{ category }}</span>
</a>
{% for owner in owners.all %}{% if not forloop.first %}, {% endif %}{% if owner.link %}<a href="{{ owner.link }}">{{ owner }}</a>{% else %}{{ owner }}{% endif %}{% endfor %}
{% extends "base.html" %}
{% load fontawesome_6 %}
{% load i18n %}
{% block breadcrumbs %}
{% include "AKSubmission/submission_breadcrumbs.html" %}
{% endblock %}
{% block footer_custom %}
{% if event.contact_email %}
<h4>
<a href="mailto:{{ event.contact_email }}">{% fa6_icon "envelope" 'fas' %} {% trans "Write to organizers of this event for questions and comments" %}</a>
</h4>
{% endif %}
{% endblock %}
{% load tags_AKModel %}
<li class="breadcrumb-item">
{% if 'AKDashboard'|check_app_installed %}
<a href="{% url 'dashboard:dashboard' %}">AKPlanning</a>
{% else %}
AKPlanning
{% endif %}
</li>
<li class="breadcrumb-item">
{% if 'AKDashboard'|check_app_installed %}
<a href="{% url 'dashboard:dashboard_event' slug=event.slug %}">{{ event }}</a>
{% else %}
{{ event }}
{% endif %}
</li>
{% extends 'AKSubmission/submission_base.html' %}
{% load i18n %}
{% load fontawesome_6 %}
{% load static %}
{% block title %}{% trans "AKs" %}: {{ event.name }} - {% trans "AK Submission" %}{% endblock %}
{% block breadcrumbs %}
{% include "AKSubmission/submission_breadcrumbs.html" %}
<li class="breadcrumb-item active">{% trans "AK Submission" %}</li>
{% endblock %}
{% block content %}
<h1>{{ event.name }}</h1>
{% include "messages.html" %}
<div class="alert alert-warning" style="margin-top:20px;margin-bottom: 20px;">
{% trans "System is not yet configured for AK submission and listing. Please try again later." %}
</div>
{% endblock %}
{% extends 'base.html' %}
{% extends 'AKSubmission/submission_base.html' %}
{% load i18n %}
{% load fontawesome %}
{% load fontawesome_6 %}
{% load static %}
{% block title %}{% trans "AKs" %}: {{ event.name }} - {% trans "AK Submission" %}{% endblock %}
{% block breadcrumbs %}
<li class="breadcrumb-item"><a href="#">AKPlanning</a></li>
<li class="breadcrumb-item"><a href="#">{{ event.slug }}</a></li>
<li class="breadcrumb-item active">{% trans "AK Submission" %}</li>
{% block meta %}
<meta name="twitter:card" content="summary" />
<meta name="twitter:title" content="{{ event.name }} - {% trans "AK Submission" %}" />
{% endblock %}
{% block content %}
<h1>{% trans "AKs" %}: {{ event.name }}</h1>
{% block imports %}
<style>
/* Prevent wrapping of buttons in AK table */
.table td:nth-child(5) {
white-space: nowrap;
}
{% include "AKSubmission/messages.html" %}
/* Make Select2 boxes match Bootstrap heights: */
.select2-selection__rendered {
line-height: 32px !important;
}
{% blocktrans %}On this page you can see a list of current AKs, change them and add new ones.{% endblocktrans %}
.select2-selection {
height: 34px !important;
}
</style>
<div class="jumbotron" style="margin-top:20px;">
<form method="POST" action="#" class="form-row">
{% csrf_token %}
<a href="{% url 'submit:submit_ak_wish' event_slug=event.slug %}" class="btn btn-info">
{% trans "New AK Wish" %}
</a>
<span style="font-size: 1.5em">
&nbsp;&nbsp; | &nbsp;
<label for="selectOwnerId" class="align-middle d-inline">{% trans "Who" %}:</label>
</span>&nbsp;&nbsp;
<select name="owner_id" id="selectOwnerId" class="">
<option value="-1">{% trans "I do not own AKs yet" %}</option>
{% for owner in existingOwners %}
<option value="{{ owner.pk }}">{{ owner }}</option>
{% endfor %}
</select> &nbsp;&nbsp;
<input
type="submit"
class="btn btn-primary"
value="{% trans "New AK" %}"
formaction="{% url 'submit:akowner_select' event_slug=event.slug %}"
/>&nbsp;&nbsp;
<input
type="submit"
class="btn btn-success"
value="{% trans 'Edit Person Info' %}"
formaction="{% url 'submit:akowner_edit_dispatch' event_slug=event.slug %}"
/>
</form>
</div>
{% include "AKSubmission/ak_interest_script.html" %}
{% endblock %}
{% block breadcrumbs %}
{% include "AKSubmission/submission_breadcrumbs.html" %}
<li class="breadcrumb-item active">{% trans "AK Submission" %}</li>
{% endblock %}
<h2>{% trans "Current AKs" %}</h2>
{% block content %}
<h1>{% trans "AKs" %}: {{ event.name }}</h1>
<noscript>
{% include "AKSubmission/ak_list_table.html" %}
</noscript>
{% include "messages.html" %}
<ul class="nav nav-tabs" style="margin-bottom:15px">
{% for category, _ in categories %}
<li class="nav-item">
<a class="nav-link {% if forloop.first %}active{% endif %}" data-toggle="tab" href="#category_{{ category.pk }}">{{ category.name }}</a>
</li>
{% endfor %}
</ul>
{% blocktrans %}On this page you can see a list of current AKs, change them and add new ones.{% endblocktrans %}
<div id="akListTabbed" class="tab-content">
{% for category, AKs in categories %}
<div class="tab-pane fade {% if forloop.first %}show active{% endif %}" id="category_{{ category.pk }}">
<p><b>{{ category.name }}:</b> {{ category.description }}</p>
{% include "AKSubmission/ak_list_table.html" %}
{% if event.active %}
<div class="card bg-secondary mt-4 mb-4">
<div class="card-body">
<form method="POST" action="#" class="form-row">
{% csrf_token %}
<a href="{% url 'submit:submit_ak_wish' event_slug=event.slug %}" class="btn btn-info">
{% trans "New AK Wish" %}
</a>
<span style="font-size: 1.5em">
&nbsp;&nbsp; | &nbsp;
<label for="selectOwnerId" class="align-middle d-inline">{% trans "Who" %}:</label>
</span>&nbsp;&nbsp;
<select name="owner_id" id="selectOwnerId" class="">
<option value="-1">{% trans "I do not own AKs yet" %}</option>
{% for owner in existingOwners %}
<option value="{{ owner.pk }}">{{ owner }}</option>
{% endfor %}
</select> &nbsp;&nbsp;
<input
type="submit"
class="btn btn-primary"
value="{% trans "New AK" %}"
formaction="{% url 'submit:akowner_select' event_slug=event.slug %}"
/>&nbsp;&nbsp;
<input
type="submit"
class="btn btn-success"
value="{% trans 'Edit Person Info' %}"
formaction="{% url 'submit:akowner_edit_dispatch' event_slug=event.slug %}"
/>
</form>
</div>
{% endfor %}
</div>
</div>
{% else %}
<div class="alert alert-warning" style="margin-top:20px;margin-bottom: 20px;">
{% trans "This event is not active. You cannot add or change AKs" %}
</div>
{% endif %}
{% include "AKSubmission/ak_list.html" %}
{% endblock %}
{% block bottom_script %}
{% if event.active %}
<script>
$("#selectOwnerId").select2();
</script>
{% endif %}
{% endblock %}
{% extends 'base.html' %}
{% extends 'AKSubmission/submission_base.html' %}
{% load i18n %}
{% load bootstrap4 %}
{% load fontawesome %}
{% load staticfiles %}
{% load django_bootstrap5 %}
{% load fontawesome_6 %}
{% load static %}
{% load tz %}
{% block title %}{% trans "AKs" %}: {{ event.name }} - {% trans "New AK" %}{% endblock %}
{% block imports %}
<link rel="stylesheet" href="{% static 'common/vendor/chosen-js/chosen.css' %}">
<link rel="stylesheet" href="{% static 'common/css/bootstrap-choosen.css' %}">
{% include "AKModel/load_fullcalendar_availabilities.html" %}
<script>
{% get_current_language as LANGUAGE_CODE %}
document.addEventListener('DOMContentLoaded', function () {
createAvailabilityEditors(
'{{ event.timezone }}',
'{{ LANGUAGE_CODE }}',
'{{ event.start | timezone:event.timezone | date:"Y-m-d H:i:s" }}',
'{{ event.end | timezone:event.timezone | date:"Y-m-d H:i:s" }}'
);
});
</script>
<style>
#id_present_helptext::after {
content: " ({% trans "only relevant for KIF-AKs - determines whether the AK appears in the slides for the closing plenary session" %})";
color: #6c757d;
}
</style>
{% endblock %}
{% block breadcrumbs %}
<li class="breadcrumb-item"><a href="#">AKPlanning</a></li>
<li class="breadcrumb-item"><a href="#">{{ event.slug }}</a></li>
{% include "AKSubmission/submission_breadcrumbs.html" %}
<li class="breadcrumb-item"><a
href="{% url 'submit:submission_overview' event_slug=event.slug %}">{% trans "AK Submission" %}</a></li>
<li class="breadcrumb-item"><a href="#">{{ owner.slug }}</a></li>
<li class="breadcrumb-item"><a
href="{% url 'submit:akowner_edit' event_slug=event.slug slug=owner.slug %}">{{ owner.slug }}</a></li>
<li class="breadcrumb-item active">{% trans "New AK" %}</li>
{% endblock %}
{% block content %}
{% include "AKSubmission/messages.html" %}
{% include "messages.html" %}
{% block headline %}
<h2>{% trans 'New AK' %}</h2>
{% endblock %}
<form method="POST" class="post-form">{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button type="reset" class="btn btn-danger">
{% fontawesome_icon "undo-alt" %} {% trans "Reset" %}
</button>
<a href="{% url 'submit:submission_overview' event_slug=event.slug %}" class="btn btn-secondary">
{% fontawesome_icon "times" %} {% trans "Cancel" %}
</a>
<button type="submit" class="save btn btn-primary float-right">
{% fontawesome_icon "check" %} {% trans "Submit" %}
</button>
{% endbuttons %}
{% block form_contents %}
{% bootstrap_form form %}
{% endblock %}
<button type="submit" class="save btn btn-primary float-end">
{% fa6_icon "check" 'fas' %} {% trans "Submit" %}
</button>
<button type="reset" class="btn btn-danger">
{% fa6_icon "undo-alt" 'fas' %} {% trans "Reset Form" %}
</button>
<a href="{% url 'submit:submission_overview' event_slug=event.slug %}" class="btn btn-secondary">
{% fa6_icon "times" 'fas' %} {% trans "Cancel" %}
</a>
</form>
{% endblock %}
{% block bottom_script %}
<script src="{% static 'common/vendor/chosen-js/chosen.jquery.js' %}"></script>
<script>
$(function() {
$('.chosen-select').chosen();
});
$(function () {
$('.chosen-select').chosen();
});
</script>
{% endblock %}
\ No newline at end of file
{% endblock %}
{% extends 'AKSubmission/submit_new.html' %}
{% load i18n %}
{% load static %}
{% block title %}{% trans "AKs" %}: {{ event.name }} - {% trans "New AK Wish" %}{% endblock %}
{% block breadcrumbs %}
<li class="breadcrumb-item"><a href="#">AKPlanning</a></li>
<li class="breadcrumb-item"><a href="#">{{ event.slug }}</a></li>
<li class="breadcrumb-item"><a href="{% url 'submit:submission_overview' event_slug=event.slug %}">{% trans "AK Submission" %}</a></li>
{% include "AKSubmission/submission_breadcrumbs.html" %}
<li class="breadcrumb-item"><a
href="{% url 'submit:submission_overview' event_slug=event.slug %}">{% trans "AK Submission" %}</a></li>
<li class="breadcrumb-item active">{% trans "New AK Wish" %}</li>
{% endblock %}
{% block headline %}
<h2>{% trans 'New AK Wish' %}</h2>
{% endblock %}
\ No newline at end of file
{% endblock %}
{% for tag in tags.all %}
<a href="{% url 'submit:ak_list_by_tag' event_slug=event_slug tag_pk=tag.pk %}"><span class="badge badge-info">{{ tag }}</span></a>
{% endfor %}
{% for track in tracks.all %}
<a href="{% url 'submit:ak_list_by_track' event_slug=event_slug track_pk=track.pk %}"><span
class="badge bg-info">{{ track }}</span></a>
{% endfor %}
from django import template
from fontawesome.templatetags.fontawesome import fontawesome_icon
from fontawesome_6.templatetags.fontawesome_6 import fa6_icon
register = template.Library()
@register.filter
def bool_symbol(bool_val):
"""
Show a nice icon instead of the string true/false
:param bool_val: boolean value to iconify
:return: check or times icon depending on the value
"""
if bool_val:
return fontawesome_icon("check")
return fontawesome_icon("times")
return fa6_icon("check", "fas")
return fa6_icon("times", "fas")
@register.inclusion_tag("AKSubmission/tags_list.html")
def tag_list(tags, event_slug):
return {"tags": tags, "event_slug": event_slug}
@register.inclusion_tag("AKSubmission/tracks_list.html")
def track_list(tracks, event_slug):
"""
Generate a clickable list of tracks (one badge per track) based upon the tracks_list template
:param tracks: tracks to consider
:param event_slug: slug of this event, required for link creation
:return: html fragment containing track links
"""
return {"tracks": tracks, "event_slug": event_slug}
@register.inclusion_tag("AKSubmission/category_list.html")
def category_list(categories, event_slug):
"""
Generate a clickable list of categories (one badge per category) based upon the category_list template
:param categories: categories to consider
:param event_slug: slug of this event, required for link creation
:return: html fragment containing category links
"""
return {"categories": categories, "event_slug": event_slug}
@register.inclusion_tag("AKSubmission/category_linked_badge.html")
def category_linked_badge(category, event_slug):
"""
Generate a clickable category badge based upon the category_linked_badge template
:param category: category to show/link
:param event_slug: slug of this event, required for link creation
:return: html fragment containing badge
"""
return {"category": category, "event_slug": event_slug}
@register.filter
def message_bootstrap_class(tag):
print(tag)
if tag == "error":
return "alert-danger"
elif tag == "success":
return "alert-success"
elif tag == "warning":
return "alert-warning"
return "alert-info"
# Create your tests here.
from datetime import datetime, timedelta
from django.test import TestCase
from django.urls import reverse_lazy
from AKModel.models import AK, AKSlot, Event
from AKModel.tests import BasicViewTests
from AKSubmission.forms import AKSubmissionForm
class ModelViewTests(BasicViewTests, TestCase):
"""
Testcases for AKSubmission app.
This extends :class:`BasicViewTests` for standard view and edit testcases
that are specified in this class as VIEWS and EDIT_TESTCASES.
Additionally several additional testcases, in particular to test the API
and the dispatching for owner selection and editing are specified.
"""
fixtures = ['model.json']
VIEWS = [
('submission_overview', {'event_slug': 'kif42'}),
('ak_detail', {'event_slug': 'kif42', 'pk': 1}),
('ak_history', {'event_slug': 'kif42', 'pk': 1}),
('ak_edit', {'event_slug': 'kif42', 'pk': 1}),
('akslot_add', {'event_slug': 'kif42', 'pk': 1}),
('akmessage_add', {'event_slug': 'kif42', 'pk': 1}),
('akslot_edit', {'event_slug': 'kif42', 'pk': 5}),
('akslot_delete', {'event_slug': 'kif42', 'pk': 5}),
('ak_list', {'event_slug': 'kif42'}),
('ak_list_by_category', {'event_slug': 'kif42', 'category_pk': 4}),
('ak_list_by_track', {'event_slug': 'kif42', 'track_pk': 1}),
('akowner_create', {'event_slug': 'kif42'}),
('akowner_edit', {'event_slug': 'kif42', 'slug': 'a'}),
('submit_ak', {'event_slug': 'kif42', 'owner_slug': 'a'}),
('submit_ak_wish', {'event_slug': 'kif42'}),
('error_not_configured', {'event_slug': 'kif42'}),
]
APP_NAME = 'submit'
EDIT_TESTCASES = [
{'view': 'ak_edit', 'target_view': 'ak_detail', 'kwargs': {'event_slug': 'kif42', 'pk': 1},
'expected_message': "AK successfully updated"},
{'view': 'akslot_edit', 'target_view': 'ak_detail', 'kwargs': {'event_slug': 'kif42', 'pk': 5},
'target_kwargs': {'event_slug': 'kif42', 'pk': 1}, 'expected_message': "AK Slot successfully updated"},
{'view': 'akowner_edit', 'target_view': 'submission_overview', 'kwargs': {'event_slug': 'kif42', 'slug': 'a'},
'target_kwargs': {'event_slug': 'kif42'}, 'expected_message': "Person Info successfully updated"},
]
def test_akslot_edit_delete_prevention(self):
"""
Slots planned already may not be modified or deleted in front end
"""
self.client.logout()
_, url = self._name_and_url(('akslot_edit', {'event_slug': 'kif42', 'pk': 1}))
response = self.client.get(url)
self.assertEqual(response.status_code, 302,
msg=f"AK Slot editing ({url}) possible even though slot was already scheduled")
self._assert_message(response, "You cannot edit a slot that has already been scheduled")
_, url = self._name_and_url(('akslot_delete', {'event_slug': 'kif42', 'pk': 1}))
response = self.client.get(url)
self.assertEqual(response.status_code, 302,
msg=f"AK Slot deletion ({url}) possible even though slot was already scheduled")
self._assert_message(response, "You cannot delete a slot that has already been scheduled")
def test_slot_creation_deletion(self):
"""
Test creation and deletion of slots in frontend
"""
ak_args = {'event_slug': 'kif42', 'pk': 1}
redirect_url = reverse_lazy(f"{self.APP_NAME}:ak_detail", kwargs=ak_args)
# Create a valid slot -> Redirect to AK detail page, message to user
count_slots = AK.objects.get(pk=1).akslot_set.count()
create_url = reverse_lazy(f"{self.APP_NAME}:akslot_add", kwargs=ak_args)
response = self.client.post(create_url, {'ak': 1, 'event': 2, 'duration': 1.5})
self.assertRedirects(response, redirect_url, status_code=302, target_status_code=200,
msg_prefix="Did not correctly trigger redirect")
self.assertEqual(AK.objects.get(pk=1).akslot_set.count(), count_slots + 1,
msg="New slot was not correctly saved")
# Get primary key of newly created Slot
slot_pk = AK.objects.get(pk=1).akslot_set.order_by('pk').last().pk
# Edit the recently created slot: Make sure view is accessible, post change
# -> redirect to detail page, duration updated
edit_url = reverse_lazy(f"{self.APP_NAME}:akslot_edit", kwargs={'event_slug': 'kif42', 'pk': slot_pk})
response = self.client.get(edit_url)
self.assertEqual(response.status_code, 200, msg=f"Cant open edit view for newly created slot ({edit_url})")
response = self.client.post(edit_url, {'ak': 1, 'event': 2, 'duration': 2})
self.assertRedirects(response, redirect_url, status_code=302, target_status_code=200,
msg_prefix="Did not correctly trigger redirect")
self.assertEqual(AKSlot.objects.get(pk=slot_pk).duration, 2,
msg="Slot was not correctly changed")
# Delete recently created slot: Make sure view is accessible, post deletion
# -> redirect to detail page, slot deleted, message to user
deletion_url = reverse_lazy(f"{self.APP_NAME}:akslot_delete", kwargs={'event_slug': 'kif42', 'pk': slot_pk})
response = self.client.get(deletion_url)
self.assertEqual(response.status_code, 200,
msg="Cant open deletion view for newly created slot ({deletion_url})")
response = self.client.post(deletion_url, {})
self.assertRedirects(response, redirect_url, status_code=302, target_status_code=200,
msg_prefix="Did not correctly trigger redirect")
self.assertFalse(AKSlot.objects.filter(pk=slot_pk).exists(), msg="Slot was not correctly deleted")
self.assertEqual(AK.objects.get(pk=1).akslot_set.count(), count_slots, msg="AK still has to many slots")
def test_ak_owner_editing(self):
"""
Test dispatch of user editing requests
"""
edit_url = reverse_lazy(f"{self.APP_NAME}:akowner_edit_dispatch", kwargs={'event_slug': 'kif42'})
base_url = reverse_lazy(f"{self.APP_NAME}:submission_overview", kwargs={'event_slug': 'kif42'})
# Empty form/no user selected -> start page
response = self.client.post(edit_url, {'owner_id': -1})
self.assertRedirects(response, base_url, status_code=302, target_status_code=200,
msg_prefix="Did not redirect to start page even though no user was selected")
self._assert_message(response, "No user selected")
# Correct selection -> user edit page for that user
edit_redirect_url = reverse_lazy(f"{self.APP_NAME}:akowner_edit", kwargs={'event_slug': 'kif42', 'slug': 'a'})
response = self.client.post(edit_url, {'owner_id': 1})
self.assertRedirects(response, edit_redirect_url, status_code=302, target_status_code=200,
msg_prefix=f"Dispatch redirect failed (should go to {edit_redirect_url})")
def test_ak_owner_selection(self):
"""
Test dispatch of owner selection requests
"""
select_url = reverse_lazy(f"{self.APP_NAME}:akowner_select", kwargs={'event_slug': 'kif42'})
create_url = reverse_lazy(f"{self.APP_NAME}:akowner_create", kwargs={'event_slug': 'kif42'})
# Empty user selection -> create a new user view
response = self.client.post(select_url, {'owner_id': -1})
self.assertRedirects(response, create_url, status_code=302, target_status_code=200,
msg_prefix="Did not redirect to user create view even though no user was specified")
# Valid user selected -> redirect to view that allows to add a new AK with this user as owner
add_redirect_url = reverse_lazy(f"{self.APP_NAME}:submit_ak", kwargs={'event_slug': 'kif42', 'owner_slug': 'a'})
response = self.client.post(select_url, {'owner_id': 1})
self.assertRedirects(response, add_redirect_url, status_code=302, target_status_code=200,
msg_prefix=f"Dispatch redirect to ak submission page failed "
f"(should go to {add_redirect_url})")
def test_orga_message_submission(self):
"""
Test submission and storing of direct confident messages to organizers
"""
form_url = reverse_lazy(f"{self.APP_NAME}:akmessage_add", kwargs={'event_slug': 'kif42', 'pk': 1})
detail_url = reverse_lazy(f"{self.APP_NAME}:ak_detail", kwargs={'event_slug': 'kif42', 'pk': 1})
count_messages = AK.objects.get(pk=1).akorgamessage_set.count()
# Test that submission view is accessible
response = self.client.get(form_url)
self.assertEqual(response.status_code, 200, msg="Could not load message form view")
# Test submission itself and the following redirect -> AK detail page
response = self.client.post(form_url, {'ak': 1, 'event': 2, 'text': 'Test message text'})
self.assertRedirects(response, detail_url, status_code=302, target_status_code=200,
msg_prefix=f"Did not trigger redirect to ak detail page ({detail_url})")
# Make sure message was correctly saved in database and user is notified about that
self._assert_message(response, "Message to organizers successfully saved")
self.assertEqual(AK.objects.get(pk=1).akorgamessage_set.count(), count_messages + 1,
msg="Message was not correctly saved")
def test_interest_api(self):
"""
Test interest indicating API (access, functionality)
"""
interest_api_url = "/kif42/api/ak/1/indicate-interest/"
ak = AK.objects.get(pk=1)
event = Event.objects.get(slug='kif42')
ak_interest_counter = ak.interest_counter
# Check Access method (only POST)
response = self.client.get(interest_api_url)
self.assertEqual(response.status_code, 405, "Should not be accessible via GET")
event.interest_start = datetime.now().astimezone(event.timezone) + timedelta(minutes=-10)
event.interest_end = datetime.now().astimezone(event.timezone) + timedelta(minutes=+10)
event.save()
# Test correct indication -> HTTP 200, counter increased
response = self.client.post(interest_api_url)
self.assertEqual(response.status_code, 200, f"API end point not working ({interest_api_url})")
self.assertEqual(AK.objects.get(pk=1).interest_counter, ak_interest_counter + 1, "Counter was not increased")
event.interest_end = datetime.now().astimezone(event.timezone) + timedelta(minutes=-2)
event.save()
# Test indication outside of indication window -> HTTP 403, counter not increased
response = self.client.post(interest_api_url)
self.assertEqual(response.status_code, 403,
"API end point still reachable even though interest indication window ended "
"({interest_api_url})")
self.assertEqual(AK.objects.get(pk=1).interest_counter, ak_interest_counter + 1,
"Counter was increased even though interest indication window ended")
# Test call for non-existing AK -> HTTP 403
invalid_interest_api_url = "/kif42/api/ak/-1/indicate-interest/"
response = self.client.post(invalid_interest_api_url)
self.assertEqual(response.status_code, 404, f"Invalid URL reachable ({interest_api_url})")
def test_adding_of_unknown_user(self):
"""
Test adding of a previously not existing owner to an AK
"""
# Pre-Check: AK detail page existing?
detail_url = reverse_lazy(f"{self.APP_NAME}:ak_detail", kwargs={'event_slug': 'kif42', 'pk': 1})
response = self.client.get(detail_url)
self.assertEqual(response.status_code, 200, msg="Could not load ak detail view")
# Make sure AK detail page contains a link to add a new owner
edit_url = reverse_lazy(f"{self.APP_NAME}:ak_edit", kwargs={'event_slug': 'kif42', 'pk': 1})
response = self.client.get(edit_url)
self.assertEqual(response.status_code, 200, msg="Could not load ak detail view")
self.assertContains(response, "Add person not in the list yet",
msg_prefix="Link to add unknown user not contained")
# Check adding of a new owner by posting an according request
# -> Redirect to AK detail page, message to user, owners list updated
self.assertEqual(AK.objects.get(pk=1).owners.count(), 1)
add_new_user_to_ak_url = reverse_lazy(f"{self.APP_NAME}:akowner_create", kwargs={'event_slug': 'kif42'}) \
+ "?add_to_existing_ak=1"
response = self.client.post(add_new_user_to_ak_url,
{'name': 'New test owner', 'event': Event.get_by_slug('kif42').pk})
self.assertRedirects(response, detail_url,
msg_prefix=f"No correct redirect: {add_new_user_to_ak_url} (POST) -> {detail_url}")
self._assert_message(response, "Added 'New test owner' as new owner of 'Test AK Inhalt'")
self.assertEqual(AK.objects.get(pk=1).owners.count(), 2)
def test_visibility_requirements_in_submission_form(self):
"""
Test visibility of requirements field in submission form
"""
event = Event.get_by_slug('kif42')
form = AKSubmissionForm(data={'name': 'Test AK', 'event': event}, instance=None, initial={"event": event})
self.assertIn('requirements', form.fields,
msg="Requirements field not present in form even though event has requirements")
event2 = Event.objects.create(name='Event without requirements',
slug='no_req',
start=datetime.now().astimezone(event.timezone),
end=datetime.now().astimezone(event.timezone),
active=True)
form2 = AKSubmissionForm(data={'name': 'Test AK', 'event': event2}, instance=None, initial={"event": event2})
self.assertNotIn('requirements', form2.fields,
msg="Requirements field should not be present for events without requirements")
def test_visibility_types_in_submission_form(self):
"""
Test visibility of types field in submission form
"""
event = Event.get_by_slug('kif42')
form = AKSubmissionForm(data={'name': 'Test AK', 'event': event}, instance=None, initial={"event": event})
self.assertIn('types', form.fields,
msg="Requirements field not present in form even though event has requirements")
event2 = Event.objects.create(name='Event without types',
slug='no_types',
start=datetime.now().astimezone(event.timezone),
end=datetime.now().astimezone(event.timezone),
active=True)
form2 = AKSubmissionForm(data={'name': 'Test AK', 'event': event2}, instance=None, initial={"event": event2})
self.assertNotIn('types', form2.fields,
msg="Requirements field should not be present for events without types")
......@@ -9,17 +9,23 @@ urlpatterns = [
'<slug:event_slug>/submission/',
include([
path('', views.SubmissionOverviewView.as_view(), name='submission_overview'),
path('ak/<int:pk>', views.AKDetailView.as_view(), name='ak_detail'),
path('ak/<int:pk>/', views.AKDetailView.as_view(), name='ak_detail'),
path('ak/<int:pk>/history/', views.AKHistoryView.as_view(), name='ak_history'),
path('ak/<int:pk>/edit/', views.AKEditView.as_view(), name='ak_edit'),
path('aks/', views.AKListView.as_view(), name='ak_list'),
path('aks/category/<int:category_pk>', views.AKListByCategoryView.as_view(), name='ak_list_by_category'),
path('aks/tag/<int:tag_pk>', views.AKListByTagView.as_view(), name='ak_list_by_tag'),
path('ak/<int:pk>/add_slot/', views.AKSlotAddView.as_view(), name='akslot_add'),
path('ak/<int:pk>/add_message/', views.AKAddOrgaMessageView.as_view(), name='akmessage_add'),
path('akslot/<int:pk>/edit/', views.AKSlotEditView.as_view(), name='akslot_edit'),
path('akslot/<int:pk>/delete/', views.AKSlotDeleteView.as_view(), name='akslot_delete'),
path('aks/', views.AKOverviewView.as_view(), name='ak_list'),
path('aks/category/<int:category_pk>/', views.AKListByCategoryView.as_view(), name='ak_list_by_category'),
path('aks/track/<int:track_pk>/', views.AKListByTrackView.as_view(), name='ak_list_by_track'),
path('owner/', views.AKOwnerCreateView.as_view(), name='akowner_create'),
path('new/', views.AKOwnerSelectDispatchView.as_view(), name='akowner_select'),
path('owner/edit/', views.AKOwnerEditDispatchView.as_view(), name='akowner_edit_dispatch'),
path('<slug:slug>/edit/', views.AKOwnerEditView.as_view(), name='akowner_edit'),
path('<slug:owner_slug>/new/', views.AKSubmissionView.as_view(), name='submit_ak'),
path('new_wish/', views.AKWishSubmissionView.as_view(), name='submit_ak_wish'),
path('error/', views.SubmissionErrorNotConfiguredView.as_view(), name='error_not_configured'),
])
),
]