forked from cybrespace/mastodon
		
	Add quick links to the admin interface in the WebUI (#8545)
* Allow to show a specific status in the admin interface * Let the front-end know the current account is a moderator * Add admin links to status and account menus If the current logged-in user is an admin, add quick links to the admin interface in account and toot dropdown menu. Suggestion by @ashkitten * Use @statuses.first instead of @statuses[0]
This commit is contained in:
		
							parent
							
								
									1512af2811
								
							
						
					
					
						commit
						6f9a7bd02c
					
				
					 8 changed files with 62 additions and 4 deletions
				
			
		| 
						 | 
				
			
			@ -22,6 +22,15 @@ module Admin
 | 
			
		|||
      @form     = Form::StatusBatch.new
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def show
 | 
			
		||||
      authorize :status, :index?
 | 
			
		||||
 | 
			
		||||
      @statuses = @account.statuses.where(id: params[:id])
 | 
			
		||||
      authorize @statuses.first, :show?
 | 
			
		||||
 | 
			
		||||
      @form = Form::StatusBatch.new
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def create
 | 
			
		||||
      authorize :status, :update?
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,7 +5,7 @@ import IconButton from './icon_button';
 | 
			
		|||
import DropdownMenuContainer from '../containers/dropdown_menu_container';
 | 
			
		||||
import { defineMessages, injectIntl } from 'react-intl';
 | 
			
		||||
import ImmutablePureComponent from 'react-immutable-pure-component';
 | 
			
		||||
import { me } from '../initial_state';
 | 
			
		||||
import { me, isStaff } from '../initial_state';
 | 
			
		||||
 | 
			
		||||
const messages = defineMessages({
 | 
			
		||||
  delete: { id: 'status.delete', defaultMessage: 'Delete' },
 | 
			
		||||
| 
						 | 
				
			
			@ -30,6 +30,8 @@ const messages = defineMessages({
 | 
			
		|||
  pin: { id: 'status.pin', defaultMessage: 'Pin on profile' },
 | 
			
		||||
  unpin: { id: 'status.unpin', defaultMessage: 'Unpin from profile' },
 | 
			
		||||
  embed: { id: 'status.embed', defaultMessage: 'Embed' },
 | 
			
		||||
  admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
 | 
			
		||||
  admin_status: { id: 'status.admin_status', defaultMessage: 'Open this status in the moderation interface' },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const obfuscatedCount = count => {
 | 
			
		||||
| 
						 | 
				
			
			@ -182,6 +184,11 @@ class StatusActionBar extends ImmutablePureComponent {
 | 
			
		|||
      menu.push({ text: intl.formatMessage(messages.mute, { name: status.getIn(['account', 'username']) }), action: this.handleMuteClick });
 | 
			
		||||
      menu.push({ text: intl.formatMessage(messages.block, { name: status.getIn(['account', 'username']) }), action: this.handleBlockClick });
 | 
			
		||||
      menu.push({ text: intl.formatMessage(messages.report, { name: status.getIn(['account', 'username']) }), action: this.handleReport });
 | 
			
		||||
      if (isStaff) {
 | 
			
		||||
        menu.push(null);
 | 
			
		||||
        menu.push({ text: intl.formatMessage(messages.admin_account, { name: status.getIn(['account', 'username']) }), href: `/admin/accounts/${status.getIn(['account', 'id'])}` });
 | 
			
		||||
        menu.push({ text: intl.formatMessage(messages.admin_status), href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}` });
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (status.get('visibility') === 'direct') {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
 | 
			
		|||
import DropdownMenuContainer from '../../../containers/dropdown_menu_container';
 | 
			
		||||
import { NavLink } from 'react-router-dom';
 | 
			
		||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 | 
			
		||||
import { me } from '../../../initial_state';
 | 
			
		||||
import { me, isStaff  } from '../../../initial_state';
 | 
			
		||||
import { shortNumberFormat } from '../../../utils/numbers';
 | 
			
		||||
 | 
			
		||||
const messages = defineMessages({
 | 
			
		||||
| 
						 | 
				
			
			@ -35,6 +35,7 @@ const messages = defineMessages({
 | 
			
		|||
  endorse: { id: 'account.endorse', defaultMessage: 'Feature on profile' },
 | 
			
		||||
  unendorse: { id: 'account.unendorse', defaultMessage: 'Don\'t feature on profile' },
 | 
			
		||||
  add_or_remove_from_list: { id: 'account.add_or_remove_from_list', defaultMessage: 'Add or Remove from lists' },
 | 
			
		||||
  admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default @injectIntl
 | 
			
		||||
| 
						 | 
				
			
			@ -151,6 +152,11 @@ class ActionBar extends React.PureComponent {
 | 
			
		|||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (account.get('id') !== me && isStaff) {
 | 
			
		||||
      menu.push(null);
 | 
			
		||||
      menu.push({ text: intl.formatMessage(messages.admin_account, { name: account.get('username') }), href: `/admin/accounts/${account.get('id')}` });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
      <div>
 | 
			
		||||
        {extraInfo}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,7 @@ import IconButton from '../../../components/icon_button';
 | 
			
		|||
import ImmutablePropTypes from 'react-immutable-proptypes';
 | 
			
		||||
import DropdownMenuContainer from '../../../containers/dropdown_menu_container';
 | 
			
		||||
import { defineMessages, injectIntl } from 'react-intl';
 | 
			
		||||
import { me } from '../../../initial_state';
 | 
			
		||||
import { me, isStaff } from '../../../initial_state';
 | 
			
		||||
 | 
			
		||||
const messages = defineMessages({
 | 
			
		||||
  delete: { id: 'status.delete', defaultMessage: 'Delete' },
 | 
			
		||||
| 
						 | 
				
			
			@ -26,6 +26,8 @@ const messages = defineMessages({
 | 
			
		|||
  pin: { id: 'status.pin', defaultMessage: 'Pin on profile' },
 | 
			
		||||
  unpin: { id: 'status.unpin', defaultMessage: 'Unpin from profile' },
 | 
			
		||||
  embed: { id: 'status.embed', defaultMessage: 'Embed' },
 | 
			
		||||
  admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
 | 
			
		||||
  admin_status: { id: 'status.admin_status', defaultMessage: 'Open this status in the moderation interface' },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default @injectIntl
 | 
			
		||||
| 
						 | 
				
			
			@ -145,6 +147,11 @@ class ActionBar extends React.PureComponent {
 | 
			
		|||
      menu.push({ text: intl.formatMessage(messages.mute, { name: status.getIn(['account', 'username']) }), action: this.handleMuteClick });
 | 
			
		||||
      menu.push({ text: intl.formatMessage(messages.block, { name: status.getIn(['account', 'username']) }), action: this.handleBlockClick });
 | 
			
		||||
      menu.push({ text: intl.formatMessage(messages.report, { name: status.getIn(['account', 'username']) }), action: this.handleReport });
 | 
			
		||||
      if (isStaff) {
 | 
			
		||||
        menu.push(null);
 | 
			
		||||
        menu.push({ text: intl.formatMessage(messages.admin_account, { name: status.getIn(['account', 'username']) }), href: `/admin/accounts/${status.getIn(['account', 'id'])}` });
 | 
			
		||||
        menu.push({ text: intl.formatMessage(messages.admin_status), href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}` });
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const shareButton = ('share' in navigator) && status.get('visibility') === 'public' && (
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,5 +16,6 @@ export const invitesEnabled = getMeta('invites_enabled');
 | 
			
		|||
export const version = getMeta('version');
 | 
			
		||||
export const mascot = getMeta('mascot');
 | 
			
		||||
export const profile_directory = getMeta('profile_directory');
 | 
			
		||||
export const isStaff = getMeta('is_staff');
 | 
			
		||||
 | 
			
		||||
export default initialState;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,6 +29,7 @@ class InitialStateSerializer < ActiveModel::Serializer
 | 
			
		|||
      store[:display_media]   = object.current_account.user.setting_display_media
 | 
			
		||||
      store[:expand_spoilers] = object.current_account.user.setting_expand_spoilers
 | 
			
		||||
      store[:reduce_motion]   = object.current_account.user.setting_reduce_motion
 | 
			
		||||
      store[:is_staff]        = object.current_account.user.staff?
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    store
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										27
									
								
								app/views/admin/statuses/show.html.haml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								app/views/admin/statuses/show.html.haml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,27 @@
 | 
			
		|||
- content_for :page_title do
 | 
			
		||||
  = t('admin.statuses.title')
 | 
			
		||||
  \-
 | 
			
		||||
  = "@#{@account.acct}"
 | 
			
		||||
 | 
			
		||||
.filters
 | 
			
		||||
  .back-link{ style: 'flex: 1 1 auto; text-align: right' }
 | 
			
		||||
    = link_to admin_account_path(@account.id) do
 | 
			
		||||
      %i.fa.fa-chevron-left.fa-fw
 | 
			
		||||
      = t('admin.statuses.back_to_account')
 | 
			
		||||
 | 
			
		||||
%hr.spacer/
 | 
			
		||||
 | 
			
		||||
= form_for(@form, url: admin_account_statuses_path(@account.id)) do |f|
 | 
			
		||||
  = hidden_field_tag :page, params[:page]
 | 
			
		||||
  = hidden_field_tag :media, params[:media]
 | 
			
		||||
 | 
			
		||||
  .batch-table
 | 
			
		||||
    .batch-table__toolbar
 | 
			
		||||
      %label.batch-table__toolbar__select.batch-checkbox-all
 | 
			
		||||
        = check_box_tag :batch_checkbox_all, nil, false
 | 
			
		||||
      .batch-table__toolbar__actions
 | 
			
		||||
        = f.button safe_join([fa_icon('eye-slash'), t('admin.statuses.batch.nsfw_on')]), name: :nsfw_on, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
 | 
			
		||||
        = f.button safe_join([fa_icon('eye'), t('admin.statuses.batch.nsfw_off')]), name: :nsfw_off, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
 | 
			
		||||
        = f.button safe_join([fa_icon('trash'), t('admin.statuses.batch.delete')]), name: :delete, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
 | 
			
		||||
    .batch-table__body
 | 
			
		||||
      = render partial: 'admin/reports/status', collection: @statuses, locals: { f: f }
 | 
			
		||||
| 
						 | 
				
			
			@ -192,7 +192,7 @@ Rails.application.routes.draw do
 | 
			
		|||
      resource :change_email, only: [:show, :update]
 | 
			
		||||
      resource :reset, only: [:create]
 | 
			
		||||
      resource :action, only: [:new, :create], controller: 'account_actions'
 | 
			
		||||
      resources :statuses, only: [:index, :create, :update, :destroy]
 | 
			
		||||
      resources :statuses, only: [:index, :show, :create, :update, :destroy]
 | 
			
		||||
      resources :followers, only: [:index]
 | 
			
		||||
 | 
			
		||||
      resource :confirmation, only: [:create] do
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue