diff --git a/app/assets/javascripts/admin/addon/components/ace-editor.js b/app/assets/javascripts/admin/addon/components/ace-editor.js index 06ed3763031..bc324978333 100644 --- a/app/assets/javascripts/admin/addon/components/ace-editor.js +++ b/app/assets/javascripts/admin/addon/components/ace-editor.js @@ -1,31 +1,33 @@ +import { action } from "@ember/object"; +import { classNames } from "@ember-decorators/component"; +import { on } from "@ember-decorators/object"; import Component from "@ember/component"; import getURL from "discourse-common/lib/get-url"; import loadScript from "discourse/lib/load-script"; import I18n from "I18n"; import { bind, observes } from "discourse-common/utils/decorators"; -import { on } from "@ember/object/evented"; const COLOR_VARS_REGEX = /\$(primary|secondary|tertiary|quaternary|header_background|header_primary|highlight|danger|success|love)(\s|;|-(low|medium|high))/g; -export default Component.extend({ - mode: "css", - classNames: ["ace-wrapper"], - _editor: null, - _skipContentChangeEvent: null, - disabled: false, - htmlPlaceholder: false, +@classNames("ace-wrapper") +export default class AceEditor extends Component { + mode = "css"; + disabled = false; + htmlPlaceholder = false; + _editor = null; + _skipContentChangeEvent = null; @observes("editorId") editorIdChanged() { if (this.autofocus) { this.send("focus"); } - }, + } didRender() { this._skipContentChangeEvent = false; - }, + } @observes("content") contentChanged() { @@ -33,14 +35,14 @@ export default Component.extend({ if (this._editor && !this._skipContentChangeEvent) { this._editor.getSession().setValue(content); } - }, + } @observes("mode") modeChanged() { if (this._editor && !this._skipContentChangeEvent) { this._editor.getSession().setMode("ace/mode/" + this.mode); } - }, + } @observes("placeholder") placeholderChanged() { @@ -49,12 +51,12 @@ export default Component.extend({ placeholder: this.placeholder, }); } - }, + } @observes("disabled") disabledStateChanged() { this.changeDisabledState(); - }, + } changeDisabledState() { const editor = this._editor; @@ -67,9 +69,10 @@ export default Component.extend({ }); editor.container.parentNode.setAttribute("data-disabled", disabled); } - }, + } - _destroyEditor: on("willDestroyElement", function () { + @on("willDestroyElement") + _destroyEditor() { if (this._editor) { this._editor.destroy(); this._editor = null; @@ -80,16 +83,16 @@ export default Component.extend({ } $(window).off("ace:resize"); - }), + } resize() { if (this._editor) { this._editor.resize(); } - }, + } didInsertElement() { - this._super(...arguments); + super.didInsertElement(...arguments); loadScript("/javascripts/ace/ace.js").then(() => { window.ace.require(["ace/ace"], (loadedAce) => { loadedAce.config.set("loadWorkerFromBlob", false); @@ -153,13 +156,13 @@ export default Component.extend({ this._darkModeListener.addListener(this.setAceTheme); }); }); - }, + } willDestroyElement() { if (this._darkModeListener) { this._darkModeListener.removeListener(this.setAceTheme); } - }, + } @bind setAceTheme() { @@ -170,7 +173,7 @@ export default Component.extend({ this._editor.setTheme( `ace/theme/${schemeType === "dark" ? "chaos" : "chrome"}` ); - }, + } warnSCSSDeprecations() { if ( @@ -202,16 +205,15 @@ export default Component.extend({ ? I18n.t("admin.customize.theme.scss_color_variables_warning") : false ); - }, + } - actions: { - focus() { - if (this._editor) { - this._editor.focus(); - this._editor.navigateFileEnd(); - } - }, - }, + @action + focus() { + if (this._editor) { + this._editor.focus(); + this._editor.navigateFileEnd(); + } + } _overridePlaceholder(loadedAce) { const originalPlaceholderSetter = @@ -239,5 +241,5 @@ export default Component.extend({ this.$updatePlaceholder(); }; - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/admin-backups-logs.js b/app/assets/javascripts/admin/addon/components/admin-backups-logs.js index c707c99b70a..424979543e2 100644 --- a/app/assets/javascripts/admin/addon/components/admin-backups-logs.js +++ b/app/assets/javascripts/admin/addon/components/admin-backups-logs.js @@ -1,28 +1,26 @@ +import { classNames } from "@ember-decorators/component"; import { observes, on } from "discourse-common/utils/decorators"; import Component from "@ember/component"; import I18n from "I18n"; import discourseDebounce from "discourse-common/lib/debounce"; import { scheduleOnce } from "@ember/runloop"; -export default Component.extend({ - classNames: ["admin-backups-logs"], - showLoadingSpinner: false, - hasFormattedLogs: false, - noLogsMessage: I18n.t("admin.backups.logs.none"), - - init() { - this._super(...arguments); - this._reset(); - }, +@classNames("admin-backups-logs") +export default class AdminBackupsLogs extends Component { + showLoadingSpinner = false; + hasFormattedLogs = false; + noLogsMessage = I18n.t("admin.backups.logs.none"); + formattedLogs = ""; + index = 0; _reset() { this.setProperties({ formattedLogs: "", index: 0 }); - }, + } _scrollDown() { const div = this.element; div.scrollTop = div.scrollHeight; - }, + } @on("init") @observes("logs.[]") @@ -31,7 +29,7 @@ export default Component.extend({ this._reset(); // reset the cached logs whenever the model is reset this.renderLogs(); } - }, + } _updateFormattedLogsFunc() { const logs = this.logs; @@ -55,13 +53,13 @@ export default Component.extend({ this.renderLogs(); scheduleOnce("afterRender", this, this._scrollDown); - }, + } @on("init") @observes("logs.[]") _updateFormattedLogs() { discourseDebounce(this, this._updateFormattedLogsFunc, 150); - }, + } renderLogs() { const formattedLogs = this.formattedLogs; @@ -76,5 +74,5 @@ export default Component.extend({ } else { this.set("showLoadingSpinner", false); } - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/admin-editable-field.js b/app/assets/javascripts/admin/addon/components/admin-editable-field.js index 892a3208e86..a99265b20cb 100644 --- a/app/assets/javascripts/admin/addon/components/admin-editable-field.js +++ b/app/assets/javascripts/admin/addon/components/admin-editable-field.js @@ -1,28 +1,22 @@ +import { tagName } from "@ember-decorators/component"; import Component from "@ember/component"; import { action } from "@ember/object"; -export default Component.extend({ - tagName: "", - - buffer: "", - editing: false, - - init() { - this._super(...arguments); - this.set("editing", false); - }, +@tagName("") +export default class AdminEditableField extends Component { + buffer = ""; + editing = false; @action edit(event) { event?.preventDefault(); this.set("buffer", this.value); this.toggleProperty("editing"); - }, + } - actions: { - save() { - // Action has to toggle 'editing' property. - this.action(this.buffer); - }, - }, -}); + @action + save() { + // Action has to toggle 'editing' property. + this.action(this.buffer); + } +} diff --git a/app/assets/javascripts/admin/addon/components/admin-form-row.js b/app/assets/javascripts/admin/addon/components/admin-form-row.js index 6217c6b913f..266301263d4 100644 --- a/app/assets/javascripts/admin/addon/components/admin-form-row.js +++ b/app/assets/javascripts/admin/addon/components/admin-form-row.js @@ -1,4 +1,5 @@ +import { classNames } from "@ember-decorators/component"; import Component from "@ember/component"; -export default Component.extend({ - classNames: ["row"], -}); + +@classNames("row") +export default class AdminFormRow extends Component {} diff --git a/app/assets/javascripts/admin/addon/components/admin-graph.js b/app/assets/javascripts/admin/addon/components/admin-graph.js index 1107abeb2ca..4ef05fca32e 100644 --- a/app/assets/javascripts/admin/addon/components/admin-graph.js +++ b/app/assets/javascripts/admin/addon/components/admin-graph.js @@ -1,9 +1,10 @@ +import { tagName } from "@ember-decorators/component"; import Component from "@ember/component"; import loadScript from "discourse/lib/load-script"; -export default Component.extend({ - tagName: "canvas", - type: "line", +@tagName("canvas") +export default class AdminGraph extends Component { + type = "line"; refreshChart() { const ctx = this.element.getContext("2d"); @@ -49,11 +50,11 @@ export default Component.extend({ }; this._chart = new window.Chart(ctx, config); - }, + } didInsertElement() { loadScript("/javascripts/Chart.min.js").then(() => this.refreshChart.apply(this) ); - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/admin-nav.js b/app/assets/javascripts/admin/addon/components/admin-nav.js index 0e6d50b17d4..2542a2238ba 100644 --- a/app/assets/javascripts/admin/addon/components/admin-nav.js +++ b/app/assets/javascripts/admin/addon/components/admin-nav.js @@ -1,4 +1,5 @@ +import { tagName } from "@ember-decorators/component"; import Component from "@ember/component"; -export default Component.extend({ - tagName: "", -}); + +@tagName("") +export default class AdminNav extends Component {} diff --git a/app/assets/javascripts/admin/addon/components/admin-penalty-history.js b/app/assets/javascripts/admin/addon/components/admin-penalty-history.js index 32c288b248d..0931ac8e4a4 100644 --- a/app/assets/javascripts/admin/addon/components/admin-penalty-history.js +++ b/app/assets/javascripts/admin/addon/components/admin-penalty-history.js @@ -1,16 +1,16 @@ +import { classNames } from "@ember-decorators/component"; import Component from "@ember/component"; import discourseComputed from "discourse-common/utils/decorators"; -export default Component.extend({ - classNames: ["penalty-history"], - +@classNames("penalty-history") +export default class AdminPenaltyHistory extends Component { @discourseComputed("user.penalty_counts.suspended") suspendedCountClass(count) { if (count > 0) { return "danger"; } return ""; - }, + } @discourseComputed("user.penalty_counts.silenced") silencedCountClass(count) { @@ -18,5 +18,5 @@ export default Component.extend({ return "danger"; } return ""; - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/admin-penalty-post-action.js b/app/assets/javascripts/admin/addon/components/admin-penalty-post-action.js index eb201ae0899..08314925460 100644 --- a/app/assets/javascripts/admin/addon/components/admin-penalty-post-action.js +++ b/app/assets/javascripts/admin/addon/components/admin-penalty-post-action.js @@ -1,5 +1,6 @@ -import Component from "@ember/component"; +import { action } from "@ember/object"; import { equal } from "@ember/object/computed"; +import Component from "@ember/component"; import discourseComputed, { afterRender, } from "discourse-common/utils/decorators"; @@ -7,30 +8,28 @@ import I18n from "I18n"; const ACTIONS = ["delete", "delete_replies", "edit", "none"]; -export default Component.extend({ - postId: null, - postAction: null, - postEdit: null, +export default class AdminPenaltyPostAction extends Component { + postId = null; + postAction = null; + postEdit = null; + @equal("postAction", "edit") editing; @discourseComputed penaltyActions() { return ACTIONS.map((id) => { return { id, name: I18n.t(`admin.user.penalty_post_${id}`) }; }); - }, + } - editing: equal("postAction", "edit"), + @action + penaltyChanged(postAction) { + this.set("postAction", postAction); - actions: { - penaltyChanged(postAction) { - this.set("postAction", postAction); - - // If we switch to edit mode, jump to the edit textarea - if (postAction === "edit") { - this._focusEditTextarea(); - } - }, - }, + // If we switch to edit mode, jump to the edit textarea + if (postAction === "edit") { + this._focusEditTextarea(); + } + } @afterRender _focusEditTextarea() { @@ -38,5 +37,5 @@ export default Component.extend({ const body = elem.closest(".modal-body"); body.scrollTo(0, body.clientHeight); elem.querySelector(".post-editor").focus(); - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/admin-penalty-reason.js b/app/assets/javascripts/admin/addon/components/admin-penalty-reason.js index ca6164e7630..e8d037d249b 100644 --- a/app/assets/javascripts/admin/addon/components/admin-penalty-reason.js +++ b/app/assets/javascripts/admin/addon/components/admin-penalty-reason.js @@ -1,43 +1,46 @@ +import { tagName } from "@ember-decorators/component"; +import { equal } from "@ember/object/computed"; import Component from "@ember/component"; import { action } from "@ember/object"; -import { equal } from "@ember/object/computed"; import discourseComputed from "discourse-common/utils/decorators"; import I18n from "I18n"; const CUSTOM_REASON_KEY = "custom"; -export default Component.extend({ - tagName: "", - selectedReason: CUSTOM_REASON_KEY, - customReason: "", - reasonKeys: [ +@tagName("") +export default class AdminPenaltyReason extends Component { + selectedReason = CUSTOM_REASON_KEY; + customReason = ""; + + reasonKeys = [ "not_listening_to_staff", "consuming_staff_time", "combative", "in_wrong_place", "no_constructive_purpose", CUSTOM_REASON_KEY, - ], - isCustomReason: equal("selectedReason", CUSTOM_REASON_KEY), + ]; + + @equal("selectedReason", CUSTOM_REASON_KEY) isCustomReason; @discourseComputed("reasonKeys") reasons(keys) { return keys.map((key) => { return { id: key, name: I18n.t(`admin.user.suspend_reasons.${key}`) }; }); - }, + } @action setSelectedReason(value) { this.set("selectedReason", value); this.setReason(); - }, + } @action setCustomReason(value) { this.set("customReason", value); this.setReason(); - }, + } setReason() { if (this.isCustomReason) { @@ -48,5 +51,5 @@ export default Component.extend({ I18n.t(`admin.user.suspend_reasons.${this.selectedReason}`) ); } - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/admin-penalty-similar-users.js b/app/assets/javascripts/admin/addon/components/admin-penalty-similar-users.js index 241927a7b7f..52996d458f3 100644 --- a/app/assets/javascripts/admin/addon/components/admin-penalty-similar-users.js +++ b/app/assets/javascripts/admin/addon/components/admin-penalty-similar-users.js @@ -1,10 +1,10 @@ +import { tagName } from "@ember-decorators/component"; import Component from "@ember/component"; import { action } from "@ember/object"; import discourseComputed from "discourse-common/utils/decorators"; -export default Component.extend({ - tagName: "", - +@tagName("") +export default class AdminPenaltySimilarUsers extends Component { @discourseComputed("penaltyType") penaltyField(penaltyType) { if (penaltyType === "suspend") { @@ -12,7 +12,7 @@ export default Component.extend({ } else if (penaltyType === "silence") { return "can_be_silenced"; } - }, + } @action selectUserId(userId, event) { @@ -25,5 +25,5 @@ export default Component.extend({ } else { this.selectedUserIds.removeObject(userId); } - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/admin-report-chart.js b/app/assets/javascripts/admin/addon/components/admin-report-chart.js index 1c4ad1caa3a..64f09aa0d7d 100644 --- a/app/assets/javascripts/admin/addon/components/admin-report-chart.js +++ b/app/assets/javascripts/admin/addon/components/admin-report-chart.js @@ -1,3 +1,4 @@ +import { classNames } from "@ember-decorators/component"; import Report from "admin/models/report"; import Component from "@ember/component"; import discourseDebounce from "discourse-common/lib/debounce"; @@ -7,31 +8,31 @@ import { number } from "discourse/lib/formatter"; import { schedule } from "@ember/runloop"; import { bind } from "discourse-common/utils/decorators"; -export default Component.extend({ - classNames: ["admin-report-chart"], - limit: 8, - total: 0, - options: null, +@classNames("admin-report-chart") +export default class AdminReportChart extends Component { + limit = 8; + total = 0; + options = null; didInsertElement() { - this._super(...arguments); + super.didInsertElement(...arguments); window.addEventListener("resize", this._resizeHandler); - }, + } willDestroyElement() { - this._super(...arguments); + super.willDestroyElement(...arguments); window.removeEventListener("resize", this._resizeHandler); this._resetChart(); - }, + } didReceiveAttrs() { - this._super(...arguments); + super.didReceiveAttrs(...arguments); discourseDebounce(this, this._scheduleChartRendering, 100); - }, + } _scheduleChartRendering() { schedule("afterRender", () => { @@ -40,7 +41,7 @@ export default Component.extend({ this.element && this.element.querySelector(".chart-canvas") ); }); - }, + } _renderChart(model, chartCanvas) { if (!chartCanvas) { @@ -99,7 +100,7 @@ export default Component.extend({ this._buildChartConfig(data, this.options) ); }); - }, + } _buildChartConfig(data, options) { return { @@ -161,21 +162,21 @@ export default Component.extend({ }, }, }; - }, + } _resetChart() { if (this._chart) { this._chart.destroy(); this._chart = null; } - }, + } _applyChartGrouping(model, data, options) { return Report.collapse(model, data, options.chartGrouping); - }, + } @bind _resizeHandler() { discourseDebounce(this, this._scheduleChartRendering, 500); - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/admin-report-counters.js b/app/assets/javascripts/admin/addon/components/admin-report-counters.js index c956b93e359..6e3dab52366 100644 --- a/app/assets/javascripts/admin/addon/components/admin-report-counters.js +++ b/app/assets/javascripts/admin/addon/components/admin-report-counters.js @@ -1,6 +1,6 @@ +import { attributeBindings, classNames } from "@ember-decorators/component"; import Component from "@ember/component"; -export default Component.extend({ - classNames: ["admin-report-counters"], - attributeBindings: ["model.description:title"], -}); +@classNames("admin-report-counters") +@attributeBindings("model.description:title") +export default class AdminReportCounters extends Component {} diff --git a/app/assets/javascripts/admin/addon/components/admin-report-counts.js b/app/assets/javascripts/admin/addon/components/admin-report-counts.js index 03c690dbbd6..fd1b6cc68d6 100644 --- a/app/assets/javascripts/admin/addon/components/admin-report-counts.js +++ b/app/assets/javascripts/admin/addon/components/admin-report-counts.js @@ -1,11 +1,12 @@ -import Component from "@ember/component"; +import { classNameBindings, tagName } from "@ember-decorators/component"; import { match } from "@ember/object/computed"; -export default Component.extend({ - allTime: true, - tagName: "tr", - reverseColors: match( - "report.type", - /^(time_to_first_response|topics_with_no_response)$/ - ), - classNameBindings: ["reverseColors"], -}); +import Component from "@ember/component"; + +@tagName("tr") +@classNameBindings("reverseColors") +export default class AdminReportCounts extends Component { + allTime = true; + + @match("report.type", /^(time_to_first_response|topics_with_no_response)$/) + reverseColors; +} diff --git a/app/assets/javascripts/admin/addon/components/admin-report-inline-table.js b/app/assets/javascripts/admin/addon/components/admin-report-inline-table.js index 753320cc31a..3e770da6467 100644 --- a/app/assets/javascripts/admin/addon/components/admin-report-inline-table.js +++ b/app/assets/javascripts/admin/addon/components/admin-report-inline-table.js @@ -1,4 +1,5 @@ +import { classNames } from "@ember-decorators/component"; import Component from "@ember/component"; -export default Component.extend({ - classNames: ["admin-report-inline-table"], -}); + +@classNames("admin-report-inline-table") +export default class AdminReportInlineTable extends Component {} diff --git a/app/assets/javascripts/admin/addon/components/admin-report-per-day-counts.js b/app/assets/javascripts/admin/addon/components/admin-report-per-day-counts.js index 7f039c061e1..ee48a5138f2 100644 --- a/app/assets/javascripts/admin/addon/components/admin-report-per-day-counts.js +++ b/app/assets/javascripts/admin/addon/components/admin-report-per-day-counts.js @@ -1,4 +1,5 @@ +import { tagName } from "@ember-decorators/component"; import Component from "@ember/component"; -export default Component.extend({ - tagName: "tr", -}); + +@tagName("tr") +export default class AdminReportPerDayCounts extends Component {} diff --git a/app/assets/javascripts/admin/addon/components/admin-report-stacked-chart.js b/app/assets/javascripts/admin/addon/components/admin-report-stacked-chart.js index 6b773957f66..b69e75141e8 100644 --- a/app/assets/javascripts/admin/addon/components/admin-report-stacked-chart.js +++ b/app/assets/javascripts/admin/addon/components/admin-report-stacked-chart.js @@ -1,3 +1,4 @@ +import { classNames } from "@ember-decorators/component"; import Report from "admin/models/report"; import Component from "@ember/component"; import discourseDebounce from "discourse-common/lib/debounce"; @@ -7,32 +8,31 @@ import { number } from "discourse/lib/formatter"; import { schedule } from "@ember/runloop"; import { bind } from "discourse-common/utils/decorators"; -export default Component.extend({ - classNames: ["admin-report-chart", "admin-report-stacked-chart"], - +@classNames("admin-report-chart", "admin-report-stacked-chart") +export default class AdminReportStackedChart extends Component { didInsertElement() { - this._super(...arguments); + super.didInsertElement(...arguments); window.addEventListener("resize", this._resizeHandler); - }, + } willDestroyElement() { - this._super(...arguments); + super.willDestroyElement(...arguments); window.removeEventListener("resize", this._resizeHandler); this._resetChart(); - }, + } didReceiveAttrs() { - this._super(...arguments); + super.didReceiveAttrs(...arguments); discourseDebounce(this, this._scheduleChartRendering, 100); - }, + } @bind _resizeHandler() { discourseDebounce(this, this._scheduleChartRendering, 500); - }, + } _scheduleChartRendering() { schedule("afterRender", () => { @@ -45,7 +45,7 @@ export default Component.extend({ this.element.querySelector(".chart-canvas") ); }); - }, + } _renderChart(model, chartCanvas) { if (!chartCanvas) { @@ -79,7 +79,7 @@ export default Component.extend({ this._chart = new window.Chart(context, this._buildChartConfig(data)); }); - }, + } _buildChartConfig(data) { return { @@ -150,10 +150,10 @@ export default Component.extend({ }, }, }; - }, + } _resetChart() { this._chart?.destroy(); this._chart = null; - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/admin-report-storage-stats.js b/app/assets/javascripts/admin/addon/components/admin-report-storage-stats.js index e12bc6432f7..ee0d7d24764 100644 --- a/app/assets/javascripts/admin/addon/components/admin-report-storage-stats.js +++ b/app/assets/javascripts/admin/addon/components/admin-report-storage-stats.js @@ -1,43 +1,45 @@ +import { classNames } from "@ember-decorators/component"; +import { alias } from "@ember/object/computed"; import Component from "@ember/component"; import I18n from "I18n"; -import { alias } from "@ember/object/computed"; import discourseComputed from "discourse-common/utils/decorators"; import { setting } from "discourse/lib/computed"; -export default Component.extend({ - classNames: ["admin-report-storage-stats"], +@classNames("admin-report-storage-stats") +export default class AdminReportStorageStats extends Component { + @setting("backup_location") backupLocation; - backupLocation: setting("backup_location"), - backupStats: alias("model.data.backups"), - uploadStats: alias("model.data.uploads"), + @alias("model.data.backups") backupStats; + + @alias("model.data.uploads") uploadStats; @discourseComputed("backupStats") showBackupStats(stats) { return stats && this.currentUser.admin; - }, + } @discourseComputed("backupLocation") backupLocationName(backupLocation) { return I18n.t(`admin.backups.location.${backupLocation}`); - }, + } @discourseComputed("backupStats.used_bytes") usedBackupSpace(bytes) { return I18n.toHumanSize(bytes); - }, + } @discourseComputed("backupStats.free_bytes") freeBackupSpace(bytes) { return I18n.toHumanSize(bytes); - }, + } @discourseComputed("uploadStats.used_bytes") usedUploadSpace(bytes) { return I18n.toHumanSize(bytes); - }, + } @discourseComputed("uploadStats.free_bytes") freeUploadSpace(bytes) { return I18n.toHumanSize(bytes); - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/admin-report-table-cell.js b/app/assets/javascripts/admin/addon/components/admin-report-table-cell.js index 838d8dbe1d4..89997c9afab 100644 --- a/app/assets/javascripts/admin/addon/components/admin-report-table-cell.js +++ b/app/assets/javascripts/admin/addon/components/admin-report-table-cell.js @@ -1,21 +1,27 @@ -import Component from "@ember/component"; +import { + attributeBindings, + classNameBindings, + classNames, + tagName, +} from "@ember-decorators/component"; import { alias } from "@ember/object/computed"; +import Component from "@ember/component"; import discourseComputed from "discourse-common/utils/decorators"; -export default Component.extend({ - tagName: "td", - classNames: ["admin-report-table-cell"], - classNameBindings: ["type", "property"], - attributeBindings: ["value:title"], - options: null, +@tagName("td") +@classNames("admin-report-table-cell") +@classNameBindings("type", "property") +@attributeBindings("value:title") +export default class AdminReportTableCell extends Component { + options = null; + + @alias("label.type") type; + @alias("label.mainProperty") property; + @alias("computedLabel.formattedValue") formattedValue; + @alias("computedLabel.value") value; @discourseComputed("label", "data", "options") computedLabel(label, data, options) { return label.compute(data, options || {}); - }, - - type: alias("label.type"), - property: alias("label.mainProperty"), - formattedValue: alias("computedLabel.formattedValue"), - value: alias("computedLabel.value"), -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/admin-report-table-header.js b/app/assets/javascripts/admin/addon/components/admin-report-table-header.js index 5c7cdf1e4ca..7de3ac97088 100644 --- a/app/assets/javascripts/admin/addon/components/admin-report-table-header.js +++ b/app/assets/javascripts/admin/addon/components/admin-report-table-header.js @@ -1,19 +1,24 @@ +import { + attributeBindings, + classNameBindings, + classNames, + tagName, +} from "@ember-decorators/component"; import Component from "@ember/component"; import discourseComputed from "discourse-common/utils/decorators"; -export default Component.extend({ - tagName: "th", - classNames: ["admin-report-table-header"], - classNameBindings: ["label.mainProperty", "label.type", "isCurrentSort"], - attributeBindings: ["label.title:title"], - +@tagName("th") +@classNames("admin-report-table-header") +@classNameBindings("label.mainProperty", "label.type", "isCurrentSort") +@attributeBindings("label.title:title") +export default class AdminReportTableHeader extends Component { @discourseComputed("currentSortLabel.sortProperty", "label.sortProperty") isCurrentSort(currentSortField, labelSortField) { return currentSortField === labelSortField; - }, + } @discourseComputed("currentSortDirection") sortIcon(currentSortDirection) { return currentSortDirection === 1 ? "caret-up" : "caret-down"; - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/admin-report-table-row.js b/app/assets/javascripts/admin/addon/components/admin-report-table-row.js index ff34cb94e8b..e5e275aa7ad 100644 --- a/app/assets/javascripts/admin/addon/components/admin-report-table-row.js +++ b/app/assets/javascripts/admin/addon/components/admin-report-table-row.js @@ -1,6 +1,8 @@ +import { classNames, tagName } from "@ember-decorators/component"; import Component from "@ember/component"; -export default Component.extend({ - tagName: "tr", - classNames: ["admin-report-table-row"], - options: null, -}); + +@tagName("tr") +@classNames("admin-report-table-row") +export default class AdminReportTableRow extends Component { + options = null; +} diff --git a/app/assets/javascripts/admin/addon/components/admin-report-table.js b/app/assets/javascripts/admin/addon/components/admin-report-table.js index a237e93ee43..3638625f872 100644 --- a/app/assets/javascripts/admin/addon/components/admin-report-table.js +++ b/app/assets/javascripts/admin/addon/components/admin-report-table.js @@ -1,22 +1,26 @@ -import Component from "@ember/component"; +import { action } from "@ember/object"; +import { classNameBindings, classNames } from "@ember-decorators/component"; import { alias } from "@ember/object/computed"; +import Component from "@ember/component"; import discourseComputed from "discourse-common/utils/decorators"; import { makeArray } from "discourse-common/lib/helpers"; const PAGES_LIMIT = 8; -export default Component.extend({ - classNameBindings: ["sortable", "twoColumns"], - classNames: ["admin-report-table"], - sortable: false, - sortDirection: 1, - perPage: alias("options.perPage"), - page: 0, +@classNameBindings("sortable", "twoColumns") +@classNames("admin-report-table") +export default class AdminReportTable extends Component { + sortable = false; + sortDirection = 1; + + @alias("options.perPage") perPage; + + page = 0; @discourseComputed("model.computedLabels.length") twoColumns(labelsLength) { return labelsLength === 2; - }, + } @discourseComputed( "totalsForSample", @@ -31,12 +35,12 @@ export default Component.extend({ .reduce((s, v) => s + v, 0); return sum >= 1 && total && datesFiltering; - }, + } @discourseComputed("model.total", "options.total", "twoColumns") showTotal(reportTotal, total, twoColumns) { return reportTotal && total && twoColumns; - }, + } @discourseComputed( "model.{average,data}", @@ -50,17 +54,17 @@ export default Component.extend({ sampleTotalValue && hasTwoColumns ); - }, + } @discourseComputed("totalsForSample.1.value", "model.data.length") averageForSample(totals, count) { return (totals / count).toFixed(0); - }, + } @discourseComputed("model.data.length") showSortingUI(dataLength) { return dataLength >= 5; - }, + } @discourseComputed("totalsForSampleRow", "model.computedLabels") totalsForSample(row, labels) { @@ -70,7 +74,7 @@ export default Component.extend({ computedLabel.property = label.mainProperty; return computedLabel; }); - }, + } @discourseComputed("model.data", "model.computedLabels") totalsForSampleRow(rows, labels) { @@ -98,7 +102,7 @@ export default Component.extend({ }); return totalsRow; - }, + } @discourseComputed("sortLabel", "sortDirection", "model.data.[]") sortedData(sortLabel, sortDirection, data) { @@ -118,7 +122,7 @@ export default Component.extend({ } return data; - }, + } @discourseComputed("sortedData.[]", "perPage", "page") paginatedData(data, perPage, page) { @@ -128,7 +132,7 @@ export default Component.extend({ } return data; - }, + } @discourseComputed("model.data", "perPage", "page") pages(data, perPage, page) { @@ -156,19 +160,19 @@ export default Component.extend({ } return pages; - }, + } - actions: { - changePage(page) { - this.set("page", page); - }, + @action + changePage(page) { + this.set("page", page); + } - sortByLabel(label) { - if (this.sortLabel === label) { - this.set("sortDirection", this.sortDirection === 1 ? -1 : 1); - } else { - this.set("sortLabel", label); - } - }, - }, -}); + @action + sortByLabel(label) { + if (this.sortLabel === label) { + this.set("sortDirection", this.sortDirection === 1 ? -1 : 1); + } else { + this.set("sortLabel", label); + } + } +} diff --git a/app/assets/javascripts/admin/addon/components/admin-report-trust-level-counts.js b/app/assets/javascripts/admin/addon/components/admin-report-trust-level-counts.js index 7f039c061e1..6da6a748934 100644 --- a/app/assets/javascripts/admin/addon/components/admin-report-trust-level-counts.js +++ b/app/assets/javascripts/admin/addon/components/admin-report-trust-level-counts.js @@ -1,4 +1,5 @@ +import { tagName } from "@ember-decorators/component"; import Component from "@ember/component"; -export default Component.extend({ - tagName: "tr", -}); + +@tagName("tr") +export default class AdminReportTrustLevelCounts extends Component {} diff --git a/app/assets/javascripts/admin/addon/components/admin-report.js b/app/assets/javascripts/admin/addon/components/admin-report.js index 9f60e09a257..fede9cc2d60 100644 --- a/app/assets/javascripts/admin/addon/components/admin-report.js +++ b/app/assets/javascripts/admin/addon/components/admin-report.js @@ -1,6 +1,7 @@ +import { classNameBindings, classNames } from "@ember-decorators/component"; +import { alias, and, equal, notEmpty, or } from "@ember/object/computed"; import EmberObject, { action, computed } from "@ember/object"; import Report, { DAILY_LIMIT_DAYS, SCHEMA_VERSION } from "admin/models/report"; -import { alias, and, equal, notEmpty, or } from "@ember/object/computed"; import Component from "@ember/component"; import I18n from "I18n"; import ReportLoader from "discourse/lib/reports-loader"; @@ -21,51 +22,58 @@ const TABLE_OPTIONS = { const CHART_OPTIONS = {}; -export default Component.extend({ - classNameBindings: [ - "isHidden:hidden", - "isHidden::is-visible", - "isEnabled", - "isLoading", - "dasherizedDataSourceName", - ], - classNames: ["admin-report"], - isEnabled: true, - disabledLabel: I18n.t("admin.dashboard.disabled"), - isLoading: false, - rateLimitationString: null, - dataSourceName: null, - report: null, - model: null, - reportOptions: null, - forcedModes: null, - showAllReportsLink: false, - filters: null, - showTrend: false, - showHeader: true, - showTitle: true, - showFilteringUI: false, - showDatesOptions: alias("model.dates_filtering"), - showRefresh: or("showDatesOptions", "model.available_filters.length"), - shouldDisplayTrend: and("showTrend", "model.prev_period"), - endDate: null, - startDate: null, +@classNameBindings( + "isHidden:hidden", + "isHidden::is-visible", + "isEnabled", + "isLoading", + "dasherizedDataSourceName" +) +@classNames("admin-report") +export default class AdminReport extends Component { + isEnabled = true; + disabledLabel = I18n.t("admin.dashboard.disabled"); + isLoading = false; + rateLimitationString = null; + dataSourceName = null; + report = null; + model = null; + reportOptions = null; + forcedModes = null; + showAllReportsLink = false; + filters = null; + showTrend = false; + showHeader = true; + showTitle = true; + showFilteringUI = false; - init() { - this._super(...arguments); + @alias("model.dates_filtering") showDatesOptions; - this._reports = []; - }, + @or("showDatesOptions", "model.available_filters.length") showRefresh; - isHidden: computed("siteSettings.dashboard_hidden_reports", function () { + @and("showTrend", "model.prev_period") shouldDisplayTrend; + + endDate = null; + startDate = null; + + @or("showTimeoutError", "showExceptionError", "showNotFoundError") showError; + @equal("model.error", "not_found") showNotFoundError; + @equal("model.error", "timeout") showTimeoutError; + @equal("model.error", "exception") showExceptionError; + @notEmpty("model.data") hasData; + + _reports = []; + + @computed("siteSettings.dashboard_hidden_reports") + get isHidden() { return (this.siteSettings.dashboard_hidden_reports || "") .split("|") .filter(Boolean) .includes(this.dataSourceName); - }), + } didReceiveAttrs() { - this._super(...arguments); + super.didReceiveAttrs(...arguments); let startDate = moment(); if (this.filters && isPresent(this.filters.startDate)) { @@ -88,42 +96,35 @@ export default Component.extend({ } else if (this.dataSourceName) { this._fetchReport(); } - }, - - showError: or("showTimeoutError", "showExceptionError", "showNotFoundError"), - showNotFoundError: equal("model.error", "not_found"), - showTimeoutError: equal("model.error", "timeout"), - showExceptionError: equal("model.error", "exception"), - - hasData: notEmpty("model.data"), + } @discourseComputed("dataSourceName", "model.type") dasherizedDataSourceName(dataSourceName, type) { return (dataSourceName || type || "undefined").replace(/_/g, "-"); - }, + } @discourseComputed("dataSourceName", "model.type") dataSource(dataSourceName, type) { dataSourceName = dataSourceName || type; return `/admin/reports/${dataSourceName}`; - }, + } @discourseComputed("displayedModes.length") showModes(displayedModesLength) { return displayedModesLength > 1; - }, + } @discourseComputed("currentMode") isChartMode(currentMode) { return currentMode === "chart"; - }, + } @action changeGrouping(grouping) { this.send("refreshReport", { chartGrouping: grouping, }); - }, + } @discourseComputed("currentMode", "model.modes", "forcedModes") displayedModes(currentMode, reportModes, forcedModes) { @@ -139,12 +140,12 @@ export default Component.extend({ icon: mode === "table" ? "table" : "signal", }; }); - }, + } @discourseComputed("currentMode") modeComponent(currentMode) { return `admin-report-${currentMode.replace(/_/g, "-")}`; - }, + } @discourseComputed( "dataSourceName", @@ -178,7 +179,7 @@ export default Component.extend({ .join(":"); return reportKey; - }, + } @discourseComputed("options.chartGrouping", "model.chartData.length") chartGroupings(grouping, count) { @@ -192,7 +193,7 @@ export default Component.extend({ class: `chart-grouping ${grouping === id ? "active" : "inactive"}`, }; }); - }, + } @action onChangeDateRange(range) { @@ -200,7 +201,7 @@ export default Component.extend({ startDate: range.from, endDate: range.to, }); - }, + } @action applyFilter(id, value) { @@ -215,7 +216,7 @@ export default Component.extend({ this.send("refreshReport", { filters: customFilters, }); - }, + } @action refreshReport(options = {}) { @@ -238,7 +239,7 @@ export default Component.extend({ ? this.get("filters.customFilters") : options.filters, }); - }, + } @action exportCsv() { @@ -254,7 +255,7 @@ export default Component.extend({ } exportEntity("report", args).then(outputExportResult); - }, + } @action onChangeMode(mode) { @@ -263,7 +264,7 @@ export default Component.extend({ this.send("refreshReport", { chartGrouping: null, }); - }, + } _computeReport() { if (!this.element || this.isDestroying || this.isDestroyed) { @@ -306,7 +307,7 @@ export default Component.extend({ } this._renderReport(report, this.forcedModes, this.currentMode); - }, + } _renderReport(report, forcedModes, currentMode) { const modes = forcedModes ? forcedModes.split(",") : report.modes; @@ -317,11 +318,9 @@ export default Component.extend({ currentMode, options: this._buildOptions(currentMode, report), }); - }, + } _fetchReport() { - this._super(...arguments); - this.setProperties({ isLoading: true, rateLimitationString: null }); next(() => { @@ -349,7 +348,7 @@ export default Component.extend({ ReportLoader.enqueue(this.dataSourceName, payload.data, callback); }); - }, + } _buildPayload(facets) { let payload = { data: { facets } }; @@ -375,7 +374,7 @@ export default Component.extend({ } return payload; - }, + } _buildOptions(mode, report) { if (mode === "table") { @@ -393,7 +392,7 @@ export default Component.extend({ }) ); } - }, + } _loadReport(jsonReport) { Report.fillMissingDates(jsonReport, { filledField: "chartData" }); @@ -423,5 +422,5 @@ export default Component.extend({ } return Report.create(jsonReport); - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/admin-theme-editor.js b/app/assets/javascripts/admin/addon/components/admin-theme-editor.js index de8f0635791..7d3389902c1 100644 --- a/app/assets/javascripts/admin/addon/components/admin-theme-editor.js +++ b/app/assets/javascripts/admin/addon/components/admin-theme-editor.js @@ -6,8 +6,10 @@ import { isDocumentRTL } from "discourse/lib/text-direction"; import { action } from "@ember/object"; import { next } from "@ember/runloop"; -export default Component.extend({ - warning: null, +export default class AdminThemeEditor extends Component { + warning = null; + + @fmt("fieldName", "currentTargetName", "%@|%@") editorId; @discourseComputed("theme.targets", "onlyOverridden", "showAdvanced") visibleTargets(targets, onlyOverridden, showAdvanced) { @@ -20,7 +22,7 @@ export default Component.extend({ } return target.edited; }); - }, + } @discourseComputed("currentTargetName", "onlyOverridden", "theme.fields") visibleFields(targetName, onlyOverridden, fields) { @@ -29,7 +31,7 @@ export default Component.extend({ fields = fields.filter((field) => field.edited); } return fields; - }, + } @discourseComputed("currentTargetName", "fieldName") activeSectionMode(targetName, fieldName) { @@ -43,7 +45,7 @@ export default Component.extend({ return "scss"; } return fieldName && fieldName.includes("scss") ? "scss" : "html"; - }, + } @discourseComputed("currentTargetName", "fieldName") placeholder(targetName, fieldName) { @@ -58,30 +60,27 @@ export default Component.extend({ }); } return ""; - }, + } @discourseComputed("fieldName", "currentTargetName", "theme") - activeSection: { - get(fieldName, target, model) { - return model.getField(target, fieldName); - }, - set(value, fieldName, target, model) { - model.setField(target, fieldName, value); - return value; - }, - }, + get activeSection() { + return this.model.getField(this.currentTargetName, this.fieldName); + } - editorId: fmt("fieldName", "currentTargetName", "%@|%@"), + set activeSection(value) { + this.theme.setField(this.fieldName, value); + return value; + } @discourseComputed("maximized") maximizeIcon(maximized) { return maximized ? "discourse-compress" : "discourse-expand"; - }, + } @discourseComputed("currentTargetName", "theme.targets") showAddField(currentTargetName, targets) { return targets.find((t) => t.name === currentTargetName).customNames; - }, + } @discourseComputed( "currentTargetName", @@ -90,52 +89,55 @@ export default Component.extend({ ) error(target, fieldName) { return this.theme.getError(target, fieldName); - }, + } @action toggleShowAdvanced(event) { event?.preventDefault(); this.toggleProperty("showAdvanced"); - }, + } @action toggleAddField(event) { event?.preventDefault(); this.toggleProperty("addingField"); - }, + } @action toggleMaximize(event) { event?.preventDefault(); this.toggleProperty("maximized"); next(() => this.appEvents.trigger("ace:resize")); - }, + } - actions: { - cancelAddField() { - this.set("addingField", false); - }, + @action + cancelAddField() { + this.set("addingField", false); + } - addField(name) { - if (!name) { - return; - } - name = name.replace(/[^a-zA-Z0-9-_/]/g, ""); - this.theme.setField(this.currentTargetName, name, ""); - this.setProperties({ newFieldName: "", addingField: false }); - this.fieldAdded(this.currentTargetName, name); - }, + @action + addField(name) { + if (!name) { + return; + } + name = name.replace(/[^a-zA-Z0-9-_/]/g, ""); + this.theme.setField(this.currentTargetName, name, ""); + this.setProperties({ newFieldName: "", addingField: false }); + this.fieldAdded(this.currentTargetName, name); + } - onlyOverriddenChanged(value) { - this.onlyOverriddenChanged(value); - }, + @action + onlyOverriddenChanged(value) { + this.onlyOverriddenChanged(value); + } - save() { - this.attrs.save(); - }, + @action + save() { + this.attrs.save(); + } - setWarning(message) { - this.set("warning", message); - }, - }, -}); + @action + setWarning(message) { + this.set("warning", message); + } +} diff --git a/app/assets/javascripts/admin/addon/components/admin-watched-word.js b/app/assets/javascripts/admin/addon/components/admin-watched-word.js index 7de7e3d8ab5..d6bde8016d2 100644 --- a/app/assets/javascripts/admin/addon/components/admin-watched-word.js +++ b/app/assets/javascripts/admin/addon/components/admin-watched-word.js @@ -1,23 +1,27 @@ -import Component from "@ember/component"; +import { classNames } from "@ember-decorators/component"; +import { inject as service } from "@ember/service"; import { alias, equal } from "@ember/object/computed"; +import Component from "@ember/component"; import discourseComputed from "discourse-common/utils/decorators"; import { action } from "@ember/object"; import I18n from "I18n"; -import { inject as service } from "@ember/service"; -export default Component.extend({ - classNames: ["watched-word"], - dialog: service(), +@classNames("watched-word") +export default class AdminWatchedWord extends Component { + @service dialog; - isReplace: equal("actionKey", "replace"), - isTag: equal("actionKey", "tag"), - isLink: equal("actionKey", "link"), - isCaseSensitive: alias("word.case_sensitive"), + @equal("actionKey", "replace") isReplace; + + @equal("actionKey", "tag") isTag; + + @equal("actionKey", "link") isLink; + + @alias("word.case_sensitive") isCaseSensitive; @discourseComputed("word.replacement") tags(replacement) { return replacement.split(","); - }, + } @action deleteWord() { @@ -33,5 +37,5 @@ export default Component.extend({ }) ); }); - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/admin-wrapper.js b/app/assets/javascripts/admin/addon/components/admin-wrapper.js index d6a3564d420..98d18997d4f 100644 --- a/app/assets/javascripts/admin/addon/components/admin-wrapper.js +++ b/app/assets/javascripts/admin/addon/components/admin-wrapper.js @@ -1,14 +1,15 @@ import Component from "@ember/component"; -export default Component.extend({ + +export default class AdminWrapper extends Component { didInsertElement() { - this._super(...arguments); + super.didInsertElement(...arguments); document.querySelector("html").classList.add("admin-area"); document.querySelector("body").classList.add("admin-interface"); - }, + } willDestroyElement() { - this._super(...arguments); + super.willDestroyElement(...arguments); document.querySelector("html").classList.remove("admin-area"); document.querySelector("body").classList.remove("admin-interface"); - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/cancel-link.js b/app/assets/javascripts/admin/addon/components/cancel-link.js index 0e6d50b17d4..aa5d4dda65c 100644 --- a/app/assets/javascripts/admin/addon/components/cancel-link.js +++ b/app/assets/javascripts/admin/addon/components/cancel-link.js @@ -1,4 +1,5 @@ +import { tagName } from "@ember-decorators/component"; import Component from "@ember/component"; -export default Component.extend({ - tagName: "", -}); + +@tagName("") +export default class CancelLink extends Component {} diff --git a/app/assets/javascripts/admin/addon/components/color-input.js b/app/assets/javascripts/admin/addon/components/color-input.js index 2974b43871a..662b6eb714b 100644 --- a/app/assets/javascripts/admin/addon/components/color-input.js +++ b/app/assets/javascripts/admin/addon/components/color-input.js @@ -1,3 +1,4 @@ +import { classNames } from "@ember-decorators/component"; import { action, computed } from "@ember/object"; import Component from "@ember/component"; import { observes } from "discourse-common/utils/decorators"; @@ -9,20 +10,20 @@ import { observes } from "discourse-common/utils/decorators"; @param brightnessValue is a number from 0 to 255 representing the brightness of the color. See ColorSchemeColor. @params valid is a boolean indicating if the input field is a valid color. **/ -export default Component.extend({ - classNames: ["color-picker"], +@classNames("color-picker") +export default class ColorInput extends Component { + onlyHex = true; + styleSelection = true; - onlyHex: true, - - styleSelection: true, - - maxlength: computed("onlyHex", function () { + @computed("onlyHex") + get maxlength() { return this.onlyHex ? 6 : null; - }), + } - normalizedHexValue: computed("hexValue", function () { + @computed("hexValue") + get normalizedHexValue() { return this.normalize(this.hexValue); - }), + } normalize(color) { if (this._valid(color)) { @@ -40,19 +41,19 @@ export default Component.extend({ } } return color; - }, + } @action onHexInput(color) { if (this.attrs.onChangeColor) { this.attrs.onChangeColor(this.normalize(color || "")); } - }, + } @action onPickerInput(event) { this.set("hexValue", event.target.value.replace("#", "")); - }, + } @observes("hexValue", "brightnessValue", "valid") hexValueChanged() { @@ -65,9 +66,9 @@ export default Component.extend({ if (this._valid()) { this.element.querySelector(".picker").value = this.normalize(hex); } - }, + } _valid(color = this.hexValue) { return /^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(color); - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/dashboard-new-feature-item.js b/app/assets/javascripts/admin/addon/components/dashboard-new-feature-item.js index 87d5ddb040f..80e6cd8a167 100644 --- a/app/assets/javascripts/admin/addon/components/dashboard-new-feature-item.js +++ b/app/assets/javascripts/admin/addon/components/dashboard-new-feature-item.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class DashboardNewFeatureItem extends Component {} diff --git a/app/assets/javascripts/admin/addon/components/dashboard-new-features.js b/app/assets/javascripts/admin/addon/components/dashboard-new-features.js index 6e8defb93c4..46b7559585b 100644 --- a/app/assets/javascripts/admin/addon/components/dashboard-new-features.js +++ b/app/assets/javascripts/admin/addon/components/dashboard-new-features.js @@ -1,18 +1,19 @@ +import { classNameBindings, classNames } from "@ember-decorators/component"; import Component from "@ember/component"; import { action, computed } from "@ember/object"; import { ajax } from "discourse/lib/ajax"; -export default Component.extend({ - newFeatures: null, - classNames: ["section", "dashboard-new-features"], - classNameBindings: ["hasUnseenFeatures:ordered-first"], - releaseNotesLink: null, +@classNames("section", "dashboard-new-features") +@classNameBindings("hasUnseenFeatures:ordered-first") +export default class DashboardNewFeatures extends Component { + newFeatures = null; + releaseNotesLink = null; - init() { - this._super(...arguments); + constructor() { + super(...arguments); ajax("/admin/dashboard/new-features.json").then((json) => { - if (!this.element || this.isDestroying || this.isDestroyed) { + if (this.isDestroying || this.isDestroyed) { return; } @@ -22,16 +23,17 @@ export default Component.extend({ releaseNotesLink: json.release_notes_link, }); }); - }, + } - columnCountClass: computed("newFeatures", function () { + @computed("newFeatures") + get columnCountClass() { return this.newFeatures.length > 2 ? "three-or-more-items" : ""; - }), + } @action dismissNewFeatures() { ajax("/admin/dashboard/mark-new-features-as-seen.json", { type: "PUT", }).then(() => this.set("hasUnseenFeatures", false)); - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/dashboard-problems.js b/app/assets/javascripts/admin/addon/components/dashboard-problems.js index 87d5ddb040f..c4df8401e0f 100644 --- a/app/assets/javascripts/admin/addon/components/dashboard-problems.js +++ b/app/assets/javascripts/admin/addon/components/dashboard-problems.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class DashboardProblems extends Component {} diff --git a/app/assets/javascripts/admin/addon/components/email-styles-editor.js b/app/assets/javascripts/admin/addon/components/email-styles-editor.js index 48621b41cf3..a3d2fe55941 100644 --- a/app/assets/javascripts/admin/addon/components/email-styles-editor.js +++ b/app/assets/javascripts/admin/addon/components/email-styles-editor.js @@ -1,17 +1,19 @@ +import { action, computed } from "@ember/object"; +import { inject as service } from "@ember/service"; +import { reads } from "@ember/object/computed"; import Component from "@ember/component"; import I18n from "I18n"; import discourseComputed from "discourse-common/utils/decorators"; -import { reads } from "@ember/object/computed"; -import { inject as service } from "@ember/service"; -export default Component.extend({ - dialog: service(), - editorId: reads("fieldName"), +export default class EmailStylesEditor extends Component { + @service dialog; + + @reads("fieldName") editorId; @discourseComputed("fieldName") currentEditorMode(fieldName) { return fieldName === "css" ? "scss" : fieldName; - }, + } @discourseComputed("fieldName", "styles.html", "styles.css") resetDisabled(fieldName) { @@ -19,36 +21,36 @@ export default Component.extend({ this.get(`styles.${fieldName}`) === this.get(`styles.default_${fieldName}`) ); - }, + } - @discourseComputed("styles", "fieldName") - editorContents: { - get(styles, fieldName) { - return styles[fieldName]; - }, - set(value, styles, fieldName) { - styles.setField(fieldName, value); - return value; - }, - }, + @computed("styles", "fieldName") + get editorContents() { + return this.styles[this.fieldName]; + } - actions: { - reset() { - this.dialog.yesNoConfirm({ - message: I18n.t("admin.customize.email_style.reset_confirm", { - fieldName: I18n.t(`admin.customize.email_style.${this.fieldName}`), - }), - didConfirm: () => { - this.styles.setField( - this.fieldName, - this.styles.get(`default_${this.fieldName}`) - ); - this.notifyPropertyChange("editorContents"); - }, - }); - }, - save() { - this.attrs.save(); - }, - }, -}); + set editorContents(value) { + this.styles.setField(this.fieldName, value); + return value; + } + + @action + reset() { + this.dialog.yesNoConfirm({ + message: I18n.t("admin.customize.email_style.reset_confirm", { + fieldName: I18n.t(`admin.customize.email_style.${this.fieldName}`), + }), + didConfirm: () => { + this.styles.setField( + this.fieldName, + this.styles.get(`default_${this.fieldName}`) + ); + this.notifyPropertyChange("editorContents"); + }, + }); + } + + @action + save() { + this.attrs.save(); + } +} diff --git a/app/assets/javascripts/admin/addon/components/embeddable-host.js b/app/assets/javascripts/admin/addon/components/embeddable-host.js index 320b173bfb5..54e9d102a4a 100644 --- a/app/assets/javascripts/admin/addon/components/embeddable-host.js +++ b/app/assets/javascripts/admin/addon/components/embeddable-host.js @@ -1,85 +1,91 @@ +import { action } from "@ember/object"; +import { tagName } from "@ember-decorators/component"; +import { inject as service } from "@ember/service"; +import { or } from "@ember/object/computed"; import Category from "discourse/models/category"; import Component from "@ember/component"; import I18n from "I18n"; import { bufferedProperty } from "discourse/mixins/buffered-content"; import discourseComputed from "discourse-common/utils/decorators"; -import { inject as service } from "@ember/service"; import { isEmpty } from "@ember/utils"; -import { or } from "@ember/object/computed"; import { popupAjaxError } from "discourse/lib/ajax-error"; -export default Component.extend(bufferedProperty("host"), { - editToggled: false, - tagName: "tr", - categoryId: null, - category: null, - dialog: service(), +@tagName("tr") +export default class EmbeddableHost extends Component.extend( + bufferedProperty("host") +) { + @service dialog; + editToggled = false; + categoryId = null; + category = null; - editing: or("host.isNew", "editToggled"), + @or("host.isNew", "editToggled") editing; - init() { - this._super(...arguments); + constructor() { + super(...arguments); const host = this.host; const categoryId = host.category_id || this.site.uncategorized_category_id; const category = Category.findById(categoryId); host.set("category", category); - }, + } @discourseComputed("buffered.host", "host.isSaving") cantSave(host, isSaving) { return isSaving || isEmpty(host); - }, + } - actions: { - edit() { - this.set("categoryId", this.get("host.category.id")); - this.set("editToggled", true); - }, + @action + edit() { + this.set("categoryId", this.get("host.category.id")); + this.set("editToggled", true); + } - save() { - if (this.cantSave) { - return; - } + @action + save() { + if (this.cantSave) { + return; + } - const props = this.buffered.getProperties( - "host", - "allowed_paths", - "class_name" - ); - props.category_id = this.categoryId; + const props = this.buffered.getProperties( + "host", + "allowed_paths", + "class_name" + ); + props.category_id = this.categoryId; - const host = this.host; + const host = this.host; - host - .save(props) - .then(() => { - host.set("category", Category.findById(this.categoryId)); - this.set("editToggled", false); - }) - .catch(popupAjaxError); - }, - - delete() { - return this.dialog.confirm({ - message: I18n.t("admin.embedding.confirm_delete"), - didConfirm: () => { - return this.host.destroyRecord().then(() => { - this.deleteHost(this.host); - }); - }, - }); - }, - - cancel() { - const host = this.host; - if (host.get("isNew")) { - this.deleteHost(host); - } else { - this.rollbackBuffer(); + host + .save(props) + .then(() => { + host.set("category", Category.findById(this.categoryId)); this.set("editToggled", false); - } - }, - }, -}); + }) + .catch(popupAjaxError); + } + + @action + delete() { + return this.dialog.confirm({ + message: I18n.t("admin.embedding.confirm_delete"), + didConfirm: () => { + return this.host.destroyRecord().then(() => { + this.deleteHost(this.host); + }); + }, + }); + } + + @action + cancel() { + const host = this.host; + if (host.get("isNew")) { + this.deleteHost(host); + } else { + this.rollbackBuffer(); + this.set("editToggled", false); + } + } +} diff --git a/app/assets/javascripts/admin/addon/components/embedding-setting.js b/app/assets/javascripts/admin/addon/components/embedding-setting.js index f571d47cf61..ab6e91fa6a3 100644 --- a/app/assets/javascripts/admin/addon/components/embedding-setting.js +++ b/app/assets/javascripts/admin/addon/components/embedding-setting.js @@ -1,33 +1,33 @@ +import { classNames } from "@ember-decorators/component"; +import { computed } from "@ember/object"; import Component from "@ember/component"; import discourseComputed from "discourse-common/utils/decorators"; import { dasherize } from "@ember/string"; -export default Component.extend({ - classNames: ["embed-setting"], - +@classNames("embed-setting") +export default class EmbeddingSetting extends Component { @discourseComputed("field") inputId(field) { return dasherize(field); - }, + } @discourseComputed("field") translationKey(field) { return `admin.embedding.${field}`; - }, + } @discourseComputed("type") isCheckbox(type) { return type === "checkbox"; - }, + } - @discourseComputed("value") - checked: { - get(value) { - return !!value; - }, - set(value) { - this.set("value", value); - return value; - }, - }, -}); + @computed("value") + get checked() { + return !!this.value; + } + + set(value) { + this.set("value", value); + return value; + } +} diff --git a/app/assets/javascripts/admin/addon/components/emoji-value-list.js b/app/assets/javascripts/admin/addon/components/emoji-value-list.js index 3f2810383d0..40363b874d8 100644 --- a/app/assets/javascripts/admin/addon/components/emoji-value-list.js +++ b/app/assets/javascripts/admin/addon/components/emoji-value-list.js @@ -1,3 +1,4 @@ +import { classNameBindings } from "@ember-decorators/component"; import Component from "@ember/component"; import I18n from "I18n"; import discourseComputed from "discourse-common/utils/decorators"; @@ -6,12 +7,12 @@ import { action, set, setProperties } from "@ember/object"; import { schedule } from "@ember/runloop"; import discourseLater from "discourse-common/lib/later"; -export default Component.extend({ - classNameBindings: [":value-list", ":emoji-list"], - values: null, - validationMessage: null, - emojiPickerIsActive: false, - isEditorFocused: false, +@classNameBindings(":value-list", ":emoji-list") +export default class EmojiValueList extends Component { + values = null; + validationMessage = null; + emojiPickerIsActive = false; + isEditorFocused = false; @discourseComputed("values") collection(values) { @@ -28,14 +29,14 @@ export default Component.extend({ emojiUrl: emojiUrlFor(value), }; }); - }, + } @action closeEmojiPicker() { this.collection.setEach("isEditing", false); this.set("emojiPickerIsActive", false); this.set("isEditorFocused", false); - }, + } @action emojiSelected(code) { @@ -65,12 +66,12 @@ export default Component.extend({ this.set("emojiPickerIsActive", false); this.set("isEditorFocused", false); - }, + } @discourseComputed("collection") showUpDownButtons(collection) { return collection.length - 1 ? true : false; - }, + } _splitValues(values) { if (values && values.length) { @@ -91,7 +92,7 @@ export default Component.extend({ } else { return []; } - }, + } @action editValue(index) { @@ -111,12 +112,12 @@ export default Component.extend({ } }, 100); }); - }, + } @action removeValue(value) { this._removeValue(value); - }, + } @action shift(operation, index) { @@ -133,7 +134,7 @@ export default Component.extend({ this.collection.insertAt(futureIndex, shiftedEmoji); this._saveValues(); - }, + } _validateInput(input) { this.set("validationMessage", null); @@ -147,12 +148,12 @@ export default Component.extend({ } return true; - }, + } _removeValue(value) { this.collection.removeObject(value); this._saveValues(); - }, + } _replaceValue(index, newValue) { const item = this.collection[index]; @@ -161,9 +162,9 @@ export default Component.extend({ } set(item, "value", newValue); this._saveValues(); - }, + } _saveValues() { this.set("values", this.collection.mapBy("value").join("|")); - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/flag-user-lists.js b/app/assets/javascripts/admin/addon/components/flag-user-lists.js index 8b886047689..0096ce0a575 100644 --- a/app/assets/javascripts/admin/addon/components/flag-user-lists.js +++ b/app/assets/javascripts/admin/addon/components/flag-user-lists.js @@ -1,4 +1,5 @@ +import { classNames } from "@ember-decorators/component"; import Component from "@ember/component"; -export default Component.extend({ - classNames: ["flag-user-lists"], -}); + +@classNames("flag-user-lists") +export default class FlagUserLists extends Component {} diff --git a/app/assets/javascripts/admin/addon/components/flag-user.js b/app/assets/javascripts/admin/addon/components/flag-user.js index 87d5ddb040f..ef9b83f7803 100644 --- a/app/assets/javascripts/admin/addon/components/flag-user.js +++ b/app/assets/javascripts/admin/addon/components/flag-user.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class FlagUser extends Component {} diff --git a/app/assets/javascripts/admin/addon/components/highlighted-code.js b/app/assets/javascripts/admin/addon/components/highlighted-code.js index 21cfaf6b154..5f0331fac5c 100644 --- a/app/assets/javascripts/admin/addon/components/highlighted-code.js +++ b/app/assets/javascripts/admin/addon/components/highlighted-code.js @@ -2,10 +2,10 @@ import { observes, on } from "discourse-common/utils/decorators"; import Component from "@ember/component"; import highlightSyntax from "discourse/lib/highlight-syntax"; -export default Component.extend({ +export default class HighlightedCode extends Component { @on("didInsertElement") @observes("code") _refresh() { highlightSyntax(this.element, this.siteSettings, this.session); - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/inline-edit-checkbox.js b/app/assets/javascripts/admin/addon/components/inline-edit-checkbox.js index cfbd2f82f98..8618e4044b4 100644 --- a/app/assets/javascripts/admin/addon/components/inline-edit-checkbox.js +++ b/app/assets/javascripts/admin/addon/components/inline-edit-checkbox.js @@ -1,15 +1,15 @@ +import { classNames } from "@ember-decorators/component"; import Component from "@ember/component"; import { action } from "@ember/object"; import discourseComputed from "discourse-common/utils/decorators"; -export default Component.extend({ - classNames: ["inline-edit"], - - buffer: null, - bufferModelId: null, +@classNames("inline-edit") +export default class InlineEditCheckbox extends Component { + buffer = null; + bufferModelId = null; didReceiveAttrs() { - this._super(...arguments); + super.didReceiveAttrs(...arguments); if (this.modelId !== this.bufferModelId) { // HACK: The condition above ensures this method is called only when its @@ -24,21 +24,21 @@ export default Component.extend({ bufferModelId: this.modelId, }); } - }, + } @discourseComputed("checked", "buffer") changed(checked, buffer) { return !!checked !== !!buffer; - }, + } @action apply() { this.set("checked", this.buffer); this.action(); - }, + } @action cancel() { this.set("buffer", this.checked); - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/install-theme-item.js b/app/assets/javascripts/admin/addon/components/install-theme-item.js index b8d8823109d..459dc5dc673 100644 --- a/app/assets/javascripts/admin/addon/components/install-theme-item.js +++ b/app/assets/javascripts/admin/addon/components/install-theme-item.js @@ -1,4 +1,5 @@ +import { classNames } from "@ember-decorators/component"; import Component from "@ember/component"; -export default Component.extend({ - classNames: ["install-theme-item"], -}); + +@classNames("install-theme-item") +export default class InstallThemeItem extends Component {} diff --git a/app/assets/javascripts/admin/addon/components/ip-lookup.js b/app/assets/javascripts/admin/addon/components/ip-lookup.js index 02a52405645..42c5f128116 100644 --- a/app/assets/javascripts/admin/addon/components/ip-lookup.js +++ b/app/assets/javascripts/admin/addon/components/ip-lookup.js @@ -1,3 +1,5 @@ +import { classNames } from "@ember-decorators/component"; +import { inject as service } from "@ember/service"; import AdminUser from "admin/models/admin-user"; import Component from "@ember/component"; import EmberObject, { action } from "@ember/object"; @@ -6,12 +8,11 @@ import { ajax } from "discourse/lib/ajax"; import copyText from "discourse/lib/copy-text"; import discourseComputed from "discourse-common/utils/decorators"; import discourseLater from "discourse-common/lib/later"; -import { inject as service } from "@ember/service"; import { popupAjaxError } from "discourse/lib/ajax-error"; -export default Component.extend({ - classNames: ["ip-lookup"], - dialog: service(), +@classNames("ip-lookup") +export default class IpLookup extends Component { + @service dialog; @discourseComputed("other_accounts.length", "totalOthersWithSameIP") otherAccountsToDelete(otherAccountsLength, totalOthersWithSameIP) { @@ -19,101 +20,100 @@ export default Component.extend({ const total = Math.min(50, totalOthersWithSameIP || 0); const visible = Math.min(50, otherAccountsLength || 0); return Math.max(visible, total); - }, + } @action hide(event) { event?.preventDefault(); this.set("show", false); - }, + } - actions: { - lookup() { - this.set("show", true); + @action + lookup() { + this.set("show", true); - if (!this.location) { - ajax("/admin/users/ip-info", { - data: { ip: this.ip }, - }).then((location) => - this.set("location", EmberObject.create(location)) - ); - } + if (!this.location) { + ajax("/admin/users/ip-info", { + data: { ip: this.ip }, + }).then((location) => this.set("location", EmberObject.create(location))); + } - if (!this.other_accounts) { - this.set("otherAccountsLoading", true); + if (!this.other_accounts) { + this.set("otherAccountsLoading", true); - const data = { - ip: this.ip, - exclude: this.userId, - order: "trust_level DESC", - }; + const data = { + ip: this.ip, + exclude: this.userId, + order: "trust_level DESC", + }; - ajax("/admin/users/total-others-with-same-ip", { - data, - }).then((result) => this.set("totalOthersWithSameIP", result.total)); + ajax("/admin/users/total-others-with-same-ip", { + data, + }).then((result) => this.set("totalOthersWithSameIP", result.total)); - AdminUser.findAll("active", data).then((users) => { - this.setProperties({ - other_accounts: users, - otherAccountsLoading: false, - }); + AdminUser.findAll("active", data).then((users) => { + this.setProperties({ + other_accounts: users, + otherAccountsLoading: false, }); - } - }, - - copy() { - let text = `IP: ${this.ip}\n`; - const location = this.location; - if (location) { - if (location.hostname) { - text += `${I18n.t("ip_lookup.hostname")}: ${location.hostname}\n`; - } - - text += I18n.t("ip_lookup.location"); - if (location.location) { - text += `: ${location.location}\n`; - } else { - text += `: ${I18n.t("ip_lookup.location_not_found")}\n`; - } - - if (location.organization) { - text += I18n.t("ip_lookup.organisation"); - text += `: ${location.organization}\n`; - } - } - - const $copyRange = $('

'); - $copyRange.html(text.trim().replace(/\n/g, "
")); - $(document.body).append($copyRange); - if (copyText(text, $copyRange[0])) { - this.set("copied", true); - discourseLater(() => this.set("copied", false), 2000); - } - $copyRange.remove(); - }, - - deleteOtherAccounts() { - this.dialog.yesNoConfirm({ - message: I18n.t("ip_lookup.confirm_delete_other_accounts"), - didConfirm: () => { - this.setProperties({ - other_accounts: null, - otherAccountsLoading: true, - totalOthersWithSameIP: null, - }); - - ajax("/admin/users/delete-others-with-same-ip.json", { - type: "DELETE", - data: { - ip: this.ip, - exclude: this.userId, - order: "trust_level DESC", - }, - }) - .catch(popupAjaxError) - .finally(this.send("lookup")); - }, }); - }, - }, -}); + } + } + + @action + copy() { + let text = `IP: ${this.ip}\n`; + const location = this.location; + if (location) { + if (location.hostname) { + text += `${I18n.t("ip_lookup.hostname")}: ${location.hostname}\n`; + } + + text += I18n.t("ip_lookup.location"); + if (location.location) { + text += `: ${location.location}\n`; + } else { + text += `: ${I18n.t("ip_lookup.location_not_found")}\n`; + } + + if (location.organization) { + text += I18n.t("ip_lookup.organisation"); + text += `: ${location.organization}\n`; + } + } + + const $copyRange = $('

'); + $copyRange.html(text.trim().replace(/\n/g, "
")); + $(document.body).append($copyRange); + if (copyText(text, $copyRange[0])) { + this.set("copied", true); + discourseLater(() => this.set("copied", false), 2000); + } + $copyRange.remove(); + } + + @action + deleteOtherAccounts() { + this.dialog.yesNoConfirm({ + message: I18n.t("ip_lookup.confirm_delete_other_accounts"), + didConfirm: () => { + this.setProperties({ + other_accounts: null, + otherAccountsLoading: true, + totalOthersWithSameIP: null, + }); + + ajax("/admin/users/delete-others-with-same-ip.json", { + type: "DELETE", + data: { + ip: this.ip, + exclude: this.userId, + order: "trust_level DESC", + }, + }) + .catch(popupAjaxError) + .finally(this.send("lookup")); + }, + }); + } +} diff --git a/app/assets/javascripts/admin/addon/components/moderation-history-item.js b/app/assets/javascripts/admin/addon/components/moderation-history-item.js index 7f039c061e1..a94d4e65532 100644 --- a/app/assets/javascripts/admin/addon/components/moderation-history-item.js +++ b/app/assets/javascripts/admin/addon/components/moderation-history-item.js @@ -1,4 +1,5 @@ +import { tagName } from "@ember-decorators/component"; import Component from "@ember/component"; -export default Component.extend({ - tagName: "tr", -}); + +@tagName("tr") +export default class ModerationHistoryItem extends Component {} diff --git a/app/assets/javascripts/admin/addon/components/permalink-form.js b/app/assets/javascripts/admin/addon/components/permalink-form.js index 9c0c64de6b3..129ab0d58e4 100644 --- a/app/assets/javascripts/admin/addon/components/permalink-form.js +++ b/app/assets/javascripts/admin/addon/components/permalink-form.js @@ -1,3 +1,5 @@ +import { tagName } from "@ember-decorators/component"; +import { inject as service } from "@ember/service"; import Component from "@ember/component"; import I18n from "I18n"; import Permalink from "admin/models/permalink"; @@ -5,16 +7,18 @@ import discourseComputed, { bind } from "discourse-common/utils/decorators"; import { fmt } from "discourse/lib/computed"; import { schedule } from "@ember/runloop"; import { action } from "@ember/object"; -import { inject as service } from "@ember/service"; -export default Component.extend({ - tagName: "", - dialog: service(), - formSubmitted: false, - permalinkType: "topic_id", - permalinkTypePlaceholder: fmt("permalinkType", "admin.permalink.%@"), - action: null, - permalinkTypeValue: null, +@tagName("") +export default class PermalinkForm extends Component { + @service dialog; + + formSubmitted = false; + permalinkType = "topic_id"; + + @fmt("permalinkType", "admin.permalink.%@") permalinkTypePlaceholder; + + action = null; + permalinkTypeValue = null; @discourseComputed permalinkTypes() { @@ -25,21 +29,21 @@ export default Component.extend({ { id: "tag_name", name: I18n.t("admin.permalink.tag_name") }, { id: "external_url", name: I18n.t("admin.permalink.external_url") }, ]; - }, + } @bind focusPermalink() { schedule("afterRender", () => document.querySelector(".permalink-url")?.focus() ); - }, + } @action submitFormOnEnter(event) { if (event.key === "Enter") { this.onSubmit(); } - }, + } @action onSubmit() { @@ -84,5 +88,5 @@ export default Component.extend({ } ); } - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/report-filters/bool.js b/app/assets/javascripts/admin/addon/components/report-filters/bool.js index 544709791c0..d406b1e87e5 100644 --- a/app/assets/javascripts/admin/addon/components/report-filters/bool.js +++ b/app/assets/javascripts/admin/addon/components/report-filters/bool.js @@ -1,16 +1,16 @@ import FilterComponent from "admin/components/report-filters/filter"; import { action } from "@ember/object"; -export default FilterComponent.extend({ - checked: false, +export default class Bool extends FilterComponent { + checked = false; didReceiveAttrs() { - this._super(...arguments); + super.didReceiveAttrs(...arguments); this.set("checked", !!this.filter.default); - }, + } @action onChange() { this.applyFilter(this.filter.id, !this.checked || undefined); - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/report-filters/category.js b/app/assets/javascripts/admin/addon/components/report-filters/category.js index 877c3aee7a2..c32e99c50f7 100644 --- a/app/assets/javascripts/admin/addon/components/report-filters/category.js +++ b/app/assets/javascripts/admin/addon/components/report-filters/category.js @@ -1,12 +1,12 @@ +import { readOnly } from "@ember/object/computed"; import FilterComponent from "admin/components/report-filters/filter"; import { action } from "@ember/object"; -import { readOnly } from "@ember/object/computed"; -export default FilterComponent.extend({ - category: readOnly("filter.default"), +export default class Category extends FilterComponent { + @readOnly("filter.default") category; @action onChange(categoryId) { this.applyFilter(this.filter.id, categoryId || undefined); - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/report-filters/filter.js b/app/assets/javascripts/admin/addon/components/report-filters/filter.js index e89fb383865..697611d1ac5 100644 --- a/app/assets/javascripts/admin/addon/components/report-filters/filter.js +++ b/app/assets/javascripts/admin/addon/components/report-filters/filter.js @@ -1,9 +1,9 @@ import Component from "@ember/component"; import { action } from "@ember/object"; -export default Component.extend({ +export default class Filter extends Component { @action onChange(value) { this.applyFilter(this.filter.id, value); - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/report-filters/group.js b/app/assets/javascripts/admin/addon/components/report-filters/group.js index 30dd4c7b1b9..8ac7eb3b9a2 100644 --- a/app/assets/javascripts/admin/addon/components/report-filters/group.js +++ b/app/assets/javascripts/admin/addon/components/report-filters/group.js @@ -1,18 +1,18 @@ -import FilterComponent from "admin/components/report-filters/filter"; +import { classNames } from "@ember-decorators/component"; import { computed } from "@ember/object"; +import FilterComponent from "admin/components/report-filters/filter"; -export default FilterComponent.extend({ - classNames: ["group-filter"], - +@classNames("group-filter") +export default class Group extends FilterComponent { @computed get groupOptions() { return (this.site.groups || []).map((group) => { return { name: group["name"], value: group["id"] }; }); - }, + } @computed("filter.default") get groupId() { return this.filter.default ? parseInt(this.filter.default, 10) : null; - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/report-filters/list.js b/app/assets/javascripts/admin/addon/components/report-filters/list.js index 654269ecd00..7ecc076e96a 100644 --- a/app/assets/javascripts/admin/addon/components/report-filters/list.js +++ b/app/assets/javascripts/admin/addon/components/report-filters/list.js @@ -1,3 +1,3 @@ import FilterComponent from "admin/components/report-filters/filter"; -export default FilterComponent.extend(); +export default class List extends FilterComponent {} diff --git a/app/assets/javascripts/admin/addon/components/resumable-upload.js b/app/assets/javascripts/admin/addon/components/resumable-upload.js index 87d5ddb040f..abfa01ea018 100644 --- a/app/assets/javascripts/admin/addon/components/resumable-upload.js +++ b/app/assets/javascripts/admin/addon/components/resumable-upload.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class ResumableUpload extends Component {} diff --git a/app/assets/javascripts/admin/addon/components/screened-ip-address-form.hbs b/app/assets/javascripts/admin/addon/components/screened-ip-address-form.hbs index 99884ddb53e..bb8b58b4e01 100644 --- a/app/assets/javascripts/admin/addon/components/screened-ip-address-form.hbs +++ b/app/assets/javascripts/admin/addon/components/screened-ip-address-form.hbs @@ -17,7 +17,7 @@ \ No newline at end of file diff --git a/app/assets/javascripts/admin/addon/components/screened-ip-address-form.js b/app/assets/javascripts/admin/addon/components/screened-ip-address-form.js index ab553b6a213..fe7945dee79 100644 --- a/app/assets/javascripts/admin/addon/components/screened-ip-address-form.js +++ b/app/assets/javascripts/admin/addon/components/screened-ip-address-form.js @@ -1,9 +1,11 @@ +import { action } from "@ember/object"; +import { classNames, tagName } from "@ember-decorators/component"; +import { inject as service } from "@ember/service"; import discourseComputed from "discourse-common/utils/decorators"; import Component from "@ember/component"; import I18n from "I18n"; import ScreenedIpAddress from "admin/models/screened-ip-address"; import { schedule } from "@ember/runloop"; -import { inject as service } from "@ember/service"; /** A form to create an IP address that will be blocked or allowed. @@ -16,12 +18,13 @@ import { inject as service } from "@ember/service"; as an argument. **/ -export default Component.extend({ - tagName: "form", - dialog: service(), - classNames: ["screened-ip-address-form", "inline-form"], - formSubmitted: false, - actionName: "block", +@tagName("form") +@classNames("screened-ip-address-form", "inline-form") +export default class ScreenedIpAddressForm extends Component { + @service dialog; + + formSubmitted = false; + actionName = "block"; @discourseComputed("siteSettings.use_admin_ip_allowlist") actionNames(adminAllowlistEnabled) { @@ -46,43 +49,42 @@ export default Component.extend({ }, ]; } - }, + } focusInput() { schedule("afterRender", () => { this.element.querySelector("input").focus(); }); - }, + } - actions: { - submit() { - if (!this.formSubmitted) { - this.set("formSubmitted", true); - const screenedIpAddress = ScreenedIpAddress.create({ - ip_address: this.ip_address, - action_name: this.actionName, - }); - screenedIpAddress - .save() - .then((result) => { - this.setProperties({ ip_address: "", formSubmitted: false }); - this.action(ScreenedIpAddress.create(result.screened_ip_address)); - this.focusInput(); - }) - .catch((e) => { - this.set("formSubmitted", false); - const message = e.jqXHR.responseJSON?.errors - ? I18n.t("generic_error_with_reason", { - error: e.jqXHR.responseJSON.errors.join(". "), - }) - : I18n.t("generic_error"); - this.dialog.alert({ - message, - didConfirm: () => this.focusInput(), - didCancel: () => this.focusInput(), - }); + @action + submitForm() { + if (!this.formSubmitted) { + this.set("formSubmitted", true); + const screenedIpAddress = ScreenedIpAddress.create({ + ip_address: this.ip_address, + action_name: this.actionName, + }); + screenedIpAddress + .save() + .then((result) => { + this.setProperties({ ip_address: "", formSubmitted: false }); + this.action(ScreenedIpAddress.create(result.screened_ip_address)); + this.focusInput(); + }) + .catch((e) => { + this.set("formSubmitted", false); + const message = e.jqXHR.responseJSON?.errors + ? I18n.t("generic_error_with_reason", { + error: e.jqXHR.responseJSON.errors.join(". "), + }) + : I18n.t("generic_error"); + this.dialog.alert({ + message, + didConfirm: () => this.focusInput(), + didCancel: () => this.focusInput(), }); - } - }, - }, -}); + }); + } + } +} diff --git a/app/assets/javascripts/admin/addon/components/secret-value-list.js b/app/assets/javascripts/admin/addon/components/secret-value-list.js index 1f31dc40e2f..4530393fe57 100644 --- a/app/assets/javascripts/admin/addon/components/secret-value-list.js +++ b/app/assets/javascripts/admin/addon/components/secret-value-list.js @@ -1,15 +1,16 @@ +import { classNameBindings } from "@ember-decorators/component"; import Component from "@ember/component"; import I18n from "I18n"; import { isEmpty } from "@ember/utils"; import { on } from "discourse-common/utils/decorators"; -import { set } from "@ember/object"; +import { action, set } from "@ember/object"; -export default Component.extend({ - classNameBindings: [":value-list", ":secret-value-list"], - inputDelimiter: null, - collection: null, - values: null, - validationMessage: null, +@classNameBindings(":value-list", ":secret-value-list") +export default class SecretValueList extends Component { + inputDelimiter = null; + collection = null; + values = null; + validationMessage = null; @on("didReceiveAttrs") _setupCollection() { @@ -19,41 +20,43 @@ export default Component.extend({ "collection", this._splitValues(values, this.inputDelimiter || "\n") ); - }, + } - actions: { - changeKey(index, event) { - const newValue = event.target.value; + @action + changeKey(index, event) { + const newValue = event.target.value; - if (this._checkInvalidInput(newValue)) { - return; - } + if (this._checkInvalidInput(newValue)) { + return; + } - this._replaceValue(index, newValue, "key"); - }, + this._replaceValue(index, newValue, "key"); + } - changeSecret(index, event) { - const newValue = event.target.value; + @action + changeSecret(index, event) { + const newValue = event.target.value; - if (this._checkInvalidInput(newValue)) { - return; - } + if (this._checkInvalidInput(newValue)) { + return; + } - this._replaceValue(index, newValue, "secret"); - }, + this._replaceValue(index, newValue, "secret"); + } - addValue() { - if (this._checkInvalidInput([this.newKey, this.newSecret])) { - return; - } - this._addValue(this.newKey, this.newSecret); - this.setProperties({ newKey: "", newSecret: "" }); - }, + @action + addValue() { + if (this._checkInvalidInput([this.newKey, this.newSecret])) { + return; + } + this._addValue(this.newKey, this.newSecret); + this.setProperties({ newKey: "", newSecret: "" }); + } - removeValue(value) { - this._removeValue(value); - }, - }, + @action + removeValue(value) { + this._removeValue(value); + } _checkInvalidInput(inputs) { this.set("validationMessage", null); @@ -66,25 +69,25 @@ export default Component.extend({ return true; } } - }, + } _addValue(value, secret) { this.collection.addObject({ key: value, secret }); this._saveValues(); - }, + } _removeValue(value) { const collection = this.collection; collection.removeObject(value); this._saveValues(); - }, + } _replaceValue(index, newValue, keyName) { let item = this.collection[index]; set(item, keyName, newValue); this._saveValues(); - }, + } _saveValues() { this.set( @@ -95,7 +98,7 @@ export default Component.extend({ }) .join("\n") ); - }, + } _splitValues(values, delimiter) { if (values && values.length) { @@ -113,5 +116,5 @@ export default Component.extend({ } else { return []; } - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/setting-validation-message.js b/app/assets/javascripts/admin/addon/components/setting-validation-message.js index 87d5ddb040f..4e60ec9c884 100644 --- a/app/assets/javascripts/admin/addon/components/setting-validation-message.js +++ b/app/assets/javascripts/admin/addon/components/setting-validation-message.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class SettingValidationMessage extends Component {} diff --git a/app/assets/javascripts/admin/addon/components/silence-details.js b/app/assets/javascripts/admin/addon/components/silence-details.js index 0e6d50b17d4..b50edba07ee 100644 --- a/app/assets/javascripts/admin/addon/components/silence-details.js +++ b/app/assets/javascripts/admin/addon/components/silence-details.js @@ -1,4 +1,5 @@ +import { tagName } from "@ember-decorators/component"; import Component from "@ember/component"; -export default Component.extend({ - tagName: "", -}); + +@tagName("") +export default class SilenceDetails extends Component {} diff --git a/app/assets/javascripts/admin/addon/components/simple-list.js b/app/assets/javascripts/admin/addon/components/simple-list.js index 5ca219ee80f..d7e0bf69f32 100644 --- a/app/assets/javascripts/admin/addon/components/simple-list.js +++ b/app/assets/javascripts/admin/addon/components/simple-list.js @@ -1,34 +1,36 @@ +import { classNameBindings } from "@ember-decorators/component"; +import { empty } from "@ember/object/computed"; import Component from "@ember/component"; import { action } from "@ember/object"; -import { empty } from "@ember/object/computed"; import discourseComputed, { on } from "discourse-common/utils/decorators"; -export default Component.extend({ - classNameBindings: [":simple-list", ":value-list"], - inputEmpty: empty("newValue"), - inputDelimiter: null, - newValue: "", - collection: null, - values: null, +@classNameBindings(":simple-list", ":value-list") +export default class SimpleList extends Component { + @empty("newValue") inputEmpty; + + inputDelimiter = null; + newValue = ""; + collection = null; + values = null; @on("didReceiveAttrs") _setupCollection() { this.set("collection", this._splitValues(this.values, this.inputDelimiter)); - }, + } keyDown(event) { if (event.which === 13) { this.addValue(this.newValue); return; } - }, + } @action changeValue(index, event) { this.collection.replace(index, 1, [event.target.value]); this.collection.arrayContentDidChange(index); this._onChange(); - }, + } @action addValue(newValue) { @@ -39,13 +41,13 @@ export default Component.extend({ this.set("newValue", null); this.collection.addObject(newValue); this._onChange(); - }, + } @action removeValue(value) { this.collection.removeObject(value); this._onChange(); - }, + } @action shift(operation, index) { @@ -62,20 +64,20 @@ export default Component.extend({ this.collection.insertAt(futureIndex, shiftedValue); this._onChange(); - }, + } _onChange() { this.onChange?.(this.collection); - }, + } @discourseComputed("collection") showUpDownButtons(collection) { return collection.length - 1 ? true : false; - }, + } _splitValues(values, delimiter) { return values && values.length ? values.split(delimiter || "\n").filter(Boolean) : []; - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/site-customization-change-details.js b/app/assets/javascripts/admin/addon/components/site-customization-change-details.js index 87d5ddb040f..cb9487ad2b2 100644 --- a/app/assets/javascripts/admin/addon/components/site-customization-change-details.js +++ b/app/assets/javascripts/admin/addon/components/site-customization-change-details.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class SiteCustomizationChangeDetails extends Component {} diff --git a/app/assets/javascripts/admin/addon/components/site-customization-change-field.js b/app/assets/javascripts/admin/addon/components/site-customization-change-field.js index 87d5ddb040f..0e361124a0f 100644 --- a/app/assets/javascripts/admin/addon/components/site-customization-change-field.js +++ b/app/assets/javascripts/admin/addon/components/site-customization-change-field.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class SiteCustomizationChangeField extends Component {} diff --git a/app/assets/javascripts/admin/addon/components/site-setting.js b/app/assets/javascripts/admin/addon/components/site-setting.js index 888daa31176..f405a425285 100644 --- a/app/assets/javascripts/admin/addon/components/site-setting.js +++ b/app/assets/javascripts/admin/addon/components/site-setting.js @@ -1,18 +1,21 @@ +import { readOnly } from "@ember/object/computed"; import BufferedContent from "discourse/mixins/buffered-content"; import Component from "@ember/component"; import SettingComponent from "admin/mixins/setting-component"; import SiteSetting from "admin/models/site-setting"; -import { readOnly } from "@ember/object/computed"; -export default Component.extend(BufferedContent, SettingComponent, { - updateExistingUsers: null, +export default class SiteSettingComponent extends Component.extend( + BufferedContent, + SettingComponent +) { + updateExistingUsers = null; + + @readOnly("setting.staffLogFilter") staffLogFilter; _save() { const setting = this.buffered; return SiteSetting.update(setting.get("setting"), setting.get("value"), { updateExistingUsers: this.updateExistingUsers, }); - }, - - staffLogFilter: readOnly("setting.staffLogFilter"), -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/site-settings/bool.js b/app/assets/javascripts/admin/addon/components/site-settings/bool.js index 70d7c59ae00..8837213db27 100644 --- a/app/assets/javascripts/admin/addon/components/site-settings/bool.js +++ b/app/assets/javascripts/admin/addon/components/site-settings/bool.js @@ -1,19 +1,18 @@ +import { computed } from "@ember/object"; import Component from "@ember/component"; -import discourseComputed from "discourse-common/utils/decorators"; import { isEmpty } from "@ember/utils"; -export default Component.extend({ - @discourseComputed("value") - enabled: { - get(value) { - if (isEmpty(value)) { - return false; - } - return value.toString() === "true"; - }, - set(value) { - this.set("value", value ? "true" : "false"); - return value; - }, - }, -}); +export default class Bool extends Component { + @computed("value") + get enabled() { + if (isEmpty(this.value)) { + return false; + } + return this.value.toString() === "true"; + } + + set enabled(value) { + this.set("value", value ? "true" : "false"); + return value; + } +} diff --git a/app/assets/javascripts/admin/addon/components/site-settings/category-list.js b/app/assets/javascripts/admin/addon/components/site-settings/category-list.js index 9dc792e6de0..44fdee3a715 100644 --- a/app/assets/javascripts/admin/addon/components/site-settings/category-list.js +++ b/app/assets/javascripts/admin/addon/components/site-settings/category-list.js @@ -1,15 +1,15 @@ +import { action, computed } from "@ember/object"; import Category from "discourse/models/category"; import Component from "@ember/component"; -import { computed } from "@ember/object"; -export default Component.extend({ - selectedCategories: computed("value", function () { +export default class CategoryList extends Component { + @computed("value") + get selectedCategories() { return Category.findByIds(this.value.split("|").filter(Boolean)); - }), + } - actions: { - onChangeSelectedCategories(value) { - this.set("value", (value || []).mapBy("id").join("|")); - }, - }, -}); + @action + onChangeSelectedCategories(value) { + this.set("value", (value || []).mapBy("id").join("|")); + } +} diff --git a/app/assets/javascripts/admin/addon/components/site-settings/category.js b/app/assets/javascripts/admin/addon/components/site-settings/category.js index 87d5ddb040f..8e11b94d30d 100644 --- a/app/assets/javascripts/admin/addon/components/site-settings/category.js +++ b/app/assets/javascripts/admin/addon/components/site-settings/category.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class Category extends Component {} diff --git a/app/assets/javascripts/admin/addon/components/site-settings/color.js b/app/assets/javascripts/admin/addon/components/site-settings/color.js index 39df6da7d5e..a044348c0b2 100644 --- a/app/assets/javascripts/admin/addon/components/site-settings/color.js +++ b/app/assets/javascripts/admin/addon/components/site-settings/color.js @@ -24,8 +24,9 @@ function RGBToHex(rgb) { return "#" + r + g + b; } -export default Component.extend({ - valid: computed("value", function () { +export default class Color extends Component { + @computed("value") + get valid() { let value = this.value.toLowerCase(); let testColor = new Option().style; @@ -43,10 +44,10 @@ export default Component.extend({ } return testColor.color && hexifiedColor === value; - }), + } @action onChangeColor(color) { this.set("value", color); - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/site-settings/compact-list.js b/app/assets/javascripts/admin/addon/components/site-settings/compact-list.js index 246d56066a9..35d86e32dce 100644 --- a/app/assets/javascripts/admin/addon/components/site-settings/compact-list.js +++ b/app/assets/javascripts/admin/addon/components/site-settings/compact-list.js @@ -1,40 +1,36 @@ +import { action, computed } from "@ember/object"; import Component from "@ember/component"; -import { computed } from "@ember/object"; import { makeArray } from "discourse-common/lib/helpers"; -export default Component.extend({ - tokenSeparator: "|", +export default class CompactList extends Component { + tokenSeparator = "|"; + createdChoices = null; - createdChoices: null, - - settingValue: computed("value", function () { + @computed("value") + get settingValue() { return this.value.toString().split(this.tokenSeparator).filter(Boolean); - }), + } - settingChoices: computed( - "settingValue", - "setting.choices.[]", - "createdChoices.[]", - function () { - return [ - ...new Set([ - ...makeArray(this.settingValue), - ...makeArray(this.setting.choices), - ...makeArray(this.createdChoices), - ]), - ]; - } - ), + @computed("settingValue", "setting.choices.[]", "createdChoices.[]") + get settingChoices() { + return [ + ...new Set([ + ...makeArray(this.settingValue), + ...makeArray(this.setting.choices), + ...makeArray(this.createdChoices), + ]), + ]; + } - actions: { - onChangeListSetting(value) { - this.set("value", value.join(this.tokenSeparator)); - }, + @action + onChangeListSetting(value) { + this.set("value", value.join(this.tokenSeparator)); + } - onChangeChoices(choices) { - this.set("createdChoices", [ - ...new Set([...makeArray(this.createdChoices), ...makeArray(choices)]), - ]); - }, - }, -}); + @action + onChangeChoices(choices) { + this.set("createdChoices", [ + ...new Set([...makeArray(this.createdChoices), ...makeArray(choices)]), + ]); + } +} diff --git a/app/assets/javascripts/admin/addon/components/site-settings/emoji-list.js b/app/assets/javascripts/admin/addon/components/site-settings/emoji-list.js index 87d5ddb040f..706d6d80840 100644 --- a/app/assets/javascripts/admin/addon/components/site-settings/emoji-list.js +++ b/app/assets/javascripts/admin/addon/components/site-settings/emoji-list.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class EmojiList extends Component {} diff --git a/app/assets/javascripts/admin/addon/components/site-settings/enum.js b/app/assets/javascripts/admin/addon/components/site-settings/enum.js index 87d5ddb040f..faebe31c2d1 100644 --- a/app/assets/javascripts/admin/addon/components/site-settings/enum.js +++ b/app/assets/javascripts/admin/addon/components/site-settings/enum.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class Enum extends Component {} diff --git a/app/assets/javascripts/admin/addon/components/site-settings/group-list.js b/app/assets/javascripts/admin/addon/components/site-settings/group-list.js index ad9dbbfd1c5..e483afc3951 100644 --- a/app/assets/javascripts/admin/addon/components/site-settings/group-list.js +++ b/app/assets/javascripts/admin/addon/components/site-settings/group-list.js @@ -1,25 +1,25 @@ +import { action, computed } from "@ember/object"; import Component from "@ember/component"; -import { computed } from "@ember/object"; -export default Component.extend({ - tokenSeparator: "|", +export default class GroupList extends Component { + tokenSeparator = "|"; + nameProperty = "name"; + valueProperty = "id"; - nameProperty: "name", - valueProperty: "id", - - groupChoices: computed("site.groups", function () { + @computed("site.groups") + get groupChoices() { return (this.site.groups || []).map((g) => { return { name: g.name, id: g.id.toString() }; }); - }), + } - settingValue: computed("value", function () { + @computed("value") + get settingValue() { return (this.value || "").split(this.tokenSeparator).filter(Boolean); - }), + } - actions: { - onChangeGroupListSetting(value) { - this.set("value", value.join(this.tokenSeparator)); - }, - }, -}); + @action + onChangeGroupListSetting(value) { + this.set("value", value.join(this.tokenSeparator)); + } +} diff --git a/app/assets/javascripts/admin/addon/components/site-settings/host-list.js b/app/assets/javascripts/admin/addon/components/site-settings/host-list.js index 8cc320da8f8..3ce615eb4f1 100644 --- a/app/assets/javascripts/admin/addon/components/site-settings/host-list.js +++ b/app/assets/javascripts/admin/addon/components/site-settings/host-list.js @@ -1,14 +1,14 @@ import Component from "@ember/component"; import { action, computed } from "@ember/object"; -export default Component.extend({ - tokenSeparator: "|", - choices: null, +export default class HostList extends Component { + tokenSeparator = "|"; + choices = null; @computed("value") get settingValue() { return this.value.toString().split(this.tokenSeparator).filter(Boolean); - }, + } @action onChange(value) { @@ -17,5 +17,5 @@ export default Component.extend({ } this.set("value", value.join(this.tokenSeparator)); - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/site-settings/list.js b/app/assets/javascripts/admin/addon/components/site-settings/list.js index 87d5ddb040f..d23ceb2ba77 100644 --- a/app/assets/javascripts/admin/addon/components/site-settings/list.js +++ b/app/assets/javascripts/admin/addon/components/site-settings/list.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class List extends Component {} diff --git a/app/assets/javascripts/admin/addon/components/site-settings/named-list.js b/app/assets/javascripts/admin/addon/components/site-settings/named-list.js index c6cf872d79a..fadfedc9f0b 100644 --- a/app/assets/javascripts/admin/addon/components/site-settings/named-list.js +++ b/app/assets/javascripts/admin/addon/components/site-settings/named-list.js @@ -1,13 +1,13 @@ import Component from "@ember/component"; import { action, computed } from "@ember/object"; -export default Component.extend({ - tokenSeparator: "|", +export default class NamedList extends Component { + tokenSeparator = "|"; @computed("value") get settingValue() { return this.value.toString().split(this.tokenSeparator).filter(Boolean); - }, + } @computed("setting.choices.[]", "settingValue") get settingChoices() { @@ -24,10 +24,10 @@ export default Component.extend({ } return choices; - }, + } @action onChangeListSetting(value) { this.set("value", value.join(this.tokenSeparator)); - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/site-settings/secret-list.js b/app/assets/javascripts/admin/addon/components/site-settings/secret-list.js index 87d5ddb040f..167dbdc6e55 100644 --- a/app/assets/javascripts/admin/addon/components/site-settings/secret-list.js +++ b/app/assets/javascripts/admin/addon/components/site-settings/secret-list.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class SecretList extends Component {} diff --git a/app/assets/javascripts/admin/addon/components/site-settings/simple-list.js b/app/assets/javascripts/admin/addon/components/site-settings/simple-list.js index 383dfeee421..ccc75e2b9dd 100644 --- a/app/assets/javascripts/admin/addon/components/site-settings/simple-list.js +++ b/app/assets/javascripts/admin/addon/components/site-settings/simple-list.js @@ -1,11 +1,11 @@ import Component from "@ember/component"; import { action } from "@ember/object"; -export default Component.extend({ - inputDelimiter: "|", +export default class SimpleList extends Component { + inputDelimiter = "|"; @action onChange(value) { this.set("value", value.join(this.inputDelimiter || "\n")); - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/site-settings/string.js b/app/assets/javascripts/admin/addon/components/site-settings/string.js index 2224c8745fa..c38c1e09082 100644 --- a/app/assets/javascripts/admin/addon/components/site-settings/string.js +++ b/app/assets/javascripts/admin/addon/components/site-settings/string.js @@ -2,7 +2,7 @@ import { action } from "@ember/object"; import Component from "@ember/component"; import showModal from "discourse/lib/show-modal"; -export default Component.extend({ +export default class String extends Component { @action launchJsonEditorModal() { const schemaModal = showModal("json-schema-editor", { @@ -16,5 +16,5 @@ export default Component.extend({ schemaModal.set("onClose", () => { this.set("value", schemaModal.model.value); }); - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/site-settings/tag-list.js b/app/assets/javascripts/admin/addon/components/site-settings/tag-list.js index d679063df14..6f1b59c5eaf 100644 --- a/app/assets/javascripts/admin/addon/components/site-settings/tag-list.js +++ b/app/assets/javascripts/admin/addon/components/site-settings/tag-list.js @@ -2,16 +2,14 @@ import Component from "@ember/component"; import { action } from "@ember/object"; import discourseComputed from "discourse-common/utils/decorators"; -export default Component.extend({ +export default class TagList extends Component { @discourseComputed("value") - selectedTags: { - get(value) { - return value.split("|").filter(Boolean); - }, - }, + selectedTags(value) { + return value.split("|").filter(Boolean); + } @action changeSelectedTags(tags) { this.set("value", tags.join("|")); - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/site-settings/upload.js b/app/assets/javascripts/admin/addon/components/site-settings/upload.js index 87d5ddb040f..ac849a73642 100644 --- a/app/assets/javascripts/admin/addon/components/site-settings/upload.js +++ b/app/assets/javascripts/admin/addon/components/site-settings/upload.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class Upload extends Component {} diff --git a/app/assets/javascripts/admin/addon/components/site-settings/uploaded-image-list.js b/app/assets/javascripts/admin/addon/components/site-settings/uploaded-image-list.js index d66b07e0e8c..4d241b84f74 100644 --- a/app/assets/javascripts/admin/addon/components/site-settings/uploaded-image-list.js +++ b/app/assets/javascripts/admin/addon/components/site-settings/uploaded-image-list.js @@ -1,16 +1,16 @@ +import { action } from "@ember/object"; import Component from "@ember/component"; import showModal from "discourse/lib/show-modal"; -export default Component.extend({ - actions: { - showUploadModal({ value, setting }) { - showModal("admin-uploaded-image-list", { - admin: true, - title: `admin.site_settings.${setting.setting}.title`, - model: { value, setting }, - }).setProperties({ - save: (v) => this.set("value", v), - }); - }, - }, -}); +export default class UploadedImageList extends Component { + @action + showUploadModal({ value, setting }) { + showModal("admin-uploaded-image-list", { + admin: true, + title: `admin.site_settings.${setting.setting}.title`, + model: { value, setting }, + }).setProperties({ + save: (v) => this.set("value", v), + }); + } +} diff --git a/app/assets/javascripts/admin/addon/components/site-settings/url-list.js b/app/assets/javascripts/admin/addon/components/site-settings/url-list.js index 87d5ddb040f..87e25fd4164 100644 --- a/app/assets/javascripts/admin/addon/components/site-settings/url-list.js +++ b/app/assets/javascripts/admin/addon/components/site-settings/url-list.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class UrlList extends Component {} diff --git a/app/assets/javascripts/admin/addon/components/site-settings/value-list.js b/app/assets/javascripts/admin/addon/components/site-settings/value-list.js index 87d5ddb040f..c358c36779f 100644 --- a/app/assets/javascripts/admin/addon/components/site-settings/value-list.js +++ b/app/assets/javascripts/admin/addon/components/site-settings/value-list.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class ValueList extends Component {} diff --git a/app/assets/javascripts/admin/addon/components/site-text-summary.js b/app/assets/javascripts/admin/addon/components/site-text-summary.js index 8f9b3f3b6c9..15ad253a68d 100644 --- a/app/assets/javascripts/admin/addon/components/site-text-summary.js +++ b/app/assets/javascripts/admin/addon/components/site-text-summary.js @@ -1,11 +1,11 @@ +import { classNameBindings, classNames } from "@ember-decorators/component"; import Component from "@ember/component"; import highlightHTML from "discourse/lib/highlight-html"; import { on } from "discourse-common/utils/decorators"; -export default Component.extend({ - classNames: ["site-text"], - classNameBindings: ["siteText.overridden"], - +@classNames("site-text") +@classNameBindings("siteText.overridden") +export default class SiteTextSummary extends Component { @on("didInsertElement") highlightTerm() { const term = this._searchTerm(); @@ -19,11 +19,11 @@ export default Component.extend({ } ); } - }, + } click() { this.editAction(this.siteText); - }, + } _searchTerm() { const regex = this.searchRegex; @@ -37,5 +37,5 @@ export default Component.extend({ } return this.term; - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/staff-actions.js b/app/assets/javascripts/admin/addon/components/staff-actions.js index c639a04746d..4e4fe55c508 100644 --- a/app/assets/javascripts/admin/addon/components/staff-actions.js +++ b/app/assets/javascripts/admin/addon/components/staff-actions.js @@ -1,10 +1,10 @@ +import { tagName } from "@ember-decorators/component"; import { action } from "@ember/object"; import Component from "@ember/component"; import DiscourseURL from "discourse/lib/url"; -export default Component.extend({ - tagName: "", - +@tagName("") +export default class StaffActions extends Component { @action openLinks(event) { const dataset = event.target.dataset; @@ -20,5 +20,5 @@ export default Component.extend({ DiscourseURL.routeTo(`/t/${dataset.linkTopicId}`); } - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/tags-uploader.js b/app/assets/javascripts/admin/addon/components/tags-uploader.js index 39425b9b656..acc31e3506e 100644 --- a/app/assets/javascripts/admin/addon/components/tags-uploader.js +++ b/app/assets/javascripts/admin/addon/components/tags-uploader.js @@ -1,24 +1,27 @@ +import { inject as service } from "@ember/service"; +import { alias } from "@ember/object/computed"; import Component from "@ember/component"; import I18n from "I18n"; import UppyUploadMixin from "discourse/mixins/uppy-upload"; -import { alias } from "@ember/object/computed"; -import { inject as service } from "@ember/service"; -export default Component.extend(UppyUploadMixin, { - type: "csv", - dialog: service(), - uploadUrl: "/tags/upload", - addDisabled: alias("uploading"), - elementId: "tag-uploader", - preventDirectS3Uploads: true, +export default class TagsUploader extends Component.extend(UppyUploadMixin) { + @service dialog; + type = "csv"; + + uploadUrl = "/tags/upload"; + + @alias("uploading") addDisabled; + + elementId = "tag-uploader"; + preventDirectS3Uploads = true; validateUploadedFilesOptions() { return { csvOnly: true }; - }, + } uploadDone() { this.closeModal(); this.refresh(); this.dialog.alert(I18n.t("tagging.upload_successful")); - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/theme-translation.js b/app/assets/javascripts/admin/addon/components/theme-translation.js index 3204a8bdfa0..eac13fd2126 100644 --- a/app/assets/javascripts/admin/addon/components/theme-translation.js +++ b/app/assets/javascripts/admin/addon/components/theme-translation.js @@ -3,9 +3,10 @@ import { alias } from "@ember/object/computed"; export default class ThemeTranslation extends SiteSettingComponent { @alias("translation") setting; - type = "string"; @alias("translation.key") settingName; + type = "string"; + _save() { return this.model.saveTranslation( this.get("translation.key"), diff --git a/app/assets/javascripts/admin/addon/components/themes-list-item.js b/app/assets/javascripts/admin/addon/components/themes-list-item.js index 29158c44967..b059b96ea47 100644 --- a/app/assets/javascripts/admin/addon/components/themes-list-item.js +++ b/app/assets/javascripts/admin/addon/components/themes-list-item.js @@ -1,3 +1,4 @@ +import { classNameBindings, classNames } from "@ember-decorators/component"; import { and, gt } from "@ember/object/computed"; import discourseComputed from "discourse-common/utils/decorators"; import Component from "@ember/component"; @@ -7,19 +8,22 @@ import { action } from "@ember/object"; const MAX_COMPONENTS = 4; -export default Component.extend({ - childrenExpanded: false, - classNames: ["themes-list-item"], - classNameBindings: ["theme.selected:selected"], - hasComponents: gt("children.length", 0), - displayComponents: and("hasComponents", "theme.isActive"), - displayHasMore: gt("theme.childThemes.length", MAX_COMPONENTS), +@classNames("themes-list-item") +@classNameBindings("theme.selected:selected") +export default class ThemesListItem extends Component { + childrenExpanded = false; + + @gt("children.length", 0) hasComponents; + + @and("hasComponents", "theme.isActive") displayComponents; + + @gt("theme.childThemes.length", MAX_COMPONENTS) displayHasMore; click(e) { if (!e.target.classList.contains("others-count")) { this.navigateToTheme(); } - }, + } @discourseComputed( "theme.component", @@ -40,12 +44,12 @@ export default Component.extend({ const name = escape(t.name); return t.enabled ? name : `${iconHTML("ban")} ${name}`; }); - }, + } @discourseComputed("children") childrenString(children) { return children.join(", "); - }, + } @discourseComputed( "theme.childThemes.length", @@ -58,11 +62,11 @@ export default Component.extend({ return 0; } return childrenCount - MAX_COMPONENTS; - }, + } @action toggleChildrenExpanded(event) { event?.preventDefault(); this.toggleProperty("childrenExpanded"); - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/themes-list.js b/app/assets/javascripts/admin/addon/components/themes-list.js index ca1d872f46b..e3ca02ef437 100644 --- a/app/assets/javascripts/admin/addon/components/themes-list.js +++ b/app/assets/javascripts/admin/addon/components/themes-list.js @@ -1,25 +1,30 @@ -import { COMPONENTS, THEMES } from "admin/models/theme"; +import { classNames } from "@ember-decorators/component"; +import { inject as service } from "@ember/service"; import { equal, gt, gte } from "@ember/object/computed"; +import { COMPONENTS, THEMES } from "admin/models/theme"; import Component from "@ember/component"; import discourseComputed from "discourse-common/utils/decorators"; -import { inject as service } from "@ember/service"; import { action } from "@ember/object"; -export default Component.extend({ - router: service(), - THEMES, - COMPONENTS, +@classNames("themes-list") +export default class ThemesList extends Component { + @service router; - classNames: ["themes-list"], - filterTerm: null, + THEMES = THEMES; + COMPONENTS = COMPONENTS; + filterTerm = null; - hasThemes: gt("themesList.length", 0), - hasActiveThemes: gt("activeThemes.length", 0), - hasInactiveThemes: gt("inactiveThemes.length", 0), - showFilter: gte("themesList.length", 10), + @gt("themesList.length", 0) hasThemes; - themesTabActive: equal("currentTab", THEMES), - componentsTabActive: equal("currentTab", COMPONENTS), + @gt("activeThemes.length", 0) hasActiveThemes; + + @gt("inactiveThemes.length", 0) hasInactiveThemes; + + @gte("themesList.length", 10) showFilter; + + @equal("currentTab", THEMES) themesTabActive; + + @equal("currentTab", COMPONENTS) componentsTabActive; @discourseComputed("themes", "components", "currentTab") themesList(themes, components) { @@ -28,7 +33,7 @@ export default Component.extend({ } else { return components; } - }, + } @discourseComputed( "themesList", @@ -49,7 +54,7 @@ export default Component.extend({ ); } return this._filterThemes(results, this.filterTerm); - }, + } @discourseComputed( "themesList", @@ -78,7 +83,7 @@ export default Component.extend({ }); } return this._filterThemes(results, this.filterTerm); - }, + } _filterThemes(themes, term) { term = term?.trim()?.toLowerCase(); @@ -86,7 +91,7 @@ export default Component.extend({ return themes; } return themes.filter(({ name }) => name.toLowerCase().includes(term)); - }, + } @action changeView(newTab) { @@ -96,10 +101,10 @@ export default Component.extend({ this.set("filterTerm", null); } } - }, + } @action navigateToTheme(theme) { this.router.transitionTo("adminCustomizeThemes.show", theme); - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/value-list.js b/app/assets/javascripts/admin/addon/components/value-list.js index 65b47c5058c..917caa4a7b3 100644 --- a/app/assets/javascripts/admin/addon/components/value-list.js +++ b/app/assets/javascripts/admin/addon/components/value-list.js @@ -1,17 +1,21 @@ -import discourseComputed, { on } from "discourse-common/utils/decorators"; +import { action } from "@ember/object"; +import { classNames } from "@ember-decorators/component"; import { empty, reads } from "@ember/object/computed"; +import discourseComputed, { on } from "discourse-common/utils/decorators"; import Component from "@ember/component"; import { makeArray } from "discourse-common/lib/helpers"; -export default Component.extend({ - classNameBindings: [":value-list"], - inputInvalid: empty("newValue"), - inputDelimiter: null, - inputType: null, - newValue: "", - collection: null, - values: null, - noneKey: reads("addKey"), +@classNames("value-list") +export default class ValueList extends Component { + @empty("newValue") inputInvalid; + + inputDelimiter = null; + inputType = null; + newValue = ""; + collection = null; + values = null; + + @reads("addKey") noneKey; @on("didReceiveAttrs") _setupCollection() { @@ -25,57 +29,60 @@ export default Component.extend({ "collection", this._splitValues(values, this.inputDelimiter || "\n") ); - }, + } @discourseComputed("choices.[]", "collection.[]") filteredChoices(choices, collection) { return makeArray(choices).filter((i) => !collection.includes(i)); - }, + } keyDown(event) { if (event.key === "Enter") { this.send("addValue", this.newValue); } - }, + } - actions: { - changeValue(index, event) { - this._replaceValue(index, event.target.value); - }, + @action + changeValue(index, event) { + this._replaceValue(index, event.target.value); + } - addValue(newValue) { - if (this.inputInvalid) { - return; - } + @action + addValue(newValue) { + if (this.inputInvalid) { + return; + } - this.set("newValue", null); - this._addValue(newValue); - }, + this.set("newValue", null); + this._addValue(newValue); + } - removeValue(value) { - this._removeValue(value); - }, + @action + removeValue(value) { + this._removeValue(value); + } - selectChoice(choice) { - this._addValue(choice); - }, + @action + selectChoice(choice) { + this._addValue(choice); + } - shift(operation, index) { - let futureIndex = index + operation; + @action + shift(operation, index) { + let futureIndex = index + operation; - if (futureIndex > this.collection.length - 1) { - futureIndex = 0; - } else if (futureIndex < 0) { - futureIndex = this.collection.length - 1; - } + if (futureIndex > this.collection.length - 1) { + futureIndex = 0; + } else if (futureIndex < 0) { + futureIndex = this.collection.length - 1; + } - const shiftedValue = this.collection[index]; - this.collection.removeAt(index); - this.collection.insertAt(futureIndex, shiftedValue); + const shiftedValue = this.collection[index]; + this.collection.removeAt(index); + this.collection.insertAt(futureIndex, shiftedValue); - this._saveValues(); - }, - }, + this._saveValues(); + } _addValue(value) { this.collection.addObject(value); @@ -87,7 +94,7 @@ export default Component.extend({ } this._saveValues(); - }, + } _removeValue(value) { this.collection.removeObject(value); @@ -99,12 +106,12 @@ export default Component.extend({ } this._saveValues(); - }, + } _replaceValue(index, newValue) { this.collection.replace(index, 1, [newValue]); this._saveValues(); - }, + } _saveValues() { if (this.inputType === "array") { @@ -113,12 +120,12 @@ export default Component.extend({ } this.set("values", this.collection.join(this.inputDelimiter || "\n")); - }, + } @discourseComputed("collection") showUpDownButtons(collection) { return collection.length - 1 ? true : false; - }, + } _splitValues(values, delimiter) { if (values && values.length) { @@ -126,5 +133,5 @@ export default Component.extend({ } else { return []; } - }, -}); + } +} diff --git a/app/assets/javascripts/admin/addon/components/version-checks.js b/app/assets/javascripts/admin/addon/components/version-checks.js index 87d5ddb040f..b06deba9d5f 100644 --- a/app/assets/javascripts/admin/addon/components/version-checks.js +++ b/app/assets/javascripts/admin/addon/components/version-checks.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class VersionChecks extends Component {} diff --git a/app/assets/javascripts/admin/addon/components/watched-word-form.hbs b/app/assets/javascripts/admin/addon/components/watched-word-form.hbs index 284ebebf67e..0e3c6939599 100644 --- a/app/assets/javascripts/admin/addon/components/watched-word-form.hbs +++ b/app/assets/javascripts/admin/addon/components/watched-word-form.hbs @@ -79,7 +79,7 @@ diff --git a/app/assets/javascripts/admin/addon/components/watched-word-form.js b/app/assets/javascripts/admin/addon/components/watched-word-form.js index f1b3138a780..9867f5dbbd5 100644 --- a/app/assets/javascripts/admin/addon/components/watched-word-form.js +++ b/app/assets/javascripts/admin/addon/components/watched-word-form.js @@ -1,30 +1,37 @@ +import { action } from "@ember/object"; +import { classNames, tagName } from "@ember-decorators/component"; +import { inject as service } from "@ember/service"; +import { equal, not } from "@ember/object/computed"; import discourseComputed, { observes } from "discourse-common/utils/decorators"; import Component from "@ember/component"; import I18n from "I18n"; import WatchedWord from "admin/models/watched-word"; -import { equal, not } from "@ember/object/computed"; import { isEmpty } from "@ember/utils"; import { schedule } from "@ember/runloop"; -import { inject as service } from "@ember/service"; -export default Component.extend({ - tagName: "form", - dialog: service(), - classNames: ["watched-word-form"], - formSubmitted: false, - actionKey: null, - showMessage: false, - selectedTags: null, - isCaseSensitive: false, - submitDisabled: not("word"), - canReplace: equal("actionKey", "replace"), - canTag: equal("actionKey", "tag"), - canLink: equal("actionKey", "link"), +@tagName("form") +@classNames("watched-word-form") +export default class WatchedWordForm extends Component { + @service dialog; + + formSubmitted = false; + actionKey = null; + showMessage = false; + selectedTags = null; + isCaseSensitive = false; + + @not("word") submitDisabled; + + @equal("actionKey", "replace") canReplace; + + @equal("actionKey", "tag") canTag; + + @equal("actionKey", "link") canLink; didInsertElement() { - this._super(...arguments); + super.didInsertElement(...arguments); this.set("selectedTags", []); - }, + } @discourseComputed("siteSettings.watched_words_regular_expressions") placeholderKey(watchedWordsRegularExpressions) { @@ -33,14 +40,14 @@ export default Component.extend({ } else { return "admin.watched_words.form.placeholder"; } - }, + } @observes("word") removeMessage() { if (this.showMessage && !isEmpty(this.word)) { this.set("showMessage", false); } - }, + } @discourseComputed("word") isUniqueWord(word) { @@ -54,71 +61,71 @@ export default Component.extend({ } return content.word.toLowerCase() !== word.toLowerCase(); }); - }, + } focusInput() { schedule("afterRender", () => this.element.querySelector("input").focus()); - }, + } - actions: { - changeSelectedTags(tags) { + @action + changeSelectedTags(tags) { + this.setProperties({ + selectedTags: tags, + replacement: tags.join(","), + }); + } + + @action + submitForm() { + if (!this.isUniqueWord) { this.setProperties({ - selectedTags: tags, - replacement: tags.join(","), + showMessage: true, + message: I18n.t("admin.watched_words.form.exists"), }); - }, + return; + } - submit() { - if (!this.isUniqueWord) { - this.setProperties({ - showMessage: true, - message: I18n.t("admin.watched_words.form.exists"), - }); - return; - } + if (!this.formSubmitted) { + this.set("formSubmitted", true); - if (!this.formSubmitted) { - this.set("formSubmitted", true); + const watchedWord = WatchedWord.create({ + word: this.word, + replacement: + this.canReplace || this.canTag || this.canLink + ? this.replacement + : null, + action: this.actionKey, + isCaseSensitive: this.isCaseSensitive, + }); - const watchedWord = WatchedWord.create({ - word: this.word, - replacement: - this.canReplace || this.canTag || this.canLink - ? this.replacement - : null, - action: this.actionKey, - isCaseSensitive: this.isCaseSensitive, - }); - - watchedWord - .save() - .then((result) => { - this.setProperties({ - word: "", - replacement: "", - formSubmitted: false, - selectedTags: [], - showMessage: true, - message: I18n.t("admin.watched_words.form.success"), - isCaseSensitive: false, - }); - this.action(WatchedWord.create(result)); - this.focusInput(); - }) - .catch((e) => { - this.set("formSubmitted", false); - const message = e.jqXHR.responseJSON?.errors - ? I18n.t("generic_error_with_reason", { - error: e.jqXHR.responseJSON.errors.join(". "), - }) - : I18n.t("generic_error"); - this.dialog.alert({ - message, - didConfirm: () => this.focusInput(), - didCancel: () => this.focusInput(), - }); + watchedWord + .save() + .then((result) => { + this.setProperties({ + word: "", + replacement: "", + formSubmitted: false, + selectedTags: [], + showMessage: true, + message: I18n.t("admin.watched_words.form.success"), + isCaseSensitive: false, }); - } - }, - }, -}); + this.action(WatchedWord.create(result)); + this.focusInput(); + }) + .catch((e) => { + this.set("formSubmitted", false); + const message = e.jqXHR.responseJSON?.errors + ? I18n.t("generic_error_with_reason", { + error: e.jqXHR.responseJSON.errors.join(". "), + }) + : I18n.t("generic_error"); + this.dialog.alert({ + message, + didConfirm: () => this.focusInput(), + didCancel: () => this.focusInput(), + }); + }); + } + } +} diff --git a/app/assets/javascripts/admin/addon/components/watched-word-uploader.js b/app/assets/javascripts/admin/addon/components/watched-word-uploader.js index 27c43ad5761..3c29a88cf7c 100644 --- a/app/assets/javascripts/admin/addon/components/watched-word-uploader.js +++ b/app/assets/javascripts/admin/addon/components/watched-word-uploader.js @@ -1,28 +1,33 @@ +import { classNames } from "@ember-decorators/component"; +import { alias } from "@ember/object/computed"; import Component from "@ember/component"; import I18n from "I18n"; import UppyUploadMixin from "discourse/mixins/uppy-upload"; -import { alias } from "@ember/object/computed"; import { dialog } from "discourse/lib/uploads"; -export default Component.extend(UppyUploadMixin, { - type: "txt", - classNames: "watched-words-uploader", - uploadUrl: "/admin/customize/watched_words/upload", - addDisabled: alias("uploading"), - preventDirectS3Uploads: true, +@classNames("watched-words-uploader") +export default class WatchedWordUploader extends Component.extend( + UppyUploadMixin +) { + type = "txt"; + uploadUrl = "/admin/customize/watched_words/upload"; + + @alias("uploading") addDisabled; + + preventDirectS3Uploads = true; validateUploadedFilesOptions() { return { skipValidation: true }; - }, + } _perFileData() { return { action_key: this.actionKey }; - }, + } uploadDone() { if (this) { dialog.alert(I18n.t("admin.watched_words.form.upload_successful")); this.done(); } - }, -}); + } +}