From 4150ec960eeaf1c9d565e7ed0b108810ae570246 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Wed, 28 Aug 2024 16:15:13 +0100 Subject: [PATCH] DEV: Convert core components to native class syntax (batch 7) (#28603) Changes made using the ember-native-class-codemod, plus some manual tweaks --- .../discourse/app/components/radio-button.js | 27 +-- .../reviewable-conversation-post.js | 7 +- .../app/components/reviewable-field-editor.js | 2 +- .../app/components/reviewable-field-tags.js | 26 +-- .../app/components/reviewable-field-text.js | 2 +- .../components/reviewable-field-textarea.js | 2 +- .../app/components/reviewable-field.js | 2 +- .../app/components/reviewable-histories.js | 7 +- .../app/components/reviewable-item.js | 196 +++++++++--------- .../app/components/reviewable-post-edits.js | 14 +- .../app/components/reviewable-post-header.js | 2 +- .../app/components/reviewable-post.js | 2 +- .../app/components/reviewable-score.js | 12 +- .../app/components/reviewable-scores.js | 2 +- .../app/components/reviewable-tags.js | 2 +- .../app/components/reviewable-topic-link.js | 2 +- .../app/components/reviewable-user.js | 6 +- .../discourse/app/components/save-controls.js | 16 +- .../app/components/scroll-tracker.js | 24 +-- .../app/components/scrolling-post-stream.js | 47 +++-- .../app/components/search-advanced-options.js | 97 +++++---- .../app/components/search-result-entries.js | 6 +- .../app/components/search-result-entry.js | 22 +- .../app/components/search-text-field.js | 13 +- .../app/components/second-factor-form.js | 14 +- .../app/components/selected-posts.js | 2 +- .../discourse/app/components/share-panel.js | 25 +-- .../app/components/shared-draft-controls.js | 65 +++--- .../discourse/app/components/signup-cta.js | 28 +-- .../app/components/slow-mode-info.js | 10 +- .../app/components/sub-category-item.js | 2 +- .../app/components/sub-category-row.js | 2 +- .../subcategories-with-featured-topics.js | 2 +- 33 files changed, 356 insertions(+), 332 deletions(-) diff --git a/app/assets/javascripts/discourse/app/components/radio-button.js b/app/assets/javascripts/discourse/app/components/radio-button.js index 35e0ea35d6b..298e09fb36a 100644 --- a/app/assets/javascripts/discourse/app/components/radio-button.js +++ b/app/assets/javascripts/discourse/app/components/radio-button.js @@ -1,17 +1,18 @@ import Component from "@ember/component"; +import { attributeBindings, tagName } from "@ember-decorators/component"; import $ from "jquery"; import discourseComputed from "discourse-common/utils/decorators"; -export default Component.extend({ - tagName: "input", - type: "radio", - attributeBindings: [ - "name", - "type", - "value", - "checked:checked", - "disabled:disabled", - ], +@tagName("input") +@attributeBindings( + "name", + "type", + "value", + "checked:checked", + "disabled:disabled" +) +export default class RadioButton extends Component { + type = "radio"; click() { const value = $(this.element).val(); @@ -24,10 +25,10 @@ export default Component.extend({ } this.set("selection", value); } - }, + } @discourseComputed("value", "selection") checked(value, selection) { return value === selection; - }, -}); + } +} diff --git a/app/assets/javascripts/discourse/app/components/reviewable-conversation-post.js b/app/assets/javascripts/discourse/app/components/reviewable-conversation-post.js index 375bac5343c..84d4d977f2a 100644 --- a/app/assets/javascripts/discourse/app/components/reviewable-conversation-post.js +++ b/app/assets/javascripts/discourse/app/components/reviewable-conversation-post.js @@ -1,5 +1,6 @@ import Component from "@ember/component"; import { gte } from "@ember/object/computed"; -export default Component.extend({ - showUsername: gte("index", 1), -}); + +export default class ReviewableConversationPost extends Component { + @gte("index", 1) showUsername; +} diff --git a/app/assets/javascripts/discourse/app/components/reviewable-field-editor.js b/app/assets/javascripts/discourse/app/components/reviewable-field-editor.js index 87d5ddb040f..f14a72c7385 100644 --- a/app/assets/javascripts/discourse/app/components/reviewable-field-editor.js +++ b/app/assets/javascripts/discourse/app/components/reviewable-field-editor.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class ReviewableFieldEditor extends Component {} diff --git a/app/assets/javascripts/discourse/app/components/reviewable-field-tags.js b/app/assets/javascripts/discourse/app/components/reviewable-field-tags.js index ee74c6802a1..70a6b0ed23d 100644 --- a/app/assets/javascripts/discourse/app/components/reviewable-field-tags.js +++ b/app/assets/javascripts/discourse/app/components/reviewable-field-tags.js @@ -1,16 +1,16 @@ import Component from "@ember/component"; +import { action } from "@ember/object"; -export default Component.extend({ - actions: { - onChange(tags) { - this.set("value", tags); +export default class ReviewableFieldTags extends Component { + @action + onChange(tags) { + this.set("value", tags); - this.valueChanged && - this.valueChanged({ - target: { - value: tags, - }, - }); - }, - }, -}); + this.valueChanged && + this.valueChanged({ + target: { + value: tags, + }, + }); + } +} diff --git a/app/assets/javascripts/discourse/app/components/reviewable-field-text.js b/app/assets/javascripts/discourse/app/components/reviewable-field-text.js index 87d5ddb040f..38fa568d82c 100644 --- a/app/assets/javascripts/discourse/app/components/reviewable-field-text.js +++ b/app/assets/javascripts/discourse/app/components/reviewable-field-text.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class ReviewableFieldText extends Component {} diff --git a/app/assets/javascripts/discourse/app/components/reviewable-field-textarea.js b/app/assets/javascripts/discourse/app/components/reviewable-field-textarea.js index 87d5ddb040f..c86105578b7 100644 --- a/app/assets/javascripts/discourse/app/components/reviewable-field-textarea.js +++ b/app/assets/javascripts/discourse/app/components/reviewable-field-textarea.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class ReviewableFieldTextarea extends Component {} diff --git a/app/assets/javascripts/discourse/app/components/reviewable-field.js b/app/assets/javascripts/discourse/app/components/reviewable-field.js index 87d5ddb040f..466abaacf80 100644 --- a/app/assets/javascripts/discourse/app/components/reviewable-field.js +++ b/app/assets/javascripts/discourse/app/components/reviewable-field.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class ReviewableField extends Component {} diff --git a/app/assets/javascripts/discourse/app/components/reviewable-histories.js b/app/assets/javascripts/discourse/app/components/reviewable-histories.js index b50025f33d5..b51fe7fab4a 100644 --- a/app/assets/javascripts/discourse/app/components/reviewable-histories.js +++ b/app/assets/javascripts/discourse/app/components/reviewable-histories.js @@ -1,5 +1,6 @@ import Component from "@ember/component"; import { filterBy } from "@ember/object/computed"; -export default Component.extend({ - filteredHistories: filterBy("histories", "created", false), -}); + +export default class ReviewableHistories extends Component { + @filterBy("histories", "created", false) filteredHistories; +} diff --git a/app/assets/javascripts/discourse/app/components/reviewable-item.js b/app/assets/javascripts/discourse/app/components/reviewable-item.js index 11ff78a6595..f8b4837bf8a 100644 --- a/app/assets/javascripts/discourse/app/components/reviewable-item.js +++ b/app/assets/javascripts/discourse/app/components/reviewable-item.js @@ -3,6 +3,7 @@ import { action, set } from "@ember/object"; import { getOwner } from "@ember/owner"; import { service } from "@ember/service"; import { classify, dasherize } from "@ember/string"; +import { tagName } from "@ember-decorators/component"; import ExplainReviewableModal from "discourse/components/modal/explain-reviewable"; import RejectReasonReviewableModal from "discourse/components/modal/reject-reason-reviewable"; import ReviseAndRejectPostReviewable from "discourse/components/modal/revise-and-reject-post-reviewable"; @@ -41,17 +42,18 @@ export function registerReviewableActionModal(actionName, modalClass) { actionModalClassMap[actionName] = modalClass; } -export default Component.extend({ - adminTools: optionalService(), - dialog: service(), - modal: service(), - siteSettings: service(), - currentUser: service(), - composer: service(), - tagName: "", - updating: null, - editing: false, - _updates: null, +@tagName("") +export default class ReviewableItem extends Component { + @service dialog; + @service modal; + @service siteSettings; + @service currentUser; + @service composer; + @optionalService adminTools; + + updating = null; + editing = false; + _updates = null; @discourseComputed( "reviewable.type", @@ -71,12 +73,12 @@ export default Component.extend({ } return classes; - }, + } @discourseComputed("reviewable.created_from_flag", "reviewable.status") displayContextQuestion(createdFromFlag, status) { return createdFromFlag && status === 0; - }, + } @discourseComputed( "reviewable.topic", @@ -85,12 +87,12 @@ export default Component.extend({ ) topicId(topic, topicId, removedTopicId) { return (topic && topic.id) || topicId || removedTopicId; - }, + } @discourseComputed("siteSettings.reviewable_claiming", "topicId") claimEnabled(claimMode, topicId) { return claimMode !== "disabled" && !!topicId; - }, + } @discourseComputed( "claimEnabled", @@ -107,7 +109,7 @@ export default Component.extend({ } return claimMode !== "required"; - }, + } @discourseComputed( "siteSettings.reviewable_claiming", @@ -125,7 +127,7 @@ export default Component.extend({ return claimMode === "optional" ? I18n.t("review.claim_help.optional") : I18n.t("review.claim_help.required"); - }, + } // Find a component to render, if one exists. For example: // `ReviewableUser` will return `reviewable-user` @@ -142,12 +144,12 @@ export default Component.extend({ owner.hasRegistration(`template:components/${dasherized}`); _components[type] = componentExists ? dasherized : null; return _components[type]; - }, + } @discourseComputed("_updates.category_id", "reviewable.category.id") tagCategoryId(updatedCategoryId, categoryId) { return updatedCategoryId || categoryId; - }, + } @bind _performConfirmed(performableAction, additionalData = {}) { @@ -219,15 +221,15 @@ export default Component.extend({ } else { return performAction(); } - }, + } clientSuspend(reviewable, performAction) { this._penalize("showSuspendModal", reviewable, performAction); - }, + } clientSilence(reviewable, performAction) { this._penalize("showSilenceModal", reviewable, performAction); - }, + } async clientEdit(reviewable, performAction) { if (!this.currentUser) { @@ -255,7 +257,7 @@ export default Component.extend({ this.composer.open(opts); return performAction(); - }, + } _penalize(adminToolMethod, reviewable, performAction) { let adminTools = this.adminTools; @@ -269,7 +271,7 @@ export default Component.extend({ before: performAction, }); } - }, + } @action explainReviewable(reviewable, event) { @@ -277,80 +279,82 @@ export default Component.extend({ this.modal.show(ExplainReviewableModal, { model: { reviewable }, }); - }, + } - actions: { - edit() { - this.set("editing", true); - this.set("_updates", { payload: {} }); - }, + @action + edit() { + this.set("editing", true); + this.set("_updates", { payload: {} }); + } - cancelEdit() { - this.set("editing", false); - }, + @action + cancelEdit() { + this.set("editing", false); + } - saveEdit() { - let updates = this._updates; + @action + saveEdit() { + let updates = this._updates; - // Remove empty objects - Object.keys(updates).forEach((name) => { - let attr = updates[name]; - if (typeof attr === "object" && Object.keys(attr).length === 0) { - delete updates[name]; - } + // Remove empty objects + Object.keys(updates).forEach((name) => { + let attr = updates[name]; + if (typeof attr === "object" && Object.keys(attr).length === 0) { + delete updates[name]; + } + }); + + this.set("updating", true); + return this.reviewable + .update(updates) + .then(() => this.set("editing", false)) + .catch(popupAjaxError) + .finally(() => this.set("updating", false)); + } + + @action + categoryChanged(categoryId) { + let category = Category.findById(categoryId); + + if (!category) { + category = Category.findUncategorized(); + } + + set(this._updates, "category_id", category.id); + } + + @action + valueChanged(fieldId, event) { + set(this._updates, fieldId, event.target.value); + } + + @action + perform(performableAction) { + if (this.updating) { + return; + } + + const message = performableAction.get("confirm_message"); + const requireRejectReason = performableAction.get("require_reject_reason"); + const actionModalClass = requireRejectReason + ? RejectReasonReviewableModal + : actionModalClassMap[performableAction.server_action]; + + if (message) { + this.dialog.confirm({ + message, + didConfirm: () => this._performConfirmed(performableAction), }); - - this.set("updating", true); - return this.reviewable - .update(updates) - .then(() => this.set("editing", false)) - .catch(popupAjaxError) - .finally(() => this.set("updating", false)); - }, - - categoryChanged(categoryId) { - let category = Category.findById(categoryId); - - if (!category) { - category = Category.findUncategorized(); - } - - set(this._updates, "category_id", category.id); - }, - - valueChanged(fieldId, event) { - set(this._updates, fieldId, event.target.value); - }, - - perform(performableAction) { - if (this.updating) { - return; - } - - const message = performableAction.get("confirm_message"); - const requireRejectReason = performableAction.get( - "require_reject_reason" - ); - const actionModalClass = requireRejectReason - ? RejectReasonReviewableModal - : actionModalClassMap[performableAction.server_action]; - - if (message) { - this.dialog.confirm({ - message, - didConfirm: () => this._performConfirmed(performableAction), - }); - } else if (actionModalClass) { - this.modal.show(actionModalClass, { - model: { - reviewable: this.reviewable, - performConfirmed: this._performConfirmed, - action: performableAction, - }, - }); - } else { - return this._performConfirmed(performableAction); - } - }, - }, -}); + } else if (actionModalClass) { + this.modal.show(actionModalClass, { + model: { + reviewable: this.reviewable, + performConfirmed: this._performConfirmed, + action: performableAction, + }, + }); + } else { + return this._performConfirmed(performableAction); + } + } +} diff --git a/app/assets/javascripts/discourse/app/components/reviewable-post-edits.js b/app/assets/javascripts/discourse/app/components/reviewable-post-edits.js index 4d769fec689..39402974d2e 100644 --- a/app/assets/javascripts/discourse/app/components/reviewable-post-edits.js +++ b/app/assets/javascripts/discourse/app/components/reviewable-post-edits.js @@ -7,20 +7,20 @@ import { longDate } from "discourse/lib/formatter"; import { historyHeat } from "discourse/widgets/post-edits-indicator"; import discourseComputed from "discourse-common/utils/decorators"; -export default Component.extend({ - modal: service(), +export default class ReviewablePostEdits extends Component { + @service modal; - hasEdits: gt("reviewable.post_version", 1), + @gt("reviewable.post_version", 1) hasEdits; @discourseComputed("reviewable.post_updated_at") historyClass(updatedAt) { return historyHeat(this.siteSettings, new Date(updatedAt)); - }, + } @discourseComputed("reviewable.post_updated_at") editedDate(updatedAt) { return longDate(updatedAt); - }, + } @action showEditHistory(event) { @@ -36,5 +36,5 @@ export default Component.extend({ }, }); }); - }, -}); + } +} diff --git a/app/assets/javascripts/discourse/app/components/reviewable-post-header.js b/app/assets/javascripts/discourse/app/components/reviewable-post-header.js index 87d5ddb040f..003976726f3 100644 --- a/app/assets/javascripts/discourse/app/components/reviewable-post-header.js +++ b/app/assets/javascripts/discourse/app/components/reviewable-post-header.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class ReviewablePostHeader extends Component {} diff --git a/app/assets/javascripts/discourse/app/components/reviewable-post.js b/app/assets/javascripts/discourse/app/components/reviewable-post.js index 87d5ddb040f..1bbf7468675 100644 --- a/app/assets/javascripts/discourse/app/components/reviewable-post.js +++ b/app/assets/javascripts/discourse/app/components/reviewable-post.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class ReviewablePost extends Component {} diff --git a/app/assets/javascripts/discourse/app/components/reviewable-score.js b/app/assets/javascripts/discourse/app/components/reviewable-score.js index dab753fe1bd..6778d347fd9 100644 --- a/app/assets/javascripts/discourse/app/components/reviewable-score.js +++ b/app/assets/javascripts/discourse/app/components/reviewable-score.js @@ -1,11 +1,11 @@ import Component from "@ember/component"; import { gt } from "@ember/object/computed"; +import { tagName } from "@ember-decorators/component"; import discourseComputed from "discourse-common/utils/decorators"; -export default Component.extend({ - tagName: "", - - showStatus: gt("rs.status", 0), +@tagName("") +export default class ReviewableScore extends Component { + @gt("rs.status", 0) showStatus; @discourseComputed("rs.score_type.title", "reviewable.target_created_by") title(title, targetCreatedBy) { @@ -17,5 +17,5 @@ export default Component.extend({ } return title; - }, -}); + } +} diff --git a/app/assets/javascripts/discourse/app/components/reviewable-scores.js b/app/assets/javascripts/discourse/app/components/reviewable-scores.js index 87d5ddb040f..a5e66c61fd3 100644 --- a/app/assets/javascripts/discourse/app/components/reviewable-scores.js +++ b/app/assets/javascripts/discourse/app/components/reviewable-scores.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class ReviewableScores extends Component {} diff --git a/app/assets/javascripts/discourse/app/components/reviewable-tags.js b/app/assets/javascripts/discourse/app/components/reviewable-tags.js index 87d5ddb040f..12dc40dc4be 100644 --- a/app/assets/javascripts/discourse/app/components/reviewable-tags.js +++ b/app/assets/javascripts/discourse/app/components/reviewable-tags.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class ReviewableTags extends Component {} diff --git a/app/assets/javascripts/discourse/app/components/reviewable-topic-link.js b/app/assets/javascripts/discourse/app/components/reviewable-topic-link.js index 87d5ddb040f..0eb6a54282e 100644 --- a/app/assets/javascripts/discourse/app/components/reviewable-topic-link.js +++ b/app/assets/javascripts/discourse/app/components/reviewable-topic-link.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class ReviewableTopicLink extends Component {} diff --git a/app/assets/javascripts/discourse/app/components/reviewable-user.js b/app/assets/javascripts/discourse/app/components/reviewable-user.js index 5418f791a05..15d55244c7e 100644 --- a/app/assets/javascripts/discourse/app/components/reviewable-user.js +++ b/app/assets/javascripts/discourse/app/components/reviewable-user.js @@ -1,9 +1,9 @@ import Component from "@ember/component"; import discourseComputed from "discourse-common/utils/decorators"; -export default Component.extend({ +export default class ReviewableUser extends Component { @discourseComputed("reviewable.user_fields") userFields(fields) { return this.site.collectUserFields(fields); - }, -}); + } +} diff --git a/app/assets/javascripts/discourse/app/components/save-controls.js b/app/assets/javascripts/discourse/app/components/save-controls.js index 7b09a7ce71f..4a26fe16598 100644 --- a/app/assets/javascripts/discourse/app/components/save-controls.js +++ b/app/assets/javascripts/discourse/app/components/save-controls.js @@ -1,19 +1,19 @@ import Component from "@ember/component"; import { or } from "@ember/object/computed"; +import { classNames } from "@ember-decorators/component"; import discourseComputed from "discourse-common/utils/decorators"; -export default Component.extend({ - classNames: ["controls", "save-button"], - - buttonDisabled: or("model.isSaving", "saveDisabled"), +@classNames("controls", "save-button") +export default class SaveControls extends Component { + @or("model.isSaving", "saveDisabled") buttonDisabled; didInsertElement() { - this._super(...arguments); + super.didInsertElement(...arguments); this.set("saved", false); - }, + } @discourseComputed("model.isSaving") savingText(saving) { return saving ? "saving" : "save"; - }, -}); + } +} diff --git a/app/assets/javascripts/discourse/app/components/scroll-tracker.js b/app/assets/javascripts/discourse/app/components/scroll-tracker.js index 1181a34e1ac..6343c3d6f7a 100644 --- a/app/assets/javascripts/discourse/app/components/scroll-tracker.js +++ b/app/assets/javascripts/discourse/app/components/scroll-tracker.js @@ -3,40 +3,40 @@ import { next } from "@ember/runloop"; import $ from "jquery"; import Scrolling from "discourse/mixins/scrolling"; -export default Component.extend(Scrolling, { +export default class ScrollTracker extends Component.extend(Scrolling) { didReceiveAttrs() { - this._super(...arguments); + super.didReceiveAttrs(...arguments); this.set("trackerName", `scroll-tracker-${this.name}`); - }, + } didInsertElement() { - this._super(...arguments); + super.didInsertElement(...arguments); this.bindScrolling(); - }, + } didRender() { - this._super(...arguments); + super.didRender(...arguments); const data = this.session.get(this.trackerName); if (data && data.position >= 0 && data.tag === this.tag) { next(() => $(window).scrollTop(data.position + 1)); } - }, + } willDestroyElement() { - this._super(...arguments); + super.willDestroyElement(...arguments); this.unbindScrolling(); - }, + } scrolled() { - this._super(...arguments); + super.scrolled(...arguments); this.session.set(this.trackerName, { position: $(window).scrollTop(), tag: this.tag, }); - }, -}); + } +} diff --git a/app/assets/javascripts/discourse/app/components/scrolling-post-stream.js b/app/assets/javascripts/discourse/app/components/scrolling-post-stream.js index ad8f629179f..29063e90623 100644 --- a/app/assets/javascripts/discourse/app/components/scrolling-post-stream.js +++ b/app/assets/javascripts/discourse/app/components/scrolling-post-stream.js @@ -32,14 +32,15 @@ function findTopView(posts, viewportTop, postsWrapperTop, min, max) { return min; } -export default MountWidget.extend({ - screenTrack: service(), - widget: "post-stream", - _topVisible: null, - _bottomVisible: null, - _currentPostObj: null, - _currentVisible: null, - _currentPercent: null, +export default class ScrollingPostStream extends MountWidget { + @service screenTrack; + + widget = "post-stream"; + _topVisible = null; + _bottomVisible = null; + _currentPostObj = null; + _currentVisible = null; + _currentPercent = null; buildArgs() { return this.getProperties( @@ -56,7 +57,7 @@ export default MountWidget.extend({ "lastReadPostNumber", "highestPostNumber" ); - }, + } scrolled() { if (this.isDestroyed || this.isDestroying) { @@ -279,11 +280,11 @@ export default MountWidget.extend({ this._previouslyNearby = newPrev; this.screenTrack.setOnscreen(onscreenPostNumbers, readPostNumbers); - }, + } _scrollTriggered() { scheduleOnce("afterRender", this, this.scrolled); - }, + } _posted(staged) { this.queueRerender(() => { @@ -292,7 +293,7 @@ export default MountWidget.extend({ DiscourseURL.jumpToPost(postNumber, { skipIfOnScreen: true }); } }); - }, + } _refresh(args) { if (args) { @@ -316,15 +317,15 @@ export default MountWidget.extend({ } this.queueRerender(); this._scrollTriggered(); - }, + } @bind _debouncedScroll() { discourseDebounce(this, this._scrollTriggered, DEBOUNCE_DELAY); - }, + } didInsertElement() { - this._super(...arguments); + super.didInsertElement(...arguments); this._previouslyNearby = new Set(); this.appEvents.on("post-stream:refresh", this, "_debouncedScroll"); @@ -357,10 +358,10 @@ export default MountWidget.extend({ DiscourseURL.routeTo(this.location.pathname); } }; - }, + } willDestroyElement() { - this._super(...arguments); + super.willDestroyElement(...arguments); document.removeEventListener("touchmove", this._debouncedScroll); window.removeEventListener("scroll", this._debouncedScroll); @@ -375,12 +376,12 @@ export default MountWidget.extend({ ); this.appEvents.off("post-stream:refresh", this, "_refresh"); this.appEvents.off("post-stream:posted", this, "_posted"); - }, + } didUpdateAttrs() { - this._super(...arguments); + super.didUpdateAttrs(...arguments); this._refresh({ force: true }); - }, + } _handleWidgetButtonHoverState(event) { if (event.target.classList.contains("widget-button")) { @@ -391,11 +392,11 @@ export default MountWidget.extend({ }); event.target.classList.add("d-hover"); } - }, + } _removeWidgetButtonHoverState() { document.querySelectorAll("button.widget-button").forEach((button) => { button.classList.remove("d-hover"); }); - }, -}); + } +} diff --git a/app/assets/javascripts/discourse/app/components/search-advanced-options.js b/app/assets/javascripts/discourse/app/components/search-advanced-options.js index 0faf4c7731b..f97d935d2d4 100644 --- a/app/assets/javascripts/discourse/app/components/search-advanced-options.js +++ b/app/assets/javascripts/discourse/app/components/search-advanced-options.js @@ -1,5 +1,10 @@ import Component from "@ember/component"; import { action } from "@ember/object"; +import { + attributeBindings, + classNames, + tagName, +} from "@ember-decorators/component"; import { escapeExpression } from "discourse/lib/utilities"; import Category from "discourse/models/category"; import I18n from "discourse-i18n"; @@ -79,14 +84,14 @@ export function addAdvancedSearchOptions(options) { _extraOptions.push(options); } -export default Component.extend({ - tagName: "details", - attributeBindings: ["expandFilters:open"], - classNames: ["advanced-filters"], - category: null, +@tagName("details") +@attributeBindings("expandFilters:open") +@classNames("advanced-filters") +export default class SearchAdvancedOptions extends Component { + category = null; init() { - this._super(...arguments); + super.init(...arguments); this.setProperties({ searchedTerms: { @@ -120,10 +125,10 @@ export default Component.extend({ postTimeOptions: postTimeOptions(), showAllTagsCheckbox: false, }); - }, + } didReceiveAttrs() { - this._super(...arguments); + super.didReceiveAttrs(...arguments); this.setSearchedTermValue("searchedTerms.username", REGEXP_USERNAME_PREFIX); this.setSearchedTermValueForCategory(); @@ -192,7 +197,7 @@ export default Component.extend({ "searchedTerms.max_views", REGEXP_MAX_VIEWS_PREFIX ); - }, + } findSearchTerms() { const searchTerm = escapeExpression(this.searchTerm); @@ -213,7 +218,7 @@ export default Component.extend({ }); return result; - }, + } filterBlocks(regexPrefix) { const blocks = this.findSearchTerms(); @@ -229,7 +234,7 @@ export default Component.extend({ }); return result; - }, + } setSearchedTermValue(key, replaceRegEx, matchRegEx = null) { matchRegEx = matchRegEx || replaceRegEx; @@ -245,7 +250,7 @@ export default Component.extend({ } else if (val && val.length !== 0) { this.set(key, null); } - }, + } setSearchedTermSpecialInValue(key, replaceRegEx) { const match = this.filterBlocks(replaceRegEx); @@ -257,7 +262,7 @@ export default Component.extend({ } else if (this.get(key) !== false) { this.set(key, false); } - }, + } setSearchedTermValueForCategory() { const match = this.filterBlocks(REGEXP_CATEGORY_PREFIX); @@ -296,7 +301,7 @@ export default Component.extend({ } else { this.set("searchedTerms.category", null); } - }, + } setSearchedTermValueForTags() { if (!this.siteSettings.tagging_enabled) { @@ -324,7 +329,7 @@ export default Component.extend({ } else if (!tags) { this.set("searchedTerms.tags", null); } - }, + } setSearchedTermValueForPostTime() { const match = this.filterBlocks(REGEXP_POST_TIME_PREFIX); @@ -351,7 +356,7 @@ export default Component.extend({ this.set("searchedTerms.time.when", "before"); this.set("searchedTerms.time.days", null); } - }, + } updateInRegex(regex, filter) { const match = this.filterBlocks(regex); @@ -367,43 +372,43 @@ export default Component.extend({ searchTerm = searchTerm.replace(match, ""); this._updateSearchTerm(searchTerm); } - }, + } @action onChangeSearchTermMinPostCount(value) { this.set("searchedTerms.min_posts", value.length ? value : null); this._updateSearchTermForMinPostCount(); - }, + } @action onChangeSearchTermMaxPostCount(value) { this.set("searchedTerms.max_posts", value.length ? value : null); this._updateSearchTermForMaxPostCount(); - }, + } @action onChangeSearchTermMinViews(value) { this.set("searchedTerms.min_views", value.length ? value : null); this._updateSearchTermForMinViews(); - }, + } @action onChangeSearchTermMaxViews(value) { this.set("searchedTerms.max_views", value.length ? value : null); this._updateSearchTermForMaxViews(); - }, + } @action onChangeSearchTermForIn(value) { this.set("searchedTerms.in", value); this._updateSearchTermForIn(); - }, + } @action onChangeSearchTermForStatus(value) { this.set("searchedTerms.status", value); this._updateSearchTermForStatus(); - }, + } @action onChangeWhenTime(time) { @@ -411,7 +416,7 @@ export default Component.extend({ this.set("searchedTerms.time.when", time); this._updateSearchTermForPostTime(); } - }, + } @action onChangeWhenDate(date) { @@ -419,7 +424,7 @@ export default Component.extend({ this.set("searchedTerms.time.days", date.format("YYYY-MM-DD")); this._updateSearchTermForPostTime(); } - }, + } @action onChangeSearchTermForCategory(categoryId) { @@ -433,55 +438,55 @@ export default Component.extend({ } this._updateSearchTermForCategory(); - }, + } @action onChangeSearchTermForUsername(username) { this.set("searchedTerms.username", username.length ? username : null); this._updateSearchTermForUsername(); - }, + } @action onChangeSearchTermForTags(tags) { this.set("searchedTerms.tags", tags.length ? tags : null); this._updateSearchTermForTags(); - }, + } @action onChangeSearchTermForAllTags(checked) { this.set("searchedTerms.special.all_tags", checked); this._updateSearchTermForTags(); - }, + } @action onChangeSearchTermForSpecialInLikes(checked) { this.set("searchedTerms.special.in.likes", checked); this.updateInRegex(REGEXP_SPECIAL_IN_LIKES_MATCH, "likes"); - }, + } @action onChangeSearchTermForSpecialInMessages(checked) { this.set("searchedTerms.special.in.messages", checked); this.updateInRegex(REGEXP_SPECIAL_IN_MESSAGES_MATCH, "messages"); - }, + } @action onChangeSearchTermForSpecialInSeen(checked) { this.set("searchedTerms.special.in.seen", checked); this.updateInRegex(REGEXP_SPECIAL_IN_SEEN_MATCH, "seen"); - }, + } @action onChangeSearchTermForSpecialInTitle(checked) { this.set("searchedTerms.special.in.title", checked); this.updateInRegex(REGEXP_SPECIAL_IN_TITLE_MATCH, "title"); - }, + } @action onChangeSearchedTermField(path, updateFnName, value) { this.set(`searchedTerms.${path}`, value); this[updateFnName](); - }, + } _updateSearchTermForTags() { const match = this.filterBlocks(REGEXP_TAGS_PREFIX); @@ -507,7 +512,7 @@ export default Component.extend({ searchTerm = searchTerm.replace(match[0], ""); this._updateSearchTerm(searchTerm); } - }, + } _updateSearchTermForCategory() { const match = this.filterBlocks(REGEXP_CATEGORY_PREFIX); @@ -566,7 +571,7 @@ export default Component.extend({ this._updateSearchTerm(searchTerm); } - }, + } _updateSearchTermForUsername() { const match = this.filterBlocks(REGEXP_USERNAME_PREFIX); @@ -585,7 +590,7 @@ export default Component.extend({ searchTerm = searchTerm.replace(match[0], ""); this._updateSearchTerm(searchTerm); } - }, + } _updateSearchTermForPostTime() { const match = this.filterBlocks(REGEXP_POST_TIME_PREFIX); @@ -605,7 +610,7 @@ export default Component.extend({ searchTerm = searchTerm.replace(match[0], ""); this._updateSearchTerm(searchTerm); } - }, + } _updateSearchTermForIn() { let regExpInMatch = this.inOptions.map((option) => option.value).join("|"); @@ -631,7 +636,7 @@ export default Component.extend({ searchTerm = searchTerm.replace(match, ""); this._updateSearchTerm(searchTerm); } - }, + } _updateSearchTermForStatus() { let regExpStatusMatch = this.statusOptions @@ -658,7 +663,7 @@ export default Component.extend({ searchTerm = searchTerm.replace(match[0], ""); this._updateSearchTerm(searchTerm); } - }, + } _updateSearchTermForMinPostCount() { const match = this.filterBlocks(REGEXP_MIN_POSTS_PREFIX); @@ -680,7 +685,7 @@ export default Component.extend({ searchTerm = searchTerm.replace(match[0], ""); this._updateSearchTerm(searchTerm); } - }, + } _updateSearchTermForMaxPostCount() { const match = this.filterBlocks(REGEXP_MAX_POSTS_PREFIX); @@ -702,7 +707,7 @@ export default Component.extend({ searchTerm = searchTerm.replace(match[0], ""); this._updateSearchTerm(searchTerm); } - }, + } _updateSearchTermForMinViews() { const match = this.filterBlocks(REGEXP_MIN_VIEWS_PREFIX); @@ -724,7 +729,7 @@ export default Component.extend({ searchTerm = searchTerm.replace(match[0], ""); this._updateSearchTerm(searchTerm); } - }, + } _updateSearchTermForMaxViews() { const match = this.filterBlocks(REGEXP_MAX_VIEWS_PREFIX); @@ -746,9 +751,9 @@ export default Component.extend({ searchTerm = searchTerm.replace(match[0], ""); this._updateSearchTerm(searchTerm); } - }, + } _updateSearchTerm(searchTerm) { this.onChangeSearchTerm(searchTerm.trim()); - }, -}); + } +} diff --git a/app/assets/javascripts/discourse/app/components/search-result-entries.js b/app/assets/javascripts/discourse/app/components/search-result-entries.js index 44494409ab5..b11dbe5a61a 100644 --- a/app/assets/javascripts/discourse/app/components/search-result-entries.js +++ b/app/assets/javascripts/discourse/app/components/search-result-entries.js @@ -1,5 +1,5 @@ import Component from "@ember/component"; +import { tagName } from "@ember-decorators/component"; -export default Component.extend({ - tagName: "", -}); +@tagName("") +export default class SearchResultEntries extends Component {} diff --git a/app/assets/javascripts/discourse/app/components/search-result-entry.js b/app/assets/javascripts/discourse/app/components/search-result-entry.js index 0b2004ec490..86aa22c7631 100644 --- a/app/assets/javascripts/discourse/app/components/search-result-entry.js +++ b/app/assets/javascripts/discourse/app/components/search-result-entry.js @@ -1,14 +1,20 @@ import Component from "@ember/component"; import { action } from "@ember/object"; +import { + attributeBindings, + classNameBindings, + classNames, + tagName, +} from "@ember-decorators/component"; import { wantsNewWindow } from "discourse/lib/intercept-click"; import { logSearchLinkClick } from "discourse/lib/search"; -export default Component.extend({ - tagName: "div", - classNames: ["fps-result"], - classNameBindings: ["bulkSelectEnabled"], - attributeBindings: ["role"], - role: "listitem", +@tagName("div") +@classNames("fps-result") +@classNameBindings("bulkSelectEnabled") +@attributeBindings("role") +export default class SearchResultEntry extends Component { + role = "listitem"; @action logClick(topicId, event) { @@ -24,5 +30,5 @@ export default Component.extend({ searchResultType: "topic", }); } - }, -}); + } +} diff --git a/app/assets/javascripts/discourse/app/components/search-text-field.js b/app/assets/javascripts/discourse/app/components/search-text-field.js index 3bbcdd8a94d..772bf2a1001 100644 --- a/app/assets/javascripts/discourse/app/components/search-text-field.js +++ b/app/assets/javascripts/discourse/app/components/search-text-field.js @@ -1,16 +1,17 @@ +import { on } from "@ember-decorators/object"; import $ from "jquery"; import TextField from "discourse/components/text-field"; import { applySearchAutocomplete } from "discourse/lib/search"; -import discourseComputed, { on } from "discourse-common/utils/decorators"; +import discourseComputed from "discourse-common/utils/decorators"; import I18n from "discourse-i18n"; -export default TextField.extend({ - autocomplete: "off", +export default class SearchTextField extends TextField { + autocomplete = "off"; @discourseComputed("searchService.searchContextEnabled") placeholder(searchContextEnabled) { return searchContextEnabled ? "" : I18n.t("search.full_page_title"); - }, + } @on("didInsertElement") becomeFocused() { @@ -24,5 +25,5 @@ export default TextField.extend({ // at the top of the page $(window).scrollTop(0); $searchInput.focus(); - }, -}); + } +} diff --git a/app/assets/javascripts/discourse/app/components/second-factor-form.js b/app/assets/javascripts/discourse/app/components/second-factor-form.js index ca73e29d015..2d7418d56f2 100644 --- a/app/assets/javascripts/discourse/app/components/second-factor-form.js +++ b/app/assets/javascripts/discourse/app/components/second-factor-form.js @@ -4,7 +4,7 @@ import { SECOND_FACTOR_METHODS } from "discourse/models/user"; import discourseComputed from "discourse-common/utils/decorators"; import I18n from "discourse-i18n"; -export default Component.extend({ +export default class SecondFactorForm extends Component { @discourseComputed("secondFactorMethod") secondFactorTitle(secondFactorMethod) { switch (secondFactorMethod) { @@ -15,7 +15,7 @@ export default Component.extend({ case SECOND_FACTOR_METHODS.BACKUP_CODE: return I18n.t("login.second_factor_backup_title"); } - }, + } @discourseComputed("secondFactorMethod") secondFactorDescription(secondFactorMethod) { @@ -27,7 +27,7 @@ export default Component.extend({ case SECOND_FACTOR_METHODS.BACKUP_CODE: return I18n.t("login.second_factor_backup_description"); } - }, + } @discourseComputed("secondFactorMethod", "isLogin") linkText(secondFactorMethod, isLogin) { @@ -40,7 +40,7 @@ export default Component.extend({ ? "user.second_factor_backup.use" : "user.second_factor.use"; } - }, + } @discourseComputed("backupEnabled", "totpEnabled", "secondFactorMethod") showToggleMethodLink(backupEnabled, totpEnabled, secondFactorMethod) { @@ -49,7 +49,7 @@ export default Component.extend({ totpEnabled && secondFactorMethod !== SECOND_FACTOR_METHODS.SECURITY_KEY ); - }, + } @action toggleSecondFactorMethod(event) { @@ -61,5 +61,5 @@ export default Component.extend({ } else { this.set("secondFactorMethod", SECOND_FACTOR_METHODS.TOTP); } - }, -}); + } +} diff --git a/app/assets/javascripts/discourse/app/components/selected-posts.js b/app/assets/javascripts/discourse/app/components/selected-posts.js index 87d5ddb040f..d722fe78e7f 100644 --- a/app/assets/javascripts/discourse/app/components/selected-posts.js +++ b/app/assets/javascripts/discourse/app/components/selected-posts.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class SelectedPosts extends Component {} diff --git a/app/assets/javascripts/discourse/app/components/share-panel.js b/app/assets/javascripts/discourse/app/components/share-panel.js index 56805af04e5..29c0057d148 100644 --- a/app/assets/javascripts/discourse/app/components/share-panel.js +++ b/app/assets/javascripts/discourse/app/components/share-panel.js @@ -8,11 +8,12 @@ import discourseLater from "discourse-common/lib/later"; import discourseComputed from "discourse-common/utils/decorators"; import I18n from "discourse-i18n"; -export default Component.extend({ - tagName: null, - type: alias("panel.model.type"), - topic: alias("panel.model.topic"), - privateCategory: alias("panel.model.topic.category.read_restricted"), +export default class SharePanel extends Component { + tagName = null; + + @alias("panel.model.type") type; + @alias("panel.model.topic") topic; + @alias("panel.model.topic.category.read_restricted") privateCategory; @discourseComputed("topic.{isPrivateMessage,invisible,category}") sources(topic) { @@ -22,13 +23,13 @@ export default Component.extend({ (topic && topic.invisible) || this.privateCategory; return Sharing.activeSources(this.siteSettings.share_links, privateContext); - }, + } @discourseComputed("type", "topic.title") shareTitle(type, topicTitle) { topicTitle = escapeExpression(topicTitle); return I18n.t("share.topic_html", { topicTitle }); - }, + } @discourseComputed("panel.model.shareUrl", "topic.shareUrl") shareUrl(forcedShareUrl, shareUrl) { @@ -45,10 +46,10 @@ export default Component.extend({ } return encodeURI(shareUrl); - }, + } didInsertElement() { - this._super(...arguments); + super.didInsertElement(...arguments); discourseLater(() => { if (this.element) { const textArea = this.element.querySelector(".topic-share-url"); @@ -57,7 +58,7 @@ export default Component.extend({ textArea.setSelectionRange(0, this.shareUrl.length); } }, 200); - }, + } @action share(source) { @@ -65,5 +66,5 @@ export default Component.extend({ url: this.shareUrl, title: this.topic.get("title"), }); - }, -}); + } +} diff --git a/app/assets/javascripts/discourse/app/components/shared-draft-controls.js b/app/assets/javascripts/discourse/app/components/shared-draft-controls.js index c79dff1c1fc..a87676b84b5 100644 --- a/app/assets/javascripts/discourse/app/components/shared-draft-controls.js +++ b/app/assets/javascripts/discourse/app/components/shared-draft-controls.js @@ -1,43 +1,46 @@ import Component from "@ember/component"; +import { action } from "@ember/object"; import { service } from "@ember/service"; +import { tagName } from "@ember-decorators/component"; import discourseComputed from "discourse-common/utils/decorators"; import I18n from "discourse-i18n"; -export default Component.extend({ - tagName: "", - dialog: service(), - publishing: false, +@tagName("") +export default class SharedDraftControls extends Component { + @service dialog; + + publishing = false; @discourseComputed("topic.destination_category_id") validCategory(destCatId) { return destCatId && destCatId !== this.site.shared_drafts_category_id; - }, + } - actions: { - updateDestinationCategory(categoryId) { - return this.topic.updateDestinationCategory(categoryId); - }, + @action + updateDestinationCategory(categoryId) { + return this.topic.updateDestinationCategory(categoryId); + } - publish() { - this.dialog.yesNoConfirm({ - message: I18n.t("shared_drafts.confirm_publish"), - didConfirm: () => { - this.set("publishing", true); - const destinationCategoryId = this.topic.destination_category_id; - return this.topic - .publish() - .then(() => { - this.topic.setProperties({ - category_id: destinationCategoryId, - destination_category_id: undefined, - is_shared_draft: false, - }); - }) - .finally(() => { - this.set("publishing", false); + @action + publish() { + this.dialog.yesNoConfirm({ + message: I18n.t("shared_drafts.confirm_publish"), + didConfirm: () => { + this.set("publishing", true); + const destinationCategoryId = this.topic.destination_category_id; + return this.topic + .publish() + .then(() => { + this.topic.setProperties({ + category_id: destinationCategoryId, + destination_category_id: undefined, + is_shared_draft: false, }); - }, - }); - }, - }, -}); + }) + .finally(() => { + this.set("publishing", false); + }); + }, + }); + } +} diff --git a/app/assets/javascripts/discourse/app/components/signup-cta.js b/app/assets/javascripts/discourse/app/components/signup-cta.js index c6f98c651bb..3ed1b0a5be3 100644 --- a/app/assets/javascripts/discourse/app/components/signup-cta.js +++ b/app/assets/javascripts/discourse/app/components/signup-cta.js @@ -1,29 +1,29 @@ import Component from "@ember/component"; import { action } from "@ember/object"; -import { on } from "@ember/object/evented"; +import { on } from "@ember-decorators/object"; import discourseLater from "discourse-common/lib/later"; -export default Component.extend({ - action: "showCreateAccount", +export default class SignupCta extends Component { + action = "showCreateAccount"; @action neverShow(event) { event?.preventDefault(); this.keyValueStore.setItem("anon-cta-never", "t"); this.session.set("showSignupCta", false); - }, + } - actions: { - hideForSession() { - this.session.set("hideSignupCta", true); - this.keyValueStore.setItem("anon-cta-hidden", Date.now()); - discourseLater(() => this.session.set("showSignupCta", false), 20 * 1000); - }, - }, + @action + hideForSession() { + this.session.set("hideSignupCta", true); + this.keyValueStore.setItem("anon-cta-hidden", Date.now()); + discourseLater(() => this.session.set("showSignupCta", false), 20 * 1000); + } - _turnOffIfHidden: on("willDestroyElement", function () { + @on("willDestroyElement") + _turnOffIfHidden() { if (this.session.get("hideSignupCta")) { this.session.set("showSignupCta", false); } - }), -}); + } +} diff --git a/app/assets/javascripts/discourse/app/components/slow-mode-info.js b/app/assets/javascripts/discourse/app/components/slow-mode-info.js index 49e41347a10..75c37095db9 100644 --- a/app/assets/javascripts/discourse/app/components/slow-mode-info.js +++ b/app/assets/javascripts/discourse/app/components/slow-mode-info.js @@ -5,21 +5,21 @@ import { popupAjaxError } from "discourse/lib/ajax-error"; import Topic from "discourse/models/topic"; import discourseComputed from "discourse-common/utils/decorators"; -export default Component.extend({ +export default class SlowModeInfo extends Component { @discourseComputed("topic.slow_mode_seconds") durationText(seconds) { return durationTextFromSeconds(seconds); - }, + } @discourseComputed("topic.slow_mode_seconds", "topic.closed") showSlowModeNotice(seconds, closed) { return seconds > 0 && !closed; - }, + } @action disableSlowMode() { Topic.setSlowMode(this.topic.id, 0) .catch(popupAjaxError) .then(() => this.set("topic.slow_mode_seconds", 0)); - }, -}); + } +} diff --git a/app/assets/javascripts/discourse/app/components/sub-category-item.js b/app/assets/javascripts/discourse/app/components/sub-category-item.js index 5d22a613297..888c2d17242 100644 --- a/app/assets/javascripts/discourse/app/components/sub-category-item.js +++ b/app/assets/javascripts/discourse/app/components/sub-category-item.js @@ -1,3 +1,3 @@ import CategoryListItem from "discourse/components/category-list-item"; -export default CategoryListItem.extend({}); +export default class SubCategoryItem extends CategoryListItem {} diff --git a/app/assets/javascripts/discourse/app/components/sub-category-row.js b/app/assets/javascripts/discourse/app/components/sub-category-row.js index 5d22a613297..c9be1502e14 100644 --- a/app/assets/javascripts/discourse/app/components/sub-category-row.js +++ b/app/assets/javascripts/discourse/app/components/sub-category-row.js @@ -1,3 +1,3 @@ import CategoryListItem from "discourse/components/category-list-item"; -export default CategoryListItem.extend({}); +export default class SubCategoryRow extends CategoryListItem {} diff --git a/app/assets/javascripts/discourse/app/components/subcategories-with-featured-topics.js b/app/assets/javascripts/discourse/app/components/subcategories-with-featured-topics.js index 87d5ddb040f..0cdcac41b2b 100644 --- a/app/assets/javascripts/discourse/app/components/subcategories-with-featured-topics.js +++ b/app/assets/javascripts/discourse/app/components/subcategories-with-featured-topics.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class SubcategoriesWithFeaturedTopics extends Component {}