Commit b9b9f388 by Waheed Ahmed

Course run list widget.

ECOM-6043
parent 57945628
...@@ -182,6 +182,10 @@ class Course(TimeStampedModel, ChangedByMixin): ...@@ -182,6 +182,10 @@ class Course(TimeStampedModel, ChangedByMixin):
for user_role in organization.organization_user_roles.all(): for user_role in organization.organization_user_roles.all():
CourseUserRole.add_course_roles(self, user_role.role, user_role.user) CourseUserRole.add_course_roles(self, user_role.role, user_role.user)
@property
def course_runs(self):
return self.publisher_course_runs.order_by('-created')
class CourseRun(TimeStampedModel, ChangedByMixin): class CourseRun(TimeStampedModel, ChangedByMixin):
""" Publisher CourseRun model. It contains fields related to the course run intake form.""" """ Publisher CourseRun model. It contains fields related to the course run intake form."""
...@@ -292,6 +296,10 @@ class CourseRun(TimeStampedModel, ChangedByMixin): ...@@ -292,6 +296,10 @@ class CourseRun(TimeStampedModel, ChangedByMixin):
def post_back_url(self): def post_back_url(self):
return reverse('publisher:publisher_course_runs_edit', kwargs={'pk': self.id}) return reverse('publisher:publisher_course_runs_edit', kwargs={'pk': self.id})
@property
def created_by(self):
return self.history.order_by('history_date').first().history_user # pylint: disable=no-member
class Seat(TimeStampedModel, ChangedByMixin): class Seat(TimeStampedModel, ChangedByMixin):
""" Seat model. """ """ Seat model. """
......
...@@ -59,6 +59,17 @@ class CourseRunTests(TestCase): ...@@ -59,6 +59,17 @@ class CourseRunTests(TestCase):
with self.assertRaises(TransitionNotAllowed): with self.assertRaises(TransitionNotAllowed):
self.course_run.change_state(target=State.PUBLISHED) self.course_run.change_state(target=State.PUBLISHED)
def test_created_by(self):
""" Verify that property returns created_by. """
self.assertIsNone(self.course_run.created_by)
user = UserFactory()
history_object = self.course_run.history.first()
history_object.history_user = user
history_object.save()
self.assertEqual(self.course_run.created_by, user)
class CourseTests(TestCase): class CourseTests(TestCase):
""" Tests for the publisher `Course` model. """ """ Tests for the publisher `Course` model. """
...@@ -191,6 +202,14 @@ class CourseTests(TestCase): ...@@ -191,6 +202,14 @@ class CourseTests(TestCase):
self.course2.assign_organization_role(self.org_extension_2.organization) self.course2.assign_organization_role(self.org_extension_2.organization)
self.assertFalse(self.course2.course_user_roles.all()) self.assertFalse(self.course2.course_user_roles.all())
def test_course_runs(self):
""" Verify that property returns queryset of course runs. """
self.assertEqual(self.course.course_runs.count(), 0)
factories.CourseRunFactory(course=self.course)
self.assertEqual(self.course.course_runs.count(), 1)
class SeatTests(TestCase): class SeatTests(TestCase):
""" Tests for the publisher `Seat` model. """ """ Tests for the publisher `Seat` model. """
......
...@@ -1512,6 +1512,20 @@ class CourseDetailViewTests(TestCase): ...@@ -1512,6 +1512,20 @@ class CourseDetailViewTests(TestCase):
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['can_edit'], can_edit) self.assertEqual(response.context['can_edit'], can_edit)
def test_details_page_with_course_runs(self):
""" Test that user can see course runs on course detail page. """
self.user.groups.add(self.organization_extension.group)
assign_perm(OrganizationExtension.VIEW_COURSE, self.organization_extension.group, self.organization_extension)
course_run = factories.CourseRunFactory(course=self.course)
response = self.client.get(self.detail_page_url)
self.assertContains(response, 'COURSE RUNS')
self.assertContains(response, 'ADD RUN')
self.assertContains(response, 'STUDIO URL -')
self.assertContains(response, 'Not yet created')
self.assertContains(response, reverse('publisher:publisher_course_run_detail', kwargs={'pk': course_run.id}))
class CourseEditViewTests(TestCase): class CourseEditViewTests(TestCase):
""" Tests for the course edit view. """ """ Tests for the course edit view. """
......
...@@ -280,7 +280,6 @@ class CourseDetailView(mixins.LoginRequiredMixin, mixins.PublisherPermissionMixi ...@@ -280,7 +280,6 @@ class CourseDetailView(mixins.LoginRequiredMixin, mixins.PublisherPermissionMixi
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(CourseDetailView, self).get_context_data(**kwargs) context = super(CourseDetailView, self).get_context_data(**kwargs)
context['comment_object'] = self
context['can_edit'] = mixins.check_course_organization_permission( context['can_edit'] = mixins.check_course_organization_permission(
self.request.user, self.object, OrganizationExtension.EDIT_COURSE self.request.user, self.object, OrganizationExtension.EDIT_COURSE
) )
......
...@@ -7,14 +7,14 @@ msgid "" ...@@ -7,14 +7,14 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-01-10 13:00+0500\n" "POT-Creation-Date: 2017-01-11 19:39+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Language: \n"
#: apps/api/filters.py #: apps/api/filters.py
#, python-brace-format #, python-brace-format
...@@ -1254,10 +1254,38 @@ msgid "Dashboard" ...@@ -1254,10 +1254,38 @@ msgid "Dashboard"
msgstr "" msgstr ""
#: templates/publisher/base.html templates/publisher/courses.html #: templates/publisher/base.html templates/publisher/courses.html
#: templates/publisher/view_course_form.html
msgid "Courses" msgid "Courses"
msgstr "" msgstr ""
#: templates/publisher/course_detail/_widgets.html
#: templates/publisher/course_run_detail/_approval_widget.html
msgid "EDIT"
msgstr ""
#: templates/publisher/course_detail/_widgets.html
msgid "COURSE RUNS"
msgstr ""
#: templates/publisher/course_detail/_widgets.html
msgid "ADD RUN"
msgstr ""
#: templates/publisher/course_detail/_widgets.html
#, python-format
msgid ""
"\n"
" Created %(created_date)s at %(created_time)s by %(created_by)s\n"
" "
msgstr ""
#: templates/publisher/course_detail/_widgets.html
msgid "STUDIO URL"
msgstr ""
#: templates/publisher/course_detail/_widgets.html
msgid "Not yet created"
msgstr ""
#: templates/publisher/course_form.html #: templates/publisher/course_form.html
msgid "UPDATE COURSE" msgid "UPDATE COURSE"
msgstr "" msgstr ""
...@@ -1440,11 +1468,6 @@ msgid "Additional Notes" ...@@ -1440,11 +1468,6 @@ msgid "Additional Notes"
msgstr "" msgstr ""
#: templates/publisher/course_run_detail/_approval_widget.html #: templates/publisher/course_run_detail/_approval_widget.html
#: templates/publisher/view_course_form.html
msgid "EDIT"
msgstr ""
#: templates/publisher/course_run_detail/_approval_widget.html
msgid "change owner" msgid "change owner"
msgstr "" msgstr ""
......
...@@ -7,14 +7,14 @@ msgid "" ...@@ -7,14 +7,14 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-01-10 13:00+0500\n" "POT-Creation-Date: 2017-01-11 19:39+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Language: \n"
#: static/js/catalogs-change-form.js #: static/js/catalogs-change-form.js
msgid "Preview" msgid "Preview"
......
...@@ -7,14 +7,14 @@ msgid "" ...@@ -7,14 +7,14 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-01-10 13:00+0500\n" "POT-Creation-Date: 2017-01-11 19:39+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Language: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: apps/api/filters.py #: apps/api/filters.py
...@@ -1525,10 +1525,41 @@ msgid "Dashboard" ...@@ -1525,10 +1525,41 @@ msgid "Dashboard"
msgstr "Däshßöärd Ⱡ'σяєм ιρѕυм ∂σł#" msgstr "Däshßöärd Ⱡ'σяєм ιρѕυм ∂σł#"
#: templates/publisher/base.html templates/publisher/courses.html #: templates/publisher/base.html templates/publisher/courses.html
#: templates/publisher/view_course_form.html
msgid "Courses" msgid "Courses"
msgstr "Çöürsés Ⱡ'σяєм ιρѕυм #" msgstr "Çöürsés Ⱡ'σяєм ιρѕυм #"
#: templates/publisher/course_detail/_widgets.html
#: templates/publisher/course_run_detail/_approval_widget.html
msgid "EDIT"
msgstr "ÉDÌT Ⱡ'σяєм ι#"
#: templates/publisher/course_detail/_widgets.html
msgid "COURSE RUNS"
msgstr "ÇÖÛRSÉ RÛNS Ⱡ'σяєм ιρѕυм ∂σłσя #"
#: templates/publisher/course_detail/_widgets.html
msgid "ADD RUN"
msgstr "ÀDD RÛN Ⱡ'σяєм ιρѕυм #"
#: templates/publisher/course_detail/_widgets.html
#, python-format
msgid ""
"\n"
" Created %(created_date)s at %(created_time)s by %(created_by)s\n"
" "
msgstr ""
"\n"
" Çréätéd %(created_date)s ät %(created_time)s ßý %(created_by)s\n"
" Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя#"
#: templates/publisher/course_detail/_widgets.html
msgid "STUDIO URL"
msgstr "STÛDÌÖ ÛRL Ⱡ'σяєм ιρѕυм ∂σłσ#"
#: templates/publisher/course_detail/_widgets.html
msgid "Not yet created"
msgstr "Nöt ýét çréätéd Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт α#"
#: templates/publisher/course_form.html #: templates/publisher/course_form.html
msgid "UPDATE COURSE" msgid "UPDATE COURSE"
msgstr "ÛPDÀTÉ ÇÖÛRSÉ Ⱡ'σяєм ιρѕυм ∂σłσя ѕι#" msgstr "ÛPDÀTÉ ÇÖÛRSÉ Ⱡ'σяєм ιρѕυм ∂σłσя ѕι#"
...@@ -1718,11 +1749,6 @@ msgid "Additional Notes" ...@@ -1718,11 +1749,6 @@ msgid "Additional Notes"
msgstr "Àddïtïönäl Nötés Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αм#" msgstr "Àddïtïönäl Nötés Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αм#"
#: templates/publisher/course_run_detail/_approval_widget.html #: templates/publisher/course_run_detail/_approval_widget.html
#: templates/publisher/view_course_form.html
msgid "EDIT"
msgstr "ÉDÌT Ⱡ'σяєм ι#"
#: templates/publisher/course_run_detail/_approval_widget.html
msgid "change owner" msgid "change owner"
msgstr "çhängé öwnér Ⱡ'σяєм ιρѕυм ∂σłσя ѕ#" msgstr "çhängé öwnér Ⱡ'σяєм ιρѕυм ∂σłσя ѕ#"
......
...@@ -7,14 +7,14 @@ msgid "" ...@@ -7,14 +7,14 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-01-10 13:00+0500\n" "POT-Creation-Date: 2017-01-11 19:39+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Language: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/js/catalogs-change-form.js #: static/js/catalogs-change-form.js
......
...@@ -241,7 +241,8 @@ $light-gray: rgba(204, 204, 204, 1); ...@@ -241,7 +241,8 @@ $light-gray: rgba(204, 204, 204, 1);
.layout-col-container { .layout-col-container {
@include padding(20px, 20px, 20px, 20px); @include padding(20px, 20px, 20px, 20px);
width: 78%; @include margin-right(0);
width: 80%;
} }
.menu-list { .menu-list {
...@@ -266,6 +267,16 @@ $light-gray: rgba(204, 204, 204, 1); ...@@ -266,6 +267,16 @@ $light-gray: rgba(204, 204, 204, 1);
} }
} }
} }
.layout-col-a-custom {
@include margin-left(0);
width: 50%;
}
.layout-col-b-custom {
@include margin-right(0);
width: 50%;
}
} }
.tabs { .tabs {
...@@ -646,7 +657,7 @@ select { ...@@ -646,7 +657,7 @@ select {
display: none; display: none;
} }
.approval-widget { .approval-widget, .course-widgets {
.btn-course-edit, .btn-courserun-edit { .btn-course-edit, .btn-courserun-edit {
@include padding(2px, 20px, 3px, 20px); @include padding(2px, 20px, 3px, 20px);
...@@ -654,6 +665,7 @@ select { ...@@ -654,6 +665,7 @@ select {
font-weight: 400; font-weight: 400;
font-size: 14px; font-size: 14px;
background: white; background: white;
border-color: black;
border-radius: 5px; border-radius: 5px;
&:hover, &:focus { &:hover, &:focus {
...@@ -698,9 +710,11 @@ select { ...@@ -698,9 +710,11 @@ select {
} }
} }
.btn-course-edit { .btn-course-edit, .btn-courserun-edit {
@include padding(2px, 20px, 3px, 20px); @include padding(2px, 20px, 3px, 20px);
@include float(right); @include float(right);
background-color: #169bd5;
border-color: #169bd5;
font-weight: 400; font-weight: 400;
font-size: 14px; font-size: 14px;
border-radius: 5px; border-radius: 5px;
...@@ -709,6 +723,16 @@ select { ...@@ -709,6 +723,16 @@ select {
.btn-course-add { .btn-course-add {
@include padding(4px, 20px, 4px, 20px); @include padding(4px, 20px, 4px, 20px);
@include margin-left(12px); @include margin-left(12px);
background-color: #169bd5;
border-color: #169bd5;
border-radius: 5px;
}
.btn-courserun-add {
@include padding(3px, 16px, 3px, 16px);
@include margin-left(10px);
background-color: #169bd5;
border-color: #169bd5;
border-radius: 5px; border-radius: 5px;
} }
...@@ -718,6 +742,10 @@ select { ...@@ -718,6 +742,10 @@ select {
font-size: 24px; font-size: 24px;
} }
.course-runs-heading {
display: inline-block;
}
.coursesTable { .coursesTable {
@include padding(20px, 20px, 20px, 20px); @include padding(20px, 20px, 20px, 20px);
border: 2px solid #169bd5; border: 2px solid #169bd5;
...@@ -742,7 +770,35 @@ select { ...@@ -742,7 +770,35 @@ select {
} }
.btn-save { .btn-save {
background-color: #169BD5; background-color: #169BD5;
border-radius: 5px; border-radius: 5px;
padding: 10px; padding: 10px;
}
.course-run-list {
.layout-reversed.course-run-item {
margin-bottom: 5px;
font-size: 14px;
.created-by {
@include margin(0, 0, 0, 0);
width: 25%;
font-size: 12px;
}
.course-run-details {
@include margin(0, 0, 0, 0);
width: 75%;
}
}
}
.studio-url-heading {
color: #999999;
font-weight: 600;
}
.studio-link, .courserun-detail-link {
text-decoration: underline;
} }
{% load i18n %}
<div class="course-widgets">
{% if can_edit %}
<a href="{% url 'publisher:publisher_courses_edit' pk=object.id %}" class="btn btn-neutral btn-courserun-edit">
{% trans "EDIT" %}
</a>
<div class="clearfix"></div>
{% endif %}
<div class="margin-top20">
<h5 class="hd-5 emphasized course-runs-heading">{% trans "COURSE RUNS" %}</h5>
<a href="{% url 'publisher:publisher_course_runs_new' parent_course_id=object.id %}" class="btn btn-brand btn-small btn-courserun-add">
{% trans "ADD RUN" %}
</a>
</div>
<div class="course-run-list">
{% for course_run in course.course_runs %}
<div class="layout-1t2t layout-reversed course-run-item">
<div class="layout-col layout-col-a created-by">
{% blocktrans with created_date=course_run.created.date created_time=course_run.created.time created_by=course_run.created_by.full_name %}
Created {{ created_date }} at {{ created_time }} by {{ created_by }}
{% endblocktrans %}
</div>
<div class="layout-col layout-col-b course-run-details">
<div class="courserun-details">
<a class="courserun-detail-link" href="{% url 'publisher:publisher_course_run_detail' pk=course_run.id %}">
{{ course_run.start.date }} - {{ course_run.get_pacing_type_display }}
</a>
</div>
<div class="studio-url">
<span class="studio-url-heading">{% trans "STUDIO URL" %} - </span>
{% if course_run.lms_course_id %}
<a class="studio-link" href="">{{ course_run.lms_course_id }}</a>
{% else %}
{% trans "Not yet created" %}
{% endif %}
</div>
</div>
</div>
{% endfor %}
</div>
</div>
...@@ -7,45 +7,44 @@ ...@@ -7,45 +7,44 @@
{% block page_content %} {% block page_content %}
{% include 'alert_messages.html' %} {% include 'alert_messages.html' %}
<div class="approval-widget"> <div class="layout-1t2t layout-flush publisher-container course-detail">
{% if can_edit %} <main class="layout-col layout-col-b layout-col-b-custom">
<a href="{% url 'publisher:publisher_courses_edit' pk=object.id %}" class="btn btn-neutral btn-course-edit"> <div class="layout-full layout">
{% trans "EDIT" %} <h2 class="layout-title">{% trans "Base information" %}</h2>
</a>
<div class="clearfix"></div>
{% endif %}
</div>
<div class="layout-full publisher-layout layout">
<h2 class="layout-title">{% trans "Base information" %}</h2>
<div class="card course-form"> <div class="card course-form">
<div class="course-information"> <div class="course-information">
<h4 class="hd-4">{% trans "Course Form" %}</h4> <h4 class="hd-4">{% trans "Course Form" %}</h4>
<fieldset class="form-group grid-container grid-manual"> <fieldset class="form-group grid-container grid-manual">
<div class="field-title">{% trans "INSTITUTION INFORMATION" %}</div> <div class="field-title">{% trans "INSTITUTION INFORMATION" %}</div>
<div class="row"> <div class="row">
<div class="col col-6"> <div class="col col-6">
{{ object.get_group_institution }} {{ object.get_group_institution }}
</div> </div>
</div>
</fieldset>
</div> </div>
</fieldset> </div>
</div> </div>
</div> <div class="layout-full layout">
</div> <h2 class="layout-title">{% trans "Course information" %}</h2>
<div class="layout-full layout"> <div class="card course-form">
<h2 class="layout-title">{% trans "Course information" %}</h2> <div class="course-information">
<div class="card course-form"> <fieldset class="form-group">
<div class="course-information"> <div class="field-row">
<fieldset class="form-group"> <div class="field-col">
<div class="field-row"> <label class="field-label " for="title">{{ course_form.title.label }}</label>
<div class="field-col"> {{ object.title }}
<label class="field-label " for="title">{{ course_form.title.label }}</label> </div>
{{ object.title }}
</div> </div>
</div> </fieldset>
</fieldset> </div>
</div> </div>
</div> </div>
</div> </main>
<aside class="layout-col layout-col-a layout-col-a-custom">
{% include 'publisher/course_detail/_widgets.html' %}
</aside>
</div>
{% endblock %} {% 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