Commit c0d6dd07 by Waheed Ahmed

Created dashboard for publisher.

ECOM-5174
parent 0c094888
......@@ -792,3 +792,29 @@ class CourseRunListViewTests(TestCase):
response = self.client.get(self.page_url)
self.assertEqual(response.status_code, 200)
def test_published_and_unpublished_course_runs(self):
""" Verify that user can access published and un-published course runs. """
# Create two courses with `DRAFT` and `NEEDS_REVIEW` state
draft_state = factories.StateFactory(name=State.DRAFT)
in_review_state = factories.StateFactory(name=State.NEEDS_REVIEW)
factories.CourseRunFactory(state=draft_state)
factories.CourseRunFactory(state=in_review_state)
response = self.client.get(self.page_url)
self.assertEqual(response.status_code, 200)
# Verify that we have 2 in progress and 0 published course runs
self.assertEqual(len(response.context['object_list']), 2)
self.assertEqual(len(response.context['published_courseruns']), 0)
# create a course with `PUBLISHED` state
published_state = factories.StateFactory(name=State.PUBLISHED)
factories.CourseRunFactory(state=published_state)
response = self.client.get(self.page_url)
self.assertEqual(response.status_code, 200)
# Verify that we have 2 in progress and 1 published course runs
self.assertEqual(len(response.context['object_list']), 2)
self.assertEqual(len(response.context['published_courseruns']), 1)
......@@ -14,7 +14,7 @@ from guardian.shortcuts import get_objects_for_user
from course_discovery.apps.publisher.forms import CourseForm, CourseRunForm, SeatForm
from course_discovery.apps.publisher import mixins
from course_discovery.apps.publisher.models import Course, CourseRun, Seat
from course_discovery.apps.publisher.models import Course, CourseRun, Seat, State
from course_discovery.apps.publisher.wrappers import CourseRunWrapper
......@@ -32,7 +32,18 @@ class CourseRunListView(mixins.LoginRequiredMixin, ListView):
courses = get_objects_for_user(self.request.user, Course.VIEW_PERMISSION, Course)
course_runs = CourseRun.objects.filter(course__in=courses).select_related('course').all()
return [CourseRunWrapper(course_run) for course_run in course_runs]
return course_runs
def get_context_data(self, **kwargs):
context = super(CourseRunListView, self).get_context_data(**kwargs)
course_runs = context.get('object_list')
published_courseruns = course_runs.filter(
state__name=State.PUBLISHED
).select_related('course').all().order_by('-state__modified')[:5]
unpublished_courseruns = course_runs.exclude(state__name=State.PUBLISHED)
context['object_list'] = [CourseRunWrapper(course_run) for course_run in unpublished_courseruns]
context['published_courseruns'] = [CourseRunWrapper(course_run) for course_run in published_courseruns]
return context
class CourseRunDetailView(mixins.LoginRequiredMixin, mixins.ViewPermissionMixin, DetailView):
......
......@@ -175,6 +175,7 @@ TEMPLATES = [
'django.template.context_processors.media',
'django.template.context_processors.static',
'django.template.context_processors.tz',
'django.template.context_processors.request',
'django.contrib.messages.context_processors.messages',
'course_discovery.apps.core.context_processors.core',
),
......
$(".administration-navbar .container > button").click(function(event) {
$(".administration-nav .tab-container > button").click(function(event) {
event.preventDefault();
$(this).addClass("selected");
$(this).siblings().removeClass("selected");
......
......@@ -6,7 +6,7 @@
// ------------------------------
// #RESET
// ------------------------------
$background-color: palette(grayscale, base) !default;
// ------------------------------
// #BASE
// ------------------------------
......@@ -14,7 +14,7 @@ html, body {
height: 100%;
margin: 0;
padding: 0;
background: $background-color;
background: $white;
}
// ------------------------------
......
......@@ -22,5 +22,5 @@
// #EXTENSIONS
// ------------------------------
@import "base";
@import 'publisher/course_detail';
@import 'publisher/course_form';
@import 'publisher/course_detail';
// ------------------------------
// // edX Course Discovery: Course Detail
// ------------------------------
$light-gray: rgba(204, 204, 204, 1);
// ------------------------------
// #TYPOGRAPHY
// ------------------------------
......@@ -13,10 +12,50 @@
margin-bottom: 10px;
}
.course-detail {
@include margin(0);
}
.container {
width: 1170px;
margin: auto;
overflow: auto;
.layout-header {
img, h1 {
padding: 20px;
@include float(left);
}
}
.layout, .layout-flush {
margin-left: 0;
margin-right: 0;
max-width: 100%;
.layout-col-menu {
padding-left: 0;
padding-right: 0;
}
.menu-list {
.item {
border-bottom: 2px solid $white;
margin-bottom: 0;
padding-bottom: 0;
a {
width: 100%;
height: 100%;
background: $light-gray;
border: 0;
border-radius: 0;
text-decoration: none;
&.active {
background: palette(primary, accent);
color: $white;
}
}
}
}
}
.tabs {
width: 100%;
......@@ -28,13 +67,13 @@
}
}
nav {
border-bottom: 2px solid #cacaca;
background-color: #f6f6f6;
.administration-nav {
font-size: 18px;
font-weight: 600;
display: inline-block;
margin: 5px 0 5px;
.container {
.tab-container {
button {
display: block;
......@@ -153,7 +192,7 @@ nav {
.page-header {
padding-bottom: 9px;
padding-top: 10px;
margin: 0 0 20px;
border-bottom: 1px solid #eeeeee;
......@@ -164,6 +203,10 @@ nav {
}
}
.publisher-footer {
padding: 20px;
}
.help-block {
display: block;
margin-top: 5px;
......@@ -198,3 +241,20 @@ nav {
font-size: 16px;
}
}
.border-left {
border-left: 1px solid;
}
.border-top {
border-top: 1px solid;
}
.empty-courserun-text {
padding: 100px 160px;
p {
padding: 0;
margin: 0;
}
}
// ------------------------------
// // edX Course Discovery: Course form
.course-form {
.publisher-container {
@include margin(20px);
overflow: auto;
......
......@@ -9,7 +9,7 @@
<head lang="{{ language_code }}">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}{% endblock title %}</title>
<title>{% block title %}{% endblock title %} | {{ platform_name }}</title>
<script type="text/javascript" language="javascript" src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="{% static 'bower_components/underscore/underscore.js' %}"></script>
<script src="{% static 'bower_components/moment/moment.js' %}"></script>
......@@ -35,9 +35,41 @@
</head>
<body>
{% block content %}
<div class="container">
<br>
{% include 'header.html' %}
<br>
<div class="layout-1q3q layout-flush border-top">
<main class="layout-col layout-col-a layout-col-menu">
<div class="institute-logo">
<img width="250" height="200" src="{% static 'images/institute-logo.png' %}">
</div>
<ul class="list-divided menu-list">
<li class="item">
{% url 'publisher:publisher_course_runs' as course_runs_url %}
<a class="btn {% if request.path == course_runs_url %}active{% endif %}" href="{{ course_runs_url }}">
{% trans "Course Runs" %}
</a>
</li>
<li class="item">
<a class="btn {% if request.path == new_course_url %}active{% endif %}" href="/publisher/course/">
{% trans "Courses" %}
</a>
</li>
</ul>
</main>
{% endblock content %}
<aside class="layout-col layout-col-b border-left">
{% block content %}
{% endblock content %}
</aside>
</div>
{% include 'footer.html' %}
</div>
{% block extra_js %}
......
......@@ -6,7 +6,7 @@
{% block content %}
<div class="layout-full layout">
<div class="card course-form">
<div class="publisher-container">
<h4 class="hd-4">{% trans "Edit Comment" %}</h4>
<form class="form" method="post" action="">
{% csrf_token %}
......
<footer class="publisher-footer border-top">
<p class="copy-base">
{% now "Y" as current_year %}
Copyright &copy; {{ current_year }} {{ platform_name }}.
</p>
</footer>
{% load staticfiles %}
<header class="header">
<div class="layout layout-header">
{% url 'publisher:publisher_course_runs' as course_runs_url %}
<a href="{{ course_runs_url }}">
<img src="{% static 'images/logo.png' %}">
</a>
</div>
</header>
......@@ -6,7 +6,7 @@
{% block content %}
<div class="layout-full layout">
<div class="card course-form">
<div class="publisher-container">
<div class="course-information">
<h4 class="hd-4">{% trans "Course Form" %}</h4>
<form class="form" method="post" action="">
......@@ -21,7 +21,7 @@
</div>
<div class="comment-container">
{% if object.id %}
<a href="{% url 'publisher:publisher_course_runs_new' %}" target="_blank" class="btn btn-neutral btn-add">
<a href="{% url 'publisher:publisher_course_runs_new' %}" class="btn btn-neutral btn-add">
{% trans "Add Course Run" %}
</a>
{% endif %}
......
......@@ -6,71 +6,69 @@
{% trans "Course Run Detail" %}
{% endblock title %}
{% block content %}
<nav class="administration-navbar">
<div class="container">
<button class="selected" data-tab="#tab-1">{% trans "All" %}</button>
<button data-tab="#tab-2">{% trans "STUDIO" %}</button>
<button data-tab="#tab-3">{% trans "CAT" %}</button>
<button data-tab="#tab-4">{% trans "DRUPAL" %}</button>
<button data-tab="#tab-5">{% trans "Salesforce" %}</button>
</div>
</nav>
<div id="app" class="container">
<ol class="breadcrumb">
<li><a href="{% url 'publisher:publisher_course_runs' %}">{% trans "Courses" %}</a></li>
<li class="active">{{ object.title }}</li>
</ol>
<div class="page-header">
<h2 class="hd-2 emphasized">
<span class="course-name">{{ object.title }}</span>
</h2>
</div>
<div class="alert-messages">
{% if messages %}
{% for message in messages %}
<div class="alert alert-{{ message.tags }}" role="alert" aria-labelledby="alert-title-{{ message.tags }}" tabindex="-1">
<div class="alert-message-with-action">
<p class="alert-copy">
{{ message }}
</p>
</div>
</div>
{% endfor %}
{% endif %}
</div>
<div class="status-information">
<div class="info-item">
<span class="item">
<span class="heading">{% trans "Status" %}:</span>
<span>{{ object.workflow_state }}</span>
</span>
<div class="publisher-container course-detail">
<nav class="administration-nav">
<div class="tab-container">
<button class="selected" data-tab="#tab-1">{% trans "All" %}</button>
<button data-tab="#tab-2">{% trans "STUDIO" %}</button>
<button data-tab="#tab-3">{% trans "CAT" %}</button>
<button data-tab="#tab-4">{% trans "DRUPAL" %}</button>
<button data-tab="#tab-5">{% trans "Salesforce" %}</button>
</div>
</div>
</nav>
<div class="tabs">
<div id="tab-1" class="tab-content active">
{% include 'publisher/course_run_detail/_all.html' %}
<div id="app">
<div class="page-header">
<h2 class="hd-2 emphasized">
<span class="course-name">{{ object.title }}</span>
</h2>
</div>
<div id="tab-2" class="tab-content">
{% include 'publisher/course_run_detail/_studio.html' %}
</div>
<div id="tab-3" class="tab-content">
{% include 'publisher/course_run_detail/_cat.html' %}
<div class="alert-messages">
{% if messages %}
{% for message in messages %}
<div class="alert alert-{{ message.tags }}" role="alert" aria-labelledby="alert-title-{{ message.tags }}" tabindex="-1">
<div class="alert-message-with-action">
<p class="alert-copy">
{{ message }}
</p>
</div>
</div>
{% endfor %}
{% endif %}
</div>
<div id="tab-4" class="tab-content">
{% include 'publisher/course_run_detail/_drupal.html' %}
<div class="status-information">
<div class="info-item">
<span class="item">
<span class="heading">{% trans "Status" %}:</span>
<span>{{ object.workflow_state }}</span>
</span>
</div>
</div>
<div id="tab-5" class="tab-content">
{% include 'publisher/course_run_detail/_salesforce.html' %}
<div class="tabs">
<div id="tab-1" class="tab-content active">
{% include 'publisher/course_run_detail/_all.html' %}
</div>
<div id="tab-2" class="tab-content">
{% include 'publisher/course_run_detail/_studio.html' %}
</div>
<div id="tab-3" class="tab-content">
{% include 'publisher/course_run_detail/_cat.html' %}
</div>
<div id="tab-4" class="tab-content">
{% include 'publisher/course_run_detail/_drupal.html' %}
</div>
<div id="tab-5" class="tab-content">
{% include 'publisher/course_run_detail/_salesforce.html' %}
</div>
</div>
</div>
<div class="actions">
<form action="{% url 'publisher:publisher_change_state' course_run_id=object.id %}" method="post"> {% csrf_token %}
<button type="submit" value="{{ object.change_state_button.value }}" class="btn-brand btn-small btn-states" name="state">{{ object.change_state_button.text }}</button>
</form>
<div class="actions">
<form action="{% url 'publisher:publisher_change_state' course_run_id=object.id %}" method="post"> {% csrf_token %}
<button type="submit" value="{{ object.change_state_button.value }}" class="btn-brand btn-small btn-states" name="state">{{ object.change_state_button.text }}</button>
</form>
</div>
</div>
</div>
{% endblock %}
......
......@@ -258,7 +258,7 @@
</div>
<div class="comment-container">
<a href="{% url 'publisher:publisher_course_runs_edit' pk=object.id %}" target="_blank" class="btn btn-neutral btn-add">
<a href="{% url 'publisher:publisher_course_runs_edit' pk=object.id %}" class="btn btn-neutral btn-add">
<span class="icon fa fa-edit" aria-hidden="true"></span>&nbsp;&nbsp;{% trans "Edit" %}
</a>
{% include 'comments/comments_list.html' %}
......
......@@ -23,5 +23,7 @@
{% include 'publisher/course_run_detail/_seats.html' %}
{% include 'publisher/course_run_detail/_credit_seat.html' %}
<div class="clearfix"></div>
{% endblock %}
......@@ -171,4 +171,5 @@
</div>
</div>
</div>
<div class="clearfix"></div>
{% endblock %}
......@@ -60,4 +60,5 @@
<div class="copy">{{ object.pacing_type }}</div>
</div>
</div>
<div class="clearfix"></div>
{% endblock %}
......@@ -6,7 +6,7 @@
{% block content %}
<div class="layout-full layout">
<div class="card course-form">
<div class="publisher-container">
<div class="course-information">
<h4 class="hd-4">{% trans "Course Run Form" %}</h4>
<div class="status-information">
......@@ -32,7 +32,7 @@
<div class="comment-container">
<span class="item">
{% if object.id %}
<a href="{% url 'publisher:publisher_seats_new' %}" target="_blank" class="btn btn-neutral btn-add">
<a href="{% url 'publisher:publisher_seats_new' %}" class="btn btn-neutral btn-add">
{% trans "Add Seat" %}
</a>
{% endif %}
......
......@@ -6,34 +6,82 @@
{% block content %}
<div class="layout-full layout">
<div class="card">
<h4 class="hd-4">{% trans "Course Run List" %}</h4>
<table class="table">
<tr>
<th>{% trans "Course Run Title" %}</th>
<th>{% trans "Course Run Start Date" %}</th>
<th>{% trans "Partner" %}</th>
<th>{% trans "Target Content?" %}</th>
<th>{% trans "Priority" %}</th>
<th>{% trans "Status" %}</th>
<th>{% trans "Last Updated" %}</th>
</tr>
{% for course_run in object_list %}
{% url 'publisher:publisher_course_run_detail' course_run.id as detail_url %}
<tr>
<td>
<a target="_blank" href="{{ detail_url }}">{{ course_run.title }}</a>
</td>
<td>{{ course_run.start }}</td>
<td>{{ course_run.partner }}</td>
<td>{{ course_run.target_content }}</td>
<td>{{ course_run.priority }}</td>
<td>{{ course_run.workflow_state }}</td>
<td>{{ course_run.modified }}</td>
</tr>
{% endfor %}
</table>
<div class="publisher-container">
<h2 class="hd-2 emphasized">{{ object_list|length }} {% trans "Course runs in progress" %}</h2>
<div class="depth depth-0">
{% if object_list|length_is:"0" %}
<div class="empty-courserun-text">
<p>{% trans "Welcome to edX Publisher. It looks like you don't have any courses." %}</p>
<p>
{% url 'publisher:publisher_courses_new' as new_course_url %}
{% with link_start='<a href="' link_middle='">' link_end='</a>' %}
{% blocktrans %}
Please {{ link_start }}{{ new_course_url }}{{ link_middle }}add a new course{{ link_end }} to create your first run
{% endblocktrans %}
{% endwith %}
</p>
</div>
{% else %}
<table class="table">
<tr>
<th>{% trans "Course Run Title" %}</th>
<th>{% trans "Course Run Start Date" %}</th>
<th>{% trans "Partner" %}</th>
<th>{% trans "Target Content?" %}</th>
<th>{% trans "Priority" %}</th>
<th>{% trans "Status" %}</th>
<th>{% trans "Last Updated" %}</th>
</tr>
{% for course_run in object_list %}
{% url 'publisher:publisher_course_run_detail' course_run.id as detail_url %}
<tr>
<td>
<a href="{{ detail_url }}">{{ course_run.title }}</a>
</td>
<td>{{ course_run.start }}</td>
<td>{{ course_run.partner }}</td>
<td>{{ course_run.target_content }}</td>
<td>{{ course_run.priority }}</td>
<td>{{ course_run.workflow_state }}</td>
<td>{{ course_run.modified }}</td>
</tr>
{% endfor %}
</table>
{% endif %}
</div>
<br>
<h2 class="hd-2 emphasized">{% trans "Recently published courses" %}</h2>
<div class="depth depth-0">
{% if published_courseruns|length_is:"0" %}
<p class="empty-courserun-text">{% trans "Looks like you haven't publish a course yet" %}</p>
{% else %}
<table class="table">
<tr>
<th>{% trans "Course Run Title" %}</th>
<th>{% trans "Course Run Start Date" %}</th>
<th>{% trans "Partner" %}</th>
<th>{% trans "Target Content?" %}</th>
<th>{% trans "Priority" %}</th>
<th>{% trans "Status" %}</th>
<th>{% trans "Last Updated" %}</th>
</tr>
{% for course_run in published_courseruns %}
{% url 'publisher:publisher_course_run_detail' course_run.id as detail_url %}
<tr>
<td>
<a href="{{ detail_url }}">{{ course_run.title }}</a>
</td>
<td>{{ course_run.start }}</td>
<td>{{ course_run.partner }}</td>
<td>{{ course_run.target_content }}</td>
<td>{{ course_run.priority }}</td>
<td>{{ course_run.workflow_state }}</td>
<td>{{ course_run.modified }}</td>
</tr>
{% endfor %}
</table>
{% endif %}
</div>
</div>
</div>
......
......@@ -7,7 +7,7 @@
{% block content %}
<div class="layout-full layout">
<div class="card course-form">
<div class="publisher-container">
<div class="course-information">
<h4 class="hd-4">{% trans "Seat Form" %}</h4>
<form class="form" method="post" action="">
......
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