mirror of
https://github.com/discourse/discourse.git
synced 2024-12-02 12:43:42 +08:00
fee8caf529
This change is preventing the "is dirty check" from happening when clicking delete on this form. This was not good UX and was also causing bugs by leaving the form in a unexpected state.
230 lines
5.2 KiB
JavaScript
230 lines
5.2 KiB
JavaScript
import { cached, tracked } from "@glimmer/tracking";
|
|
import Controller, { inject as controller } from "@ember/controller";
|
|
import { action, getProperties } from "@ember/object";
|
|
import { service } from "@ember/service";
|
|
import { ajax } from "discourse/lib/ajax";
|
|
import { popupAjaxError } from "discourse/lib/ajax-error";
|
|
import getURL from "discourse-common/lib/get-url";
|
|
import I18n from "discourse-i18n";
|
|
import BadgePreviewModal from "../../components/modal/badge-preview";
|
|
|
|
const FORM_FIELDS = [
|
|
"allow_title",
|
|
"multiple_grant",
|
|
"listable",
|
|
"auto_revoke",
|
|
"enabled",
|
|
"show_posts",
|
|
"target_posts",
|
|
"name",
|
|
"description",
|
|
"long_description",
|
|
"icon",
|
|
"image_upload_id",
|
|
"image_url",
|
|
"query",
|
|
"badge_grouping_id",
|
|
"trigger",
|
|
"badge_type_id",
|
|
];
|
|
|
|
export default class AdminBadgesShowController extends Controller {
|
|
@service router;
|
|
@service toasts;
|
|
@service dialog;
|
|
@service modal;
|
|
|
|
@controller adminBadges;
|
|
|
|
@tracked model;
|
|
@tracked previewLoading = false;
|
|
@tracked selectedGraphicType = null;
|
|
@tracked userBadges;
|
|
@tracked userBadgesAll;
|
|
|
|
@cached
|
|
get formData() {
|
|
const data = getProperties(this.model, ...FORM_FIELDS);
|
|
|
|
if (data.icon === "") {
|
|
data.icon = undefined;
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
@action
|
|
currentBadgeGrouping(data) {
|
|
return this.badgeGroupings.find((bg) => bg.id === data.badge_grouping_id)
|
|
?.name;
|
|
}
|
|
|
|
get badgeTypes() {
|
|
return this.adminBadges.badgeTypes;
|
|
}
|
|
|
|
get badgeGroupings() {
|
|
return this.adminBadges.badgeGroupings;
|
|
}
|
|
|
|
get badgeTriggers() {
|
|
return this.adminBadges.badgeTriggers;
|
|
}
|
|
|
|
get protectedSystemFields() {
|
|
return this.adminBadges.protectedSystemFields;
|
|
}
|
|
|
|
get readOnly() {
|
|
return this.model.system;
|
|
}
|
|
|
|
setup() {
|
|
// this is needed because the model doesnt have default values
|
|
// Using `set` here isn't ideal, but we don't know that tracking is set up on the model yet.
|
|
if (this.model) {
|
|
if (!this.model.badge_type_id) {
|
|
this.model.set("badge_type_id", this.badgeTypes?.[0]?.id);
|
|
}
|
|
|
|
if (!this.model.badge_grouping_id) {
|
|
this.model.set("badge_grouping_id", this.badgeGroupings?.[0]?.id);
|
|
}
|
|
|
|
if (!this.model.trigger) {
|
|
this.model.set("trigger", this.badgeTriggers?.[0]?.id);
|
|
}
|
|
}
|
|
}
|
|
|
|
hasQuery(query) {
|
|
return query?.trim?.()?.length > 0;
|
|
}
|
|
|
|
get textCustomizationPrefix() {
|
|
return `badges.${this.model.i18n_name}.`;
|
|
}
|
|
|
|
@action
|
|
onSetImage(upload, { set }) {
|
|
if (upload) {
|
|
set("image_upload_id", upload.id);
|
|
set("image_url", getURL(upload.url));
|
|
set("icon", null);
|
|
} else {
|
|
set("image_upload_id", "");
|
|
set("image_url", "");
|
|
}
|
|
}
|
|
|
|
@action
|
|
onSetIcon(value, { set }) {
|
|
set("icon", value);
|
|
set("image_upload_id", "");
|
|
set("image_url", "");
|
|
}
|
|
|
|
@action
|
|
showPreview(badge, explain, event) {
|
|
event?.preventDefault();
|
|
this.preview(badge, explain);
|
|
}
|
|
|
|
@action
|
|
validateForm(data, { addError }) {
|
|
if (!data.icon && !data.image_url) {
|
|
addError("icon", {
|
|
title: "Icon",
|
|
message: I18n.t("admin.badges.icon_or_image"),
|
|
});
|
|
addError("image_url", {
|
|
title: "Image",
|
|
message: I18n.t("admin.badges.icon_or_image"),
|
|
});
|
|
}
|
|
}
|
|
|
|
@action
|
|
async preview(badge, explain) {
|
|
try {
|
|
this.previewLoading = true;
|
|
const model = await ajax("/admin/badges/preview.json", {
|
|
type: "POST",
|
|
data: {
|
|
sql: badge.query,
|
|
target_posts: !!badge.target_posts,
|
|
trigger: badge.trigger,
|
|
explain,
|
|
},
|
|
});
|
|
|
|
this.modal.show(BadgePreviewModal, { model: { badge: model } });
|
|
} catch (e) {
|
|
// eslint-disable-next-line no-console
|
|
console.error(e);
|
|
this.dialog.alert("Network error");
|
|
} finally {
|
|
this.previewLoading = false;
|
|
}
|
|
}
|
|
|
|
@action
|
|
async handleSubmit(formData) {
|
|
let fields = FORM_FIELDS;
|
|
|
|
if (formData.system) {
|
|
const protectedFields = this.protectedSystemFields || [];
|
|
fields = fields.filter((f) => !protectedFields.includes(f));
|
|
}
|
|
|
|
const data = {};
|
|
fields.forEach(function (field) {
|
|
data[field] = formData[field];
|
|
});
|
|
|
|
const newBadge = !this.model.id;
|
|
|
|
try {
|
|
this.model = await this.model.save(data);
|
|
|
|
this.toasts.success({ data: { message: I18n.t("saved") } });
|
|
|
|
if (newBadge) {
|
|
const adminBadges = this.get("adminBadges.model");
|
|
if (!adminBadges.includes(this.model)) {
|
|
adminBadges.pushObject(this.model);
|
|
}
|
|
return this.router.transitionTo("adminBadges.show", this.model.id);
|
|
}
|
|
} catch (error) {
|
|
return popupAjaxError(error);
|
|
}
|
|
}
|
|
|
|
@action
|
|
registerApi(api) {
|
|
this.formApi = api;
|
|
}
|
|
|
|
@action
|
|
async handleDelete() {
|
|
if (!this.model?.id) {
|
|
return this.router.transitionTo("adminBadges.index");
|
|
}
|
|
|
|
return this.dialog.yesNoConfirm({
|
|
message: I18n.t("admin.badges.delete_confirm"),
|
|
didConfirm: async () => {
|
|
try {
|
|
await this.formApi.reset();
|
|
await this.model.destroy();
|
|
this.adminBadges.model.removeObject(this.model);
|
|
this.router.transitionTo("adminBadges.index");
|
|
} catch {
|
|
this.dialog.alert(I18n.t("generic_error"));
|
|
}
|
|
},
|
|
});
|
|
}
|
|
}
|