mirror of
https://github.com/discourse/discourse.git
synced 2025-01-19 05:43:16 +08:00
UX: add topic admin button to the bottom of the topic
This commit is contained in:
parent
b1271ed44b
commit
67c10a7eab
|
@ -0,0 +1,24 @@
|
|||
export default Em.Component.extend({
|
||||
tagName: "button",
|
||||
classNames: ["btn", "no-text", "show-topic-admin"],
|
||||
attributeBindings: ["title"],
|
||||
title: I18n.t("topic_admin_menu"),
|
||||
|
||||
render: function(buffer) {
|
||||
buffer.push("<i class='fa fa-wrench'></i>");
|
||||
},
|
||||
|
||||
click: function() {
|
||||
var $target = this.$(),
|
||||
position = $target.position(),
|
||||
width = $target.innerWidth();
|
||||
var location = {
|
||||
position: "fixed",
|
||||
left: position.left + width,
|
||||
top: position.top,
|
||||
};
|
||||
this.appEvents.trigger("topic-admin-menu:open", location);
|
||||
this.sendAction("show");
|
||||
return false;
|
||||
}
|
||||
});
|
|
@ -10,17 +10,11 @@ import ObjectController from 'discourse/controllers/object';
|
|||
**/
|
||||
export default ObjectController.extend({
|
||||
menuVisible: false,
|
||||
needs: ['modal'],
|
||||
showRecover: Em.computed.and('deleted', 'details.can_recover'),
|
||||
|
||||
actions: {
|
||||
show: function() {
|
||||
this.set('menuVisible', true);
|
||||
},
|
||||
show: function() { this.set('menuVisible', true); },
|
||||
hide: function() { this.set('menuVisible', false); }
|
||||
}
|
||||
|
||||
hide: function() {
|
||||
this.set('menuVisible', false);
|
||||
}
|
||||
},
|
||||
|
||||
showRecover: Em.computed.and('deleted', 'details.can_recover')
|
||||
});
|
||||
|
|
|
@ -13,6 +13,10 @@ Discourse.TopicRoute = Discourse.Route.extend({
|
|||
},
|
||||
|
||||
actions: {
|
||||
showTopicAdminMenu: function() {
|
||||
this.controllerFor("topic-admin-menu").send("show");
|
||||
},
|
||||
|
||||
// Modals that can pop up within a topic
|
||||
expandPostUser: function(post) {
|
||||
this.controllerFor('user-expansion').show(post.get('username'), post.get('uploaded_avatar_id'));
|
||||
|
|
|
@ -1,74 +1,68 @@
|
|||
{{#if menuVisible}}
|
||||
<div class="topic-admin-menu">
|
||||
<h3>{{i18n admin_title}}</h3>
|
||||
<h3>{{i18n admin_title}}</h3>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<button {{action "toggleMultiSelect"}} class='btn btn-admin'><i class='fa fa-tasks'></i> {{i18n topic.actions.multi_select}}</button>
|
||||
</li>
|
||||
<ul>
|
||||
<li>
|
||||
<button {{action "toggleMultiSelect"}} class='btn btn-admin'>{{fa-icon tasks}} {{i18n topic.actions.multi_select}}</button>
|
||||
</li>
|
||||
|
||||
{{#if details.can_delete}}
|
||||
<li>
|
||||
<button {{action "deleteTopic"}} class='btn btn-admin btn-danger'><i class='fa fa-trash-o'></i> {{i18n topic.actions.delete}}</button>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if details.can_delete}}
|
||||
<li>
|
||||
<button {{action "deleteTopic"}} class='btn btn-admin btn-danger'>{{fa-icon trash-o}} {{i18n topic.actions.delete}}</button>
|
||||
</li>
|
||||
{{/if}}
|
||||
|
||||
{{#if showRecover}}
|
||||
<li>
|
||||
<button {{action "recoverTopic"}} class='btn btn-admin'><i class='fa fa-undo'></i> {{i18n topic.actions.recover}}</button>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if showRecover}}
|
||||
<li>
|
||||
<button {{action "recoverTopic"}} class='btn btn-admin'>{{fa-icon undo}} {{i18n topic.actions.recover}}</button>
|
||||
</li>
|
||||
{{/if}}
|
||||
|
||||
<li>
|
||||
{{#if closed}}
|
||||
<button {{action "toggleClosed"}} class='btn btn-admin'><i class='fa fa-unlock'></i> {{i18n topic.actions.open}}</button>
|
||||
{{else}}
|
||||
<button {{action "toggleClosed"}} class='btn btn-admin'><i class='fa fa-lock'></i> {{i18n topic.actions.close}}</button>
|
||||
<button {{action "showAutoClose"}} class='btn btn-admin'><i class='fa fa-clock-o'></i> {{i18n topic.actions.auto_close}}</button>
|
||||
{{/if}}
|
||||
</li>
|
||||
<li>
|
||||
{{#if closed}}
|
||||
<button {{action "toggleClosed"}} class='btn btn-admin'>{{fa-icon unlock}} {{i18n topic.actions.open}}</button>
|
||||
{{else}}
|
||||
<button {{action "toggleClosed"}} class='btn btn-admin'>{{fa-icon lock}} {{i18n topic.actions.close}}</button>
|
||||
<button {{action "showAutoClose"}} class='btn btn-admin'>{{fa-icon clock-o}} {{i18n topic.actions.auto_close}}</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}}
|
||||
{{#if visible}}
|
||||
<button {{action "makeBanner"}} class='btn btn-admin'><i class='fa fa-bullhorn'></i> {{i18n topic.actions.make_banner}}</button>
|
||||
{{/if}}
|
||||
{{/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}}
|
||||
{{#if visible}}
|
||||
<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}}
|
||||
{{/if}}
|
||||
</li>
|
||||
{{/unless}}
|
||||
|
||||
<li>
|
||||
{{#if archived}}
|
||||
<button {{action "toggleArchived"}} class='btn btn-admin'><i class='fa fa-folder'></i> {{i18n topic.actions.unarchive}}</button>
|
||||
{{else}}
|
||||
<button {{action "toggleArchived"}} class='btn btn-admin'><i class='fa fa-folder'></i> {{i18n topic.actions.archive}}</button>
|
||||
{{/if}}
|
||||
</li>
|
||||
|
||||
<li>
|
||||
{{#unless isPrivateMessage}}
|
||||
<li>
|
||||
{{#if isBanner}}
|
||||
<button {{action "removeBanner"}} class='btn btn-admin'>{{fa-icon bullhorn}} {{i18n topic.actions.remove_banner}}</button>
|
||||
{{else}}
|
||||
{{#if visible}}
|
||||
<button {{action "toggleVisibility"}} class='btn btn-admin'><i class='fa fa-eye-slash'></i> {{i18n topic.actions.invisible}}</button>
|
||||
{{else}}
|
||||
<button {{action "toggleVisibility"}} class='btn btn-admin'><i class='fa fa-eye'></i> {{i18n topic.actions.visible}}</button>
|
||||
<button {{action "makeBanner"}} class='btn btn-admin'>{{fa-icon bullhorn}} {{i18n topic.actions.make_banner}}</button>
|
||||
{{/if}}
|
||||
</li>
|
||||
{{/if}}
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
{{else}}
|
||||
<button class='btn no-text' id='show-topic-admin' {{action "show"}}><i class='fa fa-wrench'></i></button>
|
||||
{{/if}}
|
||||
<li>
|
||||
{{#if pinned_at}}
|
||||
<button {{action "togglePinned"}} class='btn btn-admin'>{{fa-icon thumb-tack}} {{i18n topic.actions.unpin}}</button>
|
||||
{{else}}
|
||||
{{#if visible}}
|
||||
<button {{action "togglePinned"}} class='btn btn-admin'>{{fa-icon thumb-tack}} {{i18n topic.actions.pin}}</button>
|
||||
<button {{action "togglePinnedGlobally"}} class='btn btn-admin'>{{fa-icon thumb-tack}} {{i18n topic.actions.pin_globally}}</button>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</li>
|
||||
{{/unless}}
|
||||
|
||||
<li>
|
||||
{{#if archived}}
|
||||
<button {{action "toggleArchived"}} class='btn btn-admin'>{{fa-icon folder}} {{i18n topic.actions.unarchive}}</button>
|
||||
{{else}}
|
||||
<button {{action "toggleArchived"}} class='btn btn-admin'>{{fa-icon folder}} {{i18n topic.actions.archive}}</button>
|
||||
{{/if}}
|
||||
</li>
|
||||
|
||||
<li>
|
||||
{{#if visible}}
|
||||
<button {{action "toggleVisibility"}} class='btn btn-admin'>{{fa-icon eye-slash}} {{i18n topic.actions.invisible}}</button>
|
||||
{{else}}
|
||||
<button {{action "toggleVisibility"}} class='btn btn-admin'>{{fa-icon eye}} {{i18n topic.actions.visible}}</button>
|
||||
{{/if}}
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
|
|
@ -25,12 +25,12 @@
|
|||
{{/if}}
|
||||
{{text-field id='edit-title' value=newTitle maxLength=maxTitleLength}}
|
||||
|
||||
<button class='btn btn-primary btn-small no-text' {{action "finishedEditingTopic"}}><i class='fa fa-check'></i></button>
|
||||
<button class='btn btn-small no-text' {{action "cancelEditingTopic"}}><i class='fa fa-times'></i></button>
|
||||
<button class='btn btn-primary btn-small no-text' {{action "finishedEditingTopic"}}>{{fa-icon check}}</button>
|
||||
<button class='btn btn-small no-text' {{action "cancelEditingTopic"}}>{{fa-icon times}}</button>
|
||||
{{else}}
|
||||
<h1>
|
||||
{{#unless is_warning}}
|
||||
<span class="private-message-glyph"><i class='fa fa-envelope'></i></span>
|
||||
<span class="private-message-glyph">{{fa-icon envelope}}</span>
|
||||
{{/unless}}
|
||||
|
||||
{{#if details.loaded}}
|
||||
|
@ -46,7 +46,7 @@
|
|||
|
||||
|
||||
{{#if details.can_edit}}
|
||||
<a href='#' {{action "editTopic"}} class='edit-topic' title='{{i18n edit}}'><i class="fa fa-pencil"></i></a>
|
||||
<a href='#' {{action "editTopic"}} class='edit-topic' title='{{i18n edit}}'>{{fa-icon pencil}}</a>
|
||||
{{/if}}
|
||||
</h1>
|
||||
|
||||
|
@ -118,7 +118,6 @@
|
|||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
|
||||
</section>
|
||||
</div>
|
||||
|
||||
|
@ -134,7 +133,7 @@
|
|||
{{message}}
|
||||
{{#if noRetry}}
|
||||
{{#unless currentUser}}
|
||||
<button {{action "showLogin"}} class='btn btn-primary topic-retry'><i class="fa fa-user"></i>{{i18n log_in}}</button>
|
||||
<button {{action "showLogin"}} class='btn btn-primary topic-retry'>{{fa-icon user}} {{i18n log_in}}</button>
|
||||
{{/unless}}
|
||||
{{else}}
|
||||
<button class="btn btn-primary topic-retry" {{action "retryLoading"}}>{{i18n errors.buttons.again}}</button>
|
||||
|
@ -159,5 +158,6 @@
|
|||
{{/if}}
|
||||
|
||||
{{#if currentUser.canManageTopic}}
|
||||
{{show-topic-admin show="showTopicAdminMenu"}}
|
||||
{{render "topic-admin-menu"}}
|
||||
{{/if}}
|
||||
|
|
|
@ -5,9 +5,10 @@ export default Discourse.View.extend({
|
|||
|
||||
title: function() {
|
||||
return I18n.t(this.get('helpKey') || this.get('textKey'));
|
||||
}.property('helpKey'),
|
||||
}.property('helpKey', 'textKey'),
|
||||
|
||||
text: function() {
|
||||
if (Em.empty(this.get('textKey'))) { return ""; }
|
||||
return I18n.t(this.get('textKey'));
|
||||
}.property('textKey'),
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import ButtonView from "discourse/views/button";
|
||||
|
||||
export default ButtonView.extend({
|
||||
classNameBindings: [":no-text"],
|
||||
helpKey: "topic_admin_menu",
|
||||
|
||||
renderIcon: function(buffer) {
|
||||
buffer.push("<i class='fa fa-wrench'></i>");
|
||||
},
|
||||
|
||||
click: function() {
|
||||
var offset = this.$().offset();
|
||||
var location = {
|
||||
position: "absolute",
|
||||
left: offset.left,
|
||||
top: offset.top,
|
||||
};
|
||||
this.get("controller").appEvents.trigger("topic-admin-menu:open", location);
|
||||
return this.get("controller").send("showTopicAdminMenu");
|
||||
}
|
||||
});
|
|
@ -7,21 +7,47 @@
|
|||
@module Discourse
|
||||
**/
|
||||
export default Discourse.View.extend({
|
||||
classNameBindings: ["controller.menuVisible::hidden", ":topic-admin-menu"],
|
||||
|
||||
willDestroyElement: function() {
|
||||
$('html').off('mouseup.discourse-topic-admin-menu');
|
||||
},
|
||||
|
||||
didInsertElement: function() {
|
||||
_setup: function() {
|
||||
var self = this;
|
||||
$('html').on('mouseup.discourse-topic-admin-menu', function(e) {
|
||||
|
||||
this.appEvents.on("topic-admin-menu:open", this, "_changeLocation");
|
||||
|
||||
$("html").on("mouseup.discourse-topic-admin-menu", function(e) {
|
||||
var $target = $(e.target);
|
||||
if ($target.is('button') || self.$().has($target).length === 0) {
|
||||
self.get('controller').send('hide');
|
||||
if ($target.is("button") || self.$().has($target).length === 0) {
|
||||
self.get("controller").send("hide");
|
||||
}
|
||||
});
|
||||
}
|
||||
}.on("didInsertElement"),
|
||||
|
||||
_changeLocation: function(location) {
|
||||
console.log("_changeLocation", location);
|
||||
var $this = this.$();
|
||||
switch (location.position) {
|
||||
case "absolute": {
|
||||
$this.css({
|
||||
position: "absolute",
|
||||
top: location.top - $this.innerHeight() + 5,
|
||||
left: location.left,
|
||||
})
|
||||
break;
|
||||
}
|
||||
case "fixed": {
|
||||
$this.css({
|
||||
position: "fixed",
|
||||
top: location.top,
|
||||
left: location.left - $this.innerWidth(),
|
||||
})
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_cleanup: function() {
|
||||
$("html").off("mouseup.discourse-topic-admin-menu");
|
||||
this.appEvents.off("topic-admin-menu:open");
|
||||
}.on("willDestroyElement"),
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import TopicAdminMenuButton from 'discourse/views/topic-admin-menu-button';
|
||||
import LoginReplyButton from 'discourse/views/login-reply-button';
|
||||
import FlagTopicButton from 'discourse/views/flag-topic-button';
|
||||
import StarButton from 'discourse/views/star-button';
|
||||
|
@ -21,6 +22,9 @@ export default DiscourseContainerView.extend({
|
|||
createButtons: function() {
|
||||
var topic = this.get('topic');
|
||||
if (Discourse.User.current()) {
|
||||
if (Discourse.User.currentProp("staff")) {
|
||||
this.attachViewClass(TopicAdminMenuButton);
|
||||
}
|
||||
if (!topic.get('isPrivateMessage')) {
|
||||
// We hide some controls from private messages
|
||||
if (this.get('topic.details.can_invite_to')) {
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// Styles for the topic admin menu
|
||||
|
||||
#show-topic-admin {
|
||||
.show-topic-admin {
|
||||
position: fixed;
|
||||
top: 70px;
|
||||
right: 10px;
|
||||
z-index: 1000;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.topic-admin-menu {
|
||||
|
@ -12,9 +13,6 @@
|
|||
width: 205px;
|
||||
padding: 10px;
|
||||
border: 1px solid scale-color-diff();
|
||||
position: fixed;
|
||||
top: 70px;
|
||||
right: 10px;
|
||||
z-index: 1001;
|
||||
|
||||
ul {
|
||||
|
|
|
@ -473,6 +473,7 @@ a.star {
|
|||
color: $primary;
|
||||
}
|
||||
.btn {
|
||||
outline: 0;
|
||||
margin-bottom: 5px;
|
||||
margin-right: 10px;
|
||||
.fa-star {margin-right: 5px;}
|
||||
|
|
|
@ -101,6 +101,8 @@ en:
|
|||
google+: 'share this link on Google+'
|
||||
email: 'send this link in an email'
|
||||
|
||||
topic_admin_menu: "topic admin actions"
|
||||
|
||||
edit: 'edit the title and category of this topic'
|
||||
not_implemented: "That feature hasn't been implemented yet, sorry!"
|
||||
no_value: "No"
|
||||
|
|
Loading…
Reference in New Issue
Block a user