DEV: Admin webhooks interface issues (#19360)
1. The events table had broken styling, making each row overflow 2. It had confusing routes: `/:id` for "edit" and `/:id/events` for "show" (now it's `/:id/edit` and `/:id` respectively) 3. There previously was an unused backend action (`#edit`) - now it is used (and `web_hooks/:id/events` route has been removed) 4. There was outdated/misplaced/duplicated CSS 5. And more
This commit is contained in:
@@ -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);
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -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();
|
||||
},
|
||||
});
|
||||
@@ -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);
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -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);
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@@ -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({});
|
||||
|
||||
Reference in New Issue
Block a user