diff --git a/app/assets/javascripts/admin/addon/models/web-hook.js b/app/assets/javascripts/admin/addon/models/web-hook.js index f540d05dc30..bfdab735c7a 100644 --- a/app/assets/javascripts/admin/addon/models/web-hook.js +++ b/app/assets/javascripts/admin/addon/models/web-hook.js @@ -1,13 +1,36 @@ +import { tracked } from "@glimmer/tracking"; import { computed } from "@ember/object"; import { isEmpty } from "@ember/utils"; import { observes } from "@ember-decorators/object"; -import Category from "discourse/models/category"; import Group from "discourse/models/group"; import RestModel from "discourse/models/rest"; import Site from "discourse/models/site"; import discourseComputed from "discourse-common/utils/decorators"; +class WebHookExtras { + @tracked categories; + + constructor(args) { + this.categories = args.categories; + this.content_types = args.content_types; + this.default_event_types = args.default_event_types; + this.delivery_statuses = args.delivery_statuses; + this.grouped_event_types = args.grouped_event_types; + } + + get categoriesById() { + if (this.categories) { + return new Map(this.categories.map((c) => [c.id, c])); + } + } + + findCategoryById(id) { + return this.categoriesById?.get(id); + } +} + export default class WebHook extends RestModel { + static ExtrasClass = WebHookExtras; content_type = 1; // json last_delivery_status = 1; // inactive wildcard_web_hook = false; @@ -27,7 +50,9 @@ export default class WebHook extends RestModel { @computed("category_ids") get categories() { - return Category.findByIds(this.category_ids); + return (this.category_ids || []).map((id) => + this.extras.findCategoryById(id) + ); } set categories(value) { diff --git a/app/assets/javascripts/discourse/app/services/store.js b/app/assets/javascripts/discourse/app/services/store.js index 1b7f3c828cf..8c3e6507594 100644 --- a/app/assets/javascripts/discourse/app/services/store.js +++ b/app/assets/javascripts/discourse/app/services/store.js @@ -126,7 +126,14 @@ export default class StoreService extends Service { let hydrated = this._hydrateFindResults(result, type, findArgs, opts); if (result.extras) { - hydrated.set("extras", result.extras); + let extras = result.extras; + + const extrasClass = this._extrasClass(type); + if (extrasClass) { + extras = new extrasClass(extras); + } + + hydrated.set("extras", extras); } if (adapter.cache) { @@ -260,12 +267,28 @@ export default class StoreService extends Service { }; if (result.extras) { - createArgs.extras = result.extras; + let extras = result.extras; + + const extrasClass = this._extrasClass(type); + if (extrasClass) { + extras = new extrasClass(extras); + } + + createArgs.extras = extras; + + for (const obj of content) { + obj.extras = extras; + } } return ResultSet.create(createArgs); } + _extrasClass(type) { + const klass = this.register.lookupFactory("model:" + type) || RestModel; + return klass.class?.ExtrasClass; + } + _build(type, obj) { const adapter = this.adapterFor(type); obj.store = this; diff --git a/app/assets/javascripts/discourse/tests/acceptance/admin-webhooks-test.js b/app/assets/javascripts/discourse/tests/acceptance/admin-webhooks-test.js index 6685f3ad654..0a35407a772 100644 --- a/app/assets/javascripts/discourse/tests/acceptance/admin-webhooks-test.js +++ b/app/assets/javascripts/discourse/tests/acceptance/admin-webhooks-test.js @@ -16,6 +16,7 @@ acceptance("Admin - Webhooks", function (needs) { total_rows_web_hooks: 0, load_more_web_hooks: "/admin/api/web_hooks.json?limit=50&offset=50", extras: { + categories: [], content_types: [ { id: 1, name: "application/json" }, { id: 2, name: "application/x-www-form-urlencoded" }, diff --git a/app/controllers/admin/web_hooks_controller.rb b/app/controllers/admin/web_hooks_controller.rb index bb5e283cc67..eeb489d663f 100644 --- a/app/controllers/admin/web_hooks_controller.rb +++ b/app/controllers/admin/web_hooks_controller.rb @@ -15,15 +15,18 @@ class Admin::WebHooksController < Admin::AdminController .includes(:categories) .includes(:groups) + data = serialize_data(web_hooks, AdminWebHookSerializer, root: "web_hooks") + json = { - web_hooks: serialize_data(web_hooks, AdminWebHookSerializer), - extras: { - grouped_event_types: WebHookEventType.active_grouped, - default_event_types: WebHook.default_event_types, - content_types: WebHook.content_types.map { |name, id| { id: id, name: name } }, - delivery_statuses: - WebHook.last_delivery_statuses.map { |name, id| { id: id, name: name.to_s } }, - }, + web_hooks: data.delete("web_hooks"), + extras: + data.merge( + grouped_event_types: WebHookEventType.active_grouped, + default_event_types: WebHook.default_event_types, + content_types: WebHook.content_types.map { |name, id| { id: id, name: name } }, + delivery_statuses: + WebHook.last_delivery_statuses.map { |name, id| { id: id, name: name.to_s } }, + ), total_rows_web_hooks: WebHook.count, load_more_web_hooks: admin_web_hooks_path(limit: limit, offset: offset + limit, format: :json), @@ -33,11 +36,16 @@ class Admin::WebHooksController < Admin::AdminController end def show - render_serialized(@web_hook, AdminWebHookSerializer, root: "web_hook") + data = serialize_data(@web_hook, AdminWebHookSerializer, root: "web_hook") + web_hook = data.delete("web_hook") + data = { "extras" => data, "web_hook" => web_hook } + render json: MultiJson.dump(data), status: 200 end def edit - render_serialized(@web_hook, AdminWebHookSerializer, root: "web_hook") + data = serialize_data(@web_hook, AdminWebHookSerializer, root: "web_hook") + data["extras"] = { "categories" => data.delete(:categories) } + render json: MultiJson.dump(data), status: 200 end def create diff --git a/app/serializers/admin_web_hook_serializer.rb b/app/serializers/admin_web_hook_serializer.rb index 1fa79e384e9..fd7441ed964 100644 --- a/app/serializers/admin_web_hook_serializer.rb +++ b/app/serializers/admin_web_hook_serializer.rb @@ -11,7 +11,7 @@ class AdminWebHookSerializer < ApplicationSerializer :active, :web_hook_event_types - has_many :categories, serializer: BasicCategorySerializer, embed: :ids, include: false + has_many :categories, serializer: BasicCategorySerializer, embed: :ids, include: true has_many :tags, key: :tag_names, serializer: TagSerializer,