mirror of
https://github.com/mastodon/mastodon.git
synced 2025-07-12 15:33:14 +00:00
Compare commits
7 Commits
56f8b67c19
...
d747651b99
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d747651b99 | ||
![]() |
5910d5096d | ||
![]() |
010688a67a | ||
![]() |
c98dfb827b | ||
![]() |
7535ad01d6 | ||
![]() |
53a4a3c8cf | ||
![]() |
39d2f132e8 |
|
@ -21,6 +21,15 @@ module Admin
|
||||||
@action_logs = Admin::ActionLogFilter.new(target_domain: @instance.domain).results.limit(LOGS_LIMIT)
|
@action_logs = Admin::ActionLogFilter.new(target_domain: @instance.domain).results.limit(LOGS_LIMIT)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def availability
|
||||||
|
authorize :instance, :show?
|
||||||
|
end
|
||||||
|
|
||||||
|
def statistics
|
||||||
|
authorize :instance, :show?
|
||||||
|
@time_period = (6.days.ago.to_date...Time.now.utc.to_date)
|
||||||
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
authorize :instance, :destroy?
|
authorize :instance, :destroy?
|
||||||
Admin::DomainPurgeWorker.perform_async(@instance.domain)
|
Admin::DomainPurgeWorker.perform_async(@instance.domain)
|
||||||
|
@ -31,7 +40,7 @@ module Admin
|
||||||
def clear_delivery_errors
|
def clear_delivery_errors
|
||||||
authorize :delivery, :clear_delivery_errors?
|
authorize :delivery, :clear_delivery_errors?
|
||||||
@instance.delivery_failure_tracker.clear_failures!
|
@instance.delivery_failure_tracker.clear_failures!
|
||||||
redirect_to admin_instance_path(@instance.domain)
|
redirect_to availability_admin_instance_path(@instance.domain)
|
||||||
end
|
end
|
||||||
|
|
||||||
def restart_delivery
|
def restart_delivery
|
||||||
|
@ -42,14 +51,14 @@ module Admin
|
||||||
log_action :destroy, @instance.unavailable_domain
|
log_action :destroy, @instance.unavailable_domain
|
||||||
end
|
end
|
||||||
|
|
||||||
redirect_to admin_instance_path(@instance.domain)
|
redirect_to availability_admin_instance_path(@instance.domain)
|
||||||
end
|
end
|
||||||
|
|
||||||
def stop_delivery
|
def stop_delivery
|
||||||
authorize :delivery, :stop_delivery?
|
authorize :delivery, :stop_delivery?
|
||||||
unavailable_domain = UnavailableDomain.create!(domain: @instance.domain)
|
unavailable_domain = UnavailableDomain.create!(domain: @instance.domain)
|
||||||
log_action :create, unavailable_domain
|
log_action :create, unavailable_domain
|
||||||
redirect_to admin_instance_path(@instance.domain)
|
redirect_to availability_admin_instance_path(@instance.domain)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -60,7 +60,7 @@ export default class Dimension extends PureComponent {
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
);
|
);
|
||||||
} else {
|
} else if (data[0].data.length > 0) {
|
||||||
const sum = data[0].data.reduce((sum, cur) => sum + (cur.value * 1), 0);
|
const sum = data[0].data.reduce((sum, cur) => sum + (cur.value * 1), 0);
|
||||||
|
|
||||||
content = (
|
content = (
|
||||||
|
@ -81,6 +81,16 @@ export default class Dimension extends PureComponent {
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
content = (
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr className='dimension__item'>
|
||||||
|
<td>No data available</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -309,6 +309,27 @@ $content-width: 840px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
em {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lead {
|
||||||
|
font-size: 17px;
|
||||||
|
line-height: 22px;
|
||||||
|
color: $secondary-text-color;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $highlight-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p.with-icon {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.fields-group h6 {
|
.fields-group h6 {
|
||||||
color: $primary-text-color;
|
color: $primary-text-color;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
@ -609,6 +630,25 @@ body,
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.simple_form {
|
||||||
|
.actions {
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-group {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
|
&__button--end {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.batch-form-box {
|
.batch-form-box {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
@ -1835,7 +1875,7 @@ a.sparkline {
|
||||||
.availability-indicator {
|
.availability-indicator {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-bottom: 30px;
|
margin-bottom: 20px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 21px;
|
line-height: 21px;
|
||||||
|
|
||||||
|
|
|
@ -62,11 +62,20 @@
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr);
|
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr);
|
||||||
grid-gap: 10px;
|
grid-gap: 10px;
|
||||||
|
align-content: start;
|
||||||
|
|
||||||
@media screen and (width <= 1350px) {
|
@media screen and (width <= 1350px) {
|
||||||
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
|
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__hint {
|
||||||
|
display: flex;
|
||||||
|
gap: 4px;
|
||||||
|
grid-column: span 3;
|
||||||
|
align-items: center;
|
||||||
|
color: $darker-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
&__item {
|
&__item {
|
||||||
&--span-double-column {
|
&--span-double-column {
|
||||||
grid-column: span 2;
|
grid-column: span 2;
|
||||||
|
@ -118,4 +127,8 @@
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&--instance-overview {
|
||||||
|
min-height: 400px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ class DeliveryFailureTracker
|
||||||
include Redisable
|
include Redisable
|
||||||
|
|
||||||
FAILURE_DAYS_THRESHOLD = 7
|
FAILURE_DAYS_THRESHOLD = 7
|
||||||
|
MEASURED_DAYS = 14
|
||||||
|
|
||||||
def initialize(url_or_host)
|
def initialize(url_or_host)
|
||||||
@host = url_or_host.start_with?('https://', 'http://') ? Addressable::URI.parse(url_or_host).normalized_host : url_or_host
|
@host = url_or_host.start_with?('https://', 'http://') ? Addressable::URI.parse(url_or_host).normalized_host : url_or_host
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
%br/
|
%br/
|
||||||
|
|
||||||
= f.object.policies.map { |policy| t(policy, scope: 'admin.instances.content_policies.policies') }.join(' · ')
|
= f.object.policies.map { |policy| t(policy, scope: 'admin.instances.federation_policies.policies') }.join(' · ')
|
||||||
- if f.object.public_comment.present?
|
- if f.object.public_comment.present?
|
||||||
·
|
·
|
||||||
= f.object.public_comment
|
= f.object.public_comment
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
-# locals: (instance_domain:, period_end_at:, period_start_at:)
|
-# locals: (instance_domain:, period_end_at:, period_start_at:)
|
||||||
%p
|
|
||||||
= material_symbol 'info'
|
|
||||||
= t('admin.instances.totals_time_period_hint_html')
|
|
||||||
|
|
||||||
.dashboard
|
.dashboard.dashboard--instance-overview
|
||||||
.dashboard__item
|
.dashboard__item
|
||||||
= react_admin_component :counter,
|
= react_admin_component :counter,
|
||||||
end_at: period_end_at,
|
end_at: period_end_at,
|
||||||
|
@ -48,19 +45,6 @@
|
||||||
measure: 'instance_reports',
|
measure: 'instance_reports',
|
||||||
params: { domain: instance_domain },
|
params: { domain: instance_domain },
|
||||||
start_at: period_start_at
|
start_at: period_start_at
|
||||||
.dashboard__item
|
%p.dashboard__hint
|
||||||
= react_admin_component :dimension,
|
= material_symbol 'info'
|
||||||
dimension: 'instance_accounts',
|
= t('admin.instances.totals_time_period_hint_html')
|
||||||
end_at: period_end_at,
|
|
||||||
label: t('admin.instances.dashboard.instance_accounts_dimension'),
|
|
||||||
limit: 8,
|
|
||||||
params: { domain: instance_domain },
|
|
||||||
start_at: period_start_at
|
|
||||||
.dashboard__item
|
|
||||||
= react_admin_component :dimension,
|
|
||||||
dimension: 'instance_languages',
|
|
||||||
end_at: period_end_at,
|
|
||||||
label: t('admin.instances.dashboard.instance_languages_dimension'),
|
|
||||||
limit: 8,
|
|
||||||
params: { domain: instance_domain },
|
|
||||||
start_at: period_start_at
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
%small
|
%small
|
||||||
- if instance.domain_block
|
- if instance.domain_block
|
||||||
= instance.domain_block.policies.map { |policy| t(policy, scope: 'admin.instances.content_policies.policies') }.join(' · ')
|
= instance.domain_block.policies.map { |policy| t(policy, scope: 'admin.instances.federation_policies.policies') }.join(' · ')
|
||||||
- if instance.domain_block.public_comment.present?
|
- if instance.domain_block.public_comment.present?
|
||||||
%span.comment.public-comment #{t('admin.domain_blocks.public_comment')}: #{instance.domain_block.public_comment}
|
%span.comment.public-comment #{t('admin.domain_blocks.public_comment')}: #{instance.domain_block.public_comment}
|
||||||
- if instance.domain_block.private_comment.present?
|
- if instance.domain_block.private_comment.present?
|
||||||
|
|
47
app/views/admin/instances/availability.html.haml
Normal file
47
app/views/admin/instances/availability.html.haml
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
- content_for :page_title do
|
||||||
|
= @instance.domain
|
||||||
|
|
||||||
|
- content_for :heading do
|
||||||
|
%h2= t('admin.instances.instance.title', domain: @instance.domain)
|
||||||
|
= render partial: 'admin/instances/shared/links', locals: { instance: @instance }
|
||||||
|
|
||||||
|
%p.lead= t('admin.instances.availability.subtitle')
|
||||||
|
|
||||||
|
- if @instance.persisted?
|
||||||
|
%p
|
||||||
|
= t('admin.instances.availability.description_html', count: DeliveryFailureTracker::FAILURE_DAYS_THRESHOLD)
|
||||||
|
= t('admin.instances.availability.period_description', count: DeliveryFailureTracker::MEASURED_DAYS)
|
||||||
|
|
||||||
|
.availability-indicator
|
||||||
|
%ul.availability-indicator__graphic
|
||||||
|
- @instance.availability_over_days(DeliveryFailureTracker::MEASURED_DAYS).each do |(date, failing)|
|
||||||
|
%li.availability-indicator__graphic__item{ class: failing ? 'negative' : 'neutral', title: l(date) }
|
||||||
|
.availability-indicator__hint
|
||||||
|
- if @instance.unavailable?
|
||||||
|
%span.negative-hint
|
||||||
|
= t('admin.instances.availability.failure_threshold_reached', date: l(@instance.unavailable_domain.created_at.to_date))
|
||||||
|
- elsif @instance.exhausted_deliveries_days.empty?
|
||||||
|
%span.positive-hint
|
||||||
|
= t('admin.instances.availability.no_failures_recorded')
|
||||||
|
- else
|
||||||
|
%span.negative-hint
|
||||||
|
= t('admin.instances.availability.failures_recorded', count: @instance.delivery_failure_tracker.days)
|
||||||
|
|
||||||
|
.button-group
|
||||||
|
- if @instance.unavailable?
|
||||||
|
= link_to t('admin.instances.delivery.restart'), restart_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post }, class: 'button'
|
||||||
|
- elsif @instance.exhausted_deliveries_days.empty?
|
||||||
|
= link_to t('admin.instances.delivery.stop'), stop_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post }, class: 'button button--destructive'
|
||||||
|
- else
|
||||||
|
= link_to t('admin.instances.delivery.clear'), clear_delivery_errors_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post }, class: 'button button-secondary' unless @instance.exhausted_deliveries_days.empty?
|
||||||
|
= link_to t('admin.instances.delivery.stop'), stop_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post }, class: 'button button--destructive'
|
||||||
|
|
||||||
|
%hr.spacer
|
||||||
|
|
||||||
|
- if @instance.purgeable?
|
||||||
|
%h3= t('admin.instances.purge_title')
|
||||||
|
%p= t('admin.instances.purge_description_html')
|
||||||
|
|
||||||
|
= link_to t('admin.instances.purge'), admin_instance_path(@instance), data: { confirm: t('admin.instances.confirm_purge'), method: :delete }, class: 'button button--destructive'
|
||||||
|
- else
|
||||||
|
%p= t('admin.instances.availability.unknown_instance')
|
6
app/views/admin/instances/shared/_links.html.haml
Normal file
6
app/views/admin/instances/shared/_links.html.haml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
.content__heading__tabs
|
||||||
|
= render_navigation renderer: :links do |primary|
|
||||||
|
:ruby
|
||||||
|
primary.item :overview, safe_join([material_symbol('cloud'), t('admin.instances.title')]), admin_instance_path(instance)
|
||||||
|
primary.item :statistics, safe_join([material_symbol('trending_up'), t('admin.instances.statistics.title')]), statistics_admin_instance_path(instance)
|
||||||
|
primary.item :availability, safe_join([material_symbol('warning'), t('admin.instances.availability.title')]), availability_admin_instance_path(instance)
|
|
@ -1,6 +1,10 @@
|
||||||
- content_for :page_title do
|
- content_for :page_title do
|
||||||
= @instance.domain
|
= @instance.domain
|
||||||
|
|
||||||
|
- content_for :heading do
|
||||||
|
%h2= t('admin.instances.instance.title', domain: @instance.domain)
|
||||||
|
= render partial: 'admin/instances/shared/links', locals: { instance: @instance }
|
||||||
|
|
||||||
- if current_user.can?(:view_dashboard)
|
- if current_user.can?(:view_dashboard)
|
||||||
- content_for :heading_actions do
|
- content_for :heading_actions do
|
||||||
= date_range(@time_period)
|
= date_range(@time_period)
|
||||||
|
@ -13,34 +17,49 @@
|
||||||
|
|
||||||
%hr.spacer/
|
%hr.spacer/
|
||||||
|
|
||||||
%h3= t('admin.instances.content_policies.title')
|
%h3= t('admin.instances.federation_policies.title')
|
||||||
|
|
||||||
- if limited_federation_mode?
|
- if limited_federation_mode?
|
||||||
%p= t('admin.instances.content_policies.limited_federation_mode_description_html')
|
%p= t('admin.instances.federation_policies.limited_federation_mode_description_html')
|
||||||
|
|
||||||
- if @instance.domain_allow
|
- if @instance.domain_allow
|
||||||
= link_to t('admin.domain_allows.undo'), admin_domain_allow_path(@instance.domain_allow), class: 'button button--destructive', data: { confirm: t('admin.accounts.are_you_sure'), method: :delete }
|
= link_to t('admin.domain_allows.undo'), admin_domain_allow_path(@instance.domain_allow), class: 'button button--destructive', data: { confirm: t('admin.accounts.are_you_sure'), method: :delete }
|
||||||
- else
|
- else
|
||||||
= link_to t('admin.domain_allows.add_new'), admin_domain_allows_path(domain_allow: { domain: @instance.domain }), class: 'button', method: :post
|
= link_to t('admin.domain_allows.add_new'), admin_domain_allows_path(domain_allow: { domain: @instance.domain }), class: 'button', method: :post
|
||||||
- else
|
- else
|
||||||
%p= t('admin.instances.content_policies.description_html')
|
%p= t('admin.instances.federation_policies.description_html')
|
||||||
|
|
||||||
- if @instance.domain_block
|
- if @instance.domain_block
|
||||||
.table-wrapper
|
.table-wrapper
|
||||||
%table.table.horizontal-table
|
%table.table.horizontal-table
|
||||||
|
%thead
|
||||||
|
%tr
|
||||||
|
%th{ width: '28%' }
|
||||||
|
%th
|
||||||
%tbody
|
%tbody
|
||||||
%tr
|
%tr
|
||||||
%th= t('admin.instances.content_policies.comment')
|
%th= t('admin.instances.federation_policies.comment')
|
||||||
%td= @instance.domain_block.private_comment
|
%td
|
||||||
|
- if @instance.domain_block.private_comment.present?
|
||||||
|
= @instance.domain_block.private_comment
|
||||||
|
- else
|
||||||
|
%em= t('admin.instances.federation_policies.no_comment')
|
||||||
%tr
|
%tr
|
||||||
%th= t('admin.instances.content_policies.reason')
|
%th= t('admin.instances.federation_policies.reason')
|
||||||
%td= @instance.domain_block.public_comment
|
%td
|
||||||
|
- if @instance.domain_block.public_comment.present?
|
||||||
|
= @instance.domain_block.public_comment
|
||||||
|
- else
|
||||||
|
%em= t('admin.instances.federation_policies.no_comment')
|
||||||
%tr
|
%tr
|
||||||
%th= t('admin.instances.content_policies.policy')
|
%th= t('admin.instances.federation_policies.policy')
|
||||||
%td= @instance.domain_block.policies.map { |policy| t(policy, scope: 'admin.instances.content_policies.policies') }.join(' · ')
|
%td= @instance.domain_block.policies.map { |policy| t(policy, scope: 'admin.instances.federation_policies.policies') }.join(' · ')
|
||||||
|
|
||||||
|
.button-group
|
||||||
= link_to t('admin.domain_blocks.edit'), edit_admin_domain_block_path(@instance.domain_block), class: 'button'
|
= link_to t('admin.domain_blocks.edit'), edit_admin_domain_block_path(@instance.domain_block), class: 'button'
|
||||||
= link_to t('admin.domain_blocks.undo'), admin_domain_block_path(@instance.domain_block), class: 'button', data: { confirm: t('admin.accounts.are_you_sure'), method: :delete }
|
= link_to t('admin.domain_blocks.undo'), admin_domain_block_path(@instance.domain_block), class: 'button button-secondary', data: { confirm: t('admin.accounts.are_you_sure'), method: :delete }
|
||||||
|
- if @instance.purgeable?
|
||||||
|
= link_to t('admin.instances.federation_policies.purge_data'), admin_instance_path(@instance), data: { confirm: t('admin.instances.confirm_purge'), method: :delete }, class: 'button button-tertiary button--destructive button-group__button--end'
|
||||||
- else
|
- else
|
||||||
= link_to t('admin.domain_blocks.add_new'), new_admin_domain_block_path(_domain: @instance.domain), class: 'button'
|
= link_to t('admin.domain_blocks.add_new'), new_admin_domain_block_path(_domain: @instance.domain), class: 'button'
|
||||||
|
|
||||||
|
@ -48,12 +67,13 @@
|
||||||
%hr.spacer/
|
%hr.spacer/
|
||||||
|
|
||||||
%h3= t('admin.instances.audit_log.title')
|
%h3= t('admin.instances.audit_log.title')
|
||||||
|
%p= t('admin.instances.audit_log.description')
|
||||||
- if @action_logs.empty?
|
- if @action_logs.empty?
|
||||||
%p= t('accounts.nothing_here')
|
%p= t('accounts.nothing_here')
|
||||||
- else
|
- else
|
||||||
.report-notes
|
.report-notes
|
||||||
= render partial: 'admin/action_logs/action_log', collection: @action_logs
|
= render partial: 'admin/action_logs/action_log', collection: @action_logs
|
||||||
= link_to t('admin.instances.audit_log.view_all'), admin_action_logs_path(target_domain: @instance.domain), class: 'button'
|
= link_to t('admin.instances.audit_log.view_all'), admin_action_logs_path(target_domain: @instance.domain), class: 'button button-secondary'
|
||||||
|
|
||||||
%hr.spacer/
|
%hr.spacer/
|
||||||
|
|
||||||
|
@ -71,35 +91,3 @@
|
||||||
|
|
||||||
.actions
|
.actions
|
||||||
= form.button :button, t('admin.instances.moderation_notes.create'), type: :submit
|
= form.button :button, t('admin.instances.moderation_notes.create'), type: :submit
|
||||||
|
|
||||||
- if @instance.persisted?
|
|
||||||
%hr.spacer/
|
|
||||||
|
|
||||||
%h3= t('admin.instances.availability.title')
|
|
||||||
|
|
||||||
%p
|
|
||||||
= t('admin.instances.availability.description_html', count: DeliveryFailureTracker::FAILURE_DAYS_THRESHOLD)
|
|
||||||
|
|
||||||
.availability-indicator
|
|
||||||
%ul.availability-indicator__graphic
|
|
||||||
- @instance.availability_over_days(14).each do |(date, failing)|
|
|
||||||
%li.availability-indicator__graphic__item{ class: failing ? 'negative' : 'neutral', title: l(date) }
|
|
||||||
.availability-indicator__hint
|
|
||||||
- if @instance.unavailable?
|
|
||||||
%span.negative-hint
|
|
||||||
= t('admin.instances.availability.failure_threshold_reached', date: l(@instance.unavailable_domain.created_at.to_date))
|
|
||||||
= link_to t('admin.instances.delivery.restart'), restart_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post }
|
|
||||||
- elsif @instance.exhausted_deliveries_days.empty?
|
|
||||||
%span.positive-hint
|
|
||||||
= t('admin.instances.availability.no_failures_recorded')
|
|
||||||
= link_to t('admin.instances.delivery.stop'), stop_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post }
|
|
||||||
- else
|
|
||||||
%span.negative-hint
|
|
||||||
= t('admin.instances.availability.failures_recorded', count: @instance.delivery_failure_tracker.days)
|
|
||||||
%span= link_to t('admin.instances.delivery.clear'), clear_delivery_errors_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post } unless @instance.exhausted_deliveries_days.empty?
|
|
||||||
%span= link_to t('admin.instances.delivery.stop'), stop_delivery_admin_instance_path(@instance), data: { confirm: t('admin.accounts.are_you_sure'), method: :post }
|
|
||||||
|
|
||||||
- if @instance.purgeable?
|
|
||||||
%p= t('admin.instances.purge_description_html')
|
|
||||||
|
|
||||||
= link_to t('admin.instances.purge'), admin_instance_path(@instance), data: { confirm: t('admin.instances.confirm_purge'), method: :delete }, class: 'button button--destructive'
|
|
||||||
|
|
28
app/views/admin/instances/statistics.html.haml
Normal file
28
app/views/admin/instances/statistics.html.haml
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
- content_for :page_title do
|
||||||
|
= @instance.domain
|
||||||
|
|
||||||
|
- content_for :heading do
|
||||||
|
%h2= t('admin.instances.instance.title', domain: @instance.domain)
|
||||||
|
= render partial: 'admin/instances/shared/links', locals: { instance: @instance }
|
||||||
|
|
||||||
|
- if @instance.persisted?
|
||||||
|
%p.lead= t('admin.instances.statistics.subtitle', domain: @instance.domain)
|
||||||
|
.dashboard
|
||||||
|
.dashboard__item
|
||||||
|
= react_admin_component :dimension,
|
||||||
|
dimension: 'instance_accounts',
|
||||||
|
label: t('admin.instances.dashboard.instance_accounts_dimension'),
|
||||||
|
params: { domain: @instance.domain },
|
||||||
|
start_at: @time_period.first,
|
||||||
|
end_at: @time_period.last,
|
||||||
|
limit: 8
|
||||||
|
.dashboard__item
|
||||||
|
= react_admin_component :dimension,
|
||||||
|
dimension: 'instance_languages',
|
||||||
|
label: t('admin.instances.dashboard.instance_languages_dimension'),
|
||||||
|
params: { domain: @instance.domain },
|
||||||
|
start_at: @time_period.first,
|
||||||
|
end_at: @time_period.last,
|
||||||
|
limit: 8
|
||||||
|
- else
|
||||||
|
%p.lead= t('admin.instances.availability.unknown_instance')
|
|
@ -520,8 +520,9 @@ en:
|
||||||
unsuppress: Restore follow recommendation
|
unsuppress: Restore follow recommendation
|
||||||
instances:
|
instances:
|
||||||
audit_log:
|
audit_log:
|
||||||
title: Recent Audit Logs
|
description: These are the 5 most recent audit log entries relating to this instance.
|
||||||
view_all: View full audit logs
|
title: Audit Logs
|
||||||
|
view_all: View all audit logs
|
||||||
availability:
|
availability:
|
||||||
description_html:
|
description_html:
|
||||||
one: If delivering to the domain fails <strong>%{count} day</strong> without succeeding, no further delivery attempts will be made unless a delivery <em>from</em> the domain is received.
|
one: If delivering to the domain fails <strong>%{count} day</strong> without succeeding, no further delivery attempts will be made unless a delivery <em>from</em> the domain is received.
|
||||||
|
@ -531,25 +532,16 @@ en:
|
||||||
one: Failed attempt on %{count} day.
|
one: Failed attempt on %{count} day.
|
||||||
other: Failed attempts on %{count} different days.
|
other: Failed attempts on %{count} different days.
|
||||||
no_failures_recorded: No failures on record.
|
no_failures_recorded: No failures on record.
|
||||||
|
period_description: The bars shown are for delivery status over the last %{count} days.
|
||||||
|
subtitle: Instance availability measures how successfully we've been able to federate
|
||||||
title: Availability
|
title: Availability
|
||||||
|
unknown_instance: There is no data available for this instance as this server doesn't currently federate with it.
|
||||||
warning: The last attempt to connect to this server has been unsuccessful
|
warning: The last attempt to connect to this server has been unsuccessful
|
||||||
back_to_all: All
|
back_to_all: All
|
||||||
back_to_limited: Limited
|
back_to_limited: Limited
|
||||||
back_to_warning: Warning
|
back_to_warning: Warning
|
||||||
by_domain: Domain
|
by_domain: Domain
|
||||||
confirm_purge: Are you sure you want to permanently delete data from this domain?
|
confirm_purge: Are you sure you want to permanently delete data from this domain?
|
||||||
content_policies:
|
|
||||||
comment: Internal note
|
|
||||||
description_html: You can define content policies that will be applied to all accounts from this domain and any of its subdomains.
|
|
||||||
limited_federation_mode_description_html: You can chose whether to allow federation with this domain.
|
|
||||||
policies:
|
|
||||||
reject_media: Reject media
|
|
||||||
reject_reports: Reject reports
|
|
||||||
silence: Limit
|
|
||||||
suspend: Suspend
|
|
||||||
policy: Policy
|
|
||||||
reason: Public reason
|
|
||||||
title: Content policies
|
|
||||||
dashboard:
|
dashboard:
|
||||||
instance_accounts_dimension: Most followed accounts
|
instance_accounts_dimension: Most followed accounts
|
||||||
instance_accounts_measure: stored accounts
|
instance_accounts_measure: stored accounts
|
||||||
|
@ -571,6 +563,22 @@ en:
|
||||||
delivery_error_hint: If delivery is not possible for %{count} days, it will be automatically marked as undeliverable.
|
delivery_error_hint: If delivery is not possible for %{count} days, it will be automatically marked as undeliverable.
|
||||||
destroyed_msg: Data from %{domain} is now queued for imminent deletion.
|
destroyed_msg: Data from %{domain} is now queued for imminent deletion.
|
||||||
empty: No domains found.
|
empty: No domains found.
|
||||||
|
federation_policies:
|
||||||
|
comment: Private note
|
||||||
|
description_html: You can set a federation policy that will be applied to all accounts from this domain and any of its subdomains.
|
||||||
|
limited_federation_mode_description_html: You can chose whether to allow federation with this domain.
|
||||||
|
no_comment: None
|
||||||
|
policies:
|
||||||
|
reject_media: Reject media
|
||||||
|
reject_reports: Reject reports
|
||||||
|
silence: Limit
|
||||||
|
suspend: Suspend
|
||||||
|
policy: Policy
|
||||||
|
purge_data: Purge Data
|
||||||
|
reason: Public reason
|
||||||
|
title: Federation policy
|
||||||
|
instance:
|
||||||
|
title: Federation with %{domain}
|
||||||
known_accounts:
|
known_accounts:
|
||||||
one: "%{count} known account"
|
one: "%{count} known account"
|
||||||
other: "%{count} known accounts"
|
other: "%{count} known accounts"
|
||||||
|
@ -587,15 +595,19 @@ en:
|
||||||
title: Moderation Notes
|
title: Moderation Notes
|
||||||
private_comment: Private comment
|
private_comment: Private comment
|
||||||
public_comment: Public comment
|
public_comment: Public comment
|
||||||
purge: Purge
|
purge: Purge Data
|
||||||
purge_description_html: If you believe this domain is offline for good, you can delete all account records and associated data from this domain from your storage. This may take a while.
|
purge_description_html: If you believe this domain is offline for good, you can delete all account records and associated data from this domain from your storage. This may take a while.
|
||||||
|
purge_title: Purge Data
|
||||||
|
statistics:
|
||||||
|
subtitle: Below are a few statistics about %{domain}, that you may find interesting.
|
||||||
|
title: Statistics
|
||||||
title: Federation
|
title: Federation
|
||||||
total_blocked_by_us: Blocked by us
|
total_blocked_by_us: Blocked by us
|
||||||
total_followed_by_them: Followed by them
|
total_followed_by_them: Followed by them
|
||||||
total_followed_by_us: Followed by us
|
total_followed_by_us: Followed by us
|
||||||
total_reported: Reports about them
|
total_reported: Reports about them
|
||||||
total_storage: Media attachments
|
total_storage: Media attachments
|
||||||
totals_time_period_hint_html: The totals displayed below include data for all time.
|
totals_time_period_hint_html: The totals displayed above include data for all time.
|
||||||
unknown_instance: There is currently no record of this domain on this server.
|
unknown_instance: There is currently no record of this domain on this server.
|
||||||
invites:
|
invites:
|
||||||
deactivate_all: Deactivate all
|
deactivate_all: Deactivate all
|
||||||
|
|
|
@ -87,6 +87,8 @@ namespace :admin do
|
||||||
|
|
||||||
resources :instances, only: [:index, :show, :destroy], constraints: { id: %r{[^/]+} }, format: 'html' do
|
resources :instances, only: [:index, :show, :destroy], constraints: { id: %r{[^/]+} }, format: 'html' do
|
||||||
member do
|
member do
|
||||||
|
get :availability
|
||||||
|
get :statistics
|
||||||
post :clear_delivery_errors
|
post :clear_delivery_errors
|
||||||
post :restart_delivery
|
post :restart_delivery
|
||||||
post :stop_delivery
|
post :stop_delivery
|
||||||
|
|
Loading…
Reference in New Issue
Block a user