add make/remove banner topic actions

This commit is contained in:
Régis Hanol 2014-06-16 18:28:07 +02:00
parent 3153a84da2
commit 5238a95efb
8 changed files with 130 additions and 44 deletions

View file

@ -302,6 +302,14 @@ Discourse.TopicController = Discourse.ObjectController.extend(Discourse.Selected
this.get('content').toggleStatus('closed');
},
makeBanner: function() {
this.get('content').makeBanner();
},
removeBanner: function() {
this.get('content').removeBanner();
},
togglePinned: function() {
// Note that this is different than clearPin
this.get('content').setStatus('pinned', this.get('pinned_at') ? false : true);
@ -316,10 +324,6 @@ Discourse.TopicController = Discourse.ObjectController.extend(Discourse.Selected
this.get('content').toggleStatus('archived');
},
convertToRegular: function() {
this.get('content').convertArchetype('regular');
},
// Toggle the star on the topic
toggleStar: function() {
this.get('content').toggleStar();

View file

@ -19,22 +19,6 @@ Discourse.Topic = Discourse.Model.extend({
invisible: Em.computed.not('visible'),
deleted: Em.computed.notEmpty('deleted_at'),
canConvertToRegular: function() {
var a = this.get('archetype');
return a !== 'regular' && a !== 'private_message';
}.property('archetype'),
convertArchetype: function() {
var a = this.get('archetype');
if (a !== 'regular' && a !== 'private_message') {
this.set('archetype', 'regular');
return Discourse.ajax(this.get('url'), {
type: 'PUT',
data: {archetype: 'regular'}
});
}
},
searchContext: function() {
return ({ type: 'topic', id: this.get('id') });
}.property('id'),
@ -131,6 +115,7 @@ Discourse.Topic = Discourse.Model.extend({
}.property('archetype'),
isPrivateMessage: Em.computed.equal('archetype', 'private_message'),
isBanner: Em.computed.equal('archetype', 'banner'),
toggleStatus: function(property) {
this.toggleProperty(property);
@ -155,6 +140,18 @@ Discourse.Topic = Discourse.Model.extend({
});
},
makeBanner: function() {
var self = this;
return Discourse.ajax('/t/' + this.get('id') + '/make-banner', { type: 'PUT' })
.then(function () { self.set('archetype', 'banner'); })
},
removeBanner: function() {
var self = this;
return Discourse.ajax('/t/' + this.get('id') + '/remove-banner', { type: 'PUT' })
.then(function () { self.set('archetype', 'regular'); })
},
starTooltipKey: function() {
return this.get('starred') ? 'starred.help.unstar' : 'starred.help.star';
}.property('starred'),

View file

@ -28,14 +28,24 @@
{{/if}}
</li>
<li>
{{#if pinned_at}}
<button {{action togglePinned}} class='btn btn-admin'><i class='fa fa-thumb-tack'></i> {{i18n topic.actions.unpin}}</button>
{{else}}
<button {{action togglePinned}} class='btn btn-admin'><i class='fa fa-thumb-tack'></i> {{i18n topic.actions.pin}}</button>
<button {{action togglePinnedGlobally}} class='btn btn-admin'><i class='fa fa-thumb-tack'></i> {{i18n topic.actions.pin_globally}}</button>
{{/if}}
</li>
{{#unless isPrivateMessage}}
<li>
{{#if isBanner}}
<button {{action removeBanner}} class='btn btn-admin'><i class='fa fa-bullhorn'></i> {{i18n topic.actions.remove_banner}}</button>
{{else}}
<button {{action makeBanner}} class='btn btn-admin'><i class='fa fa-bullhorn'></i> {{i18n topic.actions.make_banner}}</button>
{{/if}}
</li>
<li>
{{#if pinned_at}}
<button {{action togglePinned}} class='btn btn-admin'><i class='fa fa-thumb-tack'></i> {{i18n topic.actions.unpin}}</button>
{{else}}
<button {{action togglePinned}} class='btn btn-admin'><i class='fa fa-thumb-tack'></i> {{i18n topic.actions.pin}}</button>
<button {{action togglePinnedGlobally}} class='btn btn-admin'><i class='fa fa-thumb-tack'></i> {{i18n topic.actions.pin_globally}}</button>
{{/if}}
</li>
{{/unless}}
<li>
{{#if archived}}
@ -53,16 +63,10 @@
{{/if}}
</li>
{{#if canConvertToRegular}}
<li>
<button {{action convertToRegular}} class='btn btn-admin'><i class='fa fa-minus'></i> {{i18n topic.actions.convert_to_topic}}</button>
</li>
{{/if}}
{{#if currentUser.staff}}
<li>
<button class='btn btn-admin' {{action resetRead}}><i class='fa fa-times'></i> {{i18n topic.actions.reset_read}}</button>
</li>
<li>
<button class='btn btn-admin' {{action resetRead}}><i class='fa fa-times'></i> {{i18n topic.actions.reset_read}}</button>
</li>
{{/if}}
</ul>
</div>

View file

@ -75,6 +75,7 @@ class TopicsController < ApplicationController
params.require(:best)
params.require(:topic_id)
params.permit(:min_trust_level, :min_score, :min_replies, :bypass_trust_level_score, :only_moderator_liked)
opts = { best: params[:best].to_i,
min_trust_level: params[:min_trust_level] ? 1 : params[:min_trust_level].to_i,
min_score: params[:min_score].to_i,
@ -105,13 +106,9 @@ class TopicsController < ApplicationController
def update
topic = Topic.find_by(id: params[:topic_id])
title, archetype = params[:title], params[:archetype]
guardian.ensure_can_edit!(topic)
topic.title = params[:title] if title.present?
# TODO: we may need smarter rules about converting archetypes
topic.archetype = "regular" if current_user.admin? && archetype == 'regular'
topic.title = params[:title] if params[:title].present?
topic.acting_user = current_user
success = false
@ -176,6 +173,32 @@ class TopicsController < ApplicationController
end
end
def make_banner
topic = Topic.find_by(id: params[:topic_id].to_i)
guardian.ensure_can_moderate!(topic)
# TODO: only one banner at the same time
topic.archetype = Archetype.banner
topic.add_moderator_post(current_user, I18n.t("archetypes.banner.message.make"))
topic.save
render nothing: true
end
def remove_banner
topic = Topic.find_by(id: params[:topic_id].to_i)
guardian.ensure_can_moderate!(topic)
topic.archetype = Archetype.default
topic.add_moderator_post(current_user, I18n.t("archetypes.banner.message.remove"))
topic.save
render nothing: true
end
def destroy
topic = Topic.find_by(id: params[:id])
guardian.ensure_can_delete!(topic)

View file

@ -837,6 +837,8 @@ en:
open: "Open Topic"
close: "Close Topic"
auto_close: "Auto Close"
make_banner: "Banner Topic"
remove_banner: "Remove Banner Topic"
unpin: "Un-Pin Topic"
pin: "Pin Topic"
pin_globally: "Pin Topic Globally"
@ -846,7 +848,6 @@ en:
visible: "Make Visible"
reset_read: "Reset Read Data"
multi_select: "Select Posts"
convert_to_topic: "Convert to Regular Topic"
reply:
title: 'Reply'

View file

@ -423,6 +423,10 @@ en:
archetypes:
regular:
title: "Regular Topic"
banner:
message:
make: "This topic is now a banner topic. It will appear at the top of every pages until it is dismissed by the users."
remove: "This topic is not a banner topic anymore. It will no longer appear at the top of every pages."
unsubscribed:
title: 'Unsubscribed'
@ -989,7 +993,6 @@ en:
autoclosed_disabled: "This topic is now opened. New replies are allowed."
pinned_enabled: "This topic is now pinned. It will appear at the top of its category until it is unpinned by staff for everyone, or by individual users for themselves."
pinned_disabled: "This topic is now unpinned. It will no longer appear at the top of its category."
pinned_globally_enabled: "This topic is now pinned globally. It will appear at the top of its category and all topic lists until it is unpinned by staff for everyone, or by individual users for themselves."
pinned_globally_disabled: "This topic is now unpinned. It will no longer appear at the top of its category."
visible_enabled: "This topic is now visible. It will be displayed in topic lists."

View file

@ -340,6 +340,8 @@ Discourse::Application.routes.draw do
put "t/:topic_id/mute" => "topics#mute", constraints: {topic_id: /\d+/}
put "t/:topic_id/unmute" => "topics#unmute", constraints: {topic_id: /\d+/}
put "t/:topic_id/autoclose" => "topics#autoclose", constraints: {topic_id: /\d+/}
put "t/:topic_id/make-banner" => "topics#make_banner", constraints: {topic_id: /\d+/}
put "t/:topic_id/remove-banner" => "topics#remove_banner", constraints: {topic_id: /\d+/}
put "t/:topic_id/remove-allowed-user" => "topics#remove_allowed_user", constraints: {topic_id: /\d+/}
put "t/:topic_id/recover" => "topics#recover", constraints: {topic_id: /\d+/}
get "t/:topic_id/:post_number" => "topics#show", constraints: {topic_id: /\d+/, post_number: /\d+/}

View file

@ -847,6 +847,58 @@ describe TopicsController do
end
describe 'make_banner' do
it 'needs you to be a staff member' do
log_in
xhr :put, :make_banner, topic_id: 99
response.should be_forbidden
end
describe 'when logged in' do
before do
@admin = log_in(:admin)
@topic = Fabricate(:topic, user: @admin)
end
it "changes the topic archetype to 'banner'" do
Topic.any_instance.expects(:archetype=).with(Archetype.banner)
Topic.any_instance.expects(:add_moderator_post)
xhr :put, :make_banner, topic_id: @topic.id
response.should be_success
end
end
end
describe 'remove_banner' do
it 'needs you to be a staff member' do
log_in
xhr :put, :remove_banner, topic_id: 99
response.should be_forbidden
end
describe 'when logged in' do
before do
@admin = log_in(:admin)
@topic = Fabricate(:topic, user: @admin)
end
it "resets the topic archetype" do
Topic.any_instance.expects(:archetype=).with(Archetype.default)
Topic.any_instance.expects(:add_moderator_post)
xhr :put, :remove_banner, topic_id: @topic.id
response.should be_success
end
end
end
describe "bulk" do
it 'needs you to be logged in' do
lambda { xhr :put, :bulk }.should raise_error(Discourse::NotLoggedIn)