Moderators can edit posts that are queued before they approve/reject

This commit is contained in:
Robin Ward 2015-04-15 17:20:34 -04:00
parent 2303b1dcd0
commit 08b4b7b7ff
8 changed files with 134 additions and 47 deletions
app
assets
javascripts/discourse
stylesheets/desktop
controllers
config/locales
test/javascripts

@ -0,0 +1,39 @@
import BufferedContent from 'discourse/mixins/buffered-content';
import { popupAjaxError } from 'discourse/lib/ajax-error';
function updateState(state) {
return function() {
const post = this.get('post');
post.update({ state }).then(() => {
this.get('controllers.queued-posts.model').removeObject(post);
}).catch(popupAjaxError);
};
}
export default Ember.Controller.extend(BufferedContent, {
needs: ['queued-posts'],
post: Ember.computed.alias('model'),
editing: false,
actions: {
approve: updateState('approved'),
reject: updateState('rejected'),
edit() {
this.set('editing', true);
},
confirmEdit() {
this.get('post').update({ raw: this.get('buffered.raw') }).then(() => {
this.commitBuffer();
this.set('editing', false);
});
},
cancelEdit() {
this.rollbackBuffer();
this.set('editing', false);
}
}
});

@ -1,16 +0,0 @@
import { popupAjaxError } from 'discourse/lib/ajax-error';
function updateState(state) {
return function(post) {
post.update({ state }).then(() => {
this.get('model').removeObject(post);
}).catch(popupAjaxError);
};
}
export default Ember.Controller.extend({
actions: {
approve: updateState('approved'),
reject: updateState('rejected')
}
});

@ -1,41 +1,63 @@
<div class='container'>
<div class='queued-posts'>
{{#each post in model}}
{{#each ctrl in model itemController='queued-post'}}
<div class='queued-post'>
<div class='poster'>
{{avatar post.user imageSize="large"}}
{{avatar ctrl.post.user imageSize="large"}}
</div>
<div class='cooked'>
<div class='names'>
<span class='username'>{{post.user.username}}</span>
<span class='username'>{{ctrl.post.user.username}}</span>
</div>
<div class='clearfix'></div>
<span class='post-title'>
{{i18n "queue.topic"}}
{{#if post.topic}}
{{topic-link post.topic}}
{{#if ctrl.post.topic}}
{{topic-link ctrl.post.topic}}
{{else}}
{{post.post_options.title}}
{{ctrl.post.post_options.title}}
{{/if}}
{{category-badge post.category}}
{{category-badge ctrl.post.category}}
</span>
{{{cook-text post.raw}}}
<div class='body'>
{{#if ctrl.editing}}
{{pagedown-editor value=ctrl.buffered.raw}}
{{else}}
{{{cook-text ctrl.post.raw}}}
{{/if}}
</div>
<div class='queue-controls'>
{{d-button action="approve"
actionParam=post
disabled=post.isSaving
label="queue.approve"
icon="check"
class="btn-primary approve"}}
{{d-button action="reject"
actionParam=post
disabled=post.isSaving
label="queue.reject"
icon="times"
class="btn-warning reject"}}
{{#if ctrl.editing}}
{{d-button action="confirmEdit"
label="queue.confirm"
disabled=ctrl.post.isSaving
class="btn-primary confirm"}}
{{d-button action="cancelEdit"
label="queue.cancel"
icon="times"
disabled=ctrl.post.isSaving
class="btn-danger cancel"}}
{{else}}
{{d-button action="approve"
disabled=ctrl.post.isSaving
label="queue.approve"
icon="check"
class="btn-primary approve"}}
{{d-button action="reject"
disabled=ctrl.post.isSaving
label="queue.reject"
icon="times"
class="btn-danger reject"}}
{{d-button action="edit"
disabled=ctrl.post.isSaving
label="queue.edit"
icon="pencil"
class="edit"}}
{{/if}}
</div>
</div>
<div class='clearfix'></div>

@ -9,8 +9,19 @@
.cooked {
width: $topic-body-width;
float: left;
#wmd-input {
width: 98%;
height: 15em;
}
}
.queue-controls {
button {
float: left;
margin-right: 0.5em;
}
}
.post-title {
color: darken(scale-color-diff(), 50%);
font-weight: bold;

@ -15,6 +15,10 @@ class QueuedPostsController < ApplicationController
def update
qp = QueuedPost.where(id: params[:id]).first
if params[:queued_post][:raw].present?
qp.update_column(:raw, params[:queued_post][:raw])
end
state = params[:queued_post][:state]
if state == 'approved'
qp.approve!(current_user)

@ -227,10 +227,13 @@ en:
queue:
topic: "Topic:"
approve: 'Approve Post'
reject: 'Reject Post'
approve: 'Approve'
reject: 'Reject'
title: "Needs Approval"
none: "There are no posts to review."
edit: "Edit"
cancel: "Cancel"
confirm: "Save Changes"
approval:
title: "Post Needs Approval"

@ -5,10 +5,6 @@ acceptance("Queued Posts", { loggedIn: true });
test("approve a post", () => {
visit("/queued-posts");
andThen(() => {
ok(exists('.queued-post'), 'it has posts listed');
});
click('.queued-post:eq(0) button.approve');
andThen(() => {
ok(!exists('.queued-post'), 'it removes the post');
@ -18,12 +14,40 @@ test("approve a post", () => {
test("reject a post", () => {
visit("/queued-posts");
andThen(() => {
ok(exists('.queued-post'), 'it has posts listed');
});
click('.queued-post:eq(0) button.reject');
andThen(() => {
ok(!exists('.queued-post'), 'it removes the post');
});
});
test("edit a post - cancel", () => {
visit("/queued-posts");
click('.queued-post:eq(0) button.edit');
andThen(() => {
equal(find('.queued-post:eq(0) textarea').val(), 'queued post text', 'it shows an editor');
});
fillIn('.queued-post:eq(0) textarea', 'new post text');
click('.queued-post:eq(0) button.cancel');
andThen(() => {
ok(!exists('textarea'), 'it disables editing');
equal(find('.queued-post:eq(0) .body p').text(), 'queued post text', 'it reverts the new text');
});
});
test("edit a post - confirm", () => {
visit("/queued-posts");
click('.queued-post:eq(0) button.edit');
andThen(() => {
equal(find('.queued-post:eq(0) textarea').val(), 'queued post text', 'it shows an editor');
});
fillIn('.queued-post:eq(0) textarea', 'new post text');
click('.queued-post:eq(0) button.confirm');
andThen(() => {
ok(!exists('textarea'), 'it disables editing');
equal(find('.queued-post:eq(0) .body p').text(), 'new post text', 'it has the new text');
});
});

@ -104,7 +104,7 @@ export default function() {
this.get('/queued_posts', function() {
return response({
queued_posts: [{id: 1}]
queued_posts: [{id: 1, raw: 'queued post text'}]
});
});