diff --git a/common/static/coffee/spec/discussion/discussion_spec_helper.coffee b/common/static/coffee/spec/discussion/discussion_spec_helper.coffee
index 0fee756658..0b052bc7ba 100644
--- a/common/static/coffee/spec/discussion/discussion_spec_helper.coffee
+++ b/common/static/coffee/spec/discussion/discussion_spec_helper.coffee
@@ -67,5 +67,6 @@ class @DiscussionSpecHelper
data-course-name="Fake Course"
data-user-create-comment="true"
data-user-create-subcomment="true"
+ data-read-only="false"
>
""")
diff --git a/common/static/coffee/spec/discussion/view/discussion_user_profile_view_spec.coffee b/common/static/coffee/spec/discussion/view/discussion_user_profile_view_spec.coffee
index c3bb52fe41..989893d64e 100644
--- a/common/static/coffee/spec/discussion/view/discussion_user_profile_view_spec.coffee
+++ b/common/static/coffee/spec/discussion/view/discussion_user_profile_view_spec.coffee
@@ -205,7 +205,7 @@ describe "DiscussionUserProfileView", ->
)
{always: ->}
)
- @view.$(".pagination a").first().click()
+ @view.$(".discussion-pagination a").first().click()
expect(@view.$(".current-page").text()).toEqual("42")
expect(@view.$(".last-page").text()).toEqual("99")
@@ -216,5 +216,5 @@ describe "DiscussionUserProfileView", ->
params.error()
{always: ->}
)
- @view.$(".pagination a").first().click()
+ @view.$(".discussion-pagination a").first().click()
expect(DiscussionUtil.discussionAlert).toHaveBeenCalled()
diff --git a/common/static/coffee/src/discussion/discussion_module_view.coffee b/common/static/coffee/src/discussion/discussion_module_view.coffee
index 9733e6658f..198d48d34c 100644
--- a/common/static/coffee/src/discussion/discussion_module_view.coffee
+++ b/common/static/coffee/src/discussion/discussion_module_view.coffee
@@ -10,10 +10,11 @@ if Backbone?
"click .discussion-paginator a": "navigateToPage"
page_re: /\?discussion_page=(\d+)/
- initialize: ->
+ initialize: (options) ->
@toggleDiscussionBtn = @$(".discussion-show")
# Set the page if it was set in the URL. This is used to allow deep linking to pages
match = @page_re.exec(window.location.href)
+ @context = options.context or "course" # allowed values are "course" or "standalone"
if match
@page = parseInt(match[1])
else
@@ -105,6 +106,7 @@ if Backbone?
el: @$("article#thread_#{thread.id}"),
model: thread,
mode: "inline",
+ context: @context,
course_settings: @course_settings,
topicId: discussionId
)
@@ -141,6 +143,7 @@ if Backbone?
el: article,
model: thread,
mode: "inline",
+ context: @context,
course_settings: @course_settings,
topicId: @$el.data("discussion-id")
)
@@ -152,7 +155,7 @@ if Backbone?
"?discussion_page=#{number}"
params = DiscussionUtil.getPaginationParams(@page, numPages, pageUrl)
pagination = _.template($("#pagination-template").html())(params)
- @$('section.pagination').html(pagination)
+ @$('section.discussion-pagination').html(pagination)
navigateToPage: (event) =>
event.preventDefault()
diff --git a/common/static/coffee/src/discussion/templates.coffee b/common/static/coffee/src/discussion/templates.coffee
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/common/static/coffee/src/discussion/views/discussion_thread_edit_view.js b/common/static/coffee/src/discussion/views/discussion_thread_edit_view.js
index 316c3aff4f..bd82bad796 100644
--- a/common/static/coffee/src/discussion/views/discussion_thread_edit_view.js
+++ b/common/static/coffee/src/discussion/views/discussion_thread_edit_view.js
@@ -18,6 +18,7 @@
this.course_settings = options.course_settings;
this.threadType = this.model.get('thread_type');
this.topicId = this.model.get('commentable_id');
+ this.context = options.context || 'course';
_.bindAll(this);
return this;
},
@@ -31,11 +32,15 @@
threadTypeTemplate = _.template($("#thread-type-template").html());
this.addField(threadTypeTemplate({form_id: formId}));
this.$("#" + formId + "-post-type-" + this.threadType).attr('checked', true);
- this.topicView = new DiscussionTopicMenuView({
- topicId: this.topicId,
- course_settings: this.course_settings
- });
- this.addField(this.topicView.render());
+ // Only allow the topic field for course threads, as standalone threads
+ // cannot be moved.
+ if (this.context === 'course') {
+ this.topicView = new DiscussionTopicMenuView({
+ topicId: this.topicId,
+ course_settings: this.course_settings
+ });
+ this.addField(this.topicView.render());
+ }
DiscussionUtil.makeWmdEditor(this.$el, $.proxy(this.$, this), 'edit-post-body');
return this;
},
@@ -53,13 +58,14 @@
var title = this.$('.edit-post-title').val(),
threadType = this.$(".post-type-input:checked").val(),
body = this.$('.edit-post-body textarea').val(),
- commentableId = this.topicView.getCurrentTopicId(),
postData = {
title: title,
thread_type: threadType,
- body: body,
- commentable_id: commentableId
+ body: body
};
+ if (this.topicView) {
+ postData.commentable_id = this.topicView.getCurrentTopicId();
+ }
return DiscussionUtil.safeAjax({
$elem: this.submitBtn,
@@ -75,7 +81,9 @@
this.$('.edit-post-title').val('').attr('prev-text', '');
this.$('.edit-post-body textarea').val('').attr('prev-text', '');
this.$('.wmd-preview p').html('');
- postData.courseware_title = this.topicView.getFullTopicName();
+ if (this.topicView) {
+ postData.courseware_title = this.topicView.getFullTopicName();
+ }
this.model.set(postData).unset('abbreviatedBody');
this.trigger('thread:updated');
if (this.threadType !== threadType) {
diff --git a/common/static/coffee/src/discussion/views/discussion_thread_show_view.coffee b/common/static/coffee/src/discussion/views/discussion_thread_show_view.coffee
index 5a1a0a5b29..75c6e9d5ac 100644
--- a/common/static/coffee/src/discussion/views/discussion_thread_show_view.coffee
+++ b/common/static/coffee/src/discussion/views/discussion_thread_show_view.coffee
@@ -13,7 +13,8 @@ if Backbone?
mode: @mode,
flagged: @model.isFlagged(),
author_display: @getAuthorDisplay(),
- cid: @model.cid
+ cid: @model.cid,
+ readOnly: $('.discussion-module').data('read-only')
},
@model.attributes,
)
diff --git a/common/static/coffee/src/discussion/views/discussion_thread_view.coffee b/common/static/coffee/src/discussion/views/discussion_thread_view.coffee
index f369cf6619..f9a6d21b00 100644
--- a/common/static/coffee/src/discussion/views/discussion_thread_view.coffee
+++ b/common/static/coffee/src/discussion/views/discussion_thread_view.coffee
@@ -19,9 +19,12 @@ if Backbone?
initialize: (options) ->
super()
@mode = options.mode or "inline" # allowed values are "tab" or "inline"
+ @context = options.context or "course" # allowed values are "course" or "standalone"
if @mode not in ["tab", "inline"]
throw new Error("invalid mode: " + @mode)
+ @readOnly = $(".discussion-module").data('read-only')
+
# Quick fix to have an actual model when we're receiving new models from
# the server.
@model.collection.on "reset", (collection) =>
@@ -50,12 +53,15 @@ if Backbone?
renderTemplate: ->
@template = _.template($("#thread-template").html())
- templateData = @model.toJSON()
container = $("#discussion-container")
if !container.length
# inline discussion
container = $(".discussion-module")
- templateData.can_create_comment = container.data("user-create-comment")
+ templateData = _.extend(
+ @model.toJSON(),
+ readOnly: @readOnly,
+ can_create_comment: container.data("user-create-comment")
+ )
@template(templateData)
render: ->
@@ -300,6 +306,7 @@ if Backbone?
container: @$('.thread-content-wrapper')
model: @model
mode: @mode
+ context: @context
course_settings: @options.course_settings
)
@editView.bind "thread:updated thread:cancel_edit", @closeEditView
diff --git a/common/static/coffee/src/discussion/views/discussion_user_profile_view.coffee b/common/static/coffee/src/discussion/views/discussion_user_profile_view.coffee
index 77cfd7df4f..6b03fca327 100644
--- a/common/static/coffee/src/discussion/views/discussion_user_profile_view.coffee
+++ b/common/static/coffee/src/discussion/views/discussion_user_profile_view.coffee
@@ -18,7 +18,7 @@ if Backbone?
baseUri = URI(window.location).removeSearch("page")
pageUrlFunc = (page) -> baseUri.clone().addSearch("page", page)
paginationParams = DiscussionUtil.getPaginationParams(@page, @numPages, pageUrlFunc)
- @$el.find(".pagination").html(_.template($("#pagination-template").html())(paginationParams))
+ @$el.find(".discussion-pagination").html(_.template($("#pagination-template").html())(paginationParams))
changePage: (event) ->
event.preventDefault()
diff --git a/common/static/coffee/src/discussion/views/new_post_view.coffee b/common/static/coffee/src/discussion/views/new_post_view.coffee
index ccbb313874..75ad7a91bc 100644
--- a/common/static/coffee/src/discussion/views/new_post_view.coffee
+++ b/common/static/coffee/src/discussion/views/new_post_view.coffee
@@ -87,7 +87,6 @@ if Backbone?
url: url
type: "POST"
dataType: 'json'
- async: false # TODO when the rest of the stuff below is made to work properly..
data:
thread_type: thread_type
title: title
diff --git a/common/static/coffee/src/discussion/views/response_comment_show_view.coffee b/common/static/coffee/src/discussion/views/response_comment_show_view.coffee
index 51432770a2..059e63f65c 100644
--- a/common/static/coffee/src/discussion/views/response_comment_show_view.coffee
+++ b/common/static/coffee/src/discussion/views/response_comment_show_view.coffee
@@ -9,7 +9,8 @@ if Backbone?
_.extend(
{
cid: @model.cid,
- author_display: @getAuthorDisplay()
+ author_display: @getAuthorDisplay(),
+ readOnly: $('.discussion-module').data('read-only')
},
@model.attributes
)
diff --git a/common/static/coffee/src/discussion/views/thread_response_show_view.coffee b/common/static/coffee/src/discussion/views/thread_response_show_view.coffee
index 6d634dd481..3e72cd56d9 100644
--- a/common/static/coffee/src/discussion/views/thread_response_show_view.coffee
+++ b/common/static/coffee/src/discussion/views/thread_response_show_view.coffee
@@ -10,7 +10,8 @@ if Backbone?
{
cid: @model.cid,
author_display: @getAuthorDisplay(),
- endorser_display: @getEndorserDisplay()
+ endorser_display: @getEndorserDisplay(),
+ readOnly: $('.discussion-module').data('read-only')
},
@model.attributes
)
diff --git a/common/static/coffee/src/discussion/views/thread_response_view.coffee b/common/static/coffee/src/discussion/views/thread_response_view.coffee
index a299738d6f..9d91d1361c 100644
--- a/common/static/coffee/src/discussion/views/thread_response_view.coffee
+++ b/common/static/coffee/src/discussion/views/thread_response_view.coffee
@@ -13,17 +13,21 @@ if Backbone?
initialize: (options) ->
@collapseComments = options.collapseComments
@createShowView()
+ @readOnly = $('.discussion-module').data('read-only')
renderTemplate: ->
@template = _.template($("#thread-response-template").html())
- templateData = @model.toJSON()
- templateData.wmdId = @model.id ? (new Date()).getTime()
container = $("#discussion-container")
if !container.length
# inline discussion
container = $(".discussion-module")
- templateData.create_sub_comment = container.data("user-create-subcomment")
+ templateData = _.extend(
+ @model.toJSON(),
+ wmdId: @model.id ? (new Date()).getTime(),
+ create_sub_comment: container.data("user-create-subcomment"),
+ readOnly: @readOnly
+ )
@template(templateData)
render: ->
@@ -88,7 +92,10 @@ if Backbone?
comment.set('thread', @model.get('thread'))
view = new ResponseCommentView(model: comment)
view.render()
- @$el.find(".comments .new-comment").before(view.el)
+ if @readOnly
+ @$el.find('.comments').append(view.el)
+ else
+ @$el.find(".comments .new-comment").before(view.el)
view.bind "comment:edit", (event) =>
@cancelEdit(event) if @editView?
@cancelCommentEdits()
diff --git a/common/static/common/templates/discussion/forum-actions.underscore b/common/static/common/templates/discussion/forum-actions.underscore
index 9fd9714a3e..5401e41180 100644
--- a/common/static/common/templates/discussion/forum-actions.underscore
+++ b/common/static/common/templates/discussion/forum-actions.underscore
@@ -1,16 +1,18 @@
-
- <% _.each(primaryActions, function(action) { print(_.template($('#forum-action-' + action).html(), {})) }) %>
-
-
-
- <%- gettext("More") %>
-
-
-
-
-
+
+
+<% } %>
diff --git a/common/static/common/templates/discussion/inline-discussion.underscore b/common/static/common/templates/discussion/inline-discussion.underscore
index 42f7f2f2f2..96dde1bed8 100644
--- a/common/static/common/templates/discussion/inline-discussion.underscore
+++ b/common/static/common/templates/discussion/inline-discussion.underscore
@@ -8,6 +8,6 @@
<% }); %>
-
diff --git a/common/static/common/templates/discussion/response-comment-show.underscore b/common/static/common/templates/discussion/response-comment-show.underscore
index 5f15338f1e..5dbf579afb 100644
--- a/common/static/common/templates/discussion/response-comment-show.underscore
+++ b/common/static/common/templates/discussion/response-comment-show.underscore
@@ -7,7 +7,8 @@
contentId: cid,
contentType: 'comment',
primaryActions: [],
- secondaryActions: ['edit', 'delete', 'report']
+ secondaryActions: ['edit', 'delete', 'report'],
+ readOnly: readOnly
}
)
%>
diff --git a/common/static/common/templates/discussion/thread-response-show.underscore b/common/static/common/templates/discussion/thread-response-show.underscore
index d43fd2d8aa..60b6b82a4d 100644
--- a/common/static/common/templates/discussion/thread-response-show.underscore
+++ b/common/static/common/templates/discussion/thread-response-show.underscore
@@ -49,7 +49,8 @@
contentId: cid,
contentType: 'response',
primaryActions: ['vote', thread.get('thread_type') == 'question' ? 'answer' : 'endorse'],
- secondaryActions: ['edit', 'delete', 'report']
+ secondaryActions: ['edit', 'delete', 'report'],
+ readOnly: readOnly
}
)
%>
diff --git a/common/static/common/templates/discussion/thread-response.underscore b/common/static/common/templates/discussion/thread-response.underscore
index 7e3aeffde2..8032f473da 100644
--- a/common/static/common/templates/discussion/thread-response.underscore
+++ b/common/static/common/templates/discussion/thread-response.underscore
@@ -12,16 +12,16 @@
diff --git a/common/static/common/templates/discussion/thread-show.underscore b/common/static/common/templates/discussion/thread-show.underscore
index 0b46318bdd..c28e0859c4 100644
--- a/common/static/common/templates/discussion/thread-show.underscore
+++ b/common/static/common/templates/discussion/thread-show.underscore
@@ -40,19 +40,22 @@
<%- gettext("Closed") %>
-
+ <% if (!readOnly) { %>
+
+ <% } %>
<%- body %>
diff --git a/common/static/common/templates/discussion/thread.underscore b/common/static/common/templates/discussion/thread.underscore
index 3212105475..8498c9ae8d 100644
--- a/common/static/common/templates/discussion/thread.underscore
+++ b/common/static/common/templates/discussion/thread.underscore
@@ -8,18 +8,20 @@
-
-
-
- <%- gettext("Add a Response") %>
-
-
+ <% if (!readOnly) { %>
+
+
+
+ <%- gettext("Add a Response") %>
+
+
+ <% } %>
<%- gettext("This thread is closed.") %>
- <% if (can_create_comment) { %>
+ <% if (can_create_comment && !readOnly) { %>
diff --git a/lms/djangoapps/teams/templates/teams/teams.html b/lms/djangoapps/teams/templates/teams/teams.html
index eb23a11d24..d2ac44343a 100644
--- a/lms/djangoapps/teams/templates/teams/teams.html
+++ b/lms/djangoapps/teams/templates/teams/teams.html
@@ -7,30 +7,42 @@
<%block name="bodyclass">view-teams is-in-course course%block>
<%block name="pagetitle">${_("Teams")}%block>
+
<%block name="headextra">
+<%static:css group='style-course-vendor'/>
<%static:css group='style-course'/>
+<%include file="../discussion/_js_head_dependencies.html" />
%block>
<%include file="/courseware/course_navigation.html" args="active_page='teams'" />
<%block name="js_extra">
+
+<%include file="../discussion/_js_body_dependencies.html" />
+<%static:js group='discussion'/>
+
+
<%static:require_module module_name="teams/js/teams_tab_factory" class_name="TeamsTabFactory">
- new TeamsTabFactory({
+ TeamsTabFactory({
+ courseID: '${ unicode(course.id) }',
topics: ${ json.dumps(topics, cls=EscapedEdxJSONEncoder) },
- topic_url: '${ topic_url }',
- topics_url: '${ topics_url }',
- teams_url: '${ teams_url }',
+ topicUrl: '${ topic_url }',
+ topicsUrl: '${ topics_url }',
+ teamsUrl: '${ teams_url }',
maxTeamSize: ${ course.teams_max_size },
- course_id: '${ unicode(course.id) }',
languages: ${ json.dumps(languages, cls=EscapedEdxJSONEncoder) },
countries: ${ json.dumps(countries, cls=EscapedEdxJSONEncoder) }
});
%static:require_module>
%block>
+
+<%include file="../discussion/_underscore_templates.html" />
diff --git a/lms/djangoapps/teams/tests/test_views.py b/lms/djangoapps/teams/tests/test_views.py
index 5c12057ff8..b8c637a8f7 100644
--- a/lms/djangoapps/teams/tests/test_views.py
+++ b/lms/djangoapps/teams/tests/test_views.py
@@ -467,7 +467,7 @@ class TestCreateTeamAPI(TeamAPITestCase):
# Verify that the creating user gets added to the team.
self.assertEqual(len(team_membership), 1)
member = team_membership[0]['user']
- self.assertEqual(member['id'], creator)
+ self.assertEqual(member['username'], creator)
self.assertEqual(team, {
'name': 'Fully specified team',
@@ -688,7 +688,7 @@ class TestListMembershipAPI(TeamAPITestCase):
membership = self.get_membership_list(status, {'team_id': self.test_team_1.team_id}, user=user)
if status == 200:
self.assertEqual(membership['count'], 1)
- self.assertEqual(membership['results'][0]['user']['id'], self.users['student_enrolled'].username)
+ self.assertEqual(membership['results'][0]['user']['username'], self.users['student_enrolled'].username)
@ddt.data(
(None, 401, False),
@@ -705,7 +705,7 @@ class TestListMembershipAPI(TeamAPITestCase):
if status == 200:
if has_content:
self.assertEqual(membership['count'], 1)
- self.assertEqual(membership['results'][0]['team']['id'], self.test_team_1.team_id)
+ self.assertEqual(membership['results'][0]['team']['team_id'], self.test_team_1.team_id)
else:
self.assertEqual(membership['count'], 0)
@@ -754,8 +754,8 @@ class TestCreateMembershipAPI(TeamAPITestCase):
user=user
)
if status == 200:
- self.assertEqual(membership['user']['id'], self.users['student_enrolled_not_on_team'].username)
- self.assertEqual(membership['team']['id'], self.test_team_1.team_id)
+ self.assertEqual(membership['user']['username'], self.users['student_enrolled_not_on_team'].username)
+ self.assertEqual(membership['team']['team_id'], self.test_team_1.team_id)
memberships = self.get_membership_list(200, {'team_id': self.test_team_1.team_id})
self.assertEqual(memberships['count'], 2)
diff --git a/lms/djangoapps/teams/views.py b/lms/djangoapps/teams/views.py
index 313b433c9f..cdcd92c08b 100644
--- a/lms/djangoapps/teams/views.py
+++ b/lms/djangoapps/teams/views.py
@@ -90,6 +90,7 @@ class TeamsDashboardView(View):
instance=topics_page,
context={'course_id': course.id, 'sort_order': sort_order}
)
+ user = request.user
context = {
"course": course,
"topics": topics_serializer.data,
@@ -100,6 +101,8 @@ class TeamsDashboardView(View):
"teams_url": reverse('teams_list', request=request),
"languages": settings.ALL_LANGUAGES,
"countries": list(countries),
+ "username": user.username,
+ "privileged": has_discussion_privileges(user, course_key)
}
return render_to_response("teams/teams.html", context)
diff --git a/lms/static/js/spec/main.js b/lms/static/js/spec/main.js
index 7f688c473e..b6e3aa8bca 100644
--- a/lms/static/js/spec/main.js
+++ b/lms/static/js/spec/main.js
@@ -21,6 +21,7 @@
'jquery.inputnumber': 'xmodule_js/common_static/js/vendor/html5-input-polyfills/number-polyfill',
'jquery.immediateDescendents': 'xmodule_js/common_static/coffee/src/jquery.immediateDescendents',
'jquery.simulate': 'xmodule_js/common_static/js/vendor/jquery.simulate',
+ 'jquery.timeago': 'xmodule_js/common_static/js/vendor/jquery.timeago',
'jquery.url': 'xmodule_js/common_static/js/vendor/url.min',
'datepair': 'xmodule_js/common_static/js/vendor/timepicker/datepair',
'date': 'xmodule_js/common_static/js/vendor/date',
@@ -30,8 +31,8 @@
'backbone': 'xmodule_js/common_static/js/vendor/backbone-min',
'backbone.associations': 'xmodule_js/common_static/js/vendor/backbone-associations-min',
'backbone.paginator': 'xmodule_js/common_static/js/vendor/backbone.paginator.min',
+ 'backbone-super': 'js/vendor/backbone-super',
'URI': 'xmodule_js/common_static/js/vendor/URI.min',
- "backbone-super": "js/vendor/backbone-super",
'tinymce': 'xmodule_js/common_static/js/vendor/tinymce/js/tinymce/tinymce.full.min',
'jquery.tinymce': 'xmodule_js/common_static/js/vendor/tinymce/js/tinymce/jquery.tinymce',
'xmodule': 'xmodule_js/src/xmodule',
@@ -57,6 +58,12 @@
'capa/display': 'xmodule_js/src/capa/display',
'string_utils': 'xmodule_js/common_static/js/src/string_utils',
'logger': 'xmodule_js/common_static/js/src/logger',
+ 'Markdown.Converter': 'js/Markdown.Converter',
+ 'Markdown.Editor': 'js/Markdown.Editor',
+ 'Markdown.Sanitizer': 'js/Markdown.Sanitizer',
+ '_split': 'js/split',
+ 'mathjax_delay_renderer': 'coffee/src/mathjax_delay_renderer',
+ 'MathJaxProcessor': 'coffee/src/customwmd',
// Manually specify LMS files that are not converted to RequireJS
'history': 'js/vendor/history',
@@ -83,6 +90,9 @@
'js/student_profile/views/learner_profile_view': 'js/student_profile/views/learner_profile_view',
'js/ccx/schedule': 'js/ccx/schedule',
+ // Discussion classes loaded explicitly until they are converted to use RequireJS
+ 'DiscussionModuleView': 'xmodule_js/common_static/coffee/src/discussion/discussion_module_view',
+
// edxnotes
'annotator_1.2.9': 'xmodule_js/common_static/js/vendor/edxnotes/annotator-full.min'
},
@@ -149,6 +159,10 @@
deps: ['jquery'],
exports: 'jQuery.fn.simulate'
},
+ 'jquery.timeago': {
+ deps: ['jquery'],
+ exports: 'jQuery.timeago'
+ },
'jquery.tinymce': {
deps: ['jquery', 'tinymce'],
exports: 'jQuery.fn.tinymce'
@@ -192,11 +206,32 @@
exports: 'Backbone.Paginator'
},
"backbone-super": {
- deps: ["backbone"],
+ deps: ["backbone"]
},
'youtube': {
exports: 'YT'
},
+ 'Markdown.Converter': {
+ deps: ['mathjax'],
+ exports: 'Markdown.Converter'
+ },
+ 'Markdown.Editor': {
+ deps: ['Markdown.Converter'],
+ exports: 'Markdown.Editor'
+ },
+ 'Markdown.Sanitizer': {
+ deps: ['Markdown.Converter'],
+ exports: 'Markdown.Sanitizer'
+ },
+ '_split': {
+ exports: '_split'
+ },
+ 'MathJaxProcessor': {
+ deps: [
+ 'Markdown.Converter', 'Markdown.Sanitizer', 'Markdown.Editor', '_split', 'mathjax_delay_renderer'
+ ],
+ exports: 'MathJaxProcessor'
+ },
'codemirror': {
exports: 'CodeMirror'
},
@@ -417,7 +452,7 @@
exports: 'edx.verify_student.IntroStepView',
deps: [
'jquery',
- 'js/verify_student/views/step_view',
+ 'js/verify_student/views/step_view'
]
},
'js/verify_student/views/make_payment_step_view': {
@@ -429,7 +464,7 @@
'jquery.cookie',
'jquery.url',
'string_utils',
- 'js/verify_student/views/step_view',
+ 'js/verify_student/views/step_view'
]
},
'js/verify_student/views/payment_confirmation_step_view': {
@@ -438,7 +473,7 @@
'jquery',
'underscore',
'gettext',
- 'js/verify_student/views/step_view',
+ 'js/verify_student/views/step_view'
]
},
'js/verify_student/views/face_photo_step_view': {
@@ -475,14 +510,14 @@
exports: 'edx.verify_student.EnrollmentConfirmationStepView',
deps: [
'jquery',
- 'js/verify_student/views/step_view',
+ 'js/verify_student/views/step_view'
]
},
'js/verify_student/views/reverify_success_step_view': {
exports: 'edx.verify_student.ReverifySuccessStepView',
deps: [
'jquery',
- 'js/verify_student/views/step_view',
+ 'js/verify_student/views/step_view'
]
},
'js/verify_student/views/pay_and_verify_view': {
@@ -520,21 +555,169 @@
'annotator_1.2.9': {
exports: 'Annotator',
deps: ['jquery']
+ },
+ // Discussions
+ 'xmodule_js/common_static/coffee/src/discussion/utils': {
+ deps: [
+ 'jquery',
+ 'jquery.timeago',
+ 'underscore',
+ 'backbone',
+ 'gettext',
+ 'MathJaxProcessor',
+ 'URI'
+ ],
+ exports: 'DiscussionUtil',
+ init: function() {
+ // Set global variables that the discussion code is expecting to be defined
+ window.Backbone = require('backbone');
+ window.URI = require('URI');
+ }
+ },
+ 'xmodule_js/common_static/coffee/src/discussion/content': {
+ deps: [
+ 'xmodule_js/common_static/coffee/src/discussion/utils'
+ ],
+ exports: 'Content'
+ },
+ 'xmodule_js/common_static/coffee/src/discussion/discussion': {
+ deps: [
+ 'xmodule_js/common_static/coffee/src/discussion/utils',
+ 'xmodule_js/common_static/coffee/src/discussion/content'
+ ],
+ exports: 'Discussion'
+ },
+ 'xmodule_js/common_static/coffee/src/discussion/discussion_filter': {
+ deps: [
+ 'xmodule_js/common_static/coffee/src/discussion/utils'
+ ],
+ exports: 'DiscussionFilter'
+ },
+ 'xmodule_js/common_static/coffee/src/discussion/models/discussion_course_settings': {
+ deps: [
+ 'xmodule_js/common_static/coffee/src/discussion/utils'
+ ],
+ exports: 'DiscussionCourseSettings'
+ },
+ 'xmodule_js/common_static/coffee/src/discussion/models/discussion_user': {
+ deps: [
+ 'xmodule_js/common_static/coffee/src/discussion/utils'
+ ],
+ exports: 'DiscussionUser'
+ },
+ 'xmodule_js/common_static/coffee/src/discussion/views/discussion_content_view': {
+ deps: [
+ 'xmodule_js/common_static/coffee/src/discussion/utils'
+ ],
+ exports: 'DiscussionContentView'
+ },
+ 'xmodule_js/common_static/coffee/src/discussion/views/discussion_thread_edit_view': {
+ deps: [
+ 'xmodule_js/common_static/coffee/src/discussion/utils'
+ ],
+ exports: 'DiscussionThreadEditView'
+ },
+ 'xmodule_js/common_static/coffee/src/discussion/views/discussion_thread_list_view': {
+ deps: [
+ 'xmodule_js/common_static/coffee/src/discussion/utils'
+ ],
+ exports: 'DiscussionThreadListView'
+ },
+ 'xmodule_js/common_static/coffee/src/discussion/views/discussion_thread_profile_view': {
+ deps: [
+ 'xmodule_js/common_static/coffee/src/discussion/utils'
+ ],
+ exports: 'DiscussionThreadProfileView'
+ },
+ 'xmodule_js/common_static/coffee/src/discussion/views/discussion_thread_show_view': {
+ deps: [
+ 'xmodule_js/common_static/coffee/src/discussion/utils'
+ ],
+ exports: 'DiscussionThreadShowView'
+ },
+ 'xmodule_js/common_static/coffee/src/discussion/views/discussion_thread_view': {
+ deps: [
+ 'xmodule_js/common_static/coffee/src/discussion/utils'
+ ],
+ exports: 'DiscussionThreadView'
+ },
+ 'xmodule_js/common_static/coffee/src/discussion/views/discussion_topic_menu_view': {
+ deps: [
+ 'xmodule_js/common_static/coffee/src/discussion/utils'
+ ],
+ exports: 'DiscussionTopicMenuView'
+ },
+ 'xmodule_js/common_static/coffee/src/discussion/views/discussion_user_profile_view': {
+ deps: [
+ 'xmodule_js/common_static/coffee/src/discussion/utils'
+ ],
+ exports: 'DiscussionUserProfileView'
+ },
+ 'xmodule_js/common_static/coffee/src/discussion/views/new_post_view': {
+ deps: [
+ 'xmodule_js/common_static/coffee/src/discussion/utils'
+ ],
+ exports: 'NewPostView'
+ },
+ 'xmodule_js/common_static/coffee/src/discussion/views/thread_response_edit_view': {
+ deps: [
+ 'xmodule_js/common_static/coffee/src/discussion/utils'
+ ],
+ exports: 'ThreadResponseEditView'
+ },
+ 'xmodule_js/common_static/coffee/src/discussion/views/thread_response_show_view': {
+ deps: [
+ 'xmodule_js/common_static/coffee/src/discussion/utils'
+ ],
+ exports: 'ThreadResponseShowView'
+ },
+ 'xmodule_js/common_static/coffee/src/discussion/views/thread_response_view': {
+ deps: [
+ 'xmodule_js/common_static/coffee/src/discussion/utils'
+ ],
+ exports: 'ThreadResponseView'
+ },
+ 'DiscussionModuleView': {
+ deps: [
+ 'jquery',
+ 'underscore',
+ 'backbone',
+ 'gettext',
+ 'URI',
+ 'xmodule_js/common_static/coffee/src/discussion/content',
+ 'xmodule_js/common_static/coffee/src/discussion/discussion',
+ 'xmodule_js/common_static/coffee/src/discussion/discussion_filter',
+ 'xmodule_js/common_static/coffee/src/discussion/utils',
+ 'xmodule_js/common_static/coffee/src/discussion/models/discussion_course_settings',
+ 'xmodule_js/common_static/coffee/src/discussion/models/discussion_user',
+ 'xmodule_js/common_static/coffee/src/discussion/views/discussion_content_view',
+ 'xmodule_js/common_static/coffee/src/discussion/views/discussion_thread_edit_view',
+ 'xmodule_js/common_static/coffee/src/discussion/views/discussion_thread_list_view',
+ 'xmodule_js/common_static/coffee/src/discussion/views/discussion_thread_profile_view',
+ 'xmodule_js/common_static/coffee/src/discussion/views/discussion_thread_show_view',
+ 'xmodule_js/common_static/coffee/src/discussion/views/discussion_thread_view',
+ 'xmodule_js/common_static/coffee/src/discussion/views/discussion_topic_menu_view',
+ 'xmodule_js/common_static/coffee/src/discussion/views/discussion_user_profile_view',
+ 'xmodule_js/common_static/coffee/src/discussion/views/new_post_view',
+ 'xmodule_js/common_static/coffee/src/discussion/views/thread_response_edit_view',
+ 'xmodule_js/common_static/coffee/src/discussion/views/thread_response_show_view',
+ 'xmodule_js/common_static/coffee/src/discussion/views/thread_response_view'
+ ],
+ exports: 'DiscussionModuleView'
+ },
+ 'xmodule_js/common_static/coffee/spec/discussion/discussion_spec_helper': {
+ deps: [
+ 'xmodule_js/common_static/coffee/src/discussion/utils'
+ ],
+ exports: 'DiscussionSpecHelper'
}
+
}
});
// TODO: why do these need 'lms/include' at the front but the CMS equivalent logic doesn't?
define([
// Run the LMS tests
- 'lms/include/teams/js/spec/teams_factory_spec.js',
- 'lms/include/teams/js/spec/topic_card_spec.js',
- 'lms/include/teams/js/spec/topic_collection_spec.js',
- 'lms/include/teams/js/spec/topics_spec.js',
- 'lms/include/teams/js/spec/teams_spec.js',
- 'lms/include/teams/js/spec/teams_tab_spec.js',
- 'lms/include/teams/js/spec/team_actions_spec.js',
- 'lms/include/teams/js/spec/edit_team_spec.js',
'lms/include/js/spec/components/header/header_spec.js',
'lms/include/js/spec/components/tabbed/tabbed_view_spec.js',
'lms/include/js/spec/components/card/card_spec.js',
@@ -605,7 +788,17 @@
'lms/include/js/spec/discovery/views/refine_sidebar_spec.js',
'lms/include/js/spec/discovery/views/search_form_spec.js',
'lms/include/js/spec/discovery/discovery_factory_spec.js',
- 'lms/include/js/spec/ccx/schedule_spec.js'
+ 'lms/include/js/spec/ccx/schedule_spec.js',
+ 'lms/include/teams/js/spec/collections/topic_collection_spec.js',
+ 'lms/include/teams/js/spec/edit_team_spec.js',
+ 'lms/include/teams/js/spec/team_actions_spec.js',
+ 'lms/include/teams/js/spec/teams_factory_spec.js',
+ 'lms/include/teams/js/spec/views/team_discussion_spec.js',
+ 'lms/include/teams/js/spec/views/team_profile_spec.js',
+ 'lms/include/teams/js/spec/views/teams_spec.js',
+ 'lms/include/teams/js/spec/views/teams_tab_spec.js',
+ 'lms/include/teams/js/spec/views/topic_card_spec.js',
+ 'lms/include/teams/js/spec/views/topics_spec.js',
]);
}).call(this, requirejs, define);
diff --git a/lms/static/js_test.yml b/lms/static/js_test.yml
index 82b875da50..4aa034d22f 100644
--- a/lms/static/js_test.yml
+++ b/lms/static/js_test.yml
@@ -39,6 +39,7 @@ lib_paths:
- xmodule_js/common_static/js/vendor/jquery.min.js
- xmodule_js/common_static/js/vendor/jquery-ui.min.js
- xmodule_js/common_static/js/vendor/jquery.cookie.js
+ - xmodule_js/common_static/js/vendor/jquery.timeago.js
- xmodule_js/common_static/js/vendor/flot/jquery.flot.js
- xmodule_js/common_static/js/vendor/CodeMirror/codemirror.js
- xmodule_js/common_static/js/vendor/URI.min.js
@@ -66,8 +67,10 @@ lib_paths:
# Paths to source JavaScript files
src_paths:
- js
+ - coffee/src
- common/js
- teams/js
+ - xmodule_js/common_static/coffee
# Paths to spec (test) JavaScript files
spec_paths:
diff --git a/lms/static/lms/js/build.js b/lms/static/lms/js/build.js
index 33b1903289..81d8568dd9 100644
--- a/lms/static/lms/js/build.js
+++ b/lms/static/lms/js/build.js
@@ -64,6 +64,7 @@
'logger': 'empty:',
'utility': 'empty:',
'URI': 'empty:',
+ 'DiscussionModuleView': 'empty:'
},
/**
diff --git a/lms/static/lms/js/require-config.js b/lms/static/lms/js/require-config.js
index 50c433affd..13270a1993 100644
--- a/lms/static/lms/js/require-config.js
+++ b/lms/static/lms/js/require-config.js
@@ -23,6 +23,7 @@
defineDependency("Logger", "logger");
defineDependency("URI", "URI");
defineDependency("Backbone", "backbone");
+
// utility.js adds two functions to the window object, but does not return anything
defineDependency("isExternal", "utility", true);
}
diff --git a/lms/static/sass/discussion/_discussion.scss b/lms/static/sass/discussion/_discussion.scss
index 7425a41618..09181d0012 100644
--- a/lms/static/sass/discussion/_discussion.scss
+++ b/lms/static/sass/discussion/_discussion.scss
@@ -753,10 +753,10 @@ body.discussion {
}
section.discussion {
- margin-top: ($baseline*1.5);
+ clear: both;
+ padding-top: $baseline;
.threads {
- margin-top: $baseline;
}
.discussion-thread {
@@ -936,7 +936,7 @@ body.discussion {
color: $white;
}
- section.pagination {
+ section.discussion-pagination {
margin-top: ($baseline*1.5);
nav.discussion-paginator {
diff --git a/lms/templates/discussion/_discussion_module.html b/lms/templates/discussion/_discussion_module.html
index aedf007343..ba6d1c88e9 100644
--- a/lms/templates/discussion/_discussion_module.html
+++ b/lms/templates/discussion/_discussion_module.html
@@ -3,7 +3,7 @@
from django.utils.translation import ugettext as _
%>
-
+
${_("Show Discussion")}
% if can_create_thread:
${_("New Post")}
diff --git a/lms/templates/discussion/index.html b/lms/templates/discussion/index.html
index 8b074b8190..00fdfd773d 100644
--- a/lms/templates/discussion/index.html
+++ b/lms/templates/discussion/index.html
@@ -31,6 +31,7 @@ from django.core.urlresolvers import reverse
data-user-info="${user_info}"
data-user-create-comment="${can_create_comment}"
data-user-create-subcomment="${can_create_subcomment}"
+ data-read-only="false"
data-threads="${threads}"
data-thread-pages="${thread_pages}"
data-content-info="${annotated_content_info}"
diff --git a/openedx/core/lib/api/serializers.py b/openedx/core/lib/api/serializers.py
index 29c20a570b..03ec001137 100644
--- a/openedx/core/lib/api/serializers.py
+++ b/openedx/core/lib/api/serializers.py
@@ -31,7 +31,6 @@ class PaginationSerializer(pagination.PaginationSerializer):
class CollapsedReferenceSerializer(serializers.HyperlinkedModelSerializer):
"""Serializes arbitrary models in a collapsed format, with just an id and url."""
- id = serializers.CharField(read_only=True) # pylint: disable=invalid-name
url = serializers.HyperlinkedIdentityField(view_name='')
def __init__(self, model_class, view_name, id_source='id', lookup_field=None, *args, **kwargs):
@@ -42,7 +41,8 @@ class CollapsedReferenceSerializer(serializers.HyperlinkedModelSerializer):
view_name (string): Name of the Django view used to lookup the
model.
id_source (string): Optional name of the id field on the model.
- Defaults to 'id'.
+ Defaults to 'id'. Also used as the property name of the field
+ in the serialized representation.
lookup_field (string): Optional name of the model field used to
lookup the model in the view. Defaults to the value of
id_source.
@@ -54,7 +54,7 @@ class CollapsedReferenceSerializer(serializers.HyperlinkedModelSerializer):
super(CollapsedReferenceSerializer, self).__init__(*args, **kwargs)
- self.fields['id'].source = id_source
+ self.fields[id_source] = serializers.CharField(read_only=True, source=id_source)
self.fields['url'].view_name = view_name
self.fields['url'].lookup_field = lookup_field
@@ -63,4 +63,4 @@ class CollapsedReferenceSerializer(serializers.HyperlinkedModelSerializer):
model is set dynamically in __init__.
"""
- fields = ("id", "url")
+ fields = ("url",)