diff --git a/app/assets/javascripts/admin/addon/templates/web-hooks-show-events.hbs b/app/assets/javascripts/admin/addon/components/webhook-events.hbs similarity index 57% rename from app/assets/javascripts/admin/addon/templates/web-hooks-show-events.hbs rename to app/assets/javascripts/admin/addon/components/webhook-events.hbs index c9791f0fc4f..927a6309fc4 100644 --- a/app/assets/javascripts/admin/addon/templates/web-hooks-show-events.hbs +++ b/app/assets/javascripts/admin/addon/components/webhook-events.hbs @@ -1,16 +1,17 @@ -
{{i18n "admin.web_hooks.events.none"}}
diff --git a/app/assets/javascripts/admin/addon/components/webhook-events.js b/app/assets/javascripts/admin/addon/components/webhook-events.js new file mode 100644 index 00000000000..a3559af8cc4 --- /dev/null +++ b/app/assets/javascripts/admin/addon/components/webhook-events.js @@ -0,0 +1,89 @@ +import Component from "@glimmer/component"; +import { inject as service } from "@ember/service"; +import { tracked } from "@glimmer/tracking"; +import { action } from "@ember/object"; +import { ajax } from "discourse/lib/ajax"; +import { gt, readOnly } from "@ember/object/computed"; +import { bind } from "discourse-common/utils/decorators"; +import { popupAjaxError } from "discourse/lib/ajax-error"; + +export default class WebhookEvents extends Component { + @service messageBus; + @service store; + + @tracked pingEnabled = true; + @tracked events = []; + @tracked incomingEventIds = []; + + @readOnly("incomingEventIds.length") incomingCount; + @gt("incomingCount", 0) hasIncoming; + + constructor() { + super(...arguments); + this.loadEvents(); + } + + async loadEvents() { + this.events = await this.store.findAll( + "web-hook-event", + this.args.webhookId + ); + } + + @bind + subscribe() { + const channel = `/web_hook_events/${this.args.webhookId}`; + this.messageBus.subscribe(channel, this._addIncoming); + } + + @bind + unsubscribe() { + this.messageBus.unsubscribe("/web_hook_events/*", this._addIncoming); + } + + @bind + _addIncoming(data) { + if (data.event_type === "ping") { + this.pingEnabled = true; + } + + if (!this.incomingEventIds.includes(data.web_hook_event_id)) { + this.incomingEventIds.pushObject(data.web_hook_event_id); + } + } + + @action + async showInserted(event) { + event?.preventDefault(); + + const path = `/admin/api/web_hooks/${this.args.webhookId}/events/bulk`; + const data = await ajax(path, { + data: { ids: this.incomingEventIds }, + }); + + const objects = data.map((webHookEvent) => + this.store.createRecord("web-hook-event", webHookEvent) + ); + this.events.unshiftObjects(objects); + this.incomingEventIds = []; + } + + @action + loadMore() { + this.events.loadMore(); + } + + @action + async ping() { + this.pingEnabled = false; + + try { + await ajax(`/admin/api/web_hooks/${this.args.webhookId}/ping`, { + type: "POST", + }); + } catch (error) { + this.pingEnabled = true; + popupAjaxError(error); + } + } +} diff --git a/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-edit.js b/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-edit.js new file mode 100644 index 00000000000..f24dfef939e --- /dev/null +++ b/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-edit.js @@ -0,0 +1,101 @@ +import Controller, { inject as controller } from "@ember/controller"; +import EmberObject, { action } from "@ember/object"; +import I18n from "I18n"; +import { alias } from "@ember/object/computed"; +import discourseComputed from "discourse-common/utils/decorators"; +import { isEmpty } from "@ember/utils"; +import { popupAjaxError } from "discourse/lib/ajax-error"; +import { inject as service } from "@ember/service"; + +export default Controller.extend({ + adminWebHooks: controller(), + dialog: service(), + eventTypes: alias("adminWebHooks.eventTypes"), + defaultEventTypes: alias("adminWebHooks.defaultEventTypes"), + contentTypes: alias("adminWebHooks.contentTypes"), + + @discourseComputed + showTagsFilter() { + return this.siteSettings.tagging_enabled; + }, + + @discourseComputed("model.isSaving", "saved", "saveButtonDisabled") + savingStatus(isSaving, saved, saveButtonDisabled) { + if (isSaving) { + return I18n.t("saving"); + } else if (!saveButtonDisabled && saved) { + return I18n.t("saved"); + } + // Use side effect of validation to clear saved text + this.set("saved", false); + return ""; + }, + + @discourseComputed("model.isNew") + saveButtonText(isNew) { + return isNew + ? I18n.t("admin.web_hooks.create") + : I18n.t("admin.web_hooks.save"); + }, + + @discourseComputed("model.secret") + secretValidation(secret) { + if (!isEmpty(secret)) { + if (secret.includes(" ")) { + return EmberObject.create({ + failed: true, + reason: I18n.t("admin.web_hooks.secret_invalid"), + }); + } + + if (secret.length < 12) { + return EmberObject.create({ + failed: true, + reason: I18n.t("admin.web_hooks.secret_too_short"), + }); + } + } + }, + + @discourseComputed("model.wildcard_web_hook", "model.web_hook_event_types.[]") + eventTypeValidation(isWildcard, eventTypes) { + if (!isWildcard && isEmpty(eventTypes)) { + return EmberObject.create({ + failed: true, + reason: I18n.t("admin.web_hooks.event_type_missing"), + }); + } + }, + + @discourseComputed( + "model.isSaving", + "secretValidation", + "eventTypeValidation", + "model.payload_url" + ) + saveButtonDisabled( + isSaving, + secretValidation, + eventTypeValidation, + payloadUrl + ) { + return isSaving + ? false + : secretValidation || eventTypeValidation || isEmpty(payloadUrl); + }, + + @action + async save() { + this.set("saved", false); + + try { + await this.model.save(); + + this.set("saved", true); + this.adminWebHooks.model.addObject(this.model); + this.transitionToRoute("adminWebHooks.show", this.model); + } catch (e) { + popupAjaxError(e); + } + }, +}); diff --git a/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-index.js b/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-index.js new file mode 100644 index 00000000000..a1294cf09d7 --- /dev/null +++ b/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-index.js @@ -0,0 +1,36 @@ +import Controller, { inject as controller } from "@ember/controller"; +import I18n from "I18n"; +import { popupAjaxError } from "discourse/lib/ajax-error"; +import { inject as service } from "@ember/service"; +import { action } from "@ember/object"; +import { alias } from "@ember/object/computed"; + +export default Controller.extend({ + adminWebHooks: controller(), + dialog: service(), + contentTypes: alias("adminWebHooks.contentTypes"), + defaultEventTypes: alias("adminWebHooks.defaultEventTypes"), + deliveryStatuses: alias("adminWebHooks.deliveryStatuses"), + eventTypes: alias("adminWebHooks.eventTypes"), + model: alias("adminWebHooks.model"), + + @action + destroy(webhook) { + return this.dialog.deleteConfirm({ + message: I18n.t("admin.web_hooks.delete_confirm"), + didConfirm: async () => { + try { + await webhook.destroyRecord(); + this.model.removeObject(webhook); + } catch (e) { + popupAjaxError(e); + } + }, + }); + }, + + @action + loadMore() { + this.model.loadMore(); + }, +}); diff --git a/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-show-events.js b/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-show-events.js deleted file mode 100644 index 5e9dacb83b7..00000000000 --- a/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-show-events.js +++ /dev/null @@ -1,81 +0,0 @@ -import Controller from "@ember/controller"; -import { ajax } from "discourse/lib/ajax"; -import { action } from "@ember/object"; -import { alias } from "@ember/object/computed"; -import discourseComputed, { bind } from "discourse-common/utils/decorators"; -import { popupAjaxError } from "discourse/lib/ajax-error"; - -export default Controller.extend({ - pingDisabled: false, - incomingCount: alias("incomingEventIds.length"), - - init() { - this._super(...arguments); - - this.incomingEventIds = []; - }, - - @discourseComputed("incomingCount") - hasIncoming(incomingCount) { - return incomingCount > 0; - }, - - subscribe() { - this.messageBus.subscribe( - `/web_hook_events/${this.get("model.extras.web_hook_id")}`, - this._addIncoming - ); - }, - - unsubscribe() { - this.messageBus.unsubscribe("/web_hook_events/*", this._addIncoming); - }, - - @bind - _addIncoming(data) { - if (data.event_type === "ping") { - this.set("pingDisabled", false); - } - - if (!this.incomingEventIds.includes(data.web_hook_event_id)) { - this.incomingEventIds.pushObject(data.web_hook_event_id); - } - }, - - @action - showInserted(event) { - event?.preventDefault(); - const webHookId = this.get("model.extras.web_hook_id"); - - ajax(`/admin/api/web_hooks/${webHookId}/events/bulk`, { - type: "GET", - data: { ids: this.incomingEventIds }, - }).then((data) => { - const objects = data.map((webHookEvent) => - this.store.createRecord("web-hook-event", webHookEvent) - ); - this.model.unshiftObjects(objects); - this.set("incomingEventIds", []); - }); - }, - - actions: { - loadMore() { - this.model.loadMore(); - }, - - ping() { - this.set("pingDisabled", true); - - ajax( - `/admin/api/web_hooks/${this.get("model.extras.web_hook_id")}/ping`, - { - type: "POST", - } - ).catch((error) => { - this.set("pingDisabled", false); - popupAjaxError(error); - }); - }, - }, -}); diff --git a/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-show.js b/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-show.js index f1e8caadcf8..38bef778fb4 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-show.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-show.js @@ -1,121 +1,32 @@ import Controller, { inject as controller } from "@ember/controller"; -import EmberObject from "@ember/object"; +import { action } from "@ember/object"; import I18n from "I18n"; -import { alias } from "@ember/object/computed"; -import discourseComputed from "discourse-common/utils/decorators"; -import { isEmpty } from "@ember/utils"; import { popupAjaxError } from "discourse/lib/ajax-error"; import { inject as service } from "@ember/service"; export default Controller.extend({ adminWebHooks: controller(), dialog: service(), - eventTypes: alias("adminWebHooks.eventTypes"), - defaultEventTypes: alias("adminWebHooks.defaultEventTypes"), - contentTypes: alias("adminWebHooks.contentTypes"), + router: service(), - @discourseComputed - showTagsFilter() { - return this.siteSettings.tagging_enabled; + @action + edit() { + return this.router.transitionTo("adminWebHooks.edit", this.model); }, - @discourseComputed("model.isSaving", "saved", "saveButtonDisabled") - savingStatus(isSaving, saved, saveButtonDisabled) { - if (isSaving) { - return I18n.t("saving"); - } else if (!saveButtonDisabled && saved) { - return I18n.t("saved"); - } - // Use side effect of validation to clear saved text - this.set("saved", false); - return ""; - }, - - @discourseComputed("model.isNew") - saveButtonText(isNew) { - return isNew - ? I18n.t("admin.web_hooks.create") - : I18n.t("admin.web_hooks.save"); - }, - - @discourseComputed("model.secret") - secretValidation(secret) { - if (!isEmpty(secret)) { - if (secret.includes(" ")) { - return EmberObject.create({ - failed: true, - reason: I18n.t("admin.web_hooks.secret_invalid"), - }); - } - - if (secret.length < 12) { - return EmberObject.create({ - failed: true, - reason: I18n.t("admin.web_hooks.secret_too_short"), - }); - } - } - }, - - @discourseComputed("model.wildcard_web_hook", "model.web_hook_event_types.[]") - eventTypeValidation(isWildcard, eventTypes) { - if (!isWildcard && isEmpty(eventTypes)) { - return EmberObject.create({ - failed: true, - reason: I18n.t("admin.web_hooks.event_type_missing"), - }); - } - }, - - @discourseComputed( - "model.isSaving", - "secretValidation", - "eventTypeValidation", - "model.payload_url" - ) - saveButtonDisabled( - isSaving, - secretValidation, - eventTypeValidation, - payloadUrl - ) { - return isSaving - ? false - : secretValidation || eventTypeValidation || isEmpty(payloadUrl); - }, - - actions: { - save() { - this.set("saved", false); - const model = this.model; - const isNew = model.get("isNew"); - - return model - .save() - .then(() => { - this.set("saved", true); - this.adminWebHooks.get("model").addObject(model); - - if (isNew) { - this.transitionToRoute("adminWebHooks.show", model.get("id")); - } - }) - .catch(popupAjaxError); - }, - - destroy() { - return this.dialog.yesNoConfirm({ - message: I18n.t("admin.web_hooks.delete_confirm"), - didConfirm: () => { - this.model - .destroyRecord() - .then(() => { - this.adminWebHooks.get("model").removeObject(this.model); - this.transitionToRoute("adminWebHooks"); - }) - .catch(popupAjaxError); - }, - }); - }, + @action + destroy() { + return this.dialog.deleteConfirm({ + message: I18n.t("admin.web_hooks.delete_confirm"), + didConfirm: async () => { + try { + await this.model.destroyRecord(); + this.adminWebHooks.model.removeObject(this.model); + this.transitionToRoute("adminWebHooks"); + } catch (e) { + popupAjaxError(e); + } + }, + }); }, }); diff --git a/app/assets/javascripts/admin/addon/controllers/admin-web-hooks.js b/app/assets/javascripts/admin/addon/controllers/admin-web-hooks.js index 405f8594132..fa4ba1ee7d2 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-web-hooks.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-web-hooks.js @@ -1,29 +1,3 @@ import Controller from "@ember/controller"; -import I18n from "I18n"; -import { popupAjaxError } from "discourse/lib/ajax-error"; -import { inject as service } from "@ember/service"; -import { action } from "@ember/object"; -export default Controller.extend({ - dialog: service(), - - @action - destroy(webhook) { - return this.dialog.yesNoConfirm({ - message: I18n.t("admin.web_hooks.delete_confirm"), - didConfirm: () => { - webhook - .destroyRecord() - .then(() => { - this.model.removeObject(webhook); - }) - .catch(popupAjaxError); - }, - }); - }, - - @action - loadMore() { - this.model.loadMore(); - }, -}); +export default Controller.extend({}); diff --git a/app/assets/javascripts/admin/addon/routes/admin-route-map.js b/app/assets/javascripts/admin/addon/routes/admin-route-map.js index 9b888f9ce55..37272c1c07a 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-route-map.js +++ b/app/assets/javascripts/admin/addon/routes/admin-route-map.js @@ -123,7 +123,7 @@ export default function () { { path: "/web_hooks", resetNamespace: true }, function () { this.route("show", { path: "/:web_hook_id" }); - this.route("showEvents", { path: "/:web_hook_id/events" }); + this.route("edit", { path: "/:web_hook_id/edit" }); } ); }); diff --git a/app/assets/javascripts/admin/addon/routes/admin-web-hooks-edit.js b/app/assets/javascripts/admin/addon/routes/admin-web-hooks-edit.js new file mode 100644 index 00000000000..6bd96b117b3 --- /dev/null +++ b/app/assets/javascripts/admin/addon/routes/admin-web-hooks-edit.js @@ -0,0 +1,28 @@ +import DiscourseRoute from "discourse/routes/discourse"; + +export default DiscourseRoute.extend({ + serialize(model) { + return { web_hook_id: model.id || "new" }; + }, + + model(params) { + if (params.web_hook_id === "new") { + return this.store.createRecord("web-hook"); + } + + return this.store.find("web-hook", params.web_hook_id); + }, + + setupController(controller, model) { + this._super(...arguments); + + if (model.get("isNew")) { + model.set( + "web_hook_event_types", + this.controllerFor("adminWebHooks").defaultEventTypes + ); + } + + controller.set("saved", false); + }, +}); diff --git a/app/assets/javascripts/admin/addon/routes/admin-web-hooks-show-events.js b/app/assets/javascripts/admin/addon/routes/admin-web-hooks-show-events.js deleted file mode 100644 index 1b7923224bb..00000000000 --- a/app/assets/javascripts/admin/addon/routes/admin-web-hooks-show-events.js +++ /dev/null @@ -1,21 +0,0 @@ -import DiscourseRoute from "discourse/routes/discourse"; -import { get } from "@ember/object"; - -export default DiscourseRoute.extend({ - model(params) { - return this.store.findAll("web-hook-event", get(params, "web_hook_id")); - }, - - setupController(controller, model) { - controller.set("model", model); - controller.subscribe(); - }, - - deactivate() { - this.controllerFor("adminWebHooks.showEvents").unsubscribe(); - }, - - renderTemplate() { - this.render("admin/templates/web-hooks-show-events", { into: "adminApi" }); - }, -}); diff --git a/app/assets/javascripts/admin/addon/routes/admin-web-hooks-show.js b/app/assets/javascripts/admin/addon/routes/admin-web-hooks-show.js index 6d7c64f9559..369bbd00597 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-web-hooks-show.js +++ b/app/assets/javascripts/admin/addon/routes/admin-web-hooks-show.js @@ -1,30 +1,7 @@ import DiscourseRoute from "discourse/routes/discourse"; -import { get } from "@ember/object"; export default DiscourseRoute.extend({ - serialize(model) { - return { web_hook_id: model.get("id") || "new" }; - }, - model(params) { - if (params.web_hook_id === "new") { - return this.store.createRecord("web-hook"); - } - return this.store.find("web-hook", get(params, "web_hook_id")); - }, - - setupController(controller, model) { - if (model.get("isNew")) { - model.set("web_hook_event_types", controller.get("defaultEventTypes")); - } - - model.set("category_ids", model.get("category_ids")); - model.set("tag_names", model.get("tag_names")); - model.set("group_ids", model.get("group_ids")); - controller.setProperties({ model, saved: false }); - }, - - renderTemplate() { - this.render("admin/templates/web-hooks-show", { into: "adminApi" }); + return this.store.find("web-hook", params.web_hook_id); }, }); diff --git a/app/assets/javascripts/admin/addon/routes/admin-web-hooks.js b/app/assets/javascripts/admin/addon/routes/admin-web-hooks.js index 4b207311360..3619142a4c2 100644 --- a/app/assets/javascripts/admin/addon/routes/admin-web-hooks.js +++ b/app/assets/javascripts/admin/addon/routes/admin-web-hooks.js @@ -1,4 +1,5 @@ import Route from "@ember/routing/route"; + export default Route.extend({ model() { return this.store.findAll("web-hook"); diff --git a/app/assets/javascripts/admin/addon/templates/components/admin-web-hook-event-chooser.hbs b/app/assets/javascripts/admin/addon/templates/components/admin-web-hook-event-chooser.hbs index 68f9a2ae9f6..b2420e4ebb9 100644 --- a/app/assets/javascripts/admin/addon/templates/components/admin-web-hook-event-chooser.hbs +++ b/app/assets/javascripts/admin/addon/templates/components/admin-web-hook-event-chooser.hbs @@ -1,3 +1,11 @@ - - -{{this.details}}
+ diff --git a/app/assets/javascripts/admin/addon/templates/web-hooks-edit.hbs b/app/assets/javascripts/admin/addon/templates/web-hooks-edit.hbs new file mode 100644 index 00000000000..0b56fb116ff --- /dev/null +++ b/app/assets/javascripts/admin/addon/templates/web-hooks-edit.hbs @@ -0,0 +1,110 @@ +{{i18n "admin.web_hooks.detailed_instruction"}}
+ + + +{{i18n "admin.web_hooks.instruction"}}
+ +{{i18n "admin.web_hooks.delivery_status.title"}} | +{{i18n "admin.web_hooks.payload_url"}} | +{{i18n "admin.web_hooks.description_label"}} | +{{i18n "admin.web_hooks.controls"}} | +
---|---|---|---|
+ |
+
+ |
+ {{webHook.description}} | +
+ |
+
{{i18n "admin.web_hooks.none"}}
+ {{/if}} +{{i18n "admin.web_hooks.detailed_instruction"}}
-