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" /> diff --git a/app/assets/javascripts/admin/addon/templates/permalinks.hbs b/app/assets/javascripts/admin/addon/templates/permalinks.hbs index c3fefa1137c..8b2f83b4bf4 100644 --- a/app/assets/javascripts/admin/addon/templates/permalinks.hbs +++ b/app/assets/javascripts/admin/addon/templates/permalinks.hbs @@ -63,7 +63,7 @@ diff --git a/app/assets/javascripts/admin/addon/templates/user-index.hbs b/app/assets/javascripts/admin/addon/templates/user-index.hbs index 2f6e5e0f3ce..b6e43794c14 100644 --- a/app/assets/javascripts/admin/addon/templates/user-index.hbs +++ b/app/assets/javascripts/admin/addon/templates/user-index.hbs @@ -898,7 +898,7 @@ @label="admin.user.delete" @icon="trash-alt" @class="btn-danger btn-user-delete" - @action={{action "destroy"}} + @action={{action "destroyUser"}} /> {{/if}}