DEV: Update admin controllers to native class syntax (#20674)

This commit was generated using the ember-native-class-codemod along with a handful of manual updates
This commit is contained in:
David Taylor
2023-03-15 09:42:12 +00:00
committed by GitHub
parent 84f590ab83
commit be354e7950
59 changed files with 1944 additions and 1849 deletions

View File

@ -2,18 +2,18 @@ import Controller from "@ember/controller";
import { action } from "@ember/object"; import { action } from "@ember/object";
import { popupAjaxError } from "discourse/lib/ajax-error"; import { popupAjaxError } from "discourse/lib/ajax-error";
export default Controller.extend({ export default class AdminApiKeysIndexController extends Controller {
loading: false, loading = false;
@action @action
revokeKey(key) { revokeKey(key) {
key.revoke().catch(popupAjaxError); key.revoke().catch(popupAjaxError);
}, }
@action @action
undoRevokeKey(key) { undoRevokeKey(key) {
key.undoRevoke().catch(popupAjaxError); key.undoRevoke().catch(popupAjaxError);
}, }
@action @action
loadMore() { loadMore() {
@ -35,5 +35,5 @@ export default Controller.extend({
.finally(() => { .finally(() => {
this.set("loading", false); this.set("loading", false);
}); });
}, }
}); }

View File

@ -1,37 +1,32 @@
import { equal } from "@ember/object/computed";
import Controller from "@ember/controller"; import Controller from "@ember/controller";
import I18n from "I18n"; import I18n from "I18n";
import discourseComputed from "discourse-common/utils/decorators"; import discourseComputed from "discourse-common/utils/decorators";
import { isBlank } from "@ember/utils"; import { isBlank } from "@ember/utils";
import { popupAjaxError } from "discourse/lib/ajax-error"; import { popupAjaxError } from "discourse/lib/ajax-error";
import { action, get } from "@ember/object"; import { action, get } from "@ember/object";
import { equal } from "@ember/object/computed";
import showModal from "discourse/lib/show-modal"; import showModal from "discourse/lib/show-modal";
import { ajax } from "discourse/lib/ajax"; import { ajax } from "discourse/lib/ajax";
export default Controller.extend({ export default class AdminApiKeysNewController extends Controller {
userModes: null, userModes = [
scopeModes: null, { id: "all", name: I18n.t("admin.api.all_users") },
globalScopes: null, { id: "single", name: I18n.t("admin.api.single_user") },
scopes: null, ];
scopeModes = [
{ id: "granular", name: I18n.t("admin.api.scopes.granular") },
{ id: "read_only", name: I18n.t("admin.api.scopes.read_only") },
{ id: "global", name: I18n.t("admin.api.scopes.global") },
];
globalScopes = null;
scopes = null;
@equal("userMode", "single") showUserSelector;
init() { init() {
this._super(...arguments); super.init(...arguments);
this.set("userModes", [
{ id: "all", name: I18n.t("admin.api.all_users") },
{ id: "single", name: I18n.t("admin.api.single_user") },
]);
this.set("scopeModes", [
{ id: "granular", name: I18n.t("admin.api.scopes.granular") },
{ id: "read_only", name: I18n.t("admin.api.scopes.read_only") },
{ id: "global", name: I18n.t("admin.api.scopes.global") },
]);
this._loadScopes(); this._loadScopes();
}, }
showUserSelector: equal("userMode", "single"),
@discourseComputed("model.{description,username}", "showUserSelector") @discourseComputed("model.{description,username}", "showUserSelector")
saveDisabled(model, showUserSelector) { saveDisabled(model, showUserSelector) {
@ -42,12 +37,12 @@ export default Controller.extend({
return true; return true;
} }
return false; return false;
}, }
@action @action
updateUsername(selected) { updateUsername(selected) {
this.set("model.username", get(selected, "firstObject")); this.set("model.username", get(selected, "firstObject"));
}, }
@action @action
changeUserMode(userMode) { changeUserMode(userMode) {
@ -55,12 +50,12 @@ export default Controller.extend({
this.model.set("username", null); this.model.set("username", null);
} }
this.set("userMode", userMode); this.set("userMode", userMode);
}, }
@action @action
changeScopeMode(scopeMode) { changeScopeMode(scopeMode) {
this.set("scopeMode", scopeMode); this.set("scopeMode", scopeMode);
}, }
@action @action
save() { save() {
@ -77,12 +72,12 @@ export default Controller.extend({
} }
return this.model.save().catch(popupAjaxError); return this.model.save().catch(popupAjaxError);
}, }
@action @action
continue() { continue() {
this.transitionToRoute("adminApiKeys.show", this.model.id); this.transitionToRoute("adminApiKeys.show", this.model.id);
}, }
@action @action
showURLs(urls) { showURLs(urls) {
@ -90,7 +85,7 @@ export default Controller.extend({
admin: true, admin: true,
model: { urls }, model: { urls },
}); });
}, }
_loadScopes() { _loadScopes() {
return ajax("/admin/api/keys/scopes.json") return ajax("/admin/api/keys/scopes.json")
@ -102,5 +97,5 @@ export default Controller.extend({
this.set("scopes", data.scopes); this.set("scopes", data.scopes);
}) })
.catch(popupAjaxError); .catch(popupAjaxError);
}, }
}); }

View File

@ -1,66 +1,74 @@
import { action } from "@ember/object";
import { empty } from "@ember/object/computed";
import Controller from "@ember/controller"; import Controller from "@ember/controller";
import { bufferedProperty } from "discourse/mixins/buffered-content"; import { bufferedProperty } from "discourse/mixins/buffered-content";
import { empty } from "@ember/object/computed";
import { isEmpty } from "@ember/utils"; import { isEmpty } from "@ember/utils";
import { popupAjaxError } from "discourse/lib/ajax-error"; import { popupAjaxError } from "discourse/lib/ajax-error";
import showModal from "discourse/lib/show-modal"; import showModal from "discourse/lib/show-modal";
export default Controller.extend(bufferedProperty("model"), { export default class AdminApiKeysShowController extends Controller.extend(
isNew: empty("model.id"), bufferedProperty("model")
) {
@empty("model.id") isNew;
actions: { @action
saveDescription() { saveDescription() {
const buffered = this.buffered; const buffered = this.buffered;
const attrs = buffered.getProperties("description"); const attrs = buffered.getProperties("description");
this.model this.model
.save(attrs) .save(attrs)
.then(() => { .then(() => {
this.set("editingDescription", false); this.set("editingDescription", false);
this.rollbackBuffer();
})
.catch(popupAjaxError);
},
cancel() {
const id = this.get("userField.id");
if (isEmpty(id)) {
this.destroyAction(this.userField);
} else {
this.rollbackBuffer(); this.rollbackBuffer();
this.set("editing", false); })
} .catch(popupAjaxError);
}, }
editDescription() { @action
this.toggleProperty("editingDescription"); cancel() {
if (!this.editingDescription) { const id = this.get("userField.id");
this.rollbackBuffer(); if (isEmpty(id)) {
} this.destroyAction(this.userField);
}, } else {
this.rollbackBuffer();
this.set("editing", false);
}
}
revokeKey(key) { @action
key.revoke().catch(popupAjaxError); editDescription() {
}, this.toggleProperty("editingDescription");
if (!this.editingDescription) {
this.rollbackBuffer();
}
}
deleteKey(key) { @action
key revokeKey(key) {
.destroyRecord() key.revoke().catch(popupAjaxError);
.then(() => this.transitionToRoute("adminApiKeys.index")) }
.catch(popupAjaxError);
},
undoRevokeKey(key) { @action
key.undoRevoke().catch(popupAjaxError); deleteKey(key) {
}, key
.destroyRecord()
.then(() => this.transitionToRoute("adminApiKeys.index"))
.catch(popupAjaxError);
}
showURLs(urls) { @action
return showModal("admin-api-key-urls", { undoRevokeKey(key) {
admin: true, key.undoRevoke().catch(popupAjaxError);
model: { }
urls,
}, @action
}); showURLs(urls) {
}, return showModal("admin-api-key-urls", {
}, admin: true,
}); model: {
urls,
},
});
}
}

View File

@ -1,3 +1,3 @@
import Controller from "@ember/controller"; import Controller from "@ember/controller";
export default Controller.extend(); export default class AdminApiKeysController extends Controller {}

View File

@ -1,19 +1,21 @@
import Controller, { inject as controller } from "@ember/controller"; import { action } from "@ember/object";
import { inject as service } from "@ember/service";
import { alias, equal } from "@ember/object/computed"; import { alias, equal } from "@ember/object/computed";
import Controller, { inject as controller } from "@ember/controller";
import { i18n, setting } from "discourse/lib/computed"; import { i18n, setting } from "discourse/lib/computed";
import I18n from "I18n"; import I18n from "I18n";
import { ajax } from "discourse/lib/ajax"; import { ajax } from "discourse/lib/ajax";
import discourseComputed from "discourse-common/utils/decorators"; import discourseComputed from "discourse-common/utils/decorators";
import { inject as service } from "@ember/service";
export default Controller.extend({ export default class AdminBackupsIndexController extends Controller {
adminBackups: controller(), @service dialog;
dialog: service(), @controller adminBackups;
status: alias("adminBackups.model"),
uploadLabel: i18n("admin.backups.upload.label"), @alias("adminBackups.model") status;
backupLocation: setting("backup_location"), @i18n("admin.backups.upload.label") uploadLabel;
localBackupStorage: equal("backupLocation", "local"), @setting("backup_location") backupLocation;
@equal("backupLocation", "local") localBackupStorage;
@discourseComputed("status.allowRestore", "status.isOperationRunning") @discourseComputed("status.allowRestore", "status.isOperationRunning")
restoreTitle(allowRestore, isOperationRunning) { restoreTitle(allowRestore, isOperationRunning) {
@ -24,35 +26,35 @@ export default Controller.extend({
} else { } else {
return "admin.backups.operations.restore.title"; return "admin.backups.operations.restore.title";
} }
}, }
actions: { @action
toggleReadOnlyMode() { toggleReadOnlyMode() {
if (!this.site.get("isReadOnly")) { if (!this.site.get("isReadOnly")) {
this.dialog.yesNoConfirm({ this.dialog.yesNoConfirm({
message: I18n.t("admin.backups.read_only.enable.confirm"), message: I18n.t("admin.backups.read_only.enable.confirm"),
didConfirm: () => { didConfirm: () => {
this.set("currentUser.hideReadOnlyAlert", true); this.set("currentUser.hideReadOnlyAlert", true);
this._toggleReadOnlyMode(true); this._toggleReadOnlyMode(true);
}, },
}); });
} else { } else {
this._toggleReadOnlyMode(false); this._toggleReadOnlyMode(false);
} }
}, }
download(backup) { @action
const link = backup.get("filename"); download(backup) {
ajax(`/admin/backups/${link}`, { type: "PUT" }).then(() => const link = backup.get("filename");
this.dialog.alert(I18n.t("admin.backups.operations.download.alert")) ajax(`/admin/backups/${link}`, { type: "PUT" }).then(() =>
); this.dialog.alert(I18n.t("admin.backups.operations.download.alert"))
}, );
}, }
_toggleReadOnlyMode(enable) { _toggleReadOnlyMode(enable) {
ajax("/admin/backups/readonly", { ajax("/admin/backups/readonly", {
type: "PUT", type: "PUT",
data: { enable }, data: { enable },
}).then(() => this.site.set("isReadOnly", enable)); }).then(() => this.site.set("isReadOnly", enable));
}, }
}); }

View File

@ -1,13 +1,10 @@
import Controller, { inject as controller } from "@ember/controller";
import { alias } from "@ember/object/computed"; import { alias } from "@ember/object/computed";
import Controller, { inject as controller } from "@ember/controller";
export default Controller.extend({ export default class AdminBackupsLogsController extends Controller {
adminBackups: controller(), @controller adminBackups;
status: alias("adminBackups.model"),
init() { @alias("adminBackups.model") status;
this._super(...arguments);
this.logs = []; logs = [];
}, }
});

View File

@ -1,11 +1,8 @@
import { and, not } from "@ember/object/computed"; import { and, not } from "@ember/object/computed";
import Controller from "@ember/controller"; import Controller from "@ember/controller";
export default Controller.extend({ export default class AdminBackupsController extends Controller {
noOperationIsRunning: not("model.isOperationRunning"), @not("model.isOperationRunning") noOperationIsRunning;
rollbackEnabled: and( @not("rollbackEnabled") rollbackDisabled;
"model.canRollback", @and("model.canRollback", "model.restoreEnabled", "noOperationIsRunning")
"model.restoreEnabled", rollbackEnabled;
"noOperationIsRunning" }
),
rollbackDisabled: not("rollbackEnabled"),
});

View File

@ -1,19 +1,19 @@
import Controller from "@ember/controller"; import Controller from "@ember/controller";
import EmberObject from "@ember/object"; import EmberObject, { action } from "@ember/object";
import I18n from "I18n"; import I18n from "I18n";
import discourseComputed from "discourse-common/utils/decorators"; import discourseComputed from "discourse-common/utils/decorators";
import showModal from "discourse/lib/show-modal"; import showModal from "discourse/lib/show-modal";
export default Controller.extend({ export default class AdminCustomizeColorsController extends Controller {
@discourseComputed("model.@each.id") @discourseComputed("model.@each.id")
baseColorScheme() { baseColorScheme() {
return this.model.findBy("is_base", true); return this.model.findBy("is_base", true);
}, }
@discourseComputed("model.@each.id") @discourseComputed("model.@each.id")
baseColorSchemes() { baseColorSchemes() {
return this.model.filterBy("is_base", true); return this.model.filterBy("is_base", true);
}, }
@discourseComputed("baseColorScheme") @discourseComputed("baseColorScheme")
baseColors(baseColorScheme) { baseColors(baseColorScheme) {
@ -22,28 +22,28 @@ export default Controller.extend({
baseColorsHash.set(color.get("name"), color); baseColorsHash.set(color.get("name"), color);
}); });
return baseColorsHash; return baseColorsHash;
}, }
actions: { @action
newColorSchemeWithBase(baseKey) { newColorSchemeWithBase(baseKey) {
const base = this.baseColorSchemes.findBy("base_scheme_id", baseKey); const base = this.baseColorSchemes.findBy("base_scheme_id", baseKey);
const newColorScheme = base.copy(); const newColorScheme = base.copy();
newColorScheme.setProperties({ newColorScheme.setProperties({
name: I18n.t("admin.customize.colors.new_name"), name: I18n.t("admin.customize.colors.new_name"),
base_scheme_id: base.get("base_scheme_id"), base_scheme_id: base.get("base_scheme_id"),
}); });
newColorScheme.save().then(() => { newColorScheme.save().then(() => {
this.model.pushObject(newColorScheme); this.model.pushObject(newColorScheme);
newColorScheme.set("savingStatus", null); newColorScheme.set("savingStatus", null);
this.replaceRoute("adminCustomize.colors.show", newColorScheme); this.replaceRoute("adminCustomize.colors.show", newColorScheme);
}); });
}, }
newColorScheme() { @action
showModal("admin-color-scheme-select-base", { newColorScheme() {
model: this.baseColorSchemes, showModal("admin-color-scheme-select-base", {
admin: true, model: this.baseColorSchemes,
}); admin: true,
}, });
}, }
}); }

View File

@ -1,38 +1,38 @@
import { action } from "@ember/object";
import { inject as service } from "@ember/service";
import Controller from "@ember/controller"; import Controller from "@ember/controller";
import I18n from "I18n"; import I18n from "I18n";
import discourseComputed from "discourse-common/utils/decorators"; import discourseComputed from "discourse-common/utils/decorators";
import { inject as service } from "@ember/service";
export default Controller.extend({ export default class AdminCustomizeEmailStyleEditController extends Controller {
dialog: service(), @service dialog;
@discourseComputed("model.isSaving") @discourseComputed("model.isSaving")
saveButtonText(isSaving) { saveButtonText(isSaving) {
return isSaving ? I18n.t("saving") : I18n.t("admin.customize.save"); return isSaving ? I18n.t("saving") : I18n.t("admin.customize.save");
}, }
@discourseComputed("model.changed", "model.isSaving") @discourseComputed("model.changed", "model.isSaving")
saveDisabled(changed, isSaving) { saveDisabled(changed, isSaving) {
return !changed || isSaving; return !changed || isSaving;
}, }
actions: { @action
save() { save() {
if (!this.model.saving) { if (!this.model.saving) {
this.set("saving", true); this.set("saving", true);
this.model this.model
.update(this.model.getProperties("html", "css")) .update(this.model.getProperties("html", "css"))
.catch((e) => { .catch((e) => {
const msg = const msg =
e.jqXHR.responseJSON && e.jqXHR.responseJSON.errors e.jqXHR.responseJSON && e.jqXHR.responseJSON.errors
? I18n.t("admin.customize.email_style.save_error_with_reason", { ? I18n.t("admin.customize.email_style.save_error_with_reason", {
error: e.jqXHR.responseJSON.errors.join(". "), error: e.jqXHR.responseJSON.errors.join(". "),
}) })
: I18n.t("generic_error"); : I18n.t("generic_error");
this.dialog.alert(msg); this.dialog.alert(msg);
}) })
.finally(() => this.set("model.changed", false)); .finally(() => this.set("model.changed", false));
} }
}, }
}, }
});

View File

@ -1,23 +1,26 @@
import { inject as service } from "@ember/service";
import Controller, { inject as controller } from "@ember/controller"; import Controller, { inject as controller } from "@ember/controller";
import I18n from "I18n"; import I18n from "I18n";
import { action } from "@ember/object"; import { action } from "@ember/object";
import { bufferedProperty } from "discourse/mixins/buffered-content"; import { bufferedProperty } from "discourse/mixins/buffered-content";
import discourseComputed from "discourse-common/utils/decorators"; import discourseComputed from "discourse-common/utils/decorators";
import { popupAjaxError } from "discourse/lib/ajax-error"; import { popupAjaxError } from "discourse/lib/ajax-error";
import { inject as service } from "@ember/service";
export default Controller.extend(bufferedProperty("emailTemplate"), { export default class AdminCustomizeEmailTemplatesEditController extends Controller.extend(
adminCustomizeEmailTemplates: controller(), bufferedProperty("emailTemplate")
dialog: service(), ) {
emailTemplate: null, @service dialog;
saved: false, @controller adminCustomizeEmailTemplates;
emailTemplate = null;
saved = false;
@discourseComputed("buffered.body", "buffered.subject") @discourseComputed("buffered.body", "buffered.subject")
saveDisabled(body, subject) { saveDisabled(body, subject) {
return ( return (
this.emailTemplate.body === body && this.emailTemplate.subject === subject this.emailTemplate.body === body && this.emailTemplate.subject === subject
); );
}, }
@discourseComputed("buffered") @discourseComputed("buffered")
hasMultipleSubjects(buffered) { hasMultipleSubjects(buffered) {
@ -26,7 +29,7 @@ export default Controller.extend(bufferedProperty("emailTemplate"), {
} else { } else {
return buffered.getProperties("id")["id"]; return buffered.getProperties("id")["id"];
} }
}, }
@action @action
saveChanges() { saveChanges() {
@ -38,7 +41,7 @@ export default Controller.extend(bufferedProperty("emailTemplate"), {
this.set("saved", true); this.set("saved", true);
}) })
.catch(popupAjaxError); .catch(popupAjaxError);
}, }
@action @action
revertChanges() { revertChanges() {
@ -57,5 +60,5 @@ export default Controller.extend(bufferedProperty("emailTemplate"), {
.catch(popupAjaxError); .catch(popupAjaxError);
}, },
}); });
}, }
}); }

View File

@ -1,18 +1,13 @@
import { sort } from "@ember/object/computed";
import Controller from "@ember/controller"; import Controller from "@ember/controller";
import { action } from "@ember/object"; import { action } from "@ember/object";
import { sort } from "@ember/object/computed";
export default Controller.extend({ export default class AdminCustomizeEmailTemplatesController extends Controller {
sortedTemplates: sort("emailTemplates", "titleSorting"), titleSorting = ["title"];
@sort("emailTemplates", "titleSorting") sortedTemplates;
init() {
this._super(...arguments);
this.set("titleSorting", ["title"]);
},
@action @action
onSelectTemplate(template) { onSelectTemplate(template) {
this.transitionToRoute("adminCustomizeEmailTemplates.edit", template); this.transitionToRoute("adminCustomizeEmailTemplates.edit", template);
}, }
}); }

View File

@ -1,47 +1,52 @@
import { action } from "@ember/object";
import { not } from "@ember/object/computed";
import Controller from "@ember/controller"; import Controller from "@ember/controller";
import { ajax } from "discourse/lib/ajax"; import { ajax } from "discourse/lib/ajax";
import { bufferedProperty } from "discourse/mixins/buffered-content"; import { bufferedProperty } from "discourse/mixins/buffered-content";
import { not } from "@ember/object/computed";
import { propertyEqual } from "discourse/lib/computed"; import { propertyEqual } from "discourse/lib/computed";
export default Controller.extend(bufferedProperty("model"), { export default class AdminCustomizeRobotsTxtController extends Controller.extend(
saved: false, bufferedProperty("model")
isSaving: false, ) {
saveDisabled: propertyEqual("model.robots_txt", "buffered.robots_txt"), saved = false;
resetDisabled: not("model.overridden"), isSaving = false;
actions: { @propertyEqual("model.robots_txt", "buffered.robots_txt") saveDisabled;
save() {
this.setProperties({
isSaving: true,
saved: false,
});
ajax("robots.json", { @not("model.overridden") resetDisabled;
type: "PUT",
data: { robots_txt: this.buffered.get("robots_txt") }, @action
save() {
this.setProperties({
isSaving: true,
saved: false,
});
ajax("robots.json", {
type: "PUT",
data: { robots_txt: this.buffered.get("robots_txt") },
})
.then((data) => {
this.commitBuffer();
this.set("saved", true);
this.set("model.overridden", data.overridden);
}) })
.then((data) => { .finally(() => this.set("isSaving", false));
this.commitBuffer(); }
this.set("saved", true);
this.set("model.overridden", data.overridden);
})
.finally(() => this.set("isSaving", false));
},
reset() { @action
this.setProperties({ reset() {
isSaving: true, this.setProperties({
saved: false, isSaving: true,
}); saved: false,
ajax("robots.json", { type: "DELETE" }) });
.then((data) => { ajax("robots.json", { type: "DELETE" })
this.buffered.set("robots_txt", data.robots_txt); .then((data) => {
this.commitBuffer(); this.buffered.set("robots_txt", data.robots_txt);
this.set("saved", true); this.commitBuffer();
this.set("model.overridden", false); this.set("saved", true);
}) this.set("model.overridden", false);
.finally(() => this.set("isSaving", false)); })
}, .finally(() => this.set("isSaving", false));
}, }
}); }

View File

@ -1,21 +1,24 @@
import { action } from "@ember/object";
import Controller from "@ember/controller"; import Controller from "@ember/controller";
import I18n from "I18n"; import I18n from "I18n";
import discourseComputed from "discourse-common/utils/decorators"; import discourseComputed from "discourse-common/utils/decorators";
import { url } from "discourse/lib/computed"; import { url } from "discourse/lib/computed";
export default Controller.extend({ export default class AdminCustomizeThemesEditController extends Controller {
section: null, section = null;
currentTarget: 0, currentTarget = 0;
maximized: false, maximized = false;
previewUrl: url("model.id", "/admin/themes/%@/preview"),
showAdvanced: false, @url("model.id", "/admin/themes/%@/preview") previewUrl;
editRouteName: "adminCustomizeThemes.edit",
showRouteName: "adminCustomizeThemes.show", showAdvanced = false;
editRouteName = "adminCustomizeThemes.edit";
showRouteName = "adminCustomizeThemes.show";
setTargetName(name) { setTargetName(name) {
const target = this.get("model.targets").find((t) => t.name === name); const target = this.get("model.targets").find((t) => t.name === name);
this.set("currentTarget", target && target.id); this.set("currentTarget", target && target.id);
}, }
@discourseComputed("currentTarget") @discourseComputed("currentTarget")
currentTargetName(id) { currentTargetName(id) {
@ -23,50 +26,52 @@ export default Controller.extend({
(t) => t.id === parseInt(id, 10) (t) => t.id === parseInt(id, 10)
); );
return target && target.name; return target && target.name;
}, }
@discourseComputed("model.isSaving") @discourseComputed("model.isSaving")
saveButtonText(isSaving) { saveButtonText(isSaving) {
return isSaving ? I18n.t("saving") : I18n.t("admin.customize.save"); return isSaving ? I18n.t("saving") : I18n.t("admin.customize.save");
}, }
@discourseComputed("model.changed", "model.isSaving") @discourseComputed("model.changed", "model.isSaving")
saveDisabled(changed, isSaving) { saveDisabled(changed, isSaving) {
return !changed || isSaving; return !changed || isSaving;
}, }
actions: { @action
save() { save() {
this.set("saving", true); this.set("saving", true);
this.model.saveChanges("theme_fields").finally(() => { this.model.saveChanges("theme_fields").finally(() => {
this.set("saving", false); this.set("saving", false);
}); });
}, }
fieldAdded(target, name) { @action
this.replaceRoute(this.editRouteName, this.get("model.id"), target, name); fieldAdded(target, name) {
}, this.replaceRoute(this.editRouteName, this.get("model.id"), target, name);
}
onlyOverriddenChanged(onlyShowOverridden) { @action
if (onlyShowOverridden) { onlyOverriddenChanged(onlyShowOverridden) {
if (!this.model.hasEdited(this.currentTargetName, this.fieldName)) { if (onlyShowOverridden) {
let firstTarget = this.get("model.targets").find((t) => t.edited); if (!this.model.hasEdited(this.currentTargetName, this.fieldName)) {
let firstField = this.get(`model.fields.${firstTarget.name}`).find( let firstTarget = this.get("model.targets").find((t) => t.edited);
(f) => f.edited let firstField = this.get(`model.fields.${firstTarget.name}`).find(
); (f) => f.edited
);
this.replaceRoute( this.replaceRoute(
this.editRouteName, this.editRouteName,
this.get("model.id"), this.get("model.id"),
firstTarget.name, firstTarget.name,
firstField.name firstField.name
); );
}
} }
}, }
}
goBack() { @action
this.replaceRoute(this.showRouteName, this.model.id); goBack() {
}, this.replaceRoute(this.showRouteName, this.model.id);
}, }
}); }

View File

@ -1,4 +1,4 @@
import { COMPONENTS, THEMES } from "admin/models/theme"; import { inject as service } from "@ember/service";
import { import {
empty, empty,
filterBy, filterBy,
@ -6,8 +6,9 @@ import {
match, match,
notEmpty, notEmpty,
} from "@ember/object/computed"; } from "@ember/object/computed";
import { COMPONENTS, THEMES } from "admin/models/theme";
import Controller from "@ember/controller"; import Controller from "@ember/controller";
import EmberObject from "@ember/object"; import EmberObject, { action } from "@ember/object";
import I18n from "I18n"; import I18n from "I18n";
import ThemeSettings from "admin/models/theme-settings"; import ThemeSettings from "admin/models/theme-settings";
import discourseComputed from "discourse-common/utils/decorators"; import discourseComputed from "discourse-common/utils/decorators";
@ -15,31 +16,35 @@ import { makeArray } from "discourse-common/lib/helpers";
import { popupAjaxError } from "discourse/lib/ajax-error"; import { popupAjaxError } from "discourse/lib/ajax-error";
import showModal from "discourse/lib/show-modal"; import showModal from "discourse/lib/show-modal";
import { url } from "discourse/lib/computed"; import { url } from "discourse/lib/computed";
import { inject as service } from "@ember/service";
const THEME_UPLOAD_VAR = 2; const THEME_UPLOAD_VAR = 2;
export default Controller.extend({ export default class AdminCustomizeThemesShowController extends Controller {
dialog: service(), @service dialog;
downloadUrl: url("model.id", "/admin/customize/themes/%@/export"),
previewUrl: url("model.id", "/admin/themes/%@/preview"), editRouteName = "adminCustomizeThemes.edit";
addButtonDisabled: empty("selectedChildThemeId"),
editRouteName: "adminCustomizeThemes.edit", @url("model.id", "/admin/customize/themes/%@/export") downloadUrl;
parentThemesNames: mapBy("model.parentThemes", "name"), @url("model.id", "/admin/themes/%@/preview") previewUrl;
availableParentThemes: filterBy("allThemes", "component", false), @empty("selectedChildThemeId") addButtonDisabled;
availableActiveParentThemes: filterBy("availableParentThemes", "isActive"), @mapBy("model.parentThemes", "name") parentThemesNames;
availableThemesNames: mapBy("availableParentThemes", "name"), @filterBy("allThemes", "component", false) availableParentThemes;
availableActiveThemesNames: mapBy("availableActiveParentThemes", "name"), @filterBy("availableParentThemes", "isActive") availableActiveParentThemes;
availableActiveChildThemes: filterBy("availableChildThemes", "hasParents"), @mapBy("availableParentThemes", "name") availableThemesNames;
availableComponentsNames: mapBy("availableChildThemes", "name"), @mapBy("availableActiveParentThemes", "name") availableActiveThemesNames;
availableActiveComponentsNames: mapBy("availableActiveChildThemes", "name"), @filterBy("availableChildThemes", "hasParents") availableActiveChildThemes;
childThemesNames: mapBy("model.childThemes", "name"), @mapBy("availableChildThemes", "name") availableComponentsNames;
extraFiles: filterBy("model.theme_fields", "target", "extra_js"), @mapBy("availableActiveChildThemes", "name") availableActiveComponentsNames;
@mapBy("model.childThemes", "name") childThemesNames;
@filterBy("model.theme_fields", "target", "extra_js") extraFiles;
@notEmpty("settings") hasSettings;
@notEmpty("translations") hasTranslations;
@match("model.remote_theme.remote_url", /^http(s)?:\/\//) sourceIsHttp;
@discourseComputed("model.component", "model.remote_theme") @discourseComputed("model.component", "model.remote_theme")
showCheckboxes() { showCheckboxes() {
return !this.model.component || this.model.remote_theme; return !this.model.component || this.model.remote_theme;
}, }
@discourseComputed("model.editedFields") @discourseComputed("model.editedFields")
editedFieldsFormatted() { editedFieldsFormatted() {
@ -57,13 +62,13 @@ export default Controller.extend({
descriptions.push(resultString); descriptions.push(resultString);
}); });
return descriptions; return descriptions;
}, }
@discourseComputed("colorSchemeId", "model.color_scheme_id") @discourseComputed("colorSchemeId", "model.color_scheme_id")
colorSchemeChanged(colorSchemeId, existingId) { colorSchemeChanged(colorSchemeId, existingId) {
colorSchemeId = colorSchemeId === null ? null : parseInt(colorSchemeId, 10); colorSchemeId = colorSchemeId === null ? null : parseInt(colorSchemeId, 10);
return colorSchemeId !== existingId; return colorSchemeId !== existingId;
}, }
@discourseComputed("availableChildThemes", "model.childThemes.[]", "model") @discourseComputed("availableChildThemes", "model.childThemes.[]", "model")
selectableChildThemes(available, childThemes) { selectableChildThemes(available, childThemes) {
@ -73,7 +78,7 @@ export default Controller.extend({
: available.filter((theme) => !childThemes.includes(theme)); : available.filter((theme) => !childThemes.includes(theme));
return themes.length === 0 ? null : themes; return themes.length === 0 ? null : themes;
} }
}, }
@discourseComputed("model.parentThemes.[]") @discourseComputed("model.parentThemes.[]")
relativesSelectorSettingsForComponent() { relativesSelectorSettingsForComponent() {
@ -91,7 +96,7 @@ export default Controller.extend({
allThemes: this.allThemes, allThemes: this.allThemes,
setDefaultValuesLabel: I18n.t("admin.customize.theme.add_all_themes"), setDefaultValuesLabel: I18n.t("admin.customize.theme.add_all_themes"),
}); });
}, }
@discourseComputed("model.parentThemes.[]") @discourseComputed("model.parentThemes.[]")
relativesSelectorSettingsForTheme() { relativesSelectorSettingsForTheme() {
@ -109,7 +114,7 @@ export default Controller.extend({
allThemes: this.allThemes, allThemes: this.allThemes,
setDefaultValuesLabel: I18n.t("admin.customize.theme.add_all"), setDefaultValuesLabel: I18n.t("admin.customize.theme.add_all"),
}); });
}, }
@discourseComputed("allThemes", "model.component", "model") @discourseComputed("allThemes", "model.component", "model")
availableChildThemes(allThemes) { availableChildThemes(allThemes) {
@ -119,40 +124,36 @@ export default Controller.extend({
(theme) => theme.get("id") !== themeId && theme.get("component") (theme) => theme.get("id") !== themeId && theme.get("component")
); );
} }
}, }
@discourseComputed("model.component") @discourseComputed("model.component")
convertKey(component) { convertKey(component) {
const type = component ? "component" : "theme"; const type = component ? "component" : "theme";
return `admin.customize.theme.convert_${type}`; return `admin.customize.theme.convert_${type}`;
}, }
@discourseComputed("model.component") @discourseComputed("model.component")
convertIcon(component) { convertIcon(component) {
return component ? "cube" : ""; return component ? "cube" : "";
}, }
@discourseComputed("model.component") @discourseComputed("model.component")
convertTooltip(component) { convertTooltip(component) {
const type = component ? "component" : "theme"; const type = component ? "component" : "theme";
return `admin.customize.theme.convert_${type}_tooltip`; return `admin.customize.theme.convert_${type}_tooltip`;
}, }
@discourseComputed("model.settings") @discourseComputed("model.settings")
settings(settings) { settings(settings) {
return settings.map((setting) => ThemeSettings.create(setting)); return settings.map((setting) => ThemeSettings.create(setting));
}, }
hasSettings: notEmpty("settings"),
@discourseComputed("model.translations") @discourseComputed("model.translations")
translations(translations) { translations(translations) {
return translations.map((setting) => return translations.map((setting) =>
ThemeSettings.create({ ...setting, textarea: true }) ThemeSettings.create({ ...setting, textarea: true })
); );
}, }
hasTranslations: notEmpty("translations"),
@discourseComputed( @discourseComputed(
"model.remote_theme.local_version", "model.remote_theme.local_version",
@ -161,12 +162,12 @@ export default Controller.extend({
) )
hasOverwrittenHistory(localVersion, remoteVersion, commitsBehind) { hasOverwrittenHistory(localVersion, remoteVersion, commitsBehind) {
return localVersion !== remoteVersion && commitsBehind === -1; return localVersion !== remoteVersion && commitsBehind === -1;
}, }
@discourseComputed("model.remoteError", "updatingRemote") @discourseComputed("model.remoteError", "updatingRemote")
showRemoteError(errorMessage, updating) { showRemoteError(errorMessage, updating) {
return errorMessage && !updating; return errorMessage && !updating;
}, }
@discourseComputed( @discourseComputed(
"model.remote_theme.remote_url", "model.remote_theme.remote_url",
@ -175,13 +176,13 @@ export default Controller.extend({
) )
finishInstall(remoteUrl, localVersion, commitsBehind) { finishInstall(remoteUrl, localVersion, commitsBehind) {
return remoteUrl && !localVersion && !commitsBehind; return remoteUrl && !localVersion && !commitsBehind;
}, }
editedFieldsForTarget(target) { editedFieldsForTarget(target) {
return this.get("model.editedFields").filter( return this.get("model.editedFields").filter(
(field) => field.target === target (field) => field.target === target
); );
}, }
commitSwitchType() { commitSwitchType() {
const model = this.model; const model = this.model;
@ -222,7 +223,8 @@ export default Controller.extend({
}); });
}) })
.catch(popupAjaxError); .catch(popupAjaxError);
}, }
transitionToEditRoute() { transitionToEditRoute() {
this.transitionToRoute( this.transitionToRoute(
this.editRouteName, this.editRouteName,
@ -230,8 +232,7 @@ export default Controller.extend({
"common", "common",
"scss" "scss"
); );
}, }
sourceIsHttp: match("model.remote_theme.remote_url", /^http(s)?:\/\//),
@discourseComputed( @discourseComputed(
"model.remote_theme.remote_url", "model.remote_theme.remote_url",
@ -241,168 +242,186 @@ export default Controller.extend({
return remoteThemeBranch return remoteThemeBranch
? `${remoteThemeUrl.replace(/\.git$/, "")}/tree/${remoteThemeBranch}` ? `${remoteThemeUrl.replace(/\.git$/, "")}/tree/${remoteThemeBranch}`
: remoteThemeUrl; : remoteThemeUrl;
}, }
@discourseComputed("model.user.id", "model.default") @discourseComputed("model.user.id", "model.default")
showConvert(userId, defaultTheme) { showConvert(userId, defaultTheme) {
return userId > 0 && !defaultTheme; return userId > 0 && !defaultTheme;
}, }
actions: { @action
updateToLatest() { updateToLatest() {
this.set("updatingRemote", true); this.set("updatingRemote", true);
this.model this.model
.updateToLatest() .updateToLatest()
.catch(popupAjaxError) .catch(popupAjaxError)
.finally(() => { .finally(() => {
this.set("updatingRemote", false); this.set("updatingRemote", false);
});
},
checkForThemeUpdates() {
this.set("updatingRemote", true);
this.model
.checkForUpdates()
.catch(popupAjaxError)
.finally(() => {
this.set("updatingRemote", false);
});
},
addUploadModal() {
showModal("admin-add-upload", { admin: true, name: "" });
},
addUpload(info) {
let model = this.model;
model.setField("common", info.name, "", info.upload_id, THEME_UPLOAD_VAR);
model.saveChanges("theme_fields").catch((e) => popupAjaxError(e));
},
cancelChangeScheme() {
this.set("colorSchemeId", this.get("model.color_scheme_id"));
},
changeScheme() {
let schemeId = this.colorSchemeId;
this.set(
"model.color_scheme_id",
schemeId === null ? null : parseInt(schemeId, 10)
);
this.model.saveChanges("color_scheme_id");
},
startEditingName() {
this.set("oldName", this.get("model.name"));
this.set("editingName", true);
},
cancelEditingName() {
this.set("model.name", this.oldName);
this.set("editingName", false);
},
finishedEditingName() {
this.model.saveChanges("name");
this.set("editingName", false);
},
editTheme() {
if (this.get("model.remote_theme.is_git")) {
this.dialog.confirm({
message: I18n.t("admin.customize.theme.edit_confirm"),
didConfirm: () => this.transitionToEditRoute(),
});
} else {
this.transitionToEditRoute();
}
},
applyDefault() {
const model = this.model;
model.saveChanges("default").then(() => {
if (model.get("default")) {
this.allThemes.forEach((theme) => {
if (theme !== model && theme.get("default")) {
theme.set("default", false);
}
});
}
}); });
}, }
applyUserSelectable() { @action
this.model.saveChanges("user_selectable"); checkForThemeUpdates() {
}, this.set("updatingRemote", true);
this.model
applyAutoUpdateable() { .checkForUpdates()
this.model.saveChanges("auto_update"); .catch(popupAjaxError)
}, .finally(() => {
this.set("updatingRemote", false);
addChildTheme() {
let themeId = parseInt(this.selectedChildThemeId, 10);
let theme = this.allThemes.findBy("id", themeId);
this.model.addChildTheme(theme).then(() => this.store.findAll("theme"));
},
removeUpload(upload) {
return this.dialog.yesNoConfirm({
message: I18n.t("admin.customize.theme.delete_upload_confirm"),
didConfirm: () => this.model.removeField(upload),
}); });
}, }
removeChildTheme(theme) { @action
this.model addUploadModal() {
.removeChildTheme(theme) showModal("admin-add-upload", { admin: true, name: "" });
.then(() => this.store.findAll("theme")); }
},
destroy() { @action
return this.dialog.yesNoConfirm({ addUpload(info) {
message: I18n.t("admin.customize.delete_confirm", { let model = this.model;
theme_name: this.get("model.name"), model.setField("common", info.name, "", info.upload_id, THEME_UPLOAD_VAR);
}), model.saveChanges("theme_fields").catch((e) => popupAjaxError(e));
didConfirm: () => { }
const model = this.model;
model.setProperties({ recentlyInstalled: false }); @action
model.destroyRecord().then(() => { cancelChangeScheme() {
this.allThemes.removeObject(model); this.set("colorSchemeId", this.get("model.color_scheme_id"));
this.transitionToRoute("adminCustomizeThemes"); }
});
}, @action
changeScheme() {
let schemeId = this.colorSchemeId;
this.set(
"model.color_scheme_id",
schemeId === null ? null : parseInt(schemeId, 10)
);
this.model.saveChanges("color_scheme_id");
}
@action
startEditingName() {
this.set("oldName", this.get("model.name"));
this.set("editingName", true);
}
@action
cancelEditingName() {
this.set("model.name", this.oldName);
this.set("editingName", false);
}
@action
finishedEditingName() {
this.model.saveChanges("name");
this.set("editingName", false);
}
@action
editTheme() {
if (this.get("model.remote_theme.is_git")) {
this.dialog.confirm({
message: I18n.t("admin.customize.theme.edit_confirm"),
didConfirm: () => this.transitionToEditRoute(),
}); });
}, } else {
this.transitionToEditRoute();
}
}
switchType() { @action
const relatives = this.get("model.component") applyDefault() {
? this.get("model.parentThemes") const model = this.model;
: this.get("model.childThemes"); model.saveChanges("default").then(() => {
if (model.get("default")) {
let message = I18n.t(`${this.convertKey}_alert_generic`); this.allThemes.forEach((theme) => {
if (theme !== model && theme.get("default")) {
if (relatives && relatives.length > 0) { theme.set("default", false);
message = I18n.t(`${this.convertKey}_alert`, { }
relatives: relatives
.map((relative) => relative.get("name"))
.join(", "),
}); });
} }
});
}
return this.dialog.yesNoConfirm({ @action
message, applyUserSelectable() {
didConfirm: () => this.commitSwitchType(), this.model.saveChanges("user_selectable");
}
@action
applyAutoUpdateable() {
this.model.saveChanges("auto_update");
}
@action
addChildTheme() {
let themeId = parseInt(this.selectedChildThemeId, 10);
let theme = this.allThemes.findBy("id", themeId);
this.model.addChildTheme(theme).then(() => this.store.findAll("theme"));
}
@action
removeUpload(upload) {
return this.dialog.yesNoConfirm({
message: I18n.t("admin.customize.theme.delete_upload_confirm"),
didConfirm: () => this.model.removeField(upload),
});
}
@action
removeChildTheme(theme) {
this.model.removeChildTheme(theme).then(() => this.store.findAll("theme"));
}
@action
destroyTheme() {
return this.dialog.yesNoConfirm({
message: I18n.t("admin.customize.delete_confirm", {
theme_name: this.get("model.name"),
}),
didConfirm: () => {
const model = this.model;
model.setProperties({ recentlyInstalled: false });
model.destroyRecord().then(() => {
this.allThemes.removeObject(model);
this.transitionToRoute("adminCustomizeThemes");
});
},
});
}
@action
switchType() {
const relatives = this.get("model.component")
? this.get("model.parentThemes")
: this.get("model.childThemes");
let message = I18n.t(`${this.convertKey}_alert_generic`);
if (relatives && relatives.length > 0) {
message = I18n.t(`${this.convertKey}_alert`, {
relatives: relatives.map((relative) => relative.get("name")).join(", "),
}); });
}, }
enableComponent() { return this.dialog.yesNoConfirm({
this.model.set("enabled", true); message,
this.model didConfirm: () => this.commitSwitchType(),
.saveChanges("enabled") });
.catch(() => this.model.set("enabled", false)); }
},
disableComponent() { @action
this.model.set("enabled", false); enableComponent() {
this.model this.model.set("enabled", true);
.saveChanges("enabled") this.model
.catch(() => this.model.set("enabled", true)); .saveChanges("enabled")
}, .catch(() => this.model.set("enabled", false));
}, }
});
@action
disableComponent() {
this.model.set("enabled", false);
this.model
.saveChanges("enabled")
.catch(() => this.model.set("enabled", true));
}
}

View File

@ -2,21 +2,21 @@ import Controller from "@ember/controller";
import { THEMES } from "admin/models/theme"; import { THEMES } from "admin/models/theme";
import discourseComputed from "discourse-common/utils/decorators"; import discourseComputed from "discourse-common/utils/decorators";
export default Controller.extend({ export default class AdminCustomizeThemesController extends Controller {
currentTab: THEMES, currentTab = THEMES;
@discourseComputed("model", "model.@each.component") @discourseComputed("model", "model.@each.component")
fullThemes(themes) { fullThemes(themes) {
return themes.filter((t) => !t.get("component")); return themes.filter((t) => !t.get("component"));
}, }
@discourseComputed("model", "model.@each.component") @discourseComputed("model", "model.@each.component")
childThemes(themes) { childThemes(themes) {
return themes.filter((t) => t.get("component")); return themes.filter((t) => t.get("component"));
}, }
@discourseComputed("model.content") @discourseComputed("model.content")
installedThemes(content) { installedThemes(content) {
return content || []; return content || [];
}, }
}); }

View File

@ -1,9 +1,9 @@
import { computed } from "@ember/object";
import Controller, { inject as controller } from "@ember/controller"; import Controller, { inject as controller } from "@ember/controller";
import AdminDashboard from "admin/models/admin-dashboard"; import AdminDashboard from "admin/models/admin-dashboard";
import I18n from "I18n"; import I18n from "I18n";
import PeriodComputationMixin from "admin/mixins/period-computation"; import PeriodComputationMixin from "admin/mixins/period-computation";
import Report from "admin/models/report"; import Report from "admin/models/report";
import { computed } from "@ember/object";
import discourseComputed from "discourse-common/utils/decorators"; import discourseComputed from "discourse-common/utils/decorators";
import getURL from "discourse-common/lib/get-url"; import getURL from "discourse-common/lib/get-url";
import { makeArray } from "discourse-common/lib/helpers"; import { makeArray } from "discourse-common/lib/helpers";
@ -15,41 +15,49 @@ function staticReport(reportType) {
}); });
} }
export default Controller.extend(PeriodComputationMixin, { export default class AdminDashboardGeneralController extends Controller.extend(
isLoading: false, PeriodComputationMixin
dashboardFetchedAt: null, ) {
exceptionController: controller("exception"), @controller("exception") exceptionController;
logSearchQueriesEnabled: setting("log_search_queries"),
isLoading = false;
dashboardFetchedAt = null;
@setting("log_search_queries") logSearchQueriesEnabled;
@staticReport("users_by_type") usersByTypeReport;
@staticReport("users_by_trust_level") usersByTrustLevelReport;
@staticReport("storage_report") storageReport;
@discourseComputed("siteSettings.dashboard_general_tab_activity_metrics") @discourseComputed("siteSettings.dashboard_general_tab_activity_metrics")
activityMetrics(metrics) { activityMetrics(metrics) {
return (metrics || "").split("|").filter(Boolean); return (metrics || "").split("|").filter(Boolean);
}, }
hiddenReports: computed("siteSettings.dashboard_hidden_reports", function () { @computed("siteSettings.dashboard_hidden_reports")
get hiddenReports() {
return (this.siteSettings.dashboard_hidden_reports || "") return (this.siteSettings.dashboard_hidden_reports || "")
.split("|") .split("|")
.filter(Boolean); .filter(Boolean);
}), }
isActivityMetricsVisible: computed( @computed("activityMetrics", "hiddenReports")
"activityMetrics", get isActivityMetricsVisible() {
"hiddenReports", return (
function () { this.activityMetrics.length &&
return ( this.activityMetrics.some((x) => !this.hiddenReports.includes(x))
this.activityMetrics.length && );
this.activityMetrics.some((x) => !this.hiddenReports.includes(x)) }
);
}
),
isSearchReportsVisible: computed("hiddenReports", function () { @computed("hiddenReports")
get isSearchReportsVisible() {
return ["top_referred_topics", "trending_search"].some( return ["top_referred_topics", "trending_search"].some(
(x) => !this.hiddenReports.includes(x) (x) => !this.hiddenReports.includes(x)
); );
}), }
isCommunityHealthVisible: computed("hiddenReports", function () { @computed("hiddenReports")
get isCommunityHealthVisible() {
return [ return [
"consolidated_page_views", "consolidated_page_views",
"signups", "signups",
@ -59,7 +67,7 @@ export default Controller.extend(PeriodComputationMixin, {
"daily_engaged_users", "daily_engaged_users",
"new_contributors", "new_contributors",
].some((x) => !this.hiddenReports.includes(x)); ].some((x) => !this.hiddenReports.includes(x));
}), }
@discourseComputed @discourseComputed
activityMetricsFilters() { activityMetricsFilters() {
@ -67,14 +75,14 @@ export default Controller.extend(PeriodComputationMixin, {
startDate: this.lastMonth, startDate: this.lastMonth,
endDate: this.today, endDate: this.today,
}; };
}, }
@discourseComputed @discourseComputed
topReferredTopicsOptions() { topReferredTopicsOptions() {
return { return {
table: { total: false, limit: 8 }, table: { total: false, limit: 8 },
}; };
}, }
@discourseComputed @discourseComputed
topReferredTopicsFilters() { topReferredTopicsFilters() {
@ -82,7 +90,7 @@ export default Controller.extend(PeriodComputationMixin, {
startDate: moment().subtract(6, "days").startOf("day"), startDate: moment().subtract(6, "days").startOf("day"),
endDate: this.today, endDate: this.today,
}; };
}, }
@discourseComputed @discourseComputed
trendingSearchFilters() { trendingSearchFilters() {
@ -90,25 +98,21 @@ export default Controller.extend(PeriodComputationMixin, {
startDate: moment().subtract(1, "month").startOf("day"), startDate: moment().subtract(1, "month").startOf("day"),
endDate: this.today, endDate: this.today,
}; };
}, }
@discourseComputed @discourseComputed
trendingSearchOptions() { trendingSearchOptions() {
return { return {
table: { total: false, limit: 8 }, table: { total: false, limit: 8 },
}; };
}, }
@discourseComputed @discourseComputed
trendingSearchDisabledLabel() { trendingSearchDisabledLabel() {
return I18n.t("admin.dashboard.reports.trending_search.disabled", { return I18n.t("admin.dashboard.reports.trending_search.disabled", {
basePath: getURL(""), basePath: getURL(""),
}); });
}, }
usersByTypeReport: staticReport("users_by_type"),
usersByTrustLevelReport: staticReport("users_by_trust_level"),
storageReport: staticReport("storage_report"),
fetchDashboard() { fetchDashboard() {
if (this.isLoading) { if (this.isLoading) {
@ -137,14 +141,14 @@ export default Controller.extend(PeriodComputationMixin, {
}) })
.finally(() => this.set("isLoading", false)); .finally(() => this.set("isLoading", false));
} }
}, }
@discourseComputed("startDate", "endDate") @discourseComputed("startDate", "endDate")
filters(startDate, endDate) { filters(startDate, endDate) {
return { startDate, endDate }; return { startDate, endDate };
}, }
_reportsForPeriodURL(period) { _reportsForPeriodURL(period) {
return getURL(`/admin?period=${period}`); return getURL(`/admin?period=${period}`);
}, }
}); }

View File

@ -1,10 +1,12 @@
import { computed } from "@ember/object";
import Controller from "@ember/controller"; import Controller from "@ember/controller";
import PeriodComputationMixin from "admin/mixins/period-computation"; import PeriodComputationMixin from "admin/mixins/period-computation";
import { computed } from "@ember/object";
import discourseComputed from "discourse-common/utils/decorators"; import discourseComputed from "discourse-common/utils/decorators";
import getURL from "discourse-common/lib/get-url"; import getURL from "discourse-common/lib/get-url";
export default Controller.extend(PeriodComputationMixin, { export default class AdminDashboardModerationController extends Controller.extend(
PeriodComputationMixin
) {
@discourseComputed @discourseComputed
flagsStatusOptions() { flagsStatusOptions() {
return { return {
@ -13,17 +15,15 @@ export default Controller.extend(PeriodComputationMixin, {
perPage: 10, perPage: 10,
}, },
}; };
}, }
isModeratorsActivityVisible: computed( @computed("siteSettings.dashboard_hidden_reports")
"siteSettings.dashboard_hidden_reports", get isModeratorsActivityVisible() {
function () { return !(this.siteSettings.dashboard_hidden_reports || "")
return !(this.siteSettings.dashboard_hidden_reports || "") .split("|")
.split("|") .filter(Boolean)
.filter(Boolean) .includes("moderators_activity");
.includes("moderators_activity"); }
}
),
@discourseComputed @discourseComputed
userFlaggingRatioOptions() { userFlaggingRatioOptions() {
@ -33,19 +33,19 @@ export default Controller.extend(PeriodComputationMixin, {
perPage: 10, perPage: 10,
}, },
}; };
}, }
@discourseComputed("startDate", "endDate") @discourseComputed("startDate", "endDate")
filters(startDate, endDate) { filters(startDate, endDate) {
return { startDate, endDate }; return { startDate, endDate };
}, }
@discourseComputed("lastWeek", "endDate") @discourseComputed("lastWeek", "endDate")
lastWeekfilters(startDate, endDate) { lastWeekfilters(startDate, endDate) {
return { startDate, endDate }; return { startDate, endDate };
}, }
_reportsForPeriodURL(period) { _reportsForPeriodURL(period) {
return getURL(`/admin/dashboard/moderation?period=${period}`); return getURL(`/admin/dashboard/moderation?period=${period}`);
}, }
}); }

View File

@ -2,10 +2,10 @@ import Controller from "@ember/controller";
import { INPUT_DELAY } from "discourse-common/config/environment"; import { INPUT_DELAY } from "discourse-common/config/environment";
import discourseComputed from "discourse-common/utils/decorators"; import discourseComputed from "discourse-common/utils/decorators";
import discourseDebounce from "discourse-common/lib/debounce"; import discourseDebounce from "discourse-common/lib/debounce";
import { get } from "@ember/object"; import { action, get } from "@ember/object";
export default Controller.extend({ export default class AdminDashboardReportsController extends Controller {
filter: null, filter = null;
@discourseComputed( @discourseComputed(
"model.[]", "model.[]",
@ -29,15 +29,14 @@ export default Controller.extend({
reports = reports.filter((report) => !hiddenReports.includes(report.type)); reports = reports.filter((report) => !hiddenReports.includes(report.type));
return reports; return reports;
}, }
actions: { @action
filterReports(filter) { filterReports(filter) {
discourseDebounce(this, this._performFiltering, filter, INPUT_DELAY); discourseDebounce(this, this._performFiltering, filter, INPUT_DELAY);
}, }
},
_performFiltering(filter) { _performFiltering(filter) {
this.set("filter", filter); this.set("filter", filter);
}, }
}); }

View File

@ -1,17 +1,19 @@
import { action, computed } from "@ember/object";
import Controller, { inject as controller } from "@ember/controller"; import Controller, { inject as controller } from "@ember/controller";
import AdminDashboard from "admin/models/admin-dashboard"; import AdminDashboard from "admin/models/admin-dashboard";
import VersionCheck from "admin/models/version-check"; import VersionCheck from "admin/models/version-check";
import { computed } from "@ember/object";
import discourseComputed from "discourse-common/utils/decorators"; import discourseComputed from "discourse-common/utils/decorators";
import { setting } from "discourse/lib/computed"; import { setting } from "discourse/lib/computed";
const PROBLEMS_CHECK_MINUTES = 1; const PROBLEMS_CHECK_MINUTES = 1;
export default Controller.extend({ export default class AdminDashboardController extends Controller {
isLoading: false, @controller("exception") exceptionController;
dashboardFetchedAt: null,
exceptionController: controller("exception"), isLoading = false;
showVersionChecks: setting("version_checks"), dashboardFetchedAt = null;
@setting("version_checks") showVersionChecks;
@discourseComputed( @discourseComputed(
"lowPriorityProblems.length", "lowPriorityProblems.length",
@ -21,25 +23,29 @@ export default Controller.extend({
const problemsLength = const problemsLength =
lowPriorityProblemsLength + highPriorityProblemsLength; lowPriorityProblemsLength + highPriorityProblemsLength;
return this.currentUser.admin && problemsLength > 0; return this.currentUser.admin && problemsLength > 0;
}, }
visibleTabs: computed("siteSettings.dashboard_visible_tabs", function () { @computed("siteSettings.dashboard_visible_tabs")
get visibleTabs() {
return (this.siteSettings.dashboard_visible_tabs || "") return (this.siteSettings.dashboard_visible_tabs || "")
.split("|") .split("|")
.filter(Boolean); .filter(Boolean);
}), }
isModerationTabVisible: computed("visibleTabs", function () { @computed("visibleTabs")
get isModerationTabVisible() {
return this.visibleTabs.includes("moderation"); return this.visibleTabs.includes("moderation");
}), }
isSecurityTabVisible: computed("visibleTabs", function () { @computed("visibleTabs")
get isSecurityTabVisible() {
return this.visibleTabs.includes("security"); return this.visibleTabs.includes("security");
}), }
isReportsTabVisible: computed("visibleTabs", function () { @computed("visibleTabs")
get isReportsTabVisible() {
return this.visibleTabs.includes("reports"); return this.visibleTabs.includes("reports");
}), }
fetchProblems() { fetchProblems() {
if (this.isLoadingProblems) { if (this.isLoadingProblems) {
@ -53,7 +59,7 @@ export default Controller.extend({
) { ) {
this._loadProblems(); this._loadProblems();
} }
}, }
fetchDashboard() { fetchDashboard() {
const versionChecks = this.siteSettings.version_checks; const versionChecks = this.siteSettings.version_checks;
@ -88,7 +94,7 @@ export default Controller.extend({
this.set("isLoading", false); this.set("isLoading", false);
}); });
} }
}, }
_loadProblems() { _loadProblems() {
this.setProperties({ this.setProperties({
@ -108,16 +114,15 @@ export default Controller.extend({
); );
}) })
.finally(() => this.set("loadingProblems", false)); .finally(() => this.set("loadingProblems", false));
}, }
@discourseComputed("problemsFetchedAt") @discourseComputed("problemsFetchedAt")
problemsTimestamp(problemsFetchedAt) { problemsTimestamp(problemsFetchedAt) {
return moment(problemsFetchedAt).locale("en").format("LLL"); return moment(problemsFetchedAt).locale("en").format("LLL");
}, }
actions: { @action
refreshProblems() { refreshProblems() {
this._loadProblems(); this._loadProblems();
}, }
}, }
});

View File

@ -1,31 +1,31 @@
import { action } from "@ember/object";
import Controller from "@ember/controller"; import Controller from "@ember/controller";
import { ajax } from "discourse/lib/ajax"; import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error"; import { popupAjaxError } from "discourse/lib/ajax-error";
export default Controller.extend({ export default class AdminEmailAdvancedTestController extends Controller {
email: null, email = null;
text: null, text = null;
elided: null, elided = null;
format: null, format = null;
loading: null, loading = null;
actions: { @action
run() { run() {
this.set("loading", true); this.set("loading", true);
ajax("/admin/email/advanced-test", { ajax("/admin/email/advanced-test", {
type: "POST", type: "POST",
data: { email: this.email }, data: { email: this.email },
})
.then((data) => {
this.setProperties({
text: data.text,
elided: data.elided,
format: data.format,
});
}) })
.then((data) => { .catch(popupAjaxError)
this.setProperties({ .finally(() => this.set("loading", false));
text: data.text, }
elided: data.elided, }
format: data.format,
});
})
.catch(popupAjaxError)
.finally(() => this.set("loading", false));
},
},
});

View File

@ -1,18 +1,18 @@
import AdminEmailLogsController from "admin/controllers/admin-email-logs"; import AdminEmailLogsController from "admin/controllers/admin-email-logs";
import { INPUT_DELAY } from "discourse-common/config/environment"; import { INPUT_DELAY } from "discourse-common/config/environment";
import discourseDebounce from "discourse-common/lib/debounce"; import discourseDebounce from "discourse-common/lib/debounce";
import { observes } from "discourse-common/utils/decorators"; import { observes } from "@ember-decorators/object";
import { action } from "@ember/object"; import { action } from "@ember/object";
export default AdminEmailLogsController.extend({ export default class AdminEmailBouncedController extends AdminEmailLogsController {
@action @action
handleShowIncomingEmail(id, event) { handleShowIncomingEmail(id, event) {
event?.preventDefault(); event?.preventDefault();
this.send("showIncomingEmail", id); this.send("showIncomingEmail", id);
}, }
@observes("filter.{status,user,address,type}") @observes("filter.{status,user,address,type}")
filterEmailLogs() { filterEmailLogs() {
discourseDebounce(this, this.loadLogs, INPUT_DELAY); discourseDebounce(this, this.loadLogs, INPUT_DELAY);
}, }
}); }

View File

@ -1,21 +1,22 @@
import { action } from "@ember/object";
import { inject as service } from "@ember/service";
import { empty } from "@ember/object/computed";
import Controller from "@ember/controller"; import Controller from "@ember/controller";
import I18n from "I18n"; import I18n from "I18n";
import { ajax } from "discourse/lib/ajax"; import { ajax } from "discourse/lib/ajax";
import { empty } from "@ember/object/computed"; import { observes } from "@ember-decorators/object";
import { observes } from "discourse-common/utils/decorators";
import { inject as service } from "@ember/service";
import { htmlSafe } from "@ember/template"; import { htmlSafe } from "@ember/template";
import { escapeExpression } from "discourse/lib/utilities"; import { escapeExpression } from "discourse/lib/utilities";
export default Controller.extend({ export default class AdminEmailIndexController extends Controller {
dialog: service(), @service dialog;
/** /**
Is the "send test email" button disabled? Is the "send test email" button disabled?
@property sendTestEmailDisabled @property sendTestEmailDisabled
**/ **/
sendTestEmailDisabled: empty("testEmailAddress"), @empty("testEmailAddress") sendTestEmailDisabled;
/** /**
Clears the 'sentTestEmail' property on successful send. Clears the 'sentTestEmail' property on successful send.
@ -25,43 +26,40 @@ export default Controller.extend({
@observes("testEmailAddress") @observes("testEmailAddress")
testEmailAddressChanged() { testEmailAddressChanged() {
this.set("sentTestEmail", false); this.set("sentTestEmail", false);
}, }
actions: { /**
/** Sends a test email to the currently entered email address
Sends a test email to the currently entered email address
@method sendTestEmail @method sendTestEmail
**/ **/
sendTestEmail() { @action
this.setProperties({ sendTestEmail() {
sendingEmail: true, this.setProperties({
sentTestEmail: false, sendingEmail: true,
}); sentTestEmail: false,
});
ajax("/admin/email/test", { ajax("/admin/email/test", {
type: "POST", type: "POST",
data: { email_address: this.testEmailAddress }, data: { email_address: this.testEmailAddress },
})
.then((response) =>
this.set("sentTestEmailMessage", response.sent_test_email_message)
)
.catch((e) => {
if (e.jqXHR.responseJSON?.errors) {
this.dialog.alert({
message: htmlSafe(
I18n.t("admin.email.error", {
server_error: escapeExpression(e.jqXHR.responseJSON.errors[0]),
})
),
});
} else {
this.dialog.alert({ message: I18n.t("admin.email.test_error") });
}
}) })
.then((response) => .finally(() => this.set("sendingEmail", false));
this.set("sentTestEmailMessage", response.sent_test_email_message) }
) }
.catch((e) => {
if (e.jqXHR.responseJSON?.errors) {
this.dialog.alert({
message: htmlSafe(
I18n.t("admin.email.error", {
server_error: escapeExpression(
e.jqXHR.responseJSON.errors[0]
),
})
),
});
} else {
this.dialog.alert({ message: I18n.t("admin.email.test_error") });
}
})
.finally(() => this.set("sendingEmail", false));
},
},
});

View File

@ -1,14 +1,11 @@
import Controller from "@ember/controller"; import Controller from "@ember/controller";
import EmailLog from "admin/models/email-log"; import EmailLog from "admin/models/email-log";
import EmberObject from "@ember/object"; import EmberObject, { action } from "@ember/object";
export default Controller.extend({ export default class AdminEmailLogsController extends Controller {
loading: false, loading = false;
filter = EmberObject.create();
init() {
this._super(...arguments);
this.set("filter", EmberObject.create());
},
loadLogs(sourceModel, loadMore) { loadLogs(sourceModel, loadMore) {
if ((loadMore && this.loading) || this.get("model.allLoaded")) { if ((loadMore && this.loading) || this.get("model.allLoaded")) {
return; return;
@ -38,11 +35,10 @@ export default Controller.extend({
} }
}) })
.finally(() => this.set("loading", false)); .finally(() => this.set("loading", false));
}, }
actions: { @action
loadMore() { loadMore() {
this.loadLogs(EmailLog, true); this.loadLogs(EmailLog, true);
}, }
}, }
});

View File

@ -1,66 +1,67 @@
import { inject as service } from "@ember/service";
import { empty, notEmpty, or } from "@ember/object/computed"; import { empty, notEmpty, or } from "@ember/object/computed";
import Controller from "@ember/controller"; import Controller from "@ember/controller";
import EmailPreview from "admin/models/email-preview"; import EmailPreview from "admin/models/email-preview";
import { action, get } from "@ember/object"; import { action, get } from "@ember/object";
import { popupAjaxError } from "discourse/lib/ajax-error"; import { popupAjaxError } from "discourse/lib/ajax-error";
import { inject as service } from "@ember/service";
export default Controller.extend({ export default class AdminEmailPreviewDigestController extends Controller {
dialog: service(), @service dialog;
username: null,
lastSeen: null, username = null;
emailEmpty: empty("email"), lastSeen = null;
sendEmailDisabled: or("emailEmpty", "sendingEmail"),
showSendEmailForm: notEmpty("model.html_content"), @empty("email") emailEmpty;
htmlEmpty: empty("model.html_content"), @or("emailEmpty", "sendingEmail") sendEmailDisabled;
@notEmpty("model.html_content") showSendEmailForm;
@empty("model.html_content") htmlEmpty;
@action @action
toggleShowHtml(event) { toggleShowHtml(event) {
event?.preventDefault(); event?.preventDefault();
this.toggleProperty("showHtml"); this.toggleProperty("showHtml");
}, }
actions: { @action
updateUsername(selected) { updateUsername(selected) {
this.set("username", get(selected, "firstObject")); this.set("username", get(selected, "firstObject"));
}, }
refresh() { @action
const model = this.model; refresh() {
const model = this.model;
this.set("loading", true); this.set("loading", true);
this.set("sentEmail", false); this.set("sentEmail", false);
let username = this.username; let username = this.username;
if (!username) { if (!username) {
username = this.currentUser.get("username"); username = this.currentUser.get("username");
this.set("username", username); this.set("username", username);
} }
EmailPreview.findDigest(username, this.lastSeen).then((email) => { EmailPreview.findDigest(username, this.lastSeen).then((email) => {
model.setProperties( model.setProperties(email.getProperties("html_content", "text_content"));
email.getProperties("html_content", "text_content") this.set("loading", false);
); });
this.set("loading", false); }
@action
sendEmail() {
this.set("sendingEmail", true);
this.set("sentEmail", false);
EmailPreview.sendDigest(this.username, this.lastSeen, this.email)
.then((result) => {
if (result.errors) {
this.dialog.alert(result.errors);
} else {
this.set("sentEmail", true);
}
})
.catch(popupAjaxError)
.finally(() => {
this.set("sendingEmail", false);
}); });
}, }
}
sendEmail() {
this.set("sendingEmail", true);
this.set("sentEmail", false);
EmailPreview.sendDigest(this.username, this.lastSeen, this.email)
.then((result) => {
if (result.errors) {
this.dialog.alert(result.errors);
} else {
this.set("sentEmail", true);
}
})
.catch(popupAjaxError)
.finally(() => {
this.set("sendingEmail", false);
});
},
},
});

View File

@ -1,18 +1,18 @@
import { action } from "@ember/object";
import AdminEmailLogsController from "admin/controllers/admin-email-logs"; import AdminEmailLogsController from "admin/controllers/admin-email-logs";
import { INPUT_DELAY } from "discourse-common/config/environment"; import { INPUT_DELAY } from "discourse-common/config/environment";
import IncomingEmail from "admin/models/incoming-email"; import IncomingEmail from "admin/models/incoming-email";
import discourseDebounce from "discourse-common/lib/debounce"; import discourseDebounce from "discourse-common/lib/debounce";
import { observes } from "discourse-common/utils/decorators"; import { observes } from "@ember-decorators/object";
export default AdminEmailLogsController.extend({ export default class AdminEmailReceivedController extends AdminEmailLogsController {
@observes("filter.{status,from,to,subject}") @observes("filter.{status,from,to,subject}")
filterIncomingEmails() { filterIncomingEmails() {
discourseDebounce(this, this.loadLogs, IncomingEmail, INPUT_DELAY); discourseDebounce(this, this.loadLogs, IncomingEmail, INPUT_DELAY);
}, }
actions: { @action
loadMore() { loadMore() {
this.loadLogs(IncomingEmail, true); this.loadLogs(IncomingEmail, true);
}, }
}, }
});

View File

@ -2,24 +2,23 @@ import AdminEmailLogsController from "admin/controllers/admin-email-logs";
import { INPUT_DELAY } from "discourse-common/config/environment"; import { INPUT_DELAY } from "discourse-common/config/environment";
import IncomingEmail from "admin/models/incoming-email"; import IncomingEmail from "admin/models/incoming-email";
import discourseDebounce from "discourse-common/lib/debounce"; import discourseDebounce from "discourse-common/lib/debounce";
import { observes } from "discourse-common/utils/decorators"; import { observes } from "@ember-decorators/object";
import { action } from "@ember/object"; import { action } from "@ember/object";
export default AdminEmailLogsController.extend({ export default class AdminEmailRejectedController extends AdminEmailLogsController {
@observes("filter.{status,from,to,subject,error}") @observes("filter.{status,from,to,subject,error}")
filterIncomingEmails() { filterIncomingEmails() {
discourseDebounce(this, this.loadLogs, IncomingEmail, INPUT_DELAY); discourseDebounce(this, this.loadLogs, IncomingEmail, INPUT_DELAY);
}, }
@action @action
handleShowIncomingEmail(id, event) { handleShowIncomingEmail(id, event) {
event?.preventDefault(); event?.preventDefault();
this.send("showIncomingEmail", id); this.send("showIncomingEmail", id);
}, }
actions: { @action
loadMore() { loadMore() {
this.loadLogs(IncomingEmail, true); this.loadLogs(IncomingEmail, true);
}, }
}, }
});

View File

@ -1,11 +1,11 @@
import AdminEmailLogsController from "admin/controllers/admin-email-logs"; import AdminEmailLogsController from "admin/controllers/admin-email-logs";
import { INPUT_DELAY } from "discourse-common/config/environment"; import { INPUT_DELAY } from "discourse-common/config/environment";
import discourseDebounce from "discourse-common/lib/debounce"; import discourseDebounce from "discourse-common/lib/debounce";
import { observes } from "discourse-common/utils/decorators"; import { observes } from "@ember-decorators/object";
export default AdminEmailLogsController.extend({ export default class AdminEmailSentController extends AdminEmailLogsController {
@observes("filter.{status,user,address,type,reply_key}") @observes("filter.{status,user,address,type,reply_key}")
filterEmailLogs() { filterEmailLogs() {
discourseDebounce(this, this.loadLogs, INPUT_DELAY); discourseDebounce(this, this.loadLogs, INPUT_DELAY);
}, }
}); }

View File

@ -1,11 +1,11 @@
import AdminEmailLogsController from "admin/controllers/admin-email-logs"; import AdminEmailLogsController from "admin/controllers/admin-email-logs";
import { INPUT_DELAY } from "discourse-common/config/environment"; import { INPUT_DELAY } from "discourse-common/config/environment";
import discourseDebounce from "discourse-common/lib/debounce"; import discourseDebounce from "discourse-common/lib/debounce";
import { observes } from "discourse-common/utils/decorators"; import { observes } from "@ember-decorators/object";
export default AdminEmailLogsController.extend({ export default class AdminEmailSkippedController extends AdminEmailLogsController {
@observes("filter.{status,user,address,type}") @observes("filter.{status,user,address,type}")
filterEmailLogs() { filterEmailLogs() {
discourseDebounce(this, this.loadLogs, INPUT_DELAY); discourseDebounce(this, this.loadLogs, INPUT_DELAY);
}, }
}); }

View File

@ -1,17 +1,18 @@
import { action } from "@ember/object";
import Controller from "@ember/controller"; import Controller from "@ember/controller";
import discourseComputed from "discourse-common/utils/decorators"; import discourseComputed from "discourse-common/utils/decorators";
import { popupAjaxError } from "discourse/lib/ajax-error"; import { popupAjaxError } from "discourse/lib/ajax-error";
export default Controller.extend({ export default class AdminEmbeddingController extends Controller {
saved: false, saved = false;
embedding: null, embedding = null;
// show settings if we have at least one created host // show settings if we have at least one created host
@discourseComputed("embedding.embeddable_hosts.@each.isCreated") @discourseComputed("embedding.embeddable_hosts.@each.isCreated")
showSecondary() { showSecondary() {
const hosts = this.get("embedding.embeddable_hosts"); const hosts = this.get("embedding.embeddable_hosts");
return hosts.length && hosts.findBy("isCreated"); return hosts.length && hosts.findBy("isCreated");
}, }
@discourseComputed("embedding.base_url") @discourseComputed("embedding.base_url")
embeddingCode(baseUrl) { embeddingCode(baseUrl) {
@ -33,27 +34,28 @@ export default Controller.extend({
</script>`; </script>`;
return html; return html;
}, }
actions: { @action
saveChanges() { saveChanges() {
const embedding = this.embedding; const embedding = this.embedding;
const updates = embedding.getProperties(embedding.get("fields")); const updates = embedding.getProperties(embedding.get("fields"));
this.set("saved", false); this.set("saved", false);
this.embedding this.embedding
.update(updates) .update(updates)
.then(() => this.set("saved", true)) .then(() => this.set("saved", true))
.catch(popupAjaxError); .catch(popupAjaxError);
}, }
addHost() { @action
const host = this.store.createRecord("embeddable-host"); addHost() {
this.get("embedding.embeddable_hosts").pushObject(host); const host = this.store.createRecord("embeddable-host");
}, this.get("embedding.embeddable_hosts").pushObject(host);
}
deleteHost(host) { @action
this.get("embedding.embeddable_hosts").removeObject(host); deleteHost(host) {
}, this.get("embedding.embeddable_hosts").removeObject(host);
}, }
}); }

View File

@ -1,49 +1,46 @@
import { inject as service } from "@ember/service";
import { sort } from "@ember/object/computed";
import EmberObject, { action, computed } from "@ember/object"; import EmberObject, { action, computed } from "@ember/object";
import Controller from "@ember/controller"; import Controller from "@ember/controller";
import I18n from "I18n"; import I18n from "I18n";
import { ajax } from "discourse/lib/ajax"; import { ajax } from "discourse/lib/ajax";
import { sort } from "@ember/object/computed";
import { inject as service } from "@ember/service";
const ALL_FILTER = "all"; const ALL_FILTER = "all";
export default Controller.extend({ export default class AdminEmojisController extends Controller {
dialog: service(), @service dialog;
filter: null,
sorting: null,
filter = null;
sorting = null;
@sort("filteredEmojis.[]", "sorting") sortedEmojis;
init() { init() {
this._super(...arguments); super.init(...arguments);
this.setProperties({ this.setProperties({
filter: ALL_FILTER, filter: ALL_FILTER,
sorting: ["group", "name"], sorting: ["group", "name"],
}); });
}, }
sortedEmojis: sort("filteredEmojis.[]", "sorting"), @computed("model")
get emojiGroups() {
return this.model.mapBy("group").uniq();
}
emojiGroups: computed("model", { @computed("emojiGroups.[]")
get() { get sortingGroups() {
return this.model.mapBy("group").uniq(); return [ALL_FILTER].concat(this.emojiGroups);
}, }
}),
sortingGroups: computed("emojiGroups.[]", { @computed("model.[]", "filter")
get() { get filteredEmojis() {
return [ALL_FILTER].concat(this.emojiGroups); if (!this.filter || this.filter === ALL_FILTER) {
}, return this.model;
}), } else {
return this.model.filterBy("group", this.filter);
filteredEmojis: computed("model.[]", "filter", { }
get() { }
if (!this.filter || this.filter === ALL_FILTER) {
return this.model;
} else {
return this.model.filterBy("group", this.filter);
}
},
}),
_highlightEmojiList() { _highlightEmojiList() {
const customEmojiListEl = document.querySelector("#custom_emoji"); const customEmojiListEl = document.querySelector("#custom_emoji");
@ -56,12 +53,12 @@ export default Controller.extend({
customEmojiListEl.classList.remove("highlighted"); customEmojiListEl.classList.remove("highlighted");
}); });
} }
}, }
@action @action
filterGroups(value) { filterGroups(value) {
this.set("filter", value); this.set("filter", value);
}, }
@action @action
emojiUploaded(emoji, group) { emojiUploaded(emoji, group) {
@ -69,7 +66,7 @@ export default Controller.extend({
emoji.group = group; emoji.group = group;
this.model.pushObject(EmberObject.create(emoji)); this.model.pushObject(EmberObject.create(emoji));
this._highlightEmojiList(); this._highlightEmojiList();
}, }
@action @action
destroyEmoji(emoji) { destroyEmoji(emoji) {
@ -85,5 +82,5 @@ export default Controller.extend({
}); });
}, },
}); });
}, }
}); }

View File

@ -1,23 +1,24 @@
import { action } from "@ember/object";
import Controller from "@ember/controller"; import Controller from "@ember/controller";
import ScreenedEmail from "admin/models/screened-email"; import ScreenedEmail from "admin/models/screened-email";
import { exportEntity } from "discourse/lib/export-csv"; import { exportEntity } from "discourse/lib/export-csv";
import { outputExportResult } from "discourse/lib/export-result"; import { outputExportResult } from "discourse/lib/export-result";
export default Controller.extend({ export default class AdminLogsScreenedEmailsController extends Controller {
loading: false, loading = false;
actions: { @action
clearBlock(row) { clearBlock(row) {
row.clearBlock().then(function () { row.clearBlock().then(function () {
// feeling lazy // feeling lazy
window.location.reload(); window.location.reload();
}); });
}, }
exportScreenedEmailList() { @action
exportEntity("screened_email").then(outputExportResult); exportScreenedEmailList() {
}, exportEntity("screened_email").then(outputExportResult);
}, }
show() { show() {
this.set("loading", true); this.set("loading", true);
@ -25,5 +26,5 @@ export default Controller.extend({
this.set("model", result); this.set("model", result);
this.set("loading", false); this.set("loading", false);
}); });
}, }
}); }

View File

@ -1,31 +1,32 @@
import { inject as service } from "@ember/service";
import Controller from "@ember/controller"; import Controller from "@ember/controller";
import I18n from "I18n"; import I18n from "I18n";
import { INPUT_DELAY } from "discourse-common/config/environment"; import { INPUT_DELAY } from "discourse-common/config/environment";
import ScreenedIpAddress from "admin/models/screened-ip-address"; import ScreenedIpAddress from "admin/models/screened-ip-address";
import discourseDebounce from "discourse-common/lib/debounce"; import discourseDebounce from "discourse-common/lib/debounce";
import { exportEntity } from "discourse/lib/export-csv"; import { exportEntity } from "discourse/lib/export-csv";
import { observes } from "discourse-common/utils/decorators"; import { observes } from "@ember-decorators/object";
import { outputExportResult } from "discourse/lib/export-result"; import { outputExportResult } from "discourse/lib/export-result";
import { action } from "@ember/object"; import { action } from "@ember/object";
import { inject as service } from "@ember/service";
export default Controller.extend({ export default class AdminLogsScreenedIpAddressesController extends Controller {
dialog: service(), @service dialog;
loading: false,
filter: null, loading = false;
savedIpAddress: null, filter = null;
savedIpAddress = null;
_debouncedShow() { _debouncedShow() {
this.set("loading", true); this.set("loading", true);
ScreenedIpAddress.findAll(this.filter).then((result) => { ScreenedIpAddress.findAll(this.filter).then((result) => {
this.setProperties({ model: result, loading: false }); this.setProperties({ model: result, loading: false });
}); });
}, }
@observes("filter") @observes("filter")
show() { show() {
discourseDebounce(this, this._debouncedShow, INPUT_DELAY); discourseDebounce(this, this._debouncedShow, INPUT_DELAY);
}, }
@action @action
edit(record, event) { edit(record, event) {
@ -34,81 +35,86 @@ export default Controller.extend({
this.set("savedIpAddress", record.get("ip_address")); this.set("savedIpAddress", record.get("ip_address"));
} }
record.set("editing", true); record.set("editing", true);
}, }
actions: { @action
allow(record) { allow(record) {
record.set("action_name", "do_nothing"); record.set("action_name", "do_nothing");
record.save(); record.save();
}, }
block(record) { @action
record.set("action_name", "block"); block(record) {
record.save(); record.set("action_name", "block");
}, record.save();
}
cancel(record) { @action
const savedIpAddress = this.savedIpAddress; cancel(record) {
if (savedIpAddress && record.get("editing")) { const savedIpAddress = this.savedIpAddress;
record.set("ip_address", savedIpAddress); if (savedIpAddress && record.get("editing")) {
} record.set("ip_address", savedIpAddress);
record.set("editing", false); }
}, record.set("editing", false);
}
save(record) { @action
const wasEditing = record.get("editing"); save(record) {
record.set("editing", false); const wasEditing = record.get("editing");
record record.set("editing", false);
.save() record
.then(() => this.set("savedIpAddress", null)) .save()
.catch((e) => { .then(() => this.set("savedIpAddress", null))
if (e.jqXHR.responseJSON && e.jqXHR.responseJSON.errors) { .catch((e) => {
if (e.jqXHR.responseJSON && e.jqXHR.responseJSON.errors) {
this.dialog.alert(
I18n.t("generic_error_with_reason", {
error: e.jqXHR.responseJSON.errors.join(". "),
})
);
} else {
this.dialog.alert(I18n.t("generic_error"));
}
if (wasEditing) {
record.set("editing", true);
}
});
}
@action
destroyRecord(record) {
return this.dialog.yesNoConfirm({
message: I18n.t("admin.logs.screened_ips.delete_confirm", {
ip_address: record.get("ip_address"),
}),
didConfirm: () => {
return record
.destroy()
.then((deleted) => {
if (deleted) {
this.model.removeObject(record);
} else {
this.dialog.alert(I18n.t("generic_error"));
}
})
.catch((e) => {
this.dialog.alert( this.dialog.alert(
I18n.t("generic_error_with_reason", { I18n.t("generic_error_with_reason", {
error: e.jqXHR.responseJSON.errors.join(". "), error: `http: ${e.status} - ${e.body}`,
}) })
); );
} else { });
this.dialog.alert(I18n.t("generic_error")); },
} });
if (wasEditing) { }
record.set("editing", true);
}
});
},
destroy(record) { @action
return this.dialog.yesNoConfirm({ recordAdded(arg) {
message: I18n.t("admin.logs.screened_ips.delete_confirm", { this.model.unshiftObject(arg);
ip_address: record.get("ip_address"), }
}),
didConfirm: () => {
return record
.destroy()
.then((deleted) => {
if (deleted) {
this.model.removeObject(record);
} else {
this.dialog.alert(I18n.t("generic_error"));
}
})
.catch((e) => {
this.dialog.alert(
I18n.t("generic_error_with_reason", {
error: `http: ${e.status} - ${e.body}`,
})
);
});
},
});
},
recordAdded(arg) { @action
this.model.unshiftObject(arg); exportScreenedIpList() {
}, exportEntity("screened_ip").then(outputExportResult);
}
exportScreenedIpList() { }
exportEntity("screened_ip").then(outputExportResult);
},
},
});

View File

@ -1,10 +1,11 @@
import { action } from "@ember/object";
import Controller from "@ember/controller"; import Controller from "@ember/controller";
import ScreenedUrl from "admin/models/screened-url"; import ScreenedUrl from "admin/models/screened-url";
import { exportEntity } from "discourse/lib/export-csv"; import { exportEntity } from "discourse/lib/export-csv";
import { outputExportResult } from "discourse/lib/export-result"; import { outputExportResult } from "discourse/lib/export-result";
export default Controller.extend({ export default class AdminLogsScreenedUrlsController extends Controller {
loading: false, loading = false;
show() { show() {
this.set("loading", true); this.set("loading", true);
@ -12,11 +13,10 @@ export default Controller.extend({
this.set("model", result); this.set("model", result);
this.set("loading", false); this.set("loading", false);
}); });
}, }
actions: { @action
exportScreenedUrlList() { exportScreenedUrlList() {
exportEntity("screened_url").then(outputExportResult); exportEntity("screened_url").then(outputExportResult);
}, }
}, }
});

View File

@ -7,22 +7,21 @@ import { outputExportResult } from "discourse/lib/export-result";
import { scheduleOnce } from "@ember/runloop"; import { scheduleOnce } from "@ember/runloop";
import showModal from "discourse/lib/show-modal"; import showModal from "discourse/lib/show-modal";
export default Controller.extend({ export default class AdminLogsStaffActionLogsController extends Controller {
queryParams: ["filters"], queryParams = ["filters"];
model = null;
model: null, filters = null;
filters: null, userHistoryActions = null;
userHistoryActions: null,
@discourseComputed("filters.action_name") @discourseComputed("filters.action_name")
actionFilter(name) { actionFilter(name) {
return name ? I18n.t("admin.logs.staff_actions.actions." + name) : null; return name ? I18n.t("admin.logs.staff_actions.actions." + name) : null;
}, }
@discourseComputed("filters") @discourseComputed("filters")
filtersExists(filters) { filtersExists(filters) {
return filters && Object.keys(filters).length > 0; return filters && Object.keys(filters).length > 0;
}, }
_refresh() { _refresh() {
this.store.findAll("staff-action-log", this.filters).then((result) => { this.store.findAll("staff-action-log", this.filters).then((result) => {
@ -44,11 +43,11 @@ export default Controller.extend({
); );
} }
}); });
}, }
scheduleRefresh() { scheduleRefresh() {
scheduleOnce("afterRender", this, this._refresh); scheduleOnce("afterRender", this, this._refresh);
}, }
resetFilters() { resetFilters() {
this.setProperties({ this.setProperties({
@ -56,7 +55,7 @@ export default Controller.extend({
filters: EmberObject.create(), filters: EmberObject.create(),
}); });
this.scheduleRefresh(); this.scheduleRefresh();
}, }
changeFilters(props) { changeFilters(props) {
this.set("model", EmberObject.create({ loadingMore: true })); this.set("model", EmberObject.create({ loadingMore: true }));
@ -76,7 +75,7 @@ export default Controller.extend({
this.send("onFiltersChange", this.filters); this.send("onFiltersChange", this.filters);
this.scheduleRefresh(); this.scheduleRefresh();
}, }
@action @action
filterActionIdChanged(filterActionId) { filterActionIdChanged(filterActionId) {
@ -87,7 +86,7 @@ export default Controller.extend({
.action_id, .action_id,
}); });
} }
}, }
@action @action
clearFilter(key, event) { clearFilter(key, event) {
@ -102,14 +101,14 @@ export default Controller.extend({
} else { } else {
this.changeFilters({ [key]: null }); this.changeFilters({ [key]: null });
} }
}, }
@action @action
clearAllFilters(event) { clearAllFilters(event) {
event?.preventDefault(); event?.preventDefault();
this.set("filterActionId", null); this.set("filterActionId", null);
this.resetFilters(); this.resetFilters();
}, }
@action @action
filterByAction(logItem, event) { filterByAction(logItem, event) {
@ -119,35 +118,35 @@ export default Controller.extend({
action_id: logItem.get("action"), action_id: logItem.get("action"),
custom_type: logItem.get("custom_type"), custom_type: logItem.get("custom_type"),
}); });
}, }
@action @action
filterByStaffUser(acting_user, event) { filterByStaffUser(acting_user, event) {
event?.preventDefault(); event?.preventDefault();
this.changeFilters({ acting_user: acting_user.username }); this.changeFilters({ acting_user: acting_user.username });
}, }
@action @action
filterByTargetUser(target_user, event) { filterByTargetUser(target_user, event) {
event?.preventDefault(); event?.preventDefault();
this.changeFilters({ target_user: target_user.username }); this.changeFilters({ target_user: target_user.username });
}, }
@action @action
filterBySubject(subject, event) { filterBySubject(subject, event) {
event?.preventDefault(); event?.preventDefault();
this.changeFilters({ subject }); this.changeFilters({ subject });
}, }
@action @action
exportStaffActionLogs() { exportStaffActionLogs() {
exportEntity("staff_action").then(outputExportResult); exportEntity("staff_action").then(outputExportResult);
}, }
@action @action
loadMore() { loadMore() {
this.model.loadMore(); this.model.loadMore();
}, }
@action @action
showDetailsModal(model, event) { showDetailsModal(model, event) {
@ -157,7 +156,7 @@ export default Controller.extend({
admin: true, admin: true,
modalClass: "log-details-modal", modalClass: "log-details-modal",
}); });
}, }
@action @action
showCustomDetailsModal(model, event) { showCustomDetailsModal(model, event) {
@ -168,5 +167,5 @@ export default Controller.extend({
modalClass: "history-modal", modalClass: "history-modal",
}); });
modal.loadDiff(); modal.loadDiff();
}, }
}); }

View File

@ -1,59 +1,63 @@
import { action } from "@ember/object";
import { inject as service } from "@ember/service";
import { or } from "@ember/object/computed";
import Controller from "@ember/controller"; import Controller from "@ember/controller";
import I18n from "I18n"; import I18n from "I18n";
import { INPUT_DELAY } from "discourse-common/config/environment"; import { INPUT_DELAY } from "discourse-common/config/environment";
import Permalink from "admin/models/permalink"; import Permalink from "admin/models/permalink";
import discourseDebounce from "discourse-common/lib/debounce"; import discourseDebounce from "discourse-common/lib/debounce";
import { observes } from "discourse-common/utils/decorators"; import { observes } from "@ember-decorators/object";
import { clipboardCopy } from "discourse/lib/utilities"; import { clipboardCopy } from "discourse/lib/utilities";
import { inject as service } from "@ember/service";
import { or } from "@ember/object/computed";
export default Controller.extend({ export default class AdminPermalinksController extends Controller {
dialog: service(), @service dialog;
loading: false,
filter: null, loading = false;
showSearch: or("model.length", "filter"), filter = null;
@or("model.length", "filter") showSearch;
_debouncedShow() { _debouncedShow() {
Permalink.findAll(this.filter).then((result) => { Permalink.findAll(this.filter).then((result) => {
this.set("model", result); this.set("model", result);
this.set("loading", false); this.set("loading", false);
}); });
}, }
@observes("filter") @observes("filter")
show() { show() {
discourseDebounce(this, this._debouncedShow, INPUT_DELAY); discourseDebounce(this, this._debouncedShow, INPUT_DELAY);
}, }
actions: { @action
recordAdded(arg) { recordAdded(arg) {
this.model.unshiftObject(arg); this.model.unshiftObject(arg);
}, }
copyUrl(pl) { @action
let linkElement = document.querySelector(`#admin-permalink-${pl.id}`); copyUrl(pl) {
clipboardCopy(linkElement.textContent); let linkElement = document.querySelector(`#admin-permalink-${pl.id}`);
}, clipboardCopy(linkElement.textContent);
}
destroy(record) { @action
return this.dialog.yesNoConfirm({ destroyRecord(record) {
message: I18n.t("admin.permalink.delete_confirm"), return this.dialog.yesNoConfirm({
didConfirm: () => { message: I18n.t("admin.permalink.delete_confirm"),
return record.destroy().then( didConfirm: () => {
(deleted) => { return record.destroy().then(
if (deleted) { (deleted) => {
this.model.removeObject(record); if (deleted) {
} else { this.model.removeObject(record);
this.dialog.alert(I18n.t("generic_error")); } else {
}
},
function () {
this.dialog.alert(I18n.t("generic_error")); this.dialog.alert(I18n.t("generic_error"));
} }
); },
}, function () {
}); this.dialog.alert(I18n.t("generic_error"));
}, }
}, );
}); },
});
}
}

View File

@ -1,18 +1,18 @@
import Controller from "@ember/controller";
import { inject as service } from "@ember/service"; import { inject as service } from "@ember/service";
import Controller from "@ember/controller";
export default Controller.extend({ export default class AdminPluginsController extends Controller {
router: service(), @service router;
get adminRoutes() { get adminRoutes() {
return this.allAdminRoutes.filter((r) => this.routeExists(r.full_location)); return this.allAdminRoutes.filter((r) => this.routeExists(r.full_location));
}, }
get brokenAdminRoutes() { get brokenAdminRoutes() {
return this.allAdminRoutes.filter( return this.allAdminRoutes.filter(
(r) => !this.routeExists(r.full_location) (r) => !this.routeExists(r.full_location)
); );
}, }
get allAdminRoutes() { get allAdminRoutes() {
return this.model return this.model
@ -21,7 +21,7 @@ export default Controller.extend({
return p.admin_route; return p.admin_route;
}) })
.filter(Boolean); .filter(Boolean);
}, }
routeExists(routeName) { routeExists(routeName) {
try { try {
@ -30,5 +30,5 @@ export default Controller.extend({
} catch (e) { } catch (e) {
return false; return false;
} }
}, }
}); }

View File

@ -1,12 +1,12 @@
import Controller from "@ember/controller"; import Controller from "@ember/controller";
import discourseComputed from "discourse-common/utils/decorators"; import discourseComputed from "discourse-common/utils/decorators";
export default Controller.extend({ export default class AdminReportsShowController extends Controller {
queryParams: ["start_date", "end_date", "filters", "chart_grouping", "mode"], queryParams = ["start_date", "end_date", "filters", "chart_grouping", "mode"];
start_date: null, start_date = null;
end_date: null, end_date = null;
filters: null, filters = null;
chart_grouping: null, chart_grouping = null;
@discourseComputed("model.type") @discourseComputed("model.type")
reportOptions(type) { reportOptions(type) {
@ -19,5 +19,5 @@ export default Controller.extend({
options.chartGrouping = this.chart_grouping; options.chartGrouping = this.chart_grouping;
return options; return options;
}, }
}); }

View File

@ -2,24 +2,19 @@ import Controller from "@ember/controller";
import I18n from "I18n"; import I18n from "I18n";
export const DEFAULT_PERIOD = "yearly"; export const DEFAULT_PERIOD = "yearly";
export default Controller.extend({ export default class AdminSearchLogsIndexController extends Controller {
loading: false, loading = false;
period: DEFAULT_PERIOD, period = DEFAULT_PERIOD;
searchType: "all", searchType = "all";
searchTypeOptions = [
init() { {
this._super(...arguments); id: "all",
name: I18n.t("admin.logs.search_logs.types.all_search_types"),
this.searchTypeOptions = [ },
{ { id: "header", name: I18n.t("admin.logs.search_logs.types.header") },
id: "all", {
name: I18n.t("admin.logs.search_logs.types.all_search_types"), id: "full_page",
}, name: I18n.t("admin.logs.search_logs.types.full_page"),
{ id: "header", name: I18n.t("admin.logs.search_logs.types.header") }, },
{ ];
id: "full_page", }
name: I18n.t("admin.logs.search_logs.types.full_page"),
},
];
},
});

View File

@ -2,29 +2,24 @@ import Controller from "@ember/controller";
import { DEFAULT_PERIOD } from "admin/controllers/admin-search-logs-index"; import { DEFAULT_PERIOD } from "admin/controllers/admin-search-logs-index";
import I18n from "I18n"; import I18n from "I18n";
export default Controller.extend({ export default class AdminSearchLogsTermController extends Controller {
loading: false, loading = false;
term: null, term = null;
period: DEFAULT_PERIOD, period = DEFAULT_PERIOD;
searchType: "all", searchType = "all";
searchTypeOptions = [
init() { {
this._super(...arguments); id: "all",
name: I18n.t("admin.logs.search_logs.types.all_search_types"),
this.searchTypeOptions = [ },
{ { id: "header", name: I18n.t("admin.logs.search_logs.types.header") },
id: "all", {
name: I18n.t("admin.logs.search_logs.types.all_search_types"), id: "full_page",
}, name: I18n.t("admin.logs.search_logs.types.full_page"),
{ id: "header", name: I18n.t("admin.logs.search_logs.types.header") }, },
{ {
id: "full_page", id: "click_through_only",
name: I18n.t("admin.logs.search_logs.types.full_page"), name: I18n.t("admin.logs.search_logs.types.click_through_only"),
}, },
{ ];
id: "click_through_only", }
name: I18n.t("admin.logs.search_logs.types.click_through_only"),
},
];
},
});

View File

@ -1,17 +1,18 @@
import Controller, { inject as controller } from "@ember/controller"; import Controller, { inject as controller } from "@ember/controller";
import discourseComputed from "discourse-common/utils/decorators"; import discourseComputed from "discourse-common/utils/decorators";
export default Controller.extend({ export default class AdminSiteSettingsCategoryController extends Controller {
adminSiteSettings: controller(), @controller adminSiteSettings;
categoryNameKey: null,
categoryNameKey = null;
@discourseComputed("adminSiteSettings.visibleSiteSettings", "categoryNameKey") @discourseComputed("adminSiteSettings.visibleSiteSettings", "categoryNameKey")
category(categories, nameKey) { category(categories, nameKey) {
return (categories || []).findBy("nameKey", nameKey); return (categories || []).findBy("nameKey", nameKey);
}, }
@discourseComputed("category") @discourseComputed("category")
filteredContent(category) { filteredContent(category) {
return category ? category.siteSettings : []; return category ? category.siteSettings : [];
}, }
}); }

View File

@ -1,16 +1,19 @@
import { alias } from "@ember/object/computed";
import Controller from "@ember/controller"; import Controller from "@ember/controller";
import I18n from "I18n"; import I18n from "I18n";
import { INPUT_DELAY } from "discourse-common/config/environment"; import { INPUT_DELAY } from "discourse-common/config/environment";
import { alias } from "@ember/object/computed";
import { isEmpty } from "@ember/utils"; import { isEmpty } from "@ember/utils";
import { debounce, observes } from "discourse-common/utils/decorators"; import { debounce } from "discourse-common/utils/decorators";
import { observes } from "@ember-decorators/object";
import { action } from "@ember/object"; import { action } from "@ember/object";
export default Controller.extend({ export default class AdminSiteSettingsController extends Controller {
filter: null, filter = null;
allSiteSettings: alias("model"),
visibleSiteSettings: null, @alias("model") allSiteSettings;
onlyOverridden: false,
visibleSiteSettings = null;
onlyOverridden = false;
filterContentNow(category) { filterContentNow(category) {
// If we have no content, don't bother filtering anything // If we have no content, don't bother filtering anything
@ -109,12 +112,12 @@ export default Controller.extend({
"adminSiteSettingsCategory", "adminSiteSettingsCategory",
category || "all_results" category || "all_results"
); );
}, }
@observes("filter", "onlyOverridden", "model") @observes("filter", "onlyOverridden", "model")
optsChanged() { optsChanged() {
this.filterContent(); this.filterContent();
}, }
@debounce(INPUT_DELAY) @debounce(INPUT_DELAY)
filterContent() { filterContent() {
@ -123,12 +126,12 @@ export default Controller.extend({
} else { } else {
this.filterContentNow(this.categoryNameKey); this.filterContentNow(this.categoryNameKey);
} }
}, }
@action @action
clearFilter() { clearFilter() {
this.setProperties({ filter: "", onlyOverridden: false }); this.setProperties({ filter: "", onlyOverridden: false });
}, }
@action @action
toggleMenu() { toggleMenu() {
@ -136,5 +139,5 @@ export default Controller.extend({
["mobile-closed", "mobile-open"].forEach((state) => { ["mobile-closed", "mobile-open"].forEach((state) => {
adminDetail.classList.toggle(state); adminDetail.classList.toggle(state);
}); });
}, }
}); }

View File

@ -1,23 +1,23 @@
import { action } from "@ember/object";
import Controller from "@ember/controller"; import Controller from "@ember/controller";
import discourseComputed from "discourse-common/utils/decorators"; import discourseComputed from "discourse-common/utils/decorators";
import discourseDebounce from "discourse-common/lib/debounce"; import discourseDebounce from "discourse-common/lib/debounce";
let lastSearch; let lastSearch;
export default Controller.extend({ export default class AdminSiteTextIndexController extends Controller {
searching: false, searching = false;
siteTexts: null, siteTexts = null;
preferred: false, preferred = false;
queryParams: ["q", "overridden", "locale"], queryParams = ["q", "overridden", "locale"];
locale: null, locale = null;
q = null;
q: null, overridden = false;
overridden: false,
init() { init() {
this._super(...arguments); super.init(...arguments);
this.set("locale", this.siteSettings.default_locale); this.set("locale", this.siteSettings.default_locale);
}, }
_performSearch() { _performSearch() {
this.store this.store
@ -26,12 +26,12 @@ export default Controller.extend({
this.set("siteTexts", results); this.set("siteTexts", results);
}) })
.finally(() => this.set("searching", false)); .finally(() => this.set("searching", false));
}, }
@discourseComputed() @discourseComputed()
availableLocales() { availableLocales() {
return JSON.parse(this.siteSettings.available_locales); return JSON.parse(this.siteSettings.available_locales);
}, }
@discourseComputed("locale") @discourseComputed("locale")
fallbackLocaleFullName() { fallbackLocaleFullName() {
@ -40,39 +40,41 @@ export default Controller.extend({
return l.value === this.siteTexts.extras.fallback_locale; return l.value === this.siteTexts.extras.fallback_locale;
}).name; }).name;
} }
}, }
actions: { @action
edit(siteText) { edit(siteText) {
this.transitionToRoute("adminSiteText.edit", siteText.get("id"), { this.transitionToRoute("adminSiteText.edit", siteText.get("id"), {
queryParams: { queryParams: {
locale: this.locale, locale: this.locale,
}, },
}); });
}, }
toggleOverridden() { @action
this.toggleProperty("overridden"); toggleOverridden() {
this.toggleProperty("overridden");
this.set("searching", true);
discourseDebounce(this, this._performSearch, 400);
}
@action
search() {
const q = this.q;
if (q !== lastSearch) {
this.set("searching", true); this.set("searching", true);
discourseDebounce(this, this._performSearch, 400); discourseDebounce(this, this._performSearch, 400);
}, lastSearch = q;
}
}
search() { @action
const q = this.q; updateLocale(value) {
if (q !== lastSearch) { this.setProperties({
this.set("searching", true); searching: true,
discourseDebounce(this, this._performSearch, 400); locale: value,
lastSearch = q; });
}
},
updateLocale(value) { discourseDebounce(this, this._performSearch, 400);
this.setProperties({ }
searching: true, }
locale: value,
});
discourseDebounce(this, this._performSearch, 400);
},
},
});

View File

@ -1,25 +1,25 @@
import Controller, { inject as controller } from "@ember/controller"; import { action } from "@ember/object";
import { inject as service } from "@ember/service";
import { alias, sort } from "@ember/object/computed"; import { alias, sort } from "@ember/object/computed";
import Controller, { inject as controller } from "@ember/controller";
import GrantBadgeController from "discourse/mixins/grant-badge-controller"; import GrantBadgeController from "discourse/mixins/grant-badge-controller";
import I18n from "I18n"; import I18n from "I18n";
import discourseComputed from "discourse-common/utils/decorators"; import discourseComputed from "discourse-common/utils/decorators";
import { next } from "@ember/runloop"; import { next } from "@ember/runloop";
import { popupAjaxError } from "discourse/lib/ajax-error"; import { popupAjaxError } from "discourse/lib/ajax-error";
import { inject as service } from "@ember/service";
export default Controller.extend(GrantBadgeController, { export default class AdminUserBadgesController extends Controller.extend(
adminUser: controller(), GrantBadgeController
dialog: service(), ) {
user: alias("adminUser.model"), @service dialog;
userBadges: alias("model"), @controller adminUser;
allBadges: alias("badges"),
sortedBadges: sort("model", "badgeSortOrder"),
init() { @alias("adminUser.model") user;
this._super(...arguments); @alias("model") userBadges;
@alias("badges") allBadges;
@sort("model", "badgeSortOrder") sortedBadges;
this.badgeSortOrder = ["granted_at:desc"]; badgeSortOrder = ["granted_at:desc"];
},
@discourseComputed("model", "model.[]", "model.expandedBadges.[]") @discourseComputed("model", "model.[]", "model.expandedBadges.[]")
groupedBadges() { groupedBadges() {
@ -59,46 +59,47 @@ export default Controller.extend(GrantBadgeController, {
}); });
return expanded.sortBy("granted_at").reverse(); return expanded.sortBy("granted_at").reverse();
}, }
actions: { @action
expandGroup(userBadge) { expandGroup(userBadge) {
const model = this.model; const model = this.model;
model.set("expandedBadges", model.get("expandedBadges") || []); model.set("expandedBadges", model.get("expandedBadges") || []);
model.get("expandedBadges").pushObject(userBadge.badge.id); model.get("expandedBadges").pushObject(userBadge.badge.id);
}, }
grantBadge() { @action
this.grantBadge( grantBadge() {
this.selectedBadgeId, this.grantBadge(
this.get("user.username"), this.selectedBadgeId,
this.badgeReason this.get("user.username"),
).then( this.badgeReason
() => { ).then(
this.set("badgeReason", ""); () => {
next(() => { this.set("badgeReason", "");
// Update the selected badge ID after the combobox has re-rendered. next(() => {
const newSelectedBadge = this.grantableBadges[0]; // Update the selected badge ID after the combobox has re-rendered.
if (newSelectedBadge) { const newSelectedBadge = this.grantableBadges[0];
this.set("selectedBadgeId", newSelectedBadge.get("id")); if (newSelectedBadge) {
} this.set("selectedBadgeId", newSelectedBadge.get("id"));
}); }
}, });
function (error) { },
popupAjaxError(error); function (error) {
} popupAjaxError(error);
); }
}, );
}
revokeBadge(userBadge) { @action
return this.dialog.yesNoConfirm({ revokeBadge(userBadge) {
message: I18n.t("admin.badges.revoke_confirm"), return this.dialog.yesNoConfirm({
didConfirm: () => { message: I18n.t("admin.badges.revoke_confirm"),
return userBadge.revoke().then(() => { didConfirm: () => {
this.model.removeObject(userBadge); return userBadge.revoke().then(() => {
}); this.model.removeObject(userBadge);
}, });
}); },
}, });
}, }
}); }

View File

@ -1,73 +1,74 @@
import { action } from "@ember/object";
import { inject as service } from "@ember/service";
import { gte, sort } from "@ember/object/computed"; import { gte, sort } from "@ember/object/computed";
import Controller from "@ember/controller"; import Controller from "@ember/controller";
import I18n from "I18n"; import I18n from "I18n";
import { popupAjaxError } from "discourse/lib/ajax-error"; import { popupAjaxError } from "discourse/lib/ajax-error";
import { inject as service } from "@ember/service";
const MAX_FIELDS = 30; const MAX_FIELDS = 30;
export default Controller.extend({ export default class AdminUserFieldsController extends Controller {
dialog: service(), @service dialog;
fieldTypes: null,
createDisabled: gte("model.length", MAX_FIELDS),
sortedFields: sort("model", "fieldSortOrder"),
init() { fieldTypes = null;
this._super(...arguments);
this.fieldSortOrder = ["position"]; @gte("model.length", MAX_FIELDS) createDisabled;
}, @sort("model", "fieldSortOrder") sortedFields;
actions: { fieldSortOrder = ["position"];
createField() {
const f = this.store.createRecord("user-field", { @action
field_type: "text", createField() {
position: MAX_FIELDS, const f = this.store.createRecord("user-field", {
field_type: "text",
position: MAX_FIELDS,
});
this.model.pushObject(f);
}
@action
moveUp(f) {
const idx = this.sortedFields.indexOf(f);
if (idx) {
const prev = this.sortedFields.objectAt(idx - 1);
const prevPos = prev.get("position");
prev.update({ position: f.get("position") });
f.update({ position: prevPos });
}
}
@action
moveDown(f) {
const idx = this.sortedFields.indexOf(f);
if (idx > -1) {
const next = this.sortedFields.objectAt(idx + 1);
const nextPos = next.get("position");
next.update({ position: f.get("position") });
f.update({ position: nextPos });
}
}
@action
destroyField(f) {
const model = this.model;
// Only confirm if we already been saved
if (f.get("id")) {
this.dialog.yesNoConfirm({
message: I18n.t("admin.user_fields.delete_confirm"),
didConfirm: () => {
return f
.destroyRecord()
.then(function () {
model.removeObject(f);
})
.catch(popupAjaxError);
},
}); });
this.model.pushObject(f); } else {
}, model.removeObject(f);
}
moveUp(f) { }
const idx = this.sortedFields.indexOf(f); }
if (idx) {
const prev = this.sortedFields.objectAt(idx - 1);
const prevPos = prev.get("position");
prev.update({ position: f.get("position") });
f.update({ position: prevPos });
}
},
moveDown(f) {
const idx = this.sortedFields.indexOf(f);
if (idx > -1) {
const next = this.sortedFields.objectAt(idx + 1);
const nextPos = next.get("position");
next.update({ position: f.get("position") });
f.update({ position: nextPos });
}
},
destroy(f) {
const model = this.model;
// Only confirm if we already been saved
if (f.get("id")) {
this.dialog.yesNoConfirm({
message: I18n.t("admin.user_fields.delete_confirm"),
didConfirm: () => {
return f
.destroyRecord()
.then(function () {
model.removeObject(f);
})
.catch(popupAjaxError);
},
});
} else {
model.removeObject(f);
}
},
},
});

View File

@ -1,2 +1,2 @@
import Controller from "@ember/controller"; import Controller from "@ember/controller";
export default Controller.extend(); export default class AdminUserController extends Controller {}

View File

@ -1,4 +1,6 @@
import discourseComputed, { observes } from "discourse-common/utils/decorators"; import { action } from "@ember/object";
import discourseComputed from "discourse-common/utils/decorators";
import { observes } from "@ember-decorators/object";
import AdminUser from "admin/models/admin-user"; import AdminUser from "admin/models/admin-user";
import CanCheckEmails from "discourse/mixins/can-check-emails"; import CanCheckEmails from "discourse/mixins/can-check-emails";
import Controller from "@ember/controller"; import Controller from "@ember/controller";
@ -7,29 +9,28 @@ import { INPUT_DELAY } from "discourse-common/config/environment";
import discourseDebounce from "discourse-common/lib/debounce"; import discourseDebounce from "discourse-common/lib/debounce";
import { i18n } from "discourse/lib/computed"; import { i18n } from "discourse/lib/computed";
export default Controller.extend(CanCheckEmails, { export default class AdminUsersListShowController extends Controller.extend(
model: null, CanCheckEmails
query: null, ) {
order: null, model = null;
asc: null, query = null;
showEmails: false, order = null;
refreshing: false, asc = null;
listFilter: null, showEmails = false;
selectAll: false, refreshing = false;
searchHint: i18n("search_hint"), listFilter = null;
selectAll = false;
init() { @i18n("search_hint") searchHint;
this._super(...arguments);
this._page = 1; _page = 1;
this._results = []; _results = [];
this._canLoadMore = true; _canLoadMore = true;
},
@discourseComputed("query") @discourseComputed("query")
title(query) { title(query) {
return I18n.t("admin.users.titles." + query); return I18n.t("admin.users.titles." + query);
}, }
@discourseComputed("showEmails") @discourseComputed("showEmails")
columnCount(showEmails) { columnCount(showEmails) {
@ -44,19 +45,19 @@ export default Controller.extend(CanCheckEmails, {
} }
return colCount; return colCount;
}, }
@observes("listFilter") @observes("listFilter")
_filterUsers() { _filterUsers() {
discourseDebounce(this, this.resetFilters, INPUT_DELAY); discourseDebounce(this, this.resetFilters, INPUT_DELAY);
}, }
resetFilters() { resetFilters() {
this._page = 1; this._page = 1;
this._results = []; this._results = [];
this._canLoadMore = true; this._canLoadMore = true;
this._refreshUsers(); this._refreshUsers();
}, }
_refreshUsers() { _refreshUsers() {
if (!this._canLoadMore) { if (!this._canLoadMore) {
@ -84,17 +85,17 @@ export default Controller.extend(CanCheckEmails, {
.finally(() => { .finally(() => {
this.set("refreshing", false); this.set("refreshing", false);
}); });
}, }
actions: { @action
loadMore() { loadMore() {
this._page += 1; this._page += 1;
this._refreshUsers(); this._refreshUsers();
}, }
toggleEmailVisibility() { @action
this.toggleProperty("showEmails"); toggleEmailVisibility() {
this.resetFilters(); this.toggleProperty("showEmails");
}, this.resetFilters();
}, }
}); }

View File

@ -1,32 +1,35 @@
import { action } from "@ember/object";
import { inject as service } from "@ember/service";
import { or } from "@ember/object/computed";
import Controller, { inject as controller } from "@ember/controller"; import Controller, { inject as controller } from "@ember/controller";
import I18n from "I18n"; import I18n from "I18n";
import WatchedWord from "admin/models/watched-word"; import WatchedWord from "admin/models/watched-word";
import { ajax } from "discourse/lib/ajax"; import { ajax } from "discourse/lib/ajax";
import discourseComputed from "discourse-common/utils/decorators"; import discourseComputed from "discourse-common/utils/decorators";
import { fmt } from "discourse/lib/computed"; import { fmt } from "discourse/lib/computed";
import { or } from "@ember/object/computed";
import { schedule } from "@ember/runloop"; import { schedule } from "@ember/runloop";
import showModal from "discourse/lib/show-modal"; import showModal from "discourse/lib/show-modal";
import { inject as service } from "@ember/service";
export default Controller.extend({ export default class AdminWatchedWordsActionController extends Controller {
adminWatchedWords: controller(), @service dialog;
actionNameKey: null, @controller adminWatchedWords;
dialog: service(),
downloadLink: fmt( actionNameKey = null;
"actionNameKey",
"/admin/customize/watched_words/action/%@/download" @fmt("actionNameKey", "/admin/customize/watched_words/action/%@/download")
), downloadLink;
showWordsList: or("adminWatchedWords.showWords", "adminWatchedWords.filter"),
@or("adminWatchedWords.showWords", "adminWatchedWords.filter")
showWordsList;
findAction(actionName) { findAction(actionName) {
return (this.adminWatchedWords.model || []).findBy("nameKey", actionName); return (this.adminWatchedWords.model || []).findBy("nameKey", actionName);
}, }
@discourseComputed("actionNameKey", "adminWatchedWords.model") @discourseComputed("actionNameKey", "adminWatchedWords.model")
currentAction(actionName) { currentAction(actionName) {
return this.findAction(actionName); return this.findAction(actionName);
}, }
@discourseComputed("currentAction.words.[]") @discourseComputed("currentAction.words.[]")
regexpError(words) { regexpError(words) {
@ -37,78 +40,81 @@ export default Controller.extend({
return I18n.t("admin.watched_words.invalid_regex", { word }); return I18n.t("admin.watched_words.invalid_regex", { word });
} }
} }
}, }
@discourseComputed("actionNameKey") @discourseComputed("actionNameKey")
actionDescription(actionNameKey) { actionDescription(actionNameKey) {
return I18n.t("admin.watched_words.action_descriptions." + actionNameKey); return I18n.t("admin.watched_words.action_descriptions." + actionNameKey);
}, }
actions: { @action
recordAdded(arg) { recordAdded(arg) {
const action = this.findAction(this.actionNameKey); const foundAction = this.findAction(this.actionNameKey);
if (!action) { if (!foundAction) {
return; return;
} }
action.words.unshiftObject(arg); foundAction.words.unshiftObject(arg);
schedule("afterRender", () => { schedule("afterRender", () => {
// remove from other actions lists // remove from other actions lists
let match = null; let match = null;
this.adminWatchedWords.model.forEach((otherAction) => { this.adminWatchedWords.model.forEach((otherAction) => {
if (match) {
return;
}
if (otherAction.nameKey !== this.actionNameKey) {
match = otherAction.words.findBy("id", arg.id);
if (match) { if (match) {
return; otherAction.words.removeObject(match);
} }
}
});
});
}
if (otherAction.nameKey !== this.actionNameKey) { @action
match = otherAction.words.findBy("id", arg.id); recordRemoved(arg) {
if (match) { if (this.currentAction) {
otherAction.words.removeObject(match); this.currentAction.words.removeObject(arg);
} }
}
@action
uploadComplete() {
WatchedWord.findAll().then((data) => {
this.adminWatchedWords.set("model", data);
});
}
@action
test() {
WatchedWord.findAll().then((data) => {
this.adminWatchedWords.set("model", data);
showModal("admin-watched-word-test", {
admin: true,
model: this.currentAction,
});
});
}
@action
clearAll() {
const actionKey = this.actionNameKey;
this.dialog.yesNoConfirm({
message: I18n.t("admin.watched_words.clear_all_confirm", {
action: I18n.t("admin.watched_words.actions." + actionKey),
}),
didConfirm: () => {
ajax(`/admin/customize/watched_words/action/${actionKey}.json`, {
type: "DELETE",
}).then(() => {
const foundAction = this.findAction(actionKey);
if (foundAction) {
foundAction.set("words", []);
} }
}); });
}); },
}, });
}
recordRemoved(arg) { }
if (this.currentAction) {
this.currentAction.words.removeObject(arg);
}
},
uploadComplete() {
WatchedWord.findAll().then((data) => {
this.adminWatchedWords.set("model", data);
});
},
test() {
WatchedWord.findAll().then((data) => {
this.adminWatchedWords.set("model", data);
showModal("admin-watched-word-test", {
admin: true,
model: this.currentAction,
});
});
},
clearAll() {
const actionKey = this.actionNameKey;
this.dialog.yesNoConfirm({
message: I18n.t("admin.watched_words.clear_all_confirm", {
action: I18n.t("admin.watched_words.actions." + actionKey),
}),
didConfirm: () => {
ajax(`/admin/customize/watched_words/action/${actionKey}.json`, {
type: "DELETE",
}).then(() => {
const action = this.findAction(actionKey);
if (action) {
action.set("words", []);
}
});
},
});
},
},
});

View File

@ -3,11 +3,11 @@ import EmberObject, { action } from "@ember/object";
import { INPUT_DELAY } from "discourse-common/config/environment"; import { INPUT_DELAY } from "discourse-common/config/environment";
import discourseDebounce from "discourse-common/lib/debounce"; import discourseDebounce from "discourse-common/lib/debounce";
import { isEmpty } from "@ember/utils"; import { isEmpty } from "@ember/utils";
import { observes } from "discourse-common/utils/decorators"; import { observes } from "@ember-decorators/object";
export default Controller.extend({ export default class AdminWatchedWordsController extends Controller {
filter: null, filter = null;
showWords: false, showWords = false;
_filterContent() { _filterContent() {
if (isEmpty(this.allWatchedWords)) { if (isEmpty(this.allWatchedWords)) {
@ -36,17 +36,17 @@ export default Controller.extend({
); );
}); });
this.set("model", model); this.set("model", model);
}, }
@observes("filter") @observes("filter")
filterContent() { filterContent() {
discourseDebounce(this, this._filterContent, INPUT_DELAY); discourseDebounce(this, this._filterContent, INPUT_DELAY);
}, }
@action @action
clearFilter() { clearFilter() {
this.set("filter", ""); this.set("filter", "");
}, }
@action @action
toggleMenu() { toggleMenu() {
@ -54,5 +54,5 @@ export default Controller.extend({
["mobile-closed", "mobile-open"].forEach((state) => { ["mobile-closed", "mobile-open"].forEach((state) => {
adminDetail.classList.toggle(state); adminDetail.classList.toggle(state);
}); });
}, }
}); }

View File

@ -1,23 +1,24 @@
import { inject as service } from "@ember/service";
import { alias } from "@ember/object/computed";
import Controller, { inject as controller } from "@ember/controller"; import Controller, { inject as controller } from "@ember/controller";
import EmberObject, { action } from "@ember/object"; import EmberObject, { action } from "@ember/object";
import I18n from "I18n"; import I18n from "I18n";
import { alias } from "@ember/object/computed";
import discourseComputed from "discourse-common/utils/decorators"; import discourseComputed from "discourse-common/utils/decorators";
import { isEmpty } from "@ember/utils"; import { isEmpty } from "@ember/utils";
import { popupAjaxError } from "discourse/lib/ajax-error"; import { popupAjaxError } from "discourse/lib/ajax-error";
import { inject as service } from "@ember/service";
export default Controller.extend({ export default class AdminWebHooksEditController extends Controller {
adminWebHooks: controller(), @service dialog;
dialog: service(), @controller adminWebHooks;
eventTypes: alias("adminWebHooks.eventTypes"),
defaultEventTypes: alias("adminWebHooks.defaultEventTypes"), @alias("adminWebHooks.eventTypes") eventTypes;
contentTypes: alias("adminWebHooks.contentTypes"), @alias("adminWebHooks.defaultEventTypes") defaultEventTypes;
@alias("adminWebHooks.contentTypes") contentTypes;
@discourseComputed @discourseComputed
showTagsFilter() { showTagsFilter() {
return this.siteSettings.tagging_enabled; return this.siteSettings.tagging_enabled;
}, }
@discourseComputed("model.isSaving", "saved", "saveButtonDisabled") @discourseComputed("model.isSaving", "saved", "saveButtonDisabled")
savingStatus(isSaving, saved, saveButtonDisabled) { savingStatus(isSaving, saved, saveButtonDisabled) {
@ -29,14 +30,14 @@ export default Controller.extend({
// Use side effect of validation to clear saved text // Use side effect of validation to clear saved text
this.set("saved", false); this.set("saved", false);
return ""; return "";
}, }
@discourseComputed("model.isNew") @discourseComputed("model.isNew")
saveButtonText(isNew) { saveButtonText(isNew) {
return isNew return isNew
? I18n.t("admin.web_hooks.create") ? I18n.t("admin.web_hooks.create")
: I18n.t("admin.web_hooks.save"); : I18n.t("admin.web_hooks.save");
}, }
@discourseComputed("model.secret") @discourseComputed("model.secret")
secretValidation(secret) { secretValidation(secret) {
@ -55,7 +56,7 @@ export default Controller.extend({
}); });
} }
} }
}, }
@discourseComputed("model.wildcard_web_hook", "model.web_hook_event_types.[]") @discourseComputed("model.wildcard_web_hook", "model.web_hook_event_types.[]")
eventTypeValidation(isWildcard, eventTypes) { eventTypeValidation(isWildcard, eventTypes) {
@ -65,7 +66,7 @@ export default Controller.extend({
reason: I18n.t("admin.web_hooks.event_type_missing"), reason: I18n.t("admin.web_hooks.event_type_missing"),
}); });
} }
}, }
@discourseComputed( @discourseComputed(
"model.isSaving", "model.isSaving",
@ -82,7 +83,7 @@ export default Controller.extend({
return isSaving return isSaving
? false ? false
: secretValidation || eventTypeValidation || isEmpty(payloadUrl); : secretValidation || eventTypeValidation || isEmpty(payloadUrl);
}, }
@action @action
async save() { async save() {
@ -97,5 +98,5 @@ export default Controller.extend({
} catch (e) { } catch (e) {
popupAjaxError(e); popupAjaxError(e);
} }
}, }
}); }

View File

@ -1,18 +1,19 @@
import { inject as service } from "@ember/service";
import { alias } from "@ember/object/computed";
import Controller, { inject as controller } from "@ember/controller"; import Controller, { inject as controller } from "@ember/controller";
import I18n from "I18n"; import I18n from "I18n";
import { popupAjaxError } from "discourse/lib/ajax-error"; import { popupAjaxError } from "discourse/lib/ajax-error";
import { inject as service } from "@ember/service";
import { action } from "@ember/object"; import { action } from "@ember/object";
import { alias } from "@ember/object/computed";
export default Controller.extend({ export default class AdminWebHooksIndexController extends Controller {
adminWebHooks: controller(), @service dialog;
dialog: service(), @controller adminWebHooks;
contentTypes: alias("adminWebHooks.contentTypes"),
defaultEventTypes: alias("adminWebHooks.defaultEventTypes"), @alias("adminWebHooks.contentTypes") contentTypes;
deliveryStatuses: alias("adminWebHooks.deliveryStatuses"), @alias("adminWebHooks.defaultEventTypes") defaultEventTypes;
eventTypes: alias("adminWebHooks.eventTypes"), @alias("adminWebHooks.deliveryStatuses") deliveryStatuses;
model: alias("adminWebHooks.model"), @alias("adminWebHooks.eventTypes") eventTypes;
@alias("adminWebHooks.model") model;
@action @action
destroy(webhook) { destroy(webhook) {
@ -27,10 +28,10 @@ export default Controller.extend({
} }
}, },
}); });
}, }
@action @action
loadMore() { loadMore() {
this.model.loadMore(); this.model.loadMore();
}, }
}); }

View File

@ -1,18 +1,18 @@
import { inject as service } from "@ember/service";
import Controller, { inject as controller } from "@ember/controller"; import Controller, { inject as controller } from "@ember/controller";
import { action } from "@ember/object"; import { action } from "@ember/object";
import I18n from "I18n"; import I18n from "I18n";
import { popupAjaxError } from "discourse/lib/ajax-error"; import { popupAjaxError } from "discourse/lib/ajax-error";
import { inject as service } from "@ember/service";
export default Controller.extend({ export default class AdminWebHooksShowController extends Controller {
adminWebHooks: controller(), @service dialog;
dialog: service(), @service router;
router: service(), @controller adminWebHooks;
@action @action
edit() { edit() {
return this.router.transitionTo("adminWebHooks.edit", this.model); return this.router.transitionTo("adminWebHooks.edit", this.model);
}, }
@action @action
destroy() { destroy() {
@ -28,5 +28,5 @@ export default Controller.extend({
} }
}, },
}); });
}, }
}); }

View File

@ -1,3 +1,3 @@
import Controller from "@ember/controller"; import Controller from "@ember/controller";
export default Controller.extend({}); export default class AdminWebHooksController extends Controller {}

View File

@ -1,20 +1,20 @@
import { inject as service } from "@ember/service";
import Controller from "@ember/controller"; import Controller from "@ember/controller";
import { dasherize } from "@ember/string"; import { dasherize } from "@ember/string";
import discourseComputed from "discourse-common/utils/decorators"; import discourseComputed from "discourse-common/utils/decorators";
import { inject as service } from "@ember/service";
export default Controller.extend({ export default class AdminController extends Controller {
router: service(), @service router;
@discourseComputed("siteSettings.enable_group_directory") @discourseComputed("siteSettings.enable_group_directory")
showGroups(enableGroupDirectory) { showGroups(enableGroupDirectory) {
return !enableGroupDirectory; return !enableGroupDirectory;
}, }
@discourseComputed("siteSettings.enable_badges") @discourseComputed("siteSettings.enable_badges")
showBadges(enableBadges) { showBadges(enableBadges) {
return this.currentUser.get("admin") && enableBadges; return this.currentUser.get("admin") && enableBadges;
}, }
@discourseComputed("router._router.currentPath") @discourseComputed("router._router.currentPath")
adminContentsClassName(currentPath) { adminContentsClassName(currentPath) {
@ -37,5 +37,5 @@ export default Controller.extend({
} }
return cssClasses; return cssClasses;
}, }
}); }

View File

@ -65,7 +65,7 @@
@label="admin.customize.theme.finish_install" @label="admin.customize.theme.finish_install"
/> />
<DButton <DButton
@action={{action "destroy"}} @action={{action "destroyTheme"}}
@label="admin.customize.delete" @label="admin.customize.delete"
@icon="trash-alt" @icon="trash-alt"
@class="btn-danger" @class="btn-danger"
@ -498,7 +498,7 @@
{{/if}} {{/if}}
<DButton <DButton
@action={{action "destroy"}} @action={{action "destroyTheme"}}
@label="admin.customize.delete" @label="admin.customize.delete"
@icon="trash-alt" @icon="trash-alt"
@class="btn-danger" @class="btn-danger"

View File

@ -96,7 +96,7 @@
{{else}} {{else}}
<DButton <DButton
@class="btn-default btn-danger" @class="btn-default btn-danger"
@action={{action "destroy"}} @action={{action "destroyRecord"}}
@actionParam={{item}} @actionParam={{item}}
@icon="far-trash-alt" @icon="far-trash-alt"
/> />

View File

@ -63,7 +63,7 @@
</td> </td>
<td class="col action" style="text-align: right;"> <td class="col action" style="text-align: right;">
<DButton <DButton
@action={{action "destroy"}} @action={{action "destroyRecord"}}
@actionParam={{pl}} @actionParam={{pl}}
@icon="far-trash-alt" @icon="far-trash-alt"
@class="btn-danger" @class="btn-danger"

View File

@ -10,7 +10,7 @@
@fieldTypes={{this.fieldTypes}} @fieldTypes={{this.fieldTypes}}
@firstField={{this.sortedFields.firstObject}} @firstField={{this.sortedFields.firstObject}}
@lastField={{this.sortedFields.lastObject}} @lastField={{this.sortedFields.lastObject}}
@destroyAction={{action "destroy"}} @destroyAction={{action "destroyField"}}
@moveUpAction={{action "moveUp"}} @moveUpAction={{action "moveUp"}}
@moveDownAction={{action "moveDown"}} @moveDownAction={{action "moveDown"}}
/> />

View File

@ -898,7 +898,7 @@
@label="admin.user.delete" @label="admin.user.delete"
@icon="trash-alt" @icon="trash-alt"
@class="btn-danger btn-user-delete" @class="btn-danger btn-user-delete"
@action={{action "destroy"}} @action={{action "destroyUser"}}
/> />
{{/if}} {{/if}}