mirror of
https://github.com/discourse/discourse.git
synced 2025-04-01 04:05:55 +08:00
Refactor flagged posts into components
This commit is contained in:
parent
40eba8cd93
commit
be0eb0a554
36
app/assets/javascripts/admin/components/flagged-post.js.es6
Normal file
36
app/assets/javascripts/admin/components/flagged-post.js.es6
Normal file
@ -0,0 +1,36 @@
|
||||
import showModal from 'discourse/lib/show-modal';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
tagName: '',
|
||||
|
||||
removeAfter(promise) {
|
||||
return promise.then(() => {
|
||||
this.attrs.removePost();
|
||||
}).catch(() => {
|
||||
bootbox.alert(I18n.t("admin.flags.error"));
|
||||
});
|
||||
},
|
||||
|
||||
_spawnModal(name, model, modalClass) {
|
||||
let controller = showModal(name, { model, admin: true, modalClass });
|
||||
controller.removeAfter = (p) => this.removeAfter(p);
|
||||
},
|
||||
|
||||
actions: {
|
||||
showAgreeFlagModal() {
|
||||
this._spawnModal('admin-agree-flag', this.get('flaggedPost'), 'agree-flag-modal');
|
||||
},
|
||||
|
||||
showDeleteFlagModal() {
|
||||
this._spawnModal('admin-delete-flag', this.get('flaggedPost'), 'delete-flag-modal');
|
||||
},
|
||||
|
||||
disagree() {
|
||||
this.removeAfter(this.get('flaggedPost').disagreeFlags());
|
||||
},
|
||||
|
||||
defer() {
|
||||
this.removeAfter(this.get('flaggedPost').deferFlags());
|
||||
}
|
||||
}
|
||||
});
|
@ -5,7 +5,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
|
||||
|
||||
_agreeFlag(action) {
|
||||
let flaggedPost = this.get('model');
|
||||
return this.removeAfter(flaggedPost.agreeFlags(action), flaggedPost).then(() => {
|
||||
return this.removeAfter(flaggedPost.agreeFlags(action)).then(() => {
|
||||
this.send('closeModal');
|
||||
});
|
||||
},
|
||||
|
@ -6,14 +6,14 @@ export default Ember.Controller.extend(ModalFunctionality, {
|
||||
actions: {
|
||||
deletePostDeferFlag() {
|
||||
let flaggedPost = this.get('model');
|
||||
this.removeAfter(flaggedPost.deferFlags(true), flaggedPost).then(() => {
|
||||
this.removeAfter(flaggedPost.deferFlags(true)).then(() => {
|
||||
this.send('closeModal');
|
||||
});
|
||||
},
|
||||
|
||||
deletePostAgreeFlag() {
|
||||
let flaggedPost = this.get('model');
|
||||
this.removeAfter(flaggedPost.agreeFlags('delete'), flaggedPost).then(() => {
|
||||
this.removeAfter(flaggedPost.agreeFlags('delete')).then(() => {
|
||||
this.send('closeModal');
|
||||
});
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ const FlaggedPost = Post.extend({
|
||||
disposedAt: postAction.disposed_at,
|
||||
dispositionIcon: this.dispositionIcon(postAction.disposition),
|
||||
tookAction: postAction.staff_took_action
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
@ -144,25 +144,31 @@ const FlaggedPost = Post.extend({
|
||||
});
|
||||
|
||||
FlaggedPost.reopenClass({
|
||||
|
||||
findAll(args) {
|
||||
let { offset, filter } = args;
|
||||
offset = offset || 0;
|
||||
let { filter } = args;
|
||||
|
||||
let result = [];
|
||||
result.set('loading', true);
|
||||
|
||||
return ajax('/admin/flags/' + filter + '.json?offset=' + offset).then(function (data) {
|
||||
let data = {};
|
||||
if (args.topic_id) {
|
||||
data.topic_id = args.topic_id;
|
||||
}
|
||||
if (args.offset) {
|
||||
data.offset = args.offset;
|
||||
}
|
||||
|
||||
return ajax(`/admin/flags/${filter}.json`, { data }).then(response => {
|
||||
// users
|
||||
let userLookup = {};
|
||||
data.users.forEach(user => userLookup[user.id] = AdminUser.create(user));
|
||||
response.users.forEach(user => userLookup[user.id] = AdminUser.create(user));
|
||||
|
||||
// topics
|
||||
let topicLookup = {};
|
||||
data.topics.forEach(topic => topicLookup[topic.id] = Topic.create(topic));
|
||||
response.topics.forEach(topic => topicLookup[topic.id] = Topic.create(topic));
|
||||
|
||||
// posts
|
||||
data.posts.forEach(post => {
|
||||
response.posts.forEach(post => {
|
||||
let f = FlaggedPost.create(post);
|
||||
f.userLookup = userLookup;
|
||||
f.topicLookup = topicLookup;
|
||||
|
@ -2,6 +2,6 @@ import FlaggedPost from 'admin/models/flagged-post';
|
||||
|
||||
export default Discourse.Route.extend({
|
||||
model() {
|
||||
return FlaggedPost.findAll('active');
|
||||
return FlaggedPost.findAll({ filter: 'active' });
|
||||
}
|
||||
});
|
||||
|
@ -2,6 +2,6 @@ import FlaggedPost from 'admin/models/flagged-post';
|
||||
|
||||
export default Discourse.Route.extend({
|
||||
model() {
|
||||
return FlaggedPost.findAll('old');
|
||||
return FlaggedPost.findAll({ filter: 'old' });
|
||||
},
|
||||
});
|
||||
|
@ -8,7 +8,10 @@ export default Ember.Route.extend({
|
||||
|
||||
return Ember.RSVP.hash({
|
||||
topic,
|
||||
flaggedPosts: FlaggedPost.findAll({ filter: 'active' })
|
||||
flaggedPosts: FlaggedPost.findAll({
|
||||
filter: 'active',
|
||||
topic_id: params.id
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -0,0 +1,169 @@
|
||||
<tr class="flagged-post {{flaggedPost.extraClasses}}">
|
||||
<td class='excerpt'>
|
||||
<div class="flex-center-align">
|
||||
<div class="flagged-post-avatar">
|
||||
{{#if flaggedPost.postAuthorFlagged}}
|
||||
{{#if flaggedPost.user}}
|
||||
{{#link-to 'adminUser' flaggedPost.user}}{{avatar flaggedPost.user imageSize="large"}}{{/link-to}}
|
||||
{{#if flaggedPost.wasEdited}}
|
||||
{{d-icon "pencil" title="admin.flags.was_edited"}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{#if canAct}}
|
||||
{{#if flaggedPost.previous_flags_count}}
|
||||
<span title="{{i18n 'admin.flags.previous_flags_count' count=flaggedPost.previous_flags_count}}" class="badge-notification flagged-posts">{{flaggedPost.previous_flags_count}}</span>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="topic-excerpt">
|
||||
<h3>
|
||||
{{#if flaggedPost.topic.isPrivateMessage}}
|
||||
<span class="private-message-glyph">{{d-icon "envelope"}}</span>
|
||||
{{/if}}
|
||||
{{topic-status topic=flaggedPost.topic}}
|
||||
<a href='{{unbound flaggedPost.url}}'>{{{unbound flaggedPost.topic.fancyTitle}}}</a>
|
||||
</h3>
|
||||
{{#unless site.mobileView}}
|
||||
{{#if flaggedPost.postAuthorFlagged}}
|
||||
<p>{{{flaggedPost.excerpt}}}</p>
|
||||
{{/if}}
|
||||
{{/unless}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if site.mobileView}}
|
||||
{{#if flaggedPost.postAuthorFlagged}}
|
||||
<p>{{{flaggedPost.excerpt}}}</p>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</td>
|
||||
|
||||
<td class='flaggers'>
|
||||
<table>
|
||||
<tbody>
|
||||
{{#each flaggedPost.flaggers as |flagger|}}
|
||||
<tr>
|
||||
<td class='avatar'>
|
||||
{{#link-to 'adminUser' flagger.user}}
|
||||
{{avatar flagger.user imageSize="medium"}}
|
||||
{{/link-to}}
|
||||
</td>
|
||||
<td>
|
||||
{{#link-to 'adminUser' flagger.user}}
|
||||
{{flagger.user.username}}
|
||||
{{/link-to}}
|
||||
{{format-age flagger.flaggedAt}}
|
||||
<br>
|
||||
{{flagger.flagType}}
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
|
||||
<td class='flaggers result'>
|
||||
{{#if showResolvedBy}}
|
||||
<table>
|
||||
<tbody>
|
||||
{{#each flaggedPost.flaggers as |flagger|}}
|
||||
<tr>
|
||||
<td class='avatar'>
|
||||
{{#link-to 'adminUser' flagger.disposedBy}}
|
||||
{{avatar flagger.disposedBy imageSize="medium"}}
|
||||
{{/link-to}}
|
||||
</td>
|
||||
<td>
|
||||
{{format-age flagger.disposedAt}}
|
||||
{{{flagger.dispositionIcon}}}
|
||||
{{#if flagger.tookAction}}
|
||||
{{d-icon "gavel" title="admin.flags.took_action"}}
|
||||
{{/if}}
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
{{/if}}
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
{{#if flaggedPost.topicFlagged}}
|
||||
<tr class='message'>
|
||||
<td colspan="3">
|
||||
<div>
|
||||
{{{i18n 'admin.flags.topic_flagged'}}} <a href='{{unbound flaggedPost.url}}' class="btn">{{i18n 'admin.flags.visit_topic'}}</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{{/if}}
|
||||
|
||||
{{#each flaggedPost.conversations as |c|}}
|
||||
<tr class='message'>
|
||||
<td colspan="3">
|
||||
<div>
|
||||
{{#if c.response}}
|
||||
<p>
|
||||
{{#link-to 'adminUser' c.response.user}}{{avatar c.response.user imageSize="medium"}}{{/link-to}} {{{c.response.excerpt}}}
|
||||
</p>
|
||||
{{#if c.reply}}
|
||||
<p>
|
||||
{{#link-to 'adminUser' c.reply.user}}{{avatar c.reply.user imageSize="medium"}}{{/link-to}} {{{c.reply.excerpt}}}
|
||||
{{#if c.hasMore}}
|
||||
<a href="{{unbound c.permalink}}">{{i18n 'admin.flags.more'}}</a>
|
||||
{{/if}}
|
||||
</p>
|
||||
{{/if}}
|
||||
<a href="{{unbound c.permalink}}">
|
||||
{{d-button
|
||||
class="btn-reply"
|
||||
icon="reply"
|
||||
label="admin.flags.reply_message"}}
|
||||
</a>
|
||||
{{/if}}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
|
||||
{{#if canAct}}
|
||||
<tr>
|
||||
<td colspan="3" class="action">
|
||||
{{d-button
|
||||
title="admin.flags.agree_title"
|
||||
label="admin.flags.agree"
|
||||
icon="thumbs-o-up"
|
||||
action="showAgreeFlagModal"
|
||||
ellipsis=true}}
|
||||
|
||||
{{#if flaggedPost.postHidden}}
|
||||
{{d-button
|
||||
title="admin.flags.disagree_flag_unhide_post_title"
|
||||
action="disagree"
|
||||
icon="thumbs-o-down"
|
||||
label="admin.flags.disagree_flag_unhide_post"}}
|
||||
{{else}}
|
||||
{{d-button
|
||||
title="admin.flags.disagree_flag_title"
|
||||
action="disagree"
|
||||
icon="thumbs-o-down"
|
||||
label="admin.flags.disagree_flag"}}
|
||||
{{/if}}
|
||||
|
||||
{{d-button
|
||||
title="admin.flags.defer_flag_title"
|
||||
action="defer"
|
||||
icon="external-link"
|
||||
label="admin.flags.defer_flag"}}
|
||||
|
||||
{{d-button
|
||||
class="btn-danger"
|
||||
title="admin.flags.delete_title"
|
||||
action="showDeleteFlagModal"
|
||||
icon="trash-o"
|
||||
label="admin.flags.delete"}}
|
||||
</td>
|
||||
</tr>
|
||||
{{/if}}
|
@ -10,157 +10,17 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each flaggedPosts as |flaggedPost|}}
|
||||
<tr class="flagged-post {{flaggedPost.extraClasses}}">
|
||||
|
||||
<td class='excerpt'>
|
||||
|
||||
<div class="flex-center-align">
|
||||
<div class="flagged-post-avatar">
|
||||
{{#if flaggedPost.postAuthorFlagged}}
|
||||
{{#if flaggedPost.user}}
|
||||
{{#link-to 'adminUser' flaggedPost.user}}{{avatar flaggedPost.user imageSize="large"}}{{/link-to}}
|
||||
{{#if flaggedPost.wasEdited}}
|
||||
{{d-icon "pencil" title="admin.flags.was_edited"}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{#if canAct}}
|
||||
{{#if flaggedPost.previous_flags_count}}
|
||||
<span title="{{i18n 'admin.flags.previous_flags_count' count=flaggedPost.previous_flags_count}}" class="badge-notification flagged-posts">{{flaggedPost.previous_flags_count}}</span>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="topic-excerpt">
|
||||
<h3>
|
||||
{{#if flaggedPost.topic.isPrivateMessage}}
|
||||
<span class="private-message-glyph">{{d-icon "envelope"}}</span>
|
||||
{{/if}}
|
||||
{{topic-status topic=flaggedPost.topic}}
|
||||
<a href='{{unbound flaggedPost.url}}'>{{{unbound flaggedPost.topic.fancyTitle}}}</a>
|
||||
</h3>
|
||||
{{#unless site.mobileView}}
|
||||
{{#if flaggedPost.postAuthorFlagged}}
|
||||
<p>{{{flaggedPost.excerpt}}}</p>
|
||||
{{/if}}
|
||||
{{/unless}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if site.mobileView}}
|
||||
{{#if flaggedPost.postAuthorFlagged}}
|
||||
<p>{{{flaggedPost.excerpt}}}</p>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</td>
|
||||
|
||||
<td class='flaggers'>
|
||||
<table>
|
||||
<tbody>
|
||||
{{#each flaggedPost.flaggers as |flagger|}}
|
||||
<tr>
|
||||
<td class='avatar'>
|
||||
{{#link-to 'adminUser' flagger.user}}
|
||||
{{avatar flagger.user imageSize="medium"}}
|
||||
{{/link-to}}
|
||||
</td>
|
||||
<td>
|
||||
{{#link-to 'adminUser' flagger.user}}
|
||||
{{flagger.user.username}}
|
||||
{{/link-to}}
|
||||
{{format-age flagger.flaggedAt}}
|
||||
<br>
|
||||
{{flagger.flagType}}
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
|
||||
<td class='flaggers result'>
|
||||
{{#if showResolvedBy}}
|
||||
<table>
|
||||
<tbody>
|
||||
{{#each flaggedPost.flaggers as |flagger|}}
|
||||
<tr>
|
||||
<td class='avatar'>
|
||||
{{#link-to 'adminUser' flagger.disposedBy}}
|
||||
{{avatar flagger.disposedBy imageSize="medium"}}
|
||||
{{/link-to}}
|
||||
</td>
|
||||
<td>
|
||||
{{format-age flagger.disposedAt}}
|
||||
{{{flagger.dispositionIcon}}}
|
||||
{{#if flagger.tookAction}}
|
||||
{{d-icon "gavel" title="admin.flags.took_action"}}
|
||||
{{/if}}
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
{{/if}}
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
{{#if flaggedPost.topicFlagged}}
|
||||
<tr class='message'>
|
||||
<td colspan="3">
|
||||
<div>
|
||||
{{{i18n 'admin.flags.topic_flagged'}}} <a href='{{unbound flaggedPost.url}}' class="btn">{{i18n 'admin.flags.visit_topic'}}</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{{/if}}
|
||||
|
||||
{{#each flaggedPost.conversations as |c|}}
|
||||
<tr class='message'>
|
||||
<td colspan="3">
|
||||
<div>
|
||||
{{#if c.response}}
|
||||
<p>
|
||||
{{#link-to 'adminUser' c.response.user}}{{avatar c.response.user imageSize="medium"}}{{/link-to}} {{{c.response.excerpt}}}
|
||||
</p>
|
||||
{{#if c.reply}}
|
||||
<p>
|
||||
{{#link-to 'adminUser' c.reply.user}}{{avatar c.reply.user imageSize="medium"}}{{/link-to}} {{{c.reply.excerpt}}}
|
||||
{{#if c.hasMore}}
|
||||
<a href="{{unbound c.permalink}}">{{i18n 'admin.flags.more'}}</a>
|
||||
{{/if}}
|
||||
</p>
|
||||
{{/if}}
|
||||
<a href="{{unbound c.permalink}}">
|
||||
<button class='btn btn-reply'>{{d-icon "reply"}} {{i18n 'admin.flags.reply_message'}}</button>
|
||||
|
||||
</a>
|
||||
{{/if}}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
|
||||
{{#if canAct}}
|
||||
<tr>
|
||||
<td colspan="3" class="action">
|
||||
<button title='{{i18n 'admin.flags.agree_title'}}' class='btn' {{action "showAgreeFlagModal" flaggedPost}}>{{d-icon "thumbs-o-up"}}{{i18n 'admin.flags.agree'}}…</button>
|
||||
{{#if flaggedPost.postHidden}}
|
||||
<button title='{{i18n 'admin.flags.disagree_flag_unhide_post_title'}}' class='btn' {{action "disagree" flaggedPost}}>{{d-icon "thumbs-o-down"}}{{i18n 'admin.flags.disagree_flag_unhide_post'}}</button>
|
||||
{{else}}
|
||||
<button title='{{i18n 'admin.flags.disagree_flag_title'}}' class='btn' {{action "disagree" flaggedPost}}>{{d-icon "thumbs-o-down"}}{{i18n 'admin.flags.disagree_flag'}}</button>
|
||||
{{/if}}
|
||||
<button title='{{i18n 'admin.flags.defer_flag_title'}}' class='btn' {{action "defer" flaggedPost}}>{{d-icon "external-link"}}{{i18n 'admin.flags.defer_flag'}}</button>
|
||||
<button title='{{i18n 'admin.flags.delete_title'}}' class='btn btn-danger' {{action "showDeleteFlagModal" flaggedPost}}>{{d-icon "trash-o"}}{{i18n 'admin.flags.delete'}}…</button>
|
||||
</td>
|
||||
</tr>
|
||||
{{/if}}
|
||||
|
||||
{{flagged-post
|
||||
flaggedPost=flaggedPost
|
||||
canAct=canAct
|
||||
showResolvedBy=showResolvedBy
|
||||
removePost=(action "removePost" flaggedPost)
|
||||
}}
|
||||
{{/each}}
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
{{/load-more}}
|
||||
|
||||
{{else}}
|
||||
<p>{{i18n 'admin.flags.no_results'}}</p>
|
||||
{{/if}}
|
||||
|
@ -1,39 +1,20 @@
|
||||
import FlaggedPost from 'admin/models/flagged-post';
|
||||
import showModal from 'discourse/lib/show-modal';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
canAct: Ember.computed.equal('filter', 'active'),
|
||||
showResolvedBy: Ember.computed.equal('filter', 'old'),
|
||||
|
||||
removeAfter(promise, flaggedPost) {
|
||||
return promise.then(() => {
|
||||
this.get('flaggedPosts').removeObject(flaggedPost);
|
||||
}).catch(() => {
|
||||
bootbox.alert(I18n.t("admin.flags.error"));
|
||||
});
|
||||
},
|
||||
|
||||
_spawnModal(name, flaggedPost, modalClass) {
|
||||
let controller = showModal(name, {
|
||||
model: flaggedPost,
|
||||
admin: true,
|
||||
modalClass
|
||||
});
|
||||
controller.removeAfter = (p, f) => this.removeAfter(p, f);
|
||||
},
|
||||
|
||||
actions: {
|
||||
disagree(flaggedPost) {
|
||||
this.removeAfter(flaggedPost.disagreeFlags(), flaggedPost);
|
||||
},
|
||||
|
||||
defer(flaggedPost) {
|
||||
this.removeAfter(flaggedPost.deferFlags(), flaggedPost);
|
||||
removePost(flaggedPost) {
|
||||
this.get('flaggedPosts').removeObject(flaggedPost);
|
||||
},
|
||||
|
||||
loadMore() {
|
||||
const flaggedPosts = this.get('flaggedPosts');
|
||||
return FlaggedPost.findAll(this.get('query'), flaggedPosts.length+1).then(data => {
|
||||
return FlaggedPost.findAll({
|
||||
filter: this.get('query'),
|
||||
offset: flaggedPosts.length+1
|
||||
}).then(data => {
|
||||
if (data.length===0) {
|
||||
flaggedPosts.set("allLoaded",true);
|
||||
}
|
||||
@ -41,12 +22,5 @@ export default Ember.Component.extend({
|
||||
});
|
||||
},
|
||||
|
||||
showAgreeFlagModal(flaggedPost) {
|
||||
this._spawnModal('admin-agree-flag', flaggedPost, 'agree-flag-modal');
|
||||
},
|
||||
|
||||
showDeleteFlagModal(flaggedPost) {
|
||||
this._spawnModal('admin-delete-flag', flaggedPost, 'delete-flag-modal');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -3,7 +3,7 @@
|
||||
{{/if}}
|
||||
|
||||
{{#if translatedLabel}}
|
||||
<span class='d-button-label'>{{{translatedLabel}}}</span>
|
||||
<span class='d-button-label'>{{{translatedLabel}}}{{#if ellipsis}}…{{/if}}</span>
|
||||
{{/if}}
|
||||
|
||||
{{yield}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user