From 0c46a9b987373e5a791cf1c5bd731a682aa652c6 Mon Sep 17 00:00:00 2001 From: Evgeny Fadeev Date: Mon, 7 May 2012 09:10:27 -0400 Subject: saving pre-approved emails&domains works, but no validation yet --- askbot/skins/common/media/js/post.js | 6 + askbot/skins/common/media/js/utils.js | 204 ++++++++++++++++++++- askbot/skins/default/templates/users.html | 1 + .../default/templates/widgets/group_info.html | 21 +++ askbot/urls.py | 5 + askbot/views/commands.py | 28 +++ 6 files changed, 260 insertions(+), 5 deletions(-) diff --git a/askbot/skins/common/media/js/post.js b/askbot/skins/common/media/js/post.js index e018197c..f6157848 100644 --- a/askbot/skins/common/media/js/post.js +++ b/askbot/skins/common/media/js/post.js @@ -2331,6 +2331,12 @@ UserGroupProfileEditor.prototype.decorate = function(element){ var open_group_btn = element.find('#open-or-close-group'); open_group_toggle.decorate(open_group_btn); + var email_editor = new TextPropertyEditor(); + email_editor.decorate(element.find('#preapproved-emails')); + + var domain_editor = new TextPropertyEditor(); + domain_editor.decorate(element.find('#preapproved-email-domains')); + var logo_changer = new ImageChanger(); logo_changer.setImageElement(element.find('.group-logo')); logo_changer.setAjaxData({ diff --git a/askbot/skins/common/media/js/utils.js b/askbot/skins/common/media/js/utils.js index d69777cd..f01f5bcf 100644 --- a/askbot/skins/common/media/js/utils.js +++ b/askbot/skins/common/media/js/utils.js @@ -296,11 +296,13 @@ TippedInput.prototype.getVal = function(){ }; TippedInput.prototype.setVal = function(value){ - this._element.val(value); - if (this.isBlank()){ - this._element.addClass('blank'); - } else { - this._element.removeClass('blank'); + if (value) { + this._element.val(value); + if (this.isBlank()){ + this._element.addClass('blank'); + } else { + this._element.removeClass('blank'); + } } }; @@ -346,6 +348,17 @@ AlertBox.prototype.setClass = function(classes){ } }; +AlertBox.prototype.setError = function(state){ + this._is_error = state; + if (this._element) { + if (state === true) { + this._element.addClass('alert-error'); + } else { + this._element.removeClass('alert-error'); + } + } +}; + AlertBox.prototype.setText = function(text){ this._text = text; if (this._content){ @@ -377,6 +390,10 @@ AlertBox.prototype.createDom = function(){ this._element = this.makeElement('div'); this._element.addClass('alert fade in'); + if (this._is_error) { + this.setError(this._is_error); + } + if (this._classes){ this._element.addClass(this._classes); } @@ -478,6 +495,183 @@ DeleteIcon.prototype.setContent = function(content){ } } +/** + * attaches a modal menu with a text editor + * to a link. The modal menu is from bootstrap.js + */ +var TextPropertyEditor = function(){ + WrappedElement.call(this); + this._editor = null; +}; +inherits(TextPropertyEditor, WrappedElement); + +TextPropertyEditor.prototype.getWidgetData = function(){ + var data = this._element.data(); + return { + object_id: data['objectId'], + model_name: data['modelName'], + property_name: data['propertyName'], + url: data['url'], + help_text: data['helpText'], + editor_heading: data['editorHeading'] + }; +}; + +TextPropertyEditor.prototype.makeEditor = function(){ + if (this._editor) { + return this._editor; + } + var editor = this.makeElement('div') + .addClass('modal'); + this._editor = editor; + + var header = this.makeElement('div') + .addClass('modal-header'); + editor.append(header); + + var close_link = this.makeElement('div') + .addClass('close') + .attr('data-dismiss', 'modal') + .html('x'); + header.append(close_link); + + var title = this.makeElement('h3') + .html(this.getWidgetData()['editor_heading']); + header.append(title); + + var body = this.makeElement('div') + .addClass('modal-body'); + editor.append(body); + + var textarea = this.makeElement('textarea') + .addClass('tipped-input blank') + .val(this.getWidgetData()['help_text']); + body.append(textarea); + + var tipped_input = new TippedInput(); + tipped_input.decorate(textarea); + this._text_input = tipped_input; + + var footer = this.makeElement('div') + .addClass('modal-footer'); + editor.append(footer); + + var save_btn = this.makeElement('button') + .addClass('btn btn-primary') + .html(gettext('Save')); + footer.append(save_btn); + + var cancel_btn = this.makeElement('button') + .addClass('btn cancel') + .html(gettext('Cancel')); + footer.append(cancel_btn); + + var me = this; + setupButtonEventHandlers(save_btn, function(){ + me.saveData(); + }); + setupButtonEventHandlers(cancel_btn, function(){ + editor.modal('hide'); + }); + editor.modal('hide'); + + $(document).append(editor); + return editor; +}; + +TextPropertyEditor.prototype.openEditor = function(){ + this._editor.modal('show'); +}; + +TextPropertyEditor.prototype.clearMessages = function(){ + this._editor.find('.alert').remove(); +}; + +TextPropertyEditor.prototype.getAlert = function(){ + if (this._alert) { + return this._alert; + } else { + var box = new AlertBox(); + this._alert = box; + this._editor.find('.modal-body').prepend(box.getElement()); + return box; + } +}; + +TextPropertyEditor.prototype.showAlert = function(text){ + var box = this.getAlert(); + box.setError(false); + box.setText(text); +}; + +TextPropertyEditor.prototype.showError = function(text){ + var box = this.getAlert(); + box.setError(true); + box.setText(text); +}; + +TextPropertyEditor.prototype.setText = function(text){ + this._text_input.setVal(text); +}; + +TextPropertyEditor.prototype.getText = function(){ + return this._text_input.getVal(); +}; + +TextPropertyEditor.prototype.hideDialog = function(){ + this._editor.modal('hide'); +}; + +TextPropertyEditor.prototype.startOpeningEditor = function(){ + var me = this; + $.ajax({ + type: 'GET', + dataType: 'json', + cache: false, + url: me.getWidgetData()['url'], + data: me.getWidgetData(), + success: function(data){ + if (data['success']) { + me.makeEditor(); + me.setText(data['text']); + me.openEditor(); + } else { + showMessage(me.getElement(), data['message']); + } + } + }); +}; + +TextPropertyEditor.prototype.saveData = function(){ + var data = this.getWidgetData(); + data['text'] = this.getText(); + var me = this; + $.ajax({ + type: 'POST', + dataType: 'json', + cache: false, + url: me.getWidgetData()['url'], + data: data, + success: function(data) { + if (data['success']) { + me.showAlert(gettext('saved')); + setTimeout(function(){ + me.clearMessages(); + me.hideDialog(); + }, 1000); + } else { + me.showError(data['message']); + } + } + }); +}; + +TextPropertyEditor.prototype.decorate = function(element){ + this._element = element; + var me = this; + setupButtonEventHandlers(element, function(){ me.startOpeningEditor() }); +}; + /** * A button on which user can click * and become added to some group (followers, group members, etc.) diff --git a/askbot/skins/default/templates/users.html b/askbot/skins/default/templates/users.html index ec4946bb..343a3494 100644 --- a/askbot/skins/default/templates/users.html +++ b/askbot/skins/default/templates/users.html @@ -82,6 +82,7 @@ askbot['urls']['delete_group_logo_url'] = '{% url delete_group_logo %}'; askbot['urls']['join_or_leave_group'] = '{% url join_or_leave_group %}'; + diff --git a/askbot/skins/default/templates/widgets/group_info.html b/askbot/skins/default/templates/widgets/group_info.html index 7e4b3e1e..601930af 100644 --- a/askbot/skins/default/templates/widgets/group_info.html +++ b/askbot/skins/default/templates/widgets/group_info.html @@ -66,6 +66,27 @@ {% trans %}anyone can join{% endtrans %}
+ {% trans %}edit preapproved emails{% endtrans %} +
+ {% trans %}edit preapproved email domains{% endtrans %} {% endif %} diff --git a/askbot/urls.py b/askbot/urls.py index fb9ea977..fa29e64e 100644 --- a/askbot/urls.py +++ b/askbot/urls.py @@ -217,6 +217,11 @@ urlpatterns = patterns('', views.commands.toggle_group_profile_property, name = 'toggle_group_profile_property' ), + url(#ajax only + r'^edit-object-property-text/', + views.commands.edit_object_property_text, + name = 'edit_object_property_text' + ), url( r'^get-groups-list/', views.commands.get_groups_list, diff --git a/askbot/views/commands.py b/askbot/views/commands.py index 4a560f1e..62db014f 100644 --- a/askbot/views/commands.py +++ b/askbot/views/commands.py @@ -823,6 +823,34 @@ def toggle_group_profile_property(request): return {'is_enabled': new_value} +@csrf.csrf_exempt +@decorators.ajax_only +@decorators.admins_only +def edit_object_property_text(request): + model_name = CharField().clean(request.REQUEST['model_name']) + object_id = IntegerField().clean(request.REQUEST['object_id']) + property_name = CharField().clean(request.REQUEST['property_name']) + + accessible_fields = ( + ('GroupProfile', 'preapproved_emails'), + ('GroupProfile', 'preapproved_email_domains') + ) + + if (model_name, property_name) not in accessible_fields: + raise exceptions.PermissionDenied() + + query_set = models.get_model(model_name).objects.filter(id=object_id) + if request.method == 'POST': + text = CharField().clean(request.POST['text']) + params = dict() + params[str(property_name)] = text #dammit str() + query_set.update(**params) + elif request.method == 'GET': + return {'text': getattr(query_set[0], property_name)} + else: + raise exceptions.PermissionDenied() + + @csrf.csrf_exempt @decorators.ajax_only @decorators.post_only -- cgit v1.2.3-1-g7c22