Skip to content

Commit 0dfb4b5

Browse files
authored
Merge pull request #33 from DataManagementLab/#8_Frontend_Allow_to_edit_course_description_and_image
#8 frontend allow to edit course description and image
2 parents 0a51cde + 0ef68c4 commit 0dfb4b5

7 files changed

Lines changed: 114 additions & 17 deletions

File tree

collab_coursebook/settings.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,3 +166,5 @@
166166
"impress_text": "",
167167
"impress_url": ""
168168
}
169+
170+
ALLOW_PUBLIC_COURSE_EDITING_BY_EVERYONE = True

frontend/locale/de_DE/LC_MESSAGES/django.po

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,23 +50,23 @@ msgstr "Abbrechen"
5050
msgid "Actions"
5151
msgstr "Aktionen"
5252

53-
#: frontend/templates/frontend/content/detail.html:43
53+
#: frontend/templates/frontend/content/detail.html:46
5454
msgid "Back to course "
5555
msgstr "Zurück zum Kurs "
5656

57-
#: frontend/templates/frontend/content/detail.html:49
57+
#: frontend/templates/frontend/content/detail.html:52
5858
msgid "By"
5959
msgstr "Von"
6060

61-
#: frontend/templates/frontend/content/detail.html:59
61+
#: frontend/templates/frontend/content/detail.html:62
6262
msgid "Created at"
6363
msgstr "Erstellt am"
6464

65-
#: frontend/templates/frontend/content/detail.html:67
65+
#: frontend/templates/frontend/content/detail.html:70
6666
msgid "Delete"
6767
msgstr "Löschen"
6868

69-
#: frontend/templates/frontend/content/detail.html:71
69+
#: frontend/templates/frontend/content/detail.html:74
7070
#, python-format
7171
msgid ""
7272
"\n"
@@ -80,30 +80,55 @@ msgstr ""
8080
" "
8181

8282
#: frontend/templates/frontend/content/detail.html:83
83+
#: frontend/templates/frontend/course/create.html:30
84+
#: frontend/templates/frontend/course/edit.html:30
85+
#: frontend/templates/frontend/profile/profile_edit.html:19
86+
msgid "Cancel"
87+
msgstr "Abbrechen"
88+
89+
#: frontend/templates/frontend/content/detail.html:86
8390
msgid "Confirm"
8491
msgstr "Bestätigen"
8592

86-
#: frontend/templates/frontend/content/detail.html:99
93+
#: frontend/templates/frontend/content/detail.html:102
8794
#: frontend/templates/frontend/course/topic_contents.html:29
8895
msgid "Rating"
8996
msgstr "Bewertung"
9097

91-
#: frontend/templates/frontend/content/detail.html:109
98+
#: frontend/templates/frontend/content/detail.html:112
9299
msgid "Comments"
93100
msgstr "Kommentare"
94101

95-
#: frontend/templates/frontend/content/detail.html:115
102+
#: frontend/templates/frontend/content/detail.html:118
96103
msgid "Add comment"
97104
msgstr "Kommentar hinzufügen"
98105

99106
#: frontend/templates/frontend/course/create.html:11
100107
msgid "Create a new course"
101108
msgstr "Neuen Kurs anlegen"
102109

110+
#: frontend/templates/frontend/course/create.html:29
111+
#: frontend/templates/frontend/course/edit.html:29
112+
msgid "Create"
113+
msgstr "Erzeugen"
114+
103115
#: frontend/templates/frontend/course/dropdown_topic.html:10
104116
msgid "Add Content"
105117
msgstr "Inhalte hinzufügen"
106118

119+
#: frontend/templates/frontend/course/edit.html:11
120+
msgid "Edit course"
121+
msgstr "Kurs bearbeiten"
122+
123+
#: frontend/templates/frontend/course/view.html:26
124+
msgid "Edit Course"
125+
msgstr "Kurs hinzufügen"
126+
127+
#: frontend/templates/frontend/course/view.html:27
128+
msgid "Delete Course"
129+
msgstr "Kurs löschen"
130+
131+
#: frontend/templates/frontend/course/view.html:63
107132
#: frontend/templates/frontend/course/view.html:78
108133
msgid "No topics yet"
109134
msgstr "Bisher keine Themen"
@@ -236,6 +261,10 @@ msgstr "Es trat ein Fehler beim Verarbeiten der Anfrage auf"
236261
msgid "Course '{cleaned_data['title']}' successfully created"
237262
msgstr "Kurs '{cleaned_data['title']}' erfolgreich angelegt"
238263

264+
#: frontend/views/course.py:52
265+
msgid "Course '{cleaned_data['title']}' successfully edited"
266+
msgstr "Kurs '{cleaned_data['title']}' erfolgreich bearbeitet"
267+
239268
#: frontend/views/profile.py:25
240269
msgid "Profile updated"
241270
msgstr "Profil aktualisiert"
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{% extends 'frontend/base_logged_in.html' %}
2+
3+
{# Load the tag library #}
4+
{% load bootstrap4 %}
5+
{% load i18n %}
6+
{% load static %}
7+
{% load fontawesome_5 %}
8+
9+
{# Load CSS and JavaScript #}
10+
11+
{% block title %}{% trans "Edit course" %} - Collab Coursebook{% endblock %}
12+
13+
{% block imports %}
14+
<link rel="stylesheet" href="{% static 'vendor/chosen-js/chosen.css' %}">
15+
<link rel="stylesheet" href="{% static 'css/bootstrap-chosen.css' %}">
16+
{% endblock %}
17+
18+
{% block content %}
19+
<h1>Edit Course</h1>
20+
21+
<form method="post" enctype=multipart/form-data>
22+
{% csrf_token %}
23+
24+
{% bootstrap_form form %}
25+
26+
{{ form.media }}
27+
<div>
28+
29+
<button type="submit" class="btn btn-primary float-right">{% fa5_icon 'plus-circle' 'fas' %} {% trans "Create" %}</button>
30+
<a href="{% url 'frontend:dashboard' %}" class="btn btn-danger">{% fa5_icon 'times' 'fas' %} {% trans "Cancel" %}</a>
31+
</div>
32+
</form>
33+
{% endblock %}
34+
35+
{% block bottom_script %}
36+
<script src="{% static 'vendor/chosen-js/chosen.jquery.js' %}"></script>
37+
<script>
38+
$(function () {
39+
$('.chosen-select').chosen();
40+
});
41+
</script>
42+
{% endblock %}

frontend/templates/frontend/course/view.html

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
{% block content %}
2020
<!-- Course markings and actions -->
21-
2221
<div class="float-right text-right">
2322
<div class="dropdown show">
2423
<button class="btn btn-primary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
@@ -28,21 +27,20 @@
2827
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenuLink">
2928
{% if user.is_authenticated %}
3029
<a class="dropdown-item" href="{# url 'favourite_content' course.id topic.id content.id ?onDetailPage=True#}">
31-
{% if favourite %}{% fa5_icon 'bookmark' 'fas' %} Unsave {% else %}{% fa5_icon 'bookmark' 'far' %} Save{% endif %}</a>
30+
{% if course in user.profile.stared_courses.all %}{% fa5_icon 'bookmark' 'fas' %} Unsave {% else %}{% fa5_icon 'bookmark' 'far' %} Save{% endif %}</a>
3231

3332
<div class="dropdown-divider"></div>
3433

35-
{% if isCurrentUserOwner or user.is_superuser or content.author == user %}
36-
<a href="{% url 'frontend:course-delete' pk=course.pk %}" class="dropdown-item text-danger"
37-
>{% fa5_icon 'trash' 'fas' %} Delete</a>
34+
{% if user|check_edit_course_permission:course %}
35+
<a href="{% url 'frontend:course-edit' pk=course.pk %}" class="dropdown-item">{% fa5_icon "pencil-alt" "fas" %} {% trans "Edit Course" %}</a>
36+
<a href="{% url 'frontend:course-delete' pk=course.pk %}" class="dropdown-item">{% fa5_icon "trash" "fas" %} {% trans "Delete Course" %}</a>
3837
{% endif %}
3938
{% endif %}
4039

4140
</div>
4241
</div>
4342
</div>
4443

45-
4644
<!-- Course header: Title, owners, description -->
4745
<h1>{{ course.title }}</h1>
4846

@@ -92,7 +90,8 @@ <h5 style="margin-top: 20px;">
9290
{% with entry.topic as topic_replace %}
9391
{% add_content_button user course.id topic_replace.id %}
9492
{% endwith %}
95-
<h3 class="text-info">{{ outer_index }}. {{ topic.title }}</h3>
93+
<h3 class="text-info">{{ outer_index }}. {{ entry.topic.title }}</h3>
94+
9695
{% with entry.topic.contents.all as topic_contents %}
9796
{% include "frontend/course/topic_contents.html" %}
9897
{% endwith %}

frontend/templatetags/cc_frontend_tags.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from django import template
22
from django.conf import settings
33

4+
from collab_coursebook.settings import ALLOW_PUBLIC_COURSE_EDITING_BY_EVERYONE
45
from content.models import CONTENT_TYPES
56

67
register = template.Library()
@@ -88,6 +89,13 @@ def content_card(type):
8889
return "content/cards/blank.html"
8990

9091

92+
@register.filter
93+
def check_edit_course_permission(user, course):
94+
# either an user is an owner or the course is public and it is allowed to edit public courses
95+
return (user.profile in course.owners.all()) or (not course.restrict_changes
96+
and ALLOW_PUBLIC_COURSE_EDITING_BY_EVERYONE)
97+
98+
9199
@register.filter
92100
def is_content_editable(type):
93101
# TODO: implement check

frontend/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
path('', views.CourseListView.as_view(), name='courses'),
1919
path('<int:pk>/', include([
2020
path('', views.CourseView.as_view(), name='course'),
21+
path('edit/', views.course.EditCourseView.as_view(), name='course-edit'),
2122
path('delete/', views.CourseDeleteView.as_view(), name='course-delete'),
2223
])),
2324
path('<int:course_id>/topic/<int:topic_id>/content/', include([

frontend/views/course.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
from django.contrib.messages.views import SuccessMessageMixin
44
from django.contrib import messages
55
from django.http import HttpResponseRedirect
6-
from django.urls import reverse_lazy
6+
from django.urls import reverse_lazy, reverse
77
from django.views.generic import DetailView
8-
from django.views.generic.edit import FormMixin, CreateView, DeleteView
8+
from django.views.generic.edit import FormMixin, CreateView, DeleteView, UpdateView
99
from django.utils.translation import gettext_lazy as _
1010

1111
from base.models import Course, CourseStructureEntry
@@ -36,6 +36,22 @@ def get_initial(self):
3636
return initial
3737

3838

39+
class EditCourseView(SuccessMessageMixin, LoginRequiredMixin, UpdateView):
40+
"""
41+
Edit course
42+
"""
43+
model = Course
44+
template_name = 'frontend/course/edit.html'
45+
form_class = AddAndEditCourseForm
46+
47+
def get_success_url(self):
48+
course_id = self.get_object().id
49+
return reverse('frontend:course', args=(course_id,))
50+
51+
def get_success_message(self, cleaned_data):
52+
return _(f"Course '{cleaned_data['title']}' successfully edited")
53+
54+
3955
class CourseView(DetailView, FormMixin): # pylint: disable=too-many-ancestors
4056
"""
4157
Displays the course detail page

0 commit comments

Comments
 (0)