Merge branch 'main' into glitch-soc/merge-upstream

This commit is contained in:
Claire
2021-04-05 14:31:07 +02:00
21 changed files with 191 additions and 47 deletions

View File

@@ -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

View File

@@ -0,0 +1,7 @@
# frozen_string_literal: true
class HealthController < ActionController::Base
def show
render plain: 'OK'
end
end

View File

@@ -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);
}
}
}

View File

@@ -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;

View File

@@ -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

View File

@@ -0,0 +1,11 @@
# frozen_string_literal: true
class Admin::SystemCheck::BaseCheck
def pass?
raise NotImplementedError
end
def message
raise NotImplementedError
end
end

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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')

View File

@@ -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')