Skip to content
Snippets Groups Projects
Commit 61fadbec authored by Tomáš Valenta's avatar Tomáš Valenta
Browse files

Merge branch 'master' into 'test'

Sync branches

See merge request !1
parents f6e39dd3 b6687f03
No related branches found
No related tags found
1 merge request!1Sync branches
Pipeline #12842 passed
Showing
with 343 additions and 1555 deletions
default_language_version:
python: python3.11
exclude: snapshots/
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace
exclude: ^.*\.md$
- id: end-of-file-fixer
- id: debug-statements
- id: mixed-line-ending
args: [--fix=lf]
- id: detect-private-key
- id: check-merge-conflict
- repo: https://github.com/timothycrosley/isort
rev: 5.12.0
hooks:
- id: isort
- repo: https://github.com/psf/black
rev: 23.1.0
hooks:
- id: black
FROM python:3.11 FROM python:3.11
# RUN echo en_US.UTF-8 UTF-8\
# cs_CZ.UTF-8 UTF-8\
# > /etc/locale.gen
# RUN locale-gen
RUN mkdir /app RUN mkdir /app
WORKDIR /app WORKDIR /app
......
...@@ -4,4 +4,4 @@ from django.apps import AppConfig ...@@ -4,4 +4,4 @@ from django.apps import AppConfig
class LecturesConfig(AppConfig): class LecturesConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField" default_auto_field = "django.db.models.BigAutoField"
name = "lectures" name = "lectures"
verbose_name = "Lekce" verbose_name = "Školení"
# Generated by Django 4.1.4 on 2023-05-09 19:17
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('auth', '0012_alter_user_first_name_max_length'),
('lectures', '0014_alter_lecture_options_alter_lecturelector_username'),
]
operations = [
migrations.AlterModelOptions(
name='lecture',
options={'ordering': ('-timestamp', '-name'), 'permissions': [('can_edit_lecture_settings', 'Can edit Školení settings')], 'verbose_name': 'Školení', 'verbose_name_plural': 'Školení'},
),
migrations.AlterField(
model_name='lecture',
name='type',
field=models.CharField(choices=[('recommended', 'Doporučené školení'), ('optional', 'Volitelné školení')], max_length=11, verbose_name='Typ'),
),
migrations.AlterField(
model_name='lecturegroup',
name='user_groups',
field=models.ManyToManyField(blank=True, help_text='Pokud žádná nedefinuješ, školení ve skupině jsou dostupné všem.', to='auth.group', verbose_name='Uživatelské skupiny'),
),
migrations.AlterField(
model_name='lecturelector',
name='lecture',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='lectors', to='lectures.lecture', verbose_name='Školení'),
),
migrations.AlterField(
model_name='lecturematerial',
name='lecture',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='materials', to='lectures.lecture', verbose_name='Školení'),
),
migrations.AlterField(
model_name='lecturerecording',
name='lecture',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='recordings', to='lectures.lecture', verbose_name='Školení'),
),
]
...@@ -30,7 +30,7 @@ class LectureGroup(NameStrMixin, models.Model): ...@@ -30,7 +30,7 @@ class LectureGroup(NameStrMixin, models.Model):
Group, Group,
blank=True, blank=True,
verbose_name="Uživatelské skupiny", verbose_name="Uživatelské skupiny",
help_text="Pokud nedefinuješ žádné, lekce ve skupině jsou dostupné všem.", help_text="Pokud žádná nedefinuješ, školení ve skupině jsou dostupné všem.",
) )
class Meta: class Meta:
...@@ -40,7 +40,8 @@ class LectureGroup(NameStrMixin, models.Model): ...@@ -40,7 +40,8 @@ class LectureGroup(NameStrMixin, models.Model):
class Lecture(NameStrMixin, models.Model): class Lecture(NameStrMixin, models.Model):
is_current_treshold = timedelta(hours=8) is_current_starting_treshold = timedelta(hours=8)
is_current_ending_treshold = timedelta(days=60)
timestamp = models.DateTimeField( timestamp = models.DateTimeField(
verbose_name="Datum a čas konání", verbose_name="Datum a čas konání",
...@@ -49,8 +50,8 @@ class Lecture(NameStrMixin, models.Model): ...@@ -49,8 +50,8 @@ class Lecture(NameStrMixin, models.Model):
) # If undefined, assume this event was in the past ) # If undefined, assume this event was in the past
class TypeChoices(models.TextChoices): class TypeChoices(models.TextChoices):
RECOMMENDED = "recommended", "Doporučená lekce" RECOMMENDED = "recommended", "Doporučené školení"
OPTIONAL = "optional", "Volitelná lekce" OPTIONAL = "optional", "Volitelné školení"
groups = models.ManyToManyField( groups = models.ManyToManyField(
LectureGroup, LectureGroup,
...@@ -77,17 +78,12 @@ class Lecture(NameStrMixin, models.Model): ...@@ -77,17 +78,12 @@ class Lecture(NameStrMixin, models.Model):
help_text="Můžeš použít Markdown.", help_text="Můžeš použít Markdown.",
) )
@property
def is_current(self) -> bool:
# On or after the current time, minus 8 hours
return self.timestamp >= (timezone.now() - self.is_current_treshold)
# Settings # Settings
settings = app_settings.LectureSettings("Nastavení") settings = app_settings.LectureSettings("Nastavení")
class Meta: class Meta:
verbose_name = "Lekce" verbose_name = "Školení"
verbose_name_plural = verbose_name verbose_name_plural = verbose_name
ordering = ("-timestamp", "-name") ordering = ("-timestamp", "-name")
...@@ -97,7 +93,7 @@ class LectureLector(NameStrMixin, models.Model): ...@@ -97,7 +93,7 @@ class LectureLector(NameStrMixin, models.Model):
"Lecture", "Lecture",
on_delete=models.CASCADE, on_delete=models.CASCADE,
related_name="lectors", related_name="lectors",
verbose_name="Lekce", verbose_name="Školení",
) )
name = models.CharField( name = models.CharField(
...@@ -133,7 +129,7 @@ class LectureRecording(NameStrMixin, models.Model): ...@@ -133,7 +129,7 @@ class LectureRecording(NameStrMixin, models.Model):
"Lecture", "Lecture",
on_delete=models.CASCADE, on_delete=models.CASCADE,
related_name="recordings", related_name="recordings",
verbose_name="Lekce", verbose_name="Školení",
) )
name = models.CharField( name = models.CharField(
...@@ -158,7 +154,7 @@ class LectureMaterial(NameStrMixin, models.Model): ...@@ -158,7 +154,7 @@ class LectureMaterial(NameStrMixin, models.Model):
"Lecture", "Lecture",
on_delete=models.CASCADE, on_delete=models.CASCADE,
related_name="materials", related_name="materials",
verbose_name="Lekce", verbose_name="Školení",
) )
name = models.CharField( name = models.CharField(
......
{% load markdownify %} {% load markdownify %}
<li> <li>
<a href="{% url "lectures:view_lecture" lecture.id %}" class="hover:no-underline"> <a href="{% url "lectures:view_lecture" lecture.id %}?related_group_id={{ group.id }}" class="hover:no-underline">
<div class="card elevation-6"> <div class="card elevation-6">
<div class="card__body p-5 hover:bg-gray-100 duration-100"> <div class="card__body p-5 hover:bg-gray-100 duration-100">
<h2 class="head-alt-sm mb-4"> <h2 class="head-alt-sm mb-4">
......
{% extends "shared/includes/base.html" %} {% extends "shared/includes/base.html" %}
{% load markdownify %} {% load render_bundle from webpack_loader %}
{% load markdownify static %}
{% block content %} {% block content %}
<h1 class="head-alt-md mb-10"> {% render_bundle "view_group_lectures" %}
<i class="ico--users mr-3"></i>
{{ group.name }} - výuka {% include "shared/includes/double_heading.html" with heading=group.name subheading="výuka" icon="ico--user" %}
</h1>
{% if group.description %} {% if group.description %}
<div class="prose max-w-none mb-10"> <div class="prose max-w-none mb-10">
{{ group.description|markdownify|safe }} {{ group.description|markdownify|safe }}
</div> </div>
{% endif %} {% endif %}
<script>
window.currentTimelineYear = {{ current_year }};
</script>
<div class="__js-root"> <div class="__js-root">
<ui-view-provider <ui-view-provider
:initial="{current_lectures: true, calendar: false, recordings: false}" :initial="{current_lectures: true, calendar: false, recordings: false}"
...@@ -18,48 +24,97 @@ ...@@ -18,48 +24,97 @@
v-slot="{ isCurrentView, toggleView }" v-slot="{ isCurrentView, toggleView }"
> >
<div class="flex justify-center mb-10"> <div class="flex justify-center mb-10">
<ui-horizontal-scrollable> <div class="switch overflow-x-auto">
<div class="switch">
<a <a
@click="toggleView('current_lectures')" @click="toggleView('current_lectures')"
class="switch__item" class="switch__item"
:class="{'switch__item--active': isCurrentView('current_lectures')}" :class="{'switch__item--active': isCurrentView('current_lectures')}"
>Aktuálně</a> >Aktuálně</a>
<a <a
@click="toggleView('calendar')" @click="toggleView('timeline')"
class="switch__item" class="switch__item"
:class="{'switch__item--active': isCurrentView('calendar')}" :class="{'switch__item--active': isCurrentView('timeline')}"
>Kalendář</a> >Časová osa</a>
<a <a
@click="toggleView('recordings')" @click="toggleView('recordings')"
class="switch__item" class="switch__item"
:class="{'switch__item--active': isCurrentView('recordings')}" :class="{'switch__item--active': isCurrentView('recordings')}"
>Záznamy</a> >Záznamy</a>
</div> </div>
</ui-horizontal-scrollable>
</div> </div>
<div> <div>
<template v-if="isCurrentView('current_lectures')"> <template v-if="isCurrentView('current_lectures')">
{% if current_lectures %} {% if current_lectures %}
<ul class="grid grid-cols-1 md:grid-cols-2 gap-4"> <ul class="grid grid-cols-1 md:grid-cols-2 gap-4">
{% for lecture in current_lectures %} {% for lecture in current_lectures %}
{% include "lectures/includes/lecture.html" with lecture=lecture %} {% include "lectures/includes/lecture.html" with lecture=lecture group=group %}
{% endfor %} {% endfor %}
</ul> </ul>
{% else %} {% else %}
<span class="text-gray-600">Žádné dostupné aktuální lekce.</span> <span class="text-gray-600">Žádná dostupná aktuální školení.</span>
{% endif %} {% endif %}
</template> </template>
<template v-if="isCurrentView('calendar')"> <template v-if="isCurrentView('timeline')">
<div> <div>
<ui-person-calendar events='{{ calendar_data|safe }}'></ui-person-calendar> <div class="head-alt-md mb-4 flex items-center justify-between">
<h3 class="flex items-center gap-2">
<i class="ico--calendar mr-2"></i>
<span id="timeline-current-year">{{ current_year }}</span>
</h3>
<div class="flex gap-1">
<button
class="bg-black p-3 text-2xl text-white hover:bg-grey-800 disabled:opacity-50 disabled:cursor-normal"
id="previous-timeline-item"
onclick="window.previousTimelineYear()"
{% if not has_previous_timeline_years %}disabled{% endif %}
><i class="ico--chevron-left"></i></button>
<button
class="bg-black p-3 text-2xl text-white hover:bg-grey-800 disabled:opacity-50 disabled:cursor-normal"
id="next-timeline-item"
onclick="window.nextTimelineYear()"
{% if not has_next_timeline_years %}disabled{% endif %}
><i class="ico--chevron-right"></i></button>
</div>
</div>
{% for year, month_data in per_month_lectures.items %}
<ul
class="__timeline-year grid grid-cols-1 md:grid-cols-3 gap-3{% if current_year != year %} hidden{% endif %}"
id="timeline-year-{{ year }}"
>
{% for month, lectures in month_data.items %}
<li class="card elevation-3">
<div class="card__body p-5">
<h4 class="head-alt-sm mb-2">{{ month }}</h4>
{% if lectures %}
<ul class="flex flex-col gap-1">
{% for lecture in lectures %}
<li>
<a
class="inline-block px-2.5 py-1.5 bg-gray-200 rounded-sm duration-100 hover:no-underline hover:bg-gray-300"
href="{% url "lectures:view_lecture" lecture.id %}?related_group_id={{ group.id }}"
>{{ lecture.name }}</a>
</li>
{% endfor %}
</ul>
{% else %}
<span class="block text-gray-600 pt-2">Žádná školení.</span>
{% endif %}
</div>
</li>
{% endfor %}
</ul>
{% endfor %}
<script type="application/javascript" defer>
window.currentTimelineYear = {{ current_year }};
</script>
</div> </div>
</template> </template>
<template v-if="isCurrentView('recordings')"> <template v-if="isCurrentView('recordings')">
{% if past_lectures %} {% if past_lectures %}
<ul class="grid grid-cols-1 md:grid-cols-2 gap-4"> <ul class="grid grid-cols-1 md:grid-cols-2 gap-4">
{% for lecture in past_lectures %} {% for lecture in past_lectures %}
{% include "lectures/includes/lecture.html" with lecture=lecture %} {% include "lectures/includes/lecture.html" with lecture=lecture group=group %}
{% endfor %} {% endfor %}
</ul> </ul>
{% else %} {% else %}
......
...@@ -5,10 +5,7 @@ ...@@ -5,10 +5,7 @@
<div class="prose max-w-none mb-10"> <div class="prose max-w-none mb-10">
{{ settings.motd|markdownify|safe }} {{ settings.motd|markdownify|safe }}
</div> </div>
<h1 class="head-alt-md mb-10"> {% include "shared/includes/double_heading.html" with heading="Výukové skupiny" icon="ico--users" %}
<i class="ico--users mr-3"></i>
Výukové skupiny
</h1>
<ul class="grid grid-cols-1 md:grid-cols-2 gap-3"> <ul class="grid grid-cols-1 md:grid-cols-2 gap-3">
{% for group in lecture_groups %} {% for group in lecture_groups %}
<li> <li>
......
...@@ -2,7 +2,17 @@ ...@@ -2,7 +2,17 @@
{% load markdownify %} {% load markdownify %}
{% block content %} {% block content %}
{% if related_group_id %}
<div class="flex gap-2 mb-10">
<i class="ico--chevron-left"></i>
<a
href="{% url "lectures:view_group_lectures" related_group_id %}"
>Zpět na seznam</a>
</div>
{% endif %}
{% include "shared/includes/double_heading.html" with heading=lecture.name subheading=lecture.get_type_display icon="ico--bookmark" %} {% include "shared/includes/double_heading.html" with heading=lecture.name subheading=lecture.get_type_display icon="ico--bookmark" %}
<div class="flex flex-col gap-2 my-4 py-4 border-y border-gray-200"> <div class="flex flex-col gap-2 my-4 py-4 border-y border-gray-200">
<div class="flex justify-between gap-2 text-lg text-gray-600"> <div class="flex justify-between gap-2 text-lg text-gray-600">
<div class="flex gap-2 items-center"> <div class="flex gap-2 items-center">
...@@ -30,12 +40,13 @@ ...@@ -30,12 +40,13 @@
</ul> </ul>
</div> </div>
</div> </div>
{% if lecture.description %} {% if lecture.description %}
<div class="prose max-w-none mb-10"> <div class="prose max-w-none mb-10">
{{ lecture.description|markdownify|safe }} {{ lecture.description|markdownify|safe }}
</div> </div>
{% endif %} {% endif %}
<div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-5 md:gap-3"> <div class="grid grid-cols-1 md:grid-cols-2 gap-5 md:gap-3">
<section> <section>
{% with lecture.materials.all as materials %} {% with lecture.materials.all as materials %}
...@@ -47,7 +58,7 @@ ...@@ -47,7 +58,7 @@
<ul class="flex flex-col gap-2 my-3 py-3 border-y border-gray-200"> <ul class="flex flex-col gap-2 my-3 py-3 border-y border-gray-200">
{% for material in materials %} {% for material in materials %}
<li> <li>
<i class="ico--{% if material.link %}link{% elif material.file %}folder-download{% endif %} mr-2"></i> <i class="ico--{% if material.link %}link{% elif material.file %}download{% endif %} mr-2"></i>
<a <a
{% if material.link %} {% if material.link %}
href="{{ material.link }}" href="{{ material.link }}"
...@@ -74,7 +85,7 @@ ...@@ -74,7 +85,7 @@
<ul class="flex flex-col gap-2 my-3 py-3 border-y border-gray-200"> <ul class="flex flex-col gap-2 my-3 py-3 border-y border-gray-200">
{% for recording in recordings %} {% for recording in recordings %}
<li> <li>
<i class="ico--link mr-2 hover:no-underline"></i> <i class="ico--youtube mr-2 hover:no-underline"></i>
<a <a
href="{{ recording.link }}" href="{{ recording.link }}"
class="text-lg" class="text-lg"
...@@ -88,6 +99,7 @@ ...@@ -88,6 +99,7 @@
{% endwith %} {% endwith %}
</section> </section>
</div> </div>
{% with lecture.lectors.all as lectors %} {% with lecture.lectors.all as lectors %}
{% if lectors %} {% if lectors %}
<section class="mt-6 flex flex-col gap-4"> <section class="mt-6 flex flex-col gap-4">
...@@ -95,7 +107,7 @@ ...@@ -95,7 +107,7 @@
<i class="ico--users mr-2"></i> <i class="ico--users mr-2"></i>
Lektoři Lektoři
</h2> </h2>
<ul class="grid grid-cols-1 md:grid-cols-2 gap-2"> <ul class="grid grid-cols-1 md:grid-cols-2 gap-4">
{% for lector in lectors %} {% for lector in lectors %}
<li class="card elevation-3"> <li class="card elevation-3">
{% if lector.url %} {% if lector.url %}
...@@ -107,7 +119,7 @@ ...@@ -107,7 +119,7 @@
> >
<div class="avatar badge__avatar avatar--sm"> <div class="avatar badge__avatar avatar--sm">
<img <img
src="https://a.pirati.cz/piratar/300/{% if lector.username %}{{ lector.username }}{% else %}default{% endif %}.webp" src="https://a.pirati.cz/piratar/300/{% if lector.username %}{{ lector.username }}{% else %}default{% endif %}.jpg"
alt="Profilový obrázek {{ lector.name }}" alt="Profilový obrázek {{ lector.name }}"
> >
</div> </div>
......
...@@ -4,7 +4,7 @@ from . import models, views ...@@ -4,7 +4,7 @@ from . import models, views
app_name = "lectures" app_name = "lectures"
urlpatterns = [ urlpatterns = [
path("", views.view_avilable_groups, name="view_avilable_groups"), path("", views.view_groups, name="view_groups"),
path( path(
"groups/<int:group_id>", views.view_group_lectures, name="view_group_lectures" "groups/<int:group_id>", views.view_group_lectures, name="view_group_lectures"
), ),
......
import datetime #import calendar
import json import json
#import locale
from datetime import datetime
from itertools import chain from itertools import chain
from django.conf import settings from django.conf import settings
...@@ -19,7 +22,7 @@ def get_base_context(request) -> dict: ...@@ -19,7 +22,7 @@ def get_base_context(request) -> dict:
} }
def view_avilable_groups(request): def view_groups(request):
lecture_groups = ( lecture_groups = (
get_objects_for_user(request.user, "lectures.view_lecturegroup") get_objects_for_user(request.user, "lectures.view_lecturegroup")
.filter( .filter(
...@@ -50,36 +53,96 @@ def view_group_lectures(request, group_id: int): ...@@ -50,36 +53,96 @@ def view_group_lectures(request, group_id: int):
id=group_id, id=group_id,
) )
timestamp_separator = timezone.now() - Lecture.is_current_treshold timestamp_starting_separator = timezone.now() - Lecture.is_current_starting_treshold
timestamp_ending_separator = timezone.now() + Lecture.is_current_ending_treshold
current_lectures = ( past_lectures = (
get_objects_for_user(request.user, "lectures.view_lecture") get_objects_for_user(request.user, "lectures.view_lecture")
.filter( .filter(
groups=group, groups=group,
timestamp__gte=timestamp_separator, timestamp__lt=timestamp_starting_separator,
) )
.all() .all()
) )
past_lectures = ( current_lectures = (
get_objects_for_user(request.user, "lectures.view_lecture") get_objects_for_user(request.user, "lectures.view_lecture")
.filter( .filter(
groups=group, groups=group,
timestamp__lt=timestamp_separator, timestamp__gte=timestamp_starting_separator,
timestamp__lte=timestamp_ending_separator
) )
.all() .all()
) )
calendar_data = [] calendar_data = []
all_lectures = list(chain(current_lectures, past_lectures)) all_lectures = list(
chain(
past_lectures,
current_lectures,
(
get_objects_for_user(request.user, "lectures.view_lecture")
.filter(
groups=group,
timestamp__gte=timestamp_ending_separator
)
.all()
)
)
)
per_month_lectures = {}
MONTH_NAMES = {
0: "",
1: "Leden",
2: "Únor",
3: "Březen",
4: "Duben",
5: "Květen",
6: "Červen",
7: "Červenec",
8: "Srpen",
9: "Září",
10: "Říjen",
11: "Listopad",
12: "Prosinec",
}
#locale.setlocale(
#locale.LC_ALL,
#"cs_CZ.UTF-8"
#)
current_year = datetime.today().year
has_previous_timeline_years = False
has_next_timeline_years = False
for lecture in all_lectures: for lecture in all_lectures:
calendar_data.append( if not has_previous_timeline_years and lecture.timestamp.year < current_year:
{ has_previous_timeline_years = True
"title": lecture.name,
"date": lecture.timestamp.date().isoformat(), if not has_next_timeline_years and lecture.timestamp.year > current_year:
"url": reverse("lectures:view_lecture", args=(lecture.id,)), has_next_timeline_years = True
if lecture.timestamp.year not in per_month_lectures:
per_month_lectures[lecture.timestamp.year] = {
MONTH_NAMES[month]: []
for month in range(1, 12 + 1)
} }
)
if current_year not in per_month_lectures:
per_month_lectures[current_year] = {
MONTH_NAMES[month]: []
for month in range(1, 12 + 1)
}
per_month_lectures[lecture.timestamp.year][MONTH_NAMES[lecture.timestamp.month]].append(lecture)
#locale.setlocale(
#locale.LC_ALL,
#""
#)
return render( return render(
request, request,
...@@ -92,7 +155,10 @@ def view_group_lectures(request, group_id: int): ...@@ -92,7 +155,10 @@ def view_group_lectures(request, group_id: int):
"group": group, "group": group,
"current_lectures": current_lectures, "current_lectures": current_lectures,
"past_lectures": past_lectures, "past_lectures": past_lectures,
"calendar_data": json.dumps(calendar_data), "per_month_lectures": per_month_lectures,
"current_year": current_year,
"has_previous_timeline_years": has_previous_timeline_years,
"has_next_timeline_years": has_next_timeline_years,
}, },
) )
...@@ -107,14 +173,29 @@ def view_lecture(request, lecture_id: int): ...@@ -107,14 +173,29 @@ def view_lecture(request, lecture_id: int):
if lecture is None: if lecture is None:
raise HTTPExceptions.NOT_FOUND raise HTTPExceptions.NOT_FOUND
related_group_id = request.GET.get("related_group_id")
if (
related_group_id is not None
and not (
get_objects_for_user(request.user, "lectures.view_lecture")
.filter(id=related_group_id)
.exists()
)
):
# Ignore the wrong part of the URL and move on, don't raise exceptions
# just because of the related_group_id being wrong.
related_group_id = None
return render( return render(
request, request,
"lectures/view_lecture.html", "lectures/view_lecture.html",
{ {
**get_base_context(request), **get_base_context(request),
"title": f"{lecture.name}", "title": f"{lecture.name}",
"description": f"e-Learningová lekce {lecture.name}.", "description": f"e-Learningové školení {lecture.name}.",
"header_name": lecture.name, "header_name": lecture.name,
"lecture": lecture, "lecture": lecture,
"related_group_id": related_group_id,
}, },
) )
Source diff could not be displayed: it is too large. Options to address this: view the blob.
/*!
* Sizzle CSS Selector Engine v2.3.10
* https://sizzlejs.com/
*
* Copyright JS Foundation and other contributors
* Released under the MIT license
* https://js.foundation/
*
* Date: 2023-02-14
*/
/*!
* Vue.js v2.7.14
* (c) 2014-2022 Evan You
* Released under the MIT License.
*/
/*!
* jQuery JavaScript Library v3.6.4
* https://jquery.com/
*
* Includes Sizzle.js
* https://sizzlejs.com/
*
* Copyright OpenJS Foundation and other contributors
* Released under the MIT license
* https://jquery.org/license
*
* Date: 2023-03-08T15:28Z
*/
(()=>{"use strict";var e,r={},t={};function n(e){var o=t[e];if(void 0!==o)return o.exports;var i=t[e]={id:e,exports:{}};return r[e].call(i.exports,i,i.exports,n),i.exports}n.m=r,e=[],n.O=(r,t,o,i)=>{if(!t){var a=1/0;for(f=0;f<e.length;f++){for(var[t,o,i]=e[f],c=!0,l=0;l<t.length;l++)(!1&i||a>=i)&&Object.keys(n.O).every((e=>n.O[e](t[l])))?t.splice(l--,1):(c=!1,i<a&&(a=i));if(c){e.splice(f--,1);var u=o();void 0!==u&&(r=u)}}return r}i=i||0;for(var f=e.length;f>0&&e[f-1][2]>i;f--)e[f]=e[f-1];e[f]=[t,o,i]},n.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return n.d(r,{a:r}),r},n.d=(e,r)=>{for(var t in r)n.o(r,t)&&!n.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),n.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),(()=>{n.b=document.baseURI||self.location.href;var e={666:0};n.O.j=r=>0===e[r];var r=(r,t)=>{var o,i,[a,c,l]=t,u=0;if(a.some((r=>0!==e[r]))){for(o in c)n.o(c,o)&&(n.m[o]=c[o]);if(l)var f=l(n)}for(r&&r(t);u<a.length;u++)i=a[u],n.o(e,i)&&e[i]&&e[i][0](),e[i]=0;return n.O(f)},t=self.webpackChunkucebnice=self.webpackChunkucebnice||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})(),n.nc=void 0})();
This diff is collapsed.
...@@ -37,16 +37,17 @@ ...@@ -37,16 +37,17 @@
> >
<link <link
href="http://localhost:3000/css/styles.css" href="https://styleguide.pirati.cz/2.12.x/css/styles.css"
rel="stylesheet" rel="stylesheet"
media="all" media="all"
> >
<link <link
href="http://localhost:3000/css/pattern-scaffolding.css" href="https://styleguide.pirati.cz/2.12.x/css/pattern-scaffolding.css"
rel="stylesheet" rel="stylesheet"
media="all" media="all"
> >
{% render_bundle "shared" %}
{% render_bundle "base" %} {% render_bundle "base" %}
<title>{{ title }} | Učebnice</title> <title>{{ title }} | Učebnice</title>
...@@ -192,7 +193,7 @@ ...@@ -192,7 +193,7 @@
</footer> </footer>
<script <script
src="http://localhost:3000/js/main.bundle.js" src="https://styleguide.pirati.cz/2.12.x/js/main.bundle.js"
></script> ></script>
</body> </body>
</html> </html>
<div class="flex gap-4 mb-10"> <div class="flex gap-4 mb-10">
<i class="{{ icon }} text-6xl md:text-7xl"></i> <i class="{{ icon }} {% if subheading %}text-6xl md:text-7xl{% else %}text-5xl md:text-6xl{% endif %}"></i>
<div> <div>
<h1 class="head-alt-md md:head-alt-lg">{{ heading }}</h1> <h1 class="head-alt-md md:head-alt-lg">{{ heading }}</h1>
<h2 class="head-alt-sm">{{ subheading }}</h2> {% if subheading %}<h2 class="head-alt-sm">{{ subheading }}</h2>{% endif %}
</div> </div>
</div> </div>
import $ from "jquery";
const showTimelineYear = () => {
$(".__timeline-year").not(`#timeline-year-${window.currentTimelineYear}`).addClass("hidden");
$(`#timeline-year-${window.currentTimelineYear}`).removeClass("hidden");
$("#timeline-current-year").html(window.currentTimelineYear);
$("#next-timeline-item").attr(
"disabled",
($(`#timeline-year-${window.currentTimelineYear + 1}`).length === 0)
);
$("#previous-timeline-item").attr(
"disabled",
($(`#timeline-year-${window.currentTimelineYear - 1}`).length === 0)
);
}
$(window).ready(
() => {
window.nextTimelineYear = () => {
window.currentTimelineYear++;
showTimelineYear();
}
window.previousTimelineYear = () => {
window.currentTimelineYear--;
showTimelineYear();
}
}
)
# Generated by Django 4.1.4 on 2023-05-09 19:17
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('lectures', '0015_alter_lecture_options_alter_lecture_type_and_more'),
('users', '0007_alter_user_rsvp_lectures'),
]
operations = [
migrations.AlterField(
model_name='user',
name='rsvp_lectures',
field=models.ManyToManyField(blank=True, related_name='rsvp_users', to='lectures.lecture', verbose_name='Zaregistrovaná školení'),
),
]
...@@ -32,7 +32,7 @@ class User(pirates_models.AbstractUser): ...@@ -32,7 +32,7 @@ class User(pirates_models.AbstractUser):
"lectures.Lecture", "lectures.Lecture",
blank=True, blank=True,
related_name="rsvp_users", related_name="rsvp_users",
verbose_name="Zaregistrované lekce", verbose_name="Zaregistrovaná školení",
) )
def set_unusable_password(self) -> None: def set_unusable_password(self) -> None:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment