Commit a025c2cf by Waheed Ahmed

Course edit page and Institution/Course admin widget.

ECOM-6488
ECOM-6055
parent 7da8b084
......@@ -29,6 +29,18 @@ class PersonModelMultipleChoice(forms.ModelMultipleChoiceField):
return str(render_to_string('publisher/_personFieldLabel.html', context=context))
class ClearableImageInput(forms.ClearableFileInput):
"""
ClearableFileInput render the saved image as link.
Render img tag instead of link and add some classes for JS and CSS, also
remove image link and clear checkbox.
"""
clear_checkbox_label = _('Remove Image')
template_with_initial = render_to_string('publisher/_clearableImageInput.html')
template_with_clear = render_to_string('publisher/_clearImageLink.html')
class BaseCourseForm(forms.ModelForm):
""" Base Course Form. """
......@@ -110,6 +122,9 @@ class CustomCourseForm(CourseForm):
class Meta(CourseForm.Meta):
model = Course
widgets = {
'image': ClearableImageInput()
}
fields = (
'title', 'number', 'short_description', 'full_description',
'expected_learnings', 'level_type', 'primary_subject', 'secondary_subject',
......@@ -118,11 +133,18 @@ class CustomCourseForm(CourseForm):
)
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
organization = kwargs.pop('organization', None)
if organization:
org_extension = OrganizationExtension.objects.get(organization=organization)
self.declared_fields['team_admin'].queryset = User.objects.filter(groups__name=org_extension.group)
if user:
self.declared_fields['organization'].queryset = Organization.objects.filter(
organization_extension__organization_id__isnull=False,
organization_extension__group__in=user.groups.all()
)
super(CustomCourseForm, self).__init__(*args, **kwargs)
......
......@@ -20,7 +20,7 @@ from course_discovery.apps.core.models import User
from course_discovery.apps.publisher.choices import PublisherUserRole
from course_discovery.apps.publisher.emails import send_email_for_course_creation
from course_discovery.apps.publisher.forms import (
CourseForm, SeatForm, CustomCourseForm, CustomCourseRunForm, CustomSeatForm, UpdateCourseForm
SeatForm, CustomCourseForm, CustomCourseRunForm, CustomSeatForm, UpdateCourseForm
)
from course_discovery.apps.publisher import mixins
from course_discovery.apps.publisher.models import (
......@@ -188,7 +188,7 @@ class CreateCourseView(mixins.LoginRequiredMixin, mixins.PublisherUserRequiredMi
def get_context_data(self):
return {
'course_form': self.course_form,
'course_form': self.course_form(user=self.request.user),
'run_form': self.run_form,
'seat_form': self.seat_form,
'publisher_hide_features_for_pilot': waffle.switch_is_active('publisher_hide_features_for_pilot'),
......@@ -204,7 +204,9 @@ class CreateCourseView(mixins.LoginRequiredMixin, mixins.PublisherUserRequiredMi
# pass selected organization to CustomCourseForm to populate related
# choices into institution admin field
organization = self.request.POST.get('organization')
course_form = self.course_form(request.POST, request.FILES, organization=organization)
course_form = self.course_form(
request.POST, request.FILES, user=self.request.user, organization=organization
)
run_form = self.run_form(request.POST)
seat_form = self.seat_form(request.POST)
if course_form.is_valid() and run_form.is_valid() and seat_form.is_valid():
......@@ -275,21 +277,62 @@ class CreateCourseView(mixins.LoginRequiredMixin, mixins.PublisherUserRequiredMi
return render(request, self.template_name, ctx, status=400)
class CourseEditView(mixins.PublisherPermissionMixin, mixins.FormValidMixin, UpdateView):
class CourseEditView(mixins.PublisherPermissionMixin, UpdateView):
""" Course Edit View."""
model = Course
form_class = CourseForm
form_class = CustomCourseForm
permission = OrganizationExtension.EDIT_COURSE
template_name = 'publisher/course_form.html'
template_name = 'publisher/course_edit_form.html'
success_url = 'publisher:publisher_course_detail'
def get_success_url(self):
return reverse(self.success_url, kwargs={'pk': self.object.id})
def get_context_data(self, **kwargs):
context = super(CourseEditView, self).get_context_data(**kwargs)
context['comment_object'] = self.object
return context
def get_form_kwargs(self):
"""
Pass extra kwargs to form, required for team_admin and organization querysets.
"""
kwargs = super(CourseEditView, self).get_form_kwargs()
request = self.request
if request.POST:
kwargs.update(
{'user': request.user, 'organization': request.POST.get('organization')}
)
else:
organization = self.object.organizations.first()
kwargs.update(
user=request.user,
organization=organization,
initial={
'organization': organization,
'team_admin': self.object.course_team_admin
}
)
return kwargs
def form_valid(self, form):
"""
If the form is valid, update organization and team_admin.
"""
self.object = form.save()
self.object.changed_by = self.request.user
self.object.save()
organization_extension = get_object_or_404(
OrganizationExtension, organization=form.data['organization']
)
self.object.organizations.remove(self.object.organizations.first())
self.object.organizations.add(organization_extension.organization)
course_admin_role = get_object_or_404(
CourseUserRole, course=self.object, role=PublisherUserRole.CourseTeam
)
course_admin_role.user_id = form.data['team_admin']
course_admin_role.save()
return super(CourseEditView, self).form_valid(form)
class CourseDetailView(mixins.LoginRequiredMixin, mixins.PublisherPermissionMixin, DetailView):
......
......@@ -40,22 +40,10 @@ class CommentsTests(TestCase):
toggle_switch('enable_publisher_email_notifications', True)
def test_course_edit_page_with_multiple_comments(self):
""" Verify course edit page can load multiple comments"""
self._add_assert_multiple_comments(self.course, self.course_edit_page)
def test_course_run_edit_page_with_multiple_comments(self):
""" Verify course-run edit page can load multiple comments"""
self._add_assert_multiple_comments(self.course_run, self.course_run_edit_page)
def test_comment_edit_with_course(self):
""" Verify that only comments attached with specific course appears on edited page. """
comments = self._generate_comments_for_all_content_types()
response = self.client.get(reverse(self.course_edit_page, kwargs={'pk': self.course.id}))
self.assertContains(response, comments.get(self.course).comment)
self.assertNotContains(response, comments.get(self.course_run).comment)
self.assertNotContains(response, comments.get(self.seat).comment)
def test_comment_edit_with_courserun(self):
""" Verify that only comments attached with specific course run appears on edited page. """
comments = self._generate_comments_for_all_content_types()
......
......@@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-01-25 12:05+0500\n"
"POT-Creation-Date: 2017-01-26 15:26+0500\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"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: \n"
#: static/js/catalogs-change-form.js
msgid "Preview"
......
......@@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-01-25 12:05+0500\n"
"POT-Creation-Date: 2017-01-26 15:26+0500\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"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/js/catalogs-change-form.js
......
......@@ -57,6 +57,25 @@ $(document).ready(function(){
renderSelectedInstructor(id, name, image_source);
});
$('.remove-image').click(function (e) {
e.preventDefault();
$('.course-image-input').removeClass('hidden');
$('.course-image-thumbnail').hide();
$('.course-image-field a').hide();
$('input#image-clear_id').prop('checked', true);
});
// If file selected mark checkbox unchecked otherwise checked.
$('input#id_image').change(function (e) {
var clearImageInput = $('input#image-clear_id');
e.preventDefault();
if (this.files && this.files[0]) {
clearImageInput.prop('checked', false);
} else {
clearImageInput.prop('checked', true);
}
});
});
$(document).on('change', '#id_organization', function (e) {
......@@ -80,7 +99,7 @@ function loadAdminUsers(org_id) {
teamAdminDropDown.append('<option selected="selected">---------</option>');
$.each(data.results, function (i, user) {
teamAdminDropDown.append($('<option> </option>').val(user.id).html(user.full_name));
teamAdminDropDown.append($('<option> </option>').val(user.id).html(user.full_name));
});
}
});
......
......@@ -120,3 +120,9 @@
.stopScroll{
overflow: hidden;
}
.course-edit-actions {
@include margin-right(10px);
@include text-align(right);
width: 100%;
}
......@@ -535,6 +535,10 @@ select {
}
}
}
textarea {
width: 100%;
}
}
.comments-container {
......@@ -820,7 +824,20 @@ select {
.course-image {
width: 480px;
height: 200px;
height: 250px;
}
.course-image-field {
.clear-image {
text-align: center;
margin-top: 10px;
width: 100%;
}
.course-image-thumbnail {
width: 100%;
height: 200px;
}
}
.selected-instructor {
......
<div class="clear-image">
<a class="remove-image" href="#">%(clear_checkbox_label)s</a>
<div class="hidden">%(clear)s</div>
</div>
<img class="course-image-thumbnail" src="%(initial_url)s">%(clear_template)s
<div class="course-image-input hidden">%(input)s</div>
{% extends 'publisher/base.html' %}
{% load i18n %}
{% block title %}
{% trans "Course Form" %}
{% endblock title %}
{% block page_content %}
<div class="layout-full layout publisher-layout">
<div class="publisher-container">
<div class="course-information">
<h4 class="hd-4">{% trans "Course Form" %}</h4>
<form class="form" method="post" action="" enctype="multipart/form-data">
{% csrf_token %}
<fieldset class="form-group">
{% for field in form %}
{% include "publisher/form_field.html" %}
{% endfor %}
</fieldset>
<a class="btn-cancel" href="{% url 'publisher:publisher_course_detail' course.id %}">{% trans "Cancel" %}</a>
<button class="btn-brand btn-base btn-save" type="submit">{% trans "UPDATE COURSE" %}</button>
</form>
</div>
<div class="comment-container">
{% if object.id %}
<a href="{% url 'publisher:publisher_course_runs_new' object.id %}" class="btn btn-neutral btn-add">
{% trans "Add Course Run" %}
</a>
{% endif %}
{% include 'comments/comments_list.html' %}
{% include 'comments/add_auth_comments.html' %}
</div>
</div>
</div>
{% endblock %}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment