Change settings area to be separated into categories in admin UI (#19407)

And update all descriptions
This commit is contained in:
Eugen Rochko 2022-10-22 11:44:41 +02:00 committed by GitHub
parent abf6c87ee8
commit 7c152acb2c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 528 additions and 296 deletions

View file

@ -0,0 +1,9 @@
# frozen_string_literal: true
class Admin::Settings::AboutController < Admin::SettingsController
private
def after_update_redirect_path
admin_settings_about_path
end
end

View file

@ -0,0 +1,9 @@
# frozen_string_literal: true
class Admin::Settings::AppearanceController < Admin::SettingsController
private
def after_update_redirect_path
admin_settings_appearance_path
end
end

View file

@ -0,0 +1,9 @@
# frozen_string_literal: true
class Admin::Settings::BrandingController < Admin::SettingsController
private
def after_update_redirect_path
admin_settings_branding_path
end
end

View file

@ -0,0 +1,9 @@
# frozen_string_literal: true
class Admin::Settings::ContentRetentionController < Admin::SettingsController
private
def after_update_redirect_path
admin_settings_content_retention_path
end
end

View file

@ -0,0 +1,9 @@
# frozen_string_literal: true
class Admin::Settings::DiscoveryController < Admin::SettingsController
private
def after_update_redirect_path
admin_settings_discovery_path
end
end

View file

@ -0,0 +1,9 @@
# frozen_string_literal: true
class Admin::Settings::RegistrationsController < Admin::SettingsController
private
def after_update_redirect_path
admin_settings_registrations_path
end
end

View file

@ -2,7 +2,7 @@
module Admin
class SettingsController < BaseController
def edit
def show
authorize :settings, :show?
@admin_settings = Form::AdminSettings.new
@ -15,14 +15,18 @@ module Admin
if @admin_settings.save
flash[:notice] = I18n.t('generic.changes_saved_msg')
redirect_to edit_admin_settings_path
redirect_to after_update_redirect_path
else
render :edit
render :show
end
end
private
def after_update_redirect_path
raise NotImplementedError
end
def settings_params
params.require(:form_admin_settings).permit(*Form::AdminSettings::KEYS)
end

View file

@ -9,7 +9,7 @@ module Admin
@site_upload.destroy!
redirect_to edit_admin_settings_path, notice: I18n.t('admin.site_uploads.destroyed_msg')
redirect_to admin_settings_path, notice: I18n.t('admin.site_uploads.destroyed_msg')
end
private

View file

@ -1,11 +1,4 @@
# frozen_string_literal: true
module Admin::SettingsHelper
def site_upload_delete_hint(hint, var)
upload = SiteUpload.find_by(var: var.to_s)
return hint unless upload
link = link_to t('admin.site_uploads.delete'), admin_site_upload_path(upload), data: { method: :delete }
safe_join([hint, link], '<br/>'.html_safe)
end
end

View file

@ -188,21 +188,70 @@ $content-width: 840px;
padding-top: 30px;
}
&-heading {
display: flex;
&__heading {
padding-bottom: 36px;
border-bottom: 1px solid lighten($ui-base-color, 8%);
margin: -15px -15px 40px 0;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
margin-bottom: 40px;
& > * {
margin-top: 15px;
margin-right: 15px;
&__row {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
margin: -15px -15px 0 0;
& > * {
margin-top: 15px;
margin-right: 15px;
}
}
&-actions {
&__tabs {
margin-top: 30px;
margin-bottom: -31px;
& > div {
display: flex;
gap: 10px;
}
a {
font-size: 14px;
display: inline-flex;
align-items: center;
padding: 7px 15px;
border-radius: 4px;
color: $darker-text-color;
text-decoration: none;
position: relative;
font-weight: 500;
gap: 5px;
white-space: nowrap;
&.selected {
font-weight: 700;
color: $primary-text-color;
&::after {
content: "";
display: block;
width: 100%;
border-bottom: 1px solid $ui-highlight-color;
position: absolute;
bottom: -5px;
left: 0;
}
}
&:hover,
&:focus,
&:active {
background: lighten($ui-base-color, 4%);
}
}
}
&__actions {
display: inline-flex;
& > :not(:first-child) {
@ -228,11 +277,7 @@ $content-width: 840px;
color: $secondary-text-color;
font-size: 24px;
line-height: 36px;
font-weight: 400;
@media screen and (max-width: $no-columns-breakpoint) {
font-weight: 700;
}
font-weight: 700;
}
h3 {
@ -437,6 +482,11 @@ body,
}
}
& > div {
display: flex;
gap: 5px;
}
strong {
font-weight: 500;
text-transform: uppercase;
@ -1143,7 +1193,7 @@ a.name-tag,
path:first-child {
fill: rgba($highlight-text-color, 0.25) !important;
fill-opacity: 1 !important;
fill-opacity: 100% !important;
}
path:last-child {

View file

@ -29,6 +29,11 @@
background: transparent;
padding: 0;
cursor: pointer;
text-decoration: none;
&--destructive {
color: $error-value-color;
}
&:hover,
&:active {

View file

@ -254,7 +254,7 @@ code {
& > label {
font-family: inherit;
font-size: 16px;
font-size: 14px;
color: $primary-text-color;
display: block;
font-weight: 500;
@ -291,6 +291,20 @@ code {
.input:last-child {
margin-bottom: 0;
}
&__thumbnail {
display: block;
margin: 0;
margin-bottom: 10px;
max-width: 100%;
height: auto;
border-radius: 4px;
background: url("images/void.png");
&:last-child {
margin-bottom: 0;
}
}
}
.fields-row {

View file

@ -8,7 +8,6 @@ class Form::AdminSettings
site_contact_email
site_title
site_short_description
site_description
site_extended_description
site_terms
registrations_mode
@ -53,45 +52,55 @@ class Form::AdminSettings
attr_accessor(*KEYS)
validates :site_short_description, :site_description, html: { wrap_with: :p }
validates :site_extended_description, :site_terms, :closed_registrations_message, html: true
validates :registrations_mode, inclusion: { in: %w(open approved none) }
validates :site_contact_email, :site_contact_username, presence: true
validates :site_contact_username, existing_username: true
validates :bootstrap_timeline_accounts, existing_username: { multiple: true }
validates :show_domain_blocks, inclusion: { in: %w(disabled users all) }
validates :show_domain_blocks_rationale, inclusion: { in: %w(disabled users all) }
validates :media_cache_retention_period, :content_cache_retention_period, :backups_retention_period, numericality: { only_integer: true }, allow_blank: true
validates :registrations_mode, inclusion: { in: %w(open approved none) }, if: -> { defined?(@registrations_mode) }
validates :site_contact_email, :site_contact_username, presence: true, if: -> { defined?(@site_contact_username) || defined?(@site_contact_email) }
validates :site_contact_username, existing_username: true, if: -> { defined?(@site_contact_username) }
validates :bootstrap_timeline_accounts, existing_username: { multiple: true }, if: -> { defined?(@bootstrap_timeline_accounts) }
validates :show_domain_blocks, inclusion: { in: %w(disabled users all) }, if: -> { defined?(@show_domain_blocks) }
validates :show_domain_blocks_rationale, inclusion: { in: %w(disabled users all) }, if: -> { defined?(@show_domain_blocks_rationale) }
validates :media_cache_retention_period, :content_cache_retention_period, :backups_retention_period, numericality: { only_integer: true }, allow_blank: true, if: -> { defined?(@media_cache_retention_period) || defined?(@content_cache_retention_period) || defined?(@backups_retention_period) }
validates :site_short_description, length: { maximum: 200 }, if: -> { defined?(@site_short_description) }
def initialize(_attributes = {})
super
initialize_attributes
KEYS.each do |key|
define_method(key) do
return instance_variable_get("@#{key}") if instance_variable_defined?("@#{key}")
stored_value = begin
if UPLOAD_KEYS.include?(key)
SiteUpload.where(var: key).first_or_initialize(var: key)
else
Setting.public_send(key)
end
end
instance_variable_set("@#{key}", stored_value)
end
end
UPLOAD_KEYS.each do |key|
define_method("#{key}=") do |file|
value = public_send(key)
value.file = file
end
end
def save
return false unless valid?
KEYS.each do |key|
value = instance_variable_get("@#{key}")
next unless instance_variable_defined?("@#{key}")
if UPLOAD_KEYS.include?(key) && !value.nil?
upload = SiteUpload.where(var: key).first_or_initialize(var: key)
upload.update(file: value)
if UPLOAD_KEYS.include?(key)
public_send(key).save
else
setting = Setting.where(var: key).first_or_initialize(var: key)
setting.update(value: typecast_value(key, value))
setting.update(value: typecast_value(key, instance_variable_get("@#{key}")))
end
end
end
private
def initialize_attributes
KEYS.each do |key|
instance_variable_set("@#{key}", Setting.public_send(key)) if instance_variable_get("@#{key}").nil?
end
end
def typecast_value(key, value)
if BOOLEAN_KEYS.include?(key)
value == '1'

View file

@ -8,6 +8,16 @@ class REST::ExtendedDescriptionSerializer < ActiveModel::Serializer
end
def content
object.text
if object.text.present?
markdown.render(object.text)
else
''
end
end
private
def markdown
@markdown ||= Redcarpet::Markdown.new(Redcarpet::Render::HTML)
end
end

View file

@ -0,0 +1,33 @@
- content_for :header_tags do
= javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
- content_for :page_title do
= t('admin.settings.about.title')
- content_for :heading do
%h2= t('admin.settings.title')
= render partial: 'admin/settings/shared/links'
= simple_form_for @admin_settings, url: admin_settings_about_path, html: { method: :patch } do |f|
= render 'shared/error_messages', object: @admin_settings
%p.lead= t('admin.settings.about.preamble')
.fields-group
= f.input :site_extended_description, wrapper: :with_block_label, as: :text, input_html: { rows: 8 }
%p.hint
= t 'admin.settings.about.rules_hint'
= link_to t('admin.settings.about.manage_rules'), admin_rules_path
.fields-row
.fields-row__column.fields-row__column-6.fields-group
= f.input :show_domain_blocks, wrapper: :with_label, collection: %i(disabled users all), label_method: lambda { |value| t("admin.settings.domain_blocks.#{value}") }, include_blank: false, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li'
.fields-row__column.fields-row__column-6.fields-group
= f.input :show_domain_blocks_rationale, wrapper: :with_label, collection: %i(disabled users all), label_method: lambda { |value| t("admin.settings.domain_blocks.#{value}") }, include_blank: false, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li'
.fields-group
= f.input :site_terms, wrapper: :with_block_label, as: :text, input_html: { rows: 8 }
.actions
= f.button :button, t('generic.save_changes'), type: :submit

View file

@ -0,0 +1,34 @@
- content_for :header_tags do
= javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
- content_for :page_title do
= t('admin.settings.appearance.title')
- content_for :heading do
%h2= t('admin.settings.title')
= render partial: 'admin/settings/shared/links'
= simple_form_for @admin_settings, url: admin_settings_appearance_path, html: { method: :patch } do |f|
= render 'shared/error_messages', object: @admin_settings
%p.lead= t('admin.settings.appearance.preamble')
.fields-group
= f.input :theme, collection: Themes.instance.names, label_method: lambda { |theme| I18n.t("themes.#{theme}", default: theme) }, wrapper: :with_label, include_blank: false
.fields-group
= f.input :custom_css, wrapper: :with_block_label, as: :text, input_html: { rows: 8 }
.fields-row
.fields-row__column.fields-row__column-6.fields-group
= f.input :mascot, as: :file, wrapper: :with_block_label
.fields-row__column.fields-row__column-6.fields-group
- if @admin_settings.mascot.persisted?
= image_tag @admin_settings.mascot.file.url, class: 'fields-group__thumbnail'
= link_to admin_site_upload_path(@admin_settings.mascot), data: { method: :delete }, class: 'link-button link-button--destructive' do
= fa_icon 'trash fw'
= t('admin.site_uploads.delete')
.actions
= f.button :button, t('generic.save_changes'), type: :submit

View file

@ -0,0 +1,39 @@
- content_for :header_tags do
= javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
- content_for :page_title do
= t('admin.settings.branding.title')
- content_for :heading do
%h2= t('admin.settings.title')
= render partial: 'admin/settings/shared/links'
= simple_form_for @admin_settings, url: admin_settings_branding_path, html: { method: :patch } do |f|
= render 'shared/error_messages', object: @admin_settings
%p.lead= t('admin.settings.branding.preamble')
.fields-group
= f.input :site_title, wrapper: :with_label
.fields-row
.fields-row__column.fields-row__column-6.fields-group
= f.input :site_contact_username, wrapper: :with_label
.fields-row__column.fields-row__column-6.fields-group
= f.input :site_contact_email, wrapper: :with_label
.fields-group
= f.input :site_short_description, wrapper: :with_block_label, as: :text, input_html: { rows: 2, maxlength: 200 }
.fields-row
.fields-row__column.fields-row__column-6.fields-group
= f.input :thumbnail, as: :file, wrapper: :with_block_label
.fields-row__column.fields-row__column-6.fields-group
- if @admin_settings.thumbnail.persisted?
= image_tag @admin_settings.thumbnail.file.url(:'@1x'), class: 'fields-group__thumbnail'
= link_to admin_site_upload_path(@admin_settings.thumbnail), data: { method: :delete }, class: 'link-button link-button--destructive' do
= fa_icon 'trash fw'
= t('admin.site_uploads.delete')
.actions
= f.button :button, t('generic.save_changes'), type: :submit

View file

@ -0,0 +1,22 @@
- content_for :header_tags do
= javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
- content_for :page_title do
= t('admin.settings.content_retention.title')
- content_for :heading do
%h2= t('admin.settings.title')
= render partial: 'admin/settings/shared/links'
= simple_form_for @admin_settings, url: admin_settings_content_retention_path, html: { method: :patch } do |f|
= render 'shared/error_messages', object: @admin_settings
%p.lead= t('admin.settings.content_retention.preamble')
.fields-group
= f.input :media_cache_retention_period, wrapper: :with_block_label, input_html: { pattern: '[0-9]+' }
= f.input :content_cache_retention_period, wrapper: :with_block_label, input_html: { pattern: '[0-9]+' }
= f.input :backups_retention_period, wrapper: :with_block_label, input_html: { pattern: '[0-9]+' }
.actions
= f.button :button, t('generic.save_changes'), type: :submit

View file

@ -0,0 +1,40 @@
- content_for :header_tags do
= javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
- content_for :page_title do
= t('admin.settings.discovery.title')
- content_for :heading do
%h2= t('admin.settings.title')
= render partial: 'admin/settings/shared/links'
= simple_form_for @admin_settings, url: admin_settings_discovery_path, html: { method: :patch } do |f|
= render 'shared/error_messages', object: @admin_settings
%p.lead= t('admin.settings.discovery.preamble')
%h4= t('admin.settings.discovery.trends')
.fields-group
= f.input :trends, as: :boolean, wrapper: :with_label
.fields-group
= f.input :trendable_by_default, as: :boolean, wrapper: :with_label
%h4= t('admin.settings.discovery.public_timelines')
.fields-group
= f.input :timeline_preview, as: :boolean, wrapper: :with_label
%h4= t('admin.settings.discovery.follow_recommendations')
.fields-group
= f.input :bootstrap_timeline_accounts, wrapper: :with_block_label
%h4= t('admin.settings.discovery.profile_directory')
.fields-group
= f.input :profile_directory, as: :boolean, wrapper: :with_label
.actions
= f.button :button, t('generic.save_changes'), type: :submit

View file

@ -1,102 +0,0 @@
- content_for :header_tags do
= javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
- content_for :page_title do
= t('admin.settings.title')
- content_for :heading_actions do
= button_tag t('generic.save_changes'), class: 'button', form: 'edit_admin'
= simple_form_for @admin_settings, url: admin_settings_path, html: { method: :patch, id: 'edit_admin' } do |f|
= render 'shared/error_messages', object: @admin_settings
.fields-group
= f.input :site_title, wrapper: :with_label, label: t('admin.settings.site_title')
.fields-row
.fields-row__column.fields-row__column-6.fields-group
= f.input :theme, collection: Themes.instance.names, label: t('simple_form.labels.defaults.setting_theme'), label_method: lambda { |theme| I18n.t("themes.#{theme}", default: theme) }, wrapper: :with_label, include_blank: false
.fields-row__column.fields-row__column-6.fields-group
= f.input :registrations_mode, collection: %w(open approved none), wrapper: :with_label, label: t('admin.settings.registrations_mode.title'), include_blank: false, label_method: lambda { |mode| I18n.t("admin.settings.registrations_mode.modes.#{mode}") }
.fields-row
.fields-row__column.fields-row__column-6.fields-group
= f.input :site_contact_username, wrapper: :with_label, label: t('admin.settings.contact_information.username')
.fields-row__column.fields-row__column-6.fields-group
= f.input :site_contact_email, wrapper: :with_label, label: t('admin.settings.contact_information.email')
.fields-group
= f.input :site_short_description, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_short_description.title'), hint: t('admin.settings.site_short_description.desc_html'), input_html: { rows: 2 }
.fields-group
= f.input :site_description, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_description.title'), hint: t('admin.settings.site_description.desc_html'), input_html: { rows: 2 }
.fields-row
.fields-row__column.fields-row__column-6.fields-group
= f.input :thumbnail, as: :file, wrapper: :with_block_label, label: t('admin.settings.thumbnail.title'), hint: site_upload_delete_hint(t('admin.settings.thumbnail.desc_html'), :thumbnail)
.fields-row
.fields-row__column.fields-row__column-6.fields-group
= f.input :mascot, as: :file, wrapper: :with_block_label, label: t('admin.settings.mascot.title'), hint: site_upload_delete_hint(t('admin.settings.mascot.desc_html'), :mascot)
%hr.spacer/
.fields-group
= f.input :require_invite_text, as: :boolean, wrapper: :with_label, label: t('admin.settings.registrations.require_invite_text.title'), hint: t('admin.settings.registrations.require_invite_text.desc_html'), disabled: !approved_registrations?
%hr.spacer/
.fields-group
= f.input :bootstrap_timeline_accounts, wrapper: :with_block_label, label: t('admin.settings.bootstrap_timeline_accounts.title'), hint: t('admin.settings.bootstrap_timeline_accounts.desc_html')
%hr.spacer/
- unless whitelist_mode?
.fields-group
= f.input :timeline_preview, as: :boolean, wrapper: :with_label, label: t('admin.settings.timeline_preview.title'), hint: t('admin.settings.timeline_preview.desc_html')
- unless whitelist_mode?
.fields-group
= f.input :activity_api_enabled, as: :boolean, wrapper: :with_label, label: t('admin.settings.activity_api_enabled.title'), hint: t('admin.settings.activity_api_enabled.desc_html'), recommended: true
.fields-group
= f.input :peers_api_enabled, as: :boolean, wrapper: :with_label, label: t('admin.settings.peers_api_enabled.title'), hint: t('admin.settings.peers_api_enabled.desc_html'), recommended: true
.fields-group
= f.input :preview_sensitive_media, as: :boolean, wrapper: :with_label, label: t('admin.settings.preview_sensitive_media.title'), hint: t('admin.settings.preview_sensitive_media.desc_html')
.fields-group
= f.input :profile_directory, as: :boolean, wrapper: :with_label, label: t('admin.settings.profile_directory.title'), hint: t('admin.settings.profile_directory.desc_html')
.fields-group
= f.input :trends, as: :boolean, wrapper: :with_label, label: t('admin.settings.trends.title'), hint: t('admin.settings.trends.desc_html')
.fields-group
= f.input :trendable_by_default, as: :boolean, wrapper: :with_label, label: t('admin.settings.trendable_by_default.title'), hint: t('admin.settings.trendable_by_default.desc_html'), recommended: :not_recommended
.fields-group
= f.input :noindex, as: :boolean, wrapper: :with_label, label: t('admin.settings.default_noindex.title'), hint: t('admin.settings.default_noindex.desc_html')
%hr.spacer/
.fields-row
.fields-row__column.fields-row__column-6.fields-group
= f.input :show_domain_blocks, wrapper: :with_label, collection: %i(disabled users all), label: t('admin.settings.domain_blocks.title'), label_method: lambda { |value| t("admin.settings.domain_blocks.#{value}") }, include_blank: false, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li'
.fields-row__column.fields-row__column-6.fields-group
= f.input :show_domain_blocks_rationale, wrapper: :with_label, collection: %i(disabled users all), label: t('admin.settings.domain_blocks_rationale.title'), label_method: lambda { |value| t("admin.settings.domain_blocks.#{value}") }, include_blank: false, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li'
.fields-group
= f.input :site_extended_description, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_description_extended.title'), hint: t('admin.settings.site_description_extended.desc_html'), input_html: { rows: 8 } unless whitelist_mode?
= f.input :closed_registrations_message, as: :text, wrapper: :with_block_label, label: t('admin.settings.registrations.closed_message.title'), hint: t('admin.settings.registrations.closed_message.desc_html'), input_html: { rows: 8 }
= f.input :site_terms, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_terms.title'), hint: t('admin.settings.site_terms.desc_html'), input_html: { rows: 8 }
= f.input :custom_css, wrapper: :with_block_label, as: :text, input_html: { rows: 8 }, label: t('admin.settings.custom_css.title'), hint: t('admin.settings.custom_css.desc_html')
%hr.spacer/
.fields-group
= f.input :media_cache_retention_period, wrapper: :with_block_label, input_html: { pattern: '[0-9]+' }
= f.input :content_cache_retention_period, wrapper: :with_block_label, input_html: { pattern: '[0-9]+' }
= f.input :backups_retention_period, wrapper: :with_block_label, input_html: { pattern: '[0-9]+' }
.actions
= f.button :button, t('generic.save_changes'), type: :submit

View file

@ -0,0 +1,27 @@
- content_for :header_tags do
= javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
- content_for :page_title do
= t('admin.settings.registrations.title')
- content_for :heading do
%h2= t('admin.settings.title')
= render partial: 'admin/settings/shared/links'
= simple_form_for @admin_settings, url: admin_settings_branding_path, html: { method: :patch } do |f|
= render 'shared/error_messages', object: @admin_settings
%p.lead= t('admin.settings.registrations.preamble')
.fields-row
.fields-row__column.fields-row__column-6.fields-group
= f.input :registrations_mode, collection: %w(open approved none), wrapper: :with_label, include_blank: false, label_method: lambda { |mode| I18n.t("admin.settings.registrations_mode.modes.#{mode}") }
.fields-row__column.fields-row__column-6.fields-group
= f.input :require_invite_text, as: :boolean, wrapper: :with_label, disabled: !approved_registrations?
.fields-group
= f.input :closed_registrations_message, as: :text, wrapper: :with_block_label, input_html: { rows: 2 }
.actions
= f.button :button, t('generic.save_changes'), type: :submit

View file

@ -0,0 +1,8 @@
.content__heading__tabs
= render_navigation renderer: :links do |primary|
- primary.item :branding, safe_join([fa_icon('pencil fw'), t('admin.settings.branding.title')]), admin_settings_branding_path
- primary.item :about, safe_join([fa_icon('file-text fw'), t('admin.settings.about.title')]), admin_settings_about_path
- primary.item :registrations, safe_join([fa_icon('users fw'), t('admin.settings.registrations.title')]), admin_settings_registrations_path
- primary.item :discovery, safe_join([fa_icon('search fw'), t('admin.settings.discovery.title')]), admin_settings_discovery_path
- primary.item :content_retention, safe_join([fa_icon('history fw'), t('admin.settings.content_retention.title')]), admin_settings_content_retention_path
- primary.item :appearance, safe_join([fa_icon('desktop fw'), t('admin.settings.appearance.title')]), admin_settings_appearance_path

View file

@ -22,15 +22,16 @@
.content-wrapper
.content
.content-heading
.content__heading
- if content_for?(:heading)
= yield :heading
- else
%h2= yield :page_title
.content__heading__row
%h2= yield :page_title
- if :heading_actions
.content-heading-actions
= yield :heading_actions
- if content_for?(:heading_actions)
.content__heading__actions
= yield :heading_actions
= render 'application/flashes'