From b52e72b5c74c4c672cf8e81cf83f8c281bd765c2 Mon Sep 17 00:00:00 2001 From: Evgeny Fadeev Date: Mon, 20 Aug 2012 10:54:41 -0400 Subject: popups for shared with users and groups lists --- .../management/commands/askbot_add_test_content.py | 2 +- askbot/skins/common/media/js/post.js | 74 +++++++++++- askbot/skins/common/media/js/utils.js | 126 +++++++++++++++++++++ askbot/skins/default/templates/question.html | 1 + .../default/templates/question/javascript.html | 1 + .../default/templates/widgets/groups_list.html | 4 + .../skins/default/templates/widgets/user_list.html | 8 +- askbot/skins/loaders.py | 12 +- askbot/views/commands.py | 33 +++++- askbot/views/readers.py | 4 +- 10 files changed, 250 insertions(+), 15 deletions(-) create mode 100644 askbot/skins/default/templates/widgets/groups_list.html diff --git a/askbot/management/commands/askbot_add_test_content.py b/askbot/management/commands/askbot_add_test_content.py index ace629d0..17d3ffd0 100644 --- a/askbot/management/commands/askbot_add_test_content.py +++ b/askbot/management/commands/askbot_add_test_content.py @@ -14,7 +14,7 @@ NUM_COMMENTS = 20 # karma. This can be calculated dynamically - max of MIN_REP_TO_... settings INITIAL_REPUTATION = 500 -BAD_STUFF = "" +BAD_STUFF = ''#"" # Defining template inputs. USERNAME_TEMPLATE = BAD_STUFF + "test_user_%s" diff --git a/askbot/skins/common/media/js/post.js b/askbot/skins/common/media/js/post.js index 5f2484ee..cafc6840 100644 --- a/askbot/skins/common/media/js/post.js +++ b/askbot/skins/common/media/js/post.js @@ -204,6 +204,65 @@ var CPValidator = function(){ }; }(); +/** + * @constructor + */ +var ThreadUsersDialog = function() { + SimpleControl.call(this); + this._heading_text = 'Add heading with the setHeadingText()'; +}; +inherits(ThreadUsersDialog, SimpleControl); + +ThreadUsersDialog.prototype.setHeadingText = function(text) { + this._heading_text = text; +}; + +ThreadUsersDialog.prototype.showUsers = function(html) { + this._dialog.setContent(html); + this._dialog.show(); +}; + +ThreadUsersDialog.prototype.startShowingUsers = function() { + var me = this; + var threadId = this._threadId; + var url = this._url; + $.ajax({ + type: 'GET', + data: {'thread_id': threadId}, + dataType: 'json', + url: url, + cache: false, + success: function(data){ + if (data['success'] == true){ + me.showUsers(data['html']); + } else { + showMessage(me.getElement(), data['message'], 'after'); + } + } + }); +}; + +ThreadUsersDialog.prototype.decorate = function(element) { + this._element = element; + ThreadUsersDialog.superClass_.decorate.call(this, element); + this._threadId = element.data('threadId'); + this._url = element.data('url'); + var dialog = new ModalDialog(); + dialog.setRejectButtonText(''); + dialog.setAcceptButtonText(gettext('Back to the question')); + dialog.setHeadingText(this._heading_text); + dialog.setAcceptHandler(function(){ dialog.hide(); }); + var dialog_element = dialog.getElement(); + $(dialog_element).find('.modal-footer').css('text-align', 'center'); + $(document).append(dialog_element); + this._dialog = dialog; + var me = this; + this.setHandler(function(){ + me.startShowingUsers(); + }); +}; + + /** * @constructor */ @@ -249,7 +308,7 @@ DraftPost.prototype.getSaveHandler = function() { return function(save_synchronously) { if (me.shouldSave()) { $.ajax({ - type: 'POST', + type: 'GET', cache: false, dataType: 'json', async: save_synchronously ? false : true, @@ -3867,6 +3926,19 @@ $(document).ready(function() { }); usersAc.decorate(usersInput); } + + var showSharedUsers = $('.see-related-users'); + if (showSharedUsers.length) { + var usersPopup = new ThreadUsersDialog(); + usersPopup.setHeadingText(gettext('Shared with the following users:')); + usersPopup.decorate(showSharedUsers); + } + var showSharedGroups = $('.see-related-groups'); + if (showSharedGroups.length) { + var groupsPopup = new ThreadUsersDialog(); + groupsPopup.setHeadingText(gettext('Shared with the following groups:')); + groupsPopup.decorate(showSharedGroups); + } }); diff --git a/askbot/skins/common/media/js/utils.js b/askbot/skins/common/media/js/utils.js index 01239304..b8a716ec 100644 --- a/askbot/skins/common/media/js/utils.js +++ b/askbot/skins/common/media/js/utils.js @@ -568,6 +568,132 @@ DeleteIcon.prototype.setContent = function(content){ } } +/** + * @contstructor + * Simple modal dialog with Ok/Cancel buttons by default + */ +var ModalDialog = function() { + WrappedElement.call(this); + this._accept_button_text = gettext('Ok'); + this._reject_button_text = gettext('Cancel'); + this._heading_text = 'Add heading by setHeadingText()'; + this._initial_content = undefined; + this._accept_handler = function(){}; + var me = this; + this._reject_handler = function() { me.hide(); }; + this._content_element = undefined; +}; +inherits(ModalDialog, WrappedElement); + +ModalDialog.prototype.show = function() { + this._element.modal('show'); +}; + +ModalDialog.prototype.hide = function() { + this._element.modal('hide'); +}; + +ModalDialog.prototype.setContent = function(content) { + this._initial_content = content; + if (this._content_element) { + this._content_element.html(content); + } +}; + +ModalDialog.prototype.prependContent = function(content) { + this._content_element.prepend(content); +}; + +ModalDialog.prototype.setHeadingText = function(text) { + this._heading_text = text; +}; + +ModalDialog.prototype.setAcceptButtonText = function(text) { + this._accept_button_text = text; +}; + +ModalDialog.prototype.setRejectButtonText = function(text) { + this._reject_button_text = text; +}; + +ModalDialog.prototype.setAcceptHandler = function(handler) { + this._accept_handler = handler; +}; + +ModalDialog.prototype.setRejectHandler = function(handler) { + this._reject_handler = handler; +}; + +ModalDialog.prototype.clearMessages = function() { + this._element.find('.alert').remove(); +}; + +ModalDialog.prototype.setMessage = function(text, message_type) { + var box = new AlertBox(); + box.setText(text); + if (message_type === 'error') { + box.setError(true); + } + this.prependContent(box.getElement()); +}; + +ModalDialog.prototype.createDom = function() { + this._element = this.makeElement('div') + var element = this._element; + + element.addClass('modal'); + + //1) create header + var header = this.makeElement('div') + header.addClass('modal-header'); + element.append(header); + + var close_link = this.makeElement('div'); + close_link.addClass('close'); + close_link.attr('data-dismiss', 'modal'); + close_link.html('x'); + header.append(close_link); + + var title = this.makeElement('h3'); + title.html(this._heading_text); + header.append(title); + + //2) create content + var body = this.makeElement('div') + body.addClass('modal-body'); + element.append(body); + this._content_element = body; + if (this._initial_content) { + this._content_element.append(this._initial_content); + } + + //3) create footer with accept and reject buttons (ok/cancel). + var footer = this.makeElement('div'); + footer.addClass('modal-footer'); + element.append(footer); + + var accept_btn = this.makeElement('button'); + accept_btn.addClass('btn btn-primary'); + accept_btn.html(this._accept_button_text); + footer.append(accept_btn); + + if (this._reject_button_text) { + var reject_btn = this.makeElement('button'); + reject_btn.addClass('btn cancel'); + reject_btn.html(this._reject_button_text); + footer.append(reject_btn); + } + + //4) attach event handlers to the buttons + setupButtonEventHandlers(accept_btn, this._accept_handler); + if (this._reject_button_text) { + setupButtonEventHandlers(reject_btn, this._reject_handler); + } + setupButtonEventHandlers(close_link, this._reject_handler); + + this.hide(); +}; + /** * attaches a modal menu with a text editor * to a link. The modal menu is from bootstrap.js diff --git a/askbot/skins/default/templates/question.html b/askbot/skins/default/templates/question.html index c810aecb..7c3ef372 100644 --- a/askbot/skins/default/templates/question.html +++ b/askbot/skins/default/templates/question.html @@ -8,6 +8,7 @@ {% block forestyle %} + {% endblock %} {% block forejs %} + {% if settings.EDITOR_TYPE == 'markdown' %} diff --git a/askbot/skins/default/templates/widgets/groups_list.html b/askbot/skins/default/templates/widgets/groups_list.html new file mode 100644 index 00000000..0669f34f --- /dev/null +++ b/askbot/skins/default/templates/widgets/groups_list.html @@ -0,0 +1,4 @@ +{% import "macros.html" as macros %} +{% for group in groups %} +

{{ macros.user_group(group) }}

+{% endfor %} diff --git a/askbot/skins/default/templates/widgets/user_list.html b/askbot/skins/default/templates/widgets/user_list.html index e51abc5b..52cf8bd4 100644 --- a/askbot/skins/default/templates/widgets/user_list.html +++ b/askbot/skins/default/templates/widgets/user_list.html @@ -1,4 +1,4 @@ -{%from "macros.html" import gravatar %} +{% import "macros.html" as macros %}
@@ -6,10 +6,10 @@ {% for user in users %}
    -
  • {{ gravatar(user, 32) }}
  • -
  • {{user.username|escape}}{{ user_country_flag(user) }}
  • +
  • {{ macros.gravatar(user, 32) }}
  • +
  • {{user.username|escape}}{{ macros.user_country_flag(user) }}
  • {{ - user_score_and_badge_summary( + macros.user_score_and_badge_summary( user, karma_mode = karma_mode, badges_mode = badges_mode diff --git a/askbot/skins/loaders.py b/askbot/skins/loaders.py index aa3188e9..c1367fe5 100644 --- a/askbot/skins/loaders.py +++ b/askbot/skins/loaders.py @@ -115,14 +115,20 @@ def get_template(template, request = None): skin.set_language(request.LANGUAGE_CODE) return skin.get_template(template) +def render_into_skin_as_string(template, data, request): + context = RequestContext(request, data) + template = get_template(template, request) + return template.render(context) + def render_into_skin(template, data, request, mimetype = 'text/html'): """in the future this function will be able to switch skin depending on the site administrator/user selection right now only admins can switch """ - context = RequestContext(request, data) - template = get_template(template, request) - return HttpResponse(template.render(context), mimetype = mimetype) + return HttpResponse( + render_into_skin_as_string(template, data, request), + mimetype=mimetype + ) def render_text_into_skin(text, data, request): context = RequestContext(request, data) diff --git a/askbot/views/commands.py b/askbot/views/commands.py index 123fc112..aa602f55 100644 --- a/askbot/views/commands.py +++ b/askbot/views/commands.py @@ -30,6 +30,7 @@ from askbot.utils import decorators from askbot.utils import url_utils from askbot import mail from askbot.skins.loaders import render_into_skin, get_template +from askbot.skins.loaders import render_into_skin_as_string from askbot import const @@ -475,15 +476,39 @@ def get_tags_by_wildcard(request): re_data = simplejson.dumps({'tag_count': count, 'tag_names': list(names)}) return HttpResponse(re_data, mimetype = 'application/json') -@decorators.ajax_only @decorators.get_only def get_thread_shared_users(request): - pass + """returns snippet of html with users""" + thread_id = request.GET['thread_id'] + thread_id = IntegerField().clean(thread_id) + thread = models.Thread.objects.get(id=thread_id) + users = thread.get_users_shared_with() + data = { + 'users': users, + } + html = render_into_skin_as_string('widgets/user_list.html', data, request) + re_data = simplejson.dumps({ + 'html': html, + 'users_count': users.count(), + 'success': True + }) + return HttpResponse(re_data, mimetype='application/json') -@decorators.ajax_only @decorators.get_only def get_thread_shared_groups(request): - pass + """returns snippet of html with groups""" + thread_id = request.GET['thread_id'] + thread_id = IntegerField().clean(thread_id) + thread = models.Thread.objects.get(id=thread_id) + groups = thread.get_groups_shared_with() + data = {'groups': groups} + html = render_into_skin_as_string('widgets/groups_list.html', data, request) + re_data = simplejson.dumps({ + 'html': html, + 'groups_count': groups.count(), + 'success': True + }) + return HttpResponse(re_data, mimetype='application/json') @decorators.ajax_only def get_html_template(request): diff --git a/askbot/views/readers.py b/askbot/views/readers.py index 268227eb..6cc49cc5 100644 --- a/askbot/views/readers.py +++ b/askbot/views/readers.py @@ -568,12 +568,12 @@ def question(request, id):#refactor - long subroutine. display question body, an #shared with ... users_count, groups_count = thread.get_sharing_info() shared_users = thread.get_users_shared_with( - max_count=2, + max_count=2,#"visitor" is implicit exclude_user=request.user ) sharing_info = { 'users': shared_users, - 'groups': thread.get_groups_shared_with(max_count=2), + 'groups': thread.get_groups_shared_with(max_count=3), 'more_users_count': max(0, users_count - 3), 'more_groups_count': max(0, groups_count - 3) } -- cgit v1.2.3-1-g7c22