Browse Source

optimize templates

subDesTagesMitExtraKaese 2 years ago
parent
commit
9313fedfd0

+ 14 - 10
locale/de/LC_MESSAGES/django.po

@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2022-12-18 23:10+0000\n"
+"POT-Creation-Date: 2022-12-21 18:02+0000\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -73,7 +73,9 @@ msgstr "Passwort"
 #: zitap/forms.py:32
 msgid ""
 "Fill in a password to create a new account. Leave empty to login as a guest."
-msgstr "Füllen Sie ein Passwort ein, um ein neues Konto zu erstellen. Leer lassen, um als Gast einzuloggen."
+msgstr ""
+"Füllen Sie ein Passwort ein, um ein neues Konto zu erstellen. Leer lassen, "
+"um als Gast einzuloggen."
 
 #: zitap/forms.py:35
 msgid "Slots"
@@ -83,9 +85,11 @@ msgstr "Zeitslots"
 msgid ""
 "Click on a time slot to select it. Click again to deselect it. You can also "
 "drag the mouse to select multiple slots."
-msgstr "Ziehe die Maus über einen Zeitslot, um ihn auszuwählen. Markiere ihn erneut, um ihn abzuwählen."
+msgstr ""
+"Ziehe die Maus über einen Zeitslot, um ihn auszuwählen. Markiere ihn erneut, "
+"um ihn abzuwählen."
 
-#: zitap/helpers.py:21
+#: zitap/helpers.py:22
 #, fuzzy, python-brace-format
 #| msgid "Invalid string length"
 msgid "Invalid string length: {0} (expected: {1})"
@@ -117,15 +121,15 @@ msgstr "Ereignis nicht gefunden"
 msgid "Event"
 msgstr "Ereignis"
 
-#: zitap/templates/zitap/event.html:49
+#: zitap/templates/zitap/event.html:37
 msgid "Update Slots"
 msgstr "Zeitslot aktualisieren"
 
-#: zitap/templates/zitap/event.html:52 zitap/templates/zitap/my-events.html:32
+#: zitap/templates/zitap/event.html:40 zitap/templates/zitap/my-events.html:32
 msgid "Logout"
 msgstr "Abmelden"
 
-#: zitap/templates/zitap/event.html:75 zitap/views.py:78
+#: zitap/templates/zitap/event.html:63 zitap/views.py:79
 msgid "Login to Update Slots"
 msgstr "Anmelden, um Zeitslots zu aktualisieren"
 
@@ -144,16 +148,16 @@ msgstr "Meine Ereignisse"
 msgid "Login"
 msgstr "Anmelden"
 
-#: zitap/views.py:49
+#: zitap/views.py:50
 msgid "Could not create event. Please try again."
 msgstr "Konnte Ereignis nicht erstellen. Bitte versuchen Sie es erneut."
 
-#: zitap/views.py:76
+#: zitap/views.py:77
 #, fuzzy
 #| msgid "Event"
 msgid "Login to My Events"
 msgstr "Anmelden, um meine Ereignisse anzuzeigen"
 
-#: zitap/views.py:95
+#: zitap/views.py:96
 msgid "Username already exists"
 msgstr "Benutzername existiert bereits"

+ 70 - 62
zitap/helpers.py

@@ -1,5 +1,6 @@
 import datetime
 from django.utils.translation import gettext as _
+from django.utils.html import escape
 
 from .models import Participant, Date, Event
 
@@ -38,18 +39,10 @@ def get_slot_count( event ) -> int :
     slots_per_day = int(timespan.total_seconds() // event.slot_interval.total_seconds())
     return days * slots_per_day
 
-def slots2grid( event : Event, participants : list[Participant]) -> dict :
+def slots2grid( event : Event, participants : list[Participant], is_input : bool) -> dict :
     """ Convert the slots of an event to data for the grid. """
-
     # Get the number of slots in the event
     n_slots = get_slot_count(event)
-
-    data = {
-        'rows': [],
-        'days': [],
-        'colors': [],
-        'n_days': event.date_set.count(),
-    }
     # Get the timespan of the event
     start_time = datetime.datetime.combine(datetime.date.today(), event.start_time)
     end_time = datetime.datetime.combine(datetime.date.today(), event.end_time)
@@ -62,57 +55,72 @@ def slots2grid( event : Event, participants : list[Participant]) -> dict :
 
     # Get the slots of each day
     participant_slot_strings = [slots2string(participant, n_slots) for participant in participants]
-    max_occupancy = 1
-
-    for n, date in enumerate(event.date_set.all()):
-        # Get participants for each slot
-        slot_participants = [[] for i in range(slots_per_day)]
-        for i, participant in enumerate(participants):
+    if is_input:
+        html = []
+        for n, date in reversed(list(enumerate(event.date_set.all()))):
+            day_offset = n * slots_per_day
+            dt = datetime.datetime.combine(date.date, datetime.time())
+            html += f'<div class="slot-column"><div class="day">{ dt.strftime("%b %d") }</div>'
+            slots = []
+
+            # Fill the slots of the day
+            for j in range(slots_per_day):
+                slot_begin = (start_time + j * event.slot_interval).strftime('%H:%M')
+                slot_end = (start_time + (j+1) * event.slot_interval).strftime('%H:%M')
+                current_time = start_time + j * event.slot_interval
+                if current_time.minute == 0:
+                    time_label = f'<div class=\"time-label\">{current_time.strftime("%H:%M")}</div>'
+                    classes = " full-hour"
+                elif current_time.minute == 30:
+                    time_label = ""
+                    classes = " half-hour"
+                else:
+                    time_label = ""
+                    classes = ""
+                checked = ""
+                for i in range(len(participant_slot_strings)):
+                    if participant_slot_strings[i][day_offset + j] == '1':
+                        checked = 'checked'
+                        break
+
+                slots.append(
+                    f'<div class="slot{classes}" title="{slot_begin} - {slot_end}">{ time_label }<input class="checkable" type="checkbox" id="slot_picker_{ day_offset + j }" name="slot_{day_offset + j}" { checked } /><label class="checkable" for="slot_picker_{day_offset + j}"></label></div>')
+            html.append(''.join(slots))
+            html.append('</div>')
+        return "".join(html)
+    else:
+        max_occupancy = 1
+        html = []
+        for n, date in reversed(list(enumerate(event.date_set.all()))):
+            day_offset = n * slots_per_day
+            dt = datetime.datetime.combine(date.date, datetime.time())
+            html.append(f'<div class="slot-column"><div class="day">{ dt.strftime("%b %d") }</div>')
+            slots = []
+            # Get participants for each slot
+            slot_participants = [[] for i in range(slots_per_day)]
             for j in range(slots_per_day):
-                if participant_slot_strings[i][n*slots_per_day + j] == '1':
-                    slot_participants[j].append(participant)
-        # Fill the slots of the day
-        slots = []
-        last_hour = None
-        last_half_hour = None
-        for j, ps in enumerate(slot_participants):
-            slot_begin = (start_time + j * event.slot_interval).strftime('%H:%M')
-            slot_end = (start_time + (j+1) * event.slot_interval).strftime('%H:%M')
-            current_time = start_time + j * event.slot_interval
-            slots.append({
-                'tooltip': f"{slot_begin} - {slot_end} \n{', '.join([p.user.username for p in ps])}",
-                'offset': n*slots_per_day + j,
-                'date': date.date,
-                'time': current_time,
-                'color': len(ps),
-                'checked': 'checked="checked"' if len(ps) > 0 else '',
-                'is_full_hour': current_time.hour != last_hour,
-                'is_half_hour': current_time.minute // 30 != last_half_hour,
-            })
-            max_occupancy = max(max_occupancy, len(ps))
-            last_hour = current_time.hour
-            last_half_hour = current_time.minute // 30
-        
-        day = {
-            'date': date.date,
-            'slots': slots,
-        }
-        data['days'].append(day)
-    data['days'] = reversed(data['days'])
-    # Fill the rows of the grid
-    last_hour = None
-    for i in range(slots_per_day):
-        current_time = start_time + i * event.slot_interval
-        data['rows'].append({
-            'time': current_time,
-            'is_full_hour': current_time.hour != last_hour,
-        })
-        last_hour = current_time.hour
-
-    data['rows'].append({
-        'time': end_time,
-        'is_full_hour': True,
-    })
-
-    data['colors'] = max_occupancy
-    return data
+                for i in range(len(participant_slot_strings)):
+                    if participant_slot_strings[i][day_offset + j] == '1':
+                        slot_participants[j].append(i)
+
+            # Fill the slots of the day
+            for j, ps in enumerate(slot_participants):
+                slot_begin = (start_time + j * event.slot_interval).strftime('%H:%M')
+                slot_end = (start_time + (j+1) * event.slot_interval).strftime('%H:%M')
+                current_time = start_time + j * event.slot_interval
+                if current_time.minute == 0:
+                    time_label = f'<div class=\"time-label\">{current_time.strftime("%H:%M")}</div>'
+                    classes = " full-hour"
+                elif current_time.minute == 30:
+                    time_label = ""
+                    classes = " half-hour"
+                else:
+                    time_label = ""
+                    classes = ""
+
+                slots.append(
+                    f'<div class="slot{classes}" id="grid_slot_{ day_offset + j }" title="{slot_begin} - {slot_end} \n{escape(", ".join([participants[p].user.username for p in ps]))}" style="--color-index:{ len(ps) }">{ time_label }</div>')
+                max_occupancy = max(max_occupancy, len(ps))
+            html.append(''.join(slots))
+            html.append('</div>')
+        return f'<div class="occupancy-grid" style="--color-count:{ max_occupancy }">{"".join(html)}</div>'

+ 1 - 12
zitap/templates/widgets/slot-picker.html

@@ -1,14 +1,3 @@
 <div class="slot-picker" id="{{ widget.attrs.id }}">
-  {% for day in widget.grid.days %}
-  <div class="slot-column">
-      <div class="day">{{ day.date|date:"M d" }}</div>
-      {% for slot in day.slots %}
-      <div class="slot {% if slot.is_full_hour %} full-hour{% elif slot.is_half_hour %} half-hour{% endif %}" title="{{ slot.tooltip }}">
-          {% if slot.is_full_hour %}<div class="time-label">{{ slot.time|date:"H:i" }}</div>{% endif %}
-          <input class="checkable" type="checkbox" id="slot_picker_{{ slot.offset }}" name="slot_{{ slot.offset }}" {{ slot.checked }} />
-          <label class="checkable" for="slot_picker_{{ slot.offset }}"></label>
-      </div>
-      {% endfor %}
-  </div>
-  {% endfor %}
+  {{ widget.grid | safe}}
 </div>

+ 1 - 13
zitap/templates/zitap/event.html

@@ -12,19 +12,7 @@
 {% block content %}
 <h1>{% trans "Event" %}: {{ event.name }}</h1>
 
-<div class="occupancy-grid" style="--color-count:{{ grid.colors }}">
-    {% for day in grid.days %}
-    <div class="slot-column">
-        <div class="day">{{ day.date|date:"M d" }}</div>
-        {% for slot in day.slots %}
-        <div class="slot{% if slot.is_full_hour %} full-hour{% elif slot.is_half_hour %} half-hour{% endif %}" id="grid_slot_{{ slot.offset }}" title="{{ slot.tooltip }}" style="--color-index:{{ slot.color }}">
-            {% if slot.is_full_hour %}<div class="time-label">{{ slot.time|date:"H:i" }}</div>{% endif %}
-        </div>
-        {% endfor %}
-    </div>
-    {% endfor %}
-</div>
-
+{{ grid | safe }}
 
 {% if update_form %}
     <form action="{% url 'update-slots' url=event.url %}" method="post" id="update-form">

+ 5 - 3
zitap/views.py

@@ -54,13 +54,15 @@ def create_event(request):
 
 def event(request, url):
     try:
-        event = Event.objects.get(url=url)
+        event = Event.objects.prefetch_related('date_set', 'participant_set', 'participant_set__user').get(url=url)
     except Event.DoesNotExist:
         return render(request, 'zitap/event-not-found.html')
     
     # Check if the user is logged in
     if 'user_id' in request.session:
-        participant, created = Participant.objects.get_or_create(user_id=request.session['user_id'], event=event)
+        participant = event.participant_set.filter(user_id=request.session['user_id']).first()
+        if participant is None:
+            participant, created = Participant.objects.get_or_create(user_id=request.session['user_id'], event=event)
         login_form = None
         update_form = UpdateSlotsForm(initial={'slots': slots2string(participant, get_slot_count(event))}, participant=participant)
     else:
@@ -69,7 +71,7 @@ def event(request, url):
     return render(
         request, 
         'zitap/event.html', 
-        {'event': event, 'grid': slots2grid(event, event.participant_set.all()), 'login_form': login_form, 'update_form': update_form}
+        {'event': event, 'grid': slots2grid(event, list(event.participant_set.all()), False), 'login_form': login_form, 'update_form': update_form}
     )
 
 def login(request, url):

+ 1 - 1
zitap/widgets.py

@@ -73,7 +73,7 @@ class SlotPickerWidget(Widget):
         context = super().get_context(name, value, attrs)
         event: Event = self.participant.event
 
-        context['widget']['grid'] = slots2grid(event, [self.participant])
+        context['widget']['grid'] = slots2grid(event, [self.participant], True)
         return context
 
     def value_from_datadict(self, data, files, name):