From 12410886305eab4b4fe7123b8e3dd7ff95556c75 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Valenta?= <tomas@imaniti.org>
Date: Mon, 26 Feb 2024 17:05:55 +0100
Subject: [PATCH] reorder views, nicer RSVP views, allow duplicating lectures

---
 base.txt                                      |   0
 lectures/admin.py                             |  18 ++-
 .../0028_alter_lecture_rsvp_users.py          |  20 +++
 lectures/models.py                            |   2 +-
 .../lectures/view_group_lectures.html         |  12 +-
 requirements/base.in                          |  19 +++
 requirements/base.txt                         | 119 ++++++++++++++++--
 requirements/production.in                    |   2 +
 requirements/production.txt                   |  14 ++-
 shared/locale/cs_CZ/LC_MESSAGES/django.mo     | Bin 0 -> 2117 bytes
 shared/locale/cs_CZ/LC_MESSAGES/django.po     |  26 ++++
 ucebnice/settings/base.py                     |   1 +
 12 files changed, 210 insertions(+), 23 deletions(-)
 create mode 100644 base.txt
 create mode 100644 lectures/migrations/0028_alter_lecture_rsvp_users.py
 create mode 100644 requirements/base.in
 create mode 100644 requirements/production.in
 create mode 100644 shared/locale/cs_CZ/LC_MESSAGES/django.mo
 create mode 100644 shared/locale/cs_CZ/LC_MESSAGES/django.po

diff --git a/base.txt b/base.txt
new file mode 100644
index 0000000..e69de29
diff --git a/lectures/admin.py b/lectures/admin.py
index e99d358..565bdb4 100644
--- a/lectures/admin.py
+++ b/lectures/admin.py
@@ -1,5 +1,6 @@
 from django.contrib import admin
 from markdownx.admin import MarkdownxModelAdmin
+from modelclone import ClonableModelAdmin
 
 from .forms import LectureGroupTypeFormset
 from .models import (
@@ -44,7 +45,7 @@ class LectureGroupTypeInline(admin.StackedInline):
     extra = 1
 
 
-class LectureAdmin(MarkdownxModelAdmin):
+class LectureAdmin(ClonableModelAdmin, MarkdownxModelAdmin):
     inlines = (
         LectureGroupTypeInline,
         LectureRecordingInline,
@@ -55,6 +56,21 @@ class LectureAdmin(MarkdownxModelAdmin):
     search_fields = ("name", "description")
     readonly_fields = ("rsvp_users",)
 
+    fieldsets = (
+        (
+            None,
+            {
+                "fields": [
+                    "timestamp",
+                    "category",
+                    "name",
+                    "description",
+                ]
+            },
+        ),
+        ("Registrovaní účastníci", {"fields": ["rsvp_users"]}),
+    )
+
     list_display = (
         "name",
         "timestamp",
diff --git a/lectures/migrations/0028_alter_lecture_rsvp_users.py b/lectures/migrations/0028_alter_lecture_rsvp_users.py
new file mode 100644
index 0000000..767bb93
--- /dev/null
+++ b/lectures/migrations/0028_alter_lecture_rsvp_users.py
@@ -0,0 +1,20 @@
+# Generated by Django 5.0.2 on 2024-02-26 16:02
+
+from django.conf import settings
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('lectures', '0027_alter_lecturecategory_options'),
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='lecture',
+            name='rsvp_users',
+            field=models.ManyToManyField(blank=True, related_name='rsvp_lectures', to=settings.AUTH_USER_MODEL, verbose_name='Registrovaní účastníci'),
+        ),
+    ]
diff --git a/lectures/models.py b/lectures/models.py
index cb058fa..1979f4e 100644
--- a/lectures/models.py
+++ b/lectures/models.py
@@ -168,7 +168,7 @@ class Lecture(NameStrMixin, models.Model):
         "users.User",
         blank=True,
         related_name="rsvp_lectures",
-        verbose_name="Zaregistrovaní uživatelé",
+        verbose_name="Registrovaní účastníci",
     )
 
     # Settings
diff --git a/lectures/templates/lectures/view_group_lectures.html b/lectures/templates/lectures/view_group_lectures.html
index 8b742c7..3195496 100644
--- a/lectures/templates/lectures/view_group_lectures.html
+++ b/lectures/templates/lectures/view_group_lectures.html
@@ -19,12 +19,17 @@
 
     <div class="__js-root">
         <ui-view-provider
-            :initial="{current_lectures: false, calendar: false, recordings: true}"
+            :initial="{current_lectures: false, timeline: true, recordings: false}"
             :sync-location="true"
             v-slot="{ isCurrentView, toggleView }"
         >
             <div class="flex justify-center mb-10">
                 <div class="switch overflow-x-auto">
+                    <a
+                        @click="toggleView('timeline')"
+                        class="switch__item whitespace-nowrap"
+                        :class="{'switch__item--active': isCurrentView('timeline')}"
+                    >Časová osa</a>
                     <a
                         @click="toggleView('recordings')"
                         class="switch__item whitespace-nowrap"
@@ -35,11 +40,6 @@
                         class="switch__item whitespace-nowrap"
                         :class="{'switch__item--active': isCurrentView('current_lectures')}"
                     >Aktuálně</a>
-                    <a
-                        @click="toggleView('timeline')"
-                        class="switch__item whitespace-nowrap"
-                        :class="{'switch__item--active': isCurrentView('timeline')}"
-                    >Časová osa</a>
                 </div>
             </div>
             <div>
diff --git a/requirements/base.in b/requirements/base.in
new file mode 100644
index 0000000..9b9f730
--- /dev/null
+++ b/requirements/base.in
@@ -0,0 +1,19 @@
+django
+django-admin-index
+django-admin-interface
+django-database-url
+django-dbsettings
+django-downloadview
+django-markdownx
+django-ordered-model
+django-webpack-loader
+pirates
+django-markdownx
+django-environ
+django-http-exceptions
+django-modelclone-next
+gql[requests]
+requests
+PyJWT
+Pillow
+psycopg2-binary
diff --git a/requirements/base.txt b/requirements/base.txt
index 9115d8a..c5f8664 100644
--- a/requirements/base.txt
+++ b/requirements/base.txt
@@ -1,18 +1,111 @@
-django==4.1.4
-django-admin-index==2.0.2
-django-admin-interface==0.24.2
+#
+# This file is autogenerated by pip-compile with Python 3.11
+# by the following command:
+#
+#    pip-compile base.in
+#
+anyio==4.3.0
+    # via gql
+asgiref==3.7.2
+    # via django
+backoff==2.2.1
+    # via gql
+certifi==2024.2.2
+    # via requests
+cffi==1.16.0
+    # via cryptography
+charset-normalizer==3.3.2
+    # via requests
+cryptography==42.0.5
+    # via
+    #   josepy
+    #   mozilla-django-oidc
+    #   pyopenssl
+django==5.0.2
+    # via
+    #   -r base.in
+    #   django-admin-index
+    #   django-database-url
+    #   django-downloadview
+    #   django-http-exceptions
+    #   django-markdownx
+    #   mozilla-django-oidc
+django-admin-index==3.1.0
+    # via -r base.in
+django-admin-interface==0.28.5
+    # via -r base.in
+django-colorfield==0.11.0
+    # via django-admin-interface
 django-database-url==1.0.3
+    # via -r base.in
 django-dbsettings==1.3.0
+    # via -r base.in
 django-downloadview==2.3.0
-django-markdownx==4.0.0b1
-django-ordered-model==3.7.1
-django-webpack-loader==1.8.0
-pirates==0.6.0
-django-markdownx==4.0.0b1
-django-environ==0.9.0
+    # via -r base.in
+django-environ==0.11.2
+    # via -r base.in
 django-http-exceptions==1.4.0
-gql[requests]==3.4.1
+    # via -r base.in
+django-markdownx==4.0.7
+    # via -r base.in
+django-modelclone-next==0.8.2
+    # via -r base.in
+django-ordered-model==3.7.4
+    # via
+    #   -r base.in
+    #   django-admin-index
+django-webpack-loader==3.0.1
+    # via -r base.in
+gql[requests]==3.5.0
+    # via -r base.in
+graphql-core==3.2.3
+    # via gql
+idna==3.6
+    # via
+    #   anyio
+    #   requests
+    #   yarl
+josepy==1.14.0
+    # via mozilla-django-oidc
+markdown==3.5.2
+    # via django-markdownx
+mozilla-django-oidc==3.0.0
+    # via pirates
+multidict==6.0.5
+    # via yarl
+pillow==10.2.0
+    # via
+    #   -r base.in
+    #   django-colorfield
+    #   django-markdownx
+pirates==0.7.0
+    # via -r base.in
+psycopg2-binary==2.9.9
+    # via -r base.in
+pycparser==2.21
+    # via cffi
+pyjwt==2.8.0
+    # via -r base.in
+pyopenssl==24.0.0
+    # via josepy
+python-slugify==8.0.4
+    # via django-admin-interface
 requests==2.31.0
-PyJWT==2.6.0
-Pillow==9.5.0
-psycopg2-binary==2.9.5
+    # via
+    #   -r base.in
+    #   django-downloadview
+    #   gql
+    #   mozilla-django-oidc
+    #   requests-toolbelt
+requests-toolbelt==1.0.0
+    # via gql
+sniffio==1.3.1
+    # via anyio
+sqlparse==0.4.4
+    # via django
+text-unidecode==1.3
+    # via python-slugify
+urllib3==2.2.1
+    # via requests
+yarl==1.9.4
+    # via gql
diff --git a/requirements/production.in b/requirements/production.in
new file mode 100644
index 0000000..e52364a
--- /dev/null
+++ b/requirements/production.in
@@ -0,0 +1,2 @@
+gunicorn
+whitenoise
diff --git a/requirements/production.txt b/requirements/production.txt
index ce5169e..f7490d5 100644
--- a/requirements/production.txt
+++ b/requirements/production.txt
@@ -1,2 +1,12 @@
-gunicorn==20.1.0
-whitenoise==6.3.0
+#
+# This file is autogenerated by pip-compile with Python 3.11
+# by the following command:
+#
+#    pip-compile production.in
+#
+gunicorn==21.2.0
+    # via -r production.in
+packaging==23.2
+    # via gunicorn
+whitenoise==6.6.0
+    # via -r production.in
diff --git a/shared/locale/cs_CZ/LC_MESSAGES/django.mo b/shared/locale/cs_CZ/LC_MESSAGES/django.mo
new file mode 100644
index 0000000000000000000000000000000000000000..675f7c4f5df3718188bad466d47e6ebce9fff765
GIT binary patch
literal 2117
zcmca7#4?qEfq_8=ivKV$FsL#xFx+7Ti83%0FflN&F)%O`GBGf4GB7YyFflN&FfcGQ
zF)=V0GB7Z-Gcho*GB7agWMW_tWME*}4^@8=s_q680|O5O1H)Y=1_o{h28LHq`EN`N
z3_=VH41b~G0?ZJ;3^N0R0|NttJ~IP@0s{j>0W-wDiOdWPk_-$C)0i0;Bp4VNHZU_V
zxG^v=oP^2?urM$PGcYiSvM?|RFfcG^vM?}kFfcG!u|VAC%mQ)0Ckq3E2?GN|Fbf02
zL`DXN4i<>{Qfv$iTnr2h@@xzY><kPHT5Jpqpdc`U@=e$v=G#E|0c;R+BiI-i_!$@&
z;@BYW&trpxS0ft(g9rlyLkAng|8v<G7{nMD7*??{Fjz7$FdSrqg!yl%c@pdl4B`w7
z3<~TF3{ngX3>NGR4B;SmvP0axnw^0`j)8$;D?7yhSJ)XCL>U+u-m*i&m6-$Letr%H
z1}z2#1}P4R`<WOZ;Q?|ZC_F&13UUXC28BN;?)VrWZU(tm8YBV5Aoqac9K;3L1&T)y
z8x%ggAO<wefZPj;8;}qv4nXk(ifd4M0EvOp3o`@6eGHDtC7Jno3@)VwIho0cC8-Rq
zDVZe<u6ZS?MGA=uWr;bZsS3&Yxdn+OnMpaR3gww48497rsYQCB!LC7mj=rw(Zl10_
zE)4EP`K1LAQlTKVC^xgXI5R)57$Q>4;E|u3%HW%rmzbWakPcP~<&+ku7BToIWu+#U
zKq(aM0Z2w6u@#CF%TiPH7y@!q6N^C(EGkM(E>S4SNL5HJD#|ZXNJ`DgFUKukOtgaF
z#IjU|kc`Y?h_e+^@>7cy^72a*QY$ixOCT~JKVX%B1Yd4qr9yIkUP)qRo<e?JPNhOl
zYDr0IQL&CfUTJPpYEiL5VqS`ZgT9`=w!W@@yh3tDVo_o;NQE8)D5$}NLS{;8UP)#e
zD3U-C29iJtDUd*3Vs0u}bumLeI7k&dT^OoCqO}T80dNEs6lLZn7F8-_r&cOdXQx)y
zqPbp=A)qK96eYTzDY{{)MWCp(Qb@^4%uCPLO)pI>O36&jQ!vys;tEPF$S*3<^({`%
zOwn~JO)u6B$+uGA3h>trN-fI->C<&dEJ?LeFfuSQ)-^QLHLz4Lw6roX&^0hKFyQh@
zEH2RvDN4*M&PgoEFS1ey$<IB!@aRH?u*96yyplu(o09z8#A1ic+{C=hl1#n)qI5eh
zUr%3GgsTko47i;0^GZ_lN_0ai3sS8VN>VFI^b2wlGxMy$VOgA7VjCLbrfY#v2eL6O
zwMf@BFF8LYGcVmr!6GTMgv%!}FTFG|J=IDfxtJ>;r?e<BN7pUCD7V;3A+G?;Ew(kb
zR)8>VHS%n24HfJa3>2&s@>C5C>}-t`)YQOC8(R|)Qv)PyU}I>YP*VdI2dOd8RIpbt
zRIpMo(zND^fcri*MK`n<>=bA?7v&eHmXsta80eYn8FMi>W+$gYvT1gHSz-x8XhBh8
zS!M}?0z+_iX+dUQB7=WH(cy(<c}HgF9bT(Y3>JjSRWi8b=N?@T(*u<(h4V{~?#nDo
zEJ@8t1?R!+5>&H5NhiCc6h#n)qfnZYe{^4JULrW*6dzujtD{f~a-TwSMrBf|Lf+xE
zNB5;-m8>LAG8AM%W(h+`Vo5&K`H2d7so+dlnw82BlA2eNuK@Q4iWEpoMt(|Oeo3N2
z?$Px}_oXW2Clx1VfPzt>AiuOKRiWVU+Tz^QyhI&^BfW>$7Uv`?Br4<`URa!yno^o|
zcy03GwF*^viP@D_h-}Ib3JWv_uiV2c^N?&$RVY(%&d5*7FUiYH&SXG|7q}Ba(NUaQ
v1j?MK%Hif7UdiC;0?xPKz)#9b%`Q=Z=H_CB?3}}EkMySILNhQTEc6%v#l}fR

literal 0
HcmV?d00001

diff --git a/shared/locale/cs_CZ/LC_MESSAGES/django.po b/shared/locale/cs_CZ/LC_MESSAGES/django.po
new file mode 100644
index 0000000..5b50947
--- /dev/null
+++ b/shared/locale/cs_CZ/LC_MESSAGES/django.po
@@ -0,0 +1,26 @@
+# Czech translation of django-guardian.
+# This file is distributed under the same license as django-guardian's package.
+# Translator: Tomáš Valenta <tomas@imaniti.org>, 2023.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: django-guardian 1.2\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-11-09 19:00+0100\n"
+"PO-Revision-Date: 2023-11-09 19:00-0600\n"
+"Last-Translator: Tomáš Valenta <tomas@imaniti.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: cs\n"
+"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+"X-Translated-Using: django-rosetta 0.7.3\n"
+
+#: admin.py:21
+msgid "Duplicate"
+msgstr "Duplikovat"
+
+#: admin.py:70
+#, python-brace-format
+msgid "{name} object with primary key {key} does not exist."
+msgstr "Objekt {name} s klíčem {key} neexistuje."
diff --git a/ucebnice/settings/base.py b/ucebnice/settings/base.py
index 792f93d..9df63b0 100644
--- a/ucebnice/settings/base.py
+++ b/ucebnice/settings/base.py
@@ -51,6 +51,7 @@ INSTALLED_APPS = [
     "django.contrib.sessions",
     "django.contrib.messages",
     "django.contrib.staticfiles",
+    "modelclone",
     "dbsettings",
     "markdownx",
     "pirates",
-- 
GitLab