discourse/app/assets/javascripts/discourse/widgets/topic-admin-menu.js.es6

175 lines
5.8 KiB
JavaScript

import { createWidget, applyDecorators } from 'discourse/widgets/widget';
import { h } from 'virtual-dom';
createWidget('admin-menu-button', {
html(attrs) {
let className = 'btn';
if (attrs.buttonClass) { className += ' ' + attrs.buttonClass; }
return h('li', { className: attrs.className }, this.attach('button', {
className,
action: attrs.action,
icon: attrs.icon,
label: `topic.${attrs.label}`,
secondaryAction: 'hideAdminMenu'
}));
}
});
createWidget('topic-admin-menu-button', {
tagName: 'span',
buildKey: () => `topic-admin-menu-button`,
defaultState() {
return { expanded: false, position: null };
},
html(attrs, state) {
if (!this.currentUser || !this.currentUser.get('canManageTopic')) { return; }
const result = [];
result.push(this.attach('button', {
className: 'btn ' + (attrs.fixed ? " show-topic-admin" : ""),
title: 'topic_admin_menu',
icon: 'wrench',
action: 'showAdminMenu',
sendActionEvent: true
}));
if (state.expanded) {
result.push(this.attach('topic-admin-menu', { position: state.position,
fixed: attrs.fixed,
topic: attrs.topic,
openUpwards: attrs.openUpwards }));
}
return result;
},
hideAdminMenu() {
this.state.expanded = false;
this.state.position = null;
},
showAdminMenu(e) {
this.state.expanded = true;
const $button = $(e.target).closest('button');
const position = $button.position();
position.left = position.left;
position.outerHeight = $button.outerHeight();
if (this.attrs.fixed) {
position.left += $button.width() - 203;
}
this.state.position = position;
}
});
export default createWidget('topic-admin-menu', {
tagName: 'div.popup-menu.topic-admin-popup-menu',
buildAttributes(attrs) {
const { top, left, outerHeight } = attrs.position;
const position = attrs.fixed ? 'fixed' : 'absolute';
if (attrs.openUpwards) {
const documentHeight = $(document).height();
const mainHeight = $('#main').height();
let bottom = documentHeight - top - $('#main').offset().top;
if (documentHeight > mainHeight) {
bottom = bottom - (documentHeight - mainHeight) - outerHeight;
}
return { style: `position: ${position}; bottom: ${bottom}px; left: ${left}px;` };
} else {
return { style: `position: ${position}; top: ${top}px; left: ${left}px;` };
}
},
html(attrs) {
const buttons = [];
buttons.push({ className: 'topic-admin-multi-select',
action: 'toggleMultiSelect',
icon: 'tasks',
label: 'actions.multi_select' });
const topic = attrs.topic;
const details = topic.get('details');
if (details.get('can_delete')) {
buttons.push({ className: 'topic-admin-delete',
buttonClass: 'btn-danger',
action: 'deleteTopic',
icon: 'trash-o',
label: 'actions.delete' });
}
if (topic.get('deleted') && details.get('can_recover')) {
buttons.push({ className: 'topic-admin-recover',
action: 'recoverTopic',
icon: 'undo',
label: 'actions.recover' });
}
if (topic.get('closed')) {
buttons.push({ className: 'topic-admin-open',
action: 'toggleClosed',
icon: 'unlock',
label: 'actions.open' });
} else {
buttons.push({ className: 'topic-admin-close',
action: 'toggleClosed',
icon: 'lock',
label: 'actions.close' });
buttons.push({ className: 'topic-admin-autoclose',
action: 'showAutoClose',
icon: 'clock-o',
label: 'actions.auto_close' });
}
const isPrivateMessage = topic.get('isPrivateMessage');
if (!isPrivateMessage && topic.get('visible')) {
const featured = topic.get('pinned_at') || topic.get('isBanner');
buttons.push({ className: 'topic-admin-pin',
action: 'showFeatureTopic',
icon: 'thumb-tack',
label: featured ? 'actions.unpin' : 'actions.pin' });
}
buttons.push({ className: 'topic-admin-change-timestamp',
action: 'showChangeTimestamp',
icon: 'calendar',
label: 'change_timestamp.title' });
if (!isPrivateMessage) {
buttons.push({ className: 'topic-admin-archive',
action: 'toggleArchived',
icon: 'folder',
label: topic.get('archived') ? 'actions.unarchive' : 'actions.archive' });
}
const visible = topic.get('visible');
buttons.push({ className: 'topic-admin-visible',
action: 'toggleVisibility',
icon: visible ? 'eye-slash' : 'eye',
label: visible ? 'actions.invisible' : 'actions.visible' });
if (this.currentUser.get('staff')) {
buttons.push({ className: 'topic-admin-convert',
action: isPrivateMessage ? 'convertToPublicTopic' : 'convertToPrivateMessage',
icon: isPrivateMessage ? 'comment' : 'envelope',
label: isPrivateMessage ? 'actions.make_public' : 'actions.make_private' });
}
const extraButtons = applyDecorators(this, 'adminMenuButtons', this.attrs, this.state);
return [ h('h3', I18n.t('admin_title')),
h('ul', buttons.concat(extraButtons).map(b => this.attach('admin-menu-button', b))) ];
},
clickOutside() {
this.sendWidgetAction('hideAdminMenu');
}
});