Merge branch 'profile' of github.com:dementrock/mitx into brittany
This commit is contained in:
@@ -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<user_id>\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<thread_id>[\w\-]+)/update$', 'update_thread', name='update_thread'),
|
||||
url(r'threads/(?P<thread_id>[\w\-]+)/reply$', 'create_comment', name='create_comment'),
|
||||
|
||||
@@ -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)
|
||||
@@ -113,6 +117,7 @@ def _create_comment(request, course_id, thread_id=None, parent_id=None):
|
||||
if request.is_ajax():
|
||||
context = {
|
||||
'comment': comment.to_dict(),
|
||||
'course_id': course_id,
|
||||
}
|
||||
html = render_to_string('discussion/ajax_create_comment.html', context)
|
||||
annotated_content_info = utils.get_annotated_content_info(course_id,
|
||||
@@ -289,6 +294,36 @@ 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,
|
||||
'course_id': course_id,
|
||||
'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)
|
||||
|
||||
@@ -326,7 +326,7 @@ initializeFollowThread = (thread) ->
|
||||
handleVote($elem, "down")
|
||||
|
||||
"click .admin-endorse": ->
|
||||
handleEndorse(this, true)#, $(this).is(":checked"))
|
||||
handleEndorse(this, not $content.hasClass("endorsed"))
|
||||
|
||||
"click .discussion-openclose": ->
|
||||
handleOpenClose(this, $(this).text())
|
||||
|
||||
@@ -20,4 +20,4 @@ $ ->
|
||||
Discussion.initializeDiscussion(discussion)
|
||||
Discussion.bindDiscussionEvents(discussion)
|
||||
|
||||
|
||||
Discussion.initializeUserProfile($(".discussion-sidebar>.user-profile"))
|
||||
|
||||
32
lms/static/coffee/src/discussion/user_profile.coffee
Normal file
32
lms/static/coffee/src/discussion/user_profile.coffee
Normal file
@@ -0,0 +1,32 @@
|
||||
if not @Discussion?
|
||||
@Discussion = {}
|
||||
|
||||
Discussion = @Discussion
|
||||
|
||||
@Discussion = $.extend @Discussion,
|
||||
initializeUserProfile: ($userProfile) ->
|
||||
$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)
|
||||
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)
|
||||
@@ -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) ->
|
||||
|
||||
@@ -98,16 +98,6 @@
|
||||
<ul class="discussion-actions">
|
||||
<li>${render_link("discussion-link discussion-reply discussion-reply-" + type, "Reply")}</li>
|
||||
<li><div class="follow-wrapper"></div></li>
|
||||
<li>
|
||||
% if type == "comment" and request.user.is_staff:
|
||||
% if content['endorsed']:
|
||||
<input type="checkbox" checked="checked" class="discussion-link discussion-endorse" id="discussion-endorse-${content['id']}">
|
||||
% else:
|
||||
<input type="checkbox" class="discussion-link discussion-endorse" id="discussion-endorse-${content['id']}">
|
||||
% endif
|
||||
<label class="discussion-link" for="discussion-endorse-${content['id']}">Endorsed</label>
|
||||
% endif
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</%def>
|
||||
|
||||
22
lms/templates/discussion/_user_profile.html
Normal file
22
lms/templates/discussion/_user_profile.html
Normal file
@@ -0,0 +1,22 @@
|
||||
<%! from django_comment_client.utils import pluralize %>
|
||||
<%! from django_comment_client.permissions import has_permission, check_permissions_by_view %>
|
||||
|
||||
|
||||
<div class="user-profile">
|
||||
<%
|
||||
role_names = sorted(map(lambda x: x.name, django_user.roles.all()))
|
||||
%>
|
||||
<div class="sidebar-username">${django_user.username}</div>
|
||||
<div class="sidebar-user-roles">
|
||||
${", ".join(role_names)}
|
||||
</div>
|
||||
<div class="sidebar-threads-count"><span>${discussion_user['threads_count']}</span> ${pluralize('discussion', discussion_user['threads_count'])} started</div>
|
||||
<div class="sidebar-comments-count"><span>${discussion_user['comments_count']}</span> ${pluralize('comment', discussion_user['comments_count'])}</div>
|
||||
% if check_permissions_by_view(user, course.id, content=None, name='update_moderator_status'):
|
||||
% if "Moderator" in role_names:
|
||||
<a href="javascript:void(0)" class="sidebar-revoke-moderator-button">Revoke Moderator provileges</a>
|
||||
% else:
|
||||
<a href="javascript:void(0)" class="sidebar-promote-moderator-button">Promote to Moderator</a>
|
||||
% endif
|
||||
% endif
|
||||
</div>
|
||||
1
lms/templates/discussion/ajax_user_profile.html
Normal file
1
lms/templates/discussion/ajax_user_profile.html
Normal file
@@ -0,0 +1 @@
|
||||
<%include file="_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 @@
|
||||
<div class="course-wrapper">
|
||||
<section aria-label="User Profile" class="user-profile">
|
||||
<nav>
|
||||
<%
|
||||
role_names = sorted(map(lambda x: x.name, django_user.roles.all()))
|
||||
%>
|
||||
|
||||
<article class="sidebar-module discussion-sidebar">
|
||||
<div class="sidebar-username">${django_user.username}</div>
|
||||
<div class="sidebar-user-roles">
|
||||
${", ".join(role_names)}
|
||||
</div>
|
||||
<div class="sidebar-threads-count"><span>${discussion_user['threads_count']}</span> ${pluralize('discussion', discussion_user['threads_count'])} started</div>
|
||||
<div class="sidebar-comments-count"><span>${discussion_user['comments_count']}</span> ${pluralize('comment', discussion_user['comments_count'])}</div>
|
||||
% if check_permissions_by_view(user, course.id, content=None, name='update_moderator_status'):
|
||||
% if "Moderator" in role_names:
|
||||
<a href="javascript:void(0)" class="sidebar-revoke-moderator-button">Revoke Moderator provileges</a>
|
||||
% else:
|
||||
<a href="javascript:void(0)" class="sidebar-promote-moderator-button">Promote to Moderator</a>
|
||||
% endif
|
||||
% endif
|
||||
<%include file="_user_profile.html" />
|
||||
</article>
|
||||
|
||||
</nav>
|
||||
@@ -48,3 +32,8 @@
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script type="text/javascript">
|
||||
var $$profiled_user_id = "${user.id | escapejs}";
|
||||
var $$course_id = "${course.id | escapejs}";
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user