mirror of
https://github.com/lunaisnotaboy/mastodon.git
synced 2024-12-22 05:08:03 +00:00
Add batch actions and categories to admin UI for custom emojis (#11793)
This commit is contained in:
parent
14d4a783cd
commit
1110ea1a91
|
@ -2,19 +2,20 @@
|
||||||
|
|
||||||
module Admin
|
module Admin
|
||||||
class CustomEmojisController < BaseController
|
class CustomEmojisController < BaseController
|
||||||
before_action :set_custom_emoji, except: [:index, :new, :create]
|
|
||||||
before_action :set_filter_params
|
|
||||||
|
|
||||||
include ObfuscateFilename
|
include ObfuscateFilename
|
||||||
|
|
||||||
obfuscate_filename [:custom_emoji, :image]
|
obfuscate_filename [:custom_emoji, :image]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
authorize :custom_emoji, :index?
|
authorize :custom_emoji, :index?
|
||||||
|
|
||||||
@custom_emojis = filtered_custom_emojis.eager_load(:local_counterpart).page(params[:page])
|
@custom_emojis = filtered_custom_emojis.eager_load(:local_counterpart).page(params[:page])
|
||||||
|
@form = Form::CustomEmojiBatch.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
authorize :custom_emoji, :create?
|
authorize :custom_emoji, :create?
|
||||||
|
|
||||||
@custom_emoji = CustomEmoji.new
|
@custom_emoji = CustomEmoji.new
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -31,69 +32,17 @@ module Admin
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def batch
|
||||||
authorize @custom_emoji, :update?
|
@form = Form::CustomEmojiBatch.new(form_custom_emoji_batch_params.merge(current_account: current_account, action: action_from_button))
|
||||||
|
@form.save
|
||||||
if @custom_emoji.update(resource_params)
|
rescue ActionController::ParameterMissing
|
||||||
log_action :update, @custom_emoji
|
flash[:alert] = I18n.t('admin.accounts.no_account_selected')
|
||||||
flash[:notice] = I18n.t('admin.custom_emojis.updated_msg')
|
ensure
|
||||||
else
|
redirect_to admin_custom_emojis_path(filter_params)
|
||||||
flash[:alert] = I18n.t('admin.custom_emojis.update_failed_msg')
|
|
||||||
end
|
|
||||||
redirect_to admin_custom_emojis_path(page: params[:page], **@filter_params)
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
authorize @custom_emoji, :destroy?
|
|
||||||
@custom_emoji.destroy!
|
|
||||||
log_action :destroy, @custom_emoji
|
|
||||||
flash[:notice] = I18n.t('admin.custom_emojis.destroyed_msg')
|
|
||||||
redirect_to admin_custom_emojis_path(page: params[:page], **@filter_params)
|
|
||||||
end
|
|
||||||
|
|
||||||
def copy
|
|
||||||
authorize @custom_emoji, :copy?
|
|
||||||
|
|
||||||
emoji = CustomEmoji.find_or_initialize_by(domain: nil,
|
|
||||||
shortcode: @custom_emoji.shortcode)
|
|
||||||
emoji.image = @custom_emoji.image
|
|
||||||
|
|
||||||
if emoji.save
|
|
||||||
log_action :create, emoji
|
|
||||||
flash[:notice] = I18n.t('admin.custom_emojis.copied_msg')
|
|
||||||
else
|
|
||||||
flash[:alert] = I18n.t('admin.custom_emojis.copy_failed_msg')
|
|
||||||
end
|
|
||||||
|
|
||||||
redirect_to admin_custom_emojis_path(page: params[:page], **@filter_params)
|
|
||||||
end
|
|
||||||
|
|
||||||
def enable
|
|
||||||
authorize @custom_emoji, :enable?
|
|
||||||
@custom_emoji.update!(disabled: false)
|
|
||||||
log_action :enable, @custom_emoji
|
|
||||||
flash[:notice] = I18n.t('admin.custom_emojis.enabled_msg')
|
|
||||||
redirect_to admin_custom_emojis_path(page: params[:page], **@filter_params)
|
|
||||||
end
|
|
||||||
|
|
||||||
def disable
|
|
||||||
authorize @custom_emoji, :disable?
|
|
||||||
@custom_emoji.update!(disabled: true)
|
|
||||||
log_action :disable, @custom_emoji
|
|
||||||
flash[:notice] = I18n.t('admin.custom_emojis.disabled_msg')
|
|
||||||
redirect_to admin_custom_emojis_path(page: params[:page], **@filter_params)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_custom_emoji
|
|
||||||
@custom_emoji = CustomEmoji.find(params[:id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_filter_params
|
|
||||||
@filter_params = filter_params.to_hash.symbolize_keys
|
|
||||||
end
|
|
||||||
|
|
||||||
def resource_params
|
def resource_params
|
||||||
params.require(:custom_emoji).permit(:shortcode, :image, :visible_in_picker)
|
params.require(:custom_emoji).permit(:shortcode, :image, :visible_in_picker)
|
||||||
end
|
end
|
||||||
|
@ -103,12 +52,29 @@ module Admin
|
||||||
end
|
end
|
||||||
|
|
||||||
def filter_params
|
def filter_params
|
||||||
params.permit(
|
params.slice(:local, :remote, :by_domain, :shortcode, :page).permit(:local, :remote, :by_domain, :shortcode, :page)
|
||||||
:local,
|
end
|
||||||
:remote,
|
|
||||||
:by_domain,
|
def action_from_button
|
||||||
:shortcode
|
if params[:update]
|
||||||
)
|
'update'
|
||||||
|
elsif params[:list]
|
||||||
|
'list'
|
||||||
|
elsif params[:unlist]
|
||||||
|
'unlist'
|
||||||
|
elsif params[:enable]
|
||||||
|
'enable'
|
||||||
|
elsif params[:disable]
|
||||||
|
'disable'
|
||||||
|
elsif params[:copy]
|
||||||
|
'copy'
|
||||||
|
elsif params[:delete]
|
||||||
|
'delete'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def form_custom_emoji_batch_params
|
||||||
|
params.require(:form_custom_emoji_batch).permit(:action, :category_id, :category_name, custom_emoji_ids: [])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -180,6 +180,18 @@ a.table-action-link {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__form {
|
||||||
|
padding: 16px;
|
||||||
|
border: 1px solid darken($ui-base-color, 8%);
|
||||||
|
border-top: 0;
|
||||||
|
background: $ui-base-color;
|
||||||
|
|
||||||
|
.fields-row {
|
||||||
|
padding-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&__row {
|
&__row {
|
||||||
border: 1px solid darken($ui-base-color, 8%);
|
border: 1px solid darken($ui-base-color, 8%);
|
||||||
border-top: 0;
|
border-top: 0;
|
||||||
|
@ -210,6 +222,35 @@ a.table-action-link {
|
||||||
&--unpadded {
|
&--unpadded {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&--with-image {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__image {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 10px;
|
||||||
|
|
||||||
|
.emojione {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__extra {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
text-align: right;
|
||||||
|
color: $darker-text-color;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.directory__tag {
|
.directory__tag {
|
||||||
|
|
|
@ -59,6 +59,12 @@ class CustomEmoji < ApplicationRecord
|
||||||
:emoji
|
:emoji
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def copy!
|
||||||
|
copy = self.class.find_or_initialize_by(domain: nil, shortcode: shortcode)
|
||||||
|
copy.image = image
|
||||||
|
copy.save!
|
||||||
|
end
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
def from_text(text, domain)
|
def from_text(text, domain)
|
||||||
return [] if text.blank?
|
return [] if text.blank?
|
||||||
|
|
|
@ -12,4 +12,6 @@
|
||||||
|
|
||||||
class CustomEmojiCategory < ApplicationRecord
|
class CustomEmojiCategory < ApplicationRecord
|
||||||
has_many :emojis, class_name: 'CustomEmoji', foreign_key: 'category_id', inverse_of: :category
|
has_many :emojis, class_name: 'CustomEmoji', foreign_key: 'category_id', inverse_of: :category
|
||||||
|
|
||||||
|
validates :name, presence: true, uniqueness: true
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,6 +11,8 @@ class CustomEmojiFilter
|
||||||
scope = CustomEmoji.alphabetic
|
scope = CustomEmoji.alphabetic
|
||||||
|
|
||||||
params.each do |key, value|
|
params.each do |key, value|
|
||||||
|
next if key.to_s == 'page'
|
||||||
|
|
||||||
scope.merge!(scope_for(key, value)) if value.present?
|
scope.merge!(scope_for(key, value)) if value.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -22,13 +24,13 @@ class CustomEmojiFilter
|
||||||
def scope_for(key, value)
|
def scope_for(key, value)
|
||||||
case key.to_s
|
case key.to_s
|
||||||
when 'local'
|
when 'local'
|
||||||
CustomEmoji.local
|
CustomEmoji.local.left_joins(:category).reorder(Arel.sql('custom_emoji_categories.name ASC NULLS FIRST, custom_emojis.shortcode ASC'))
|
||||||
when 'remote'
|
when 'remote'
|
||||||
CustomEmoji.remote
|
CustomEmoji.remote
|
||||||
when 'by_domain'
|
when 'by_domain'
|
||||||
CustomEmoji.where(domain: value.downcase)
|
CustomEmoji.where(domain: value.strip.downcase)
|
||||||
when 'shortcode'
|
when 'shortcode'
|
||||||
CustomEmoji.search(value)
|
CustomEmoji.search(value.strip)
|
||||||
else
|
else
|
||||||
raise "Unknown filter: #{key}"
|
raise "Unknown filter: #{key}"
|
||||||
end
|
end
|
||||||
|
|
106
app/models/form/custom_emoji_batch.rb
Normal file
106
app/models/form/custom_emoji_batch.rb
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class Form::CustomEmojiBatch
|
||||||
|
include ActiveModel::Model
|
||||||
|
include Authorization
|
||||||
|
include AccountableConcern
|
||||||
|
|
||||||
|
attr_accessor :custom_emoji_ids, :action, :current_account,
|
||||||
|
:category_id, :category_name, :visible_in_picker
|
||||||
|
|
||||||
|
def save
|
||||||
|
case action
|
||||||
|
when 'update'
|
||||||
|
update!
|
||||||
|
when 'list'
|
||||||
|
list!
|
||||||
|
when 'unlist'
|
||||||
|
unlist!
|
||||||
|
when 'enable'
|
||||||
|
enable!
|
||||||
|
when 'disable'
|
||||||
|
disable!
|
||||||
|
when 'copy'
|
||||||
|
copy!
|
||||||
|
when 'delete'
|
||||||
|
delete!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def custom_emojis
|
||||||
|
CustomEmoji.where(id: custom_emoji_ids)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update!
|
||||||
|
custom_emojis.each { |custom_emoji| authorize(custom_emoji, :update?) }
|
||||||
|
|
||||||
|
category = begin
|
||||||
|
if category_id.present?
|
||||||
|
CustomEmojiCategory.find(category_id)
|
||||||
|
elsif category_name.present?
|
||||||
|
CustomEmojiCategory.create!(name: category_name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
custom_emojis.each do |custom_emoji|
|
||||||
|
custom_emoji.update(category_id: category&.id)
|
||||||
|
log_action :update, custom_emoji
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def list!
|
||||||
|
custom_emojis.each { |custom_emoji| authorize(custom_emoji, :update?) }
|
||||||
|
|
||||||
|
custom_emojis.each do |custom_emoji|
|
||||||
|
custom_emoji.update(visible_in_picker: true)
|
||||||
|
log_action :update, custom_emoji
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def unlist!
|
||||||
|
custom_emojis.each { |custom_emoji| authorize(custom_emoji, :update?) }
|
||||||
|
|
||||||
|
custom_emojis.each do |custom_emoji|
|
||||||
|
custom_emoji.update(visible_in_picker: false)
|
||||||
|
log_action :update, custom_emoji
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def enable!
|
||||||
|
custom_emojis.each { |custom_emoji| authorize(custom_emoji, :enable?) }
|
||||||
|
|
||||||
|
custom_emojis.each do |custom_emoji|
|
||||||
|
custom_emoji.update(disabled: false)
|
||||||
|
log_action :enable, custom_emoji
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def disable!
|
||||||
|
custom_emojis.each { |custom_emoji| authorize(custom_emoji, :disable?) }
|
||||||
|
|
||||||
|
custom_emojis.each do |custom_emoji|
|
||||||
|
custom_emoji.update(disabled: true)
|
||||||
|
log_action :disable, custom_emoji
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def copy!
|
||||||
|
custom_emojis.each { |custom_emoji| authorize(custom_emoji, :copy?) }
|
||||||
|
|
||||||
|
custom_emojis.each do |custom_emoji|
|
||||||
|
copied_custom_emoji = custom_emoji.copy!
|
||||||
|
log_action :create, copied_custom_emoji
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete!
|
||||||
|
custom_emojis.each { |custom_emoji| authorize(custom_emoji, :destroy?) }
|
||||||
|
|
||||||
|
custom_emojis.each do |custom_emoji|
|
||||||
|
custom_emoji.destroy
|
||||||
|
log_action :destroy, custom_emoji
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,28 +1,31 @@
|
||||||
%tr
|
.batch-table__row
|
||||||
%td
|
%label.batch-table__row__select.batch-table__row__select--aligned.batch-checkbox
|
||||||
= custom_emoji_tag(custom_emoji)
|
= f.check_box :custom_emoji_ids, { multiple: true, include_hidden: false }, custom_emoji.id
|
||||||
%td
|
.batch-table__row__content.batch-table__row__content--with-image
|
||||||
%samp= ":#{custom_emoji.shortcode}:"
|
.batch-table__row__content__image
|
||||||
%td
|
= custom_emoji_tag(custom_emoji)
|
||||||
- if custom_emoji.local?
|
|
||||||
= t('admin.accounts.location.local')
|
.batch-table__row__content__text
|
||||||
- else
|
%samp= ":#{custom_emoji.shortcode}:"
|
||||||
= link_to custom_emoji.domain, admin_custom_emojis_path(by_domain: custom_emoji.domain)
|
|
||||||
%td
|
- if custom_emoji.local?
|
||||||
- if custom_emoji.local?
|
%span.account-role.bot= custom_emoji.category&.name || t('admin.custom_emojis.uncategorized')
|
||||||
- if custom_emoji.visible_in_picker
|
|
||||||
= table_link_to 'eye', t('admin.custom_emojis.listed'), admin_custom_emoji_path(custom_emoji, custom_emoji: { visible_in_picker: false }, page: params[:page], **@filter_params), method: :patch
|
.batch-table__row__content__extra
|
||||||
|
- if custom_emoji.local?
|
||||||
|
= t('admin.accounts.location.local')
|
||||||
- else
|
- else
|
||||||
= table_link_to 'eye-slash', t('admin.custom_emojis.unlisted'), admin_custom_emoji_path(custom_emoji, custom_emoji: { visible_in_picker: true }, page: params[:page], **@filter_params), method: :patch
|
= custom_emoji.domain
|
||||||
- else
|
|
||||||
- if custom_emoji.local_counterpart.present?
|
%br/
|
||||||
= link_to safe_join([custom_emoji_tag(custom_emoji.local_counterpart), t('admin.custom_emojis.overwrite')]), copy_admin_custom_emoji_path(custom_emoji, page: params[:page], **@filter_params), method: :post, class: 'table-action-link'
|
|
||||||
|
- if custom_emoji.disabled?
|
||||||
|
= t('admin.custom_emojis.disabled')
|
||||||
- else
|
- else
|
||||||
= table_link_to 'copy', t('admin.custom_emojis.copy'), copy_admin_custom_emoji_path(custom_emoji, page: params[:page], **@filter_params), method: :post
|
= t('admin.custom_emojis.enabled')
|
||||||
%td
|
- if custom_emoji.local?
|
||||||
- if custom_emoji.disabled?
|
•
|
||||||
= table_link_to 'power-off', t('admin.custom_emojis.enable'), enable_admin_custom_emoji_path(custom_emoji, page: params[:page], **@filter_params), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }
|
- if custom_emoji.visible_in_picker?
|
||||||
- else
|
= t('admin.custom_emojis.listed')
|
||||||
= table_link_to 'power-off', t('admin.custom_emojis.disable'), disable_admin_custom_emoji_path(custom_emoji, page: params[:page], **@filter_params), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }
|
- else
|
||||||
%td
|
= t('admin.custom_emojis.unlisted')
|
||||||
= table_link_to 'times', t('admin.custom_emojis.delete'), admin_custom_emoji_path(custom_emoji, page: params[:page], **@filter_params), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') }
|
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
- content_for :page_title do
|
- content_for :page_title do
|
||||||
= t('admin.custom_emojis.title')
|
= t('admin.custom_emojis.title')
|
||||||
|
|
||||||
|
- content_for :header_tags do
|
||||||
|
= javascript_pack_tag 'admin', integrity: true, async: true, crossorigin: 'anonymous'
|
||||||
|
|
||||||
.filters
|
.filters
|
||||||
.filter-subset
|
.filter-subset
|
||||||
%strong= t('admin.accounts.location.title')
|
%strong= t('admin.accounts.location.title')
|
||||||
|
@ -20,8 +23,7 @@
|
||||||
= form_tag admin_custom_emojis_url, method: 'GET', class: 'simple_form' do
|
= form_tag admin_custom_emojis_url, method: 'GET', class: 'simple_form' do
|
||||||
.fields-group
|
.fields-group
|
||||||
- Admin::FilterHelper::CUSTOM_EMOJI_FILTERS.each do |key|
|
- Admin::FilterHelper::CUSTOM_EMOJI_FILTERS.each do |key|
|
||||||
- if params[key].present?
|
= hidden_field_tag key, params[key] if params[key].present?
|
||||||
= hidden_field_tag key, params[key]
|
|
||||||
|
|
||||||
- %i(shortcode by_domain).each do |key|
|
- %i(shortcode by_domain).each do |key|
|
||||||
.input.string.optional
|
.input.string.optional
|
||||||
|
@ -31,18 +33,54 @@
|
||||||
%button= t('admin.accounts.search')
|
%button= t('admin.accounts.search')
|
||||||
= link_to t('admin.accounts.reset'), admin_custom_emojis_path, class: 'button negative'
|
= link_to t('admin.accounts.reset'), admin_custom_emojis_path, class: 'button negative'
|
||||||
|
|
||||||
.table-wrapper
|
= form_for(@form, url: batch_admin_custom_emojis_path) do |f|
|
||||||
%table.table
|
= hidden_field_tag :page, params[:page] || 1
|
||||||
%thead
|
|
||||||
%tr
|
- Admin::FilterHelper::CUSTOM_EMOJI_FILTERS.each do |key|
|
||||||
%th= t('admin.custom_emojis.emoji')
|
= hidden_field_tag key, params[key] if params[key].present?
|
||||||
%th= t('admin.custom_emojis.shortcode')
|
|
||||||
%th= t('admin.accounts.domain')
|
.batch-table
|
||||||
%th
|
.batch-table__toolbar
|
||||||
%th
|
%label.batch-table__toolbar__select.batch-checkbox-all
|
||||||
%th
|
= check_box_tag :batch_checkbox_all, nil, false
|
||||||
%tbody
|
.batch-table__toolbar__actions
|
||||||
= render @custom_emojis
|
- if params[:local] == '1'
|
||||||
|
= f.button safe_join([fa_icon('save'), t('generic.save_changes')]), name: :update, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
||||||
|
|
||||||
|
= f.button safe_join([fa_icon('eye'), t('admin.custom_emojis.list')]), name: :list, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
||||||
|
|
||||||
|
= f.button safe_join([fa_icon('eye-slash'), t('admin.custom_emojis.unlist')]), name: :unlist, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
||||||
|
|
||||||
|
= f.button safe_join([fa_icon('power-off'), t('admin.custom_emojis.enable')]), name: :enable, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
||||||
|
|
||||||
|
= f.button safe_join([fa_icon('power-off'), t('admin.custom_emojis.disable')]), name: :disable, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
||||||
|
|
||||||
|
= f.button safe_join([fa_icon('times'), t('admin.custom_emojis.delete')]), name: :delete, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
||||||
|
|
||||||
|
- unless params[:local] == '1'
|
||||||
|
= f.button safe_join([fa_icon('copy'), t('admin.custom_emojis.copy')]), name: :copy, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
||||||
|
|
||||||
|
- if params[:local] == '1'
|
||||||
|
.batch-table__form.simple_form
|
||||||
|
.fields-row
|
||||||
|
.fields-group.fields-row__column.fields-row__column-6
|
||||||
|
.input.select.optional
|
||||||
|
.label_input
|
||||||
|
= f.select :category_id, options_from_collection_for_select(CustomEmojiCategory.all, 'id', 'name'), prompt: t('admin.custom_emojis.assign_category'), class: 'select optional', 'aria-label': t('admin.custom_emojis.assign_category')
|
||||||
|
|
||||||
|
.fields-group.fields-row__column.fields-row__column-6
|
||||||
|
.input.string.optional
|
||||||
|
.label_input
|
||||||
|
= f.text_field :category_name, class: 'string optional', placeholder: t('admin.custom_emojis.create_new_category'), 'aria-label': t('admin.custom_emojis.create_new_category')
|
||||||
|
|
||||||
|
.batch-table__body
|
||||||
|
- if @custom_emojis.empty?
|
||||||
|
= nothing_here 'nothing-here--under-tabs'
|
||||||
|
- else
|
||||||
|
= render partial: 'custom_emoji', collection: @custom_emojis, locals: { f: f }
|
||||||
|
|
||||||
= paginate @custom_emojis
|
= paginate @custom_emojis
|
||||||
|
|
||||||
|
%hr.spacer/
|
||||||
|
|
||||||
= link_to t('admin.custom_emojis.upload'), new_admin_custom_emoji_path, class: 'button'
|
= link_to t('admin.custom_emojis.upload'), new_admin_custom_emoji_path, class: 'button'
|
||||||
|
|
|
@ -225,10 +225,12 @@ en:
|
||||||
deleted_status: "(deleted status)"
|
deleted_status: "(deleted status)"
|
||||||
title: Audit log
|
title: Audit log
|
||||||
custom_emojis:
|
custom_emojis:
|
||||||
|
assign_category: Assign category
|
||||||
by_domain: Domain
|
by_domain: Domain
|
||||||
copied_msg: Successfully created local copy of the emoji
|
copied_msg: Successfully created local copy of the emoji
|
||||||
copy: Copy
|
copy: Copy
|
||||||
copy_failed_msg: Could not make a local copy of that emoji
|
copy_failed_msg: Could not make a local copy of that emoji
|
||||||
|
create_new_category: Create new category
|
||||||
created_msg: Emoji successfully created!
|
created_msg: Emoji successfully created!
|
||||||
delete: Delete
|
delete: Delete
|
||||||
destroyed_msg: Emojo successfully destroyed!
|
destroyed_msg: Emojo successfully destroyed!
|
||||||
|
@ -245,6 +247,7 @@ en:
|
||||||
shortcode: Shortcode
|
shortcode: Shortcode
|
||||||
shortcode_hint: At least 2 characters, only alphanumeric characters and underscores
|
shortcode_hint: At least 2 characters, only alphanumeric characters and underscores
|
||||||
title: Custom emojis
|
title: Custom emojis
|
||||||
|
uncategorized: Uncategorized
|
||||||
unlisted: Unlisted
|
unlisted: Unlisted
|
||||||
update_failed_msg: Could not update that emoji
|
update_failed_msg: Could not update that emoji
|
||||||
updated_msg: Emoji successfully updated!
|
updated_msg: Emoji successfully updated!
|
||||||
|
|
|
@ -242,11 +242,9 @@ Rails.application.routes.draw do
|
||||||
resource :two_factor_authentication, only: [:destroy]
|
resource :two_factor_authentication, only: [:destroy]
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :custom_emojis, only: [:index, :new, :create, :update, :destroy] do
|
resources :custom_emojis, only: [:index, :new, :create] do
|
||||||
member do
|
collection do
|
||||||
post :copy
|
post :batch
|
||||||
post :enable
|
|
||||||
post :disable
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -52,64 +52,4 @@ describe Admin::CustomEmojisController do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'PUT #update' do
|
|
||||||
let(:custom_emoji) { Fabricate(:custom_emoji, shortcode: 'test') }
|
|
||||||
let(:image) { fixture_file_upload(Rails.root.join('spec', 'fixtures', 'files', 'emojo.png'), 'image/png') }
|
|
||||||
|
|
||||||
before do
|
|
||||||
put :update, params: { id: custom_emoji.id, custom_emoji: params }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when parameter is valid' do
|
|
||||||
let(:params) { { shortcode: 'updated', image: image } }
|
|
||||||
|
|
||||||
it 'succeeds in updating custom emoji' do
|
|
||||||
expect(flash[:notice]).to eq I18n.t('admin.custom_emojis.updated_msg')
|
|
||||||
expect(custom_emoji.reload).to have_attributes(shortcode: 'updated')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when parameter is invalid' do
|
|
||||||
let(:params) { { shortcode: 'u', image: image } }
|
|
||||||
|
|
||||||
it 'fails to update custom emoji' do
|
|
||||||
expect(flash[:alert]).to eq I18n.t('admin.custom_emojis.update_failed_msg')
|
|
||||||
expect(custom_emoji.reload).to have_attributes(shortcode: 'test')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'POST #copy' do
|
|
||||||
subject { post :copy, params: { id: custom_emoji.id } }
|
|
||||||
|
|
||||||
let(:custom_emoji) { Fabricate(:custom_emoji, shortcode: 'test') }
|
|
||||||
|
|
||||||
it 'copies custom emoji' do
|
|
||||||
expect { subject }.to change { CustomEmoji.where(shortcode: 'test').count }.by(1)
|
|
||||||
expect(flash[:notice]).to eq I18n.t('admin.custom_emojis.copied_msg')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'POST #enable' do
|
|
||||||
let(:custom_emoji) { Fabricate(:custom_emoji, shortcode: 'test', disabled: true) }
|
|
||||||
|
|
||||||
before { post :enable, params: { id: custom_emoji.id } }
|
|
||||||
|
|
||||||
it 'enables custom emoji' do
|
|
||||||
expect(response).to redirect_to admin_custom_emojis_path
|
|
||||||
expect(custom_emoji.reload).to have_attributes(disabled: false)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'POST #disable' do
|
|
||||||
let(:custom_emoji) { Fabricate(:custom_emoji, shortcode: 'test', disabled: false) }
|
|
||||||
|
|
||||||
before { post :disable, params: { id: custom_emoji.id } }
|
|
||||||
|
|
||||||
it 'enables custom emoji' do
|
|
||||||
expect(response).to redirect_to admin_custom_emojis_path
|
|
||||||
expect(custom_emoji.reload).to have_attributes(disabled: true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue