Commit 08168ec6 by Jason Bau

Merge pull request #859 from edx/jbau/studio-link-in-instructor-panel

Add link in lms legacy instructor dashboard to cms course_index
parents ac2b7a3a ec989e49
...@@ -2,10 +2,11 @@ from collections import defaultdict ...@@ -2,10 +2,11 @@ from collections import defaultdict
from fs.errors import ResourceNotFoundError from fs.errors import ResourceNotFoundError
import logging import logging
import inspect import inspect
import re
from path import path from path import path
from django.http import Http404 from django.http import Http404
from django.conf import settings
from .module_render import get_module from .module_render import get_module
from xmodule.course_module import CourseDescriptor from xmodule.course_module import CourseDescriptor
from xmodule.modulestore import Location, XML_MODULESTORE_TYPE from xmodule.modulestore import Location, XML_MODULESTORE_TYPE
...@@ -294,3 +295,19 @@ def sort_by_announcement(courses): ...@@ -294,3 +295,19 @@ def sort_by_announcement(courses):
courses = sorted(courses, key=key) courses = sorted(courses, key=key)
return courses return courses
def get_cms_course_link_by_id(course_id):
"""
Returns a proto-relative link to course_index for editing the course in cms, assuming that the course is actually
cms-backed. If course_id is improperly formatted, just return the root of the cms
"""
format_str = r'^(?P<org>[^/]+)/(?P<course>[^/]+)/(?P<name>[^/]+)$'
host = "//{}/".format(settings.CMS_BASE) # protocol-relative
m_obj = re.match(format_str, course_id)
if m_obj:
return "{host}{org}/{course}/course/{name}".format(host=host,
org=m_obj.group('org'),
course=m_obj.group('course'),
name=m_obj.group('name'))
return host
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.test import TestCase from django.test import TestCase
from django.http import Http404 from django.http import Http404
from courseware.courses import get_course_by_id from django.test.utils import override_settings
from courseware.courses import get_course_by_id, get_cms_course_link_by_id
CMS_BASE_TEST = 'testcms'
class CoursesTest(TestCase): class CoursesTest(TestCase):
def test_get_course_by_id_invalid_chars(self): def test_get_course_by_id_invalid_chars(self):
...@@ -14,3 +17,12 @@ class CoursesTest(TestCase): ...@@ -14,3 +17,12 @@ class CoursesTest(TestCase):
get_course_by_id('MITx/foobar/statistics=introduction') get_course_by_id('MITx/foobar/statistics=introduction')
get_course_by_id('MITx/foobar/business and management') get_course_by_id('MITx/foobar/business and management')
get_course_by_id('MITx/foobar/NiñøJoséMaríáßç') get_course_by_id('MITx/foobar/NiñøJoséMaríáßç')
@override_settings(CMS_BASE=CMS_BASE_TEST)
def test_get_cms_course_link_by_id(self):
"""
Tests that get_cms_course_link_by_id returns the right thing
"""
self.assertEqual("//{}/".format(CMS_BASE_TEST), get_cms_course_link_by_id("blah_bad_course_id"))
self.assertEqual("//{}/".format(CMS_BASE_TEST), get_cms_course_link_by_id("too/too/many/slashes"))
self.assertEqual("//{}/org/num/course/name".format(CMS_BASE_TEST), get_cms_course_link_by_id('org/num/name'))
...@@ -33,7 +33,7 @@ from xmodule.html_module import HtmlDescriptor ...@@ -33,7 +33,7 @@ from xmodule.html_module import HtmlDescriptor
from courseware import grades from courseware import grades
from courseware.access import (has_access, get_access_group_name, from courseware.access import (has_access, get_access_group_name,
course_beta_test_group_name) course_beta_test_group_name)
from courseware.courses import get_course_with_access from courseware.courses import get_course_with_access, get_cms_course_link_by_id
from courseware.models import StudentModule from courseware.models import StudentModule
from django_comment_common.models import (Role, from django_comment_common.models import (Role,
FORUM_ROLE_ADMINISTRATOR, FORUM_ROLE_ADMINISTRATOR,
...@@ -792,23 +792,30 @@ def instructor_dashboard(request, course_id): ...@@ -792,23 +792,30 @@ def instructor_dashboard(request, course_id):
else: else:
instructor_tasks = None instructor_tasks = None
# determine if this is a studio-backed course so we can 1) provide a link to edit this course in studio
# 2) enable course email
is_studio_course = modulestore().get_modulestore_type(course_id) == MONGO_MODULESTORE_TYPE
email_editor = None
# HTML editor for email # HTML editor for email
if idash_mode == 'Email': if idash_mode == 'Email' and is_studio_course:
html_module = HtmlDescriptor(course.system, {'data': html_message}) html_module = HtmlDescriptor(course.system, {'data': html_message})
email_editor = wrap_xmodule(html_module.get_html, html_module, 'xmodule_edit.html')() email_editor = wrap_xmodule(html_module.get_html, html_module, 'xmodule_edit.html')()
else:
email_editor = None studio_url = None
if is_studio_course:
studio_url = get_cms_course_link_by_id(course_id)
# Flag for whether or not we display the email tab (depending upon # Flag for whether or not we display the email tab (depending upon
# what backing store this course using (Mongo vs. XML)) # what backing store this course using (Mongo vs. XML))
if settings.MITX_FEATURES['ENABLE_INSTRUCTOR_EMAIL'] and \ if settings.MITX_FEATURES['ENABLE_INSTRUCTOR_EMAIL'] and is_studio_course:
modulestore().get_modulestore_type(course_id) == MONGO_MODULESTORE_TYPE:
show_email_tab = True show_email_tab = True
# display course stats only if there is no other table to display: # display course stats only if there is no other table to display:
course_stats = None course_stats = None
if not datatable: if not datatable:
course_stats = get_course_stats_table() course_stats = get_course_stats_table()
#---------------------------------------- #----------------------------------------
# context for rendering # context for rendering
...@@ -821,6 +828,7 @@ def instructor_dashboard(request, course_id): ...@@ -821,6 +828,7 @@ def instructor_dashboard(request, course_id):
'course_stats': course_stats, 'course_stats': course_stats,
'msg': msg, 'msg': msg,
'modeflag': {idash_mode: 'selectedmode'}, 'modeflag': {idash_mode: 'selectedmode'},
'studio_url': studio_url,
'to_option': email_to_option, # email 'to_option': email_to_option, # email
'subject': email_subject, # email 'subject': email_subject, # email
...@@ -843,7 +851,6 @@ def instructor_dashboard(request, course_id): ...@@ -843,7 +851,6 @@ def instructor_dashboard(request, course_id):
return render_to_response('courseware/instructor_dashboard.html', context) return render_to_response('courseware/instructor_dashboard.html', context)
def _do_remote_gradebook(user, course, action, args=None, files=None): def _do_remote_gradebook(user, course, action, args=None, files=None):
''' '''
Perform remote gradebook action. Returns msg, datatable. Perform remote gradebook action. Returns msg, datatable.
......
...@@ -111,6 +111,8 @@ SITE_NAME = ENV_TOKENS['SITE_NAME'] ...@@ -111,6 +111,8 @@ SITE_NAME = ENV_TOKENS['SITE_NAME']
SESSION_ENGINE = ENV_TOKENS.get('SESSION_ENGINE', SESSION_ENGINE) SESSION_ENGINE = ENV_TOKENS.get('SESSION_ENGINE', SESSION_ENGINE)
SESSION_COOKIE_DOMAIN = ENV_TOKENS.get('SESSION_COOKIE_DOMAIN') SESSION_COOKIE_DOMAIN = ENV_TOKENS.get('SESSION_COOKIE_DOMAIN')
CMS_BASE = ENV_TOKENS.get('CMS_BASE', 'studio.edx.org')
# allow for environments to specify what cookie name our login subsystem should use # allow for environments to specify what cookie name our login subsystem should use
# this is to fix a bug regarding simultaneous logins between edx.org and edge.edx.org which can # this is to fix a bug regarding simultaneous logins between edx.org and edge.edx.org which can
# happen with some browsers (e.g. Firefox) # happen with some browsers (e.g. Firefox)
......
...@@ -355,6 +355,9 @@ DEBUG = False ...@@ -355,6 +355,9 @@ DEBUG = False
TEMPLATE_DEBUG = False TEMPLATE_DEBUG = False
USE_TZ = True USE_TZ = True
# CMS base
CMS_BASE = 'localhost:8001'
# Site info # Site info
SITE_ID = 1 SITE_ID = 1
SITE_NAME = "edx.org" SITE_NAME = "edx.org"
......
...@@ -8,6 +8,12 @@ ...@@ -8,6 +8,12 @@
right: 2em; right: 2em;
} }
.studio-edit-link{
position: absolute;
top: 3.5em;
right: 2em;
}
section.instructor-dashboard-content { section.instructor-dashboard-content {
@extend .content; @extend .content;
padding: 40px; padding: 40px;
......
...@@ -109,8 +109,13 @@ function goto( mode) ...@@ -109,8 +109,13 @@ function goto( mode)
<div class="instructor-dashboard-wrapper"> <div class="instructor-dashboard-wrapper">
%if settings.MITX_FEATURES.get('ENABLE_INSTRUCTOR_BETA_DASHBOARD'): %if settings.MITX_FEATURES.get('ENABLE_INSTRUCTOR_BETA_DASHBOARD'):
<div class="beta-button-wrapper"><a href="${ beta_dashboard_url }"> Try New Beta Dashboard </a></div> <div class="beta-button-wrapper"><a href="${ beta_dashboard_url }">${_("Try New Beta Dashboard")}</a></div>
%endif %endif
%if studio_url:
## not checking access because if user can see this, they are at least course staff (with studio edit access)
<div class="studio-edit-link"><a href="${studio_url}" target="_blank">${_('Edit Course In Studio')}</a></div>
%endif
<section class="instructor-dashboard-content"> <section class="instructor-dashboard-content">
<h1>${_("Instructor Dashboard")}</h1> <h1>${_("Instructor Dashboard")}</h1>
...@@ -125,7 +130,7 @@ function goto( mode) ...@@ -125,7 +130,7 @@ function goto( mode)
<a href="#" onclick="goto('Data');" class="${modeflag.get('Data')}">${_("DataDump")}</a> | <a href="#" onclick="goto('Data');" class="${modeflag.get('Data')}">${_("DataDump")}</a> |
<a href="#" onclick="goto('Manage Groups');" class="${modeflag.get('Manage Groups')}">${_("Manage Groups")}</a> <a href="#" onclick="goto('Manage Groups');" class="${modeflag.get('Manage Groups')}">${_("Manage Groups")}</a>
%if show_email_tab: %if show_email_tab:
| <a href="#" onclick="goto('Email')" class="${modeflag.get('Email')}">Email</a> | <a href="#" onclick="goto('Email')" class="${modeflag.get('Email')}">${_("Email")}</a>
%endif %endif
%if settings.MITX_FEATURES.get('ENABLE_INSTRUCTOR_ANALYTICS'): %if settings.MITX_FEATURES.get('ENABLE_INSTRUCTOR_ANALYTICS'):
| <a href="#" onclick="goto('Analytics');" class="${modeflag.get('Analytics')}">${_("Analytics")}</a> | <a href="#" onclick="goto('Analytics');" class="${modeflag.get('Analytics')}">${_("Analytics")}</a>
......
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