diff --git a/app/assets/javascripts/admin/addon/controllers/admin-api-keys-index.js b/app/assets/javascripts/admin/addon/controllers/admin-api-keys-index.js
index 7b98fdba1d1..e7c90f292b3 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-api-keys-index.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-api-keys-index.js
@@ -2,18 +2,18 @@ import Controller from "@ember/controller";
import { action } from "@ember/object";
import { popupAjaxError } from "discourse/lib/ajax-error";
-export default Controller.extend({
- loading: false,
+export default class AdminApiKeysIndexController extends Controller {
+ loading = false;
@action
revokeKey(key) {
key.revoke().catch(popupAjaxError);
- },
+ }
@action
undoRevokeKey(key) {
key.undoRevoke().catch(popupAjaxError);
- },
+ }
@action
loadMore() {
@@ -35,5 +35,5 @@ export default Controller.extend({
.finally(() => {
this.set("loading", false);
});
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-api-keys-new.js b/app/assets/javascripts/admin/addon/controllers/admin-api-keys-new.js
index a95c7845c08..ba9a2da8d4c 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-api-keys-new.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-api-keys-new.js
@@ -1,37 +1,32 @@
+import { equal } from "@ember/object/computed";
import Controller from "@ember/controller";
import I18n from "I18n";
import discourseComputed from "discourse-common/utils/decorators";
import { isBlank } from "@ember/utils";
import { popupAjaxError } from "discourse/lib/ajax-error";
import { action, get } from "@ember/object";
-import { equal } from "@ember/object/computed";
import showModal from "discourse/lib/show-modal";
import { ajax } from "discourse/lib/ajax";
-export default Controller.extend({
- userModes: null,
- scopeModes: null,
- globalScopes: null,
- scopes: null,
+export default class AdminApiKeysNewController extends Controller {
+ userModes = [
+ { id: "all", name: I18n.t("admin.api.all_users") },
+ { id: "single", name: I18n.t("admin.api.single_user") },
+ ];
+ 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() {
- this._super(...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") },
- ]);
-
+ super.init(...arguments);
this._loadScopes();
- },
-
- showUserSelector: equal("userMode", "single"),
+ }
@discourseComputed("model.{description,username}", "showUserSelector")
saveDisabled(model, showUserSelector) {
@@ -42,12 +37,12 @@ export default Controller.extend({
return true;
}
return false;
- },
+ }
@action
updateUsername(selected) {
this.set("model.username", get(selected, "firstObject"));
- },
+ }
@action
changeUserMode(userMode) {
@@ -55,12 +50,12 @@ export default Controller.extend({
this.model.set("username", null);
}
this.set("userMode", userMode);
- },
+ }
@action
changeScopeMode(scopeMode) {
this.set("scopeMode", scopeMode);
- },
+ }
@action
save() {
@@ -77,12 +72,12 @@ export default Controller.extend({
}
return this.model.save().catch(popupAjaxError);
- },
+ }
@action
continue() {
this.transitionToRoute("adminApiKeys.show", this.model.id);
- },
+ }
@action
showURLs(urls) {
@@ -90,7 +85,7 @@ export default Controller.extend({
admin: true,
model: { urls },
});
- },
+ }
_loadScopes() {
return ajax("/admin/api/keys/scopes.json")
@@ -102,5 +97,5 @@ export default Controller.extend({
this.set("scopes", data.scopes);
})
.catch(popupAjaxError);
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-api-keys-show.js b/app/assets/javascripts/admin/addon/controllers/admin-api-keys-show.js
index 28a883d985f..e96aaff49dd 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-api-keys-show.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-api-keys-show.js
@@ -1,66 +1,74 @@
+import { action } from "@ember/object";
+import { empty } from "@ember/object/computed";
import Controller from "@ember/controller";
import { bufferedProperty } from "discourse/mixins/buffered-content";
-import { empty } from "@ember/object/computed";
import { isEmpty } from "@ember/utils";
import { popupAjaxError } from "discourse/lib/ajax-error";
import showModal from "discourse/lib/show-modal";
-export default Controller.extend(bufferedProperty("model"), {
- isNew: empty("model.id"),
+export default class AdminApiKeysShowController extends Controller.extend(
+ bufferedProperty("model")
+) {
+ @empty("model.id") isNew;
- actions: {
- saveDescription() {
- const buffered = this.buffered;
- const attrs = buffered.getProperties("description");
+ @action
+ saveDescription() {
+ const buffered = this.buffered;
+ const attrs = buffered.getProperties("description");
- this.model
- .save(attrs)
- .then(() => {
- this.set("editingDescription", false);
- this.rollbackBuffer();
- })
- .catch(popupAjaxError);
- },
-
- cancel() {
- const id = this.get("userField.id");
- if (isEmpty(id)) {
- this.destroyAction(this.userField);
- } else {
+ this.model
+ .save(attrs)
+ .then(() => {
+ this.set("editingDescription", false);
this.rollbackBuffer();
- this.set("editing", false);
- }
- },
+ })
+ .catch(popupAjaxError);
+ }
- editDescription() {
- this.toggleProperty("editingDescription");
- if (!this.editingDescription) {
- this.rollbackBuffer();
- }
- },
+ @action
+ cancel() {
+ const id = this.get("userField.id");
+ if (isEmpty(id)) {
+ this.destroyAction(this.userField);
+ } else {
+ this.rollbackBuffer();
+ this.set("editing", false);
+ }
+ }
- revokeKey(key) {
- key.revoke().catch(popupAjaxError);
- },
+ @action
+ editDescription() {
+ this.toggleProperty("editingDescription");
+ if (!this.editingDescription) {
+ this.rollbackBuffer();
+ }
+ }
- deleteKey(key) {
- key
- .destroyRecord()
- .then(() => this.transitionToRoute("adminApiKeys.index"))
- .catch(popupAjaxError);
- },
+ @action
+ revokeKey(key) {
+ key.revoke().catch(popupAjaxError);
+ }
- undoRevokeKey(key) {
- key.undoRevoke().catch(popupAjaxError);
- },
+ @action
+ deleteKey(key) {
+ key
+ .destroyRecord()
+ .then(() => this.transitionToRoute("adminApiKeys.index"))
+ .catch(popupAjaxError);
+ }
- showURLs(urls) {
- return showModal("admin-api-key-urls", {
- admin: true,
- model: {
- urls,
- },
- });
- },
- },
-});
+ @action
+ undoRevokeKey(key) {
+ key.undoRevoke().catch(popupAjaxError);
+ }
+
+ @action
+ showURLs(urls) {
+ return showModal("admin-api-key-urls", {
+ admin: true,
+ model: {
+ urls,
+ },
+ });
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-api-keys.js b/app/assets/javascripts/admin/addon/controllers/admin-api-keys.js
index 7ae8f5a1e2e..08fee5c7335 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-api-keys.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-api-keys.js
@@ -1,3 +1,3 @@
import Controller from "@ember/controller";
-export default Controller.extend();
+export default class AdminApiKeysController extends Controller {}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-backups-index.js b/app/assets/javascripts/admin/addon/controllers/admin-backups-index.js
index 72a1bd18a54..09b7a3f9734 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-backups-index.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-backups-index.js
@@ -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 Controller, { inject as controller } from "@ember/controller";
import { i18n, setting } from "discourse/lib/computed";
import I18n from "I18n";
import { ajax } from "discourse/lib/ajax";
import discourseComputed from "discourse-common/utils/decorators";
-import { inject as service } from "@ember/service";
-export default Controller.extend({
- adminBackups: controller(),
- dialog: service(),
- status: alias("adminBackups.model"),
- uploadLabel: i18n("admin.backups.upload.label"),
- backupLocation: setting("backup_location"),
- localBackupStorage: equal("backupLocation", "local"),
+export default class AdminBackupsIndexController extends Controller {
+ @service dialog;
+ @controller adminBackups;
+
+ @alias("adminBackups.model") status;
+ @i18n("admin.backups.upload.label") uploadLabel;
+ @setting("backup_location") backupLocation;
+ @equal("backupLocation", "local") localBackupStorage;
@discourseComputed("status.allowRestore", "status.isOperationRunning")
restoreTitle(allowRestore, isOperationRunning) {
@@ -24,35 +26,35 @@ export default Controller.extend({
} else {
return "admin.backups.operations.restore.title";
}
- },
+ }
- actions: {
- toggleReadOnlyMode() {
- if (!this.site.get("isReadOnly")) {
- this.dialog.yesNoConfirm({
- message: I18n.t("admin.backups.read_only.enable.confirm"),
- didConfirm: () => {
- this.set("currentUser.hideReadOnlyAlert", true);
- this._toggleReadOnlyMode(true);
- },
- });
- } else {
- this._toggleReadOnlyMode(false);
- }
- },
+ @action
+ toggleReadOnlyMode() {
+ if (!this.site.get("isReadOnly")) {
+ this.dialog.yesNoConfirm({
+ message: I18n.t("admin.backups.read_only.enable.confirm"),
+ didConfirm: () => {
+ this.set("currentUser.hideReadOnlyAlert", true);
+ this._toggleReadOnlyMode(true);
+ },
+ });
+ } else {
+ this._toggleReadOnlyMode(false);
+ }
+ }
- download(backup) {
- const link = backup.get("filename");
- ajax(`/admin/backups/${link}`, { type: "PUT" }).then(() =>
- this.dialog.alert(I18n.t("admin.backups.operations.download.alert"))
- );
- },
- },
+ @action
+ download(backup) {
+ const link = backup.get("filename");
+ ajax(`/admin/backups/${link}`, { type: "PUT" }).then(() =>
+ this.dialog.alert(I18n.t("admin.backups.operations.download.alert"))
+ );
+ }
_toggleReadOnlyMode(enable) {
ajax("/admin/backups/readonly", {
type: "PUT",
data: { enable },
}).then(() => this.site.set("isReadOnly", enable));
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-backups-logs.js b/app/assets/javascripts/admin/addon/controllers/admin-backups-logs.js
index e8a1694e2c2..3eae5564d17 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-backups-logs.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-backups-logs.js
@@ -1,13 +1,10 @@
-import Controller, { inject as controller } from "@ember/controller";
import { alias } from "@ember/object/computed";
+import Controller, { inject as controller } from "@ember/controller";
-export default Controller.extend({
- adminBackups: controller(),
- status: alias("adminBackups.model"),
+export default class AdminBackupsLogsController extends Controller {
+ @controller adminBackups;
- init() {
- this._super(...arguments);
+ @alias("adminBackups.model") status;
- this.logs = [];
- },
-});
+ logs = [];
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-backups.js b/app/assets/javascripts/admin/addon/controllers/admin-backups.js
index 77dfbc31329..bb5c7251b16 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-backups.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-backups.js
@@ -1,11 +1,8 @@
import { and, not } from "@ember/object/computed";
import Controller from "@ember/controller";
-export default Controller.extend({
- noOperationIsRunning: not("model.isOperationRunning"),
- rollbackEnabled: and(
- "model.canRollback",
- "model.restoreEnabled",
- "noOperationIsRunning"
- ),
- rollbackDisabled: not("rollbackEnabled"),
-});
+export default class AdminBackupsController extends Controller {
+ @not("model.isOperationRunning") noOperationIsRunning;
+ @not("rollbackEnabled") rollbackDisabled;
+ @and("model.canRollback", "model.restoreEnabled", "noOperationIsRunning")
+ rollbackEnabled;
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-customize-colors.js b/app/assets/javascripts/admin/addon/controllers/admin-customize-colors.js
index 7f06b1f3f06..795d7f24f0d 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-customize-colors.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-customize-colors.js
@@ -1,19 +1,19 @@
import Controller from "@ember/controller";
-import EmberObject from "@ember/object";
+import EmberObject, { action } from "@ember/object";
import I18n from "I18n";
import discourseComputed from "discourse-common/utils/decorators";
import showModal from "discourse/lib/show-modal";
-export default Controller.extend({
+export default class AdminCustomizeColorsController extends Controller {
@discourseComputed("model.@each.id")
baseColorScheme() {
return this.model.findBy("is_base", true);
- },
+ }
@discourseComputed("model.@each.id")
baseColorSchemes() {
return this.model.filterBy("is_base", true);
- },
+ }
@discourseComputed("baseColorScheme")
baseColors(baseColorScheme) {
@@ -22,28 +22,28 @@ export default Controller.extend({
baseColorsHash.set(color.get("name"), color);
});
return baseColorsHash;
- },
+ }
- actions: {
- newColorSchemeWithBase(baseKey) {
- const base = this.baseColorSchemes.findBy("base_scheme_id", baseKey);
- const newColorScheme = base.copy();
- newColorScheme.setProperties({
- name: I18n.t("admin.customize.colors.new_name"),
- base_scheme_id: base.get("base_scheme_id"),
- });
- newColorScheme.save().then(() => {
- this.model.pushObject(newColorScheme);
- newColorScheme.set("savingStatus", null);
- this.replaceRoute("adminCustomize.colors.show", newColorScheme);
- });
- },
+ @action
+ newColorSchemeWithBase(baseKey) {
+ const base = this.baseColorSchemes.findBy("base_scheme_id", baseKey);
+ const newColorScheme = base.copy();
+ newColorScheme.setProperties({
+ name: I18n.t("admin.customize.colors.new_name"),
+ base_scheme_id: base.get("base_scheme_id"),
+ });
+ newColorScheme.save().then(() => {
+ this.model.pushObject(newColorScheme);
+ newColorScheme.set("savingStatus", null);
+ this.replaceRoute("adminCustomize.colors.show", newColorScheme);
+ });
+ }
- newColorScheme() {
- showModal("admin-color-scheme-select-base", {
- model: this.baseColorSchemes,
- admin: true,
- });
- },
- },
-});
+ @action
+ newColorScheme() {
+ showModal("admin-color-scheme-select-base", {
+ model: this.baseColorSchemes,
+ admin: true,
+ });
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-customize-email-style-edit.js b/app/assets/javascripts/admin/addon/controllers/admin-customize-email-style-edit.js
index ad664f79b5f..02b553c4312 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-customize-email-style-edit.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-customize-email-style-edit.js
@@ -1,38 +1,38 @@
+import { action } from "@ember/object";
+import { inject as service } from "@ember/service";
import Controller from "@ember/controller";
import I18n from "I18n";
import discourseComputed from "discourse-common/utils/decorators";
-import { inject as service } from "@ember/service";
-export default Controller.extend({
- dialog: service(),
+export default class AdminCustomizeEmailStyleEditController extends Controller {
+ @service dialog;
@discourseComputed("model.isSaving")
saveButtonText(isSaving) {
return isSaving ? I18n.t("saving") : I18n.t("admin.customize.save");
- },
+ }
@discourseComputed("model.changed", "model.isSaving")
saveDisabled(changed, isSaving) {
return !changed || isSaving;
- },
+ }
- actions: {
- save() {
- if (!this.model.saving) {
- this.set("saving", true);
- this.model
- .update(this.model.getProperties("html", "css"))
- .catch((e) => {
- const msg =
- e.jqXHR.responseJSON && e.jqXHR.responseJSON.errors
- ? I18n.t("admin.customize.email_style.save_error_with_reason", {
- error: e.jqXHR.responseJSON.errors.join(". "),
- })
- : I18n.t("generic_error");
- this.dialog.alert(msg);
- })
- .finally(() => this.set("model.changed", false));
- }
- },
- },
-});
+ @action
+ save() {
+ if (!this.model.saving) {
+ this.set("saving", true);
+ this.model
+ .update(this.model.getProperties("html", "css"))
+ .catch((e) => {
+ const msg =
+ e.jqXHR.responseJSON && e.jqXHR.responseJSON.errors
+ ? I18n.t("admin.customize.email_style.save_error_with_reason", {
+ error: e.jqXHR.responseJSON.errors.join(". "),
+ })
+ : I18n.t("generic_error");
+ this.dialog.alert(msg);
+ })
+ .finally(() => this.set("model.changed", false));
+ }
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-customize-email-templates-edit.js b/app/assets/javascripts/admin/addon/controllers/admin-customize-email-templates-edit.js
index c784deb0ec5..b517fc3feda 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-customize-email-templates-edit.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-customize-email-templates-edit.js
@@ -1,23 +1,26 @@
+import { inject as service } from "@ember/service";
import Controller, { inject as controller } from "@ember/controller";
import I18n from "I18n";
import { action } from "@ember/object";
import { bufferedProperty } from "discourse/mixins/buffered-content";
import discourseComputed from "discourse-common/utils/decorators";
import { popupAjaxError } from "discourse/lib/ajax-error";
-import { inject as service } from "@ember/service";
-export default Controller.extend(bufferedProperty("emailTemplate"), {
- adminCustomizeEmailTemplates: controller(),
- dialog: service(),
- emailTemplate: null,
- saved: false,
+export default class AdminCustomizeEmailTemplatesEditController extends Controller.extend(
+ bufferedProperty("emailTemplate")
+) {
+ @service dialog;
+ @controller adminCustomizeEmailTemplates;
+
+ emailTemplate = null;
+ saved = false;
@discourseComputed("buffered.body", "buffered.subject")
saveDisabled(body, subject) {
return (
this.emailTemplate.body === body && this.emailTemplate.subject === subject
);
- },
+ }
@discourseComputed("buffered")
hasMultipleSubjects(buffered) {
@@ -26,7 +29,7 @@ export default Controller.extend(bufferedProperty("emailTemplate"), {
} else {
return buffered.getProperties("id")["id"];
}
- },
+ }
@action
saveChanges() {
@@ -38,7 +41,7 @@ export default Controller.extend(bufferedProperty("emailTemplate"), {
this.set("saved", true);
})
.catch(popupAjaxError);
- },
+ }
@action
revertChanges() {
@@ -57,5 +60,5 @@ export default Controller.extend(bufferedProperty("emailTemplate"), {
.catch(popupAjaxError);
},
});
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-customize-email-templates.js b/app/assets/javascripts/admin/addon/controllers/admin-customize-email-templates.js
index a3d7f360e03..68e7fb6159b 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-customize-email-templates.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-customize-email-templates.js
@@ -1,18 +1,13 @@
+import { sort } from "@ember/object/computed";
import Controller from "@ember/controller";
import { action } from "@ember/object";
-import { sort } from "@ember/object/computed";
-export default Controller.extend({
- sortedTemplates: sort("emailTemplates", "titleSorting"),
-
- init() {
- this._super(...arguments);
-
- this.set("titleSorting", ["title"]);
- },
+export default class AdminCustomizeEmailTemplatesController extends Controller {
+ titleSorting = ["title"];
+ @sort("emailTemplates", "titleSorting") sortedTemplates;
@action
onSelectTemplate(template) {
this.transitionToRoute("adminCustomizeEmailTemplates.edit", template);
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-customize-robots-txt.js b/app/assets/javascripts/admin/addon/controllers/admin-customize-robots-txt.js
index 4463b361d6b..de93b226c3b 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-customize-robots-txt.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-customize-robots-txt.js
@@ -1,47 +1,52 @@
+import { action } from "@ember/object";
+import { not } from "@ember/object/computed";
import Controller from "@ember/controller";
import { ajax } from "discourse/lib/ajax";
import { bufferedProperty } from "discourse/mixins/buffered-content";
-import { not } from "@ember/object/computed";
import { propertyEqual } from "discourse/lib/computed";
-export default Controller.extend(bufferedProperty("model"), {
- saved: false,
- isSaving: false,
- saveDisabled: propertyEqual("model.robots_txt", "buffered.robots_txt"),
- resetDisabled: not("model.overridden"),
+export default class AdminCustomizeRobotsTxtController extends Controller.extend(
+ bufferedProperty("model")
+) {
+ saved = false;
+ isSaving = false;
- actions: {
- save() {
- this.setProperties({
- isSaving: true,
- saved: false,
- });
+ @propertyEqual("model.robots_txt", "buffered.robots_txt") saveDisabled;
- ajax("robots.json", {
- type: "PUT",
- data: { robots_txt: this.buffered.get("robots_txt") },
+ @not("model.overridden") resetDisabled;
+
+ @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) => {
- this.commitBuffer();
- this.set("saved", true);
- this.set("model.overridden", data.overridden);
- })
- .finally(() => this.set("isSaving", false));
- },
+ .finally(() => this.set("isSaving", false));
+ }
- reset() {
- this.setProperties({
- isSaving: true,
- saved: false,
- });
- ajax("robots.json", { type: "DELETE" })
- .then((data) => {
- this.buffered.set("robots_txt", data.robots_txt);
- this.commitBuffer();
- this.set("saved", true);
- this.set("model.overridden", false);
- })
- .finally(() => this.set("isSaving", false));
- },
- },
-});
+ @action
+ reset() {
+ this.setProperties({
+ isSaving: true,
+ saved: false,
+ });
+ ajax("robots.json", { type: "DELETE" })
+ .then((data) => {
+ this.buffered.set("robots_txt", data.robots_txt);
+ this.commitBuffer();
+ this.set("saved", true);
+ this.set("model.overridden", false);
+ })
+ .finally(() => this.set("isSaving", false));
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-customize-themes-edit.js b/app/assets/javascripts/admin/addon/controllers/admin-customize-themes-edit.js
index 2c0cd18a702..e89b1a8c122 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-customize-themes-edit.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-customize-themes-edit.js
@@ -1,21 +1,24 @@
+import { action } from "@ember/object";
import Controller from "@ember/controller";
import I18n from "I18n";
import discourseComputed from "discourse-common/utils/decorators";
import { url } from "discourse/lib/computed";
-export default Controller.extend({
- section: null,
- currentTarget: 0,
- maximized: false,
- previewUrl: url("model.id", "/admin/themes/%@/preview"),
- showAdvanced: false,
- editRouteName: "adminCustomizeThemes.edit",
- showRouteName: "adminCustomizeThemes.show",
+export default class AdminCustomizeThemesEditController extends Controller {
+ section = null;
+ currentTarget = 0;
+ maximized = false;
+
+ @url("model.id", "/admin/themes/%@/preview") previewUrl;
+
+ showAdvanced = false;
+ editRouteName = "adminCustomizeThemes.edit";
+ showRouteName = "adminCustomizeThemes.show";
setTargetName(name) {
const target = this.get("model.targets").find((t) => t.name === name);
this.set("currentTarget", target && target.id);
- },
+ }
@discourseComputed("currentTarget")
currentTargetName(id) {
@@ -23,50 +26,52 @@ export default Controller.extend({
(t) => t.id === parseInt(id, 10)
);
return target && target.name;
- },
+ }
@discourseComputed("model.isSaving")
saveButtonText(isSaving) {
return isSaving ? I18n.t("saving") : I18n.t("admin.customize.save");
- },
+ }
@discourseComputed("model.changed", "model.isSaving")
saveDisabled(changed, isSaving) {
return !changed || isSaving;
- },
+ }
- actions: {
- save() {
- this.set("saving", true);
- this.model.saveChanges("theme_fields").finally(() => {
- this.set("saving", false);
- });
- },
+ @action
+ save() {
+ this.set("saving", true);
+ this.model.saveChanges("theme_fields").finally(() => {
+ this.set("saving", false);
+ });
+ }
- fieldAdded(target, name) {
- this.replaceRoute(this.editRouteName, this.get("model.id"), target, name);
- },
+ @action
+ fieldAdded(target, name) {
+ this.replaceRoute(this.editRouteName, this.get("model.id"), target, name);
+ }
- onlyOverriddenChanged(onlyShowOverridden) {
- if (onlyShowOverridden) {
- if (!this.model.hasEdited(this.currentTargetName, this.fieldName)) {
- let firstTarget = this.get("model.targets").find((t) => t.edited);
- let firstField = this.get(`model.fields.${firstTarget.name}`).find(
- (f) => f.edited
- );
+ @action
+ onlyOverriddenChanged(onlyShowOverridden) {
+ if (onlyShowOverridden) {
+ if (!this.model.hasEdited(this.currentTargetName, this.fieldName)) {
+ let firstTarget = this.get("model.targets").find((t) => t.edited);
+ let firstField = this.get(`model.fields.${firstTarget.name}`).find(
+ (f) => f.edited
+ );
- this.replaceRoute(
- this.editRouteName,
- this.get("model.id"),
- firstTarget.name,
- firstField.name
- );
- }
+ this.replaceRoute(
+ this.editRouteName,
+ this.get("model.id"),
+ firstTarget.name,
+ firstField.name
+ );
}
- },
+ }
+ }
- goBack() {
- this.replaceRoute(this.showRouteName, this.model.id);
- },
- },
-});
+ @action
+ goBack() {
+ this.replaceRoute(this.showRouteName, this.model.id);
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-customize-themes-show.js b/app/assets/javascripts/admin/addon/controllers/admin-customize-themes-show.js
index 45d19733059..218e6ee3f71 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-customize-themes-show.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-customize-themes-show.js
@@ -1,4 +1,4 @@
-import { COMPONENTS, THEMES } from "admin/models/theme";
+import { inject as service } from "@ember/service";
import {
empty,
filterBy,
@@ -6,8 +6,9 @@ import {
match,
notEmpty,
} from "@ember/object/computed";
+import { COMPONENTS, THEMES } from "admin/models/theme";
import Controller from "@ember/controller";
-import EmberObject from "@ember/object";
+import EmberObject, { action } from "@ember/object";
import I18n from "I18n";
import ThemeSettings from "admin/models/theme-settings";
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 showModal from "discourse/lib/show-modal";
import { url } from "discourse/lib/computed";
-import { inject as service } from "@ember/service";
const THEME_UPLOAD_VAR = 2;
-export default Controller.extend({
- dialog: service(),
- downloadUrl: url("model.id", "/admin/customize/themes/%@/export"),
- previewUrl: url("model.id", "/admin/themes/%@/preview"),
- addButtonDisabled: empty("selectedChildThemeId"),
- editRouteName: "adminCustomizeThemes.edit",
- parentThemesNames: mapBy("model.parentThemes", "name"),
- availableParentThemes: filterBy("allThemes", "component", false),
- availableActiveParentThemes: filterBy("availableParentThemes", "isActive"),
- availableThemesNames: mapBy("availableParentThemes", "name"),
- availableActiveThemesNames: mapBy("availableActiveParentThemes", "name"),
- availableActiveChildThemes: filterBy("availableChildThemes", "hasParents"),
- availableComponentsNames: mapBy("availableChildThemes", "name"),
- availableActiveComponentsNames: mapBy("availableActiveChildThemes", "name"),
- childThemesNames: mapBy("model.childThemes", "name"),
- extraFiles: filterBy("model.theme_fields", "target", "extra_js"),
+export default class AdminCustomizeThemesShowController extends Controller {
+ @service dialog;
+
+ editRouteName = "adminCustomizeThemes.edit";
+
+ @url("model.id", "/admin/customize/themes/%@/export") downloadUrl;
+ @url("model.id", "/admin/themes/%@/preview") previewUrl;
+ @empty("selectedChildThemeId") addButtonDisabled;
+ @mapBy("model.parentThemes", "name") parentThemesNames;
+ @filterBy("allThemes", "component", false) availableParentThemes;
+ @filterBy("availableParentThemes", "isActive") availableActiveParentThemes;
+ @mapBy("availableParentThemes", "name") availableThemesNames;
+ @mapBy("availableActiveParentThemes", "name") availableActiveThemesNames;
+ @filterBy("availableChildThemes", "hasParents") availableActiveChildThemes;
+ @mapBy("availableChildThemes", "name") availableComponentsNames;
+ @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")
showCheckboxes() {
return !this.model.component || this.model.remote_theme;
- },
+ }
@discourseComputed("model.editedFields")
editedFieldsFormatted() {
@@ -57,13 +62,13 @@ export default Controller.extend({
descriptions.push(resultString);
});
return descriptions;
- },
+ }
@discourseComputed("colorSchemeId", "model.color_scheme_id")
colorSchemeChanged(colorSchemeId, existingId) {
colorSchemeId = colorSchemeId === null ? null : parseInt(colorSchemeId, 10);
return colorSchemeId !== existingId;
- },
+ }
@discourseComputed("availableChildThemes", "model.childThemes.[]", "model")
selectableChildThemes(available, childThemes) {
@@ -73,7 +78,7 @@ export default Controller.extend({
: available.filter((theme) => !childThemes.includes(theme));
return themes.length === 0 ? null : themes;
}
- },
+ }
@discourseComputed("model.parentThemes.[]")
relativesSelectorSettingsForComponent() {
@@ -91,7 +96,7 @@ export default Controller.extend({
allThemes: this.allThemes,
setDefaultValuesLabel: I18n.t("admin.customize.theme.add_all_themes"),
});
- },
+ }
@discourseComputed("model.parentThemes.[]")
relativesSelectorSettingsForTheme() {
@@ -109,7 +114,7 @@ export default Controller.extend({
allThemes: this.allThemes,
setDefaultValuesLabel: I18n.t("admin.customize.theme.add_all"),
});
- },
+ }
@discourseComputed("allThemes", "model.component", "model")
availableChildThemes(allThemes) {
@@ -119,40 +124,36 @@ export default Controller.extend({
(theme) => theme.get("id") !== themeId && theme.get("component")
);
}
- },
+ }
@discourseComputed("model.component")
convertKey(component) {
const type = component ? "component" : "theme";
return `admin.customize.theme.convert_${type}`;
- },
+ }
@discourseComputed("model.component")
convertIcon(component) {
return component ? "cube" : "";
- },
+ }
@discourseComputed("model.component")
convertTooltip(component) {
const type = component ? "component" : "theme";
return `admin.customize.theme.convert_${type}_tooltip`;
- },
+ }
@discourseComputed("model.settings")
settings(settings) {
return settings.map((setting) => ThemeSettings.create(setting));
- },
-
- hasSettings: notEmpty("settings"),
+ }
@discourseComputed("model.translations")
translations(translations) {
return translations.map((setting) =>
ThemeSettings.create({ ...setting, textarea: true })
);
- },
-
- hasTranslations: notEmpty("translations"),
+ }
@discourseComputed(
"model.remote_theme.local_version",
@@ -161,12 +162,12 @@ export default Controller.extend({
)
hasOverwrittenHistory(localVersion, remoteVersion, commitsBehind) {
return localVersion !== remoteVersion && commitsBehind === -1;
- },
+ }
@discourseComputed("model.remoteError", "updatingRemote")
showRemoteError(errorMessage, updating) {
return errorMessage && !updating;
- },
+ }
@discourseComputed(
"model.remote_theme.remote_url",
@@ -175,13 +176,13 @@ export default Controller.extend({
)
finishInstall(remoteUrl, localVersion, commitsBehind) {
return remoteUrl && !localVersion && !commitsBehind;
- },
+ }
editedFieldsForTarget(target) {
return this.get("model.editedFields").filter(
(field) => field.target === target
);
- },
+ }
commitSwitchType() {
const model = this.model;
@@ -222,7 +223,8 @@ export default Controller.extend({
});
})
.catch(popupAjaxError);
- },
+ }
+
transitionToEditRoute() {
this.transitionToRoute(
this.editRouteName,
@@ -230,8 +232,7 @@ export default Controller.extend({
"common",
"scss"
);
- },
- sourceIsHttp: match("model.remote_theme.remote_url", /^http(s)?:\/\//),
+ }
@discourseComputed(
"model.remote_theme.remote_url",
@@ -241,168 +242,186 @@ export default Controller.extend({
return remoteThemeBranch
? `${remoteThemeUrl.replace(/\.git$/, "")}/tree/${remoteThemeBranch}`
: remoteThemeUrl;
- },
+ }
@discourseComputed("model.user.id", "model.default")
showConvert(userId, defaultTheme) {
return userId > 0 && !defaultTheme;
- },
+ }
- actions: {
- updateToLatest() {
- this.set("updatingRemote", true);
- this.model
- .updateToLatest()
- .catch(popupAjaxError)
- .finally(() => {
- 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);
- }
- });
- }
+ @action
+ updateToLatest() {
+ this.set("updatingRemote", true);
+ this.model
+ .updateToLatest()
+ .catch(popupAjaxError)
+ .finally(() => {
+ this.set("updatingRemote", false);
});
- },
+ }
- applyUserSelectable() {
- this.model.saveChanges("user_selectable");
- },
-
- applyAutoUpdateable() {
- this.model.saveChanges("auto_update");
- },
-
- 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),
+ @action
+ checkForThemeUpdates() {
+ this.set("updatingRemote", true);
+ this.model
+ .checkForUpdates()
+ .catch(popupAjaxError)
+ .finally(() => {
+ this.set("updatingRemote", false);
});
- },
+ }
- removeChildTheme(theme) {
- this.model
- .removeChildTheme(theme)
- .then(() => this.store.findAll("theme"));
- },
+ @action
+ addUploadModal() {
+ showModal("admin-add-upload", { admin: true, name: "" });
+ }
- destroy() {
- 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
+ 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));
+ }
+
+ @action
+ cancelChangeScheme() {
+ this.set("colorSchemeId", this.get("model.color_scheme_id"));
+ }
+
+ @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() {
- 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(", "),
+ @action
+ 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);
+ }
});
}
+ });
+ }
- return this.dialog.yesNoConfirm({
- message,
- didConfirm: () => this.commitSwitchType(),
+ @action
+ applyUserSelectable() {
+ 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() {
- this.model.set("enabled", true);
- this.model
- .saveChanges("enabled")
- .catch(() => this.model.set("enabled", false));
- },
+ return this.dialog.yesNoConfirm({
+ message,
+ didConfirm: () => this.commitSwitchType(),
+ });
+ }
- disableComponent() {
- this.model.set("enabled", false);
- this.model
- .saveChanges("enabled")
- .catch(() => this.model.set("enabled", true));
- },
- },
-});
+ @action
+ enableComponent() {
+ this.model.set("enabled", true);
+ this.model
+ .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));
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-customize-themes.js b/app/assets/javascripts/admin/addon/controllers/admin-customize-themes.js
index a598ade6f5c..341114f89fb 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-customize-themes.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-customize-themes.js
@@ -2,21 +2,21 @@ import Controller from "@ember/controller";
import { THEMES } from "admin/models/theme";
import discourseComputed from "discourse-common/utils/decorators";
-export default Controller.extend({
- currentTab: THEMES,
+export default class AdminCustomizeThemesController extends Controller {
+ currentTab = THEMES;
@discourseComputed("model", "model.@each.component")
fullThemes(themes) {
return themes.filter((t) => !t.get("component"));
- },
+ }
@discourseComputed("model", "model.@each.component")
childThemes(themes) {
return themes.filter((t) => t.get("component"));
- },
+ }
@discourseComputed("model.content")
installedThemes(content) {
return content || [];
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-dashboard-general.js b/app/assets/javascripts/admin/addon/controllers/admin-dashboard-general.js
index bde2cf574b2..3edc3a1cc19 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-dashboard-general.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-dashboard-general.js
@@ -1,9 +1,9 @@
+import { computed } from "@ember/object";
import Controller, { inject as controller } from "@ember/controller";
import AdminDashboard from "admin/models/admin-dashboard";
import I18n from "I18n";
import PeriodComputationMixin from "admin/mixins/period-computation";
import Report from "admin/models/report";
-import { computed } from "@ember/object";
import discourseComputed from "discourse-common/utils/decorators";
import getURL from "discourse-common/lib/get-url";
import { makeArray } from "discourse-common/lib/helpers";
@@ -15,41 +15,49 @@ function staticReport(reportType) {
});
}
-export default Controller.extend(PeriodComputationMixin, {
- isLoading: false,
- dashboardFetchedAt: null,
- exceptionController: controller("exception"),
- logSearchQueriesEnabled: setting("log_search_queries"),
+export default class AdminDashboardGeneralController extends Controller.extend(
+ PeriodComputationMixin
+) {
+ @controller("exception") exceptionController;
+
+ 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")
activityMetrics(metrics) {
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 || "")
.split("|")
.filter(Boolean);
- }),
+ }
- isActivityMetricsVisible: computed(
- "activityMetrics",
- "hiddenReports",
- function () {
- return (
- this.activityMetrics.length &&
- this.activityMetrics.some((x) => !this.hiddenReports.includes(x))
- );
- }
- ),
+ @computed("activityMetrics", "hiddenReports")
+ get isActivityMetricsVisible() {
+ return (
+ 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(
(x) => !this.hiddenReports.includes(x)
);
- }),
+ }
- isCommunityHealthVisible: computed("hiddenReports", function () {
+ @computed("hiddenReports")
+ get isCommunityHealthVisible() {
return [
"consolidated_page_views",
"signups",
@@ -59,7 +67,7 @@ export default Controller.extend(PeriodComputationMixin, {
"daily_engaged_users",
"new_contributors",
].some((x) => !this.hiddenReports.includes(x));
- }),
+ }
@discourseComputed
activityMetricsFilters() {
@@ -67,14 +75,14 @@ export default Controller.extend(PeriodComputationMixin, {
startDate: this.lastMonth,
endDate: this.today,
};
- },
+ }
@discourseComputed
topReferredTopicsOptions() {
return {
table: { total: false, limit: 8 },
};
- },
+ }
@discourseComputed
topReferredTopicsFilters() {
@@ -82,7 +90,7 @@ export default Controller.extend(PeriodComputationMixin, {
startDate: moment().subtract(6, "days").startOf("day"),
endDate: this.today,
};
- },
+ }
@discourseComputed
trendingSearchFilters() {
@@ -90,25 +98,21 @@ export default Controller.extend(PeriodComputationMixin, {
startDate: moment().subtract(1, "month").startOf("day"),
endDate: this.today,
};
- },
+ }
@discourseComputed
trendingSearchOptions() {
return {
table: { total: false, limit: 8 },
};
- },
+ }
@discourseComputed
trendingSearchDisabledLabel() {
return I18n.t("admin.dashboard.reports.trending_search.disabled", {
basePath: getURL(""),
});
- },
-
- usersByTypeReport: staticReport("users_by_type"),
- usersByTrustLevelReport: staticReport("users_by_trust_level"),
- storageReport: staticReport("storage_report"),
+ }
fetchDashboard() {
if (this.isLoading) {
@@ -137,14 +141,14 @@ export default Controller.extend(PeriodComputationMixin, {
})
.finally(() => this.set("isLoading", false));
}
- },
+ }
@discourseComputed("startDate", "endDate")
filters(startDate, endDate) {
return { startDate, endDate };
- },
+ }
_reportsForPeriodURL(period) {
return getURL(`/admin?period=${period}`);
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-dashboard-moderation.js b/app/assets/javascripts/admin/addon/controllers/admin-dashboard-moderation.js
index 16e632d6e22..ef08301f811 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-dashboard-moderation.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-dashboard-moderation.js
@@ -1,10 +1,12 @@
+import { computed } from "@ember/object";
import Controller from "@ember/controller";
import PeriodComputationMixin from "admin/mixins/period-computation";
-import { computed } from "@ember/object";
import discourseComputed from "discourse-common/utils/decorators";
import getURL from "discourse-common/lib/get-url";
-export default Controller.extend(PeriodComputationMixin, {
+export default class AdminDashboardModerationController extends Controller.extend(
+ PeriodComputationMixin
+) {
@discourseComputed
flagsStatusOptions() {
return {
@@ -13,17 +15,15 @@ export default Controller.extend(PeriodComputationMixin, {
perPage: 10,
},
};
- },
+ }
- isModeratorsActivityVisible: computed(
- "siteSettings.dashboard_hidden_reports",
- function () {
- return !(this.siteSettings.dashboard_hidden_reports || "")
- .split("|")
- .filter(Boolean)
- .includes("moderators_activity");
- }
- ),
+ @computed("siteSettings.dashboard_hidden_reports")
+ get isModeratorsActivityVisible() {
+ return !(this.siteSettings.dashboard_hidden_reports || "")
+ .split("|")
+ .filter(Boolean)
+ .includes("moderators_activity");
+ }
@discourseComputed
userFlaggingRatioOptions() {
@@ -33,19 +33,19 @@ export default Controller.extend(PeriodComputationMixin, {
perPage: 10,
},
};
- },
+ }
@discourseComputed("startDate", "endDate")
filters(startDate, endDate) {
return { startDate, endDate };
- },
+ }
@discourseComputed("lastWeek", "endDate")
lastWeekfilters(startDate, endDate) {
return { startDate, endDate };
- },
+ }
_reportsForPeriodURL(period) {
return getURL(`/admin/dashboard/moderation?period=${period}`);
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-dashboard-reports.js b/app/assets/javascripts/admin/addon/controllers/admin-dashboard-reports.js
index b4b8c16617c..920f9459eca 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-dashboard-reports.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-dashboard-reports.js
@@ -2,10 +2,10 @@ import Controller from "@ember/controller";
import { INPUT_DELAY } from "discourse-common/config/environment";
import discourseComputed from "discourse-common/utils/decorators";
import discourseDebounce from "discourse-common/lib/debounce";
-import { get } from "@ember/object";
+import { action, get } from "@ember/object";
-export default Controller.extend({
- filter: null,
+export default class AdminDashboardReportsController extends Controller {
+ filter = null;
@discourseComputed(
"model.[]",
@@ -29,15 +29,14 @@ export default Controller.extend({
reports = reports.filter((report) => !hiddenReports.includes(report.type));
return reports;
- },
+ }
- actions: {
- filterReports(filter) {
- discourseDebounce(this, this._performFiltering, filter, INPUT_DELAY);
- },
- },
+ @action
+ filterReports(filter) {
+ discourseDebounce(this, this._performFiltering, filter, INPUT_DELAY);
+ }
_performFiltering(filter) {
this.set("filter", filter);
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-dashboard.js b/app/assets/javascripts/admin/addon/controllers/admin-dashboard.js
index 004df68daa7..b420d8a86cc 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-dashboard.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-dashboard.js
@@ -1,17 +1,19 @@
+import { action, computed } from "@ember/object";
import Controller, { inject as controller } from "@ember/controller";
import AdminDashboard from "admin/models/admin-dashboard";
import VersionCheck from "admin/models/version-check";
-import { computed } from "@ember/object";
import discourseComputed from "discourse-common/utils/decorators";
import { setting } from "discourse/lib/computed";
const PROBLEMS_CHECK_MINUTES = 1;
-export default Controller.extend({
- isLoading: false,
- dashboardFetchedAt: null,
- exceptionController: controller("exception"),
- showVersionChecks: setting("version_checks"),
+export default class AdminDashboardController extends Controller {
+ @controller("exception") exceptionController;
+
+ isLoading = false;
+ dashboardFetchedAt = null;
+
+ @setting("version_checks") showVersionChecks;
@discourseComputed(
"lowPriorityProblems.length",
@@ -21,25 +23,29 @@ export default Controller.extend({
const problemsLength =
lowPriorityProblemsLength + highPriorityProblemsLength;
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 || "")
.split("|")
.filter(Boolean);
- }),
+ }
- isModerationTabVisible: computed("visibleTabs", function () {
+ @computed("visibleTabs")
+ get isModerationTabVisible() {
return this.visibleTabs.includes("moderation");
- }),
+ }
- isSecurityTabVisible: computed("visibleTabs", function () {
+ @computed("visibleTabs")
+ get isSecurityTabVisible() {
return this.visibleTabs.includes("security");
- }),
+ }
- isReportsTabVisible: computed("visibleTabs", function () {
+ @computed("visibleTabs")
+ get isReportsTabVisible() {
return this.visibleTabs.includes("reports");
- }),
+ }
fetchProblems() {
if (this.isLoadingProblems) {
@@ -53,7 +59,7 @@ export default Controller.extend({
) {
this._loadProblems();
}
- },
+ }
fetchDashboard() {
const versionChecks = this.siteSettings.version_checks;
@@ -88,7 +94,7 @@ export default Controller.extend({
this.set("isLoading", false);
});
}
- },
+ }
_loadProblems() {
this.setProperties({
@@ -108,16 +114,15 @@ export default Controller.extend({
);
})
.finally(() => this.set("loadingProblems", false));
- },
+ }
@discourseComputed("problemsFetchedAt")
problemsTimestamp(problemsFetchedAt) {
return moment(problemsFetchedAt).locale("en").format("LLL");
- },
+ }
- actions: {
- refreshProblems() {
- this._loadProblems();
- },
- },
-});
+ @action
+ refreshProblems() {
+ this._loadProblems();
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-email-advanced-test.js b/app/assets/javascripts/admin/addon/controllers/admin-email-advanced-test.js
index 860f276f8ae..1b27a572b6f 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-email-advanced-test.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-email-advanced-test.js
@@ -1,31 +1,31 @@
+import { action } from "@ember/object";
import Controller from "@ember/controller";
import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
-export default Controller.extend({
- email: null,
- text: null,
- elided: null,
- format: null,
- loading: null,
+export default class AdminEmailAdvancedTestController extends Controller {
+ email = null;
+ text = null;
+ elided = null;
+ format = null;
+ loading = null;
- actions: {
- run() {
- this.set("loading", true);
+ @action
+ run() {
+ this.set("loading", true);
- ajax("/admin/email/advanced-test", {
- type: "POST",
- data: { email: this.email },
+ ajax("/admin/email/advanced-test", {
+ type: "POST",
+ data: { email: this.email },
+ })
+ .then((data) => {
+ this.setProperties({
+ text: data.text,
+ elided: data.elided,
+ format: data.format,
+ });
})
- .then((data) => {
- this.setProperties({
- text: data.text,
- elided: data.elided,
- format: data.format,
- });
- })
- .catch(popupAjaxError)
- .finally(() => this.set("loading", false));
- },
- },
-});
+ .catch(popupAjaxError)
+ .finally(() => this.set("loading", false));
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-email-bounced.js b/app/assets/javascripts/admin/addon/controllers/admin-email-bounced.js
index c7a8ec98a60..79384e70f18 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-email-bounced.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-email-bounced.js
@@ -1,18 +1,18 @@
import AdminEmailLogsController from "admin/controllers/admin-email-logs";
import { INPUT_DELAY } from "discourse-common/config/environment";
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";
-export default AdminEmailLogsController.extend({
+export default class AdminEmailBouncedController extends AdminEmailLogsController {
@action
handleShowIncomingEmail(id, event) {
event?.preventDefault();
this.send("showIncomingEmail", id);
- },
+ }
@observes("filter.{status,user,address,type}")
filterEmailLogs() {
discourseDebounce(this, this.loadLogs, INPUT_DELAY);
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-email-index.js b/app/assets/javascripts/admin/addon/controllers/admin-email-index.js
index dddec41d1cb..81bda7c5b16 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-email-index.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-email-index.js
@@ -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 I18n from "I18n";
import { ajax } from "discourse/lib/ajax";
-import { empty } from "@ember/object/computed";
-import { observes } from "discourse-common/utils/decorators";
-import { inject as service } from "@ember/service";
+import { observes } from "@ember-decorators/object";
import { htmlSafe } from "@ember/template";
import { escapeExpression } from "discourse/lib/utilities";
-export default Controller.extend({
- dialog: service(),
+export default class AdminEmailIndexController extends Controller {
+ @service dialog;
/**
Is the "send test email" button disabled?
@property sendTestEmailDisabled
**/
- sendTestEmailDisabled: empty("testEmailAddress"),
+ @empty("testEmailAddress") sendTestEmailDisabled;
/**
Clears the 'sentTestEmail' property on successful send.
@@ -25,43 +26,40 @@ export default Controller.extend({
@observes("testEmailAddress")
testEmailAddressChanged() {
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
- **/
- sendTestEmail() {
- this.setProperties({
- sendingEmail: true,
- sentTestEmail: false,
- });
+ @method sendTestEmail
+ **/
+ @action
+ sendTestEmail() {
+ this.setProperties({
+ sendingEmail: true,
+ sentTestEmail: false,
+ });
- ajax("/admin/email/test", {
- type: "POST",
- data: { email_address: this.testEmailAddress },
+ ajax("/admin/email/test", {
+ type: "POST",
+ 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) =>
- 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));
- },
- },
-});
+ .finally(() => this.set("sendingEmail", false));
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-email-logs.js b/app/assets/javascripts/admin/addon/controllers/admin-email-logs.js
index 048ad491528..cb8e04736a7 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-email-logs.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-email-logs.js
@@ -1,14 +1,11 @@
import Controller from "@ember/controller";
import EmailLog from "admin/models/email-log";
-import EmberObject from "@ember/object";
+import EmberObject, { action } from "@ember/object";
-export default Controller.extend({
- loading: false,
+export default class AdminEmailLogsController extends Controller {
+ loading = false;
+ filter = EmberObject.create();
- init() {
- this._super(...arguments);
- this.set("filter", EmberObject.create());
- },
loadLogs(sourceModel, loadMore) {
if ((loadMore && this.loading) || this.get("model.allLoaded")) {
return;
@@ -38,11 +35,10 @@ export default Controller.extend({
}
})
.finally(() => this.set("loading", false));
- },
+ }
- actions: {
- loadMore() {
- this.loadLogs(EmailLog, true);
- },
- },
-});
+ @action
+ loadMore() {
+ this.loadLogs(EmailLog, true);
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-email-preview-digest.js b/app/assets/javascripts/admin/addon/controllers/admin-email-preview-digest.js
index 84f85eea6d3..4120390eedb 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-email-preview-digest.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-email-preview-digest.js
@@ -1,66 +1,67 @@
+import { inject as service } from "@ember/service";
import { empty, notEmpty, or } from "@ember/object/computed";
import Controller from "@ember/controller";
import EmailPreview from "admin/models/email-preview";
import { action, get } from "@ember/object";
import { popupAjaxError } from "discourse/lib/ajax-error";
-import { inject as service } from "@ember/service";
-export default Controller.extend({
- dialog: service(),
- username: null,
- lastSeen: null,
- emailEmpty: empty("email"),
- sendEmailDisabled: or("emailEmpty", "sendingEmail"),
- showSendEmailForm: notEmpty("model.html_content"),
- htmlEmpty: empty("model.html_content"),
+export default class AdminEmailPreviewDigestController extends Controller {
+ @service dialog;
+
+ username = null;
+ lastSeen = null;
+
+ @empty("email") emailEmpty;
+ @or("emailEmpty", "sendingEmail") sendEmailDisabled;
+ @notEmpty("model.html_content") showSendEmailForm;
+ @empty("model.html_content") htmlEmpty;
@action
toggleShowHtml(event) {
event?.preventDefault();
this.toggleProperty("showHtml");
- },
+ }
- actions: {
- updateUsername(selected) {
- this.set("username", get(selected, "firstObject"));
- },
+ @action
+ updateUsername(selected) {
+ this.set("username", get(selected, "firstObject"));
+ }
- refresh() {
- const model = this.model;
+ @action
+ refresh() {
+ const model = this.model;
- this.set("loading", true);
- this.set("sentEmail", false);
+ this.set("loading", true);
+ this.set("sentEmail", false);
- let username = this.username;
- if (!username) {
- username = this.currentUser.get("username");
- this.set("username", username);
- }
+ let username = this.username;
+ if (!username) {
+ username = this.currentUser.get("username");
+ this.set("username", username);
+ }
- EmailPreview.findDigest(username, this.lastSeen).then((email) => {
- model.setProperties(
- email.getProperties("html_content", "text_content")
- );
- this.set("loading", false);
+ EmailPreview.findDigest(username, this.lastSeen).then((email) => {
+ model.setProperties(email.getProperties("html_content", "text_content"));
+ 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);
- });
- },
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-email-received.js b/app/assets/javascripts/admin/addon/controllers/admin-email-received.js
index 0a2933fa23d..65434538eff 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-email-received.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-email-received.js
@@ -1,18 +1,18 @@
+import { action } from "@ember/object";
import AdminEmailLogsController from "admin/controllers/admin-email-logs";
import { INPUT_DELAY } from "discourse-common/config/environment";
import IncomingEmail from "admin/models/incoming-email";
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}")
filterIncomingEmails() {
discourseDebounce(this, this.loadLogs, IncomingEmail, INPUT_DELAY);
- },
+ }
- actions: {
- loadMore() {
- this.loadLogs(IncomingEmail, true);
- },
- },
-});
+ @action
+ loadMore() {
+ this.loadLogs(IncomingEmail, true);
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-email-rejected.js b/app/assets/javascripts/admin/addon/controllers/admin-email-rejected.js
index 6e4ce786568..184d632db66 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-email-rejected.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-email-rejected.js
@@ -2,24 +2,23 @@ import AdminEmailLogsController from "admin/controllers/admin-email-logs";
import { INPUT_DELAY } from "discourse-common/config/environment";
import IncomingEmail from "admin/models/incoming-email";
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";
-export default AdminEmailLogsController.extend({
+export default class AdminEmailRejectedController extends AdminEmailLogsController {
@observes("filter.{status,from,to,subject,error}")
filterIncomingEmails() {
discourseDebounce(this, this.loadLogs, IncomingEmail, INPUT_DELAY);
- },
+ }
@action
handleShowIncomingEmail(id, event) {
event?.preventDefault();
this.send("showIncomingEmail", id);
- },
+ }
- actions: {
- loadMore() {
- this.loadLogs(IncomingEmail, true);
- },
- },
-});
+ @action
+ loadMore() {
+ this.loadLogs(IncomingEmail, true);
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-email-sent.js b/app/assets/javascripts/admin/addon/controllers/admin-email-sent.js
index 5cc83109f8f..6d28b33d798 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-email-sent.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-email-sent.js
@@ -1,11 +1,11 @@
import AdminEmailLogsController from "admin/controllers/admin-email-logs";
import { INPUT_DELAY } from "discourse-common/config/environment";
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}")
filterEmailLogs() {
discourseDebounce(this, this.loadLogs, INPUT_DELAY);
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-email-skipped.js b/app/assets/javascripts/admin/addon/controllers/admin-email-skipped.js
index 15005495645..366f27b8d2e 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-email-skipped.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-email-skipped.js
@@ -1,11 +1,11 @@
import AdminEmailLogsController from "admin/controllers/admin-email-logs";
import { INPUT_DELAY } from "discourse-common/config/environment";
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}")
filterEmailLogs() {
discourseDebounce(this, this.loadLogs, INPUT_DELAY);
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-embedding.js b/app/assets/javascripts/admin/addon/controllers/admin-embedding.js
index 04579a40cd7..9fcccf318fc 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-embedding.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-embedding.js
@@ -1,17 +1,18 @@
+import { action } from "@ember/object";
import Controller from "@ember/controller";
import discourseComputed from "discourse-common/utils/decorators";
import { popupAjaxError } from "discourse/lib/ajax-error";
-export default Controller.extend({
- saved: false,
- embedding: null,
+export default class AdminEmbeddingController extends Controller {
+ saved = false;
+ embedding = null;
// show settings if we have at least one created host
@discourseComputed("embedding.embeddable_hosts.@each.isCreated")
showSecondary() {
const hosts = this.get("embedding.embeddable_hosts");
return hosts.length && hosts.findBy("isCreated");
- },
+ }
@discourseComputed("embedding.base_url")
embeddingCode(baseUrl) {
@@ -33,27 +34,28 @@ export default Controller.extend({
`;
return html;
- },
+ }
- actions: {
- saveChanges() {
- const embedding = this.embedding;
- const updates = embedding.getProperties(embedding.get("fields"));
+ @action
+ saveChanges() {
+ const embedding = this.embedding;
+ const updates = embedding.getProperties(embedding.get("fields"));
- this.set("saved", false);
- this.embedding
- .update(updates)
- .then(() => this.set("saved", true))
- .catch(popupAjaxError);
- },
+ this.set("saved", false);
+ this.embedding
+ .update(updates)
+ .then(() => this.set("saved", true))
+ .catch(popupAjaxError);
+ }
- addHost() {
- const host = this.store.createRecord("embeddable-host");
- this.get("embedding.embeddable_hosts").pushObject(host);
- },
+ @action
+ addHost() {
+ const host = this.store.createRecord("embeddable-host");
+ this.get("embedding.embeddable_hosts").pushObject(host);
+ }
- deleteHost(host) {
- this.get("embedding.embeddable_hosts").removeObject(host);
- },
- },
-});
+ @action
+ deleteHost(host) {
+ this.get("embedding.embeddable_hosts").removeObject(host);
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-emojis.js b/app/assets/javascripts/admin/addon/controllers/admin-emojis.js
index eab68cf088a..6e7f86d88aa 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-emojis.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-emojis.js
@@ -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 Controller from "@ember/controller";
import I18n from "I18n";
import { ajax } from "discourse/lib/ajax";
-import { sort } from "@ember/object/computed";
-import { inject as service } from "@ember/service";
const ALL_FILTER = "all";
-export default Controller.extend({
- dialog: service(),
- filter: null,
- sorting: null,
+export default class AdminEmojisController extends Controller {
+ @service dialog;
+ filter = null;
+ sorting = null;
+
+ @sort("filteredEmojis.[]", "sorting") sortedEmojis;
init() {
- this._super(...arguments);
+ super.init(...arguments);
this.setProperties({
filter: ALL_FILTER,
sorting: ["group", "name"],
});
- },
+ }
- sortedEmojis: sort("filteredEmojis.[]", "sorting"),
+ @computed("model")
+ get emojiGroups() {
+ return this.model.mapBy("group").uniq();
+ }
- emojiGroups: computed("model", {
- get() {
- return this.model.mapBy("group").uniq();
- },
- }),
+ @computed("emojiGroups.[]")
+ get sortingGroups() {
+ return [ALL_FILTER].concat(this.emojiGroups);
+ }
- sortingGroups: computed("emojiGroups.[]", {
- get() {
- return [ALL_FILTER].concat(this.emojiGroups);
- },
- }),
-
- filteredEmojis: computed("model.[]", "filter", {
- get() {
- if (!this.filter || this.filter === ALL_FILTER) {
- return this.model;
- } else {
- return this.model.filterBy("group", this.filter);
- }
- },
- }),
+ @computed("model.[]", "filter")
+ get filteredEmojis() {
+ if (!this.filter || this.filter === ALL_FILTER) {
+ return this.model;
+ } else {
+ return this.model.filterBy("group", this.filter);
+ }
+ }
_highlightEmojiList() {
const customEmojiListEl = document.querySelector("#custom_emoji");
@@ -56,12 +53,12 @@ export default Controller.extend({
customEmojiListEl.classList.remove("highlighted");
});
}
- },
+ }
@action
filterGroups(value) {
this.set("filter", value);
- },
+ }
@action
emojiUploaded(emoji, group) {
@@ -69,7 +66,7 @@ export default Controller.extend({
emoji.group = group;
this.model.pushObject(EmberObject.create(emoji));
this._highlightEmojiList();
- },
+ }
@action
destroyEmoji(emoji) {
@@ -85,5 +82,5 @@ export default Controller.extend({
});
},
});
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-logs-screened-emails.js b/app/assets/javascripts/admin/addon/controllers/admin-logs-screened-emails.js
index ed3cd6489d7..4ce490eff02 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-logs-screened-emails.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-logs-screened-emails.js
@@ -1,23 +1,24 @@
+import { action } from "@ember/object";
import Controller from "@ember/controller";
import ScreenedEmail from "admin/models/screened-email";
import { exportEntity } from "discourse/lib/export-csv";
import { outputExportResult } from "discourse/lib/export-result";
-export default Controller.extend({
- loading: false,
+export default class AdminLogsScreenedEmailsController extends Controller {
+ loading = false;
- actions: {
- clearBlock(row) {
- row.clearBlock().then(function () {
- // feeling lazy
- window.location.reload();
- });
- },
+ @action
+ clearBlock(row) {
+ row.clearBlock().then(function () {
+ // feeling lazy
+ window.location.reload();
+ });
+ }
- exportScreenedEmailList() {
- exportEntity("screened_email").then(outputExportResult);
- },
- },
+ @action
+ exportScreenedEmailList() {
+ exportEntity("screened_email").then(outputExportResult);
+ }
show() {
this.set("loading", true);
@@ -25,5 +26,5 @@ export default Controller.extend({
this.set("model", result);
this.set("loading", false);
});
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-logs-screened-ip-addresses.js b/app/assets/javascripts/admin/addon/controllers/admin-logs-screened-ip-addresses.js
index bc11ec51f46..99e0bcfc2bd 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-logs-screened-ip-addresses.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-logs-screened-ip-addresses.js
@@ -1,31 +1,32 @@
+import { inject as service } from "@ember/service";
import Controller from "@ember/controller";
import I18n from "I18n";
import { INPUT_DELAY } from "discourse-common/config/environment";
import ScreenedIpAddress from "admin/models/screened-ip-address";
import discourseDebounce from "discourse-common/lib/debounce";
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 { action } from "@ember/object";
-import { inject as service } from "@ember/service";
-export default Controller.extend({
- dialog: service(),
- loading: false,
- filter: null,
- savedIpAddress: null,
+export default class AdminLogsScreenedIpAddressesController extends Controller {
+ @service dialog;
+
+ loading = false;
+ filter = null;
+ savedIpAddress = null;
_debouncedShow() {
this.set("loading", true);
ScreenedIpAddress.findAll(this.filter).then((result) => {
this.setProperties({ model: result, loading: false });
});
- },
+ }
@observes("filter")
show() {
discourseDebounce(this, this._debouncedShow, INPUT_DELAY);
- },
+ }
@action
edit(record, event) {
@@ -34,81 +35,86 @@ export default Controller.extend({
this.set("savedIpAddress", record.get("ip_address"));
}
record.set("editing", true);
- },
+ }
- actions: {
- allow(record) {
- record.set("action_name", "do_nothing");
- record.save();
- },
+ @action
+ allow(record) {
+ record.set("action_name", "do_nothing");
+ record.save();
+ }
- block(record) {
- record.set("action_name", "block");
- record.save();
- },
+ @action
+ block(record) {
+ record.set("action_name", "block");
+ record.save();
+ }
- cancel(record) {
- const savedIpAddress = this.savedIpAddress;
- if (savedIpAddress && record.get("editing")) {
- record.set("ip_address", savedIpAddress);
- }
- record.set("editing", false);
- },
+ @action
+ cancel(record) {
+ const savedIpAddress = this.savedIpAddress;
+ if (savedIpAddress && record.get("editing")) {
+ record.set("ip_address", savedIpAddress);
+ }
+ record.set("editing", false);
+ }
- save(record) {
- const wasEditing = record.get("editing");
- record.set("editing", false);
- record
- .save()
- .then(() => this.set("savedIpAddress", null))
- .catch((e) => {
- if (e.jqXHR.responseJSON && e.jqXHR.responseJSON.errors) {
+ @action
+ save(record) {
+ const wasEditing = record.get("editing");
+ record.set("editing", false);
+ record
+ .save()
+ .then(() => this.set("savedIpAddress", null))
+ .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(
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) {
- 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(
- I18n.t("generic_error_with_reason", {
- error: `http: ${e.status} - ${e.body}`,
- })
- );
- });
- },
- });
- },
+ @action
+ recordAdded(arg) {
+ this.model.unshiftObject(arg);
+ }
- recordAdded(arg) {
- this.model.unshiftObject(arg);
- },
-
- exportScreenedIpList() {
- exportEntity("screened_ip").then(outputExportResult);
- },
- },
-});
+ @action
+ exportScreenedIpList() {
+ exportEntity("screened_ip").then(outputExportResult);
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-logs-screened-urls.js b/app/assets/javascripts/admin/addon/controllers/admin-logs-screened-urls.js
index 86621f59689..dc1e174d6a5 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-logs-screened-urls.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-logs-screened-urls.js
@@ -1,10 +1,11 @@
+import { action } from "@ember/object";
import Controller from "@ember/controller";
import ScreenedUrl from "admin/models/screened-url";
import { exportEntity } from "discourse/lib/export-csv";
import { outputExportResult } from "discourse/lib/export-result";
-export default Controller.extend({
- loading: false,
+export default class AdminLogsScreenedUrlsController extends Controller {
+ loading = false;
show() {
this.set("loading", true);
@@ -12,11 +13,10 @@ export default Controller.extend({
this.set("model", result);
this.set("loading", false);
});
- },
+ }
- actions: {
- exportScreenedUrlList() {
- exportEntity("screened_url").then(outputExportResult);
- },
- },
-});
+ @action
+ exportScreenedUrlList() {
+ exportEntity("screened_url").then(outputExportResult);
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-logs-staff-action-logs.js b/app/assets/javascripts/admin/addon/controllers/admin-logs-staff-action-logs.js
index 11e5324bd61..5b8727aa115 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-logs-staff-action-logs.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-logs-staff-action-logs.js
@@ -7,22 +7,21 @@ import { outputExportResult } from "discourse/lib/export-result";
import { scheduleOnce } from "@ember/runloop";
import showModal from "discourse/lib/show-modal";
-export default Controller.extend({
- queryParams: ["filters"],
-
- model: null,
- filters: null,
- userHistoryActions: null,
+export default class AdminLogsStaffActionLogsController extends Controller {
+ queryParams = ["filters"];
+ model = null;
+ filters = null;
+ userHistoryActions = null;
@discourseComputed("filters.action_name")
actionFilter(name) {
return name ? I18n.t("admin.logs.staff_actions.actions." + name) : null;
- },
+ }
@discourseComputed("filters")
filtersExists(filters) {
return filters && Object.keys(filters).length > 0;
- },
+ }
_refresh() {
this.store.findAll("staff-action-log", this.filters).then((result) => {
@@ -44,11 +43,11 @@ export default Controller.extend({
);
}
});
- },
+ }
scheduleRefresh() {
scheduleOnce("afterRender", this, this._refresh);
- },
+ }
resetFilters() {
this.setProperties({
@@ -56,7 +55,7 @@ export default Controller.extend({
filters: EmberObject.create(),
});
this.scheduleRefresh();
- },
+ }
changeFilters(props) {
this.set("model", EmberObject.create({ loadingMore: true }));
@@ -76,7 +75,7 @@ export default Controller.extend({
this.send("onFiltersChange", this.filters);
this.scheduleRefresh();
- },
+ }
@action
filterActionIdChanged(filterActionId) {
@@ -87,7 +86,7 @@ export default Controller.extend({
.action_id,
});
}
- },
+ }
@action
clearFilter(key, event) {
@@ -102,14 +101,14 @@ export default Controller.extend({
} else {
this.changeFilters({ [key]: null });
}
- },
+ }
@action
clearAllFilters(event) {
event?.preventDefault();
this.set("filterActionId", null);
this.resetFilters();
- },
+ }
@action
filterByAction(logItem, event) {
@@ -119,35 +118,35 @@ export default Controller.extend({
action_id: logItem.get("action"),
custom_type: logItem.get("custom_type"),
});
- },
+ }
@action
filterByStaffUser(acting_user, event) {
event?.preventDefault();
this.changeFilters({ acting_user: acting_user.username });
- },
+ }
@action
filterByTargetUser(target_user, event) {
event?.preventDefault();
this.changeFilters({ target_user: target_user.username });
- },
+ }
@action
filterBySubject(subject, event) {
event?.preventDefault();
this.changeFilters({ subject });
- },
+ }
@action
exportStaffActionLogs() {
exportEntity("staff_action").then(outputExportResult);
- },
+ }
@action
loadMore() {
this.model.loadMore();
- },
+ }
@action
showDetailsModal(model, event) {
@@ -157,7 +156,7 @@ export default Controller.extend({
admin: true,
modalClass: "log-details-modal",
});
- },
+ }
@action
showCustomDetailsModal(model, event) {
@@ -168,5 +167,5 @@ export default Controller.extend({
modalClass: "history-modal",
});
modal.loadDiff();
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-permalinks.js b/app/assets/javascripts/admin/addon/controllers/admin-permalinks.js
index 37f51260685..dcd31f10207 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-permalinks.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-permalinks.js
@@ -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 I18n from "I18n";
import { INPUT_DELAY } from "discourse-common/config/environment";
import Permalink from "admin/models/permalink";
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 { inject as service } from "@ember/service";
-import { or } from "@ember/object/computed";
-export default Controller.extend({
- dialog: service(),
- loading: false,
- filter: null,
- showSearch: or("model.length", "filter"),
+export default class AdminPermalinksController extends Controller {
+ @service dialog;
+
+ loading = false;
+ filter = null;
+
+ @or("model.length", "filter") showSearch;
_debouncedShow() {
Permalink.findAll(this.filter).then((result) => {
this.set("model", result);
this.set("loading", false);
});
- },
+ }
@observes("filter")
show() {
discourseDebounce(this, this._debouncedShow, INPUT_DELAY);
- },
+ }
- actions: {
- recordAdded(arg) {
- this.model.unshiftObject(arg);
- },
+ @action
+ recordAdded(arg) {
+ this.model.unshiftObject(arg);
+ }
- copyUrl(pl) {
- let linkElement = document.querySelector(`#admin-permalink-${pl.id}`);
- clipboardCopy(linkElement.textContent);
- },
+ @action
+ copyUrl(pl) {
+ let linkElement = document.querySelector(`#admin-permalink-${pl.id}`);
+ clipboardCopy(linkElement.textContent);
+ }
- destroy(record) {
- return this.dialog.yesNoConfirm({
- message: I18n.t("admin.permalink.delete_confirm"),
- didConfirm: () => {
- return record.destroy().then(
- (deleted) => {
- if (deleted) {
- this.model.removeObject(record);
- } else {
- this.dialog.alert(I18n.t("generic_error"));
- }
- },
- function () {
+ @action
+ destroyRecord(record) {
+ return this.dialog.yesNoConfirm({
+ message: I18n.t("admin.permalink.delete_confirm"),
+ didConfirm: () => {
+ return record.destroy().then(
+ (deleted) => {
+ if (deleted) {
+ this.model.removeObject(record);
+ } else {
this.dialog.alert(I18n.t("generic_error"));
}
- );
- },
- });
- },
- },
-});
+ },
+ function () {
+ this.dialog.alert(I18n.t("generic_error"));
+ }
+ );
+ },
+ });
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-plugins.js b/app/assets/javascripts/admin/addon/controllers/admin-plugins.js
index 72d9231f01c..0222b6ec17c 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-plugins.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-plugins.js
@@ -1,18 +1,18 @@
-import Controller from "@ember/controller";
import { inject as service } from "@ember/service";
+import Controller from "@ember/controller";
-export default Controller.extend({
- router: service(),
+export default class AdminPluginsController extends Controller {
+ @service router;
get adminRoutes() {
return this.allAdminRoutes.filter((r) => this.routeExists(r.full_location));
- },
+ }
get brokenAdminRoutes() {
return this.allAdminRoutes.filter(
(r) => !this.routeExists(r.full_location)
);
- },
+ }
get allAdminRoutes() {
return this.model
@@ -21,7 +21,7 @@ export default Controller.extend({
return p.admin_route;
})
.filter(Boolean);
- },
+ }
routeExists(routeName) {
try {
@@ -30,5 +30,5 @@ export default Controller.extend({
} catch (e) {
return false;
}
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-reports-show.js b/app/assets/javascripts/admin/addon/controllers/admin-reports-show.js
index 5f19399edf3..11057b29e6a 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-reports-show.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-reports-show.js
@@ -1,12 +1,12 @@
import Controller from "@ember/controller";
import discourseComputed from "discourse-common/utils/decorators";
-export default Controller.extend({
- queryParams: ["start_date", "end_date", "filters", "chart_grouping", "mode"],
- start_date: null,
- end_date: null,
- filters: null,
- chart_grouping: null,
+export default class AdminReportsShowController extends Controller {
+ queryParams = ["start_date", "end_date", "filters", "chart_grouping", "mode"];
+ start_date = null;
+ end_date = null;
+ filters = null;
+ chart_grouping = null;
@discourseComputed("model.type")
reportOptions(type) {
@@ -19,5 +19,5 @@ export default Controller.extend({
options.chartGrouping = this.chart_grouping;
return options;
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-search-logs-index.js b/app/assets/javascripts/admin/addon/controllers/admin-search-logs-index.js
index bf110796f25..57b4be3ca0c 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-search-logs-index.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-search-logs-index.js
@@ -2,24 +2,19 @@ import Controller from "@ember/controller";
import I18n from "I18n";
export const DEFAULT_PERIOD = "yearly";
-export default Controller.extend({
- loading: false,
- period: DEFAULT_PERIOD,
- searchType: "all",
-
- init() {
- this._super(...arguments);
-
- this.searchTypeOptions = [
- {
- id: "all",
- name: I18n.t("admin.logs.search_logs.types.all_search_types"),
- },
- { id: "header", name: I18n.t("admin.logs.search_logs.types.header") },
- {
- id: "full_page",
- name: I18n.t("admin.logs.search_logs.types.full_page"),
- },
- ];
- },
-});
+export default class AdminSearchLogsIndexController extends Controller {
+ loading = false;
+ period = DEFAULT_PERIOD;
+ searchType = "all";
+ searchTypeOptions = [
+ {
+ id: "all",
+ name: I18n.t("admin.logs.search_logs.types.all_search_types"),
+ },
+ { id: "header", name: I18n.t("admin.logs.search_logs.types.header") },
+ {
+ id: "full_page",
+ name: I18n.t("admin.logs.search_logs.types.full_page"),
+ },
+ ];
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-search-logs-term.js b/app/assets/javascripts/admin/addon/controllers/admin-search-logs-term.js
index 2d4f22211b6..f4732ebb599 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-search-logs-term.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-search-logs-term.js
@@ -2,29 +2,24 @@ import Controller from "@ember/controller";
import { DEFAULT_PERIOD } from "admin/controllers/admin-search-logs-index";
import I18n from "I18n";
-export default Controller.extend({
- loading: false,
- term: null,
- period: DEFAULT_PERIOD,
- searchType: "all",
-
- init() {
- this._super(...arguments);
-
- this.searchTypeOptions = [
- {
- id: "all",
- name: I18n.t("admin.logs.search_logs.types.all_search_types"),
- },
- { id: "header", name: I18n.t("admin.logs.search_logs.types.header") },
- {
- id: "full_page",
- name: I18n.t("admin.logs.search_logs.types.full_page"),
- },
- {
- id: "click_through_only",
- name: I18n.t("admin.logs.search_logs.types.click_through_only"),
- },
- ];
- },
-});
+export default class AdminSearchLogsTermController extends Controller {
+ loading = false;
+ term = null;
+ period = DEFAULT_PERIOD;
+ searchType = "all";
+ searchTypeOptions = [
+ {
+ id: "all",
+ name: I18n.t("admin.logs.search_logs.types.all_search_types"),
+ },
+ { id: "header", name: I18n.t("admin.logs.search_logs.types.header") },
+ {
+ id: "full_page",
+ name: I18n.t("admin.logs.search_logs.types.full_page"),
+ },
+ {
+ id: "click_through_only",
+ name: I18n.t("admin.logs.search_logs.types.click_through_only"),
+ },
+ ];
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-site-settings-category.js b/app/assets/javascripts/admin/addon/controllers/admin-site-settings-category.js
index 2727c56010e..50202e00f32 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-site-settings-category.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-site-settings-category.js
@@ -1,17 +1,18 @@
import Controller, { inject as controller } from "@ember/controller";
import discourseComputed from "discourse-common/utils/decorators";
-export default Controller.extend({
- adminSiteSettings: controller(),
- categoryNameKey: null,
+export default class AdminSiteSettingsCategoryController extends Controller {
+ @controller adminSiteSettings;
+
+ categoryNameKey = null;
@discourseComputed("adminSiteSettings.visibleSiteSettings", "categoryNameKey")
category(categories, nameKey) {
return (categories || []).findBy("nameKey", nameKey);
- },
+ }
@discourseComputed("category")
filteredContent(category) {
return category ? category.siteSettings : [];
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-site-settings.js b/app/assets/javascripts/admin/addon/controllers/admin-site-settings.js
index 1e61c2c85a4..d3eb8658f64 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-site-settings.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-site-settings.js
@@ -1,16 +1,19 @@
+import { alias } from "@ember/object/computed";
import Controller from "@ember/controller";
import I18n from "I18n";
import { INPUT_DELAY } from "discourse-common/config/environment";
-import { alias } from "@ember/object/computed";
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";
-export default Controller.extend({
- filter: null,
- allSiteSettings: alias("model"),
- visibleSiteSettings: null,
- onlyOverridden: false,
+export default class AdminSiteSettingsController extends Controller {
+ filter = null;
+
+ @alias("model") allSiteSettings;
+
+ visibleSiteSettings = null;
+ onlyOverridden = false;
filterContentNow(category) {
// If we have no content, don't bother filtering anything
@@ -109,12 +112,12 @@ export default Controller.extend({
"adminSiteSettingsCategory",
category || "all_results"
);
- },
+ }
@observes("filter", "onlyOverridden", "model")
optsChanged() {
this.filterContent();
- },
+ }
@debounce(INPUT_DELAY)
filterContent() {
@@ -123,12 +126,12 @@ export default Controller.extend({
} else {
this.filterContentNow(this.categoryNameKey);
}
- },
+ }
@action
clearFilter() {
this.setProperties({ filter: "", onlyOverridden: false });
- },
+ }
@action
toggleMenu() {
@@ -136,5 +139,5 @@ export default Controller.extend({
["mobile-closed", "mobile-open"].forEach((state) => {
adminDetail.classList.toggle(state);
});
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-site-text-index.js b/app/assets/javascripts/admin/addon/controllers/admin-site-text-index.js
index 1ec7abbbea6..962944145c0 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-site-text-index.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-site-text-index.js
@@ -1,23 +1,23 @@
+import { action } from "@ember/object";
import Controller from "@ember/controller";
import discourseComputed from "discourse-common/utils/decorators";
import discourseDebounce from "discourse-common/lib/debounce";
let lastSearch;
-export default Controller.extend({
- searching: false,
- siteTexts: null,
- preferred: false,
- queryParams: ["q", "overridden", "locale"],
- locale: null,
-
- q: null,
- overridden: false,
+export default class AdminSiteTextIndexController extends Controller {
+ searching = false;
+ siteTexts = null;
+ preferred = false;
+ queryParams = ["q", "overridden", "locale"];
+ locale = null;
+ q = null;
+ overridden = false;
init() {
- this._super(...arguments);
+ super.init(...arguments);
this.set("locale", this.siteSettings.default_locale);
- },
+ }
_performSearch() {
this.store
@@ -26,12 +26,12 @@ export default Controller.extend({
this.set("siteTexts", results);
})
.finally(() => this.set("searching", false));
- },
+ }
@discourseComputed()
availableLocales() {
return JSON.parse(this.siteSettings.available_locales);
- },
+ }
@discourseComputed("locale")
fallbackLocaleFullName() {
@@ -40,39 +40,41 @@ export default Controller.extend({
return l.value === this.siteTexts.extras.fallback_locale;
}).name;
}
- },
+ }
- actions: {
- edit(siteText) {
- this.transitionToRoute("adminSiteText.edit", siteText.get("id"), {
- queryParams: {
- locale: this.locale,
- },
- });
- },
+ @action
+ edit(siteText) {
+ this.transitionToRoute("adminSiteText.edit", siteText.get("id"), {
+ queryParams: {
+ locale: this.locale,
+ },
+ });
+ }
- toggleOverridden() {
- this.toggleProperty("overridden");
+ @action
+ 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);
discourseDebounce(this, this._performSearch, 400);
- },
+ lastSearch = q;
+ }
+ }
- search() {
- const q = this.q;
- if (q !== lastSearch) {
- this.set("searching", true);
- discourseDebounce(this, this._performSearch, 400);
- lastSearch = q;
- }
- },
+ @action
+ updateLocale(value) {
+ this.setProperties({
+ searching: true,
+ locale: value,
+ });
- updateLocale(value) {
- this.setProperties({
- searching: true,
- locale: value,
- });
-
- discourseDebounce(this, this._performSearch, 400);
- },
- },
-});
+ discourseDebounce(this, this._performSearch, 400);
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-user-badges.js b/app/assets/javascripts/admin/addon/controllers/admin-user-badges.js
index b36a22af0ce..dc0ea3ba4f5 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-user-badges.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-user-badges.js
@@ -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 Controller, { inject as controller } from "@ember/controller";
import GrantBadgeController from "discourse/mixins/grant-badge-controller";
import I18n from "I18n";
import discourseComputed from "discourse-common/utils/decorators";
import { next } from "@ember/runloop";
import { popupAjaxError } from "discourse/lib/ajax-error";
-import { inject as service } from "@ember/service";
-export default Controller.extend(GrantBadgeController, {
- adminUser: controller(),
- dialog: service(),
- user: alias("adminUser.model"),
- userBadges: alias("model"),
- allBadges: alias("badges"),
- sortedBadges: sort("model", "badgeSortOrder"),
+export default class AdminUserBadgesController extends Controller.extend(
+ GrantBadgeController
+) {
+ @service dialog;
+ @controller adminUser;
- init() {
- this._super(...arguments);
+ @alias("adminUser.model") user;
+ @alias("model") userBadges;
+ @alias("badges") allBadges;
+ @sort("model", "badgeSortOrder") sortedBadges;
- this.badgeSortOrder = ["granted_at:desc"];
- },
+ badgeSortOrder = ["granted_at:desc"];
@discourseComputed("model", "model.[]", "model.expandedBadges.[]")
groupedBadges() {
@@ -59,46 +59,47 @@ export default Controller.extend(GrantBadgeController, {
});
return expanded.sortBy("granted_at").reverse();
- },
+ }
- actions: {
- expandGroup(userBadge) {
- const model = this.model;
- model.set("expandedBadges", model.get("expandedBadges") || []);
- model.get("expandedBadges").pushObject(userBadge.badge.id);
- },
+ @action
+ expandGroup(userBadge) {
+ const model = this.model;
+ model.set("expandedBadges", model.get("expandedBadges") || []);
+ model.get("expandedBadges").pushObject(userBadge.badge.id);
+ }
- grantBadge() {
- this.grantBadge(
- this.selectedBadgeId,
- this.get("user.username"),
- this.badgeReason
- ).then(
- () => {
- this.set("badgeReason", "");
- next(() => {
- // Update the selected badge ID after the combobox has re-rendered.
- const newSelectedBadge = this.grantableBadges[0];
- if (newSelectedBadge) {
- this.set("selectedBadgeId", newSelectedBadge.get("id"));
- }
- });
- },
- function (error) {
- popupAjaxError(error);
- }
- );
- },
+ @action
+ grantBadge() {
+ this.grantBadge(
+ this.selectedBadgeId,
+ this.get("user.username"),
+ this.badgeReason
+ ).then(
+ () => {
+ this.set("badgeReason", "");
+ next(() => {
+ // Update the selected badge ID after the combobox has re-rendered.
+ const newSelectedBadge = this.grantableBadges[0];
+ if (newSelectedBadge) {
+ this.set("selectedBadgeId", newSelectedBadge.get("id"));
+ }
+ });
+ },
+ function (error) {
+ popupAjaxError(error);
+ }
+ );
+ }
- revokeBadge(userBadge) {
- return this.dialog.yesNoConfirm({
- message: I18n.t("admin.badges.revoke_confirm"),
- didConfirm: () => {
- return userBadge.revoke().then(() => {
- this.model.removeObject(userBadge);
- });
- },
- });
- },
- },
-});
+ @action
+ revokeBadge(userBadge) {
+ return this.dialog.yesNoConfirm({
+ message: I18n.t("admin.badges.revoke_confirm"),
+ didConfirm: () => {
+ return userBadge.revoke().then(() => {
+ this.model.removeObject(userBadge);
+ });
+ },
+ });
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-user-fields.js b/app/assets/javascripts/admin/addon/controllers/admin-user-fields.js
index 619c1cf6293..255b6c12817 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-user-fields.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-user-fields.js
@@ -1,73 +1,74 @@
+import { action } from "@ember/object";
+import { inject as service } from "@ember/service";
import { gte, sort } from "@ember/object/computed";
import Controller from "@ember/controller";
import I18n from "I18n";
import { popupAjaxError } from "discourse/lib/ajax-error";
-import { inject as service } from "@ember/service";
const MAX_FIELDS = 30;
-export default Controller.extend({
- dialog: service(),
- fieldTypes: null,
- createDisabled: gte("model.length", MAX_FIELDS),
- sortedFields: sort("model", "fieldSortOrder"),
+export default class AdminUserFieldsController extends Controller {
+ @service dialog;
- init() {
- this._super(...arguments);
+ fieldTypes = null;
- this.fieldSortOrder = ["position"];
- },
+ @gte("model.length", MAX_FIELDS) createDisabled;
+ @sort("model", "fieldSortOrder") sortedFields;
- actions: {
- createField() {
- const f = this.store.createRecord("user-field", {
- field_type: "text",
- position: MAX_FIELDS,
+ fieldSortOrder = ["position"];
+
+ @action
+ createField() {
+ 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);
- },
-
- 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);
- }
- },
- },
-});
+ } else {
+ model.removeObject(f);
+ }
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-user-index.js b/app/assets/javascripts/admin/addon/controllers/admin-user-index.js
index 25403010f1a..b4bfbac8fa9 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-user-index.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-user-index.js
@@ -1,5 +1,7 @@
-import DiscourseURL, { userPath } from "discourse/lib/url";
+import { action } from "@ember/object";
+import { inject as service } from "@ember/service";
import { and, notEmpty } from "@ember/object/computed";
+import DiscourseURL, { userPath } from "discourse/lib/url";
import { fmt, propertyNotEqual, setting } from "discourse/lib/computed";
import AdminUser from "admin/models/admin-user";
import CanCheckEmails from "discourse/mixins/can-check-emails";
@@ -10,37 +12,37 @@ import discourseComputed from "discourse-common/utils/decorators";
import getURL from "discourse-common/lib/get-url";
import { htmlSafe } from "@ember/template";
import { extractError, popupAjaxError } from "discourse/lib/ajax-error";
-import { inject as service } from "@ember/service";
import showModal from "discourse/lib/show-modal";
-export default Controller.extend(CanCheckEmails, {
- router: service(),
- dialog: service(),
- adminTools: service(),
- originalPrimaryGroupId: null,
- customGroupIdsBuffer: null,
- availableGroups: null,
- userTitleValue: null,
- ssoExternalEmail: null,
- ssoLastPayload: null,
+export default class AdminUserIndexController extends Controller.extend(
+ CanCheckEmails
+) {
+ @service router;
+ @service dialog;
+ @service adminTools;
- showBadges: setting("enable_badges"),
- hasLockedTrustLevel: notEmpty("model.manual_locked_trust_level"),
+ originalPrimaryGroupId = null;
+ customGroupIdsBuffer = null;
+ availableGroups = null;
+ userTitleValue = null;
+ ssoExternalEmail = null;
+ ssoLastPayload = null;
- primaryGroupDirty: propertyNotEqual(
- "originalPrimaryGroupId",
- "model.primary_group_id"
- ),
+ @setting("enable_badges") showBadges;
+ @notEmpty("model.manual_locked_trust_level") hasLockedTrustLevel;
- canDisableSecondFactor: and(
- "model.second_factor_enabled",
- "model.can_disable_second_factor"
- ),
+ @propertyNotEqual("originalPrimaryGroupId", "model.primary_group_id")
+ primaryGroupDirty;
+
+ @and("model.second_factor_enabled", "model.can_disable_second_factor")
+ canDisableSecondFactor;
+
+ @fmt("model.username_lower", userPath("%@/preferences")) preferencesPath;
@discourseComputed("model.customGroups")
customGroupIds(customGroups) {
return customGroups.mapBy("id");
- },
+ }
@discourseComputed("customGroupIdsBuffer", "customGroupIds")
customGroupsDirty(buffer, original) {
@@ -51,7 +53,7 @@ export default Controller.extend(CanCheckEmails, {
return buffer.length === original.length
? buffer.any((id) => !original.includes(id))
: true;
- },
+ }
@discourseComputed("model.automaticGroups")
automaticGroups(automaticGroups) {
@@ -61,26 +63,24 @@ export default Controller.extend(CanCheckEmails, {
return `${name}`;
})
.join(", ");
- },
+ }
@discourseComputed("model.associated_accounts")
associatedAccountsLoaded(associatedAccounts) {
return typeof associatedAccounts !== "undefined";
- },
+ }
@discourseComputed("model.associated_accounts")
associatedAccounts(associatedAccounts) {
return associatedAccounts
.map((provider) => `${provider.name} (${provider.description})`)
.join(", ");
- },
+ }
@discourseComputed("model.user_fields.[]")
userFields(userFields) {
return this.site.collectUserFields(userFields);
- },
-
- preferencesPath: fmt("model.username_lower", userPath("%@/preferences")),
+ }
@discourseComputed(
"model.can_delete_all_posts",
@@ -104,7 +104,7 @@ export default Controller.extend(CanCheckEmails, {
count: this.siteSettings.delete_user_max_post_age,
});
}
- },
+ }
@discourseComputed("model.canBeDeleted", "model.staff")
deleteExplanation(canBeDeleted, staff) {
@@ -119,18 +119,18 @@ export default Controller.extend(CanCheckEmails, {
count: this.siteSettings.delete_user_max_post_age,
});
}
- },
+ }
@discourseComputed("model.username")
postEditsByEditorFilter(username) {
return { editor: username };
- },
+ }
groupAdded(added) {
this.model
.groupAdded(added)
.catch(() => this.dialog.alert(I18n.t("generic_error")));
- },
+ }
groupRemoved(groupId) {
this.model
@@ -141,482 +141,533 @@ export default Controller.extend(CanCheckEmails, {
}
})
.catch(() => this.dialog.alert(I18n.t("generic_error")));
- },
+ }
@discourseComputed("ssoLastPayload")
ssoPayload(lastPayload) {
return lastPayload.split("&");
- },
+ }
- actions: {
- impersonate() {
- return this.model
- .impersonate()
- .then(() => DiscourseURL.redirectTo("/"))
- .catch((e) => {
- if (e.status === 404) {
- this.dialog.alert(I18n.t("admin.impersonate.not_found"));
+ @action
+ impersonate() {
+ return this.model
+ .impersonate()
+ .then(() => DiscourseURL.redirectTo("/"))
+ .catch((e) => {
+ if (e.status === 404) {
+ this.dialog.alert(I18n.t("admin.impersonate.not_found"));
+ } else {
+ this.dialog.alert(I18n.t("admin.impersonate.invalid"));
+ }
+ });
+ }
+
+ @action
+ logOut() {
+ return this.model
+ .logOut()
+ .then(() => this.dialog.alert(I18n.t("admin.user.logged_out")));
+ }
+
+ @action
+ resetBounceScore() {
+ return this.model.resetBounceScore();
+ }
+
+ @action
+ approve() {
+ return this.model.approve(this.currentUser);
+ }
+
+ @action
+ _formatError(event) {
+ return `http: ${event.status} - ${event.body}`;
+ }
+
+ @action
+ deactivate() {
+ return this.model
+ .deactivate()
+ .then(() =>
+ this.model.setProperties({ active: false, can_activate: true })
+ )
+ .catch((e) => {
+ const error = I18n.t("admin.user.deactivate_failed", {
+ error: this._formatError(e),
+ });
+ this.dialog.alert(error);
+ });
+ }
+
+ @action
+ sendActivationEmail() {
+ return this.model
+ .sendActivationEmail()
+ .then(() => this.dialog.alert(I18n.t("admin.user.activation_email_sent")))
+ .catch(popupAjaxError);
+ }
+
+ @action
+ activate() {
+ return this.model
+ .activate()
+ .then(() =>
+ this.model.setProperties({
+ active: true,
+ can_deactivate: !this.model.staff,
+ })
+ )
+ .catch((e) => {
+ const error = I18n.t("admin.user.activate_failed", {
+ error: this._formatError(e),
+ });
+ this.dialog.alert(error);
+ });
+ }
+
+ @action
+ revokeAdmin() {
+ return this.model.revokeAdmin();
+ }
+
+ @action
+ grantAdmin() {
+ return this.model
+ .grantAdmin()
+ .then((result) => {
+ if (result.email_confirmation_required) {
+ this.dialog.alert(I18n.t("admin.user.grant_admin_confirm"));
+ }
+ })
+ .catch((error) => {
+ const nonce = error.jqXHR?.responseJSON.second_factor_challenge_nonce;
+ if (nonce) {
+ this.router.transitionTo("second-factor-auth", {
+ queryParams: { nonce },
+ });
+ } else {
+ const htmlMessage = error.jqXHR?.responseJSON.html_message;
+ if (htmlMessage) {
+ this.dialog.alert({
+ message: htmlSafe(error.jqXHR?.responseJSON.error),
+ });
} else {
- this.dialog.alert(I18n.t("admin.impersonate.invalid"));
+ popupAjaxError(error);
}
- });
- },
- logOut() {
- return this.model
- .logOut()
- .then(() => this.dialog.alert(I18n.t("admin.user.logged_out")));
- },
- resetBounceScore() {
- return this.model.resetBounceScore();
- },
- approve() {
- return this.model.approve(this.currentUser);
- },
+ }
+ });
+ }
- _formatError(event) {
- return `http: ${event.status} - ${event.body}`;
- },
+ @action
+ revokeModeration() {
+ return this.model.revokeModeration();
+ }
- deactivate() {
- return this.model
- .deactivate()
- .then(() =>
- this.model.setProperties({ active: false, can_activate: true })
- )
- .catch((e) => {
- const error = I18n.t("admin.user.deactivate_failed", {
+ @action
+ grantModeration() {
+ return this.model.grantModeration();
+ }
+
+ @action
+ saveTrustLevel() {
+ return this.model
+ .saveTrustLevel()
+ .then(() => window.location.reload())
+ .catch((e) => {
+ let error;
+ if (e.jqXHR.responseJSON && e.jqXHR.responseJSON.errors) {
+ error = e.jqXHR.responseJSON.errors[0];
+ }
+ error =
+ error ||
+ I18n.t("admin.user.trust_level_change_failed", {
error: this._formatError(e),
});
- this.dialog.alert(error);
- });
- },
- sendActivationEmail() {
- return this.model
- .sendActivationEmail()
- .then(() =>
- this.dialog.alert(I18n.t("admin.user.activation_email_sent"))
- )
- .catch(popupAjaxError);
- },
- activate() {
- return this.model
- .activate()
- .then(() =>
- this.model.setProperties({
- active: true,
- can_deactivate: !this.model.staff,
- })
- )
- .catch((e) => {
- const error = I18n.t("admin.user.activate_failed", {
+ this.dialog.alert(error);
+ });
+ }
+
+ @action
+ restoreTrustLevel() {
+ return this.model.restoreTrustLevel();
+ }
+
+ @action
+ lockTrustLevel(locked) {
+ return this.model
+ .lockTrustLevel(locked)
+ .then(() => window.location.reload())
+ .catch((e) => {
+ let error;
+ if (e.jqXHR.responseJSON && e.jqXHR.responseJSON.errors) {
+ error = e.jqXHR.responseJSON.errors[0];
+ }
+ error =
+ error ||
+ I18n.t("admin.user.trust_level_change_failed", {
error: this._formatError(e),
});
- this.dialog.alert(error);
- });
- },
- revokeAdmin() {
- return this.model.revokeAdmin();
- },
- grantAdmin() {
- return this.model
- .grantAdmin()
- .then((result) => {
- if (result.email_confirmation_required) {
- this.dialog.alert(I18n.t("admin.user.grant_admin_confirm"));
+ this.dialog.alert(error);
+ });
+ }
+
+ @action
+ unsilence() {
+ return this.model.unsilence();
+ }
+
+ @action
+ silence() {
+ return this.model.silence();
+ }
+
+ @action
+ anonymize() {
+ const user = this.model;
+
+ const performAnonymize = () => {
+ this.model
+ .anonymize()
+ .then((data) => {
+ if (data.success) {
+ if (data.username) {
+ document.location = getURL(
+ `/admin/users/${user.get("id")}/${data.username}`
+ );
+ } else {
+ document.location = getURL("/admin/users/list/active");
+ }
+ } else {
+ this.dialog.alert(I18n.t("admin.user.anonymize_failed"));
+ if (data.user) {
+ user.setProperties(data.user);
+ }
}
})
- .catch((error) => {
- const nonce = error.jqXHR?.responseJSON.second_factor_challenge_nonce;
- if (nonce) {
- this.router.transitionTo("second-factor-auth", {
- queryParams: { nonce },
- });
- } else {
- const htmlMessage = error.jqXHR?.responseJSON.html_message;
- if (htmlMessage) {
- this.dialog.alert({
- message: htmlSafe(error.jqXHR?.responseJSON.error),
- });
- } else {
- popupAjaxError(error);
- }
- }
- });
- },
- revokeModeration() {
- return this.model.revokeModeration();
- },
- grantModeration() {
- return this.model.grantModeration();
- },
- saveTrustLevel() {
- return this.model
- .saveTrustLevel()
- .then(() => window.location.reload())
- .catch((e) => {
- let error;
- if (e.jqXHR.responseJSON && e.jqXHR.responseJSON.errors) {
- error = e.jqXHR.responseJSON.errors[0];
- }
- error =
- error ||
- I18n.t("admin.user.trust_level_change_failed", {
- error: this._formatError(e),
- });
- this.dialog.alert(error);
- });
- },
- restoreTrustLevel() {
- return this.model.restoreTrustLevel();
- },
- lockTrustLevel(locked) {
- return this.model
- .lockTrustLevel(locked)
- .then(() => window.location.reload())
- .catch((e) => {
- let error;
- if (e.jqXHR.responseJSON && e.jqXHR.responseJSON.errors) {
- error = e.jqXHR.responseJSON.errors[0];
- }
- error =
- error ||
- I18n.t("admin.user.trust_level_change_failed", {
- error: this._formatError(e),
- });
- this.dialog.alert(error);
- });
- },
- unsilence() {
- return this.model.unsilence();
- },
- silence() {
- return this.model.silence();
- },
+ .catch(() => this.dialog.alert(I18n.t("admin.user.anonymize_failed")));
+ };
- anonymize() {
- const user = this.model;
-
- const performAnonymize = () => {
- this.model
- .anonymize()
- .then((data) => {
- if (data.success) {
- if (data.username) {
- document.location = getURL(
- `/admin/users/${user.get("id")}/${data.username}`
- );
- } else {
- document.location = getURL("/admin/users/list/active");
- }
- } else {
- this.dialog.alert(I18n.t("admin.user.anonymize_failed"));
- if (data.user) {
- user.setProperties(data.user);
- }
- }
- })
- .catch(() =>
- this.dialog.alert(I18n.t("admin.user.anonymize_failed"))
- );
- };
-
- this.dialog.alert({
- message: I18n.t("admin.user.anonymize_confirm"),
- class: "delete-user-modal",
- buttons: [
- {
- icon: "exclamation-triangle",
- label: I18n.t("admin.user.anonymize_yes"),
- class: "btn-danger",
- action: () => performAnonymize(),
- },
- {
- label: I18n.t("composer.cancel"),
- },
- ],
- });
- },
-
- disableSecondFactor() {
- return this.model.disableSecondFactor();
- },
-
- clearPenaltyHistory() {
- const user = this.model;
- const path = `/admin/users/${user.get("id")}/penalty_history`;
-
- return ajax(path, { type: "DELETE" })
- .then(() => user.set("tl3_requirements.penalty_counts.total", 0))
- .catch(popupAjaxError);
- },
-
- destroy() {
- const postCount = this.get("model.post_count");
- const maxPostCount = this.siteSettings.delete_all_posts_max;
- const location = document.location.pathname;
-
- const performDestroy = (block) => {
- this.dialog.notice(I18n.t("admin.user.deleting_user"));
- let formData = { context: location };
- if (block) {
- formData["block_email"] = true;
- formData["block_urls"] = true;
- formData["block_ip"] = true;
- }
- if (postCount <= maxPostCount) {
- formData["delete_posts"] = true;
- }
- this.model
- .destroy(formData)
- .then((data) => {
- if (data.deleted) {
- if (/^\/admin\/users\/list\//.test(location)) {
- document.location = location;
- } else {
- document.location = getURL("/admin/users/list/active");
- }
- } else {
- this.dialog.alert(I18n.t("admin.user.delete_failed"));
- }
- })
- .catch(() => {
- this.dialog.alert(I18n.t("admin.user.delete_failed"));
- });
- };
-
- this.dialog.alert({
- title: I18n.t("admin.user.delete_confirm_title"),
- message: I18n.t("admin.user.delete_confirm"),
- class: "delete-user-modal",
- buttons: [
- {
- label: I18n.t("admin.user.delete_dont_block"),
- class: "btn-primary",
- action: () => {
- return performDestroy(false);
- },
- },
- {
- icon: "exclamation-triangle",
- label: I18n.t("admin.user.delete_and_block"),
- class: "btn-danger",
- action: () => {
- return performDestroy(true);
- },
- },
- {
- label: I18n.t("composer.cancel"),
- },
- ],
- });
- },
-
- promptTargetUser() {
- showModal("admin-merge-users-prompt", {
- admin: true,
- model: this.model,
- });
- },
-
- showMergeConfirmation(targetUsername) {
- showModal("admin-merge-users-confirmation", {
- admin: true,
- model: {
- username: this.model.username,
- targetUsername,
+ this.dialog.alert({
+ message: I18n.t("admin.user.anonymize_confirm"),
+ class: "delete-user-modal",
+ buttons: [
+ {
+ icon: "exclamation-triangle",
+ label: I18n.t("admin.user.anonymize_yes"),
+ class: "btn-danger",
+ action: () => performAnonymize(),
},
- });
- },
+ {
+ label: I18n.t("composer.cancel"),
+ },
+ ],
+ });
+ }
- merge(targetUsername) {
- const user = this.model;
- const location = document.location.pathname;
+ @action
+ disableSecondFactor() {
+ return this.model.disableSecondFactor();
+ }
+ @action
+ clearPenaltyHistory() {
+ const user = this.model;
+ const path = `/admin/users/${user.get("id")}/penalty_history`;
+
+ return ajax(path, { type: "DELETE" })
+ .then(() => user.set("tl3_requirements.penalty_counts.total", 0))
+ .catch(popupAjaxError);
+ }
+
+ @action
+ destroyUser() {
+ const postCount = this.get("model.post_count");
+ const maxPostCount = this.siteSettings.delete_all_posts_max;
+ const location = document.location.pathname;
+
+ const performDestroy = (block) => {
+ this.dialog.notice(I18n.t("admin.user.deleting_user"));
let formData = { context: location };
-
- if (targetUsername) {
- formData["target_username"] = targetUsername;
+ if (block) {
+ formData["block_email"] = true;
+ formData["block_urls"] = true;
+ formData["block_ip"] = true;
+ }
+ if (postCount <= maxPostCount) {
+ formData["delete_posts"] = true;
}
-
this.model
- .merge(formData)
- .then((response) => {
- if (response.success) {
- showModal("admin-merge-users-progress", {
- admin: true,
- model: this.model,
- });
+ .destroy(formData)
+ .then((data) => {
+ if (data.deleted) {
+ if (/^\/admin\/users\/list\//.test(location)) {
+ document.location = location;
+ } else {
+ document.location = getURL("/admin/users/list/active");
+ }
} else {
- this.dialog.alert(I18n.t("admin.user.merge_failed"));
+ this.dialog.alert(I18n.t("admin.user.delete_failed"));
}
})
.catch(() => {
- AdminUser.find(user.id).then((u) => user.setProperties(u));
- this.dialog.alert(I18n.t("admin.user.merge_failed"));
+ this.dialog.alert(I18n.t("admin.user.delete_failed"));
});
- },
+ };
- viewActionLogs() {
- this.adminTools.showActionLogs(this, {
- target_user: this.get("model.username"),
- });
- },
- showSuspendModal() {
- this.adminTools.showSuspendModal(this.model);
- },
- unsuspend() {
- this.model.unsuspend().catch(popupAjaxError);
- },
- showSilenceModal() {
- this.adminTools.showSilenceModal(this.model);
- },
+ this.dialog.alert({
+ title: I18n.t("admin.user.delete_confirm_title"),
+ message: I18n.t("admin.user.delete_confirm"),
+ class: "delete-user-modal",
+ buttons: [
+ {
+ label: I18n.t("admin.user.delete_dont_block"),
+ class: "btn-primary",
+ action: () => {
+ return performDestroy(false);
+ },
+ },
+ {
+ icon: "exclamation-triangle",
+ label: I18n.t("admin.user.delete_and_block"),
+ class: "btn-danger",
+ action: () => {
+ return performDestroy(true);
+ },
+ },
+ {
+ label: I18n.t("composer.cancel"),
+ },
+ ],
+ });
+ }
- saveUsername(newUsername) {
- const oldUsername = this.get("model.username");
- this.set("model.username", newUsername);
+ @action
+ promptTargetUser() {
+ showModal("admin-merge-users-prompt", {
+ admin: true,
+ model: this.model,
+ });
+ }
- const path = `/users/${oldUsername.toLowerCase()}/preferences/username`;
+ @action
+ showMergeConfirmation(targetUsername) {
+ showModal("admin-merge-users-confirmation", {
+ admin: true,
+ model: {
+ username: this.model.username,
+ targetUsername,
+ },
+ });
+ }
- return ajax(path, { data: { new_username: newUsername }, type: "PUT" })
- .catch((e) => {
- this.set("model.username", oldUsername);
- popupAjaxError(e);
- })
- .finally(() => this.toggleProperty("editingUsername"));
- },
+ @action
+ merge(targetUsername) {
+ const user = this.model;
+ const location = document.location.pathname;
- saveName(newName) {
- const oldName = this.get("model.name");
- this.set("model.name", newName);
+ let formData = { context: location };
- const path = userPath(`${this.get("model.username").toLowerCase()}.json`);
+ if (targetUsername) {
+ formData["target_username"] = targetUsername;
+ }
- return ajax(path, { data: { name: newName }, type: "PUT" })
- .catch((e) => {
- this.set("model.name", oldName);
- popupAjaxError(e);
- })
- .finally(() => this.toggleProperty("editingName"));
- },
-
- saveTitle(newTitle) {
- const oldTitle = this.get("model.title");
- this.set("model.title", newTitle);
-
- const path = userPath(`${this.get("model.username").toLowerCase()}.json`);
-
- return ajax(path, { data: { title: newTitle }, type: "PUT" })
- .catch((e) => {
- this.set("model.title", oldTitle);
- popupAjaxError(e);
- })
- .finally(() => this.toggleProperty("editingTitle"));
- },
-
- saveCustomGroups() {
- const currentIds = this.customGroupIds;
- const bufferedIds = this.customGroupIdsBuffer;
- const availableGroups = this.availableGroups;
-
- bufferedIds
- .filter((id) => !currentIds.includes(id))
- .forEach((id) => this.groupAdded(availableGroups.findBy("id", id)));
-
- currentIds
- .filter((id) => !bufferedIds.includes(id))
- .forEach((id) => this.groupRemoved(id));
- },
-
- resetCustomGroups() {
- this.set("customGroupIdsBuffer", this.model.customGroups.mapBy("id"));
- },
-
- savePrimaryGroup() {
- const primaryGroupId = this.get("model.primary_group_id");
- const path = `/admin/users/${this.get("model.id")}/primary_group`;
-
- return ajax(path, {
- type: "PUT",
- data: { primary_group_id: primaryGroupId },
- })
- .then(() => this.set("originalPrimaryGroupId", primaryGroupId))
- .catch(() => this.dialog.alert(I18n.t("generic_error")));
- },
-
- resetPrimaryGroup() {
- this.set("model.primary_group_id", this.originalPrimaryGroupId);
- },
-
- deleteSSORecord() {
- return this.dialog.yesNoConfirm({
- message: I18n.t("admin.user.discourse_connect.confirm_delete"),
- didConfirm: () => this.model.deleteSSORecord(),
- });
- },
-
- checkSsoEmail() {
- return ajax(userPath(`${this.model.username_lower}/sso-email.json`), {
- data: { context: window.location.pathname },
- }).then((result) => {
- if (result) {
- this.set("ssoExternalEmail", result.email);
- }
- });
- },
-
- checkSsoPayload() {
- return ajax(userPath(`${this.model.username_lower}/sso-payload.json`), {
- data: { context: window.location.pathname },
- }).then((result) => {
- if (result) {
- this.set("ssoLastPayload", result.payload);
- }
- });
- },
-
- showDeletePostsConfirmation() {
- showModal("admin-delete-posts-confirmation", {
- admin: true,
- model: this.model,
- });
- },
-
- deleteAllPosts() {
- let deletedPosts = 0;
- let deletedPercentage = 0;
- const user = this.model;
-
- const performDelete = (progressModal) => {
- this.model
- .deleteAllPosts()
- .then(({ posts_deleted }) => {
- if (posts_deleted === 0) {
- user.set("post_count", 0);
- progressModal.send("closeModal");
- } else {
- deletedPosts += posts_deleted;
- deletedPercentage = Math.floor(
- (deletedPosts * 100) / user.get("post_count")
- );
- progressModal.setProperties({
- deletedPercentage,
- });
- performDelete(progressModal);
- }
- })
- .catch((e) => {
- progressModal.send("closeModal");
- let error;
- AdminUser.find(user.get("id")).then((u) => user.setProperties(u));
- error = extractError(e) || I18n.t("admin.user.delete_posts_failed");
- this.dialog.alert(error);
+ this.model
+ .merge(formData)
+ .then((response) => {
+ if (response.success) {
+ showModal("admin-merge-users-progress", {
+ admin: true,
+ model: this.model,
});
- };
-
- const progressModal = showModal("admin-delete-user-posts-progress", {
- admin: true,
+ } else {
+ this.dialog.alert(I18n.t("admin.user.merge_failed"));
+ }
+ })
+ .catch(() => {
+ AdminUser.find(user.id).then((u) => user.setProperties(u));
+ this.dialog.alert(I18n.t("admin.user.merge_failed"));
});
- performDelete(progressModal);
- },
- },
-});
+ }
+
+ @action
+ viewActionLogs() {
+ this.adminTools.showActionLogs(this, {
+ target_user: this.get("model.username"),
+ });
+ }
+
+ @action
+ showSuspendModal() {
+ this.adminTools.showSuspendModal(this.model);
+ }
+
+ @action
+ unsuspend() {
+ this.model.unsuspend().catch(popupAjaxError);
+ }
+
+ @action
+ showSilenceModal() {
+ this.adminTools.showSilenceModal(this.model);
+ }
+
+ @action
+ saveUsername(newUsername) {
+ const oldUsername = this.get("model.username");
+ this.set("model.username", newUsername);
+
+ const path = `/users/${oldUsername.toLowerCase()}/preferences/username`;
+
+ return ajax(path, { data: { new_username: newUsername }, type: "PUT" })
+ .catch((e) => {
+ this.set("model.username", oldUsername);
+ popupAjaxError(e);
+ })
+ .finally(() => this.toggleProperty("editingUsername"));
+ }
+
+ @action
+ saveName(newName) {
+ const oldName = this.get("model.name");
+ this.set("model.name", newName);
+
+ const path = userPath(`${this.get("model.username").toLowerCase()}.json`);
+
+ return ajax(path, { data: { name: newName }, type: "PUT" })
+ .catch((e) => {
+ this.set("model.name", oldName);
+ popupAjaxError(e);
+ })
+ .finally(() => this.toggleProperty("editingName"));
+ }
+
+ @action
+ saveTitle(newTitle) {
+ const oldTitle = this.get("model.title");
+ this.set("model.title", newTitle);
+
+ const path = userPath(`${this.get("model.username").toLowerCase()}.json`);
+
+ return ajax(path, { data: { title: newTitle }, type: "PUT" })
+ .catch((e) => {
+ this.set("model.title", oldTitle);
+ popupAjaxError(e);
+ })
+ .finally(() => this.toggleProperty("editingTitle"));
+ }
+
+ @action
+ saveCustomGroups() {
+ const currentIds = this.customGroupIds;
+ const bufferedIds = this.customGroupIdsBuffer;
+ const availableGroups = this.availableGroups;
+
+ bufferedIds
+ .filter((id) => !currentIds.includes(id))
+ .forEach((id) => this.groupAdded(availableGroups.findBy("id", id)));
+
+ currentIds
+ .filter((id) => !bufferedIds.includes(id))
+ .forEach((id) => this.groupRemoved(id));
+ }
+
+ @action
+ resetCustomGroups() {
+ this.set("customGroupIdsBuffer", this.model.customGroups.mapBy("id"));
+ }
+
+ @action
+ savePrimaryGroup() {
+ const primaryGroupId = this.get("model.primary_group_id");
+ const path = `/admin/users/${this.get("model.id")}/primary_group`;
+
+ return ajax(path, {
+ type: "PUT",
+ data: { primary_group_id: primaryGroupId },
+ })
+ .then(() => this.set("originalPrimaryGroupId", primaryGroupId))
+ .catch(() => this.dialog.alert(I18n.t("generic_error")));
+ }
+
+ @action
+ resetPrimaryGroup() {
+ this.set("model.primary_group_id", this.originalPrimaryGroupId);
+ }
+
+ @action
+ deleteSSORecord() {
+ return this.dialog.yesNoConfirm({
+ message: I18n.t("admin.user.discourse_connect.confirm_delete"),
+ didConfirm: () => this.model.deleteSSORecord(),
+ });
+ }
+
+ @action
+ checkSsoEmail() {
+ return ajax(userPath(`${this.model.username_lower}/sso-email.json`), {
+ data: { context: window.location.pathname },
+ }).then((result) => {
+ if (result) {
+ this.set("ssoExternalEmail", result.email);
+ }
+ });
+ }
+
+ @action
+ checkSsoPayload() {
+ return ajax(userPath(`${this.model.username_lower}/sso-payload.json`), {
+ data: { context: window.location.pathname },
+ }).then((result) => {
+ if (result) {
+ this.set("ssoLastPayload", result.payload);
+ }
+ });
+ }
+
+ @action
+ showDeletePostsConfirmation() {
+ showModal("admin-delete-posts-confirmation", {
+ admin: true,
+ model: this.model,
+ });
+ }
+
+ @action
+ deleteAllPosts() {
+ let deletedPosts = 0;
+ let deletedPercentage = 0;
+ const user = this.model;
+
+ const performDelete = (progressModal) => {
+ this.model
+ .deleteAllPosts()
+ .then(({ posts_deleted }) => {
+ if (posts_deleted === 0) {
+ user.set("post_count", 0);
+ progressModal.send("closeModal");
+ } else {
+ deletedPosts += posts_deleted;
+ deletedPercentage = Math.floor(
+ (deletedPosts * 100) / user.get("post_count")
+ );
+ progressModal.setProperties({
+ deletedPercentage,
+ });
+ performDelete(progressModal);
+ }
+ })
+ .catch((e) => {
+ progressModal.send("closeModal");
+ let error;
+ AdminUser.find(user.get("id")).then((u) => user.setProperties(u));
+ error = extractError(e) || I18n.t("admin.user.delete_posts_failed");
+ this.dialog.alert(error);
+ });
+ };
+
+ const progressModal = showModal("admin-delete-user-posts-progress", {
+ admin: true,
+ });
+ performDelete(progressModal);
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-user.js b/app/assets/javascripts/admin/addon/controllers/admin-user.js
index cf6c4e3aa2e..9fc1e78e7f8 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-user.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-user.js
@@ -1,2 +1,2 @@
import Controller from "@ember/controller";
-export default Controller.extend();
+export default class AdminUserController extends Controller {}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-users-list-show.js b/app/assets/javascripts/admin/addon/controllers/admin-users-list-show.js
index 0976adec96a..7865e57c5d6 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-users-list-show.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-users-list-show.js
@@ -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 CanCheckEmails from "discourse/mixins/can-check-emails";
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 { i18n } from "discourse/lib/computed";
-export default Controller.extend(CanCheckEmails, {
- model: null,
- query: null,
- order: null,
- asc: null,
- showEmails: false,
- refreshing: false,
- listFilter: null,
- selectAll: false,
- searchHint: i18n("search_hint"),
+export default class AdminUsersListShowController extends Controller.extend(
+ CanCheckEmails
+) {
+ model = null;
+ query = null;
+ order = null;
+ asc = null;
+ showEmails = false;
+ refreshing = false;
+ listFilter = null;
+ selectAll = false;
- init() {
- this._super(...arguments);
+ @i18n("search_hint") searchHint;
- this._page = 1;
- this._results = [];
- this._canLoadMore = true;
- },
+ _page = 1;
+ _results = [];
+ _canLoadMore = true;
@discourseComputed("query")
title(query) {
return I18n.t("admin.users.titles." + query);
- },
+ }
@discourseComputed("showEmails")
columnCount(showEmails) {
@@ -44,19 +45,19 @@ export default Controller.extend(CanCheckEmails, {
}
return colCount;
- },
+ }
@observes("listFilter")
_filterUsers() {
discourseDebounce(this, this.resetFilters, INPUT_DELAY);
- },
+ }
resetFilters() {
this._page = 1;
this._results = [];
this._canLoadMore = true;
this._refreshUsers();
- },
+ }
_refreshUsers() {
if (!this._canLoadMore) {
@@ -84,17 +85,17 @@ export default Controller.extend(CanCheckEmails, {
.finally(() => {
this.set("refreshing", false);
});
- },
+ }
- actions: {
- loadMore() {
- this._page += 1;
- this._refreshUsers();
- },
+ @action
+ loadMore() {
+ this._page += 1;
+ this._refreshUsers();
+ }
- toggleEmailVisibility() {
- this.toggleProperty("showEmails");
- this.resetFilters();
- },
- },
-});
+ @action
+ toggleEmailVisibility() {
+ this.toggleProperty("showEmails");
+ this.resetFilters();
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-watched-words-action.js b/app/assets/javascripts/admin/addon/controllers/admin-watched-words-action.js
index a1b158a6774..9529d6bb7f3 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-watched-words-action.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-watched-words-action.js
@@ -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 I18n from "I18n";
import WatchedWord from "admin/models/watched-word";
import { ajax } from "discourse/lib/ajax";
import discourseComputed from "discourse-common/utils/decorators";
import { fmt } from "discourse/lib/computed";
-import { or } from "@ember/object/computed";
import { schedule } from "@ember/runloop";
import showModal from "discourse/lib/show-modal";
-import { inject as service } from "@ember/service";
-export default Controller.extend({
- adminWatchedWords: controller(),
- actionNameKey: null,
- dialog: service(),
- downloadLink: fmt(
- "actionNameKey",
- "/admin/customize/watched_words/action/%@/download"
- ),
- showWordsList: or("adminWatchedWords.showWords", "adminWatchedWords.filter"),
+export default class AdminWatchedWordsActionController extends Controller {
+ @service dialog;
+ @controller adminWatchedWords;
+
+ actionNameKey = null;
+
+ @fmt("actionNameKey", "/admin/customize/watched_words/action/%@/download")
+ downloadLink;
+
+ @or("adminWatchedWords.showWords", "adminWatchedWords.filter")
+ showWordsList;
findAction(actionName) {
return (this.adminWatchedWords.model || []).findBy("nameKey", actionName);
- },
+ }
@discourseComputed("actionNameKey", "adminWatchedWords.model")
currentAction(actionName) {
return this.findAction(actionName);
- },
+ }
@discourseComputed("currentAction.words.[]")
regexpError(words) {
@@ -37,78 +40,81 @@ export default Controller.extend({
return I18n.t("admin.watched_words.invalid_regex", { word });
}
}
- },
+ }
@discourseComputed("actionNameKey")
actionDescription(actionNameKey) {
return I18n.t("admin.watched_words.action_descriptions." + actionNameKey);
- },
+ }
- actions: {
- recordAdded(arg) {
- const action = this.findAction(this.actionNameKey);
- if (!action) {
- return;
- }
+ @action
+ recordAdded(arg) {
+ const foundAction = this.findAction(this.actionNameKey);
+ if (!foundAction) {
+ return;
+ }
- action.words.unshiftObject(arg);
- schedule("afterRender", () => {
- // remove from other actions lists
- let match = null;
- this.adminWatchedWords.model.forEach((otherAction) => {
+ foundAction.words.unshiftObject(arg);
+ schedule("afterRender", () => {
+ // remove from other actions lists
+ let match = null;
+ this.adminWatchedWords.model.forEach((otherAction) => {
+ if (match) {
+ return;
+ }
+
+ if (otherAction.nameKey !== this.actionNameKey) {
+ match = otherAction.words.findBy("id", arg.id);
if (match) {
- return;
+ otherAction.words.removeObject(match);
}
+ }
+ });
+ });
+ }
- if (otherAction.nameKey !== this.actionNameKey) {
- match = otherAction.words.findBy("id", arg.id);
- if (match) {
- otherAction.words.removeObject(match);
- }
+ @action
+ recordRemoved(arg) {
+ if (this.currentAction) {
+ 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", []);
- }
- });
- },
- });
- },
- },
-});
+ },
+ });
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-watched-words.js b/app/assets/javascripts/admin/addon/controllers/admin-watched-words.js
index 27e741e9ce5..72a2dedd430 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-watched-words.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-watched-words.js
@@ -3,11 +3,11 @@ import EmberObject, { action } from "@ember/object";
import { INPUT_DELAY } from "discourse-common/config/environment";
import discourseDebounce from "discourse-common/lib/debounce";
import { isEmpty } from "@ember/utils";
-import { observes } from "discourse-common/utils/decorators";
+import { observes } from "@ember-decorators/object";
-export default Controller.extend({
- filter: null,
- showWords: false,
+export default class AdminWatchedWordsController extends Controller {
+ filter = null;
+ showWords = false;
_filterContent() {
if (isEmpty(this.allWatchedWords)) {
@@ -36,17 +36,17 @@ export default Controller.extend({
);
});
this.set("model", model);
- },
+ }
@observes("filter")
filterContent() {
discourseDebounce(this, this._filterContent, INPUT_DELAY);
- },
+ }
@action
clearFilter() {
this.set("filter", "");
- },
+ }
@action
toggleMenu() {
@@ -54,5 +54,5 @@ export default Controller.extend({
["mobile-closed", "mobile-open"].forEach((state) => {
adminDetail.classList.toggle(state);
});
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-edit.js b/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-edit.js
index f24dfef939e..a223e06feb1 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-edit.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-edit.js
@@ -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 EmberObject, { action } from "@ember/object";
import I18n from "I18n";
-import { alias } from "@ember/object/computed";
import discourseComputed from "discourse-common/utils/decorators";
import { isEmpty } from "@ember/utils";
import { popupAjaxError } from "discourse/lib/ajax-error";
-import { inject as service } from "@ember/service";
-export default Controller.extend({
- adminWebHooks: controller(),
- dialog: service(),
- eventTypes: alias("adminWebHooks.eventTypes"),
- defaultEventTypes: alias("adminWebHooks.defaultEventTypes"),
- contentTypes: alias("adminWebHooks.contentTypes"),
+export default class AdminWebHooksEditController extends Controller {
+ @service dialog;
+ @controller adminWebHooks;
+
+ @alias("adminWebHooks.eventTypes") eventTypes;
+ @alias("adminWebHooks.defaultEventTypes") defaultEventTypes;
+ @alias("adminWebHooks.contentTypes") contentTypes;
@discourseComputed
showTagsFilter() {
return this.siteSettings.tagging_enabled;
- },
+ }
@discourseComputed("model.isSaving", "saved", "saveButtonDisabled")
savingStatus(isSaving, saved, saveButtonDisabled) {
@@ -29,14 +30,14 @@ export default Controller.extend({
// Use side effect of validation to clear saved text
this.set("saved", false);
return "";
- },
+ }
@discourseComputed("model.isNew")
saveButtonText(isNew) {
return isNew
? I18n.t("admin.web_hooks.create")
: I18n.t("admin.web_hooks.save");
- },
+ }
@discourseComputed("model.secret")
secretValidation(secret) {
@@ -55,7 +56,7 @@ export default Controller.extend({
});
}
}
- },
+ }
@discourseComputed("model.wildcard_web_hook", "model.web_hook_event_types.[]")
eventTypeValidation(isWildcard, eventTypes) {
@@ -65,7 +66,7 @@ export default Controller.extend({
reason: I18n.t("admin.web_hooks.event_type_missing"),
});
}
- },
+ }
@discourseComputed(
"model.isSaving",
@@ -82,7 +83,7 @@ export default Controller.extend({
return isSaving
? false
: secretValidation || eventTypeValidation || isEmpty(payloadUrl);
- },
+ }
@action
async save() {
@@ -97,5 +98,5 @@ export default Controller.extend({
} catch (e) {
popupAjaxError(e);
}
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-index.js b/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-index.js
index a1294cf09d7..865fbad990c 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-index.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-index.js
@@ -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 I18n from "I18n";
import { popupAjaxError } from "discourse/lib/ajax-error";
-import { inject as service } from "@ember/service";
import { action } from "@ember/object";
-import { alias } from "@ember/object/computed";
-export default Controller.extend({
- adminWebHooks: controller(),
- dialog: service(),
- contentTypes: alias("adminWebHooks.contentTypes"),
- defaultEventTypes: alias("adminWebHooks.defaultEventTypes"),
- deliveryStatuses: alias("adminWebHooks.deliveryStatuses"),
- eventTypes: alias("adminWebHooks.eventTypes"),
- model: alias("adminWebHooks.model"),
+export default class AdminWebHooksIndexController extends Controller {
+ @service dialog;
+ @controller adminWebHooks;
+
+ @alias("adminWebHooks.contentTypes") contentTypes;
+ @alias("adminWebHooks.defaultEventTypes") defaultEventTypes;
+ @alias("adminWebHooks.deliveryStatuses") deliveryStatuses;
+ @alias("adminWebHooks.eventTypes") eventTypes;
+ @alias("adminWebHooks.model") model;
@action
destroy(webhook) {
@@ -27,10 +28,10 @@ export default Controller.extend({
}
},
});
- },
+ }
@action
loadMore() {
this.model.loadMore();
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-show.js b/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-show.js
index 38bef778fb4..e216859b93b 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-show.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-web-hooks-show.js
@@ -1,18 +1,18 @@
+import { inject as service } from "@ember/service";
import Controller, { inject as controller } from "@ember/controller";
import { action } from "@ember/object";
import I18n from "I18n";
import { popupAjaxError } from "discourse/lib/ajax-error";
-import { inject as service } from "@ember/service";
-export default Controller.extend({
- adminWebHooks: controller(),
- dialog: service(),
- router: service(),
+export default class AdminWebHooksShowController extends Controller {
+ @service dialog;
+ @service router;
+ @controller adminWebHooks;
@action
edit() {
return this.router.transitionTo("adminWebHooks.edit", this.model);
- },
+ }
@action
destroy() {
@@ -28,5 +28,5 @@ export default Controller.extend({
}
},
});
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin-web-hooks.js b/app/assets/javascripts/admin/addon/controllers/admin-web-hooks.js
index fa4ba1ee7d2..6de7af26830 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin-web-hooks.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin-web-hooks.js
@@ -1,3 +1,3 @@
import Controller from "@ember/controller";
-export default Controller.extend({});
+export default class AdminWebHooksController extends Controller {}
diff --git a/app/assets/javascripts/admin/addon/controllers/admin.js b/app/assets/javascripts/admin/addon/controllers/admin.js
index 03838b789cd..9b802fe89e9 100644
--- a/app/assets/javascripts/admin/addon/controllers/admin.js
+++ b/app/assets/javascripts/admin/addon/controllers/admin.js
@@ -1,20 +1,20 @@
+import { inject as service } from "@ember/service";
import Controller from "@ember/controller";
import { dasherize } from "@ember/string";
import discourseComputed from "discourse-common/utils/decorators";
-import { inject as service } from "@ember/service";
-export default Controller.extend({
- router: service(),
+export default class AdminController extends Controller {
+ @service router;
@discourseComputed("siteSettings.enable_group_directory")
showGroups(enableGroupDirectory) {
return !enableGroupDirectory;
- },
+ }
@discourseComputed("siteSettings.enable_badges")
showBadges(enableBadges) {
return this.currentUser.get("admin") && enableBadges;
- },
+ }
@discourseComputed("router._router.currentPath")
adminContentsClassName(currentPath) {
@@ -37,5 +37,5 @@ export default Controller.extend({
}
return cssClasses;
- },
-});
+ }
+}
diff --git a/app/assets/javascripts/admin/addon/templates/customize-themes-show.hbs b/app/assets/javascripts/admin/addon/templates/customize-themes-show.hbs
index b7fb0efd771..8f3682f611f 100644
--- a/app/assets/javascripts/admin/addon/templates/customize-themes-show.hbs
+++ b/app/assets/javascripts/admin/addon/templates/customize-themes-show.hbs
@@ -65,7 +65,7 @@
@label="admin.customize.theme.finish_install"
/>