0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-06 13:08:40 +08:00
discourse/app/services/categories/unconfigure.rb
Kris ad87713821
FEATURE: add API for custom composer actions, new "event" composer action (#40203)
This creates a new API method, `addComposerAction`, which is used to add
a new "Create Event" action that's available in event category types
(enabled by the upcoming change `events category type setup`).

When creating a new topic in an events category, the composer will use
the "Create Event" action by default which automatically enters the
BBCode to create a new event.

Frontend core changes: 
* `composer-actions.js` - exports `registerComposerAction` and
`_clearRegisteredActions`, merges the actions into the dropdown, and the
selection routes to `opts.action()`
* `models/composer.js` - `titlePlaceholder` checks
`customizationFor("titlePlaceholder")` to apply a custom title
placeholder based on category
* `services/composer.js` - `saveIcon` checks
`customizationFor("saveIcon")` which is also based on category

Backend core changes: 
* `category_types` is moved from `CategorySerializer` to
`SiteCategorySerializer` because the composer gets category info from
`Site.categories`
* `Categories::Configure` and `Categories::Unconfigure` run
`Site.clear_cache` so category type changes happen immediately, they
were being cached for 30 minutes otherwise

Calendar and events plugin: 
* Initializer adds the event action type
* Inserts BBCode placeholder for events when selecting the event action
or switching to the events category in the composer (default action
type)
* Observes the content of the topic so we can switch action type when an
event is added or removed

The one piece I've saved for a later change is changing the action icon
in the composer... it's a bit wonky to do this in select-kit right now
(requires an observer as far as I can tell because it's not tracked) and
there's a PR that's switching the menu to DMenu
(https://github.com/discourse/discourse/pull/38068), which makes it
significantly easier

<img width="1000" alt="image"
src="https://github.com/user-attachments/assets/273d1ab9-e319-4a8f-91d5-d1c0227f3e6a"
/>
2026-05-28 09:56:34 -04:00

65 lines
1.5 KiB
Ruby
Vendored

# frozen_string_literal: true
module Categories
class Unconfigure
include Service::Base
params do
attribute :category_id, :integer
attribute :category_type, :string
validates :category_id, presence: true
validates :category_type, presence: true
validate :category_type_is_valid
def category_type_is_valid
return if category_type.blank?
return if Categories::TypeRegistry.valid?(category_type)
errors.add(:category_type, :invalid)
end
end
model :category
policy :can_modify_category
model :type_class
step :unconfigure_category
step :log_action
step :clear_category_type_counts_cache
step :clear_site_cache
private
def fetch_category(params:)
Category.find_by(id: params.category_id)
end
def can_modify_category(guardian:, category:)
guardian.can_edit_category?(category)
end
def fetch_type_class(params:)
Categories::TypeRegistry.get(params.category_type)
end
def unconfigure_category(type_class:, category:, guardian:)
type_class.unconfigure_category(category, guardian:)
end
def log_action(guardian:, category:, params:)
StaffActionLogger.new(guardian.user).log_custom(
"unconfigure_category_type",
{ category_id: category.id, category_type: params.category_type },
)
end
def clear_category_type_counts_cache
Discourse.cache.delete(Categories::TypeRegistry::COUNTS_CACHE_KEY)
end
def clear_site_cache
Site.clear_cache
end
end
end