Fixes some Ember Deprecations for 1.13:

- Remove ArrayController
- Remove {{view}} from templates
- Replace many cases of needs: [‘controller’] with inject
- Enable Ember Legacy Views
This commit is contained in:
Robin Ward 2016-10-20 13:26:41 -04:00
parent 2a61cc8c88
commit bf91532260
50 changed files with 255 additions and 336 deletions

View File

@ -2,17 +2,20 @@ import debounce from 'discourse/lib/debounce';
import { renderSpinner } from 'discourse/helpers/loading-spinner'; import { renderSpinner } from 'discourse/helpers/loading-spinner';
import { escapeExpression } from 'discourse/lib/utilities'; import { escapeExpression } from 'discourse/lib/utilities';
export default Ember.View.extend({ export default Ember.Component.extend({
classNames: ["admin-backups-logs"], classNames: ["admin-backups-logs"],
_initialize: function() { this._reset(); }.on("init"), init() {
this._super();
this._reset();
},
_reset() { _reset() {
this.setProperties({ formattedLogs: "", index: 0 }); this.setProperties({ formattedLogs: "", index: 0 });
}, },
_updateFormattedLogs: debounce(function() { _updateFormattedLogs: debounce(function() {
const logs = this.get("controller.model"); const logs = this.get("logs");
if (logs.length === 0) { if (logs.length === 0) {
this._reset(); // reset the cached logs whenever the model is reset this._reset(); // reset the cached logs whenever the model is reset
} else { } else {
@ -28,7 +31,7 @@ export default Ember.View.extend({
// force rerender // force rerender
this.rerender(); this.rerender();
} }
}, 150).observes("controller.model.[]"), }, 150).observes("logs.[]").on('init'),
render(buffer) { render(buffer) {
const formattedLogs = this.get("formattedLogs"); const formattedLogs = this.get("formattedLogs");
@ -40,14 +43,14 @@ export default Ember.View.extend({
buffer.push("<p>" + I18n.t("admin.backups.logs.none") + "</p>"); buffer.push("<p>" + I18n.t("admin.backups.logs.none") + "</p>");
} }
// add a loading indicator // add a loading indicator
if (this.get("controller.status.model.isOperationRunning")) { if (this.get("status.isOperationRunning")) {
buffer.push(renderSpinner('small')); buffer.push(renderSpinner('small'));
} }
}, },
_forceScrollToBottom: function() { didInsertElement() {
this._super();
const $div = this.$()[0]; const $div = this.$()[0];
$div.scrollTop = $div.scrollHeight; $div.scrollTop = $div.scrollHeight;
}.on("didInsertElement") },
}); });

View File

@ -1,66 +1,30 @@
import ApiKey from 'admin/models/api-key'; import ApiKey from 'admin/models/api-key';
/** export default Ember.Controller.extend({
This controller supports the interface for dealing with API keys
@class AdminApiController
@extends Ember.ArrayController
@namespace Discourse
@module Discourse
**/
export default Ember.ArrayController.extend({
actions: { actions: {
/** generateMasterKey() {
Generates a master api key ApiKey.generateMasterKey().then(key => this.get('model').pushObject(key));
@method generateMasterKey
**/
generateMasterKey: function() {
var self = this;
ApiKey.generateMasterKey().then(function (key) {
self.get('model').pushObject(key);
});
}, },
/** regenerateKey(key) {
Creates an API key instance with internal user object bootbox.confirm(I18n.t("admin.api.confirm_regen"), I18n.t("no_value"), I18n.t("yes_value"), result => {
@method regenerateKey
@param {ApiKey} key the key to regenerate
**/
regenerateKey: function(key) {
bootbox.confirm(I18n.t("admin.api.confirm_regen"), I18n.t("no_value"), I18n.t("yes_value"), function(result) {
if (result) { if (result) {
key.regenerate(); key.regenerate();
} }
}); });
}, },
/** revokeKey(key) {
Revokes an API key bootbox.confirm(I18n.t("admin.api.confirm_revoke"), I18n.t("no_value"), I18n.t("yes_value"), result => {
@method revokeKey
@param {ApiKey} key the key to revoke
**/
revokeKey: function(key) {
var self = this;
bootbox.confirm(I18n.t("admin.api.confirm_revoke"), I18n.t("no_value"), I18n.t("yes_value"), function(result) {
if (result) { if (result) {
key.revoke().then(function() { key.revoke().then(() => this.get('model').removeObject(key));
self.get('model').removeObject(key);
});
} }
}); });
} }
}, },
/** // Has a master key already been generated?
Has a master key already been generated?
@property hasMasterKey
@type {Boolean}
**/
hasMasterKey: function() { hasMasterKey: function() {
return !!this.get('model').findBy('user', null); return !!this.get('model').findBy('user', null);
}.property('model.[]') }.property('model.[]')

View File

@ -1,19 +1,20 @@
import { ajax } from 'discourse/lib/ajax'; import { ajax } from 'discourse/lib/ajax';
export default Ember.ArrayController.extend({
needs: ["adminBackups"], export default Ember.Controller.extend({
status: Ember.computed.alias("controllers.adminBackups"), adminBackups: Ember.inject.controller(),
status: Ember.computed.alias('adminBackups.model'),
uploadLabel: function() { return I18n.t("admin.backups.upload.label"); }.property(), uploadLabel: function() { return I18n.t("admin.backups.upload.label"); }.property(),
restoreTitle: function() { restoreTitle: function() {
if (!this.get('status.model.allowRestore')) { if (!this.get('status.allowRestore')) {
return "admin.backups.operations.restore.is_disabled"; return "admin.backups.operations.restore.is_disabled";
} else if (this.get("status.model.isOperationRunning")) { } else if (this.get("status.isOperationRunning")) {
return "admin.backups.operations.is_running"; return "admin.backups.operations.is_running";
} else { } else {
return "admin.backups.operations.restore.title"; return "admin.backups.operations.restore.title";
} }
}.property("status.model.{allowRestore,isOperationRunning}"), }.property("status.{allowRestore,isOperationRunning}"),
actions: { actions: {

View File

@ -1,4 +1,5 @@
export default Ember.ArrayController.extend({ export default Ember.Controller.extend({
needs: ["adminBackups"], logs: [],
status: Em.computed.alias("controllers.adminBackups") adminBackups: Ember.inject.controller(),
status: Em.computed.alias("adminBackups.model")
}); });

View File

@ -3,14 +3,14 @@ import BufferedContent from 'discourse/mixins/buffered-content';
import { propertyNotEqual } from 'discourse/lib/computed'; import { propertyNotEqual } from 'discourse/lib/computed';
export default Ember.Controller.extend(BufferedContent, { export default Ember.Controller.extend(BufferedContent, {
needs: ['admin-badges'], adminBadges: Ember.inject.controller(),
saving: false, saving: false,
savingStatus: '', savingStatus: '',
badgeTypes: Em.computed.alias('controllers.admin-badges.badgeTypes'), badgeTypes: Em.computed.alias('adminBadges.badgeTypes'),
badgeGroupings: Em.computed.alias('controllers.admin-badges.badgeGroupings'), badgeGroupings: Em.computed.alias('adminBadges.badgeGroupings'),
badgeTriggers: Em.computed.alias('controllers.admin-badges.badgeTriggers'), badgeTriggers: Em.computed.alias('adminBadges.badgeTriggers'),
protectedSystemFields: Em.computed.alias('controllers.admin-badges.protectedSystemFields'), protectedSystemFields: Em.computed.alias('adminBadges.protectedSystemFields'),
readOnly: Ember.computed.alias('buffered.system'), readOnly: Ember.computed.alias('buffered.system'),
showDisplayName: propertyNotEqual('name', 'displayName'), showDisplayName: propertyNotEqual('name', 'displayName'),
@ -30,16 +30,15 @@ export default Ember.Controller.extend(BufferedContent, {
}.observes('model.id'), }.observes('model.id'),
actions: { actions: {
save: function() { save() {
if (!this.get('saving')) { if (!this.get('saving')) {
var fields = ['allow_title', 'multiple_grant', let fields = ['allow_title', 'multiple_grant',
'listable', 'auto_revoke', 'listable', 'auto_revoke',
'enabled', 'show_posts', 'enabled', 'show_posts',
'target_posts', 'name', 'description', 'target_posts', 'name', 'description',
'long_description', 'long_description',
'icon', 'image', 'query', 'badge_grouping_id', 'icon', 'image', 'query', 'badge_grouping_id',
'trigger', 'badge_type_id'], 'trigger', 'badge_type_id'];
self = this;
if (this.get('buffered.system')){ if (this.get('buffered.system')){
var protectedFields = this.get('protectedSystemFields'); var protectedFields = this.get('protectedSystemFields');
@ -51,54 +50,55 @@ export default Ember.Controller.extend(BufferedContent, {
this.set('saving', true); this.set('saving', true);
this.set('savingStatus', I18n.t('saving')); this.set('savingStatus', I18n.t('saving'));
var boolFields = ['allow_title', 'multiple_grant', const boolFields = ['allow_title', 'multiple_grant',
'listable', 'auto_revoke', 'listable', 'auto_revoke',
'enabled', 'show_posts', 'enabled', 'show_posts',
'target_posts' ]; 'target_posts' ];
var data = {}, const data = {};
buffered = this.get('buffered'); const buffered = this.get('buffered');
fields.forEach(function(field){ fields.forEach(function(field){
var d = buffered.get(field); var d = buffered.get(field);
if (_.include(boolFields, field)) { d = !!d; } if (_.include(boolFields, field)) { d = !!d; }
data[field] = d; data[field] = d;
}); });
var newBadge = !this.get('id'), const newBadge = !this.get('id');
model = this.get('model'); const model = this.get('model');
this.get('model').save(data).then(function() { this.get('model').save(data).then(() => {
if (newBadge) { if (newBadge) {
var adminBadgesController = self.get('controllers.admin-badges'); const adminBadges = this.get('adminBadges.model');
if (!adminBadgesController.contains(model)) adminBadgesController.pushObject(model); if (!adminBadges.contains(model)) {
self.transitionToRoute('adminBadges.show', model.get('id')); adminBadges.pushObject(model);
}
this.transitionToRoute('adminBadges.show', model.get('id'));
} else { } else {
self.commitBuffer(); this.commitBuffer();
self.set('savingStatus', I18n.t('saved')); this.set('savingStatus', I18n.t('saved'));
} }
}).catch(popupAjaxError).finally(function() { }).catch(popupAjaxError).finally(() => {
self.set('saving', false); this.set('saving', false);
self.set('savingStatus', ''); this.set('savingStatus', '');
}); });
} }
}, },
destroy: function() { destroy() {
var self = this, const adminBadges = this.get('adminBadges.model');
adminBadgesController = this.get('controllers.admin-badges'), const model = this.get('model');
model = this.get('model');
if (!model.get('id')) { if (!model.get('id')) {
self.transitionToRoute('adminBadges.index'); this.transitionToRoute('adminBadges.index');
return; return;
} }
return bootbox.confirm(I18n.t("admin.badges.delete_confirm"), I18n.t("no_value"), I18n.t("yes_value"), function(result) { return bootbox.confirm(I18n.t("admin.badges.delete_confirm"), I18n.t("no_value"), I18n.t("yes_value"), result => {
if (result) { if (result) {
model.destroy().then(function() { model.destroy().then(() => {
adminBadgesController.removeObject(model); adminBadges.removeObject(model);
self.transitionToRoute('adminBadges.index'); this.transitionToRoute('adminBadges.index');
}).catch(function() { }).catch(() => {
bootbox.alert(I18n.t('generic_error')); bootbox.alert(I18n.t('generic_error'));
}); });
} }

View File

@ -1 +1 @@
export default Ember.ArrayController.extend(); export default Ember.Controller.extend();

View File

@ -1,4 +1,4 @@
export default Ember.ArrayController.extend({ export default Ember.Controller.extend({
onlyOverridden: false, onlyOverridden: false,
baseColorScheme: function() { baseColorScheme: function() {
@ -13,8 +13,8 @@ export default Ember.ArrayController.extend({
return baseColorsHash; return baseColorsHash;
}.property('baseColorScheme'), }.property('baseColorScheme'),
removeSelected: function() { removeSelected() {
this.removeObject(this.get('selectedItem')); this.get('model').removeObject(this.get('selectedItem'));
this.set('selectedItem', null); this.set('selectedItem', null);
}, },
@ -26,8 +26,7 @@ export default Ember.ArrayController.extend({
return; return;
} }
var matches = Em.A(); const matches = [];
_.each(this.get('selectedItem.colors'), function(color){ _.each(this.get('selectedItem.colors'), function(color){
if (color.get('overridden')) matches.pushObject(color); if (color.get('overridden')) matches.pushObject(color);
}); });
@ -58,10 +57,10 @@ export default Ember.ArrayController.extend({
this.filterContent(); this.filterContent();
}, },
newColorScheme: function() { newColorScheme() {
var newColorScheme = Em.copy(this.get('baseColorScheme'), true); const newColorScheme = Em.copy(this.get('baseColorScheme'), true);
newColorScheme.set('name', I18n.t('admin.customize.colors.new_name')); newColorScheme.set('name', I18n.t('admin.customize.colors.new_name'));
this.pushObject(newColorScheme); this.get('model').pushObject(newColorScheme);
this.send('selectColorScheme', newColorScheme); this.send('selectColorScheme', newColorScheme);
this.set('onlyOverridden', false); this.set('onlyOverridden', false);
}, },
@ -86,10 +85,10 @@ export default Ember.ArrayController.extend({
this.updateEnabled(); this.updateEnabled();
}, },
copy: function(colorScheme) { copy(colorScheme) {
var newColorScheme = Em.copy(colorScheme, true); var newColorScheme = Em.copy(colorScheme, true);
newColorScheme.set('name', I18n.t('admin.customize.colors.copy_name_prefix') + ' ' + colorScheme.get('name')); newColorScheme.set('name', I18n.t('admin.customize.colors.copy_name_prefix') + ' ' + colorScheme.get('name'));
this.pushObject(newColorScheme); this.get('model').pushObject(newColorScheme);
this.send('selectColorScheme', newColorScheme); this.send('selectColorScheme', newColorScheme);
}, },

View File

@ -1,23 +1,23 @@
import { ajax } from 'discourse/lib/ajax'; import { ajax } from 'discourse/lib/ajax';
export default Ember.ArrayController.extend({ export default Ember.Controller.extend({
sortProperties: ["name"], sortedEmojis: Ember.computed.sort('model', 'emojiSorting'),
emojiSorting: ['name'],
actions: { actions: {
emojiUploaded(emoji) { emojiUploaded(emoji) {
emoji.url += "?t=" + new Date().getTime(); emoji.url += "?t=" + new Date().getTime();
this.pushObject(Ember.Object.create(emoji)); this.get('model').pushObject(Ember.Object.create(emoji));
}, },
destroy(emoji) { destroy(emoji) {
const self = this;
return bootbox.confirm( return bootbox.confirm(
I18n.t("admin.emoji.delete_confirm", { name: emoji.get("name") }), I18n.t("admin.emoji.delete_confirm", { name: emoji.get("name") }),
I18n.t("no_value"), I18n.t("no_value"),
I18n.t("yes_value"), I18n.t("yes_value"),
function(destroy) { destroy => {
if (destroy) { if (destroy) {
return ajax("/admin/customize/emojis/" + emoji.get("name"), { type: "DELETE" }).then(function() { return ajax("/admin/customize/emojis/" + emoji.get("name"), { type: "DELETE" }).then(() => {
self.removeObject(emoji); this.get('model').removeObject(emoji);
}); });
} }
} }

View File

@ -1,6 +1,6 @@
import FlaggedPost from 'admin/models/flagged-post'; import FlaggedPost from 'admin/models/flagged-post';
export default Ember.ArrayController.extend({ export default Ember.Controller.extend({
query: null, query: null,
adminOldFlagsView: Em.computed.equal("query", "old"), adminOldFlagsView: Em.computed.equal("query", "old"),
@ -8,18 +8,16 @@ export default Ember.ArrayController.extend({
actions: { actions: {
disagreeFlags(flaggedPost) { disagreeFlags(flaggedPost) {
var self = this; flaggedPost.disagreeFlags().then(() => {
flaggedPost.disagreeFlags().then(function () { this.get('model').removeObject(flaggedPost);
self.removeObject(flaggedPost);
}, function () { }, function () {
bootbox.alert(I18n.t("admin.flags.error")); bootbox.alert(I18n.t("admin.flags.error"));
}); });
}, },
deferFlags(flaggedPost) { deferFlags(flaggedPost) {
var self = this; flaggedPost.deferFlags().then(() => {
flaggedPost.deferFlags().then(function () { this.get('model').removeObject(flaggedPost);
self.removeObject(flaggedPost);
}, function () { }, function () {
bootbox.alert(I18n.t("admin.flags.error")); bootbox.alert(I18n.t("admin.flags.error"));
}); });
@ -29,7 +27,7 @@ export default Ember.ArrayController.extend({
this.send("disagreeFlags", item); this.send("disagreeFlags", item);
}, },
loadMore(){ loadMore() {
const flags = this.get('model'); const flags = this.get('model');
return FlaggedPost.findAll(this.get('query'), flags.length+1).then(data => { return FlaggedPost.findAll(this.get('query'), flags.length+1).then(data => {
if (data.length===0) { if (data.length===0) {

View File

@ -4,7 +4,7 @@ import { escapeExpression } from 'discourse/lib/utilities';
import computed from 'ember-addons/ember-computed-decorators'; import computed from 'ember-addons/ember-computed-decorators';
export default Ember.Controller.extend({ export default Ember.Controller.extend({
needs: ['adminGroupsType'], adminGroupsType: Ember.inject.controller(),
disableSave: false, disableSave: false,
savingStatus: '', savingStatus: '',
@ -131,13 +131,13 @@ export default Ember.Controller.extend({
save() { save() {
const group = this.get('model'), const group = this.get('model'),
groupsController = this.get("controllers.adminGroupsType"), groupsController = this.get("adminGroupsType"),
groupType = groupsController.get("type"); groupType = groupsController.get("type");
this.set('disableSave', true); this.set('disableSave', true);
this.set('savingStatus', I18n.t('saving')); this.set('savingStatus', I18n.t('saving'));
let promise = group.get("id") ? group.save() : group.create().then(() => groupsController.addObject(group)); let promise = group.get("id") ? group.save() : group.create().then(() => groupsController.get('model').addObject(group));
promise.then(() => { promise.then(() => {
this.transitionToRoute("adminGroup", groupType, group.get('name')); this.transitionToRoute("adminGroup", groupType, group.get('name'));
@ -148,7 +148,7 @@ export default Ember.Controller.extend({
destroy() { destroy() {
const group = this.get('model'), const group = this.get('model'),
groupsController = this.get('controllers.adminGroupsType'), groupsController = this.get('adminGroupsType'),
self = this; self = this;
if (!group.get('id')) { if (!group.get('id')) {

View File

@ -1,18 +1,18 @@
import { ajax } from 'discourse/lib/ajax'; import { ajax } from 'discourse/lib/ajax';
export default Ember.ArrayController.extend({ export default Ember.Controller.extend({
sortProperties: ['name'], sortedGroups: Ember.computed.sort('model', 'groupSorting'),
groupSorting: ['name'],
refreshingAutoGroups: false, refreshingAutoGroups: false,
isAuto: function(){
return this.get('type') === 'automatic'; isAuto: Ember.computed.equal('type', 'automatic'),
}.property('type'),
actions: { actions: {
refreshAutoGroups: function(){ refreshAutoGroups() {
var self = this;
this.set('refreshingAutoGroups', true); this.set('refreshingAutoGroups', true);
ajax('/admin/groups/refresh_automatic_groups', {type: 'POST'}).then(function() { ajax('/admin/groups/refresh_automatic_groups', {type: 'POST'}).then(() => {
self.transitionToRoute("adminGroupsType", "automatic").then(function() { this.transitionToRoute("adminGroupsType", "automatic").then(() => {
self.set('refreshingAutoGroups', false); this.set('refreshingAutoGroups', false);
}); });
}); });
} }

View File

@ -2,12 +2,12 @@ import { exportEntity } from 'discourse/lib/export-csv';
import { outputExportResult } from 'discourse/lib/export-result'; import { outputExportResult } from 'discourse/lib/export-result';
import ScreenedEmail from 'admin/models/screened-email'; import ScreenedEmail from 'admin/models/screened-email';
export default Ember.ArrayController.extend({ export default Ember.Controller.extend({
loading: false, loading: false,
actions: { actions: {
clearBlock(row){ clearBlock(row){
row.clearBlock().then(function(){ row.clearBlock().then(function() {
// feeling lazy // feeling lazy
window.location.reload(); window.location.reload();
}); });
@ -19,11 +19,10 @@ export default Ember.ArrayController.extend({
}, },
show() { show() {
var self = this; this.set('loading', true);
self.set('loading', true); ScreenedEmail.findAll().then(result => {
ScreenedEmail.findAll().then(function(result) { this.set('model', result);
self.set('model', result); this.set('loading', false);
self.set('loading', false);
}); });
} }
}); });

View File

@ -3,7 +3,7 @@ import { outputExportResult } from 'discourse/lib/export-result';
import { exportEntity } from 'discourse/lib/export-csv'; import { exportEntity } from 'discourse/lib/export-csv';
import ScreenedIpAddress from 'admin/models/screened-ip-address'; import ScreenedIpAddress from 'admin/models/screened-ip-address';
export default Ember.ArrayController.extend({ export default Ember.Controller.extend({
loading: false, loading: false,
filter: null, filter: null,
savedIpAddress: null, savedIpAddress: null,
@ -63,16 +63,15 @@ export default Ember.ArrayController.extend({
}, },
destroy(record) { destroy(record) {
const self = this;
return bootbox.confirm( return bootbox.confirm(
I18n.t("admin.logs.screened_ips.delete_confirm", { ip_address: record.get('ip_address') }), I18n.t("admin.logs.screened_ips.delete_confirm", { ip_address: record.get('ip_address') }),
I18n.t("no_value"), I18n.t("no_value"),
I18n.t("yes_value"), I18n.t("yes_value"),
function (result) { result => {
if (result) { if (result) {
record.destroy().then(deleted => { record.destroy().then(deleted => {
if (deleted) { if (deleted) {
self.get("content").removeObject(record); this.get("model").removeObject(record);
} else { } else {
bootbox.alert(I18n.t("generic_error")); bootbox.alert(I18n.t("generic_error"));
} }

View File

@ -2,15 +2,14 @@ import { exportEntity } from 'discourse/lib/export-csv';
import { outputExportResult } from 'discourse/lib/export-result'; import { outputExportResult } from 'discourse/lib/export-result';
import ScreenedUrl from 'admin/models/screened-url'; import ScreenedUrl from 'admin/models/screened-url';
export default Ember.ArrayController.extend({ export default Ember.Controller.extend({
loading: false, loading: false,
show() { show() {
const self = this; this.set('loading', true);
self.set('loading', true); ScreenedUrl.findAll().then(result => {
ScreenedUrl.findAll().then(function(result) { this.set('model', result);
self.set('model', result); this.set('loading', false);
self.set('loading', false);
}); });
}, },

View File

@ -2,7 +2,7 @@ import { exportEntity } from 'discourse/lib/export-csv';
import { outputExportResult } from 'discourse/lib/export-result'; import { outputExportResult } from 'discourse/lib/export-result';
import StaffActionLog from 'admin/models/staff-action-log'; import StaffActionLog from 'admin/models/staff-action-log';
export default Ember.ArrayController.extend({ export default Ember.Controller.extend({
loading: false, loading: false,
filters: null, filters: null,

View File

@ -1,16 +1,14 @@
import debounce from 'discourse/lib/debounce'; import debounce from 'discourse/lib/debounce';
import Permalink from 'admin/models/permalink'; import Permalink from 'admin/models/permalink';
export default Ember.ArrayController.extend({ export default Ember.Controller.extend({
loading: false, loading: false,
filter: null, filter: null,
show: debounce(function() { show: debounce(function() {
var self = this; Permalink.findAll(this.get("filter")).then(result => {
self.set('loading', true); this.set('model', result);
Permalink.findAll(self.get("filter")).then(function(result) { this.set('loading', false);
self.set('model', result);
self.set('loading', false);
}); });
}, 250).observes("filter"), }, 250).observes("filter"),
@ -20,12 +18,11 @@ export default Ember.ArrayController.extend({
}, },
destroy: function(record) { destroy: function(record) {
const self = this; return bootbox.confirm(I18n.t("admin.permalink.delete_confirm"), I18n.t("no_value"), I18n.t("yes_value"), result => {
return bootbox.confirm(I18n.t("admin.permalink.delete_confirm"), I18n.t("no_value"), I18n.t("yes_value"), function(result) {
if (result) { if (result) {
record.destroy().then(function(deleted) { record.destroy().then(deleted => {
if (deleted) { if (deleted) {
self.removeObject(record); this.get('model').removeObject(record);
} else { } else {
bootbox.alert(I18n.t("generic_error")); bootbox.alert(I18n.t("generic_error"));
} }

View File

@ -1,10 +1,9 @@
export default Ember.ArrayController.extend({ export default Ember.Controller.extend({
adminRoutes: function() { adminRoutes: function() {
return this.get('model').map(function(p) { return this.get('model').map(p => {
if (p.get('enabled')) { if (p.get('enabled')) {
return p.admin_route; return p.admin_route;
} }
}).compact(); }).compact();
}.property() }.property()
}); });

View File

@ -1,11 +1,11 @@
export default Ember.Controller.extend({ export default Ember.Controller.extend({
categoryNameKey: null, categoryNameKey: null,
needs: ['adminSiteSettings'], adminSiteSettings: Ember.inject.controller(),
filteredContent: function() { filteredContent: function() {
if (!this.get('categoryNameKey')) { return []; } if (!this.get('categoryNameKey')) { return []; }
const category = this.get('controllers.adminSiteSettings.content').findProperty('nameKey', this.get('categoryNameKey')); const category = this.get('adminSiteSettings.allSiteSettings').findProperty('nameKey', this.get('categoryNameKey'));
if (category) { if (category) {
return category.siteSettings; return category.siteSettings;
} else { } else {

View File

@ -1,6 +1,6 @@
import debounce from 'discourse/lib/debounce'; import debounce from 'discourse/lib/debounce';
export default Ember.ArrayController.extend({ export default Ember.Controller.extend({
filter: null, filter: null,
onlyOverridden: false, onlyOverridden: false,
filtered: Ember.computed.notEmpty('filter'), filtered: Ember.computed.notEmpty('filter'),

View File

@ -1,10 +1,11 @@
import UserBadge from 'discourse/models/user-badge'; import UserBadge from 'discourse/models/user-badge';
export default Ember.ArrayController.extend({ export default Ember.Controller.extend({
needs: ["adminUser"], adminUser: Ember.inject.controller(),
user: Em.computed.alias('controllers.adminUser.model'), user: Ember.computed.alias('adminUser.model'),
sortProperties: ['granted_at'],
sortAscending: false, sortedBadges: Ember.computed.sort('model', 'badgeSortOrder'),
badgeSortOrder: ['granted_at:desc'],
groupedBadges: function(){ groupedBadges: function(){
const allBadges = this.get('model'); const allBadges = this.get('model');
@ -38,8 +39,6 @@ export default Ember.ArrayController.extend({
}); });
return _(expanded).sortBy(group => group.granted_at).reverse().value(); return _(expanded).sortBy(group => group.granted_at).reverse().value();
}.property('model', 'model.[]', 'model.expandedBadges.[]'), }.property('model', 'model.[]', 'model.expandedBadges.[]'),
/** /**
@ -80,22 +79,15 @@ export default Ember.ArrayController.extend({
model.get('expandedBadges').pushObject(userBadge.badge.id); model.get('expandedBadges').pushObject(userBadge.badge.id);
}, },
/** grantBadge(badgeId) {
Grant the selected badge to the user. UserBadge.grant(badgeId, this.get('user.username'), this.get('badgeReason')).then(userBadge => {
this.set('badgeReason', '');
@method grantBadge this.get('model').pushObject(userBadge);
@param {Integer} badgeId id of the badge we want to grant. Ember.run.next(() => {
**/
grantBadge: function(badgeId) {
var self = this;
UserBadge.grant(badgeId, this.get('user.username'), this.get('badgeReason')).then(function(userBadge) {
self.set('badgeReason', '');
self.pushObject(userBadge);
Ember.run.next(function() {
// Update the selected badge ID after the combobox has re-rendered. // Update the selected badge ID after the combobox has re-rendered.
var newSelectedBadge = self.get('grantableBadges')[0]; const newSelectedBadge = this.get('grantableBadges')[0];
if (newSelectedBadge) { if (newSelectedBadge) {
self.set('selectedBadgeId', newSelectedBadge.get('id')); this.set('selectedBadgeId', newSelectedBadge.get('id'));
} }
}); });
}, function() { }, function() {
@ -104,12 +96,11 @@ export default Ember.ArrayController.extend({
}); });
}, },
revokeBadge: function(userBadge) { revokeBadge(userBadge) {
var self = this; return bootbox.confirm(I18n.t("admin.badges.revoke_confirm"), I18n.t("no_value"), I18n.t("yes_value"), result => {
return bootbox.confirm(I18n.t("admin.badges.revoke_confirm"), I18n.t("no_value"), I18n.t("yes_value"), function(result) {
if (result) { if (result) {
userBadge.revoke().then(function() { userBadge.revoke().then(() => {
self.get('model').removeObject(userBadge); this.get('model').removeObject(userBadge);
}); });
} }
}); });

View File

@ -2,7 +2,7 @@ import debounce from 'discourse/lib/debounce';
import { i18n } from 'discourse/lib/computed'; import { i18n } from 'discourse/lib/computed';
import AdminUser from 'admin/models/admin-user'; import AdminUser from 'admin/models/admin-user';
export default Ember.ArrayController.extend({ export default Ember.Controller.extend({
query: null, query: null,
showEmails: false, showEmails: false,
refreshing: false, refreshing: false,

View File

@ -1,16 +1,15 @@
import ModalFunctionality from 'discourse/mixins/modal-functionality'; import ModalFunctionality from 'discourse/mixins/modal-functionality';
export default Ember.Controller.extend(ModalFunctionality, { export default Ember.Controller.extend(ModalFunctionality, {
needs: ["admin-flags-list"], adminFlagsList: Ember.inject.controller(),
_agreeFlag: function (actionOnPost) { _agreeFlag: function (actionOnPost) {
var adminFlagController = this.get("controllers.admin-flags-list"); const adminFlagController = this.get("adminFlagsList");
var post = this.get("content"); const post = this.get("content");
var self = this;
return post.agreeFlags(actionOnPost).then(function () { return post.agreeFlags(actionOnPost).then(() => {
adminFlagController.removeObject(post); adminFlagController.get('model').removeObject(post);
self.send("closeModal"); this.send("closeModal");
}, function () { }, function () {
bootbox.alert(I18n.t("admin.flags.error")); bootbox.alert(I18n.t("admin.flags.error"));
}); });

View File

@ -1,36 +1,31 @@
import ModalFunctionality from 'discourse/mixins/modal-functionality'; import ModalFunctionality from 'discourse/mixins/modal-functionality';
export default Ember.Controller.extend(ModalFunctionality, { export default Ember.Controller.extend(ModalFunctionality, {
needs: ["admin-flags-list"], adminFlagsList: Ember.inject.controller(),
actions: { actions: {
deletePostDeferFlag() {
const adminFlagController = this.get("adminFlagsList");
const post = this.get("content");
deletePostDeferFlag: function () { return post.deferFlags(true).then(() => {
var adminFlagController = this.get("controllers.admin-flags-list"); adminFlagController.get('model').removeObject(post);
var post = this.get("content"); this.send("closeModal");
var self = this;
return post.deferFlags(true).then(function () {
adminFlagController.removeObject(post);
self.send("closeModal");
}, function () { }, function () {
bootbox.alert(I18n.t("admin.flags.error")); bootbox.alert(I18n.t("admin.flags.error"));
}); });
}, },
deletePostAgreeFlag: function () { deletePostAgreeFlag() {
var adminFlagController = this.get("controllers.admin-flags-list"); const adminFlagController = this.get("adminFlagsList");
var post = this.get("content"); const post = this.get("content");
var self = this;
return post.agreeFlags("delete").then(function () { return post.agreeFlags("delete").then(() => {
adminFlagController.removeObject(post); adminFlagController.get('model').removeObject(post);
self.send("closeModal"); this.send("closeModal");
}, function () { }, function () {
bootbox.alert(I18n.t("admin.flags.error")); bootbox.alert(I18n.t("admin.flags.error"));
}); });
} }
} }
}); });

View File

@ -2,7 +2,6 @@ import { ajax } from 'discourse/lib/ajax';
import PreloadStore from 'preload-store'; import PreloadStore from 'preload-store';
const Backup = Discourse.Model.extend({ const Backup = Discourse.Model.extend({
destroy() { destroy() {
return ajax("/admin/backups/" + this.get("filename"), { type: "DELETE" }); return ajax("/admin/backups/" + this.get("filename"), { type: "DELETE" });
}, },
@ -13,11 +12,9 @@ const Backup = Discourse.Model.extend({
data: { client_id: window.MessageBus.clientId } data: { client_id: window.MessageBus.clientId }
}); });
} }
}); });
Backup.reopenClass({ Backup.reopenClass({
find() { find() {
return PreloadStore.getAndRemove("backups", () => ajax("/admin/backups.json")) return PreloadStore.getAndRemove("backups", () => ajax("/admin/backups.json"))
.then(backups => backups.map(backup => Backup.create(backup))); .then(backups => backups.map(backup => Backup.create(backup)));

View File

@ -5,17 +5,17 @@ export default Ember.Route.extend({
// since the logs are pushed via the message bus // since the logs are pushed via the message bus
// we only want to preload them (hence the beforeModel hook) // we only want to preload them (hence the beforeModel hook)
beforeModel() { beforeModel() {
const logsController = this.controllerFor("adminBackupsLogs"); const logs = this.controllerFor("adminBackupsLogs").get('logs');
// preload the logs if any // preload the logs if any
PreloadStore.getAndRemove("logs").then(function (preloadedLogs) { PreloadStore.getAndRemove("logs").then(function (preloadedLogs) {
if (preloadedLogs && preloadedLogs.length) { if (preloadedLogs && preloadedLogs.length) {
// we need to filter out message like: "[SUCCESS]" // we need to filter out message like: "[SUCCESS]"
// and convert POJOs to Ember Objects // and convert POJOs to Ember Objects
const logs = _.chain(preloadedLogs) const newLogs = _.chain(preloadedLogs)
.reject(function (log) { return log.message.length === 0 || log.message[0] === "["; }) .reject(function (log) { return log.message.length === 0 || log.message[0] === "["; })
.map(function (log) { return Em.Object.create(log); }) .map(function (log) { return Em.Object.create(log); })
.value(); .value();
logsController.pushObjects(logs); logs.pushObjects(newLogs);
} }
}); });
}, },

View File

@ -15,7 +15,7 @@ export default Discourse.Route.extend({
_processLogMessage(log) { _processLogMessage(log) {
if (log.message === "[STARTED]") { if (log.message === "[STARTED]") {
this.controllerFor("adminBackups").set("model.isOperationRunning", true); this.controllerFor("adminBackups").set("model.isOperationRunning", true);
this.controllerFor("adminBackupsLogs").clear(); this.controllerFor("adminBackupsLogs").get('logs').clear();
} else if (log.message === "[FAILED]") { } else if (log.message === "[FAILED]") {
this.controllerFor("adminBackups").set("model.isOperationRunning", false); this.controllerFor("adminBackups").set("model.isOperationRunning", false);
bootbox.alert(I18n.t("admin.backups.operations.failed", { operation: log.operation })); bootbox.alert(I18n.t("admin.backups.operations.failed", { operation: log.operation }));
@ -27,7 +27,7 @@ export default Discourse.Route.extend({
window.location.pathname = Discourse.getURL("/"); window.location.pathname = Discourse.getURL("/");
} }
} else { } else {
this.controllerFor("adminBackupsLogs").pushObject(Em.Object.create(log)); this.controllerFor("adminBackupsLogs").get('logs').pushObject(Em.Object.create(log));
} }
}, },

View File

@ -5,21 +5,20 @@ import BadgeGrouping from 'discourse/models/badge-grouping';
export default Discourse.Route.extend({ export default Discourse.Route.extend({
_json: null, _json: null,
model: function() { model() {
var self = this; return ajax('/admin/badges.json').then(json => {
return ajax('/admin/badges.json').then(function(json) { this._json = json;
self._json = json;
return Badge.createFromJson(json); return Badge.createFromJson(json);
}); });
}, },
setupController: function(controller, model) { setupController(controller, model) {
var json = this._json, const json = this._json;
triggers = [], const badgeTriggers = [];
badgeGroupings = []; const badgeGroupings = [];
_.each(json.admin_badges.triggers,function(v,k){ _.each(json.admin_badges.triggers,function(v,k){
triggers.push({id: v, name: I18n.t('admin.badges.trigger_type.'+k)}); badgeTriggers.push({id: v, name: I18n.t('admin.badges.trigger_type.'+k)});
}); });
json.badge_groupings.forEach(function(badgeGroupingJson) { json.badge_groupings.forEach(function(badgeGroupingJson) {
@ -30,8 +29,8 @@ export default Discourse.Route.extend({
badgeGroupings: badgeGroupings, badgeGroupings: badgeGroupings,
badgeTypes: json.badge_types, badgeTypes: json.badge_types,
protectedSystemFields: json.admin_badges.protected_system_fields, protectedSystemFields: json.admin_badges.protected_system_fields,
badgeTriggers: triggers, badgeTriggers,
model: model model
}); });
} }
}); });

View File

@ -30,5 +30,4 @@
{{#unless hasMasterKey}} {{#unless hasMasterKey}}
<button class='btn' {{action "generateMasterKey"}}><i class="fa fa-key"></i>{{i18n 'admin.api.generate_master'}}</button> <button class='btn' {{action "generateMasterKey"}}><i class="fa fa-key"></i>{{i18n 'admin.api.generate_master'}}</button>
{{/unless }} {{/unless}}

View File

@ -0,0 +1 @@
{{admin-backups-logs logs=logs status=status}}

View File

@ -6,9 +6,9 @@
<div class="pull-right"> <div class="pull-right">
{{resumable-upload target="/admin/backups/upload" success="uploadSuccess" error="uploadError" uploadText=uploadLabel title="admin.backups.upload.title"}} {{resumable-upload target="/admin/backups/upload" success="uploadSuccess" error="uploadError" uploadText=uploadLabel title="admin.backups.upload.title"}}
{{#if site.isReadOnly}} {{#if site.isReadOnly}}
{{d-button icon="eye" action="toggleReadOnlyMode" disabled=status.model.isOperationRunning title="admin.backups.read_only.disable.title" label="admin.backups.read_only.disable.label"}} {{d-button icon="eye" action="toggleReadOnlyMode" disabled=status.isOperationRunning title="admin.backups.read_only.disable.title" label="admin.backups.read_only.disable.label"}}
{{else}} {{else}}
{{d-button icon="eye" action="toggleReadOnlyMode" disabled=status.model.isOperationRunning title="admin.backups.read_only.enable.title" label="admin.backups.read_only.enable.label"}} {{d-button icon="eye" action="toggleReadOnlyMode" disabled=status.isOperationRunning title="admin.backups.read_only.enable.title" label="admin.backups.read_only.enable.label"}}
{{/if}} {{/if}}
</div> </div>
</th> </th>
@ -20,12 +20,12 @@
<td> <td>
<div class="pull-right"> <div class="pull-right">
<a href={{backup.link}} class="btn download" title="{{i18n 'admin.backups.operations.download.title'}}">{{fa-icon "download"}}{{i18n 'admin.backups.operations.download.label'}}</a> <a href={{backup.link}} class="btn download" title="{{i18n 'admin.backups.operations.download.title'}}">{{fa-icon "download"}}{{i18n 'admin.backups.operations.download.label'}}</a>
{{#if status.model.isOperationRunning}} {{#if status.isOperationRunning}}
{{d-button icon="trash-o" action="destroyBackup" actionParam=backup class="btn-danger" disabled="true" title="admin.backups.operations.is_running"}} {{d-button icon="trash-o" action="destroyBackup" actionParam=backup class="btn-danger" disabled="true" title="admin.backups.operations.is_running"}}
{{d-button icon="play" action="startRestore" actionParam=backup disabled=status.model.restoreDisabled title=restoreTitle label="admin.backups.operations.restore.label"}} {{d-button icon="play" action="startRestore" actionParam=backup disabled=status.restoreDisabled title=restoreTitle label="admin.backups.operations.restore.label"}}
{{else}} {{else}}
{{d-button icon="trash-o" action="destroyBackup" actionParam=backup class="btn-danger" title="admin.backups.operations.destroy.title"}} {{d-button icon="trash-o" action="destroyBackup" actionParam=backup class="btn-danger" title="admin.backups.operations.destroy.title"}}
{{d-button icon="play" action="startRestore" actionParam=backup disabled=status.model.restoreDisabled title=restoreTitle label="admin.backups.operations.restore.label"}} {{d-button icon="play" action="startRestore" actionParam=backup disabled=status.restoreDisabled title=restoreTitle label="admin.backups.operations.restore.label"}}
{{/if}} {{/if}}
</div> </div>
</td> </td>

View File

@ -5,7 +5,7 @@
<p>{{emoji-uploader done="emojiUploaded"}}</p> <p>{{emoji-uploader done="emojiUploaded"}}</p>
{{#if model}} {{#if sortedEmojis}}
<div class="span8"> <div class="span8">
<table id="custom_emoji"> <table id="custom_emoji">
<thead> <thead>
@ -16,7 +16,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{{#each model as |e|}} {{#each sortedEmojis as |e|}}
<tr> <tr>
<th><img class="emoji" src="{{unbound e.url}}" title="{{unbound e.name}}"></th> <th><img class="emoji" src="{{unbound e.url}}" title="{{unbound e.name}}"></th>
<th>:{{e.name}}:</th> <th>:{{e.name}}:</th>

View File

@ -2,7 +2,7 @@
<div class='content-list span6'> <div class='content-list span6'>
<h3>{{i18n 'admin.groups.edit'}}</h3> <h3>{{i18n 'admin.groups.edit'}}</h3>
<ul> <ul>
{{#each model as |group|}} {{#each sortedGroups as |group|}}
<li> <li>
{{#link-to "adminGroup" group.type group.name}}{{group.name}} {{#link-to "adminGroup" group.type group.name}}{{group.name}}
{{#if group.userCountDisplay}} {{#if group.userCountDisplay}}

View File

@ -3,7 +3,7 @@ import { topicLevels } from 'discourse/lib/notification-levels';
// Support for changing the notification level of various topics // Support for changing the notification level of various topics
export default Ember.Controller.extend({ export default Ember.Controller.extend({
needs: ['topic-bulk-actions'], topicBulkActions: Ember.inject.controller(),
notificationLevelId: null, notificationLevelId: null,
@computed @computed
@ -21,7 +21,7 @@ export default Ember.Controller.extend({
actions: { actions: {
changeNotificationLevel() { changeNotificationLevel() {
this.get('controllers.topic-bulk-actions').performAndRefresh({ this.get('topicBulkActions').performAndRefresh({
type: 'change_notification_level', type: 'change_notification_level',
notification_level_id: this.get('notificationLevelId') notification_level_id: this.get('notificationLevelId')
}); });

View File

@ -1,19 +1,18 @@
import { fmt } from 'discourse/lib/computed'; import { fmt } from 'discourse/lib/computed';
export default Ember.ArrayController.extend({ export default Ember.Controller.extend({
needs: ['group'], group: Ember.inject.controller(),
loading: false, loading: false,
emptyText: fmt('type', 'groups.empty.%@'), emptyText: fmt('type', 'groups.empty.%@'),
actions: { actions: {
loadMore() { loadMore() {
if (this.get('loading')) { return; } if (this.get('loading')) { return; }
this.set('loading', true); this.set('loading', true);
const posts = this.get('model'); const posts = this.get('model');
if (posts && posts.length) { if (posts && posts.length) {
const beforePostId = posts[posts.length-1].get('id'); const beforePostId = posts[posts.length-1].get('id');
const group = this.get('controllers.group.model'); const group = this.get('group.model');
const opts = { beforePostId, type: this.get('type') }; const opts = { beforePostId, type: this.get('type') };
group.findPosts(opts).then(newPosts => { group.findPosts(opts).then(newPosts => {

View File

@ -1,27 +1,26 @@
import { ajax } from 'discourse/lib/ajax'; import { ajax } from 'discourse/lib/ajax';
import BadgeSelectController from "discourse/mixins/badge-select-controller"; import BadgeSelectController from "discourse/mixins/badge-select-controller";
export default Ember.ArrayController.extend(BadgeSelectController, { export default Ember.Controller.extend(BadgeSelectController, {
filteredList: function() { filteredList: function() {
return this.get('model').filterBy('badge.allow_title', true); return this.get('model').filterBy('badge.allow_title', true);
}.property('model'), }.property('model'),
actions: { actions: {
save: function() { save() {
this.setProperties({ saved: false, saving: true }); this.setProperties({ saved: false, saving: true });
var self = this;
ajax(this.get('user.path') + "/preferences/badge_title", { ajax(this.get('user.path') + "/preferences/badge_title", {
type: "PUT", type: "PUT",
data: { user_badge_id: self.get('selectedUserBadgeId') } data: { user_badge_id: this.get('selectedUserBadgeId') }
}).then(function() { }).then(() => {
self.setProperties({ this.setProperties({
saved: true, saved: true,
saving: false, saving: false,
"user.title": self.get('selectedUserBadge.badge.name') "user.title": this.get('selectedUserBadge.badge.name')
}); });
}, function() { }, () => {
bootbox.alert(I18n.t('generic_error')); bootbox.alert(I18n.t('generic_error'));
}); });
} }

View File

@ -1,7 +1,7 @@
import { ajax } from 'discourse/lib/ajax'; import { ajax } from 'discourse/lib/ajax';
import BadgeSelectController from "discourse/mixins/badge-select-controller"; import BadgeSelectController from "discourse/mixins/badge-select-controller";
export default Ember.ArrayController.extend(BadgeSelectController, { export default Ember.Controller.extend(BadgeSelectController, {
filteredList: function() { filteredList: function() {
return this.get('model').filter(function(b) { return this.get('model').filter(function(b) {
return !Ember.isEmpty(b.get('badge.image')); return !Ember.isEmpty(b.get('badge.image'));
@ -12,18 +12,17 @@ export default Ember.ArrayController.extend(BadgeSelectController, {
save: function() { save: function() {
this.setProperties({ saved: false, saving: true }); this.setProperties({ saved: false, saving: true });
var self = this;
ajax(this.get('user.path') + "/preferences/card-badge", { ajax(this.get('user.path') + "/preferences/card-badge", {
type: "PUT", type: "PUT",
data: { user_badge_id: self.get('selectedUserBadgeId') } data: { user_badge_id: this.get('selectedUserBadgeId') }
}).then(function() { }).then(() => {
self.setProperties({ this.setProperties({
saved: true, saved: true,
saving: false, saving: false,
"user.card_image_badge": self.get('selectedUserBadge.badge.image') "user.card_image_badge": this.get('selectedUserBadge.badge.image')
}); });
}).catch(function() { }).catch(() => {
self.set('saving', false); this.set('saving', false);
bootbox.alert(I18n.t('generic_error')); bootbox.alert(I18n.t('generic_error'));
}); });
} }

View File

@ -1,5 +1,5 @@
export default Ember.Controller.extend({ export default Ember.Controller.extend({
needs: ['tagGroups'], tagGroups: Ember.inject.controller(),
actions: { actions: {
save() { save() {
@ -7,17 +7,16 @@ export default Ember.Controller.extend({
}, },
destroy() { destroy() {
const self = this;
return bootbox.confirm( return bootbox.confirm(
I18n.t("tagging.groups.confirm_delete"), I18n.t("tagging.groups.confirm_delete"),
I18n.t("no_value"), I18n.t("no_value"),
I18n.t("yes_value"), I18n.t("yes_value"),
function(destroy) { destroy => {
if (destroy) { if (destroy) {
const c = self.controllerFor('tagGroups'); const c = this.get('tagGroups.model');
return self.get('model').destroy().then(function() { return this.get('model').destroy().then(() => {
c.removeObject(self.get('model')); c.removeObject(this.get('model'));
self.transitionToRoute('tagGroups'); this.transitionToRoute('tagGroups');
}); });
} }
} }

View File

@ -1,6 +1,6 @@
export default Ember.ArrayController.extend({ export default Ember.Controller.extend({
actions: { actions: {
selectTagGroup: function(tagGroup) { selectTagGroup(tagGroup) {
if (this.get('selectedItem')) { this.get('selectedItem').set('selected', false); } if (this.get('selectedItem')) { this.get('selectedItem').set('selected', false); }
this.set('selectedItem', tagGroup); this.set('selectedItem', tagGroup);
tagGroup.set('selected', true); tagGroup.set('selected', true);
@ -8,10 +8,10 @@ export default Ember.ArrayController.extend({
this.transitionToRoute('tagGroups.show', tagGroup); this.transitionToRoute('tagGroups.show', tagGroup);
}, },
newTagGroup: function() { newTagGroup() {
const newTagGroup = this.store.createRecord('tag-group'); const newTagGroup = this.store.createRecord('tag-group');
newTagGroup.set('name', I18n.t('tagging.groups.new_name')); newTagGroup.set('name', I18n.t('tagging.groups.new_name'));
this.pushObject(newTagGroup); this.get('model').pushObject(newTagGroup);
this.send('selectTagGroup', newTagGroup); this.send('selectTagGroup', newTagGroup);
} }
} }

View File

@ -17,7 +17,7 @@ addBulkButton('unlistTopics', 'unlist_topics');
addBulkButton('showTagTopics', 'change_tags'); addBulkButton('showTagTopics', 'change_tags');
// Modal for performing bulk actions on topics // Modal for performing bulk actions on topics
export default Ember.ArrayController.extend(ModalFunctionality, { export default Ember.Controller.extend(ModalFunctionality, {
tags: null, tags: null,
buttonRows: null, buttonRows: null,

View File

@ -24,6 +24,7 @@ export default Ember.Controller.extend(SelectedPostsCount, BufferedContent, {
retrying: false, retrying: false,
userTriggeredProgress: null, userTriggeredProgress: null,
_progressIndex: null, _progressIndex: null,
hasScrolled: null,
topicDelegated: [ topicDelegated: [
'toggleMultiSelect', 'toggleMultiSelect',

View File

@ -1,20 +1,6 @@
export default Ember.ArrayController.extend({ export default Ember.Controller.extend({
needs: ["user"], user: Ember.inject.controller(),
user: Em.computed.alias("controllers.user.model"), username: Ember.computed.alias('user.model.username_lower'),
sortProperties: ['badge.badge_type.sort_order', 'badge.name'], sortedBadges: Ember.computed.sort('model', 'badgeSortOrder'),
orderBy: function(ub1, ub2){ badgeSortOrder: ['badge.badge_type.sort_order', 'badge.name'],
var sr1 = ub1.get('badge.badge_type.sort_order');
var sr2 = ub2.get('badge.badge_type.sort_order');
if(sr1 > sr2) {
return -1;
}
if(sr2 > sr1) {
return 1;
}
return ub1.get('badge.name') < ub2.get('badge.name') ? -1 : 1;
}
}); });

View File

@ -1,12 +1,12 @@
import { ajax } from 'discourse/lib/ajax'; import { ajax } from 'discourse/lib/ajax';
import { default as computed, observes } from 'ember-addons/ember-computed-decorators'; import { default as computed, observes } from 'ember-addons/ember-computed-decorators';
export default Ember.ArrayController.extend({ export default Ember.Controller.extend({
needs: ['application'], application: Ember.inject.controller(),
@observes('model.canLoadMore') @observes('model.canLoadMore')
_showFooter() { _showFooter() {
this.set("controllers.application.showFooter", !this.get("model.canLoadMore")); this.set("application.showFooter", !this.get("model.canLoadMore"));
}, },
@computed('model.content.length') @computed('model.content.length')
@ -16,11 +16,9 @@ export default Ember.ArrayController.extend({
@computed('model.content.@each.read') @computed('model.content.@each.read')
allNotificationsRead() { allNotificationsRead() {
return !this.get('model.content').some((notification) => !notification.get('read')); return !this.get('model.content').some(notification => !notification.get('read'));
}, },
currentPath: Em.computed.alias('controllers.application.currentPath'),
actions: { actions: {
resetNew() { resetNew() {
ajax('/notifications/mark-read', { method: 'PUT' }).then(() => { ajax('/notifications/mark-read', { method: 'PUT' }).then(() => {

View File

@ -1,6 +1,6 @@
{{#discovery-categories refresh="refresh"}} {{#discovery-categories refresh="refresh"}}
{{component controller.categoryPageStyle {{component categoryPageStyle
categories=model.categories categories=model.categories
latestTopicOnly=controller.latestTopicOnly latestTopicOnly=latestTopicOnly
topics=model.topics}} topics=model.topics}}
{{/discovery-categories}} {{/discovery-categories}}

View File

@ -1,6 +1,6 @@
<div class='modal-body'> <div class='modal-body'>
<p>{{{i18n 'topics.bulk.selected' count=length}}}</p> <p>{{{i18n 'topics.bulk.selected' count=model.length}}}</p>
{{outlet "bulkOutlet"}} {{outlet "bulkOutlet"}}

View File

@ -1,6 +1,6 @@
{{#if model}} {{#if model}}
<div class="container"> <div class="container">
{{discourse-banner user=currentUser banner=site.banner overlay=view.hasScrolled hide=model.errorLoading}} {{discourse-banner user=currentUser banner=site.banner overlay=hasScrolled hide=model.errorLoading}}
</div> </div>
{{/if}} {{/if}}

View File

@ -1,5 +1,5 @@
<section class='user-content user-badges-list'> <section class='user-content user-badges-list'>
{{#each model as |ub|}} {{#each sortedBadges as |ub|}}
{{badge-card badge=ub.badge count=ub.count navigateOnClick="true" username=user.username_lower}} {{badge-card badge=ub.badge count=ub.count navigateOnClick="true" username=username}}
{{/each}} {{/each}}
</section> </section>

View File

@ -1,5 +1,5 @@
<section class='user-navigation'> <section class='user-navigation'>
{{#mobile-nav class='notifications-nav' desktopClass='notification-list action-list nav-stacked' currentPath=currentPath}} {{#mobile-nav class='notifications-nav' desktopClass='notification-list action-list nav-stacked' currentPath=application.currentPath}}
<li class='no-glyph'> <li class='no-glyph'>
{{#link-to 'userNotifications.index'}}{{i18n 'user.filters.all'}}{{/link-to}} {{#link-to 'userNotifications.index'}}{{i18n 'user.filters.all'}}{{/link-to}}
</li> </li>

View File

@ -93,9 +93,6 @@ const TopicView = Ember.View.extend(AddCategoryClass, AddArchetypeClass, Scrolli
this.set('docAt', false); this.set('docAt', false);
}, },
offset: 0,
hasScrolled: Em.computed.gt("offset", 0),
showTopicInHeader(topic, offset) { showTopicInHeader(topic, offset) {
if (this.get('docAt')) { if (this.get('docAt')) {
return offset >= this.get('docAt') || topic.get('postStream.firstPostNotLoaded'); return offset >= this.get('docAt') || topic.get('postStream.firstPostNotLoaded');
@ -118,7 +115,7 @@ const TopicView = Ember.View.extend(AddCategoryClass, AddArchetypeClass, Scrolli
} }
} }
this.set("offset", offset); this.set('controller.hasScrolled', offset > 0);
const topic = this.get('topic'); const topic = this.get('topic');
const showTopic = this.showTopicInHeader(topic, offset); const showTopic = this.showTopicInHeader(topic, offset);

View File

@ -1,3 +1,4 @@
window.ENV = { }; window.ENV = { };
window.EmberENV = window.EmberENV || {}; window.EmberENV = window.EmberENV || {};
window.EmberENV['FORCE_JQUERY'] = true; window.EmberENV.FORCE_JQUERY = true;
window.EmberENV._ENABLE_LEGACY_VIEW_SUPPORT = true;

View File

@ -9,7 +9,7 @@ test("grantableBadges", function() {
const badgeMiddle = Badge.create({id: 1, name: "My Badge", enabled: true}); const badgeMiddle = Badge.create({id: 1, name: "My Badge", enabled: true});
const badgeLast = Badge.create({id: 2, name: "Zoo Badge", enabled: true}); const badgeLast = Badge.create({id: 2, name: "Zoo Badge", enabled: true});
const badgeDisabled = Badge.create({id: 4, name: "Disabled Badge", enabled: false}); const badgeDisabled = Badge.create({id: 4, name: "Disabled Badge", enabled: false});
const controller = this.subject({ badges: [badgeLast, badgeFirst, badgeMiddle, badgeDisabled] }); const controller = this.subject({ model: [], badges: [badgeLast, badgeFirst, badgeMiddle, badgeDisabled] });
const sortedNames = [badgeFirst.name, badgeMiddle.name, badgeLast.name]; const sortedNames = [badgeFirst.name, badgeMiddle.name, badgeLast.name];
const badgeNames = controller.get('grantableBadges').map(function(badge) { const badgeNames = controller.get('grantableBadges').map(function(badge) {
return badge.name; return badge.name;