0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-06 00:15:24 +08:00
discourse/app/services/upcoming_changes/list.rb
Martin Brennan 2e30f331be
DEV: Show depends_on site settings for upcoming changes (#41646)
Sometimes for upcoming changes we need to tell the admin about
some settings that must be enabled for the change to take effect.
Currently the only way to do this is with a note in the change
description which is not ideal.

This commit introduces a way to display the depends_on settings
for the upcoming change in the admin upcoming changes page. The
warning only shows if any of the settings are not enabled, if all
dependencies are satisfied we do not show the warning to the admin.

There is a link to each setting from the upcoming changes list
to make it easy for the admin to enable the setting if needed.

<img width="1280" height="720" alt="image"
src="https://github.com/user-attachments/assets/724762a9-cc40-45b4-b080-d6ee87dc57ca"
/>
2026-07-14 09:29:47 +10:00

108 lines
3.2 KiB
Ruby
Vendored

# frozen_string_literal: true
class UpcomingChanges::List
include Service::Base
options { attribute :filter_statuses, :array, default: [] }
policy :current_user_is_admin
model :upcoming_changes, optional: true
step :load_upcoming_change_groups
step :sort_changes
step :update_last_visited
private
def current_user_is_admin(guardian:)
guardian.is_admin?
end
def fetch_upcoming_changes(options:)
SiteSetting
.all_settings(
only_upcoming_changes: true,
include_hidden: true,
include_locale_setting: false,
)
.select do |setting|
if options.filter_statuses.any?
options
.filter_statuses
.map(&:to_sym)
.include?(UpcomingChanges.change_status(setting[:setting]))
else
true
end
end
.select { |setting| UpcomingChanges::ConditionalDisplay.should_display?(setting[:setting]) }
.each do |setting|
setting[:value] = setting[:value] == "true"
if UpcomingChanges.image_exists?(setting[:setting])
setting[:upcoming_change][:image] = UpcomingChanges.image_data(setting[:setting])
end
if setting[:plugin]
plugin = Discourse.plugins_by_name[setting[:plugin]]
# NOTE (martin) Maybe later we add a URL or something? Not sure.
# Then the plugin name could be clicked in the UI
setting[:plugin] = plugin.humanized_name
end
end
.map do |setting|
# We don't need to return all the other setting metadata for
# endpoints that use this.
setting.slice(
:setting,
:humanized_name,
:description,
:value,
:upcoming_change,
:plugin,
:depends_on,
:depends_on_humanized_names,
).merge(
dependents: UpcomingChanges.find_dependents_for_change(setting[:setting]),
depends_on_met: UpcomingChanges.change_dependencies_met?(setting[:setting]),
overriding_defaults:
SiteSetting.upcoming_change_default_overrides.values.any? do |override|
override[:upcoming_change] == setting[:setting]
end,
)
end
end
def load_upcoming_change_groups(upcoming_changes:)
group_ids =
(
upcoming_changes.flat_map do |change|
SiteSetting.site_setting_group_ids[change[:setting]]
end + [Group::AUTO_GROUPS[:staff]]
).compact.uniq
groups = Group.where(id: group_ids).pluck(:id, :name).to_h
upcoming_changes.each do |setting|
enabled_for, setting_groups =
UpcomingChanges.enabled_for_with_groups(
setting[:setting],
setting[:value],
groups,
).values_at(:enabled_for, :setting_groups)
setting[:upcoming_change][:enabled_for] = enabled_for
setting[:groups] = setting_groups
end
end
def sort_changes(upcoming_changes:)
context[:upcoming_changes] = upcoming_changes.sort_by { |change| change[:setting] }
end
def update_last_visited(guardian:)
return if guardian.user.is_system_user? || guardian.user.bot?
guardian.user.custom_fields["last_visited_upcoming_changes_at"] = Time.current.iso8601
guardian.user.save_custom_fields
end
end