summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeny Fadeev <evgeny.fadeev@gmail.com>2012-05-07 09:10:27 -0400
committerEvgeny Fadeev <evgeny.fadeev@gmail.com>2012-05-07 09:10:27 -0400
commit0c46a9b987373e5a791cf1c5bd731a682aa652c6 (patch)
treec0317f5f8c9cd0d32dae5253ec52599aa2ecf97b
parent10279a75eeee523dd16db092b9e1da424f9060dc (diff)
downloadaskbot-0c46a9b987373e5a791cf1c5bd731a682aa652c6.tar.gz
askbot-0c46a9b987373e5a791cf1c5bd731a682aa652c6.tar.bz2
askbot-0c46a9b987373e5a791cf1c5bd731a682aa652c6.zip
saving pre-approved emails&domains works, but no validation yet
-rw-r--r--askbot/skins/common/media/js/post.js6
-rw-r--r--askbot/skins/common/media/js/utils.js204
-rw-r--r--askbot/skins/default/templates/users.html1
-rw-r--r--askbot/skins/default/templates/widgets/group_info.html21
-rw-r--r--askbot/urls.py5
-rw-r--r--askbot/views/commands.py28
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);
}
@@ -479,6 +496,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.)
* or toggle some state on/off
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 %}';
</script>
+ <script type="text/javascript" src='{{"/bootstrap/js/bootstrap.js"|media}}' />
<script type='text/javascript' src='{{"/js/editor.js"|media}}'></script>
<script type='text/javascript' src='{{"/js/wmd/showdown.js"|media}}'></script>
<script type='text/javascript' src='{{"/js/wmd/wmd.js"|media}}'></script>
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 %}
</label>
<br/>
+ <a
+ id="preapproved-emails"
+ title="{% trans %}list of email addresses of pre-approved users{% endtrans %}"
+ data-object-id="{{group.group_profile.id}}"
+ data-model-name="GroupProfile"
+ data-property-name="preapproved_emails"
+ data-url="{% url edit_object_property_text %}"
+ data-editor-heading="{% trans %}List of preapproved email addresses{% endtrans %}"
+ data-help-text="{% trans %}Users with these email adderesses will be added to the group automatically.{% endtrans %}"
+ >{% trans %}edit preapproved emails{% endtrans %}</a>
+ <br/>
+ <a
+ id="preapproved-email-domains"
+ title="{% trans %}list of preapproved email address domain names{% endtrans %}"
+ data-object-id="{{group.group_profile.id}}"
+ data-model-name="GroupProfile"
+ data-property-name="preapproved_email_domains"
+ data-url="{% url edit_object_property_text %}"
+ data-editor-heading="{% trans %}List of preapproved email domain names{% endtrans %}"
+ data-help-text="{% trans %}Users whose email adderesses belong to these domains will be added to the group automatically.{% endtrans %}"
+ >{% trans %}edit preapproved email domains{% endtrans %}</a>
</div>
{% endif %}
</div>
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
@@ -825,6 +825,34 @@ def toggle_group_profile_property(request):
@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
def join_or_leave_group(request):
"""only current user can join/leave group"""