From 29840888e5eef2f6cf73e59bcc8f346708776169 Mon Sep 17 00:00:00 2001
From: Erick Guan
*a
") end + it 'can include code class correctly' do + expect(PrettyText.cook("```cpp\ncpp\n```")).to match_html("cpp")
+ end
+
end
diff --git a/test/javascripts/helpers/site-settings.js b/test/javascripts/helpers/site-settings.js
index f1266061d8..881162480a 100644
--- a/test/javascripts/helpers/site-settings.js
+++ b/test/javascripts/helpers/site-settings.js
@@ -1,3 +1,3 @@
/*jshint maxlen:10000000 */
-Discourse.SiteSettingsOriginal = {"title":"Discourse Meta","logo_url":"/assets/logo.png","logo_small_url":"/assets/logo-single.png","mobile_logo_url":"","favicon_url":"//meta.discourse.org/uploads/default/2499/79d53726406d87af.ico","allow_user_locale":false,"suggested_topics":7,"track_external_right_clicks":false,"ga_universal_tracking_code":"","ga_universal_domain_name":"auto","ga_tracking_code":"UA-33736483-2","ga_domain_name":"","top_menu":"latest|new|unread|categories|top","post_menu":"like|share|flag|edit|bookmark|delete|admin|reply","post_menu_hidden_items":"edit|delete|admin","share_links":"twitter|facebook|google+|email","category_colors":"BF1E2E|F1592A|F7941D|9EB83B|3AB54A|12A89D|25AAE2|0E76BD|652D90|92278F|ED207B|8C6238|231F20|808281|B3B5B4|283890","enable_mobile_theme":true,"relative_date_duration":14,"category_featured_topics":4,"fixed_category_positions":false,"show_subcategory_list":false,"enable_badges":true,"invite_only":false,"login_required":false,"must_approve_users":false,"enable_local_logins":true,"allow_new_registrations":true,"enable_google_logins":true,"enable_google_oauth2_logins":false,"enable_yahoo_logins":true,"enable_twitter_logins":true,"enable_facebook_logins":true,"enable_github_logins":true,"enable_sso":false,"min_username_length":3,"max_username_length":20,"min_password_length":8,"enable_names":true,"invites_shown":30,"delete_user_max_post_age":60,"delete_all_posts_max":15,"min_post_length":20,"min_private_message_post_length":10,"max_post_length":32000,"min_topic_title_length":15,"max_topic_title_length":255,"min_private_message_title_length":2,"allow_uncategorized_topics":true,"min_title_similar_length":10,"min_body_similar_length":15,"edit_history_visible_to_public":true,"delete_removed_posts_after":24,"traditional_markdown_linebreaks":false,"suppress_reply_directly_below":true,"suppress_reply_directly_above":true,"newuser_max_images":0,"newuser_max_attachments":0,"display_name_on_posts":true,"short_progress_text_threshold":10000,"default_code_lang":"lang-auto","autohighlight_all_code":false,"email_in":false,"max_image_size_kb":3072,"max_attachment_size_kb":1024,"authorized_extensions":".jpg|.jpeg|.png|.gif|.svg|.txt|.ico|.yml","max_image_width":690,"max_image_height":500,"allow_profile_backgrounds":true,"allow_uploaded_avatars":true,"allow_animated_avatars":false,"tl1_requires_read_posts":30,"enable_long_polling":true,"polling_interval":3000,"anon_polling_interval":30000,"flush_timings_secs":5,"tos_url":"","privacy_policy_url":"","tos_accept_required":false,"faq_url":"","allow_restore":false,"maximum_backups":7,"version_checks":true,"suppress_uncategorized_badge":true,"min_search_term_length":3,"topic_views_heat_low":1000,"topic_views_heat_medium":2000,"topic_views_heat_high":5000,"global_notice":"","show_create_topics_notice":true,"available_locales":"cs|da|de|en|es|fr|he|id|it|ja|ko|nb_NO|nl|pl_PL|pt|pt_BR|ru|sv|uk|zh_CN|zh_TW"};
+Discourse.SiteSettingsOriginal = {"title":"Discourse Meta","logo_url":"/assets/logo.png","logo_small_url":"/assets/logo-single.png","mobile_logo_url":"","favicon_url":"//meta.discourse.org/uploads/default/2499/79d53726406d87af.ico","allow_user_locale":false,"suggested_topics":7,"track_external_right_clicks":false,"ga_universal_tracking_code":"","ga_universal_domain_name":"auto","ga_tracking_code":"UA-33736483-2","ga_domain_name":"","top_menu":"latest|new|unread|categories|top","post_menu":"like|share|flag|edit|bookmark|delete|admin|reply","post_menu_hidden_items":"edit|delete|admin","share_links":"twitter|facebook|google+|email","category_colors":"BF1E2E|F1592A|F7941D|9EB83B|3AB54A|12A89D|25AAE2|0E76BD|652D90|92278F|ED207B|8C6238|231F20|808281|B3B5B4|283890","enable_mobile_theme":true,"relative_date_duration":14,"category_featured_topics":4,"fixed_category_positions":false,"show_subcategory_list":false,"enable_badges":true,"invite_only":false,"login_required":false,"must_approve_users":false,"enable_local_logins":true,"allow_new_registrations":true,"enable_google_logins":true,"enable_google_oauth2_logins":false,"enable_yahoo_logins":true,"enable_twitter_logins":true,"enable_facebook_logins":true,"enable_github_logins":true,"enable_sso":false,"min_username_length":3,"max_username_length":20,"min_password_length":8,"enable_names":true,"invites_shown":30,"delete_user_max_post_age":60,"delete_all_posts_max":15,"min_post_length":20,"min_private_message_post_length":10,"max_post_length":32000,"min_topic_title_length":15,"max_topic_title_length":255,"min_private_message_title_length":2,"allow_uncategorized_topics":true,"min_title_similar_length":10,"min_body_similar_length":15,"edit_history_visible_to_public":true,"delete_removed_posts_after":24,"traditional_markdown_linebreaks":false,"suppress_reply_directly_below":true,"suppress_reply_directly_above":true,"newuser_max_images":0,"newuser_max_attachments":0,"display_name_on_posts":true,"short_progress_text_threshold":10000,"default_code_lang":"lang-auto","autohighlight_all_code":false,"email_in":false,"max_image_size_kb":3072,"max_attachment_size_kb":1024,"authorized_extensions":".jpg|.jpeg|.png|.gif|.svg|.txt|.ico|.yml","max_image_width":690,"max_image_height":500,"allow_profile_backgrounds":true,"allow_uploaded_avatars":true,"allow_animated_avatars":false,"tl1_requires_read_posts":30,"enable_long_polling":true,"polling_interval":3000,"anon_polling_interval":30000,"flush_timings_secs":5,"tos_url":"","privacy_policy_url":"","tos_accept_required":false,"faq_url":"","allow_restore":false,"maximum_backups":7,"version_checks":true,"suppress_uncategorized_badge":true,"min_search_term_length":3,"topic_views_heat_low":1000,"topic_views_heat_medium":2000,"topic_views_heat_high":5000,"global_notice":"","show_create_topics_notice":true,"available_locales":"cs|da|de|en|es|fr|he|id|it|ja|ko|nb_NO|nl|pl_PL|pt|pt_BR|ru|sv|uk|zh_CN|zh_TW","highlighted_languages":"apache|bash|cs|cpp|css|coffeescript|diff|xml|http|ini|json|java|javascript|makefile|markdown|nginx|objectivec|ruby|perl|php|python|sql|handlebars"};
Discourse.SiteSettings = jQuery.extend(true, {}, Discourse.SiteSettingsOriginal);
diff --git a/test/javascripts/test_helper.js b/test/javascripts/test_helper.js
index 38c3eb2a96..94b842a546 100644
--- a/test/javascripts/test_helper.js
+++ b/test/javascripts/test_helper.js
@@ -25,8 +25,6 @@
// Pagedown customizations
//= require ../../app/assets/javascripts/pagedown_custom.js
-//= require ../../public/javascripts/highlight.pack.js
-
//= require vendor
//= require htmlparser.js
From 1da2b466ba563e47b9e6fc238622bb3da4dcba31 Mon Sep 17 00:00:00 2001
From: Sam {{{unPinMessage}}}
+ {{#if pinned_globally}} +{{i18n "topic.feature_topic.global_pin_note"}}
++ {{#loading-spinner size="small" condition=loading}} + {{{i18n "topic.feature_topic.already_pinned_globally" count=pinnedGloballyCount}}} + {{/loading-spinner}} +
+ {{else}} +{{i18n "topic.feature_topic.pin_note"}}
++ {{#loading-spinner size="small" condition=loading}} + {{{alreadyPinnedMessage}}} + {{/loading-spinner}} +
+ {{/if}} +{{{pinMessage}}}
+{{i18n "topic.feature_topic.pin_note"}}
++ {{#loading-spinner size="small" condition=loading}} + {{{alreadyPinnedMessage}}} + {{/loading-spinner}} +
+{{i18n "topic.feature_topic.pin_globally"}}
+{{i18n "topic.feature_topic.global_pin_note"}}
++ {{#loading-spinner size="small" condition=loading}} + {{{i18n "topic.feature_topic.already_pinned_globally" count=pinnedGloballyCount}}} + {{/loading-spinner}} +
+{{i18n "topic.feature_topic.remove_banner"}}
+ {{else}} + {{d-button action="makeBanner" icon="bullhorn" label="topic.actions.make_banner" class="btn-primary btn-small"}} +{{i18n "topic.feature_topic.make_banner"}}
+ {{/if}} +{{i18n "topic.feature_topic.banner_note"}}
++ {{#loading-spinner size="small" condition=loading}} + {{{i18n "topic.feature_topic.already_banner" count=bannerCount}}} + {{/loading-spinner}} +
+{{{unPinMessage}}}
- {{#if pinned_globally}} -{{i18n "topic.feature_topic.global_pin_note"}}
-- {{#loading-spinner size="small" condition=loading}} - {{{i18n "topic.feature_topic.already_pinned_globally" count=pinnedGloballyCount}}} - {{/loading-spinner}} -
- {{else}} +{{{unPinMessage}}}
+ {{#if pinned_globally}} +{{i18n "topic.feature_topic.global_pin_note"}}
++ {{#loading-spinner size="small" condition=loading}} + {{{i18n "topic.feature_topic.already_pinned_globally" count=pinnedGloballyCount}}} + {{/loading-spinner}} +
+ {{else}} +{{i18n "topic.feature_topic.pin_note"}}
++ {{#loading-spinner size="small" condition=loading}} + {{{alreadyPinnedMessage}}} + {{/loading-spinner}} +
+ {{/if}} +{{{pinMessage}}}
{{i18n "topic.feature_topic.pin_note"}}
{{#loading-spinner size="small" condition=loading}} {{{alreadyPinnedMessage}}} {{/loading-spinner}}
- {{/if}} +{{{pinMessage}}}
-{{i18n "topic.feature_topic.pin_note"}}
-- {{#loading-spinner size="small" condition=loading}} - {{{alreadyPinnedMessage}}} - {{/loading-spinner}} -
-{{i18n "topic.feature_topic.pin_globally"}}
-{{i18n "topic.feature_topic.global_pin_note"}}
-- {{#loading-spinner size="small" condition=loading}} - {{{i18n "topic.feature_topic.already_pinned_globally" count=pinnedGloballyCount}}} - {{/loading-spinner}} -
+{{i18n "topic.feature_topic.pin_globally"}}
+{{i18n "topic.feature_topic.global_pin_note"}}
++ {{#loading-spinner size="small" condition=loading}} + {{{i18n "topic.feature_topic.already_pinned_globally" count=pinnedGloballyCount}}} + {{/loading-spinner}} +
+{{i18n "topic.feature_topic.remove_banner"}}
- {{else}} - {{d-button action="makeBanner" icon="bullhorn" label="topic.actions.make_banner" class="btn-primary btn-small"}} -{{i18n "topic.feature_topic.make_banner"}}
- {{/if}} -{{i18n "topic.feature_topic.banner_note"}}
-- {{#loading-spinner size="small" condition=loading}} - {{{i18n "topic.feature_topic.already_banner" count=bannerCount}}} - {{/loading-spinner}} -
+{{i18n "topic.feature_topic.remove_banner"}}
+ {{else}} +{{i18n "topic.feature_topic.make_banner"}}
+ {{/if}} +{{i18n "topic.feature_topic.banner_note"}}
++ {{#loading-spinner size="small" condition=loading}} + {{{i18n "topic.feature_topic.already_banner" count=bannerCount}}} + {{/loading-spinner}} +
+...code blocks text = text.replace(/(^\n*|\n\n)
([\s\S]*?)<\/pre>/ig, function(_, before, content) {
var hash = md5(content);
- hoisted[hash] = escape(showBackslashEscapedCharacters(content.trim()));
+ hoisted[hash] = escape(showBackslashEscapedCharacters(removeEmptyLines(content)));
return before + "" + hash + "
";
});
// fenced code blocks (AKA GitHub code blocks)
text = text.replace(/(^\n*|\n\n)```([a-z0-9\-]*)\n([\s\S]*?)\n```/g, function(_, before, language, content) {
var hash = md5(content);
- hoisted[hash] = escape(showBackslashEscapedCharacters(content.trim()));
+ hoisted[hash] = escape(showBackslashEscapedCharacters(removeEmptyLines(content)));
return before + "```" + language + "\n" + hash + "\n```";
});
@@ -209,9 +214,7 @@ function hoistCodeBlocksAndSpans(text) {
}
// we can safely hoist the code block
var hash = md5(content);
- // only remove trailing whitespace
- content = content.replace(/\s+$/, "");
- hoisted[hash] = escape(outdent(showBackslashEscapedCharacters(content)));
+ hoisted[hash] = escape(outdent(showBackslashEscapedCharacters(removeEmptyLines(content))));
return before + " " + hash + "\n";
});
diff --git a/test/javascripts/lib/markdown-test.js.es6 b/test/javascripts/lib/markdown-test.js.es6
index 6ae727c550..f5859165f1 100644
--- a/test/javascripts/lib/markdown-test.js.es6
+++ b/test/javascripts/lib/markdown-test.js.es6
@@ -529,6 +529,6 @@ test("censoring", function() {
test("code blocks/spans hoisting", function() {
cooked("```\n\n some code\n```",
- "some code
",
+ " some code
",
"it works when nesting standard markdown code blocks within a fenced code block");
});
From 56e01a766b4e3ebc64b37dcc3b3da1b2a6f7bbb1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9gis=20Hanol?=
Date: Tue, 17 Mar 2015 17:29:18 +0100
Subject: [PATCH 043/114] FIX: clear emoji cache after restore
---
lib/backup_restore/restorer.rb | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/lib/backup_restore/restorer.rb b/lib/backup_restore/restorer.rb
index 8b7fcff2d0..bccd2e607d 100644
--- a/lib/backup_restore/restorer.rb
+++ b/lib/backup_restore/restorer.rb
@@ -50,6 +50,7 @@ module BackupRestore
migrate_database
reconnect_database
reload_site_settings
+ clear_emoji_cache
disable_readonly_mode
### READ-ONLY / END ###
@@ -267,6 +268,11 @@ module BackupRestore
SiteSetting.refresh!
end
+ def clear_emoji_cache
+ log "Clearing emoji cache..."
+ Emoji.clear_cache
+ end
+
def extract_uploads
if `tar --list --file #{@tar_filename} | grep 'uploads/'`.present?
log "Extracting uploads..."
From 9cbd0f8e7867daa42acb74a4da9473270fc3643a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9gis=20Hanol?=
Date: Tue, 17 Mar 2015 22:59:05 +0100
Subject: [PATCH 044/114] UX: separate custom from automatic groups in user
admin REFACTOR: some moar ES6 refactoring
---
.../components/admin-group-selector.js.es6 | 35 +-
.../admin/controllers/admin-user-index.js.es6 | 81 +--
.../{admin_user.js => admin-user.js.es6} | 475 +++++++++---------
.../admin/templates/user_index.hbs | 109 ++--
config/locales/client.en.yml | 4 +
5 files changed, 349 insertions(+), 355 deletions(-)
rename app/assets/javascripts/admin/models/{admin_user.js => admin-user.js.es6} (51%)
diff --git a/app/assets/javascripts/admin/components/admin-group-selector.js.es6 b/app/assets/javascripts/admin/components/admin-group-selector.js.es6
index f838830b08..0f8841889e 100644
--- a/app/assets/javascripts/admin/components/admin-group-selector.js.es6
+++ b/app/assets/javascripts/admin/components/admin-group-selector.js.es6
@@ -1,31 +1,36 @@
export default Ember.Component.extend({
tagName: 'div',
- didInsertElement: function(){
+ _init: function(){
this.$("input").select2({
multiple: true,
width: '100%',
- query: function(opts){
- opts.callback({
- results: this.get("available").map(this._format)
- });
+ query: function(opts) {
+ opts.callback({ results: this.get("available").map(this._format) });
}.bind(this)
}).on("change", function(evt) {
if (evt.added){
- this.triggerAction({action: "groupAdded",
- actionContext: this.get("available"
- ).findBy("id", evt.added.id)});
+ this.triggerAction({
+ action: "groupAdded",
+ actionContext: this.get("available").findBy("id", evt.added.id)
+ });
} else if (evt.removed) {
- this.triggerAction({action:"groupRemoved",
- actionContext: this.get("selected"
- ).findBy("id", evt.removed.id)});
+ this.triggerAction({
+ action:"groupRemoved",
+ actionContext: evt.removed.id
+ });
}
}.bind(this));
- this._refreshOnReset();
- },
- _format: function(item){
- return {"text": item.name, "id": item.id, "locked": item.automatic};
+ this._refreshOnReset();
+ }.on("didInsertElement"),
+
+ _format(item) {
+ return {
+ "text": item.name,
+ "id": item.id,
+ "locked": item.automatic
+ };
},
_refreshOnReset: function() {
diff --git a/app/assets/javascripts/admin/controllers/admin-user-index.js.es6 b/app/assets/javascripts/admin/controllers/admin-user-index.js.es6
index 89e4c2441b..88d775b1b8 100644
--- a/app/assets/javascripts/admin/controllers/admin-user-index.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-user-index.js.es6
@@ -11,58 +11,61 @@ export default ObjectController.extend(CanCheckEmails, {
primaryGroupDirty: Discourse.computed.propertyNotEqual('originalPrimaryGroupId', 'primary_group_id'),
- custom_groups: Ember.computed.filter("model.groups", function(g){
- return (!g.automatic && g.visible);
- }),
+ automaticGroups: function() {
+ return this.get("model.automaticGroups").map((g) => g.name).join(", ");
+ }.property("model.automaticGroups"),
userFields: function() {
- var siteUserFields = this.site.get('user_fields'),
- userFields = this.get('user_fields');
+ const siteUserFields = this.site.get('user_fields'),
+ userFields = this.get('user_fields');
if (!Ember.isEmpty(siteUserFields)) {
return siteUserFields.map(function(uf) {
- var value = userFields ? userFields[uf.get('id').toString()] : null;
- return {name: uf.get('name'), value: value};
+ let value = userFields ? userFields[uf.get('id').toString()] : null;
+ return { name: uf.get('name'), value: value };
});
}
return [];
}.property('user_fields.@each'),
actions: {
- toggleTitleEdit: function() {
+ toggleTitleEdit() {
this.toggleProperty('editingTitle');
},
- saveTitle: function() {
- Discourse.ajax("/users/" + this.get('username').toLowerCase(), {
+ saveTitle() {
+ const self = this;
+
+ return Discourse.ajax("/users/" + this.get('username').toLowerCase(), {
data: {title: this.get('title')},
type: 'PUT'
- }).then(null, function(e){
+ }).catch(function(e) {
bootbox.alert(I18n.t("generic_error_with_reason", {error: "http: " + e.status + " - " + e.body}));
+ }).finally(function() {
+ self.send('toggleTitleEdit');
});
-
- this.send('toggleTitleEdit');
},
- generateApiKey: function() {
+ generateApiKey() {
this.get('model').generateApiKey();
},
- groupAdded: function(added){
+ groupAdded(added) {
this.get('model').groupAdded(added).catch(function() {
bootbox.alert(I18n.t('generic_error'));
});
},
- groupRemoved: function(removed){
- this.get('model').groupRemoved(removed).catch(function() {
+ groupRemoved(groupId) {
+ this.get('model').groupRemoved(groupId).catch(function() {
bootbox.alert(I18n.t('generic_error'));
});
},
- savePrimaryGroup: function() {
- var self = this;
- Discourse.ajax("/admin/users/" + this.get('id') + "/primary_group", {
+ savePrimaryGroup() {
+ const self = this;
+
+ return Discourse.ajax("/admin/users/" + this.get('id') + "/primary_group", {
type: 'PUT',
data: {primary_group_id: this.get('primary_group_id')}
}).then(function () {
@@ -72,33 +75,41 @@ export default ObjectController.extend(CanCheckEmails, {
});
},
- resetPrimaryGroup: function() {
+ resetPrimaryGroup() {
this.set('primary_group_id', this.get('originalPrimaryGroupId'));
},
- regenerateApiKey: function() {
- var self = this;
- bootbox.confirm(I18n.t("admin.api.confirm_regen"), I18n.t("no_value"), I18n.t("yes_value"), function(result) {
- if (result) {
- self.get('model').generateApiKey();
+ regenerateApiKey() {
+ const self = this;
+
+ bootbox.confirm(
+ I18n.t("admin.api.confirm_regen"),
+ I18n.t("no_value"),
+ I18n.t("yes_value"),
+ function(result) {
+ if (result) { self.get('model').generateApiKey(); }
}
- });
+ );
},
- revokeApiKey: function() {
- var self = this;
- bootbox.confirm(I18n.t("admin.api.confirm_revoke"), I18n.t("no_value"), I18n.t("yes_value"), function(result) {
- if (result) {
- self.get('model').revokeApiKey();
+ revokeApiKey() {
+ const self = this;
+
+ bootbox.confirm(
+ I18n.t("admin.api.confirm_revoke"),
+ I18n.t("no_value"),
+ I18n.t("yes_value"),
+ function(result) {
+ if (result) { self.get('model').revokeApiKey(); }
}
- });
+ );
},
- anonymize: function() {
+ anonymize() {
this.get('model').anonymize();
},
- destroy: function() {
+ destroy() {
this.get('model').destroy();
}
}
diff --git a/app/assets/javascripts/admin/models/admin_user.js b/app/assets/javascripts/admin/models/admin-user.js.es6
similarity index 51%
rename from app/assets/javascripts/admin/models/admin_user.js
rename to app/assets/javascripts/admin/models/admin-user.js.es6
index b2d6c1a17e..98230fbafe 100644
--- a/app/assets/javascripts/admin/models/admin_user.js
+++ b/app/assets/javascripts/admin/models/admin-user.js.es6
@@ -1,58 +1,36 @@
-/**
- Our data model for dealing with users from the admin section.
+const AdminUser = Discourse.User.extend({
- @class AdminUser
- @extends Discourse.Model
- @namespace Discourse
- @module Discourse
-**/
-Discourse.AdminUser = Discourse.User.extend({
+ customGroups: Em.computed.filter("groups", (g) => !g.automatic && g.visible && Discourse.Group.create(g)),
+ automaticGroups: Em.computed.filter("groups", (g) => g.automatic && Discourse.Group.create(g)),
- /**
- Generates an API key for the user. Will regenerate if they already have one.
-
- @method generateApiKey
- @returns {Promise} a promise that resolves to the newly generated API key
- **/
- generateApiKey: function() {
- var self = this;
- return Discourse.ajax("/admin/users/" + this.get('id') + "/generate_api_key", {type: 'POST'}).then(function (result) {
- var apiKey = Discourse.ApiKey.create(result.api_key);
+ generateApiKey() {
+ const self = this;
+ return Discourse.ajax("/admin/users/" + this.get('id') + "/generate_api_key", {
+ type: 'POST'
+ }).then(function (result) {
+ const apiKey = Discourse.ApiKey.create(result.api_key);
self.set('api_key', apiKey);
return apiKey;
});
},
- groupAdded: function(added){
- var self = this;
+ groupAdded(added) {
return Discourse.ajax("/admin/users/" + this.get('id') + "/groups", {
type: 'POST',
- data: {group_id: added.id}
- }).then(function () {
- self.get('groups').pushObject(added);
- });
+ data: { group_id: added.id }
+ }).then(() => this.get('groups').pushObject(added));
},
- groupRemoved: function(removed){
- var self = this;
- return Discourse.ajax("/admin/users/" + this.get('id') + "/groups/" + removed.id, {
+ groupRemoved(groupId) {
+ return Discourse.ajax("/admin/users/" + this.get('id') + "/groups/" + groupId, {
type: 'DELETE'
- }).then(function () {
- self.set('groups.[]', self.get('groups').rejectBy("id", removed.id));
- });
+ }).then(() => this.set('groups.[]', this.get('groups').rejectBy("id", groupId)));
},
- /**
- Revokes a user's current API key
-
- @method revokeApiKey
- @returns {Promise} a promise that resolves when the API key has been deleted
- **/
- revokeApiKey: function() {
- var self = this;
- return Discourse.ajax("/admin/users/" + this.get('id') + "/revoke_api_key", {type: 'DELETE'}).then(function () {
- self.set('api_key', null);
- });
+ revokeApiKey() {
+ return Discourse.ajax("/admin/users/" + this.get('id') + "/revoke_api_key", {
+ type: 'DELETE'
+ }).then(() => this.set('api_key', null));
},
deleteAllPostsExplanation: function() {
@@ -70,99 +48,111 @@ Discourse.AdminUser = Discourse.User.extend({
}
}.property('can_delete_all_posts', 'deleteForbidden'),
- deleteAllPosts: function() {
- var user = this;
- var message = I18n.t('admin.user.delete_all_posts_confirm', {posts: user.get('post_count'), topics: user.get('topic_count')});
- var buttons = [{
- "label": I18n.t("composer.cancel"),
- "class": "cancel-inline",
- "link": true
- }, {
- "label": ' ' + I18n.t("admin.user.delete_all_posts"),
- "class": "btn btn-danger",
- "callback": function() {
- Discourse.ajax("/admin/users/" + (user.get('id')) + "/delete_all_posts", {type: 'PUT'}).then(function(){
- user.set('post_count', 0);
- });
- }
- }];
- bootbox.dialog(message, buttons, {"classes": "delete-all-posts"});
+ deleteAllPosts() {
+ const user = this,
+ message = I18n.t('admin.user.delete_all_posts_confirm', { posts: user.get('post_count'), topics: user.get('topic_count') }),
+ buttons = [{
+ "label": I18n.t("composer.cancel"),
+ "class": "cancel-inline",
+ "link": true
+ }, {
+ "label": ' ' + I18n.t("admin.user.delete_all_posts"),
+ "class": "btn btn-danger",
+ "callback": function() {
+ Discourse.ajax("/admin/users/" + user.get('id') + "/delete_all_posts", {
+ type: 'PUT'
+ }).then(() => user.set('post_count', 0));
+ }
+ }];
+ bootbox.dialog(message, buttons, { "classes": "delete-all-posts" });
},
- // Revoke the user's admin access
- revokeAdmin: function() {
- this.set('admin', false);
- this.set('can_grant_admin', true);
- this.set('can_revoke_admin', false);
- return Discourse.ajax("/admin/users/" + (this.get('id')) + "/revoke_admin", {type: 'PUT'});
- },
-
- grantAdmin: function() {
- this.set('admin', true);
- this.set('can_grant_admin', false);
- this.set('can_revoke_admin', true);
- var self = this;
-
- Discourse.ajax("/admin/users/" + (this.get('id')) + "/grant_admin", {type: 'PUT'})
- .then(null, function(e) {
- self.set('admin', false);
- self.set('can_grant_admin', true);
- self.set('can_revoke_admin', false);
-
- var error;
- if (e.responseJSON && e.responseJSON.error) {
- error = e.responseJSON.error;
- }
- error = error || I18n.t('admin.user.grant_admin_failed', { error: "http: " + e.status + " - " + e.body });
- bootbox.alert(error);
+ revokeAdmin() {
+ const self = this;
+ return Discourse.ajax("/admin/users/" + this.get('id') + "/revoke_admin", {
+ type: 'PUT'
+ }).then(function() {
+ self.setProperties({
+ admin: false,
+ can_grant_admin: true,
+ can_revoke_admin: false
});
+ });
},
- // Revoke the user's moderation access
- revokeModeration: function() {
- this.set('moderator', false);
- this.set('can_grant_moderation', true);
- this.set('can_revoke_moderation', false);
- return Discourse.ajax("/admin/users/" + (this.get('id')) + "/revoke_moderation", {type: 'PUT'});
+ grantAdmin() {
+ const self = this;
+ return Discourse.ajax("/admin/users/" + this.get('id') + "/grant_admin", {
+ type: 'PUT'
+ }).then(function() {
+ self.setProperties({
+ admin: true,
+ can_grant_admin: false,
+ can_revoke_admin: true
+ });
+ }).catch(function(e) {
+ let error;
+ if (e.responseJSON && e.responseJSON.error) {
+ error = e.responseJSON.error;
+ }
+ error = error || I18n.t('admin.user.grant_admin_failed', { error: "http: " + e.status + " - " + e.body });
+ bootbox.alert(error);
+ });
},
- grantModeration: function() {
- this.set('moderator', true);
- this.set('can_grant_moderation', false);
- this.set('can_revoke_moderation', true);
- var self = this;
- Discourse.ajax("/admin/users/" + (this.get('id')) + "/grant_moderation", {type: 'PUT'})
- .then(null, function(e) {
- self.set('moderator', false);
- self.set('can_grant_moderation', true);
- self.set('can_revoke_moderation', false);
-
- var error;
- if (e.responseJSON && e.responseJSON.error) {
- error = e.responseJSON.error;
- }
- error = error || I18n.t('admin.user.grant_moderation_failed', { error: "http: " + e.status + " - " + e.body });
- bootbox.alert(error);
- });
+ revokeModeration() {
+ const self = this;
+ return Discourse.ajax("/admin/users/" + this.get('id') + "/revoke_moderation", {
+ type: 'PUT'
+ }).then(function() {
+ self.setProperties({
+ moderator: false,
+ can_grant_moderation: true,
+ can_revoke_moderation: false
+ });
+ });
},
- refreshBrowsers: function() {
- Discourse.ajax("/admin/users/" + (this.get('id')) + "/refresh_browsers", {type: 'POST'});
- bootbox.alert(I18n.t("admin.user.refresh_browsers_message"));
+ grantModeration() {
+ const self = this;
+ return Discourse.ajax("/admin/users/" + this.get('id') + "/grant_moderation", {
+ type: 'PUT'
+ }).then(function() {
+ self.setProperties({
+ moderator: true,
+ can_grant_moderation: false,
+ can_revoke_moderation: true
+ });
+ }).catch(function(e) {
+ let error;
+ if (e.responseJSON && e.responseJSON.error) {
+ error = e.responseJSON.error;
+ }
+ error = error || I18n.t('admin.user.grant_moderation_failed', { error: "http: " + e.status + " - " + e.body });
+ bootbox.alert(error);
+ });
},
- approve: function() {
- this.set('can_approve', false);
- this.set('approved', true);
- this.set('approved_by', Discourse.User.current());
- Discourse.ajax("/admin/users/" + (this.get('id')) + "/approve", {type: 'PUT'});
+ refreshBrowsers() {
+ return Discourse.ajax("/admin/users/" + this.get('id') + "/refresh_browsers", {
+ type: 'POST'
+ }).finally(() => bootbox.alert(I18n.t("admin.user.refresh_browsers_message")));
},
- username_lower: (function() {
- return this.get('username').toLowerCase();
- }).property('username'),
+ approve() {
+ const self = this;
+ return Discourse.ajax("/admin/users/" + this.get('id') + "/approve", {
+ type: 'PUT'
+ }).then(function() {
+ self.setProperties({
+ can_approve: false,
+ approved: true,
+ approved_by: Discourse.User.current()
+ });
+ });
+ },
- setOriginalTrustLevel: function() {
+ setOriginalTrustLevel() {
this.set('originalTrustLevel', this.get('trust_level'));
},
@@ -172,16 +162,14 @@ Discourse.AdminUser = Discourse.User.extend({
dirty: Discourse.computed.propertyNotEqual('originalTrustLevel', 'trustLevel.id'),
- saveTrustLevel: function() {
- Discourse.ajax("/admin/users/" + this.id + "/trust_level", {
+ saveTrustLevel() {
+ return Discourse.ajax("/admin/users/" + this.id + "/trust_level", {
type: 'PUT',
- data: {level: this.get('trustLevel.id')}
- }).then(function () {
- // succeeded
+ data: { level: this.get('trustLevel.id') }
+ }).then(function() {
window.location.reload();
- }, function(e) {
- // failure
- var error;
+ }).catch(function(e) {
+ let error;
if (e.responseJSON && e.responseJSON.errors) {
error = e.responseJSON.errors[0];
}
@@ -190,20 +178,18 @@ Discourse.AdminUser = Discourse.User.extend({
});
},
- restoreTrustLevel: function() {
+ restoreTrustLevel() {
this.set('trustLevel.id', this.get('originalTrustLevel'));
},
- lockTrustLevel: function(locked) {
- Discourse.ajax("/admin/users/" + this.id + "/trust_level_lock", {
+ lockTrustLevel(locked) {
+ return Discourse.ajax("/admin/users/" + this.id + "/trust_level_lock", {
type: 'PUT',
data: { locked: !!locked }
}).then(function() {
- // succeeded
window.location.reload();
- }, function(e) {
- // failure
- var error;
+ }).catch(function(e) {
+ let error;
if (e.responseJSON && e.responseJSON.errors) {
error = e.responseJSON.errors[0];
}
@@ -212,7 +198,7 @@ Discourse.AdminUser = Discourse.User.extend({
});
},
- canLockTrustLevel: function(){
+ canLockTrustLevel: function() {
return this.get('trust_level') < 4;
}.property('trust_level'),
@@ -220,51 +206,45 @@ Discourse.AdminUser = Discourse.User.extend({
canSuspend: Em.computed.not('staff'),
suspendDuration: function() {
- var suspended_at = moment(this.suspended_at);
- var suspended_till = moment(this.suspended_till);
+ const suspended_at = moment(this.suspended_at),
+ suspended_till = moment(this.suspended_till);
return suspended_at.format('L') + " - " + suspended_till.format('L');
}.property('suspended_till', 'suspended_at'),
- suspend: function(duration, reason) {
+ suspend(duration, reason) {
return Discourse.ajax("/admin/users/" + this.id + "/suspend", {
type: 'PUT',
- data: {duration: duration, reason: reason}
+ data: { duration: duration, reason: reason }
});
},
- unsuspend: function() {
- Discourse.ajax("/admin/users/" + this.id + "/unsuspend", {
+ unsuspend() {
+ return Discourse.ajax("/admin/users/" + this.id + "/unsuspend", {
type: 'PUT'
}).then(function() {
- // succeeded
window.location.reload();
- }, function(e) {
- // failed
+ }).catch(function(e) {
var error = I18n.t('admin.user.unsuspend_failed', { error: "http: " + e.status + " - " + e.body });
bootbox.alert(error);
});
},
- log_out: function(){
- Discourse.ajax("/admin/users/" + this.id + "/log_out", {
- type: 'POST',
- data: { username_or_email: this.get('username') }
- }).then(
- function(){
- bootbox.alert(I18n.t("admin.user.logged_out"));
- }
- );
- },
-
- impersonate: function() {
- Discourse.ajax("/admin/impersonate", {
+ log_out() {
+ return Discourse.ajax("/admin/users/" + this.id + "/log_out", {
+ type: 'POST',
+ data: { username_or_email: this.get('username') }
+ }).then(function() {
+ bootbox.alert(I18n.t("admin.user.logged_out"));
+ });
+ },
+
+ impersonate() {
+ return Discourse.ajax("/admin/impersonate", {
type: 'POST',
data: { username_or_email: this.get('username') }
}).then(function() {
- // succeeded
document.location = "/";
- }, function(e) {
- // failed
+ }).catch(function(e) {
if (e.status === 404) {
bootbox.alert(I18n.t('admin.impersonate.not_found'));
} else {
@@ -273,56 +253,57 @@ Discourse.AdminUser = Discourse.User.extend({
});
},
- activate: function() {
- Discourse.ajax('/admin/users/' + this.id + '/activate', {type: 'PUT'}).then(function() {
- // succeeded
+ activate() {
+ return Discourse.ajax('/admin/users/' + this.id + '/activate', {
+ type: 'PUT'
+ }).then(function() {
window.location.reload();
- }, function(e) {
- // failed
+ }).catch(function(e) {
var error = I18n.t('admin.user.activate_failed', { error: "http: " + e.status + " - " + e.body });
bootbox.alert(error);
});
},
- deactivate: function() {
- Discourse.ajax('/admin/users/' + this.id + '/deactivate', {type: 'PUT'}).then(function() {
- // succeeded
+ deactivate() {
+ return Discourse.ajax('/admin/users/' + this.id + '/deactivate', {
+ type: 'PUT'
+ }).then(function() {
window.location.reload();
- }, function(e) {
- // failed
+ }).catch(function(e) {
var error = I18n.t('admin.user.deactivate_failed', { error: "http: " + e.status + " - " + e.body });
bootbox.alert(error);
});
},
- unblock: function() {
- Discourse.ajax('/admin/users/' + this.id + '/unblock', {type: 'PUT'}).then(function() {
- // succeeded
+ unblock() {
+ return Discourse.ajax('/admin/users/' + this.id + '/unblock', {
+ type: 'PUT'
+ }).then(function() {
window.location.reload();
- }, function(e) {
- // failed
+ }).catch(function(e) {
var error = I18n.t('admin.user.unblock_failed', { error: "http: " + e.status + " - " + e.body });
bootbox.alert(error);
});
},
- block: function() {
- Discourse.ajax('/admin/users/' + this.id + '/block', {type: 'PUT'}).then(function() {
- // succeeded
+ block() {
+ return Discourse.ajax('/admin/users/' + this.id + '/block', {
+ type: 'PUT'
+ }).then(function() {
window.location.reload();
- }, function(e) {
- // failed
+ }).catch(function(e) {
var error = I18n.t('admin.user.block_failed', { error: "http: " + e.status + " - " + e.body });
bootbox.alert(error);
});
},
- sendActivationEmail: function() {
- Discourse.ajax('/users/action/send_activation_email', {data: {username: this.get('username')}, type: 'POST'}).then(function() {
- // succeeded
+ sendActivationEmail() {
+ return Discourse.ajax('/users/action/send_activation_email', {
+ type: 'POST',
+ data: { username: this.get('username') }
+ }).then(function() {
bootbox.alert( I18n.t('admin.user.activation_email_sent') );
- }, function(e) {
- // failed
+ }).catch(function(e) {
var error = I18n.t('admin.user.send_activation_email_failed', { error: "http: " + e.status + " - " + e.body });
bootbox.alert(error);
});
@@ -330,11 +311,14 @@ Discourse.AdminUser = Discourse.User.extend({
anonymizeForbidden: Em.computed.not("can_be_anonymized"),
- anonymize: function() {
- var user = this;
+ anonymize() {
+ const user = this,
+ message = I18n.t("admin.user.anonymize_confirm");
- var performAnonymize = function() {
- Discourse.ajax("/admin/users/" + user.get('id') + '/anonymize.json', {type: 'PUT'}).then(function(data) {
+ const performAnonymize = function() {
+ return Discourse.ajax("/admin/users/" + user.get('id') + '/anonymize.json', {
+ type: 'PUT'
+ }).then(function(data) {
if (data.success) {
if (data.username) {
document.location = "/admin/users/" + data.username;
@@ -347,26 +331,22 @@ Discourse.AdminUser = Discourse.User.extend({
user.setProperties(data.user);
}
}
- }, function() {
+ }).catch(function() {
bootbox.alert(I18n.t("admin.user.anonymize_failed"));
});
};
- var message = I18n.t("admin.user.anonymize_confirm");
-
- var buttons = [{
+ const buttons = [{
"label": I18n.t("composer.cancel"),
"class": "cancel",
"link": true
}, {
"label": '' + I18n.t('admin.user.anonymize_yes'),
"class": "btn btn-danger",
- "callback": function(){
- performAnonymize();
- }
+ "callback": function() { performAnonymize(); }
}];
- bootbox.dialog(message, buttons, {"classes": "delete-user-modal"});
+ bootbox.dialog(message, buttons, { "classes": "delete-user-modal" });
},
deleteForbidden: Em.computed.not("canBeDeleted"),
@@ -383,12 +363,13 @@ Discourse.AdminUser = Discourse.User.extend({
}
}.property('deleteForbidden'),
- destroy: function(opts) {
- var user = this;
- var location = document.location.pathname;
+ destroy(opts) {
+ const user = this,
+ message = I18n.t("admin.user.delete_confirm"),
+ location = document.location.pathname;
- var performDestroy = function(block) {
- var formData = { context: location };
+ const performDestroy = function(block) {
+ let formData = { context: location };
if (block) {
formData["block_email"] = true;
formData["block_urls"] = true;
@@ -397,7 +378,7 @@ Discourse.AdminUser = Discourse.User.extend({
if (opts && opts.deletePosts) {
formData["delete_posts"] = true;
}
- Discourse.ajax("/admin/users/" + user.get('id') + '.json', {
+ return Discourse.ajax("/admin/users/" + user.get('id') + '.json', {
type: 'DELETE',
data: formData
}).then(function(data) {
@@ -413,47 +394,42 @@ Discourse.AdminUser = Discourse.User.extend({
user.setProperties(data.user);
}
}
- }, function() {
+ }).catch(function() {
Discourse.AdminUser.find( user.get('username') ).then(function(u){ user.setProperties(u); });
bootbox.alert(I18n.t("admin.user.delete_failed"));
});
};
- var message = I18n.t("admin.user.delete_confirm");
-
- var buttons = [{
+ const buttons = [{
"label": I18n.t("composer.cancel"),
"class": "cancel",
"link": true
}, {
"label": I18n.t('admin.user.delete_dont_block'),
"class": "btn",
- "callback": function(){
- performDestroy(false);
- }
+ "callback": function(){ performDestroy(false); }
}, {
"label": '' + I18n.t('admin.user.delete_and_block'),
"class": "btn btn-danger",
- "callback": function(){
- performDestroy(true);
- }
+ "callback": function(){ performDestroy(true); }
}];
- bootbox.dialog(message, buttons, {"classes": "delete-user-modal"});
+ bootbox.dialog(message, buttons, { "classes": "delete-user-modal" });
},
- deleteAsSpammer: function(successCallback) {
- var user = this;
+ deleteAsSpammer(successCallback) {
+ const user = this;
user.checkEmail().then(function() {
- var data = {
+ const data = {
posts: user.get('post_count'),
topics: user.get('topic_count'),
email: user.get('email') || I18n.t("flagging.hidden_email_address"),
ip_address: user.get('ip_address') || I18n.t("flagging.ip_address_missing")
- };
- var message = I18n.t('flagging.delete_confirm', data);
- var buttons = [{
+ };
+
+ const message = I18n.t('flagging.delete_confirm', data),
+ buttons = [{
"label": I18n.t("composer.cancel"),
"class": "cancel-inline",
"link": true
@@ -461,7 +437,7 @@ Discourse.AdminUser = Discourse.User.extend({
"label": ' ' + I18n.t("flagging.yes_delete_spammer"),
"class": "btn btn-danger",
"callback": function() {
- Discourse.ajax("/admin/users/" + user.get('id') + '.json', {
+ return Discourse.ajax("/admin/users/" + user.get('id') + '.json', {
type: 'DELETE',
data: {
delete_posts: true,
@@ -477,23 +453,24 @@ Discourse.AdminUser = Discourse.User.extend({
} else {
bootbox.alert(I18n.t("admin.user.delete_failed"));
}
- }, function() {
+ }).catch(function() {
bootbox.alert(I18n.t("admin.user.delete_failed"));
});
}
}];
+
bootbox.dialog(message, buttons, {"classes": "flagging-delete-spammer"});
});
-
},
- loadDetails: function() {
- var model = this;
- if (model.get('loadedDetails')) { return Ember.RSVP.resolve(model); }
+ loadDetails() {
+ const user = this;
- return Discourse.AdminUser.find(model.get('username_lower')).then(function (result) {
- model.setProperties(result);
- model.set('loadedDetails', true);
+ if (user.get('loadedDetails')) { return Ember.RSVP.resolve(user); }
+
+ return Discourse.AdminUser.find(user.get('username_lower')).then(function (result) {
+ user.setProperties(result);
+ user.set('loadedDetails', true);
});
},
@@ -517,29 +494,25 @@ Discourse.AdminUser = Discourse.User.extend({
});
-Discourse.AdminUser.reopenClass({
+AdminUser.reopenClass({
- bulkApprove: function(users) {
+ bulkApprove(users) {
_.each(users, function(user) {
- user.set('approved', true);
- user.set('can_approve', false);
- return user.set('selected', false);
+ user.setProperties({
+ approved: true,
+ can_approve: false,
+ selected: false
+ });
});
- bootbox.alert(I18n.t("admin.user.approve_bulk_success"));
-
return Discourse.ajax("/admin/users/approve-bulk", {
type: 'PUT',
- data: {
- users: users.map(function(u) {
- return u.id;
- })
- }
- });
+ data: { users: users.map((u) => u.id) }
+ }).finally(() => bootbox.alert(I18n.t("admin.user.approve_bulk_success")));
},
- bulkReject: function(users) {
- _.each(users, function(user){
+ bulkReject(users) {
+ _.each(users, function(user) {
user.set('can_approve', false);
user.set('selected', false);
});
@@ -547,26 +520,26 @@ Discourse.AdminUser.reopenClass({
return Discourse.ajax("/admin/users/reject-bulk", {
type: 'DELETE',
data: {
- users: users.map(function(u) { return u.id; }),
+ users: users.map((u) => u.id),
context: window.location.pathname
}
});
},
- find: function(username) {
+ find(username) {
return Discourse.ajax("/admin/users/" + username + ".json").then(function (result) {
result.loadedDetails = true;
return Discourse.AdminUser.create(result);
});
},
- findAll: function(query, filter) {
+ findAll(query, filter) {
return Discourse.ajax("/admin/users/list/" + query + ".json", {
data: filter
}).then(function(users) {
- return users.map(function(u) {
- return Discourse.AdminUser.create(u);
- });
+ return users.map((u) => Discourse.AdminUser.create(u));
});
}
});
+
+export default AdminUser;
diff --git a/app/assets/javascripts/admin/templates/user_index.hbs b/app/assets/javascripts/admin/templates/user_index.hbs
index 25223ae661..e6347ff68c 100644
--- a/app/assets/javascripts/admin/templates/user_index.hbs
+++ b/app/assets/javascripts/admin/templates/user_index.hbs
@@ -3,20 +3,20 @@
{{#if active}}
{{#link-to 'user' model class="btn"}}
-
+ {{fa-icon "user"}}
{{i18n 'admin.user.show_public_profile'}}
{{/link-to}}
{{#if can_impersonate}}
-
+
{{/if}}
{{#if currentUser.admin}}
-
+
{{/if}}
{{/if}}
@@ -26,7 +26,7 @@
{{username}}
{{#link-to 'preferences.username' model class="btn"}}
-
+ {{fa-icon "pencil"}}
{{i18n 'user.change_username.title'}}
{{/link-to}}
@@ -75,28 +75,32 @@