Skip to content
Snippets Groups Projects
Select Git revision
  • f18aef099ac3c99c85c57ab1156f73cb132f9274
  • main default protected
2 results

invitebox.html

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    scheduling.html 8.09 KiB
    {% extends "admin_base.html" %}
    {% load tags_AKModel %}
    
    {% load i18n %}
    {% load l10n %}
    {% load tz %}
    {% load static %}
    {% load tags_AKPlan %}
    
    {% block title %}{% trans "Scheduling for" %} {{event}}{% endblock %}
    
    {% block extrahead %}
        {{ block.super }}
        {% include "AKPlan/load_fullcalendar.html" %}
    
        <style>
            .unscheduled-slot {
                cursor: move;
    
            }
    
            .fc-v-event, .tooltip {
                white-space: pre-line;
            }
        </style>
    
        <script>
            document.addEventListener('DOMContentLoaded', function () {
                // CSRF Protection/Authentication
                function getCookie(name) {
                    let cookieValue = null;
                    if (document.cookie && document.cookie !== '') {
                        const cookies = document.cookie.split(';');
                        for (let i = 0; i < cookies.length; i++) {
                            const cookie = cookies[i].trim();
                            // Does this cookie string begin with the name we want?
                            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                                break;
                            }
                        }
                    }
                    return cookieValue;
                }
    
                const csrftoken = getCookie('csrftoken');
    
                function csrfSafeMethod(method) {
                    // these HTTP methods do not require CSRF protection
                    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
                }
    
                $.ajaxSetup({
                    beforeSend: function (xhr, settings) {
                        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                            xhr.setRequestHeader("X-CSRFToken", csrftoken);
                        }
                    }
                });
    
    
                // Place slots by dropping placeholders on calendar
                var containerEl = document.getElementById('unscheduled-slots');
                new FullCalendar.Draggable(containerEl, {
                    itemSelector: '.unscheduled-slot',
                });
    
    
                // Calendar
                var planEl = document.getElementById('planCalendar');
    
                plan = new FullCalendar.Calendar(planEl, {
                    timeZone: '{{ event.timezone }}',
                    headerToolbar: {
                        left: 'today prev,next',
                        center: 'title',
                        right: 'resourceTimelineDayVert,resourceTimelineDayHoriz,resourceTimelineEventVert,resourceTimelineEventHoriz'
                    },
                    //aspectRatio: 2,
                    themeSystem: 'bootstrap',
                    initialView: 'resourceTimelineEventVert',
                    views: {
                        resourceTimelineDayHoriz: {
                            type: 'resourceTimelineDay',
                            buttonText: '{% trans "Day (Horizontal)" %}',
                            slotDuration: '00:15',
                            scrollTime: '08:00',
                            titleFormat: {weekday: 'long', day: 'numeric', month: 'numeric'},
                        },
                        resourceTimelineDayVert: {
                            type: 'resourceTimeGridDay',
                            buttonText: '{% trans "Day (Vertical)" %}',
                            slotDuration: '00:30',
                            scrollTime: '08:00',
                            titleFormat: {weekday: 'long', day: 'numeric', month: 'numeric'},
                        },
                        resourceTimelineEventHoriz: {
                            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 (Horizontal)" %}',
                            slotDuration: '00:15',
                        },
                        resourceTimelineEventVert: {
                            type: 'resourceTimeGrid',
                            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 (Vertical)" %}',
                            slotDuration: '00:30',
                        }
                    },
                    // Show full AK title as tooltip for each AK (needs to be removed and newly placed when AK is moved)
                    eventDidMount: function (info) {
                        if (info.event.extendedProps.description !== undefined) {
                            $(info.el).tooltip({title: info.event.extendedProps.description, trigger: 'hover'});
                        }
                    },
                    eventWillUnmount: function (info) {
                        $(info.el).tooltip('dispose');
                    },
    
                    // React to event changes (moving or change of duration)
                    eventChange: updateEvent,
                    eventReceive: updateEvent,
                    editable: true,
                    dropable: true,
                    drop: function (info) {
                        info.draggedEl.parentNode.removeChild(info.draggedEl);
                    },
                    allDaySlot: false,
                    nowIndicator: true,
                    eventTextColor: '#fff',
                    eventColor: '#127ba3',
                    datesAboveResources: true,
                    resourceAreaHeaderContent: '{% trans "Room" %}',
                    resources: '{% url "model:scheduling-resources-list" event_slug=event.slug %}',
                    eventSources: [
                        '{% url "model:scheduling-events" event_slug=event.slug %}',
                        '{% url "model:scheduling-room-availabilities" event_slug=event.slug %}'
                    ],
                    schedulerLicenseKey: 'GPL-My-Project-Is-Open-Source',
                    dayMinWidth: 100,
                });
    
                plan.setOption('contentHeight', $(window).height() - $('#header').height() * 11);
                plan.render();
    
                function updateEvent(changeInfo) {
                    room = changeInfo.event.getResources()[0];
                    $.ajax({
                        url: '{% url "model:scheduling-event-list" event_slug=event.slug %}' + changeInfo.event.extendedProps.slotID + "/",
                        type: 'PUT',
                        data: {
                            start: plan.formatIso(changeInfo.event.start),
                            end: plan.formatIso(changeInfo.event.end),
                            roomId: room.id,
                        },
                        success: function (response) {
                        },
                        error: function (response) {
                            changeInfo.revert();
                            alert("ERROR. Did not update " + changeInfo.event.title)
                        }
                    });
                }
    
                $('.unscheduled-slot').each(function() {
                    $(this).tooltip({title: $(this).first().attr('data-details'), trigger: 'hover'});
                });
            });
        </script>
    {% endblock extrahead %}
    
    {% block content %}
    
        <div class="row" style="margin-bottom: 50px;">
            <div class="col-md-10 col-lg-10">
                <div id="planCalendar"></div>
            </div>
            <div class="col-md-2 col-lg-2" id="unscheduled-slots">
                {% for slot in slots_unscheduled %}
                    <div class="unscheduled-slot badge badge-primary" style='background-color: {{ slot.ak.category.color }}'
                         data-event='{ "title": "{{ slot.ak.short_name }}", "duration": {"hours": "{{ slot.duration|unlocalize }}"}, "description": "{{ slot.ak.details | escapejs }}", "slotID": "{{ slot.pk }}", "backgroundColor": "{{ slot.ak.category.color }}"}' data-details="{{ slot.ak.details }}">{{ slot.ak.short_name }}
                        ({{ slot.duration }} h)<br>{{ slot.ak.owners_list }}
                    </div>
                {% endfor %}
            </div>
        </div>
    
    
        <a href="{% url 'admin:event_status' event.slug %}">{% trans "Event Status" %}</a>
    {% endblock %}