FEATURE: flag dispositions normalization
All flags should end up in one of the three dispositions - Agree - Disagree - Defer In the administration area, the *active* flags section displays 4 buttons - Agree (hide post + send PM) - Disagree - Defer - Delete Clicking "Delete" will open a modal that offer to - Delete Post & Defer Flags - Delete Post & Agree with Flags - Delete Spammer (if available) When the flag has a list associated, the list will now display 1 response and 1 reply and a "show more..." link if there are more in the conversation. Replying to the conversation will NOT give a disposition. Moderators must click the buttons that does that. If someone clicks one buttons, this will add a default moderator message from that moderator saying what happened. The *old* flags section now displays the proper dispositions and is super duper fast (no more N+9999 queries). FIX: the old list includes deleted topics FIX: the lists now properly display the topic states (deleted, closed, archived, hidden, PM) FIX: flagging a topic that you've already flagged the first post
This commit is contained in:
@@ -8,36 +8,34 @@
|
||||
**/
|
||||
export default Ember.ArrayController.extend({
|
||||
|
||||
adminOldFlagsView: Em.computed.equal('query', 'old'),
|
||||
adminActiveFlagsView: Em.computed.equal('query', 'active'),
|
||||
|
||||
actions: {
|
||||
/**
|
||||
Clear all flags on a post
|
||||
|
||||
@method clearFlags
|
||||
@param {Discourse.FlaggedPost} item The post whose flags we want to clear
|
||||
**/
|
||||
disagreeFlags: function(item) {
|
||||
var adminFlagsController = this;
|
||||
item.disagreeFlags().then(function() {
|
||||
adminFlagsController.removeObject(item);
|
||||
}, function() {
|
||||
agreeFlags: function (flaggedPost) {
|
||||
var self = this;
|
||||
flaggedPost.agreeFlags().then(function () {
|
||||
self.removeObject(flaggedPost);
|
||||
}, function () {
|
||||
bootbox.alert(I18n.t("admin.flags.error"));
|
||||
});
|
||||
},
|
||||
|
||||
agreeFlags: function(item) {
|
||||
var adminFlagsController = this;
|
||||
item.agreeFlags().then(function() {
|
||||
adminFlagsController.removeObject(item);
|
||||
}, function() {
|
||||
disagreeFlags: function (flaggedPost) {
|
||||
var self = this;
|
||||
flaggedPost.disagreeFlags().then(function () {
|
||||
self.removeObject(flaggedPost);
|
||||
}, function () {
|
||||
bootbox.alert(I18n.t("admin.flags.error"));
|
||||
});
|
||||
},
|
||||
|
||||
deferFlags: function(item) {
|
||||
var adminFlagsController = this;
|
||||
item.deferFlags().then(function() {
|
||||
adminFlagsController.removeObject(item);
|
||||
}, function() {
|
||||
deferFlags: function (flaggedPost) {
|
||||
var self = this;
|
||||
flaggedPost.deferFlags().then(function () {
|
||||
self.removeObject(flaggedPost);
|
||||
}, function () {
|
||||
bootbox.alert(I18n.t("admin.flags.error"));
|
||||
});
|
||||
},
|
||||
@@ -45,47 +43,8 @@ export default Ember.ArrayController.extend({
|
||||
doneTopicFlags: function(item) {
|
||||
this.send('disagreeFlags', item);
|
||||
},
|
||||
|
||||
/**
|
||||
Deletes a post
|
||||
|
||||
@method deletePost
|
||||
@param {Discourse.FlaggedPost} post The post to delete
|
||||
**/
|
||||
deletePost: function(post) {
|
||||
var adminFlagsController = this;
|
||||
post.deletePost().then(function() {
|
||||
adminFlagsController.removeObject(post);
|
||||
}, function() {
|
||||
bootbox.alert(I18n.t("admin.flags.error"));
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
Deletes a user and all posts and topics created by that user.
|
||||
|
||||
@method deleteSpammer
|
||||
@param {Discourse.FlaggedPost} item The post to delete
|
||||
**/
|
||||
deleteSpammer: function(item) {
|
||||
item.get('user').deleteAsSpammer(function() { window.location.reload(); });
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
Are we viewing the 'old' view?
|
||||
|
||||
@property adminOldFlagsView
|
||||
**/
|
||||
adminOldFlagsView: Em.computed.equal('query', 'old'),
|
||||
|
||||
/**
|
||||
Are we viewing the 'active' view?
|
||||
|
||||
@property adminActiveFlagsView
|
||||
**/
|
||||
adminActiveFlagsView: Em.computed.equal('query', 'active'),
|
||||
|
||||
loadMore: function(){
|
||||
var flags = this.get('model');
|
||||
return Discourse.FlaggedPost.findAll(this.get('query'),flags.length+1).then(function(data){
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
The modal for deleting a flag.
|
||||
|
||||
@class AdminDeleteFlagController
|
||||
@extends Discourse.Controller
|
||||
@namespace Discourse
|
||||
@uses Discourse.ModalFunctionality
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.AdminDeleteFlagController = Discourse.ObjectController.extend(Discourse.ModalFunctionality, {
|
||||
|
||||
needs: ["adminFlags"],
|
||||
|
||||
actions: {
|
||||
|
||||
deletePostDeferFlag: function () {
|
||||
var adminFlagController = this.get("controllers.adminFlags");
|
||||
var post = this.get("content");
|
||||
var self = this;
|
||||
|
||||
return post.deferFlags(true).then(function () {
|
||||
adminFlagController.removeObject(post);
|
||||
self.send("closeModal");
|
||||
}, function () {
|
||||
bootbox.alert(I18n.t("admin.flags.error"));
|
||||
});
|
||||
},
|
||||
|
||||
deletePostAgreeFlag: function () {
|
||||
var adminFlagController = this.get("controllers.adminFlags");
|
||||
var post = this.get("content");
|
||||
var self = this;
|
||||
|
||||
return post.agreeFlags(true).then(function () {
|
||||
adminFlagController.removeObject(post);
|
||||
self.send("closeModal");
|
||||
}, function () {
|
||||
bootbox.alert(I18n.t("admin.flags.error"));
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
Deletes a user and all posts and topics created by that user.
|
||||
|
||||
@method deleteSpammer
|
||||
**/
|
||||
deleteSpammer: function () {
|
||||
this.get("content.user").deleteAsSpammer(function() { window.location.reload(); });
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
@@ -8,64 +8,69 @@
|
||||
**/
|
||||
Discourse.FlaggedPost = Discourse.Post.extend({
|
||||
|
||||
summary: function(){
|
||||
summary: function () {
|
||||
return _(this.post_actions)
|
||||
.groupBy(function(a){ return a.post_action_type_id; })
|
||||
.map(function(v,k){
|
||||
return I18n.t('admin.flags.summary.action_type_' + k, {count: v.length});
|
||||
})
|
||||
.groupBy(function (a) { return a.post_action_type_id; })
|
||||
.map(function (v,k) { return I18n.t('admin.flags.summary.action_type_' + k, { count: v.length }); })
|
||||
.join(',');
|
||||
}.property(),
|
||||
|
||||
flaggers: function() {
|
||||
var r,
|
||||
_this = this;
|
||||
r = [];
|
||||
_.each(this.post_actions, function(action) {
|
||||
var user = _this.userLookup[action.user_id];
|
||||
var deletedBy = null;
|
||||
if(action.deleted_by_id){
|
||||
deletedBy = _this.userLookup[action.deleted_by_id];
|
||||
}
|
||||
flaggers: function () {
|
||||
var self = this;
|
||||
var flaggers = [];
|
||||
|
||||
var flagType = I18n.t('admin.flags.summary.action_type_' + action.post_action_type_id, {count: 1});
|
||||
|
||||
r.push({
|
||||
user: user, flagType: flagType, flaggedAt: action.created_at, deletedBy: deletedBy,
|
||||
tookAction: action.staff_took_action, deletedAt: action.deleted_at
|
||||
_.each(this.post_actions, function (postAction) {
|
||||
flaggers.push({
|
||||
user: self.userLookup[postAction.user_id],
|
||||
topic: self.topicLookup[postAction.topic_id],
|
||||
flagType: I18n.t('admin.flags.summary.action_type_' + postAction.post_action_type_id, { count: 1 }),
|
||||
flaggedAt: postAction.created_at,
|
||||
disposedBy: postAction.disposed_by_id ? self.userLookup[postAction.disposed_by_id] : null,
|
||||
disposedAt: postAction.disposed_at,
|
||||
disposition: postAction.disposition ? I18n.t('admin.flags.dispositions.' + postAction.disposition) : null,
|
||||
tookAction: postAction.staff_took_action
|
||||
});
|
||||
});
|
||||
return r;
|
||||
|
||||
return flaggers;
|
||||
}.property(),
|
||||
|
||||
messages: function() {
|
||||
var r,
|
||||
_this = this;
|
||||
r = [];
|
||||
_.each(this.post_actions,function(action) {
|
||||
if (action.message) {
|
||||
r.push({
|
||||
user: _this.userLookup[action.user_id],
|
||||
message: action.message,
|
||||
permalink: action.permalink,
|
||||
bySystemUser: (action.user_id === -1 ? true : false)
|
||||
});
|
||||
conversations: function () {
|
||||
var self = this;
|
||||
var conversations = [];
|
||||
|
||||
_.each(this.post_actions, function (postAction) {
|
||||
if (postAction.conversation) {
|
||||
var conversation = {
|
||||
permalink: postAction.permalink,
|
||||
hasMore: postAction.conversation.has_more,
|
||||
response: {
|
||||
excerpt: postAction.conversation.response.excerpt,
|
||||
user: self.userLookup[postAction.conversation.response.user_id]
|
||||
}
|
||||
};
|
||||
|
||||
if (postAction.conversation.reply) {
|
||||
conversation["reply"] = {
|
||||
excerpt: postAction.conversation.reply.excerpt,
|
||||
user: self.userLookup[postAction.conversation.reply.user_id]
|
||||
};
|
||||
}
|
||||
|
||||
conversations.push(conversation);
|
||||
}
|
||||
});
|
||||
return r;
|
||||
}.property(),
|
||||
|
||||
lastFlagged: function() {
|
||||
return this.post_actions[0].created_at;
|
||||
return conversations;
|
||||
}.property(),
|
||||
|
||||
user: function() {
|
||||
return this.userLookup[this.user_id];
|
||||
}.property(),
|
||||
|
||||
topicHidden: function() {
|
||||
return !this.get('topic_visible');
|
||||
}.property('topic_hidden'),
|
||||
topic: function () {
|
||||
return this.topicLookup[this.topic_id];
|
||||
}.property(),
|
||||
|
||||
flaggedForSpam: function() {
|
||||
return !_.every(this.get('post_actions'), function(action) { return action.name_key !== 'spam'; });
|
||||
@@ -80,7 +85,7 @@ Discourse.FlaggedPost = Discourse.Post.extend({
|
||||
}.property('post_actions.@each.targets_topic'),
|
||||
|
||||
canDeleteAsSpammer: function() {
|
||||
return (Discourse.User.currentProp('staff') && this.get('flaggedForSpam') && this.get('user.can_delete_all_posts') && this.get('user.can_be_deleted'));
|
||||
return Discourse.User.currentProp('staff') && this.get('flaggedForSpam') && this.get('user.can_delete_all_posts') && this.get('user.can_be_deleted');
|
||||
}.property('flaggedForSpam'),
|
||||
|
||||
deletePost: function() {
|
||||
@@ -91,28 +96,24 @@ Discourse.FlaggedPost = Discourse.Post.extend({
|
||||
}
|
||||
},
|
||||
|
||||
disagreeFlags: function() {
|
||||
disagreeFlags: function () {
|
||||
return Discourse.ajax('/admin/flags/disagree/' + this.id, { type: 'POST', cache: false });
|
||||
},
|
||||
|
||||
deferFlags: function() {
|
||||
return Discourse.ajax('/admin/flags/defer/' + this.id, { type: 'POST', cache: false });
|
||||
deferFlags: function (deletePost) {
|
||||
return Discourse.ajax('/admin/flags/defer/' + this.id, { type: 'POST', cache: false, data: { delete_post: deletePost } });
|
||||
},
|
||||
|
||||
agreeFlags: function() {
|
||||
return Discourse.ajax('/admin/flags/agree/' + this.id, { type: 'POST', cache: false });
|
||||
agreeFlags: function (deletePost) {
|
||||
return Discourse.ajax('/admin/flags/agree/' + this.id, { type: 'POST', cache: false, data: { delete_post: deletePost } });
|
||||
},
|
||||
|
||||
postHidden: Em.computed.alias('hidden'),
|
||||
|
||||
extraClasses: function() {
|
||||
var classes = [];
|
||||
if (this.get('hidden')) {
|
||||
classes.push('hidden-post');
|
||||
}
|
||||
if (this.get('deleted')){
|
||||
classes.push('deleted');
|
||||
}
|
||||
if (this.get('hidden')) { classes.push('hidden-post'); }
|
||||
if (this.get('deleted')) { classes.push('deleted'); }
|
||||
return classes.join(' ');
|
||||
}.property(),
|
||||
|
||||
@@ -121,26 +122,36 @@ Discourse.FlaggedPost = Discourse.Post.extend({
|
||||
});
|
||||
|
||||
Discourse.FlaggedPost.reopenClass({
|
||||
findAll: function(filter, offset) {
|
||||
|
||||
findAll: function (filter, offset) {
|
||||
offset = offset || 0;
|
||||
|
||||
var result = Em.A();
|
||||
result.set('loading', true);
|
||||
return Discourse.ajax('/admin/flags/' + filter + '.json?offset=' + offset).then(function(data) {
|
||||
|
||||
return Discourse.ajax('/admin/flags/' + filter + '.json?offset=' + offset).then(function (data) {
|
||||
// users
|
||||
var userLookup = {};
|
||||
_.each(data.users,function(user) {
|
||||
_.each(data.users,function (user) {
|
||||
userLookup[user.id] = Discourse.AdminUser.create(user);
|
||||
});
|
||||
_.each(data.posts,function(post) {
|
||||
|
||||
// topics
|
||||
var topicLookup = {};
|
||||
_.each(data.topics, function (topic) {
|
||||
topicLookup[topic.id] = Discourse.Topic.create(topic);
|
||||
});
|
||||
|
||||
// posts
|
||||
_.each(data.posts,function (post) {
|
||||
var f = Discourse.FlaggedPost.create(post);
|
||||
f.userLookup = userLookup;
|
||||
f.topicLookup = topicLookup;
|
||||
result.pushObject(f);
|
||||
});
|
||||
|
||||
result.set('loading', false);
|
||||
|
||||
return result;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -18,7 +18,16 @@ Discourse.AdminFlagsRouteType = Discourse.Route.extend({
|
||||
});
|
||||
|
||||
Discourse.AdminFlagsActiveRoute = Discourse.AdminFlagsRouteType.extend({
|
||||
filter: 'active'
|
||||
filter: 'active',
|
||||
|
||||
actions: {
|
||||
|
||||
showDeleteFlagModal: function(flaggedPost) {
|
||||
Discourse.Route.showModal(this, 'admin_delete_flag', flaggedPost);
|
||||
this.controllerFor('modal').set('modalClass', 'delete-flag-modal');
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
</div>
|
||||
|
||||
<div class="admin-container">
|
||||
{{#if model.loading}}
|
||||
{{#if loading}}
|
||||
<div class='admin-loading'>{{i18n loading}}</div>
|
||||
{{else}}
|
||||
{{#if model.length}}
|
||||
{{#if length}}
|
||||
<table class='admin-flags'>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -19,131 +19,141 @@
|
||||
<th class='excerpt'></th>
|
||||
<th class='flaggers'>{{i18n admin.flags.flagged_by}}</th>
|
||||
<th class='flaggers'>{{#if adminOldFlagsView}}{{i18n admin.flags.resolved_by}}{{/if}}</th>
|
||||
<th class='last-flagged'></th>
|
||||
<th class='action'></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each flaggedPost in content}}
|
||||
<tr {{bind-attr class="flaggedPost.extraClasses"}}>
|
||||
<tr {{bind-attr class="flaggedPost.extraClasses"}}>
|
||||
|
||||
<td class='user'>
|
||||
{{#if flaggedPost.postAuthorFlagged}}
|
||||
{{#if flaggedPost.user}}
|
||||
{{#link-to 'adminUser' flaggedPost.user}}{{avatar flaggedPost.user imageSize="small"}}{{/link-to}}
|
||||
<td class='user'>
|
||||
{{#if flaggedPost.postAuthorFlagged}}
|
||||
{{#if flaggedPost.user}}
|
||||
{{#link-to 'adminUser' flaggedPost.user}}{{avatar flaggedPost.user imageSize="small"}}{{/link-to}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</td>
|
||||
</td>
|
||||
|
||||
<td class='excerpt'>
|
||||
{{#if flaggedPost.topicHidden}}<i title='{{i18n topic_statuses.invisible.help}}' class='fa fa-eye-slash'></i> {{/if}}<h3><a href='{{unbound flaggedPost.url}}'>{{flaggedPost.title}}</a></h3>
|
||||
<br>
|
||||
{{#if flaggedPost.postAuthorFlagged}}
|
||||
{{{flaggedPost.excerpt}}}
|
||||
{{/if}}
|
||||
</td>
|
||||
<td class='excerpt'>
|
||||
<h3>
|
||||
{{#if flaggedPost.topic.isPrivateMessage}}
|
||||
<span class="private-message-glyph">{{icon envelope}}</span>
|
||||
{{/if}}
|
||||
{{topic-status topic=flaggedPost.topic}}
|
||||
<a href='{{unbound flaggedPost.topic.url}}'>{{flaggedPost.topic.title}}</a>
|
||||
</h3>
|
||||
{{#if flaggedPost.postAuthorFlagged}}
|
||||
{{{flaggedPost.excerpt}}}
|
||||
{{/if}}
|
||||
</td>
|
||||
|
||||
<td class='flaggers'>
|
||||
<table>
|
||||
<tbody>
|
||||
{{#each flaggedPost.flaggers}}
|
||||
<tr>
|
||||
<td>
|
||||
{{#link-to 'adminUser' this.user}}{{avatar this.user imageSize="small"}} {{/link-to}}
|
||||
</td>
|
||||
<td>
|
||||
{{date this.flaggedAt}}
|
||||
</td>
|
||||
<td>
|
||||
{{this.flagType}}
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
<td class='flaggers'>
|
||||
<table>
|
||||
<tbody>
|
||||
{{#each flaggedPost.flaggers}}
|
||||
<tr>
|
||||
<td width="20%">
|
||||
{{#link-to 'adminUser' user}}
|
||||
{{avatar user imageSize="small"}}
|
||||
{{/link-to}}
|
||||
</td>
|
||||
<td width="30%">
|
||||
{{date flaggedAt}}
|
||||
</td>
|
||||
<td width="50%">
|
||||
{{flagType}}
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
|
||||
<td class='flaggers result'>
|
||||
<table>
|
||||
<tbody>
|
||||
{{#each flaggedPost.flaggers}}
|
||||
<tr>
|
||||
{{#if deletedBy}}
|
||||
<td>
|
||||
{{#link-to 'adminUser' this.deletedBy}}{{avatar this.deletedBy imageSize="small"}} {{/link-to}}
|
||||
</td>
|
||||
<td>
|
||||
{{#if this.tookAction}}
|
||||
<i class='fa fa-gavel'></i>
|
||||
{{/if}}
|
||||
</td>
|
||||
<td>
|
||||
{{date this.deletedAt}}
|
||||
</td>
|
||||
{{/if}}
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<td class='flaggers result'>
|
||||
<table>
|
||||
<tbody>
|
||||
{{#each flaggedPost.flaggers}}
|
||||
<tr>
|
||||
<td width="20%">
|
||||
{{#link-to 'adminUser' disposedBy}}
|
||||
{{avatar disposedBy imageSize="small"}}
|
||||
{{/link-to}}
|
||||
</td>
|
||||
<td width="30%">
|
||||
{{date disposedAt}}
|
||||
</td>
|
||||
<td width="50%">
|
||||
{{disposition}}
|
||||
{{#if tookAction}}
|
||||
<i class='fa fa-gavel'></i>
|
||||
{{/if}}
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
{{#if flaggedPost.topicFlagged}}
|
||||
<tr>
|
||||
<td></td>
|
||||
<td class='message'><div>{{{i18n admin.flags.topic_flagged}}}</div></td>
|
||||
<td></td>
|
||||
<tr class='message'>
|
||||
<td></td>
|
||||
<td colspan="3">
|
||||
<div>
|
||||
{{{i18n admin.flags.topic_flagged}}}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{{/if}}
|
||||
|
||||
{{#each flaggedPost.messages}}
|
||||
<tr>
|
||||
{{#each flaggedPost.conversations}}
|
||||
<tr class='message'>
|
||||
<td></td>
|
||||
<td class='message'>
|
||||
<td colspan="3">
|
||||
<div>
|
||||
{{#unless bySystemUser}}
|
||||
{{#link-to 'adminUser' user}}{{avatar user imageSize="small"}}{{/link-to}}
|
||||
{{message}}
|
||||
<a href="{{unbound permalink}}"><button class='btn'><i class="fa fa-reply"></i> {{i18n admin.flags.view_message}}</button></a>
|
||||
{{else}}
|
||||
<b>{{i18n admin.flags.system}}</b>:
|
||||
{{message}}
|
||||
{{/unless}}
|
||||
{{#if response}}
|
||||
<p>
|
||||
{{#link-to 'adminUser' response.user}}{{avatar response.user imageSize="small"}}{{/link-to}} {{{response.excerpt}}}
|
||||
</p>
|
||||
{{#if reply}}
|
||||
<p>
|
||||
{{#link-to 'adminUser' reply.user}}{{avatar reply.user imageSize="small"}}{{/link-to}} {{{reply.excerpt}}}
|
||||
{{#if hasMore}}
|
||||
<a href="{{unbound permalink}}">{{i18n admin.flags.more}}</a>
|
||||
{{/if}}
|
||||
</p>
|
||||
{{/if}}
|
||||
<a href="{{unbound permalink}}">
|
||||
<button class='btn btn-reply'><i class="fa fa-reply"></i> {{i18n admin.flags.reply_message}}</button>
|
||||
</a>
|
||||
{{/if}}
|
||||
</div>
|
||||
</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
|
||||
<tr>
|
||||
<tr>
|
||||
<td colspan="4" class="action">
|
||||
{{#if adminActiveFlagsView}}
|
||||
{{#if flaggedPost.topicFlagged}}
|
||||
<a href='{{unbound flaggedPost.url}}' class="btn">{{i18n admin.flags.visit_topic}}</a>
|
||||
{{/if}}
|
||||
{{#if adminActiveFlagsView}}
|
||||
{{#if flaggedPost.topicFlagged}}
|
||||
<a href='{{unbound flaggedPost.url}}' class="btn">{{i18n admin.flags.visit_topic}}</a>
|
||||
{{/if}}
|
||||
|
||||
{{#if flaggedPost.postAuthorFlagged}}
|
||||
{{#if flaggedPost.postHidden}}
|
||||
<button title='{{i18n admin.flags.disagree_unhide_title}}' class='btn' {{action disagreeFlags flaggedPost}}><i class="fa fa-thumbs-o-down"></i> {{i18n admin.flags.disagree_unhide}}</button>
|
||||
<button title='{{i18n admin.flags.defer_title}}' class='btn' {{action deferFlags flaggedPost}}><i class="fa fa-external-link"></i> {{i18n admin.flags.defer}}</button>
|
||||
{{#if flaggedPost.postAuthorFlagged}}
|
||||
{{#if flaggedPost.postHidden}}
|
||||
<button title='{{i18n admin.flags.disagree_flag_unhide_post_title}}' class='btn' {{action disagreeFlags flaggedPost}}><i class="fa fa-thumbs-o-down"></i> {{i18n admin.flags.disagree_flag_unhide_post}}</button>
|
||||
{{else}}
|
||||
<button title='{{i18n admin.flags.agree_flag_hide_post_title}}' class='btn btn-primary' {{action agreeFlags flaggedPost}}><i class="fa fa-thumbs-o-up"></i> {{i18n admin.flags.agree_flag_hide_post}}</button>
|
||||
<button title='{{i18n admin.flags.disagree_flag_title}}' class='btn' {{action disagreeFlags flaggedPost}}><i class="fa fa-thumbs-o-down"></i> {{i18n admin.flags.disagree_flag}}</button>
|
||||
{{/if}}
|
||||
<button title='{{i18n admin.flags.defer_flag_title}}' class='btn' {{action deferFlags flaggedPost}}><i class="fa fa-external-link"></i> {{i18n admin.flags.defer_flag}}</button>
|
||||
<button title='{{i18n admin.flags.delete_title}}' class='btn btn-danger' {{action showDeleteFlagModal flaggedPost}}><i class="fa fa-trash-o"></i> {{i18n admin.flags.delete}}</button>
|
||||
{{else}}
|
||||
<button title='{{i18n admin.flags.agree_hide_title}}' class='btn' {{action agreeFlags flaggedPost}}><i class="fa fa-thumbs-o-up"></i> {{i18n admin.flags.agree_hide}}</button>
|
||||
<button title='{{i18n admin.flags.disagree_title}}' class='btn' {{action disagreeFlags flaggedPost}}><i class="fa fa-thumbs-o-down"></i> {{i18n admin.flags.disagree}}</button>
|
||||
<button title='{{i18n admin.flags.clear_topic_flags_title}}' class='btn' {{action doneTopicFlags flaggedPost}}>{{i18n admin.flags.clear_topic_flags}}</button>
|
||||
{{/if}}
|
||||
|
||||
{{#if flaggedPost.canDeleteAsSpammer}}
|
||||
<button title='{{i18n admin.flags.delete_spammer_title}}' class="btn" {{action deleteSpammer flaggedPost}}><i class="fa fa-exclamation-triangle"></i> {{i18n flagging.delete_spammer}}</button>
|
||||
{{/if}}
|
||||
|
||||
<button title='{{i18n admin.flags.delete_post_title}}' class='btn' {{action deletePost flaggedPost}}><i class="fa fa-trash-o"></i> {{i18n admin.flags.delete_post}}</button>
|
||||
{{else}}
|
||||
<button title='{{i18n admin.flags.clear_topic_flags_title}}' class='btn' {{action doneTopicFlags flaggedPost}}>{{i18n admin.flags.clear_topic_flags}}</button>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</td>
|
||||
</tr>
|
||||
</tr>
|
||||
|
||||
{{/each}}
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<button title="{{i18n admin.flags.delete_post_defer_flag_title}}" {{action deletePostDeferFlag}} class="btn btn-primary"><i class="fa fa-trash-o"></i> {{i18n admin.flags.delete_post_defer_flag}}</button>
|
||||
<button title="{{i18n admin.flags.delete_post_agree_flag_title}}" {{action deletePostAgreeFlag}} class="btn btn-primary"><i class="fa fa-trash-o"></i> {{i18n admin.flags.delete_post_agree_flag}}</button>
|
||||
{{#if canDeleteAsSpammer}}
|
||||
<button title="{{i18n admin.flags.delete_spammer_title}}" {{action deleteSpammer}} class="btn btn-danger"><i class="fa fa-exclamation-triangle"></i> {{i18n admin.flags.delete_spammer}}</button>
|
||||
{{/if}}
|
||||
@@ -1,13 +1,21 @@
|
||||
Discourse.AdminFlagsView = Discourse.View.extend(Discourse.LoadMore, {
|
||||
loading: false,
|
||||
eyelineSelector: '.admin-flags tbody tr',
|
||||
loadMore: function() {
|
||||
var view = this;
|
||||
if(this.get("loading") || this.get("model.allLoaded")) { return; }
|
||||
this.set("loading", true);
|
||||
this.get("controller").loadMore().then(function(){
|
||||
view.set("loading", false);
|
||||
});
|
||||
|
||||
actions: {
|
||||
|
||||
loadMore: function() {
|
||||
var self = this;
|
||||
|
||||
if (this.get("loading") || this.get("model.allLoaded")) { return; }
|
||||
|
||||
this.set("loading", true);
|
||||
|
||||
this.get("controller").loadMore().then(function () {
|
||||
self.set("loading", false);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
A modal view for deleting a flag.
|
||||
|
||||
@class AdminDeleteFlagView
|
||||
@extends Discourse.ModalBodyView
|
||||
@namespace Discourse
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.AdminDeleteFlagView = Discourse.ModalBodyView.extend({
|
||||
templateName: 'admin/templates/modal/admin_delete_flag',
|
||||
title: I18n.t('admin.flags.delete_flag_modal_title')
|
||||
});
|
||||
Reference in New Issue
Block a user