Commit c2716d47 by jmclaus

TNL-172: Change type of a previously posted post. IMPORTANT: this commit depends…

TNL-172: Change type of a previously posted post. IMPORTANT: this commit depends on commit 774887b in cs_comments_service.
parent 76a52acf
...@@ -298,26 +298,6 @@ browser and pasting the output. When that file changes, this one should be rege ...@@ -298,26 +298,6 @@ browser and pasting the output. When that file changes, this one should be rege
<script aria-hidden="true" type="text/template" id="new-post-template"> <script aria-hidden="true" type="text/template" id="new-post-template">
<form class="forum-new-post-form"> <form class="forum-new-post-form">
<ul class="post-errors" style="display: none"></ul> <ul class="post-errors" style="display: none"></ul>
<div class="post-field">
<div class="field-label">
<span class="field-label-text">
Post type:
</span><fieldset class="field-input">
<input type="radio" name="<%= form_id %>-post-type" class="post-type-input" id="<%= form_id %>-post-type-question" value="question" checked>
<label for="<%= form_id %>-post-type-question" class="post-type-label">
<i class="icon icon-question"></i>
Question
</label>
<input type="radio" name="<%= form_id %>-post-type" class="post-type-input" id="<%= form_id %>-post-type-discussion" value="discussion">
<label for="<%= form_id %>-post-type-discussion" class="post-type-label">
<i class="icon icon-comments"></i>
Discussion
</label>
</fieldset>
</div><span class="field-help">
Questions raise issues that need answers. Discussions share ideas and start conversations.
</span>
</div>
<div class="forum-new-post-form-wrapper"></div> <div class="forum-new-post-form-wrapper"></div>
<% if (cohort_options) { %> <% if (cohort_options) { %>
<div class="post-field"> <div class="post-field">
...@@ -369,6 +349,29 @@ browser and pasting the output. When that file changes, this one should be rege ...@@ -369,6 +349,29 @@ browser and pasting the output. When that file changes, this one should be rege
</form> </form>
</script> </script>
<script aria-hidden="true" type="text/template" id="thread-type-template">
<div class="post-field">
<div class="field-label">
<span class="field-label-text">
"Post type:"
</span><fieldset class="field-input">
<input type="radio" name="<%= form_id %>-post-type" class="post-type-input" id="<%= form_id %>-post-type-question" value="question" checked>
<label for="<%= form_id %>-post-type-question" class="post-type-label">
<i class="icon icon-question"></i>
"Question"
</label>
<input type="radio" name="<%= form_id %>-post-type" class="post-type-input" id="<%= form_id %>-post-type-discussion" value="discussion">
<label for="<%= form_id %>-post-type-discussion" class="post-type-label">
<i class="icon icon-comments"></i>
"Discussion"
</label>
</fieldset>
</div><span class="field-help">
"Questions raise issues that need answers. Discussions share ideas and start conversations."
</span>
</div>
</script>
<script aria-hidden="true" type="text/template" id="new-post-menu-entry-template"> <script aria-hidden="true" type="text/template" id="new-post-menu-entry-template">
<li role="menuitem" class="topic-menu-item"> <li role="menuitem" class="topic-menu-item">
<a href="#" class="topic-title" data-discussion-id="<%- id %>" data-cohorted="<%- is_cohorted %>"><%- text %></a> <a href="#" class="topic-title" data-discussion-id="<%- id %>" data-cohorted="<%- is_cohorted %>"><%- text %></a>
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
model: this.thread, model: this.thread,
mode: 'tab', mode: 'tab',
topicId: 'dummy_id', topicId: 'dummy_id',
threadType: 'question',
course_settings: this.course_settings course_settings: this.course_settings
}, options); }, options);
this.view = new DiscussionThreadEditView(options); this.view = new DiscussionThreadEditView(options);
...@@ -37,6 +38,7 @@ ...@@ -37,6 +38,7 @@
var view; var view;
spyOn($, 'ajax').andCallFake(function(params) { spyOn($, 'ajax').andCallFake(function(params) {
expect(params.url.path()).toEqual(DiscussionUtil.urlFor('update_thread', 'dummy_id')); expect(params.url.path()).toEqual(DiscussionUtil.urlFor('update_thread', 'dummy_id'));
expect(params.data.thread_type).toBe('discussion');
expect(params.data.commentable_id).toBe('topic'); expect(params.data.commentable_id).toBe('topic');
expect(params.data.title).toBe('new_title'); expect(params.data.title).toBe('new_title');
params.success(); params.success();
...@@ -45,11 +47,13 @@ ...@@ -45,11 +47,13 @@
this.createEditView(); this.createEditView();
this.view.$el.find('a.topic-title').first().click(); // set new topic this.view.$el.find('a.topic-title').first().click(); // set new topic
this.view.$('.edit-post-title').val('new_title'); // set new title this.view.$('.edit-post-title').val('new_title'); // set new title
this.view.$("label[for$='post-type-discussion']").click(); // set new thread type
this.view.$('.post-update').click(); this.view.$('.post-update').click();
expect($.ajax).toHaveBeenCalled(); expect($.ajax).toHaveBeenCalled();
expect(this.thread.get('title')).toBe('new_title'); expect(this.thread.get('title')).toBe('new_title');
expect(this.thread.get('commentable_id')).toBe('topic'); expect(this.thread.get('commentable_id')).toBe('topic');
expect(this.thread.get('thread_type')).toBe('discussion');
expect(this.thread.get('courseware_title')).toBe('Topic'); expect(this.thread.get('courseware_title')).toBe('Topic');
expect(this.view.$('.edit-post-title')).toHaveValue(''); expect(this.view.$('.edit-post-title')).toHaveValue('');
......
...@@ -115,7 +115,7 @@ describe "NewPostView", -> ...@@ -115,7 +115,7 @@ describe "NewPostView", ->
eventSpy = jasmine.createSpy('eventSpy') eventSpy = jasmine.createSpy('eventSpy')
view.listenTo(view, "newPost:cancel", eventSpy) view.listenTo(view, "newPost:cancel", eventSpy)
view.$(".post-errors").html("<li class='post-error'>Title can't be empty</li>") view.$(".post-errors").html("<li class='post-error'>Title can't be empty</li>")
view.$("#tab-post-type-discussion").click() view.$("label[for$='post-type-discussion']").click()
view.$(".js-post-title").val("Test Title") view.$(".js-post-title").val("Test Title")
view.$(".js-post-body textarea").val("Test body") view.$(".js-post-body textarea").val("Test body")
view.$(".wmd-preview p").html("Test body") view.$(".wmd-preview p").html("Test body")
...@@ -127,13 +127,14 @@ describe "NewPostView", -> ...@@ -127,13 +127,14 @@ describe "NewPostView", ->
view.$(".cancel").click() view.$(".cancel").click()
expect(eventSpy).toHaveBeenCalled() expect(eventSpy).toHaveBeenCalled()
expect(view.$(".post-errors").html()).toEqual(""); expect(view.$(".post-errors").html()).toEqual("");
expect($("##{mode}-post-type-question").prop("checked")).toBe(true) if mode == "tab"
expect($("##{mode}-post-type-discussion").prop("checked")).toBe(false) expect($("input[id$='post-type-question']")).toBeChecked()
expect($("input[id$='post-type-discussion']")).not.toBeChecked()
expect(view.$(".js-post-title").val()).toEqual(""); expect(view.$(".js-post-title").val()).toEqual("");
expect(view.$(".js-post-body textarea").val()).toEqual(""); expect(view.$(".js-post-body textarea").val()).toEqual("");
expect(view.$(".js-follow").prop("checked")).toBe(true) expect(view.$(".js-follow")).toBeChecked()
expect(view.$(".js-anon").prop("checked")).toBe(false) expect(view.$(".js-anon")).not.toBeChecked()
expect(view.$(".js-anon-peers").prop("checked")).toBe(false) expect(view.$(".js-anon-peers")).not.toBeChecked()
if mode == "tab" if mode == "tab"
expect(view.$(".js-selected-topic").text()).toEqual("General") expect(view.$(".js-selected-topic").text()).toEqual("General")
......
...@@ -46,6 +46,9 @@ if Backbone? ...@@ -46,6 +46,9 @@ if Backbone?
@thread.set("unread_comments_count", 0) @thread.set("unread_comments_count", 0)
@thread.set("read", true) @thread.set("read", true)
@setActiveThread() @setActiveThread()
@showMain()
showMain: =>
if(@main) if(@main)
@main.cleanup() @main.cleanup()
@main.undelegateEvents() @main.undelegateEvents()
...@@ -63,6 +66,7 @@ if Backbone? ...@@ -63,6 +66,7 @@ if Backbone?
@main.render() @main.render()
@main.on "thread:responses:rendered", => @main.on "thread:responses:rendered", =>
@nav.updateSidebar() @nav.updateSidebar()
@thread.on "thread:thread_type_updated", @showMain
navigateToThread: (thread_id) => navigateToThread: (thread_id) =>
thread = @discussion.get(thread_id) thread = @discussion.get(thread_id)
......
...@@ -16,16 +16,22 @@ ...@@ -16,16 +16,22 @@
this.container = options.container || $('.thread-content-wrapper'); this.container = options.container || $('.thread-content-wrapper');
this.mode = options.mode || 'inline'; this.mode = options.mode || 'inline';
this.course_settings = options.course_settings; this.course_settings = options.course_settings;
this.threadType = this.model.get('thread_type');
this.topicId = options.topicId; this.topicId = options.topicId;
_.bindAll(this); _.bindAll(this);
return this; return this;
}, },
render: function() { render: function() {
var threadTypeTemplate,
formId = _.uniqueId("form-");
this.template = _.template($('#thread-edit-template').html()); this.template = _.template($('#thread-edit-template').html());
this.$el.html(this.template(this.model.toJSON())).appendTo(this.container); this.$el.html(this.template(this.model.toJSON())).appendTo(this.container);
this.submitBtn = this.$('.post-update'); this.submitBtn = this.$('.post-update');
if (this.isTabMode()) { if (this.isTabMode()) {
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({ this.topicView = new DiscussionTopicMenuView({
topicId: this.topicId, topicId: this.topicId,
course_settings: this.course_settings course_settings: this.course_settings
...@@ -47,6 +53,7 @@ ...@@ -47,6 +53,7 @@
save: function() { save: function() {
var title = this.$('.edit-post-title').val(), var title = this.$('.edit-post-title').val(),
threadType = this.$(".post-type-input:checked").val(),
body = this.$('.edit-post-body textarea').val(), body = this.$('.edit-post-body textarea').val(),
commentableId = this.isTabMode() ? this.topicView.getCurrentTopicId() : null; commentableId = this.isTabMode() ? this.topicView.getCurrentTopicId() : null;
...@@ -59,6 +66,7 @@ ...@@ -59,6 +66,7 @@
async: false, // @TODO when the rest of the stuff below is made to work properly.. async: false, // @TODO when the rest of the stuff below is made to work properly..
data: { data: {
title: title, title: title,
thread_type: threadType,
body: body, body: body,
commentable_id: commentableId commentable_id: commentableId
}, },
...@@ -74,12 +82,17 @@ ...@@ -74,12 +82,17 @@
this.$('.wmd-preview p').html(''); this.$('.wmd-preview p').html('');
if (this.isTabMode()) { if (this.isTabMode()) {
_.extend(newAttrs, { _.extend(newAttrs, {
thread_type: threadType,
commentable_id: commentableId, commentable_id: commentableId,
courseware_title: this.topicView.getFullTopicName() courseware_title: this.topicView.getFullTopicName()
}); });
} }
this.model.set(newAttrs).unset('abbreviatedBody'); this.model.set(newAttrs).unset('abbreviatedBody');
this.trigger('thread:updated'); this.trigger('thread:updated');
if (this.threadType !== threadType) {
this.model.trigger('thread:thread_type_updated');
this.trigger('comment:endorse');
}
}.bind(this) }.bind(this)
}); });
}, },
......
...@@ -275,6 +275,7 @@ if Backbone? ...@@ -275,6 +275,7 @@ if Backbone?
topicId: @model.get('commentable_id') topicId: @model.get('commentable_id')
) )
@editView.bind "thread:updated thread:cancel_edit", @closeEditView @editView.bind "thread:updated thread:cancel_edit", @closeEditView
@editView.bind "comment:endorse", @endorseThread
renderSubView: (view) -> renderSubView: (view) ->
view.setElement(@$('.thread-content-wrapper')) view.setElement(@$('.thread-content-wrapper'))
......
...@@ -17,6 +17,8 @@ if Backbone? ...@@ -17,6 +17,8 @@ if Backbone?
}) })
@$el.html(_.template($("#new-post-template").html(), context)) @$el.html(_.template($("#new-post-template").html(), context))
if @isTabMode() if @isTabMode()
threadTypeTemplate = _.template($("#thread-type-template").html());
@addField(threadTypeTemplate({form_id: _.uniqueId("form-")}));
@topicView = new DiscussionTopicMenuView { @topicView = new DiscussionTopicMenuView {
topicId: @topicId topicId: @topicId
course_settings: @course_settings course_settings: @course_settings
......
...@@ -868,7 +868,7 @@ class UpdateThreadUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin, MockReq ...@@ -868,7 +868,7 @@ class UpdateThreadUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin, MockReq
"user_id": str(self.student.id), "user_id": str(self.student.id),
"closed": False, "closed": False,
}) })
request = RequestFactory().post("dummy_url", {"body": text, "title": text, "commentable_id": "test_commentable"}) request = RequestFactory().post("dummy_url", {"body": text, "title": text, "thread_type": "question", "commentable_id": "test_commentable"})
request.user = self.student request.user = self.student
request.view_name = "update_thread" request.view_name = "update_thread"
response = views.update_thread(request, course_id=self.course.id.to_deprecated_string(), thread_id="dummy_thread_id") response = views.update_thread(request, course_id=self.course.id.to_deprecated_string(), thread_id="dummy_thread_id")
...@@ -877,6 +877,7 @@ class UpdateThreadUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin, MockReq ...@@ -877,6 +877,7 @@ class UpdateThreadUnicodeTestCase(ModuleStoreTestCase, UnicodeTestMixin, MockReq
self.assertTrue(mock_request.called) self.assertTrue(mock_request.called)
self.assertEqual(mock_request.call_args[1]["data"]["body"], text) self.assertEqual(mock_request.call_args[1]["data"]["body"], text)
self.assertEqual(mock_request.call_args[1]["data"]["title"], text) self.assertEqual(mock_request.call_args[1]["data"]["title"], text)
self.assertEqual(mock_request.call_args[1]["data"]["thread_type"], "question")
self.assertEqual(mock_request.call_args[1]["data"]["commentable_id"], "test_commentable") self.assertEqual(mock_request.call_args[1]["data"]["commentable_id"], "test_commentable")
......
...@@ -143,7 +143,10 @@ def update_thread(request, course_id, thread_id): ...@@ -143,7 +143,10 @@ def update_thread(request, course_id, thread_id):
thread = cc.Thread.find(thread_id) thread = cc.Thread.find(thread_id)
thread.body = request.POST["body"] thread.body = request.POST["body"]
thread.title = request.POST["title"] thread.title = request.POST["title"]
# The following checks should avoid issues we've seen during deploys, where end users are hitting an updated server
# while their browser still has the old client code. This will avoid erasing present values in those cases.
if "thread_type" in request.POST:
thread.thread_type = request.POST["thread_type"]
if "commentable_id" in request.POST: if "commentable_id" in request.POST:
course = get_course_with_access(request.user, 'load', course_key) course = get_course_with_access(request.user, 'load', course_key)
id_map = get_discussion_id_map(course) id_map = get_discussion_id_map(course)
......
...@@ -22,7 +22,7 @@ class Thread(models.Model): ...@@ -22,7 +22,7 @@ class Thread(models.Model):
updatable_fields = [ updatable_fields = [
'title', 'body', 'anonymous', 'anonymous_to_peers', 'course_id', 'title', 'body', 'anonymous', 'anonymous_to_peers', 'course_id',
'closed', 'user_id', 'commentable_id', 'group_id', 'group_name', 'pinned' 'closed', 'user_id', 'commentable_id', 'group_id', 'group_name', 'pinned', 'thread_type'
] ]
metric_tag_fields = [ metric_tag_fields = [
......
...@@ -383,30 +383,6 @@ ...@@ -383,30 +383,6 @@
<script aria-hidden="true" type="text/template" id="new-post-template"> <script aria-hidden="true" type="text/template" id="new-post-template">
<form class="forum-new-post-form"> <form class="forum-new-post-form">
<ul class="post-errors" style="display: none"></ul> <ul class="post-errors" style="display: none"></ul>
<div class="post-field">
<div class="field-label">
<span class="field-label-text">
## Translators: This is the label for a control to
## select a forum post type
${_("Post type:")}
</span><fieldset class="field-input">
<input type="radio" name="${"<%= form_id %>"}-post-type" class="post-type-input" id="${"<%= form_id %>"}-post-type-question" value="question" checked>
<label for="${"<%= form_id %>"}-post-type-question" class="post-type-label">
<i class="icon icon-question"></i>
## Translators: This is a forum post type
${_("Question")}
</label>
<input type="radio" name="${"<%= form_id %>"}-post-type" class="post-type-input" id="${"<%= form_id %>"}-post-type-discussion" value="discussion">
<label for="${"<%= form_id %>"}-post-type-discussion" class="post-type-label">
<i class="icon icon-comments"></i>
## Translators: This is a forum post type
${_("Discussion")}
</label>
</fieldset>
</div><span class="field-help">
${_("Questions raise issues that need answers. Discussions share ideas and start conversations.")}
</span>
</div>
<div class="forum-new-post-form-wrapper"></div> <div class="forum-new-post-form-wrapper"></div>
${'<% if (cohort_options) { %>'} ${'<% if (cohort_options) { %>'}
<div class="post-field"> <div class="post-field">
...@@ -459,6 +435,33 @@ ...@@ -459,6 +435,33 @@
</form> </form>
</script> </script>
<script aria-hidden="true" type="text/template" id="thread-type-template">
<div class="post-field">
<div class="field-label">
<span class="field-label-text">
## Translators: This is the label for a control to
## select a forum post type
${_("Post type:")}
</span><fieldset class="field-input">
<input type="radio" name="${"<%= form_id %>"}-post-type" class="post-type-input" id="${"<%= form_id %>"}-post-type-question" value="question" checked>
<label for="${"<%= form_id %>"}-post-type-question" class="post-type-label">
<i class="icon icon-question"></i>
## Translators: This is a forum post type
${_("Question")}
</label>
<input type="radio" name="${"<%= form_id %>"}-post-type" class="post-type-input" id="${"<%= form_id %>"}-post-type-discussion" value="discussion">
<label for="${"<%= form_id %>"}-post-type-discussion" class="post-type-label">
<i class="icon icon-comments"></i>
## Translators: This is a forum post type
${_("Discussion")}
</label>
</fieldset>
</div><span class="field-help">
${_("Questions raise issues that need answers. Discussions share ideas and start conversations.")}
</span>
</div>
</script>
<script aria-hidden="true" type="text/template" id="new-post-menu-entry-template"> <script aria-hidden="true" type="text/template" id="new-post-menu-entry-template">
<li role="menuitem" class="topic-menu-item"> <li role="menuitem" class="topic-menu-item">
<a href="#" class="topic-title" data-discussion-id="${'<%- id %>'}" data-cohorted="${'<%- is_cohorted %>'}">${'<%- text %>'}</a> <a href="#" class="topic-title" data-discussion-id="${'<%- id %>'}" data-cohorted="${'<%- is_cohorted %>'}">${'<%- text %>'}</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