discourse/lib/admin_dashboard/reports/registry.rb
Osama Sayegh 08fdf23a07
DEV: Scaffold backend for the new admin dashboard Reports section (#40017)
Adds the backend for the customisable Reports section on the new admin
dashboard, gated by `dashboard_improvements`.

- `admin_dashboard_reports` table + AR model for pinned reports.
- Plugin-extension contract via
  `Plugin::Instance#register_admin_dashboard_report_source` and the
  `AdminDashboard::Reports::SourceProvider` base class. Core ships a
  built-in provider; `discourse-data-explorer` registers its own.
- `AdminDashboard::Reports::Section` builds the `reports` entry in the
  dashboard's `sections` payload; `AdminDashboard::Reports::BulkFetch`
  powers the bulk endpoint. Both share a
  `Registry.dispatch_per_source` helper that batches work by source.
- `POST /admin/dashboard/reports/bulk` fetches data for multiple
  mounted reports in one round trip, batched by source.
- Defaults are seeded via core + plugin fixtures (Daily engaged users,
  Time to first response; `accepted_solutions` when Solved is in use).

Next: list-available and save-layout endpoints for the Manage Reports
modal, plus the frontend (section UI, modal, bulk loader).
2026-05-20 09:53:26 +03:00

28 lines
722 B
Ruby
Vendored

# frozen_string_literal: true
module AdminDashboard
module Reports
class Registry
CORE_PROVIDERS = [CoreReportProvider].freeze
def self.providers
CORE_PROVIDERS + DiscoursePluginRegistry.admin_dashboard_report_sources
end
def self.provider_for(source_name)
providers.find { |klass| klass.source_name.to_s == source_name.to_s }
end
def self.dispatch_per_source(items)
items
.group_by { |item| item[:source] }
.each_with_object({}) do |(source, group), result|
provider = provider_for(source)
next if provider.nil?
result[source] = yield(provider, group)
end
end
end
end
end