From 457b7f468fcf5673318910896877bd729cd5469a Mon Sep 17 00:00:00 2001 From: Rocky Duan Date: Tue, 14 Aug 2012 16:43:33 -0700 Subject: [PATCH 1/2] toggle moderator status --- .../django_comment_client/base/urls.py | 1 + .../django_comment_client/base/views.py | 37 +++++++++++++- lms/static/coffee/src/discussion/main.coffee | 2 +- .../coffee/src/discussion/user_profile.coffee | 30 +++++++++++ lms/static/coffee/src/discussion/utils.coffee | 51 ++++++++++--------- lms/templates/discussion/_user_profile.html | 22 ++++++++ .../discussion/ajax_user_profile.html | 1 + lms/templates/discussion/user_profile.html | 25 +++------ 8 files changed, 123 insertions(+), 46 deletions(-) create mode 100644 lms/static/coffee/src/discussion/user_profile.coffee create mode 100644 lms/templates/discussion/_user_profile.html create mode 100644 lms/templates/discussion/ajax_user_profile.html diff --git a/lms/djangoapps/django_comment_client/base/urls.py b/lms/djangoapps/django_comment_client/base/urls.py index ac830af6cc..f2cb4ccb15 100644 --- a/lms/djangoapps/django_comment_client/base/urls.py +++ b/lms/djangoapps/django_comment_client/base/urls.py @@ -4,6 +4,7 @@ import django_comment_client.base.views urlpatterns = patterns('django_comment_client.base.views', url(r'upload$', 'upload', name='upload'), + url(r'users/(?P\w+)/update_moderator_status$', 'update_moderator_status', name='update_moderator_status'), url(r'threads/tags/autocomplete$', 'tags_autocomplete', name='tags_autocomplete'), url(r'threads/(?P[\w\-]+)/update$', 'update_thread', name='update_thread'), url(r'threads/(?P[\w\-]+)/reply$', 'create_comment', name='create_comment'), diff --git a/lms/djangoapps/django_comment_client/base/views.py b/lms/djangoapps/django_comment_client/base/views.py index 0890ccac0e..fb2e1686f8 100644 --- a/lms/djangoapps/django_comment_client/base/views.py +++ b/lms/djangoapps/django_comment_client/base/views.py @@ -4,8 +4,10 @@ import os import os.path import logging import urlparse +import functools import comment_client as cc +import django_comment_client.utils as utils from django.core import exceptions from django.contrib.auth.decorators import login_required @@ -14,13 +16,15 @@ from django.views.decorators import csrf from django.core.files.storage import get_storage_class from django.utils.translation import ugettext as _ from django.conf import settings +from django.contrib.auth.models import User from mitxmako.shortcuts import render_to_response, render_to_string +from courseware.courses import check_course + from django_comment_client.utils import JsonResponse, JsonError, extract -import django_comment_client.utils as utils from django_comment_client.permissions import check_permissions_by_view -import functools +from django_comment_client.models import Role def permitted(fn): @functools.wraps(fn) @@ -289,6 +293,35 @@ def unfollow_user(request, course_id, followed_user_id): user.unfollow(followed_user) return JsonResponse({}) +@require_POST +@login_required +@permitted +def update_moderator_status(request, course_id, user_id): + is_moderator = request.POST.get('is_moderator', '').lower() + if is_moderator not in ["true", "false"]: + return JsonError("Must provide is_moderator as boolean value") + is_moderator = is_moderator == "true" + user = User.objects.get(id=user_id) + role = Role.objects.get(course_id=course_id, name="Moderator") + if is_moderator: + user.roles.add(role) + else: + user.roles.remove(role) + if request.is_ajax(): + course = check_course(request.user, course_id) + discussion_user = cc.User(id=user_id, course_id=course_id) + context = { + 'course': course, + 'user': request.user, + 'django_user': user, + 'discussion_user': discussion_user.to_dict(), + } + return JsonResponse({ + 'html': render_to_string('discussion/ajax_user_profile.html', context) + }) + else: + return JsonResponse({}) + @require_GET def search_similar_threads(request, course_id, commentable_id): text = request.GET.get('text', None) diff --git a/lms/static/coffee/src/discussion/main.coffee b/lms/static/coffee/src/discussion/main.coffee index ae340aba84..29d809a41b 100644 --- a/lms/static/coffee/src/discussion/main.coffee +++ b/lms/static/coffee/src/discussion/main.coffee @@ -20,4 +20,4 @@ $ -> Discussion.initializeDiscussion(discussion) Discussion.bindDiscussionEvents(discussion) - + Discussion.initializeUserProfile($(".discussion-sidebar>.user-profile")) diff --git a/lms/static/coffee/src/discussion/user_profile.coffee b/lms/static/coffee/src/discussion/user_profile.coffee new file mode 100644 index 0000000000..e41751e1ee --- /dev/null +++ b/lms/static/coffee/src/discussion/user_profile.coffee @@ -0,0 +1,30 @@ +if not @Discussion? + @Discussion = {} + +Discussion = @Discussion + +@Discussion = $.extend @Discussion, + initializeUserProfile: ($userProfile) -> + $local = Discussion.generateLocal $userProfile + + handleUpdateModeratorStatus = (elem, isModerator) -> + url = Discussion.urlFor('update_moderator_status', $$profiled_user_id) + Discussion.safeAjax + $elem: $(elem) + url: url + type: "POST" + dataType: 'json' + data: + is_moderator: isModerator + error: (response, textStatus, e) -> + console.log e + success: (response, textStatus) -> + parent = $userProfile.parent() + $userProfile.replaceWith(response.html) + Discussion.initializeUserProfile parent.children(".user-profile") + + Discussion.bindLocalEvents $local, + "click .sidebar-revoke-moderator-button": (event) -> + handleUpdateModeratorStatus(this, false) + "click .sidebar-promote-moderator-button": (event) -> + handleUpdateModeratorStatus(this, true) diff --git a/lms/static/coffee/src/discussion/utils.coffee b/lms/static/coffee/src/discussion/utils.coffee index f8ee4bea83..c2ee2dcd6a 100644 --- a/lms/static/coffee/src/discussion/utils.coffee +++ b/lms/static/coffee/src/discussion/utils.coffee @@ -18,31 +18,32 @@ wmdEditors = {} urlFor: (name, param, param1) -> { - follow_discussion : "/courses/#{$$course_id}/discussion/#{param}/follow" - unfollow_discussion : "/courses/#{$$course_id}/discussion/#{param}/unfollow" - create_thread : "/courses/#{$$course_id}/discussion/#{param}/threads/create" - search_similar_threads : "/courses/#{$$course_id}/discussion/#{param}/threads/search_similar" - update_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/update" - create_comment : "/courses/#{$$course_id}/discussion/threads/#{param}/reply" - delete_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/delete" - upvote_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/upvote" - downvote_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/downvote" - undo_vote_for_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/unvote" - follow_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/follow" - unfollow_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/unfollow" - openclose_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/close" - update_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/update" - endorse_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/endorse" - create_sub_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/reply" - delete_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/delete" - upvote_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/upvote" - downvote_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/downvote" - undo_vote_for_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/unvote" - upload : "/courses/#{$$course_id}/discussion/upload" - search : "/courses/#{$$course_id}/discussion/forum/search" - tags_autocomplete : "/courses/#{$$course_id}/discussion/threads/tags/autocomplete" - retrieve_discussion : "/courses/#{$$course_id}/discussion/forum/#{param}/inline" - retrieve_single_thread : "/courses/#{$$course_id}/discussion/forum/#{param}/threads/#{param1}" + follow_discussion : "/courses/#{$$course_id}/discussion/#{param}/follow" + unfollow_discussion : "/courses/#{$$course_id}/discussion/#{param}/unfollow" + create_thread : "/courses/#{$$course_id}/discussion/#{param}/threads/create" + search_similar_threads : "/courses/#{$$course_id}/discussion/#{param}/threads/search_similar" + update_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/update" + create_comment : "/courses/#{$$course_id}/discussion/threads/#{param}/reply" + delete_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/delete" + upvote_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/upvote" + downvote_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/downvote" + undo_vote_for_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/unvote" + follow_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/follow" + unfollow_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/unfollow" + openclose_thread : "/courses/#{$$course_id}/discussion/threads/#{param}/close" + update_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/update" + endorse_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/endorse" + create_sub_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/reply" + delete_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/delete" + upvote_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/upvote" + downvote_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/downvote" + undo_vote_for_comment : "/courses/#{$$course_id}/discussion/comments/#{param}/unvote" + upload : "/courses/#{$$course_id}/discussion/upload" + search : "/courses/#{$$course_id}/discussion/forum/search" + tags_autocomplete : "/courses/#{$$course_id}/discussion/threads/tags/autocomplete" + retrieve_discussion : "/courses/#{$$course_id}/discussion/forum/#{param}/inline" + retrieve_single_thread : "/courses/#{$$course_id}/discussion/forum/#{param}/threads/#{param1}" + update_moderator_status : "/courses/#{$$course_id}/discussion/users/#{param}/update_moderator_status" }[name] safeAjax: (params) -> diff --git a/lms/templates/discussion/_user_profile.html b/lms/templates/discussion/_user_profile.html new file mode 100644 index 0000000000..82f12c56b7 --- /dev/null +++ b/lms/templates/discussion/_user_profile.html @@ -0,0 +1,22 @@ +<%! from django_comment_client.utils import pluralize %> +<%! from django_comment_client.permissions import has_permission, check_permissions_by_view %> + + + diff --git a/lms/templates/discussion/ajax_user_profile.html b/lms/templates/discussion/ajax_user_profile.html new file mode 100644 index 0000000000..c24081845f --- /dev/null +++ b/lms/templates/discussion/ajax_user_profile.html @@ -0,0 +1 @@ +<%include file="_user_profile.html" /> diff --git a/lms/templates/discussion/user_profile.html b/lms/templates/discussion/user_profile.html index 01d9c66c61..87b802e66a 100644 --- a/lms/templates/discussion/user_profile.html +++ b/lms/templates/discussion/user_profile.html @@ -1,5 +1,4 @@ -<%! from django_comment_client.utils import pluralize %> -<%! from django_comment_client.permissions import has_permission, check_permissions_by_view %> +<%! from django.template.defaultfilters import escapejs %> <%inherit file="../main.html" /> <%namespace name='static' file='../static_content.html'/> @@ -20,24 +19,9 @@
+ + From dd80cbc42361a9e5dfb837ba09153fe11ecd0ca8 Mon Sep 17 00:00:00 2001 From: Rocky Duan Date: Tue, 14 Aug 2012 16:57:20 -0700 Subject: [PATCH 2/2] confirm before changing moderator status --- lms/static/coffee/src/discussion/user_profile.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lms/static/coffee/src/discussion/user_profile.coffee b/lms/static/coffee/src/discussion/user_profile.coffee index e41751e1ee..a431688f96 100644 --- a/lms/static/coffee/src/discussion/user_profile.coffee +++ b/lms/static/coffee/src/discussion/user_profile.coffee @@ -8,6 +8,8 @@ Discussion = @Discussion $local = Discussion.generateLocal $userProfile handleUpdateModeratorStatus = (elem, isModerator) -> + confirmValue = confirm("Are you sure?") + if not confirmValue then return url = Discussion.urlFor('update_moderator_status', $$profiled_user_id) Discussion.safeAjax $elem: $(elem)