diff --git a/app/assets/javascripts/admin/controllers/admin-badge.js.es6 b/app/assets/javascripts/admin/controllers/admin-badge.js.es6 deleted file mode 100644 index a1088411baa..00000000000 --- a/app/assets/javascripts/admin/controllers/admin-badge.js.es6 +++ /dev/null @@ -1,37 +0,0 @@ -import ObjectController from 'discourse/controllers/object'; - -/** - This is the itemController for `Discourse.AdminBadgesController`. Its main purpose - is to indicate which badge was selected. - - @class AdminBadgeController - @extends ObjectController - @namespace Discourse - @module Discourse -**/ - -export default ObjectController.extend({ - /** - Whether this badge has been selected. - - @property selected - @type {Boolean} - **/ - selected: Discourse.computed.propertyEqual('model.name', 'parentController.selectedItem.name'), - - /** - Show the displayName only if it is different from the name. - - @property showDisplayName - @type {Boolean} - **/ - showDisplayName: Discourse.computed.propertyNotEqual('selectedItem.name', 'selectedItem.displayName'), - - /** - Don't allow editing if this is a system badge. - - @property readOnly - @type {Boolean} - **/ - readOnly: Ember.computed.alias('model.system') -}); diff --git a/app/assets/javascripts/admin/controllers/admin-badges-show.js.es6 b/app/assets/javascripts/admin/controllers/admin-badges-show.js.es6 new file mode 100644 index 00000000000..b3d03c2d48b --- /dev/null +++ b/app/assets/javascripts/admin/controllers/admin-badges-show.js.es6 @@ -0,0 +1,98 @@ +import BufferedContent from 'discourse/mixins/buffered-content'; + +export default Ember.ObjectController.extend(BufferedContent, { + needs: ['admin-badges'], + saving: false, + savingStatus: '', + + badgeTypes: Em.computed.alias('controllers.admin-badges.badgeTypes'), + badgeGroupings: Em.computed.alias('controllers.admin-badges.badgeGroupings'), + badgeTriggers: Em.computed.alias('controllers.admin-badges.badgeTriggers'), + protectedSystemFields: Em.computed.alias('controllers.admin-badges.protectedSystemFields'), + + readOnly: Ember.computed.alias('buffered.system'), + showDisplayName: Discourse.computed.propertyNotEqual('name', 'displayName'), + canEditDescription: Em.computed.none('buffered.translatedDescription'), + + _resetSaving: function() { + this.set('saving', false); + this.set('savingStatus', ''); + }.observes('model.id'), + + actions: { + save: function() { + if (!this.get('saving')) { + var fields = ['allow_title', 'multiple_grant', + 'listable', 'auto_revoke', + 'enabled', 'show_posts', + 'target_posts', 'name', 'description', + 'icon', 'query', 'badge_grouping_id', + 'trigger', 'badge_type_id'], + self = this; + + if (this.get('buffered.system')){ + var protectedFields = this.get('protectedSystemFields'); + fields = _.filter(fields, function(f){ + return !_.include(protectedFields,f); + }); + } + + this.set('saving', true); + this.set('savingStatus', I18n.t('saving')); + + var boolFields = ['allow_title', 'multiple_grant', + 'listable', 'auto_revoke', + 'enabled', 'show_posts', + 'target_posts' ]; + + var data = {}, + buffered = this.get('buffered'); + fields.forEach(function(field){ + var d = buffered.get(field); + if (_.include(boolFields, field)) { d = !!d; } + data[field] = d; + }); + + var newBadge = !this.get('id'), + model = this.get('model'); + this.get('model').save(data).then(function() { + if (newBadge) { + self.get('controllers.admin-badges').pushObject(model); + self.transitionToRoute('adminBadges.show', model.get('id')); + } else { + self.commitBuffer(); + self.set('savingStatus', I18n.t('saved')); + } + + }).catch(function(error) { + self.set('savingStatus', I18n.t('failed')); + self.send('saveError', error); + }).finally(function() { + self.set('saving', false); + }); + } + }, + + destroy: function() { + var self = this, + adminBadgesController = this.get('controllers.admin-badges'), + model = this.get('model'); + + if (!model.get('id')) { + self.transitionToRoute('adminBadges.index'); + return; + } + + return bootbox.confirm(I18n.t("admin.badges.delete_confirm"), I18n.t("no_value"), I18n.t("yes_value"), function(result) { + if (result) { + model.destroy().then(function() { + adminBadgesController.removeObject(model); + self.transitionToRoute('adminBadges.index'); + }).catch(function() { + bootbox.alert(I18n.t('generic_error')); + }); + } + }); + } + } +}); diff --git a/app/assets/javascripts/admin/controllers/admin-badges.js.es6 b/app/assets/javascripts/admin/controllers/admin-badges.js.es6 index c679db8402b..24c4c051390 100644 --- a/app/assets/javascripts/admin/controllers/admin-badges.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-badges.js.es6 @@ -1,165 +1 @@ -/** - This controller supports the interface for dealing with badges. - - @class AdminBadgesController - @extends Ember.ArrayController - @namespace Discourse - @module Discourse -**/ -export default Ember.ArrayController.extend({ - needs: ['modal'], - itemController: 'admin-badge', - queryParams: ['badgeId'], - badgeId: Em.computed.alias('selectedId'), - - /** - ID of the currently selected badge. - - @property selectedId - @type {Integer} - **/ - selectedId: null, - - /** - Badge that is currently selected. - - @property selectedItem - @type {Discourse.Badge} - **/ - selectedItem: function() { - if (this.get('selectedId') === undefined || this.get('selectedId') === "undefined") { - // New Badge - return this.get('newBadge'); - } else { - // Existing Badge - var selectedId = parseInt(this.get('selectedId')); - return this.get('model').filter(function(badge) { - return parseInt(badge.get('id')) === selectedId; - })[0]; - } - }.property('selectedId', 'newBadge'), - - /** - Unsaved badge, if one exists. - - @property newBadge - @type {Discourse.Badge} - **/ - newBadge: function() { - return this.get('model').filter(function(badge) { - return badge.get('id') === undefined; - })[0]; - }.property('model.@each.id'), - - /** - Whether a new unsaved badge exists. - - @property newBadgeExists - @type {Discourse.Badge} - **/ - newBadgeExists: Em.computed.notEmpty('newBadge'), - - /** - We don't allow setting a description if a translation for the given badge - name exists. - - @property canEditDescription - @type {Boolean} - **/ - canEditDescription: Em.computed.none('selectedItem.translatedDescription'), - - /** - Disable saving if the currently selected item is being saved. - - @property disableSave - @type {Boolean} - **/ - disableSave: Em.computed.alias('selectedItem.saving'), - - actions: { - - /** - Create a new badge and select it. - - @method newBadge - **/ - createNewBadge: function() { - var badge = Discourse.Badge.create({ - name: I18n.t('admin.badges.new_badge') - }); - this.pushObject(badge); - this.send('selectBadge', badge); - }, - - /** - Select a particular badge. - - @method selectBadge - @param {Discourse.Badge} badge The badge to be selected - **/ - selectBadge: function(badge) { - this.set('selectedId', badge.get('id')); - }, - - /** - Save the selected badge. - - @method save - **/ - save: function() { - if (!this.get('disableSave')) { - var fields = ['allow_title', 'multiple_grant', - 'listable', 'auto_revoke', - 'enabled', 'show_posts', - 'target_posts', 'name', 'description', - 'icon', 'query', 'badge_grouping_id', - 'trigger', 'badge_type_id'], - self = this; - - if (this.get('selectedItem.system')){ - var protectedFields = this.get('protectedSystemFields'); - fields = _.filter(fields, function(f){ - return !_.include(protectedFields,f); - }); - } - - this.get('selectedItem').save(fields).catch(function(error) { - // this shows the admin-badge-preview modal with the error - // kinda weird, but it consolidates the display logic for badge errors - self.send('saveError', error); - }); - } - }, - - /** - Confirm before destroying the selected badge. - - @method destroy - **/ - destroy: function() { - // Delete immediately if the selected badge is new. - if (!this.get('selectedItem.id')) { - this.get('model').removeObject(this.get('selectedItem')); - this.set('selectedId', null); - return; - } - - var self = this; - return bootbox.confirm(I18n.t("admin.badges.delete_confirm"), I18n.t("no_value"), I18n.t("yes_value"), function(result) { - if (result) { - var selected = self.get('selectedItem'); - selected.destroy().then(function() { - // Success. - self.set('selectedId', null); - self.get('model').removeObject(selected); - }, function() { - // Failure. - bootbox.alert(I18n.t('generic_error')); - }); - } - }); - } - - } - -}); +export default Ember.ArrayController.extend(); diff --git a/app/assets/javascripts/admin/routes/admin-badges-show.js.es6 b/app/assets/javascripts/admin/routes/admin-badges-show.js.es6 new file mode 100644 index 00000000000..7cbb1ce4f25 --- /dev/null +++ b/app/assets/javascripts/admin/routes/admin-badges-show.js.es6 @@ -0,0 +1,52 @@ +export default Ember.Route.extend({ + serialize: function(m) { + return {badge_id: Em.get(m, 'id') || 'new'}; + }, + + model: function(params) { + if (params.badge_id === "new") { + return Discourse.Badge.create({ + name: I18n.t('admin.badges.new_badge') + }); + } + return this.modelFor('adminBadges').findProperty('id', parseInt(params.badge_id)); + }, + + actions: { + saveError: function(e) { + var msg = I18n.t("generic_error"); + if (e.responseJSON && e.responseJSON.errors) { + msg = I18n.t("generic_error_with_reason", {error: e.responseJSON.errors.join('. ')}); + } + bootbox.alert(msg); + }, + + editGroupings: function() { + var groupings = this.controllerFor('admin-badges').get('badgeGroupings'); + Discourse.Route.showModal(this, 'admin_edit_badge_groupings', groupings); + }, + + preview: function(badge, explain) { + var self = this; + + badge.set('preview_loading', true); + Discourse.ajax('/admin/badges/preview.json', { + method: 'post', + data: { + sql: badge.get('query'), + target_posts: !!badge.get('target_posts'), + trigger: badge.get('trigger'), + explain: explain + } + }).then(function(json) { + badge.set('preview_loading', false); + Discourse.Route.showModal(self, 'admin_badge_preview', json); + }).catch(function(error) { + badge.set('preview_loading', false); + Em.Logger.error(error); + bootbox.alert("Network error"); + }); + } + } + +}); diff --git a/app/assets/javascripts/admin/routes/admin-badges.js.es6 b/app/assets/javascripts/admin/routes/admin-badges.js.es6 new file mode 100644 index 00000000000..3d417f53c2f --- /dev/null +++ b/app/assets/javascripts/admin/routes/admin-badges.js.es6 @@ -0,0 +1,28 @@ +export default Discourse.Route.extend({ + _json: null, + + model: function() { + var self = this; + return Discourse.ajax('/admin/badges.json').then(function(json) { + self._json = json; + return Discourse.Badge.createFromJson(json); + }); + }, + + setupController: function(controller, model) { + var json = this._json, + triggers = []; + + _.each(json.admin_badges.triggers,function(v,k){ + triggers.push({id: v, name: I18n.t('admin.badges.trigger_type.'+k)}); + }); + + controller.setProperties({ + badgeGroupings: json.badge_groupings, + badgeTypes: json.badge_types, + protectedSystemFields: json.admin_badges.protected_system_fields, + badgeTriggers: triggers, + model: model + }); + } +}); diff --git a/app/assets/javascripts/admin/routes/admin_badges_route.js b/app/assets/javascripts/admin/routes/admin_badges_route.js deleted file mode 100644 index 4ef15173d36..00000000000 --- a/app/assets/javascripts/admin/routes/admin_badges_route.js +++ /dev/null @@ -1,54 +0,0 @@ -Discourse.AdminBadgesRoute = Discourse.Route.extend({ - setupController: function(controller) { - Discourse.ajax('/admin/badges.json').then(function(json){ - - controller.set('badgeGroupings', Em.A(json.badge_groupings)); - controller.set('badgeTypes', json.badge_types); - controller.set('protectedSystemFields', json.admin_badges.protected_system_fields); - var triggers = []; - _.each(json.admin_badges.triggers,function(v,k){ - triggers.push({id: v, name: I18n.t('admin.badges.trigger_type.'+k)}); - }); - controller.set('badgeTriggers', triggers); - controller.set('model', Discourse.Badge.createFromJson(json)); - }); - }, - - actions: { - editGroupings: function(model) { - Discourse.Route.showModal(this, 'admin_edit_badge_groupings', model); - }, - - saveError: function(jqXhr) { - if (jqXhr.status === 422) { - Discourse.Route.showModal(this, 'admin_badge_preview', jqXhr.responseJSON); - } else { - Em.Logger.error(jqXhr); - bootbox.alert(I18n.t('errors.description.unknown')); - } - }, - - preview: function(badge, explain) { - var self = this; - - badge.set('preview_loading', true); - Discourse.ajax('/admin/badges/preview.json', { - method: 'post', - data: { - sql: badge.query, - target_posts: !!badge.target_posts, - trigger: badge.trigger, - explain: explain - } - }).then(function(json) { - badge.set('preview_loading', false); - Discourse.Route.showModal(self, 'admin_badge_preview', json); - }).catch(function(error) { - badge.set('preview_loading', false); - Em.Logger.error(error); - bootbox.alert("Network error"); - }); - } - } - -}); diff --git a/app/assets/javascripts/admin/routes/admin_routes.js b/app/assets/javascripts/admin/routes/admin_routes.js index c5b63815f51..7ab29af5a6a 100644 --- a/app/assets/javascripts/admin/routes/admin_routes.js +++ b/app/assets/javascripts/admin/routes/admin_routes.js @@ -58,7 +58,9 @@ Discourse.Route.buildRoutes(function() { }); }); - this.route('badges'); + this.resource('adminBadges', { path: '/badges' }, function() { + this.route('show', { path: '/:badge_id' }); + }); }); }); diff --git a/app/assets/javascripts/admin/templates/admin.hbs b/app/assets/javascripts/admin/templates/admin.hbs index 0c85e3e0795..d67291e9ada 100644 --- a/app/assets/javascripts/admin/templates/admin.hbs +++ b/app/assets/javascripts/admin/templates/admin.hbs @@ -10,7 +10,7 @@ {{/if}}
{{i18n admin.badges.none_selected}}
+ +