Cleaned up admin JS, added YUIDoc headers to all admin classes.

This commit is contained in:
Robin Ward 2013-02-21 14:09:28 -05:00
parent 8620024798
commit c1b5803486
27 changed files with 333 additions and 144 deletions

View File

@ -1,79 +1,81 @@
(function() {
/**
Our data model for dealing with users from the admin section.
@class AdminUser
@extends Discourse.Model
@namespace Discourse
@module Discourse
**/
window.Discourse.AdminUser = Discourse.Model.extend({
deleteAllPosts: function() {
this.set('can_delete_all_posts', false);
return jQuery.ajax("/admin/users/" + (this.get('id')) + "/delete_all_posts", {
type: 'PUT'
});
jQuery.ajax("/admin/users/" + (this.get('id')) + "/delete_all_posts", {type: 'PUT'});
},
/* Revoke the user's admin access
*/
// 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 jQuery.ajax("/admin/users/" + (this.get('id')) + "/revoke_admin", {
type: 'PUT'
});
return jQuery.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);
return jQuery.ajax("/admin/users/" + (this.get('id')) + "/grant_admin", {
type: 'PUT'
});
jQuery.ajax("/admin/users/" + (this.get('id')) + "/grant_admin", {type: 'PUT'});
},
/* Revoke the user's moderation access
*/
// 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 jQuery.ajax("/admin/users/" + (this.get('id')) + "/revoke_moderation", {
type: 'PUT'
});
return jQuery.ajax("/admin/users/" + (this.get('id')) + "/revoke_moderation", {type: 'PUT'});
},
grantModeration: function() {
this.set('moderator', true);
this.set('can_grant_moderation', false);
this.set('can_revoke_moderation', true);
return jQuery.ajax("/admin/users/" + (this.get('id')) + "/grant_moderation", {
type: 'PUT'
});
jQuery.ajax("/admin/users/" + (this.get('id')) + "/grant_moderation", {type: 'PUT'});
},
refreshBrowsers: function() {
jQuery.ajax("/admin/users/" + (this.get('id')) + "/refresh_browsers", {
type: 'POST'
});
return bootbox.alert("Message sent to all clients!");
jQuery.ajax("/admin/users/" + (this.get('id')) + "/refresh_browsers", {type: 'POST'});
bootbox.alert("Message sent to all clients!");
},
approve: function() {
this.set('can_approve', false);
this.set('approved', true);
this.set('approved_by', Discourse.get('currentUser'));
return jQuery.ajax("/admin/users/" + (this.get('id')) + "/approve", {
type: 'PUT'
});
jQuery.ajax("/admin/users/" + (this.get('id')) + "/approve", {type: 'PUT'});
},
username_lower: (function() {
return this.get('username').toLowerCase();
}).property('username'),
trustLevel: (function() {
return Discourse.get('site.trust_levels').findProperty('id', this.get('trust_level'));
}).property('trust_level'),
canBan: (function() {
return !this.admin && !this.moderator;
}).property('admin', 'moderator'),
banDuration: (function() {
var banned_at, banned_till;
banned_at = Date.create(this.banned_at);
banned_till = Date.create(this.banned_till);
return "" + (banned_at.short()) + " - " + (banned_till.short());
}).property('banned_till', 'banned_at'),
ban: function() {
var duration,
_this = this;
@ -81,9 +83,7 @@
if (duration > 0) {
return jQuery.ajax("/admin/users/" + this.id + "/ban", {
type: 'PUT',
data: {
duration: duration
},
data: {duration: duration},
success: function() {
window.location.reload();
},
@ -98,6 +98,7 @@
}
}
},
unban: function() {
var _this = this;
return jQuery.ajax("/admin/users/" + this.id + "/unban", {
@ -114,6 +115,7 @@
}
});
},
impersonate: function() {
var _this = this;
return jQuery.ajax("/admin/impersonate", {
@ -134,13 +136,11 @@
}
});
}
});
window.Discourse.AdminUser.reopenClass({
create: function(result) {
result = this._super(result);
return result;
},
bulkApprove: function(users) {
users.each(function(user) {
user.set('approved', true);
@ -156,6 +156,7 @@
}
});
},
find: function(username) {
var promise;
promise = new RSVP.Promise();
@ -167,6 +168,7 @@
});
return promise;
},
findAll: function(query, filter) {
var result;
result = Em.A();

View File

@ -1,25 +1,33 @@
(function() {
/**
Our data model for representing an email log.
@class EmailLog
@extends Discourse.Model
@namespace Discourse
@module Discourse
**/
window.Discourse.EmailLog = Discourse.Model.extend({});
window.Discourse.EmailLog.reopenClass({
create: function(attrs) {
if (attrs.user) {
attrs.user = Discourse.AdminUser.create(attrs.user);
}
return this._super(attrs);
},
findAll: function(filter) {
var result;
result = Em.A();
jQuery.ajax({
url: "/admin/email_logs.json",
data: {
filter: filter
},
data: { filter: filter },
success: function(logs) {
return logs.each(function(log) {
return result.pushObject(Discourse.EmailLog.create(log));
logs.each(function(log) {
result.pushObject(Discourse.EmailLog.create(log));
});
}
});

View File

@ -1,6 +1,15 @@
(function() {
/**
Our data model for interacting with flagged posts.
@class FlaggedPost
@extends Discourse.Post
@namespace Discourse
@module Discourse
**/
window.Discourse.FlaggedPost = Discourse.Post.extend({
flaggers: (function() {
var r,
_this = this;
@ -10,6 +19,7 @@
});
return r;
}).property(),
messages: (function() {
var r,
_this = this;
@ -24,15 +34,19 @@
});
return r;
}).property(),
lastFlagged: (function() {
return this.post_actions[0].created_at;
}).property(),
user: (function() {
return this.userLookup[this.user_id];
}).property(),
topicHidden: (function() {
return this.get('topic_visible') === 'f';
}).property('topic_hidden'),
deletePost: function() {
var promise;
promise = new RSVP.Promise();
@ -41,10 +55,10 @@
type: 'DELETE',
cache: false,
success: function() {
return promise.resolve();
promise.resolve();
},
error: function(e) {
return promise.reject();
promise.reject();
}
});
} else {
@ -52,14 +66,15 @@
type: 'DELETE',
cache: false,
success: function() {
return promise.resolve();
promise.resolve();
},
error: function(e) {
return promise.reject();
promise.reject();
}
});
}
},
clearFlags: function() {
var promise;
promise = new RSVP.Promise();
@ -67,19 +82,19 @@
type: 'POST',
cache: false,
success: function() {
return promise.resolve();
promise.resolve();
},
error: function(e) {
return promise.reject();
promise.reject();
}
});
return promise;
},
hiddenClass: (function() {
if (this.get('hidden') === "t") {
return "hidden-post";
}
if (this.get('hidden') === "t") return "hidden-post";
}).property()
});
window.Discourse.FlaggedPost.reopenClass({

View File

@ -1,15 +1,26 @@
(function() {
var SiteCustomizations;
/**
Our data model for interacting with site customizations.
@class SiteCustomization
@extends Discourse.Model
@namespace Discourse
@module Discourse
**/
window.Discourse.SiteCustomization = Discourse.Model.extend({
trackedProperties: ['enabled', 'name', 'stylesheet', 'header', 'override_default_style'],
init: function() {
this._super();
return this.startTrackingChanges();
},
trackedProperties: ['enabled', 'name', 'stylesheet', 'header', 'override_default_style'],
description: (function() {
return "" + this.name + (this.enabled ? ' (*)' : '');
}).property('selected', 'name'),
changed: (function() {
var _this = this;
if (!this.originals) {
@ -19,6 +30,7 @@
return _this.originals[p] !== _this.get(p);
});
}).property('override_default_style', 'enabled', 'name', 'stylesheet', 'header', 'originals'),
startTrackingChanges: function() {
var _this = this;
this.set('originals', {});
@ -27,12 +39,15 @@
return true;
});
},
previewUrl: (function() {
return "/?preview-style=" + (this.get('key'));
}).property('key'),
disableSave: (function() {
return !this.get('changed');
}).property('changed'),
save: function() {
var data;
this.startTrackingChanges();
@ -51,15 +66,16 @@
type: this.id ? 'PUT' : 'POST'
});
},
"delete": function() {
if (!this.id) {
return;
}
if (!this.id) return;
return jQuery.ajax({
url: "/admin/site_customizations/" + this.id,
type: 'DELETE'
});
}
});
SiteCustomizations = Ember.ArrayProxy.extend({

View File

@ -1,21 +1,26 @@
(function() {
window.Discourse.SiteSetting = Discourse.Model.extend(Discourse.Presence, {
/* Whether a property is short.
*/
/**
Our data model for interacting with site settings.
@class SiteCustomization
@extends Discourse.Model
@namespace Discourse
@module Discourse
**/
window.Discourse.SiteSetting = Discourse.Model.extend(Discourse.Presence, {
// Whether a property is short.
short: (function() {
if (this.blank('value')) {
return true;
}
if (this.blank('value')) return true;
return this.get('value').toString().length < 80;
}).property('value'),
/* Whether the site setting has changed
*/
// Whether the site setting has changed
dirty: (function() {
return this.get('originalValue') !== this.get('value');
}).property('originalValue', 'value'),
overridden: (function() {
var defaultVal, val;
val = this.get('value');
@ -25,21 +30,19 @@
}
return val !== defaultVal;
}).property('value'),
resetValue: function() {
return this.set('value', this.get('originalValue'));
},
save: function() {
/* Update the setting
*/
resetValue: function() {
this.set('value', this.get('originalValue'));
},
save: function() {
// Update the setting
var _this = this;
return jQuery.ajax("/admin/site_settings/" + (this.get('setting')), {
data: {
value: this.get('value')
},
data: { value: this.get('value') },
type: 'PUT',
success: function() {
return _this.set('originalValue', _this.get('value'));
_this.set('originalValue', _this.get('value'));
}
});
}

View File

@ -1,5 +1,13 @@
(function() {
/**
Our data model for determining whether there's a new version of Discourse
@class VersionCheck
@extends Discourse.Model
@namespace Discourse
@module Discourse
**/
window.Discourse.VersionCheck = Discourse.Model.extend({});
Discourse.VersionCheck.reopenClass({

View File

@ -1,5 +1,13 @@
(function() {
/**
Handles routes related to customization
@class AdminCustomizeRoute
@extends Discourse.Route
@namespace Discourse
@module Discourse
**/
Discourse.AdminCustomizeRoute = Discourse.Route.extend({
model: function() {
return Discourse.SiteCustomization.findAll();

View File

@ -1,11 +1,19 @@
(function() {
/**
Handles the default admin route
@class AdminDashboardRoute
@extends Discourse.Route
@namespace Discourse
@module Discourse
**/
Discourse.AdminDashboardRoute = Discourse.Route.extend({
setupController: function(c) {
if( Discourse.SiteSettings.version_checks ) {
return Discourse.VersionCheck.find().then(function(vc) {
Discourse.VersionCheck.find().then(function(vc) {
c.set('versionCheck', vc);
return c.set('loading', false);
c.set('loading', false);
});
}
}

View File

@ -1,5 +1,13 @@
(function() {
/**
Handles routes related to viewing email logs.
@class AdminEmailLogsRoute
@extends Discourse.Route
@namespace Discourse
@module Discourse
**/
Discourse.AdminEmailLogsRoute = Discourse.Route.extend({
model: function() {
return Discourse.EmailLog.findAll();

View File

@ -1,15 +1,25 @@
(function() {
/**
Handles routes related to viewing active flags.
@class AdminFlagsActiveRoute
@extends Discourse.Route
@namespace Discourse
@module Discourse
**/
Discourse.AdminFlagsActiveRoute = Discourse.Route.extend({
model: function() {
return Discourse.FlaggedPost.findAll('active');
},
setupController: function(controller, model) {
var c;
c = this.controllerFor('adminFlags');
c.set('content', model);
return c.set('query', 'active');
var adminFlagsController = this.controllerFor('adminFlags');
adminFlagsController.set('content', model);
adminFlagsController.set('query', 'active');
}
});
}).call(this);

View File

@ -1,15 +1,25 @@
(function() {
/**
Handles routes related to viewing old flags.
@class AdminFlagsOldRoute
@extends Discourse.Route
@namespace Discourse
@module Discourse
**/
Discourse.AdminFlagsOldRoute = Discourse.Route.extend({
model: function() {
return Discourse.FlaggedPost.findAll('old');
},
setupController: function(controller, model) {
var c;
c = this.controllerFor('adminFlags');
c.set('content', model);
return c.set('query', 'old');
var adminFlagsController = this.controllerFor('adminFlags');
adminFlagsController.set('content', model);
adminFlagsController.set('query', 'old');
}
});
}).call(this);

View File

@ -1,51 +1,30 @@
(function() {
/**
Declare all the routes used in the admin section.
**/
Discourse.buildRoutes(function() {
return this.resource('admin', {
path: '/admin'
}, function() {
this.route('dashboard', {
path: '/'
return this.resource('admin', { path: '/admin' }, function() {
this.route('dashboard', { path: '/' });
this.route('site_settings', { path: '/site_settings' });
this.route('email_logs', { path: '/email_logs' });
this.route('customize', { path: '/customize' });
this.resource('adminFlags', { path: '/flags' }, function() {
this.route('active', { path: '/active' });
this.route('old', { path: '/old' });
});
this.route('site_settings', {
path: '/site_settings'
});
this.route('email_logs', {
path: '/email_logs'
});
this.route('customize', {
path: '/customize'
});
this.resource('adminFlags', {
path: '/flags'
}, function() {
this.route('active', {
path: '/active'
});
return this.route('old', {
path: '/old'
});
});
return this.resource('adminUsers', {
path: '/users'
}, function() {
this.resource('adminUser', {
path: '/:username'
});
return this.resource('adminUsersList', {
path: '/list'
}, function() {
this.route('active', {
path: '/active'
});
this.route('new', {
path: '/new'
});
return this.route('pending', {
path: '/pending'
});
this.resource('adminUsers', { path: '/users' }, function() {
this.resource('adminUser', { path: '/:username' });
this.resource('adminUsersList', { path: '/list' }, function() {
this.route('active', { path: '/active' });
this.route('new', { path: '/new' });
this.route('pending', { path: '/pending' });
});
});
});
});

View File

@ -1,5 +1,13 @@
(function() {
/**
Handles routes related to viewing and editing site settings.
@class AdminSiteSettingsRoute
@extends Discourse.Route
@namespace Discourse
@module Discourse
**/
Discourse.AdminSiteSettingsRoute = Discourse.Route.extend({
model: function() {
return Discourse.SiteSetting.findAll();

View File

@ -1,5 +1,13 @@
(function() {
/**
Handles routes related to users.
@class AdminUserRoute
@extends Discourse.Route
@namespace Discourse
@module Discourse
**/
Discourse.AdminUserRoute = Discourse.Route.extend({
model: function(params) {
return Discourse.AdminUser.find(params.username);

View File

@ -1,7 +1,15 @@
(function() {
/**
Handles the route that lists active users.
@class AdminUsersListActiveRoute
@extends Discourse.Route
@namespace Discourse
@module Discourse
**/
Discourse.AdminUsersListActiveRoute = Discourse.Route.extend({
setupController: function(c) {
setupController: function() {
return this.controllerFor('adminUsersList').show('active');
}
});

View File

@ -1,7 +1,15 @@
(function() {
/**
Handles the route that lists new users.
@class AdminUsersListNewRoute
@extends Discourse.Route
@namespace Discourse
@module Discourse
**/
Discourse.AdminUsersListNewRoute = Discourse.Route.extend({
setupController: function(c) {
setupController: function() {
return this.controllerFor('adminUsersList').show('new');
}
});

View File

@ -1,7 +1,15 @@
(function() {
Discourse.AdminUsersListNewRoute = Discourse.Route.extend({
setupController: function(c) {
/**
Handles the route that lists pending users.
@class AdminUsersListNewRoute
@extends Discourse.Route
@namespace Discourse
@module Discourse
**/
Discourse.AdminUsersListPendingRoute = Discourse.Route.extend({
setupController: function() {
return this.controllerFor('adminUsersList').show('pending');
}
});

View File

@ -1,14 +1,24 @@
/*global ace:true */
(function() {
/**
A view that wraps the ACE editor (http://ace.ajax.org/)
@class AceEditorView
@extends Discourse.View
@namespace Discourse
@module Discourse
**/
Discourse.AceEditorView = window.Discourse.View.extend({
mode: 'css',
classNames: ['ace-wrapper'],
contentChanged: (function() {
if (this.editor && !this.skipContentChangeEvent) {
return this.editor.getSession().setValue(this.get('content'));
}
}).observes('content'),
render: function(buffer) {
buffer.push("<div class='ace'>");
if (this.get('content')) {
@ -16,12 +26,14 @@
}
return buffer.push("</div>");
},
willDestroyElement: function() {
if (this.editor) {
this.editor.destroy();
this.editor = null;
}
},
didInsertElement: function() {
var initAce,
_this = this;
@ -32,21 +44,11 @@
_this.editor.getSession().setMode("ace/mode/" + (_this.get('mode')));
return _this.editor.on("change", function(e) {
/* amending stuff as you type seems a bit out of scope for now - can revisit after launch
*/
/* changes = @get('changes')
*/
/* unless changes
*/
/* changes = []
*/
/* @set('changes', changes)
*/
/* changes.push e.data
changes = @get('changes')
unless changes
changes = []
@set('changes', changes)
changes.push e.data
*/
_this.skipContentChangeEvent = true;
_this.set('content', _this.editor.getSession().getValue());

View File

@ -1,26 +1,40 @@
/*global Mousetrap:true */
(function() {
/**
A view to handle site customizations
@class AdminCustomizeView
@extends Discourse.View
@namespace Discourse
@module Discourse
**/
Discourse.AdminCustomizeView = window.Discourse.View.extend({
templateName: 'admin/templates/customize',
classNames: ['customize'],
contentBinding: 'controller.content',
init: function() {
this._super();
return this.set('selected', 'stylesheet');
this.set('selected', 'stylesheet');
},
headerActive: (function() {
return this.get('selected') === 'header';
}).property('selected'),
stylesheetActive: (function() {
return this.get('selected') === 'stylesheet';
}).property('selected'),
selectHeader: function() {
return this.set('selected', 'header');
this.set('selected', 'header');
},
selectStylesheet: function() {
return this.set('selected', 'stylesheet');
this.set('selected', 'stylesheet');
},
didInsertElement: function() {
var _this = this;
return Mousetrap.bindGlobal(['meta+s', 'ctrl+s'], function() {
@ -28,9 +42,11 @@
return false;
});
},
willDestroyElement: function() {
return Mousetrap.unbindGlobal('meta+s', 'ctrl+s');
}
});
}).call(this);

View File

@ -1,5 +1,13 @@
(function() {
/**
The default view in the admin section
@class AdminDashboardView
@extends Discourse.View
@namespace Discourse
@module Discourse
**/
Discourse.AdminDashboardView = window.Discourse.View.extend({
templateName: 'admin/templates/dashboard'
});

View File

@ -1,5 +1,13 @@
(function() {
/**
A view for listing email logs
@class AdminEmailLogsView
@extends Discourse.View
@namespace Discourse
@module Discourse
**/
Discourse.AdminEmailLogsView = window.Discourse.View.extend({
templateName: 'admin/templates/email_logs'
});

View File

@ -1,5 +1,13 @@
(function() {
/**
A view for listing admin flags
@class AdminFlagsView
@extends Discourse.View
@namespace Discourse
@module Discourse
**/
Discourse.AdminFlagsView = window.Discourse.View.extend({
templateName: 'admin/templates/flags'
});

View File

@ -1,5 +1,13 @@
(function() {
/**
A view for dealing with site settings
@class AdminSiteSettingsView
@extends Discourse.View
@namespace Discourse
@module Discourse
**/
Discourse.AdminSiteSettingsView = window.Discourse.View.extend({
templateName: 'admin/templates/site_settings'
});

View File

@ -1,5 +1,13 @@
(function() {
/**
A view for showing a user in the admin section
@class AdminUserView
@extends Discourse.View
@namespace Discourse
@module Discourse
**/
Discourse.AdminUserView = window.Discourse.View.extend({
templateName: 'admin/templates/user'
});

View File

@ -1,5 +1,13 @@
(function() {
/**
A view for listing users in the admin section
@class AdminUsersListView
@extends Discourse.View
@namespace Discourse
@module Discourse
**/
Discourse.AdminUsersListView = window.Discourse.View.extend({
templateName: 'admin/templates/users_list'
});

View File

@ -1,5 +1,13 @@
(function() {
/**
A base view for the admin section
@class AdminView
@extends Discourse.View
@namespace Discourse
@module Discourse
**/
Discourse.AdminView = window.Discourse.View.extend({
templateName: 'admin/templates/admin'
});

View File

@ -3,7 +3,7 @@
"description": "This is the EmberJS client to access a Discourse Server",
"url": "http://www.discourse.org/",
"options": {
"exclude": "external,external_production",
"exclude": "external,external_production,defer",
"outdir": "./build"
}
}