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
Showing
with 898 additions and 2 deletions
# Generated by Django 4.1.5 on 2023-03-21 23:41
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('AKOnline', '0004_rework_virtual_3'),
]
operations = [
migrations.DeleteModel(
name='VirtualRoomOld',
),
]
from django.db import models
from django.utils.translation import gettext_lazy as _
from AKModel.models import Room
class VirtualRoom(models.Model):
"""
Add details about a virtual or hybrid version of a room to it
"""
url = models.URLField(verbose_name=_("URL"), help_text=_("URL to the room or server"), blank=True)
room = models.OneToOneField(Room, verbose_name=_("Room"), on_delete=models.CASCADE,
related_name='virtual', primary_key=True)
class Meta:
verbose_name = _('Virtual Room')
verbose_name_plural = _('Virtual Rooms')
@property
def event(self):
"""
Property: Event this virtual room belongs to.
:return: Event this virtual room belongs to
:rtype: Event
"""
return self.room.event
def __str__(self):
return f"{self.room.title}: {self.url}"
{% extends "admin/AKModel/room_create.html" %}
{% load tags_AKModel %}
{% load i18n %}
{% load django_bootstrap5 %}
{% block form_details %}
{% bootstrap_form form.room %}
<h3>{% trans "Virtual Room" %}</h3>
<p>{% trans "Leave empty if that room is not virtual/hybrid." %}</p>
{% bootstrap_form form.virtual %}
{% endblock %}
{% load i18n %}
<ul>
{% for room in event.room_set.all %}
{% if room.virtual and room.virtual.url %}
<li>
<a href="{% url 'admin:AKOnline_virtualroom_change' room.pk %}">{{ room }} ({{ room.virtual.url | truncatechars:30 }})</a>
</li>
{% endif %}
{% endfor %}
</ul>
from django.contrib import messages
from django.http import HttpResponseRedirect
from django.utils.translation import gettext_lazy as _
from AKModel.metaviews import status_manager
from AKModel.metaviews.status import TemplateStatusWidget
from AKModel.views.room import RoomCreationView
from AKOnline.forms import RoomWithVirtualForm
class RoomCreationWithVirtualView(RoomCreationView):
"""
View to create both rooms and optionally virtual rooms by filling one form
"""
form_class = RoomWithVirtualForm
template_name = 'admin/AKOnline/room_create_with_virtual.html'
room = None
def form_valid(self, form):
# This will create the room and additionally a virtual room if the url field is not blank
# objects['room'] will always a room instance afterwards, objects['virtual'] may be empty
objects = form.save()
self.room = objects['room']
# Create a (translated) success message containing information about the created room
messages.success(self.request, _("Created Room '%(room)s'" % {'room': objects['room']})) #pylint: disable=consider-using-f-string, line-too-long
if objects['virtual'] is not None:
# Create a (translated) success message containing information about the created virtual room
messages.success(self.request, _("Created related Virtual Room '%(vroom)s'" % {'vroom': objects['virtual']})) #pylint: disable=consider-using-f-string, line-too-long
return HttpResponseRedirect(self.get_success_url())
@status_manager.register(name="event_virtual_rooms")
class EventVirtualRoomsWidget(TemplateStatusWidget):
"""
Status page widget to contain information about all virtual rooms belonging to the given event
"""
required_context_type = "event"
title = _("Virtual Rooms")
template_name = "admin/AKOnline/status/event_virtual_rooms.html"
# Register your models here.
......@@ -2,4 +2,7 @@ from django.apps import AppConfig
class AkplanConfig(AppConfig):
"""
App configuration (default, only specifies name of the app)
"""
name = 'AKPlan'
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-05-15 20:03+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: AKPlan/templates/AKPlan/plan_base.html:9
#, fuzzy
#| msgid "AK Plan"
msgid "Plan"
msgstr "Plan"
#: 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"
#: AKPlan/templates/AKPlan/plan_index.html:36
msgid "Day"
msgstr "Tag"
#: AKPlan/templates/AKPlan/plan_index.html:46
msgid "Event"
msgstr "Veranstaltung"
#: AKPlan/templates/AKPlan/plan_index.html:59
#: AKPlan/templates/AKPlan/plan_room.html:13
#: AKPlan/templates/AKPlan/plan_room.html:59
#: AKPlan/templates/AKPlan/plan_wall.html:65
msgid "Room"
msgstr "Raum"
#: AKPlan/templates/AKPlan/plan_index.html:80
#: AKPlan/templates/AKPlan/plan_room.html:11
#: AKPlan/templates/AKPlan/plan_track.html:9
msgid "AK Plan"
msgstr "AK-Plan"
#: AKPlan/templates/AKPlan/plan_index.html:92
#: AKPlan/templates/AKPlan/plan_room.html:49
msgid "Rooms"
msgstr "Räume"
#: AKPlan/templates/AKPlan/plan_index.html:105
#: AKPlan/templates/AKPlan/plan_track.html:36
msgid "Tracks"
msgstr "Tracks"
#: AKPlan/templates/AKPlan/plan_index.html:117
msgid "AK Wall"
msgstr "AK-Wall"
#: AKPlan/templates/AKPlan/plan_index.html:130
#: AKPlan/templates/AKPlan/plan_wall.html:130
msgid "Current AKs"
msgstr "Aktuelle AKs"
#: AKPlan/templates/AKPlan/plan_index.html:137
#: AKPlan/templates/AKPlan/plan_wall.html:135
msgid "Next AKs"
msgstr "Nächste AKs"
#: AKPlan/templates/AKPlan/plan_index.html:145
msgid "This event is not active."
msgstr "Dieses Event ist nicht aktiv."
#: AKPlan/templates/AKPlan/plan_index.html:158
#: AKPlan/templates/AKPlan/plan_room.html:77
#: AKPlan/templates/AKPlan/plan_track.html:58
msgid "Plan is not visible (yet)."
msgstr "Plan ist (noch) nicht sichtbar"
#: AKPlan/templates/AKPlan/plan_room.html:63
msgid "Go to virtual room"
msgstr "Zum virtuellen Raum"
#: AKPlan/templates/AKPlan/plan_room.html:84
msgid "Capacity"
msgstr "Kapazität"
#: AKPlan/templates/AKPlan/plan_room.html:88
msgid "Properties"
msgstr "Eigenschaften"
#: AKPlan/templates/AKPlan/plan_track.html:11
#: AKPlan/templates/AKPlan/plan_track.html:46
msgid "Track"
msgstr "Track"
#: AKPlan/templates/AKPlan/plan_wall.html:145
msgid "Reload page automatically?"
msgstr "Seite automatisch neu laden?"
#: AKPlan/templates/AKPlan/slots_table.html:14
msgid "No AKs"
msgstr "Keine AKs"
# Create your models here.
{% load tz %}
{% load tags_AKPlan %}
[
{% for slot in slots %}
{% if slot.start %}
{
'title': '{{ slot.ak.short_name }}',
'description': '{{ slot.ak.name }}',
'start': '{{ slot.start | timezone:event.timezone | date:"Y-m-d H:i:s" }}',
'end': '{{ slot.end | timezone:event.timezone | date:"Y-m-d H:i:s" }}',
'resourceId': '{{ slot.room.title }}',
'backgroundColor': '{{ slot|highlight_change_colors }}',
'borderColor': '{{ slot.ak.category.color }}',
'url': '{{ slot.ak.detail_url }}'
},
{% endif %}
{% endfor %}
]
[
{% for room in rooms %}
{
'id': '{{ room.title }}',
'title': '{{ room.title }}',
'parentId': '{{ room.location }}',
},
{% endfor %}
{% for building in buildings %}
{
'id': '{{ building }}',
'title': '{{ building }}',
},
{% endfor %}
]
{% load static %}
{% load tz %}
{% load i18n %}
{% load tags_AKPlan %}
{% include "AKModel/load_fullcalendar.html" %}
<script>
{% get_current_language as LANGUAGE_CODE %}
document.addEventListener('DOMContentLoaded', function () {
var calendarEl = document.getElementById('akSlotCalendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
// Adapt to timezone of the connected event
timeZone: '{{ ak.event.timezone }}',
initialView: 'timeGrid',
// Adapt to user selected locale
locale: '{{ LANGUAGE_CODE }}',
// No header, not buttons
headerToolbar: false,
aspectRatio: 2.5,
themeSystem: 'bootstrap5',
buttonIcons: {
prev: 'ignore fa-solid fa-angle-left',
next: 'ignore fa-solid fa-angle-right',
},
// Only show calendar view for the dates of the connected event
visibleRange: {
start: '{{ ak.event.start | timezone:ak.event.timezone | date:"Y-m-d H:i:s" }}',
end: '{{ ak.event.end | timezone:ak.event.timezone | date:"Y-m-d H:i:s"}}',
},
scrollTime: '08:00:00',
allDaySlot: false,
nowIndicator: true,
now: "{% timestamp_now event.timezone %}",
eventTextColor: '#fff',
eventColor: '#127ba3',
// Create entries for all scheduled slots
events: [
{% if not ak.event.plan_hidden or user.is_staff %}
{% for slot in ak.akslot_set.all %}
{% if slot.start %}
{
'title': '{{ slot.room }}',
'start': '{{ slot.start | timezone:ak.event.timezone | date:"Y-m-d H:i:s" }}',
'end': '{{ slot.end | timezone:ak.event.timezone | date:"Y-m-d H:i:s" }}',
'url' : '{% if slot.room %}{% url "plan:plan_room" event_slug=ak.event.slug pk=slot.room.pk %}{% else %}#{% endif %}'
},
{% endif %}
{% endfor %}
{% endif %}
{% for a in availabilities %}
{
title: '{{ Verfuegbarkeit }}',
start: '{{ a.start | timezone:ak.event.timezone | date:"Y-m-d H:i:s" }}',
end: '{{ a.end | timezone:ak.event.timezone | date:"Y-m-d H:i:s" }}',
backgroundColor: '#28B62C',
display: 'background'
},
{% endfor %}
],
schedulerLicenseKey: 'GPL-My-Project-Is-Open-Source',
});
calendar.render();
});
</script>
{% extends "base.html" %}
{% load fontawesome_6 %}
{% load i18n %}
{% load static %}
{% block meta %}
<meta name="twitter:card" content="summary" />
<meta name="twitter:title" content="{{ event.name }} - {% trans "Plan" %}" />
{% endblock %}
{% block imports %}
{% include "AKModel/load_fullcalendar.html" %}
{% block fullcalendar %}{% endblock %}
{% endblock imports %}
{% block footer_custom %}
{% if event.contact_email %}
<h4>
<a href="mailto:{{ event.contact_email }}">{% fa6_icon "envelope" "far" %} {% trans "Write to organizers of this event for questions and comments" %}</a>
</h4>
{% endif %}
{% endblock %}
{% load i18n %}
{% 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 "AKPlan/plan_base.html" %}
{% load fontawesome_6 %}
{% load i18n %}
{% load static %}
{% load tz %}
{% load tags_AKPlan %}
{% block fullcalendar %}
{% if not event.plan_hidden or user.is_staff %}
{% get_current_language as LANGUAGE_CODE %}
<script>
document.addEventListener('DOMContentLoaded', function () {
var calendarEl = document.getElementById('planCalendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
// Adapt to timezone of the connected event
timeZone: '{{ event.timezone }}',
initialView: 'timeGrid',
// Adapt to user selected locale
locale: '{{ LANGUAGE_CODE }}',
// No header, not buttons
headerToolbar: {
left: '',
center: '',
right: ''
},
aspectRatio: 2,
themeSystem: 'bootstrap5',
buttonIcons: {
prev: 'ignore fa-solid fa-angle-left',
next: 'ignore fa-solid fa-angle-right',
},
// Only show calendar view for the dates of the connected event
visibleRange: {
start: '{{ event.start | timezone:event.timezone | date:"Y-m-d H:i:s" }}',
end: '{{ event.end | timezone:event.timezone | date:"Y-m-d H:i:s"}}',
},
scrollTime: '08:00:00',
allDaySlot: false,
nowIndicator: true,
now: "{% timestamp_now event.timezone %}",
eventTextColor: '#fff',
eventColor: '#127ba3',
// Create entries for all scheduled slots
events: {% block encode %}{% endblock %},
schedulerLicenseKey: 'GPL-My-Project-Is-Open-Source',
});
calendar.render();
});
</script>
{% endif %}
{% endblock %}
{% extends "AKPlan/plan_base.html" %}
{% load fontawesome_6 %}
{% load i18n %}
{% load static %}
{% load tz %}
{% load tags_AKPlan %}
{% block fullcalendar %}
{% if not event.plan_hidden or user.is_staff %}
{% get_current_language as LANGUAGE_CODE %}
<script>
document.addEventListener('DOMContentLoaded', function () {
var planEl = document.getElementById('planCalendar');
var plan = new FullCalendar.Calendar(planEl, {
timeZone: '{{ event.timezone }}',
headerToolbar: {
left: 'today prev,next',
center: 'title',
right: 'resourceTimelineDay,resourceTimelineEvent'
},
themeSystem: 'bootstrap5',
buttonIcons: {
prev: 'ignore fa-solid fa-angle-left',
next: 'ignore fa-solid fa-angle-right',
},
// Adapt to user selected locale
locale: '{{ LANGUAGE_CODE }}',
initialView: 'resourceTimelineEvent',
views: {
resourceTimelineDay: {
type: 'resourceTimeline',
buttonText: '{% trans "Day" %}',
slotDuration: '01:00',
scrollTime: '08:00',
},
resourceTimelineEvent: {
type: 'resourceTimeline',
visibleRange: {
start: '{{ event.start | timezone:event.timezone | date:"Y-m-d H:i:s" }}',
end: '{{ event.end | timezone:event.timezone | date:"Y-m-d H:i:s"}}',
},
buttonText: '{% trans "Event" %}',
}
},
eventDidMount: function(info) {
$(info.el).tooltip({title: info.event.extendedProps.description});
},
editable: false,
allDaySlot: false,
nowIndicator: true,
now: "{% timestamp_now event.timezone %}",
eventTextColor: '#fff',
eventColor: '#127ba3',
resourceAreaWidth: '15%',
resourceAreaHeaderContent: '{% trans "Room" %}',
resources: {% include "AKPlan/encode_rooms.html" %},
events: {% with akslots as slots %}{% include "AKPlan/encode_events.html" %}{% endwith %},
schedulerLicenseKey: 'GPL-My-Project-Is-Open-Source',
});
plan.render();
// Scroll to current time
if($(".fc-timeline-now-indicator-line").length) {
$('.fc-scroller').scrollLeft($('.fc-timeline-now-indicator-line').position().left);
}
});
</script>
{% endif %}
{% endblock %}
{% block breadcrumbs %}
{% include "AKPlan/plan_breadcrumbs.html" %}
<li class="breadcrumb-item">
{% trans "AK Plan" %}
</li>
{% endblock %}
{% block content %}
<div class="float-end">
<ul class="nav nav-pills">
{% if rooms|length > 0 %}
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button"
aria-haspopup="true"
aria-expanded="false">{% trans "Rooms" %}</a>
<div class="dropdown-menu" style="">
{% for r in event.room_set.all %}
<a class="dropdown-item"
href="{% url "plan:plan_room" event_slug=event.slug pk=r.pk %}">{{ r }}</a>
{% endfor %}
</div>
</li>
{% endif %}
{% if tracks|length > 0 %}
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button"
aria-haspopup="true"
aria-expanded="false">{% trans "Tracks" %}</a>
<div class="dropdown-menu">
{% for t in tracks %}
<a class="dropdown-item"
href="{% url "plan:plan_track" event_slug=event.slug pk=t.pk %}">{{ t }}</a>
{% endfor %}
</div>
</li>
{% endif %}
{% if event.active %}
<li class="nav-item">
<a class="nav-link active"
href="{% url 'plan:plan_wall' event_slug=event.slug %}">{% fa6_icon 'desktop' 'fas' %}&nbsp;&nbsp;{% trans "AK Wall" %}</a>
</li>
{% endif %}
</ul>
</div>
<h1>Plan: {{ event }}</h1>
{% timezone event.timezone %}
<div class="row" style="margin-top:30px;">
{% if not event.plan_hidden or user.is_staff %}
{% if event.active %}
<div class="col-md-6">
<h2><a name="currentAKs">{% trans "Current AKs" %}:</a></h2>
{% with akslots_now as slots %}
{% include "AKPlan/slots_table.html" %}
{% endwith %}
</div>
<div class="col-md-6">
<h2><a name="currentAKs">{% trans "Next AKs" %}:</a></h2>
{% with akslots_next as slots %}
{% include "AKPlan/slots_table.html" %}
{% endwith %}
</div>
{% else %}
<div class="col-md-12">
<div class="alert alert-warning">
<p class="mb-0">{% trans "This event is not active." %}</p>
</div>
</div>
{% endif %}
<div class="col-md-12">
<div style="margin-top:30px;margin-bottom: 70px;">
<div id="planCalendar"></div>
</div>
</div>
{% else %}
<div class="col-md-12">
<div class="alert alert-warning">
<p class="mb-0">{% trans "Plan is not visible (yet)." %}</p>
</div>
</div>
{% endif %}
</div>
{% endtimezone %}
{% endblock %}
{% extends "AKPlan/plan_detail.html" %}
{% load fontawesome_6 %}
{% load tags_AKModel %}
{% load tz %}
{% load i18n %}
{% block breadcrumbs %}
{% include "AKPlan/plan_breadcrumbs.html" %}
<li class="breadcrumb-item">
<a href="{% url 'plan:plan_overview' event_slug=event.slug %}">{% trans "AK Plan" %}</a>
</li>
<li class="breadcrumb-item">{% trans "Room" %}: {{ room.title }}</li>
{% endblock %}
{% block encode %}
[
{% for slot in slots %}
{% if slot.start %}
{'title': '{{ slot.ak }}',
'start': '{{ slot.start | timezone:event.timezone | date:"Y-m-d H:i:s" }}',
'end': '{{ slot.end | timezone:event.timezone | date:"Y-m-d H:i:s" }}',
'url': '{{ slot.ak.detail_url }}',
'borderColor': '{{ slot.ak.track.color }}',
'color': '{{ slot.ak.category.color }}',
},
{% endif %}
{% endfor %}
{% for a in room.availabilities.all %}
{
title: '',
start: '{{ a.start | timezone:event.timezone | date:"Y-m-d H:i:s" }}',
end: '{{ a.end | timezone:event.timezone | date:"Y-m-d H:i:s" }}',
'resourceId': '{{ a.room.title }}',
backgroundColor: '#28B62C',
display: 'background',
groupId: 'roomAvailable',
},
{% endfor %}
]
{% endblock %}
{% block content %}
<div class="float-end">
<ul class="nav nav-pills">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">{% trans "Rooms" %}</a>
<div class="dropdown-menu" style="">
{% for r in event.room_set.all %}
<a class="dropdown-item" href="{% url "plan:plan_room" event_slug=event.slug pk=r.pk %}">{{ r }}</a>
{% endfor %}
</div>
</li>
</ul>
</div>
<h1>{% trans "Room" %}: {{ room.name }} {% if room.location != '' %}({{ room.location }}){% endif %}</h1>
{% if "AKOnline"|check_app_installed and room.virtual and room.virtual.url != '' %}
<a class="btn btn-success" target="_parent" href="{{ room.virtual.url }}">
{% fa6_icon 'external-link-alt' 'fas' %} {% trans "Go to virtual room" %}
</a>
{% endif %}
{% if not event.plan_hidden or user.is_staff %}
{% timezone event.timezone %}
<div class="row" style="margin-top:30px;clear:both;">
<div class="col-md-12">
<div id="planCalendar"></div>
</div>
</div>
{% endtimezone %}
{% else %}
<div class="alert alert-warning mt-3">
<p class="mb-0">{% trans "Plan is not visible (yet)." %}</p>
</div>
{% endif %}
<table class="table table-borderless" style="margin-top: 30px;">
<tbody>
<tr>
<td>{% trans "Capacity" %}:</td><td>{{ room.capacity }}</td>
</tr>
{% if room.properties.count > 0 %}
<tr>
<td>{% trans "Properties" %}:</td>
<td>
{% for property in room.properties.all %}
{% if forloop.counter0 > 0 %}
,&nbsp;
{% endif %}
{{ property }}
{% endfor %}
</td>
</tr>
{% endif %}
</tbody>
</table>
{% endblock %}
{% extends "AKPlan/plan_detail.html" %}
{% load tz %}
{% load i18n %}
{% block breadcrumbs %}
{% include "AKPlan/plan_breadcrumbs.html" %}
<li class="breadcrumb-item">
<a href="{% url 'plan:plan_overview' event_slug=event.slug %}">{% trans "AK Plan" %}</a>
</li>
<li class="breadcrumb-item">{% trans "Track" %}: {{ track }}</li>
{% endblock %}
{% block encode %}
[
{% for slot in slots %}
{% if slot.start %}
{'title': '{{ slot.ak }} @ {{ slot.room }}',
'start': '{{ slot.start | timezone:event.timezone | date:"Y-m-d H:i:s" }}',
'end': '{{ slot.end | timezone:event.timezone | date:"Y-m-d H:i:s" }}',
'url': '{{ slot.ak.detail_url }}',
'color': '{{ track.color }}',
'borderColor': '{{ slot.ak.category.color }}',
},
{% endif %}
{% endfor %}
]
{% endblock %}
{% block content %}
<div class="float-end">
<ul class="nav nav-pills">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">{% trans "Tracks" %}</a>
<div class="dropdown-menu">
{% for t in event.aktrack_set.all %}
<a class="dropdown-item" href="{% url "plan:plan_track" event_slug=event.slug pk=t.pk %}">{{ t }}</a>
{% endfor %}
</div>
</li>
</ul>
</div>
<h1>Plan: {{ event }} ({% trans "Track" %}: {{ track }})</h1>
{% if not event.plan_hidden or user.is_staff %}
{% timezone event.timezone %}
<div class="row" style="margin-top:30px;clear:both;">
<div class="col-md-12">
<div id="planCalendar"></div>
</div>
</div>
{% endtimezone %}
{% else %}
<div class="alert alert-warning mt-3">
<p class="mb-0">{% trans "Plan is not visible (yet)." %}</p>
</div>
{% endif %}
{% endblock %}
{% load compress %}
{% load static %}
{% load i18n %}
{% load django_bootstrap5 %}
{% load fontawesome_6 %}
{% load tags_AKModel %}
{% load tags_AKPlan %}
{% load tz %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}AK Planning{% endblock %}</title>
{# Load Bootstrap CSS and JavaScript as well as font awesome #}
{% compress css %}
<link rel="stylesheet" type="text/x-scss" href="{% static 'common/vendor/bootswatch-lumen/theme.scss' %}">
{% fontawesome_6_css %}
<link rel="stylesheet" href="{% static 'common/css/custom.css' %}">
{% endcompress %}
{% compress js %}
{% bootstrap_javascript %}
<script src="{% static 'common/vendor/jquery/jquery-3.6.3.min.js' %}"></script>
{% fontawesome_6_js %}
{% endcompress %}
{% include "AKModel/load_fullcalendar.html" %}
{% get_current_language as LANGUAGE_CODE %}
<script>
document.addEventListener('DOMContentLoaded', function () {
var planEl = document.getElementById('planCalendar');
var plan = new FullCalendar.Calendar(planEl, {
timeZone: '{{ event.timezone }}',
headerToolbar: false,
themeSystem: 'bootstrap5',
buttonIcons: {
prev: 'ignore fa-solid fa-angle-left',
next: 'ignore fa-solid fa-angle-right',
},
// Adapt to user selected locale
locale: '{{ LANGUAGE_CODE }}',
slotDuration: '01:00',
initialView: 'resourceTimeline',
visibleRange: {
start: '{{ start | 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) {
$(info.el).tooltip({title: info.event.extendedProps.description});
},
editable: false,
allDaySlot: false,
nowIndicator: true,
now: "{% timestamp_now event.timezone %}",
eventTextColor: '#fff',
eventColor: '#127ba3',
height: '90%',
resourceAreaWidth: '15%',
resourceAreaHeaderContent: '{% trans "Room" %}',
resources: [
{% for room in rooms %}
{
'id': '{{ room.title }}',
'title': '{{ room.title }}'
},
{% endfor %}
],
events: {% with akslots as slots %}{% include "AKPlan/encode_events.html" %}{% endwith %},
schedulerLicenseKey: 'GPL-My-Project-Is-Open-Source',
});
plan.render();
// Scroll to current time
if($(".fc-timeline-now-indicator-line").length) {
$('.fc-scroller').scrollLeft($('.fc-timeline-now-indicator-line').position().left);
}
// == Auto Reload ==
// function from: https://stackoverflow.com/questions/5448545/how-to-retrieve-get-parameters-from-javascript/
function findGetParameter(parameterName) {
var result = null,
tmp = [];
location.search
.substr(1)
.split("&")
.forEach(function (item) {
tmp = item.split("=");
if (tmp[0] === parameterName) result = decodeURIComponent(tmp[1]);
});
return result;
}
// Check whether an autoreload frequency was specified and treat it as full minutes
const autoreload_frequency = Math.ceil(findGetParameter("autoreload"));
const cbxAutoReload = $('#cbxAutoReload');
if(autoreload_frequency>0) {
window.setTimeout ( function() { window.location.reload(); }, autoreload_frequency * 60 * 1000);
console.log("Autoreload active");
cbxAutoReload.prop('checked', true);
}
else {
cbxAutoReload.prop('checked', false);
}
cbxAutoReload.change(function () {
let url = window.location.href.split('?')[0];
if(cbxAutoReload.prop('checked')) {
url = url + "?autoreload=5";
}
window.location.replace(url);
});
});
</script>
</head>
<body>
{% timezone event.timezone %}
<div class="row" style="height:100vh;margin:0;padding:1vh;">
<div class="col-md-3">
<h1>Plan: {{ event }}</h1>
<h2><a name="currentAKs">{% trans "Current AKs" %}:</a></h2>
{% with akslots_now as slots %}
{% include "AKPlan/slots_table.html" %}
{% endwith %}
<h2><a name="currentAKs">{% trans "Next AKs" %}:</a></h2>
{% with akslots_next as slots %}
{% include "AKPlan/slots_table.html" %}
{% endwith %}
</div>
<div class="col-md-9" style="height:98vh;">
<div id="planCalendar"></div>
</div>
</div>
<div style="position: absolute;bottom: 1vh;left:1vw;background-color: #FFFFFF;padding: 1vh;">
<input type="checkbox" name="autoreload" id="cbxAutoReload"> <label for="cbxAutoReload">{% trans "Reload page automatically?" %}</label>
</div>
{% endtimezone %}
</body>
</html>