diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/controllers/admin/dashboard_controller.rb | 7 | ||||
-rw-r--r-- | app/controllers/health_controller.rb | 7 | ||||
-rw-r--r-- | app/javascript/flavours/glitch/features/ui/components/columns_area.js | 12 | ||||
-rw-r--r-- | app/javascript/flavours/glitch/styles/forms.scss | 42 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/columns_area.js | 12 | ||||
-rw-r--r-- | app/javascript/styles/mastodon/forms.scss | 42 | ||||
-rw-r--r-- | app/lib/admin/system_check.rb | 21 | ||||
-rw-r--r-- | app/lib/admin/system_check/base_check.rb | 11 | ||||
-rw-r--r-- | app/lib/admin/system_check/database_schema_check.rb | 11 | ||||
-rw-r--r-- | app/lib/admin/system_check/message.rb | 11 | ||||
-rw-r--r-- | app/lib/admin/system_check/rules_check.rb | 13 | ||||
-rw-r--r-- | app/lib/admin/system_check/sidekiq_process_check.rb | 26 | ||||
-rw-r--r-- | app/views/admin/dashboard/index.html.haml | 8 | ||||
-rwxr-xr-x | app/views/layouts/application.html.haml | 4 | ||||
-rw-r--r-- | app/views/layouts/embedded.html.haml | 2 |
15 files changed, 216 insertions, 13 deletions
diff --git a/app/controllers/admin/dashboard_controller.rb b/app/controllers/admin/dashboard_controller.rb index e87dd076f..9e921fb95 100644 --- a/app/controllers/admin/dashboard_controller.rb +++ b/app/controllers/admin/dashboard_controller.rb @@ -3,13 +3,8 @@ require 'sidekiq/api' module Admin class DashboardController < BaseController - SIDEKIQ_QUEUES = %w(default push mailers pull scheduler).freeze - def index - missing_queues = Sidekiq::ProcessSet.new.reduce(SIDEKIQ_QUEUES) { |queues, process| queues - process['queues'] } - - flash.now[:alert] = I18n.t('admin.dashboard.misconfigured_sidekiq_alert', queues: missing_queues.join(', ')) unless missing_queues.empty? - + @system_checks = Admin::SystemCheck.perform @users_count = User.count @pending_users_count = User.pending.count @registrations_week = Redis.current.get("activity:accounts:local:#{current_week}") || 0 diff --git a/app/controllers/health_controller.rb b/app/controllers/health_controller.rb new file mode 100644 index 000000000..2a22a0557 --- /dev/null +++ b/app/controllers/health_controller.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class HealthController < ActionController::Base + def show + render plain: 'OK' + end +end diff --git a/app/javascript/flavours/glitch/features/ui/components/columns_area.js b/app/javascript/flavours/glitch/features/ui/components/columns_area.js index b41de58d7..4ea7b48fe 100644 --- a/app/javascript/flavours/glitch/features/ui/components/columns_area.js +++ b/app/javascript/flavours/glitch/features/ui/components/columns_area.js @@ -90,7 +90,11 @@ class ColumnsArea extends ImmutablePureComponent { } if (this.mediaQuery) { - this.mediaQuery.addEventListener('change', this.handleLayoutChange); + if (this.mediaQuery.addEventListener) { + this.mediaQuery.addEventListener('change', this.handleLayoutChange); + } else { + this.mediaQuery.addListener(this.handleLayoutChange); + } this.setState({ renderComposePanel: !this.mediaQuery.matches }); } @@ -125,7 +129,11 @@ class ColumnsArea extends ImmutablePureComponent { } if (this.mediaQuery) { - this.mediaQuery.removeEventListener('change', this.handleLayoutChange); + if (this.mediaQuery.removeEventListener) { + this.mediaQuery.removeEventListener('change', this.handleLayoutChange); + } else { + this.mediaQuery.removeListener(this.handleLayouteChange); + } } } diff --git a/app/javascript/flavours/glitch/styles/forms.scss b/app/javascript/flavours/glitch/styles/forms.scss index a65ef4454..b93acd6cd 100644 --- a/app/javascript/flavours/glitch/styles/forms.scss +++ b/app/javascript/flavours/glitch/styles/forms.scss @@ -595,6 +595,12 @@ code { color: $valid-value-color; } + &.warning { + border: 1px solid rgba($gold-star, 0.5); + background: rgba($gold-star, 0.25); + color: $gold-star; + } + &.alert { border: 1px solid rgba($error-value-color, 0.5); background: rgba($error-value-color, 0.1); @@ -616,6 +622,19 @@ code { } } + &.warning a { + font-weight: 700; + color: inherit; + text-decoration: underline; + + &:hover, + &:focus, + &:active { + text-decoration: none; + color: inherit; + } + } + p { margin-bottom: 15px; } @@ -672,6 +691,29 @@ code { } } +.flash-message-stack { + margin-bottom: 30px; + + .flash-message { + border-radius: 0; + margin-bottom: 0; + border-top-width: 0; + + &:first-child { + border-radius: 4px 4px 0 0; + border-top-width: 1px; + } + + &:last-child { + border-radius: 0 0 4px 4px; + + &:first-child { + border-radius: 4px; + } + } + } +} + .form-footer { margin-top: 30px; text-align: center; diff --git a/app/javascript/mastodon/features/ui/components/columns_area.js b/app/javascript/mastodon/features/ui/components/columns_area.js index 85a92fc3a..270be2851 100644 --- a/app/javascript/mastodon/features/ui/components/columns_area.js +++ b/app/javascript/mastodon/features/ui/components/columns_area.js @@ -90,7 +90,11 @@ class ColumnsArea extends ImmutablePureComponent { } if (this.mediaQuery) { - this.mediaQuery.addEventListener('change', this.handleLayoutChange); + if (this.mediaQuery.addEventListener) { + this.mediaQuery.addEventListener('change', this.handleLayoutChange); + } else { + this.mediaQuery.addListener(this.handleLayoutChange); + } this.setState({ renderComposePanel: !this.mediaQuery.matches }); } @@ -125,7 +129,11 @@ class ColumnsArea extends ImmutablePureComponent { } if (this.mediaQuery) { - this.mediaQuery.removeEventListener('change', this.handleLayoutChange); + if (this.mediaQuery.removeEventListener) { + this.mediaQuery.removeEventListener('change', this.handleLayoutChange); + } else { + this.mediaQuery.removeListener(this.handleLayouteChange); + } } } diff --git a/app/javascript/styles/mastodon/forms.scss b/app/javascript/styles/mastodon/forms.scss index e0604303b..ef4a08c59 100644 --- a/app/javascript/styles/mastodon/forms.scss +++ b/app/javascript/styles/mastodon/forms.scss @@ -604,6 +604,12 @@ code { color: $valid-value-color; } + &.warning { + border: 1px solid rgba($gold-star, 0.5); + background: rgba($gold-star, 0.25); + color: $gold-star; + } + &.alert { border: 1px solid rgba($error-value-color, 0.5); background: rgba($error-value-color, 0.1); @@ -625,6 +631,19 @@ code { } } + &.warning a { + font-weight: 700; + color: inherit; + text-decoration: underline; + + &:hover, + &:focus, + &:active { + text-decoration: none; + color: inherit; + } + } + p { margin-bottom: 15px; } @@ -681,6 +700,29 @@ code { } } +.flash-message-stack { + margin-bottom: 30px; + + .flash-message { + border-radius: 0; + margin-bottom: 0; + border-top-width: 0; + + &:first-child { + border-radius: 4px 4px 0 0; + border-top-width: 1px; + } + + &:last-child { + border-radius: 0 0 4px 4px; + + &:first-child { + border-radius: 4px; + } + } + } +} + .form-footer { margin-top: 30px; text-align: center; diff --git a/app/lib/admin/system_check.rb b/app/lib/admin/system_check.rb new file mode 100644 index 000000000..afb20cb47 --- /dev/null +++ b/app/lib/admin/system_check.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class Admin::SystemCheck + ACTIVE_CHECKS = [ + Admin::SystemCheck::DatabaseSchemaCheck, + Admin::SystemCheck::SidekiqProcessCheck, + Admin::SystemCheck::RulesCheck, + ].freeze + + def self.perform + ACTIVE_CHECKS.each_with_object([]) do |klass, arr| + check = klass.new + + if check.pass? + arr + else + arr << check.message + end + end + end +end diff --git a/app/lib/admin/system_check/base_check.rb b/app/lib/admin/system_check/base_check.rb new file mode 100644 index 000000000..fcad8daca --- /dev/null +++ b/app/lib/admin/system_check/base_check.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class Admin::SystemCheck::BaseCheck + def pass? + raise NotImplementedError + end + + def message + raise NotImplementedError + end +end diff --git a/app/lib/admin/system_check/database_schema_check.rb b/app/lib/admin/system_check/database_schema_check.rb new file mode 100644 index 000000000..b93d1954e --- /dev/null +++ b/app/lib/admin/system_check/database_schema_check.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class Admin::SystemCheck::DatabaseSchemaCheck < Admin::SystemCheck::BaseCheck + def pass? + !ActiveRecord::Base.connection.migration_context.needs_migration? + end + + def message + Admin::SystemCheck::Message.new(:database_schema_check) + end +end diff --git a/app/lib/admin/system_check/message.rb b/app/lib/admin/system_check/message.rb new file mode 100644 index 000000000..bfcad3bf3 --- /dev/null +++ b/app/lib/admin/system_check/message.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class Admin::SystemCheck::Message + attr_reader :key, :value, :action + + def initialize(key, value = nil, action = nil) + @key = key + @value = value + @action = action + end +end diff --git a/app/lib/admin/system_check/rules_check.rb b/app/lib/admin/system_check/rules_check.rb new file mode 100644 index 000000000..1fbdf955d --- /dev/null +++ b/app/lib/admin/system_check/rules_check.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class Admin::SystemCheck::RulesCheck < Admin::SystemCheck::BaseCheck + include RoutingHelper + + def pass? + Rule.kept.exists? + end + + def message + Admin::SystemCheck::Message.new(:rules_check, nil, admin_rules_path) + end +end diff --git a/app/lib/admin/system_check/sidekiq_process_check.rb b/app/lib/admin/system_check/sidekiq_process_check.rb new file mode 100644 index 000000000..c44d86c44 --- /dev/null +++ b/app/lib/admin/system_check/sidekiq_process_check.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +class Admin::SystemCheck::SidekiqProcessCheck < Admin::SystemCheck::BaseCheck + SIDEKIQ_QUEUES = %w( + default + push + mailers + pull + scheduler + ingress + ).freeze + + def pass? + missing_queues.empty? + end + + def message + Admin::SystemCheck::Message.new(:sidekiq_process_check, missing_queues.join(', ')) + end + + private + + def missing_queues + @missing_queues ||= Sidekiq::ProcessSet.new.reduce(SIDEKIQ_QUEUES) { |queues, process| queues - process['queues'] } + end +end diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml index 249e12563..f2f0c813d 100644 --- a/app/views/admin/dashboard/index.html.haml +++ b/app/views/admin/dashboard/index.html.haml @@ -1,6 +1,14 @@ - content_for :page_title do = t('admin.dashboard.title') +- unless @system_checks.empty? + .flash-message-stack + - @system_checks.each do |message| + .flash-message.warning + = t("admin.system_checks.#{message.key}.message_html", message.value ? { value: content_tag(:strong, message.value) } : {}) + - if message.action + = link_to t("admin.system_checks.#{message.key}.action"), message.action + .dashboard__counters %div = link_to admin_accounts_url(local: 1, recent: 1) do diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 3daaf93a9..09826afb3 100755 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -45,5 +45,5 @@ = content_for?(:content) ? yield(:content) : yield .logo-resources - = render file: Rails.root.join('app', 'javascript', 'images', 'logo_transparent.svg') - = render file: Rails.root.join('app', 'javascript', 'images', 'logo_full.svg') + = raw render file: Rails.root.join('app', 'javascript', 'images', 'logo_transparent.svg') + = raw render file: Rails.root.join('app', 'javascript', 'images', 'logo_full.svg') diff --git a/app/views/layouts/embedded.html.haml b/app/views/layouts/embedded.html.haml index 431bd260c..2a2996d28 100644 --- a/app/views/layouts/embedded.html.haml +++ b/app/views/layouts/embedded.html.haml @@ -25,4 +25,4 @@ = yield .logo-resources - = render file: Rails.root.join('app', 'javascript', 'images', 'logo_transparent.svg') + = raw render file: Rails.root.join('app', 'javascript', 'images', 'logo_transparent.svg') |