From d1cc60c435e5cec989721e732533bab2026ad6e6 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Fri, 23 Aug 2024 12:17:07 +0100 Subject: [PATCH] DEV: Convert select-kit components to native class syntax (#28489) Changes made using the ember-native-class-codemod, plus some manual tweaks --- .../bulk-select-bookmarks-dropdown.js | 31 +-- .../components/categories-admin-dropdown.js | 35 +-- .../addon/components/category-chooser.js | 82 +++--- .../addon/components/category-drop.js | 246 +++++++++--------- .../category-drop/category-drop-header.js | 12 +- .../category-notifications-button.js | 23 +- .../addon/components/category-selector.js | 64 ++--- .../addon/components/color-palettes.js | 20 +- .../color-palettes/color-palettes-row.js | 18 +- .../select-kit/addon/components/combo-box.js | 28 +- .../components/combo-box/combo-box-header.js | 27 +- .../addon/components/composer-actions.js | 135 +++++----- .../addon/components/create-color-row.js | 12 +- .../addon/components/dropdown-select-box.js | 36 +-- .../dropdown-select-box-header.js | 43 ++- .../dropdown-select-box-row.js | 9 +- .../email-group-user-chooser-filter.js | 10 +- .../email-group-user-chooser-row.js | 6 +- .../components/email-group-user-chooser.js | 36 +-- .../addon/components/flair-chooser.js | 49 ++-- .../select-kit/addon/components/flair-row.js | 6 +- .../addon/components/form-template-chooser.js | 38 +-- .../components/future-date-input-selector.js | 53 ++-- .../future-date-input-selector-header.js | 6 +- .../future-date-input-selector-row.js | 6 +- .../addon/components/group-chooser.js | 18 +- .../addon/components/group-dropdown.js | 57 ++-- .../components/group-notifications-button.js | 19 +- .../addon/components/icon-picker.js | 55 ++-- .../addon/components/list-setting.js | 42 +-- .../addon/components/mini-tag-chooser.js | 76 +++--- .../mini-tag-chooser/selected-collection.js | 14 +- .../multi-select/format-selected-content.js | 18 +- .../multi-select/multi-select-filter.js | 12 +- .../multi-select/multi-select-header.js | 33 +-- .../multi-select/selected-category.js | 13 +- .../components/multi-select/selected-color.js | 10 +- .../addon/components/none-category-row.js | 10 +- .../addon/components/notifications-button.js | 41 +-- .../notifications-button-row.js | 31 ++- .../addon/components/notifications-filter.js | 22 +- .../notifications-filter-header.js | 11 +- .../addon/components/period-chooser.js | 58 +++-- .../period-chooser/period-chooser-header.js | 10 +- .../period-chooser/period-chooser-row.js | 10 +- .../addon/components/pinned-button.js | 18 +- .../addon/components/pinned-options.js | 30 ++- .../search-advanced-category-chooser.js | 27 +- .../select-kit/errors-collection.js | 6 +- .../components/select-kit/select-kit-body.js | 27 +- .../select-kit/select-kit-collection.js | 14 +- .../select-kit/select-kit-create-row.js | 6 +- .../select-kit/select-kit-filter.js | 50 ++-- .../select-kit/select-kit-header.js | 72 ++--- .../select-kit/select-kit-none-row.js | 6 +- .../components/select-kit/select-kit-row.js | 134 +++++----- .../select-kit/single-select-header.js | 25 +- .../components/selected-choice-category.js | 14 +- .../addon/components/selected-choice-color.js | 19 +- .../addon/components/selected-choice.js | 39 +-- .../addon/components/selected-color.js | 12 +- .../addon/components/selected-flair.js | 6 +- .../addon/components/selected-name.js | 58 +++-- .../addon/components/tag-chooser-row.js | 6 +- .../addon/components/tag-chooser.js | 108 ++++---- .../select-kit/addon/components/tag-drop.js | 144 +++++----- .../components/tag-drop/tag-drop-header.js | 6 +- .../addon/components/tag-group-chooser.js | 45 ++-- .../components/tag-notifications-button.js | 21 +- .../select-kit/addon/components/tag-row.js | 10 +- .../components/tags-intersection-chooser.js | 23 +- .../addon/components/timezone-input.js | 31 ++- .../components/toolbar-popup-menu-options.js | 31 ++- .../toolbar-popup-menu-options-heading.js | 2 +- .../addon/components/topic-chooser.js | 37 +-- .../topic-footer-mobile-dropdown.js | 35 +-- .../components/topic-notifications-button.js | 32 +-- .../components/topic-notifications-options.js | 31 ++- .../select-kit/addon/components/topic-row.js | 6 +- .../addon/components/user-chooser.js | 75 +++--- .../addon/components/user-chooser/user-row.js | 6 +- .../components/user-notifications-dropdown.js | 55 ++-- .../addon/components/watched-words.js | 29 ++- 83 files changed, 1528 insertions(+), 1359 deletions(-) diff --git a/app/assets/javascripts/select-kit/addon/components/bulk-select-bookmarks-dropdown.js b/app/assets/javascripts/select-kit/addon/components/bulk-select-bookmarks-dropdown.js index e5fc1c59709..a1e66276d7d 100644 --- a/app/assets/javascripts/select-kit/addon/components/bulk-select-bookmarks-dropdown.js +++ b/app/assets/javascripts/select-kit/addon/components/bulk-select-bookmarks-dropdown.js @@ -1,9 +1,11 @@ import { action } from "@ember/object"; import { service } from "@ember/service"; +import { classNames } from "@ember-decorators/component"; import { popupAjaxError } from "discourse/lib/ajax-error"; import Bookmark from "discourse/models/bookmark"; import i18n from "discourse-common/helpers/i18n"; import DropdownSelectBoxComponent from "select-kit/components/dropdown-select-box"; +import { selectKitOptions } from "./select-kit"; const _customButtons = []; const _customActions = {}; @@ -12,19 +14,18 @@ export function addBulkDropdownAction(name, customAction) { _customActions[name] = customAction; } -export default DropdownSelectBoxComponent.extend({ - classNames: ["bulk-select-bookmarks-dropdown"], - headerIcon: null, +@classNames("bulk-select-bookmarks-dropdown") +@selectKitOptions({ + showCaret: true, showFullTitle: true, - selectKitOptions: { - showCaret: true, - showFullTitle: true, - none: "select_kit.components.bulk_select_bookmarks_dropdown.title", - }, + none: "select_kit.components.bulk_select_bookmarks_dropdown.title", +}) +export default class BulkSelectBookmarksDropdown extends DropdownSelectBoxComponent { + @service router; + @service toasts; + @service dialog; - router: service(), - toasts: service(), - dialog: service(), + headerIcon = null; get content() { let options = []; @@ -42,11 +43,11 @@ export default DropdownSelectBoxComponent.extend({ ]); return [...options, ..._customButtons]; - }, + } getSelectedBookmarks() { return this.bulkSelectHelper.selected; - }, + } @action onSelect(id) { @@ -99,5 +100,5 @@ export default DropdownSelectBoxComponent.extend({ }, }); } - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/categories-admin-dropdown.js b/app/assets/javascripts/select-kit/addon/components/categories-admin-dropdown.js index 7a25ba23b39..22bdaf63934 100644 --- a/app/assets/javascripts/select-kit/addon/components/categories-admin-dropdown.js +++ b/app/assets/javascripts/select-kit/addon/components/categories-admin-dropdown.js @@ -1,21 +1,22 @@ import { computed } from "@ember/object"; +import { classNames } from "@ember-decorators/component"; import I18n from "discourse-i18n"; import DropdownSelectBoxComponent from "select-kit/components/dropdown-select-box"; +import { pluginApiIdentifiers, selectKitOptions } from "./select-kit"; -export default DropdownSelectBoxComponent.extend({ - pluginApiIdentifiers: ["categories-admin-dropdown"], - classNames: ["categories-admin-dropdown"], - - selectKitOptions: { - icons: ["wrench", "caret-down"], - showFullTitle: false, - autoFilterable: false, - filterable: false, - none: "select_kit.components.categories_admin_dropdown.title", - focusAfterOnChange: false, - }, - - content: computed(function () { +@classNames("categories-admin-dropdown") +@selectKitOptions({ + icons: ["wrench", "caret-down"], + showFullTitle: false, + autoFilterable: false, + filterable: false, + none: "select_kit.components.categories_admin_dropdown.title", + focusAfterOnChange: false, +}) +@pluginApiIdentifiers(["categories-admin-dropdown"]) +export default class CategoriesAdminDropdown extends DropdownSelectBoxComponent { + @computed + get content() { const items = [ { id: "create", @@ -33,7 +34,7 @@ export default DropdownSelectBoxComponent.extend({ }); return items; - }), + } _onChange(value, item) { if (item.onChange) { @@ -41,5 +42,5 @@ export default DropdownSelectBoxComponent.extend({ } else if (this.onChange) { this.onChange(value, item); } - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/category-chooser.js b/app/assets/javascripts/select-kit/addon/components/category-chooser.js index 9188d94a593..31f75d57cc5 100644 --- a/app/assets/javascripts/select-kit/addon/components/category-chooser.js +++ b/app/assets/javascripts/select-kit/addon/components/category-chooser.js @@ -1,6 +1,7 @@ import { computed, set } from "@ember/object"; import { htmlSafe } from "@ember/template"; import { isNone } from "@ember/utils"; +import { classNames } from "@ember-decorators/component"; import { categoryBadgeHTML } from "discourse/helpers/category-link"; import { setting } from "discourse/lib/computed"; import Category from "discourse/models/category"; @@ -8,26 +9,26 @@ import PermissionType from "discourse/models/permission-type"; import I18n from "discourse-i18n"; import CategoryRow from "select-kit/components/category-row"; import ComboBoxComponent from "select-kit/components/combo-box"; +import { pluginApiIdentifiers, selectKitOptions } from "./select-kit"; -export default ComboBoxComponent.extend({ - pluginApiIdentifiers: ["category-chooser"], - classNames: ["category-chooser"], - allowUncategorized: setting("allow_uncategorized_topics"), - fixedCategoryPositionsOnCreate: setting("fixed_category_positions_on_create"), - - selectKitOptions: { - filterable: true, - allowUncategorized: "allowUncategorized", - autoInsertNoneItem: false, - allowSubCategories: true, - permissionType: PermissionType.FULL, - excludeCategoryId: null, - scopedCategoryId: null, - prioritizedCategoryId: null, - }, +@classNames("category-chooser") +@selectKitOptions({ + filterable: true, + allowUncategorized: "allowUncategorized", + autoInsertNoneItem: false, + allowSubCategories: true, + permissionType: PermissionType.FULL, + excludeCategoryId: null, + scopedCategoryId: null, + prioritizedCategoryId: null, +}) +@pluginApiIdentifiers(["category-chooser"]) +export default class CategoryChooser extends ComboBoxComponent { + @setting("allow_uncategorized_topics") allowUncategorized; + @setting("fixed_category_positions_on_create") fixedCategoryPositionsOnCreate; init() { - this._super(...arguments); + super.init(...arguments); if ( this.site.lazy_load_categories && @@ -40,11 +41,11 @@ export default ComboBoxComponent.extend({ this.notifyPropertyChange("value"); }); } - }, + } modifyComponentForRow() { return CategoryRow; - }, + } modifyNoSelection() { if (!isNone(this.selectKit.options.none)) { @@ -67,7 +68,7 @@ export default ComboBoxComponent.extend({ return this.defaultItem(null, htmlSafe(I18n.t("category.choose"))); } } - }, + } modifySelection(content) { if (this.selectKit.hasSelection) { @@ -88,7 +89,7 @@ export default ComboBoxComponent.extend({ } return content; - }, + } search(filter) { if (this.site.lazy_load_categories) { @@ -119,29 +120,28 @@ export default ComboBoxComponent.extend({ } else { return this.content; } - }, + } - content: computed( + @computed( "selectKit.filter", "selectKit.options.scopedCategoryId", - "selectKit.options.prioritizedCategoryId", - function () { - if (!this.selectKit.filter) { - let { scopedCategoryId, prioritizedCategoryId } = - this.selectKit.options; + "selectKit.options.prioritizedCategoryId" + ) + get content() { + if (!this.selectKit.filter) { + let { scopedCategoryId, prioritizedCategoryId } = this.selectKit.options; - if (scopedCategoryId) { - return this.categoriesByScope({ scopedCategoryId }); - } - - if (prioritizedCategoryId) { - return this.categoriesByScope({ prioritizedCategoryId }); - } + if (scopedCategoryId) { + return this.categoriesByScope({ scopedCategoryId }); } - return this.categoriesByScope(); + if (prioritizedCategoryId) { + return this.categoriesByScope({ prioritizedCategoryId }); + } } - ), + + return this.categoriesByScope(); + } categoriesByScope({ scopedCategoryId = null, @@ -218,14 +218,14 @@ export default ComboBoxComponent.extend({ } else { return scopedCategories; } - }, + } _matchCategory(filter, categoryName) { return this._normalize(categoryName).includes(filter); - }, + } _onChange(value) { this._boundaryActionHandler("onChangeCategory", Category.findById(value)); return true; - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/category-drop.js b/app/assets/javascripts/select-kit/addon/components/category-drop.js index 703a5521280..08f368cd84a 100644 --- a/app/assets/javascripts/select-kit/addon/components/category-drop.js +++ b/app/assets/javascripts/select-kit/addon/components/category-drop.js @@ -1,6 +1,7 @@ -import { computed } from "@ember/object"; +import { action, computed } from "@ember/object"; import { readOnly } from "@ember/object/computed"; import { htmlSafe } from "@ember/template"; +import { classNameBindings, classNames } from "@ember-decorators/component"; import { categoryBadgeHTML } from "discourse/helpers/category-link"; import { setting } from "discourse/lib/computed"; import DiscourseURL, { @@ -12,113 +13,118 @@ import I18n from "discourse-i18n"; import CategoryDropMoreCollection from "select-kit/components/category-drop-more-collection"; import CategoryRow from "select-kit/components/category-row"; import ComboBoxComponent from "select-kit/components/combo-box"; -import { MAIN_COLLECTION } from "select-kit/components/select-kit"; +import { + MAIN_COLLECTION, + pluginApiIdentifiers, + selectKitOptions, +} from "select-kit/components/select-kit"; export const NO_CATEGORIES_ID = "no-categories"; export const ALL_CATEGORIES_ID = "all-categories"; const MORE_COLLECTION = "MORE_COLLECTION"; -export default ComboBoxComponent.extend({ - pluginApiIdentifiers: ["category-drop"], - classNames: ["category-drop"], - classNameBindings: ["noSubcategories:has-selection"], - value: readOnly("category.id"), - content: readOnly("categoriesWithShortcuts.[]"), - noCategoriesLabel: I18n.t("categories.no_subcategories"), - navigateToEdit: false, - editingCategory: false, - editingCategoryTab: null, - allowUncategorized: setting("allow_uncategorized_topics"), +@classNames("category-drop") +@classNameBindings("noSubcategories:has-selection") +@selectKitOptions({ + filterable: true, + none: "category.all", + caretDownIcon: "caret-right", + caretUpIcon: "caret-down", + fullWidthOnMobile: true, + noSubcategories: false, + subCategory: false, + clearable: false, + hideParentCategory: "hideParentCategory", + countSubcategories: false, + autoInsertNoneItem: false, + displayCategoryDescription: "displayCategoryDescription", + headerComponent: "category-drop/category-drop-header", + parentCategory: false, + allowUncategorized: "allowUncategorized", +}) +@pluginApiIdentifiers(["category-drop"]) +export default class CategoryDrop extends ComboBoxComponent { + @readOnly("category.id") value; + @readOnly("categoriesWithShortcuts.[]") content; + @readOnly("selectKit.options.parentCategory.displayName") parentCategoryName; + @setting("allow_uncategorized_topics") allowUncategorized; - selectKitOptions: { - filterable: true, - none: "category.all", - caretDownIcon: "caret-right", - caretUpIcon: "caret-down", - fullWidthOnMobile: true, - noSubcategories: false, - subCategory: false, - clearable: false, - hideParentCategory: "hideParentCategory", - countSubcategories: false, - autoInsertNoneItem: false, - displayCategoryDescription: "displayCategoryDescription", - headerComponent: "category-drop/category-drop-header", - parentCategory: false, - allowUncategorized: "allowUncategorized", - }, + noCategoriesLabel = I18n.t("categories.no_subcategories"); + navigateToEdit = false; + editingCategory = false; + editingCategoryTab = null; init() { - this._super(...arguments); - + super.init(...arguments); this.insertAfterCollection(MAIN_COLLECTION, MORE_COLLECTION); - }, + } modifyComponentForCollection(collection) { if (collection === MORE_COLLECTION) { return CategoryDropMoreCollection; } - }, + } modifyComponentForRow() { return CategoryRow; - }, + } - noSubcategories: computed("selectKit.options.noSubcategories", function () { + @computed("selectKit.options.noSubcategories") + get noSubcategories() { return this.selectKit.options.noSubcategories; - }), + } - displayCategoryDescription: computed(function () { + @computed + get displayCategoryDescription() { return !( this.get("currentUser.staff") || this.get("currentUser.trust_level") > 0 ); - }), + } - hideParentCategory: computed(function () { + @computed + get hideParentCategory() { return this.options.subCategory || false; - }), + } - shortcuts: computed( - "value", - "selectKit.options.{subCategory,noSubcategories}", - function () { - const shortcuts = []; + @computed("value", "selectKit.options.{subCategory,noSubcategories}") + get shortcuts() { + const shortcuts = []; - if ( - (this.value && !this.editingCategory) || - (this.selectKit.options.noSubcategories && - this.selectKit.options.subCategory) - ) { - shortcuts.push({ - id: ALL_CATEGORIES_ID, - name: this.allCategoriesLabel, - }); - } - - if ( - this.selectKit.options.subCategory && - (this.value || !this.selectKit.options.noSubcategories) - ) { - shortcuts.push({ - id: NO_CATEGORIES_ID, - name: this.noCategoriesLabel, - }); - } - - // If there is a single shortcut, we can have a single "remove filter" option - if (shortcuts.length === 1 && shortcuts[0].id === ALL_CATEGORIES_ID) { - shortcuts[0].name = I18n.t("categories.remove_filter"); - } - - return shortcuts; + if ( + (this.value && !this.editingCategory) || + (this.selectKit.options.noSubcategories && + this.selectKit.options.subCategory) + ) { + shortcuts.push({ + id: ALL_CATEGORIES_ID, + name: this.allCategoriesLabel, + }); } - ), - categoriesWithShortcuts: computed("categories.[]", "shortcuts", function () { + if ( + this.selectKit.options.subCategory && + (this.value || !this.selectKit.options.noSubcategories) + ) { + shortcuts.push({ + id: NO_CATEGORIES_ID, + name: this.noCategoriesLabel, + }); + } + + // If there is a single shortcut, we can have a single "remove filter" option + if (shortcuts.length === 1 && shortcuts[0].id === ALL_CATEGORIES_ID) { + shortcuts[0].name = I18n.t("categories.remove_filter"); + } + + return shortcuts; + } + + @computed("categories.[]", "shortcuts") + get categoriesWithShortcuts() { const results = this._filterUncategorized(this.categories || []); return this.shortcuts.concat(results); - }), + } modifyNoSelection() { if (this.selectKit.options.noSubcategories) { @@ -134,7 +140,7 @@ export default ComboBoxComponent.extend({ : I18n.t("categories.categories_label") ); } - }, + } modifySelection(content) { if (this.value) { @@ -150,27 +156,22 @@ export default ComboBoxComponent.extend({ } return content; - }, + } - parentCategoryName: readOnly("selectKit.options.parentCategory.displayName"), - - allCategoriesLabel: computed( - "parentCategoryName", - "selectKit.options.subCategory", - function () { - if (this.editingCategory) { - return this.noCategoriesLabel; - } - - if (this.selectKit.options.subCategory) { - return I18n.t("categories.remove_filter", { - categoryName: this.parentCategoryName, - }); - } - - return I18n.t("categories.all"); + @computed("parentCategoryName", "selectKit.options.subCategory") + get allCategoriesLabel() { + if (this.editingCategory) { + return this.noCategoriesLabel; } - ), + + if (this.selectKit.options.subCategory) { + return I18n.t("categories.remove_filter", { + categoryName: this.parentCategoryName, + }); + } + + return I18n.t("categories.all"); + } async search(filter) { if (this.site.lazy_load_categories) { @@ -221,34 +222,33 @@ export default ComboBoxComponent.extend({ } else { return this._filterUncategorized(this.content); } - }, + } - actions: { - onChange(categoryId) { - const category = - categoryId === ALL_CATEGORIES_ID || categoryId === NO_CATEGORIES_ID - ? this.selectKit.options.parentCategory - : Category.findById(parseInt(categoryId, 10)); + @action + onChange(categoryId) { + const category = + categoryId === ALL_CATEGORIES_ID || categoryId === NO_CATEGORIES_ID + ? this.selectKit.options.parentCategory + : Category.findById(parseInt(categoryId, 10)); - let route; - if (this.editingCategoryTab) { - // rendered on category page - route = getEditCategoryUrl( - category, - categoryId !== NO_CATEGORIES_ID, - this.editingCategoryTab - ); - } else { - route = getCategoryAndTagUrl( - category, - categoryId !== NO_CATEGORIES_ID, - this.tagId - ); - } + let route; + if (this.editingCategoryTab) { + // rendered on category page + route = getEditCategoryUrl( + category, + categoryId !== NO_CATEGORIES_ID, + this.editingCategoryTab + ); + } else { + route = getCategoryAndTagUrl( + category, + categoryId !== NO_CATEGORIES_ID, + this.tagId + ); + } - DiscourseURL.routeToUrl(route); - }, - }, + DiscourseURL.routeToUrl(route); + } _filterUncategorized(content) { if (!this.siteSettings.allow_uncategorized_topics) { @@ -258,5 +258,5 @@ export default ComboBoxComponent.extend({ } return content; - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/category-drop/category-drop-header.js b/app/assets/javascripts/select-kit/addon/components/category-drop/category-drop-header.js index 82c2c03c6b3..f63e625a157 100644 --- a/app/assets/javascripts/select-kit/addon/components/category-drop/category-drop-header.js +++ b/app/assets/javascripts/select-kit/addon/components/category-drop/category-drop-header.js @@ -1,16 +1,16 @@ +import { classNames } from "@ember-decorators/component"; import discourseComputed from "discourse-common/utils/decorators"; import ComboBoxSelectBoxHeaderComponent from "select-kit/components/combo-box/combo-box-header"; -export default ComboBoxSelectBoxHeaderComponent.extend({ - classNames: ["category-drop-header"], - +@classNames("category-drop-header") +export default class CategoryDropHeader extends ComboBoxSelectBoxHeaderComponent { @discourseComputed("selectedContent.color") categoryBackgroundColor(categoryColor) { return categoryColor || "#e9e9e9"; - }, + } @discourseComputed("selectedContent.text_color") categoryTextColor(categoryTextColor) { return categoryTextColor || "#333"; - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/category-notifications-button.js b/app/assets/javascripts/select-kit/addon/components/category-notifications-button.js index d146066e8e1..fb57f40115b 100644 --- a/app/assets/javascripts/select-kit/addon/components/category-notifications-button.js +++ b/app/assets/javascripts/select-kit/addon/components/category-notifications-button.js @@ -1,15 +1,16 @@ import { or } from "@ember/object/computed"; +import { classNames } from "@ember-decorators/component"; import I18n from "discourse-i18n"; import NotificationOptionsComponent from "select-kit/components/notifications-button"; +import { pluginApiIdentifiers, selectKitOptions } from "./select-kit"; -export default NotificationOptionsComponent.extend({ - pluginApiIdentifiers: ["category-notifications-button"], - classNames: ["category-notifications-button"], - isHidden: or("category.deleted"), - - selectKitOptions: { - i18nPrefix: "category.notifications", - showFullTitle: false, - headerAriaLabel: I18n.t("category.notifications.title"), - }, -}); +@selectKitOptions({ + i18nPrefix: "category.notifications", + showFullTitle: false, + headerAriaLabel: I18n.t("category.notifications.title"), +}) +@pluginApiIdentifiers(["category-notifications-button"]) +@classNames("category-notifications-button") +export default class CategoryNotificationsButton extends NotificationOptionsComponent { + @or("category.deleted") isHidden; +} diff --git a/app/assets/javascripts/select-kit/addon/components/category-selector.js b/app/assets/javascripts/select-kit/addon/components/category-selector.js index eb096a7cd79..980b1a3c039 100644 --- a/app/assets/javascripts/select-kit/addon/components/category-selector.js +++ b/app/assets/javascripts/select-kit/addon/components/category-selector.js @@ -1,33 +1,36 @@ -import EmberObject, { computed } from "@ember/object"; +import EmberObject, { action, computed } from "@ember/object"; import { mapBy } from "@ember/object/computed"; +import { classNames } from "@ember-decorators/component"; import Category from "discourse/models/category"; import { makeArray } from "discourse-common/lib/helpers"; import CategoryRow from "select-kit/components/category-row"; import MultiSelectComponent from "select-kit/components/multi-select"; +import { pluginApiIdentifiers, selectKitOptions } from "./select-kit"; -export default MultiSelectComponent.extend({ - pluginApiIdentifiers: ["category-selector"], - classNames: ["category-selector"], - categories: null, - blockedCategories: null, - - selectKitOptions: { - filterable: true, - allowAny: false, - allowUncategorized: true, - displayCategoryDescription: false, - selectedChoiceComponent: "selected-choice-category", - }, +@classNames("category-selector") +@selectKitOptions({ + filterable: true, + allowAny: false, + allowUncategorized: true, + displayCategoryDescription: false, + selectedChoiceComponent: "selected-choice-category", +}) +@pluginApiIdentifiers(["category-selector"]) +export default class CategorySelector extends MultiSelectComponent { + categories = null; + blockedCategories = null; + @mapBy("categories", "id") value; init() { - this._super(...arguments); + super.init(...arguments); if (!this.blockedCategories) { this.set("blockedCategories", []); } - }, + } - content: computed("categories.[]", "blockedCategories.[]", function () { + @computed("categories.[]", "blockedCategories.[]") + get content() { return Category.list().filter((category) => { if (category.isUncategorizedCategory) { if (this.options?.allowUncategorized !== undefined) { @@ -42,13 +45,11 @@ export default MultiSelectComponent.extend({ !this.blockedCategories.includes(category) ); }); - }), - - value: mapBy("categories", "id"), + } modifyComponentForRow() { return CategoryRow; - }, + } async search(filter) { let categories; @@ -66,7 +67,7 @@ export default MultiSelectComponent.extend({ rejectCategoryIds: Array.from(rejectCategoryIds), }); } else { - categories = this._super(filter); + categories = super.search(filter); } // If there is a single match or an exact match and it has subcategories, @@ -91,7 +92,7 @@ export default MultiSelectComponent.extend({ } return categories; - }, + } async select(value, item) { // item is usually a category, but if the "category" property is set, then @@ -113,14 +114,13 @@ export default MultiSelectComponent.extend({ makeArray(this.selectedContent).concat(item.category.descendants) ); } else { - this._super(value, item); + super.select(value, item); } - }, + } - actions: { - onChange(values) { - this.onChange(values.map((v) => Category.findById(v)).filter(Boolean)); - return false; - }, - }, -}); + @action + _onChange(values) { + this.onChange(values.map((v) => Category.findById(v)).filter(Boolean)); + return false; + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/color-palettes.js b/app/assets/javascripts/select-kit/addon/components/color-palettes.js index f8ca6d539f2..7d5c06c62ae 100644 --- a/app/assets/javascripts/select-kit/addon/components/color-palettes.js +++ b/app/assets/javascripts/select-kit/addon/components/color-palettes.js @@ -1,15 +1,15 @@ +import { classNames } from "@ember-decorators/component"; import I18n from "discourse-i18n"; import ComboBoxComponent from "select-kit/components/combo-box"; +import { pluginApiIdentifiers, selectKitOptions } from "./select-kit"; -export default ComboBoxComponent.extend({ - pluginApiIdentifiers: ["color-palettes"], - classNames: ["color-palettes"], - +@classNames("color-palettes") +@selectKitOptions({ + translatedNone: I18n.t("admin.customize.theme.default_light_scheme"), +}) +@pluginApiIdentifiers(["color-palettes"]) +export default class ColorPalettes extends ComboBoxComponent { modifyComponentForRow() { return "color-palettes/color-palettes-row"; - }, - - selectKitOptions: { - translatedNone: I18n.t("admin.customize.theme.default_light_scheme"), - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/color-palettes/color-palettes-row.js b/app/assets/javascripts/select-kit/addon/components/color-palettes/color-palettes-row.js index 91ea0f517b5..93d210b748d 100644 --- a/app/assets/javascripts/select-kit/addon/components/color-palettes/color-palettes-row.js +++ b/app/assets/javascripts/select-kit/addon/components/color-palettes/color-palettes-row.js @@ -1,11 +1,12 @@ import { computed } from "@ember/object"; import { htmlSafe } from "@ember/template"; +import { classNames } from "@ember-decorators/component"; import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row"; -export default SelectKitRowComponent.extend({ - classNames: ["color-palettes-row"], - - palettes: computed("item.colors.[]", function () { +@classNames("color-palettes-row") +export default class ColorPalettesRow extends SelectKitRowComponent { + @computed("item.colors.[]") + get palettes() { return htmlSafe( (this.item.colors || []) .filter((color) => color.name !== "secondary") @@ -16,9 +17,10 @@ export default SelectKitRowComponent.extend({ ) .join("") ); - }), + } - backgroundColor: computed("item.colors.[]", function () { + @computed("item.colors.[]") + get backgroundColor() { const secondary = (this.item.colors || []).findBy("name", "secondary"); if (secondary && secondary.hex) { @@ -26,5 +28,5 @@ export default SelectKitRowComponent.extend({ } else { return ""; } - }), -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/combo-box.js b/app/assets/javascripts/select-kit/addon/components/combo-box.js index 0a0be73938d..b7bcdeb5a78 100644 --- a/app/assets/javascripts/select-kit/addon/components/combo-box.js +++ b/app/assets/javascripts/select-kit/addon/components/combo-box.js @@ -1,17 +1,17 @@ import { gte } from "@ember/object/computed"; +import { classNames } from "@ember-decorators/component"; import SingleSelectComponent from "select-kit/components/single-select"; +import { pluginApiIdentifiers, selectKitOptions } from "./select-kit"; -export default SingleSelectComponent.extend({ - pluginApiIdentifiers: ["combo-box"], - classNames: ["combobox", "combo-box"], - - selectKitOptions: { - caretUpIcon: "caret-up", - caretDownIcon: "caret-down", - autoFilterable: "autoFilterable", - clearable: false, - headerComponent: "combo-box/combo-box-header", - }, - - autoFilterable: gte("content.length", 10), -}); +@classNames("combobox", "combo-box") +@pluginApiIdentifiers(["combo-box"]) +@selectKitOptions({ + caretUpIcon: "caret-up", + caretDownIcon: "caret-down", + autoFilterable: "autoFilterable", + clearable: false, + headerComponent: "combo-box/combo-box-header", +}) +export default class ComboBox extends SingleSelectComponent { + @gte("content.length", 10) autoFilterable; +} diff --git a/app/assets/javascripts/select-kit/addon/components/combo-box/combo-box-header.js b/app/assets/javascripts/select-kit/addon/components/combo-box/combo-box-header.js index cc2f82e5c70..c10426eab5b 100644 --- a/app/assets/javascripts/select-kit/addon/components/combo-box/combo-box-header.js +++ b/app/assets/javascripts/select-kit/addon/components/combo-box/combo-box-header.js @@ -1,20 +1,17 @@ import { computed } from "@ember/object"; import { and, reads } from "@ember/object/computed"; +import { classNames } from "@ember-decorators/component"; import SingleSelectHeaderComponent from "select-kit/components/select-kit/single-select-header"; -export default SingleSelectHeaderComponent.extend({ - classNames: ["combo-box-header"], - clearable: reads("selectKit.options.clearable"), - caretUpIcon: reads("selectKit.options.caretUpIcon"), - caretDownIcon: reads("selectKit.options.caretDownIcon"), - shouldDisplayClearableButton: and("clearable", "value"), +@classNames("combo-box-header") +export default class ComboBoxHeader extends SingleSelectHeaderComponent { + @reads("selectKit.options.clearable") clearable; + @reads("selectKit.options.caretUpIcon") caretUpIcon; + @reads("selectKit.options.caretDownIcon") caretDownIcon; + @and("clearable", "value") shouldDisplayClearableButton; - caretIcon: computed( - "selectKit.isExpanded", - "caretUpIcon", - "caretDownIcon", - function () { - return this.selectKit.isExpanded ? this.caretUpIcon : this.caretDownIcon; - } - ), -}); + @computed("selectKit.isExpanded", "caretUpIcon", "caretDownIcon") + get caretIcon() { + return this.selectKit.isExpanded ? this.caretUpIcon : this.caretDownIcon; + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/composer-actions.js b/app/assets/javascripts/select-kit/addon/components/composer-actions.js index e2af0841d45..af51b92d88e 100644 --- a/app/assets/javascripts/select-kit/addon/components/composer-actions.js +++ b/app/assets/javascripts/select-kit/addon/components/composer-actions.js @@ -1,7 +1,9 @@ +import { action } from "@ember/object"; import { equal, gt } from "@ember/object/computed"; import { service } from "@ember/service"; import { camelize } from "@ember/string"; import { isEmpty } from "@ember/utils"; +import { classNames } from "@ember-decorators/component"; import { escapeExpression } from "discourse/lib/utilities"; import { CREATE_SHARED_DRAFT, @@ -14,6 +16,7 @@ import Draft from "discourse/models/draft"; import discourseComputed from "discourse-common/utils/decorators"; import I18n from "discourse-i18n"; import DropdownSelectBoxComponent from "select-kit/components/dropdown-select-box"; +import { pluginApiIdentifiers, selectKitOptions } from "./select-kit"; // Component can get destroyed and lose state let _topicSnapshot = null; @@ -26,30 +29,37 @@ export function _clearSnapshots() { _actionSnapshot = null; } -export default DropdownSelectBoxComponent.extend({ - dialog: service(), - composer: service(), - seq: 0, - pluginApiIdentifiers: ["composer-actions"], - classNames: ["composer-actions"], - isEditing: equal("action", EDIT), - isInSlowMode: gt("topic.slow_mode_seconds", 0), +@classNames("composer-actions") +@pluginApiIdentifiers(["composer-actions"]) +@selectKitOptions({ + icon: "iconForComposerAction", + filterable: false, + showFullTitle: false, + preventHeaderFocus: true, + customStyle: true, +}) +export default class ComposerActions extends DropdownSelectBoxComponent { + @service dialog; + @service composer; - selectKitOptions: { - icon: "iconForComposerAction", - filterable: false, - showFullTitle: false, - preventHeaderFocus: true, - customStyle: true, - }, + seq = 0; + + @equal("action", EDIT) isEditing; + @gt("topic.slow_mode_seconds", 0) isInSlowMode; @discourseComputed("isEditing", "action", "whisper", "noBump", "isInSlowMode") - iconForComposerAction(isEditing, action, whisper, noBump, isInSlowMode) { - if (action === CREATE_TOPIC) { + iconForComposerAction( + isEditing, + composerAction, + whisper, + noBump, + isInSlowMode + ) { + if (composerAction === CREATE_TOPIC) { return "plus"; - } else if (action === PRIVATE_MESSAGE) { + } else if (composerAction === PRIVATE_MESSAGE) { return "envelope"; - } else if (action === CREATE_SHARED_DRAFT) { + } else if (composerAction === CREATE_SHARED_DRAFT) { return "far-clipboard"; } else if (whisper) { return "far-eye-slash"; @@ -62,14 +72,14 @@ export default DropdownSelectBoxComponent.extend({ } else { return "share"; } - }, + } contentChanged() { this.set("seq", this.seq + 1); - }, + } didReceiveAttrs() { - this._super(...arguments); + super.didReceiveAttrs(...arguments); let changeContent = false; // if we change topic we want to change both snapshots @@ -98,11 +108,11 @@ export default DropdownSelectBoxComponent.extend({ } this.set("selectKit.isHidden", isEmpty(this.content)); - }, + } modifySelection() { return {}; - }, + } @discourseComputed("seq") content() { @@ -233,7 +243,7 @@ export default DropdownSelectBoxComponent.extend({ } return items; - }, + } _continuedFromText(post, topic) { let url = post?.url || topic?.url; @@ -248,7 +258,7 @@ export default DropdownSelectBoxComponent.extend({ return I18n.t("post.continue_discussion", { postLink: link, }); - }, + } _replyFromExisting(options, post, topic) { this.composer.closeComposer(); @@ -256,20 +266,20 @@ export default DropdownSelectBoxComponent.extend({ ...options, prependText: this._continuedFromText(post, topic), }); - }, + } _openComposer(options) { this.composer.closeComposer(); this.composer.open(options); - }, + } toggleWhisperSelected(options, model) { model.toggleProperty("whisper"); - }, + } toggleTopicBumpSelected(options, model) { model.toggleProperty("noBump"); - }, + } replyAsNewGroupMessageSelected(options) { const recipients = []; @@ -284,21 +294,21 @@ export default DropdownSelectBoxComponent.extend({ options.skipDraftCheck = true; this._replyFromExisting(options, _postSnapshot, _topicSnapshot); - }, + } replyToTopicSelected(options) { options.action = REPLY; options.topic = _topicSnapshot; options.skipDraftCheck = true; this._openComposer(options); - }, + } replyToPostSelected(options) { options.action = REPLY; options.post = _postSnapshot; options.skipDraftCheck = true; this._openComposer(options); - }, + } replyAsNewTopicSelected(options) { Draft.get("new_topic").then((response) => { @@ -314,7 +324,7 @@ export default DropdownSelectBoxComponent.extend({ this._replyAsNewTopicSelect(options); } }); - }, + } _replyAsNewTopicSelect(options) { options.action = CREATE_TOPIC; @@ -322,7 +332,7 @@ export default DropdownSelectBoxComponent.extend({ options.disableScopedCategory = true; options.skipDraftCheck = true; this._replyFromExisting(options, _postSnapshot, _topicSnapshot); - }, + } replyAsPrivateMessageSelected(options) { let usernames; @@ -349,44 +359,43 @@ export default DropdownSelectBoxComponent.extend({ options.skipDraftCheck = true; this._replyFromExisting(options, _postSnapshot, _topicSnapshot); - }, + } - _switchCreate(options, action) { - options.action = action; + _switchCreate(options, composerAction) { + options.action = composerAction; options.categoryId = this.get("composerModel.categoryId"); options.topicTitle = this.get("composerModel.title"); options.tags = this.get("composerModel.tags"); options.skipDraftCheck = true; this._openComposer(options); - }, + } createTopicSelected(options) { this._switchCreate(options, CREATE_TOPIC); - }, + } sharedDraftSelected(options) { this._switchCreate(options, CREATE_SHARED_DRAFT); - }, + } - actions: { - onChange(value) { - const action = `${camelize(value)}Selected`; - if (this[action]) { - this[action]( - this.composerModel.getProperties( - "draftKey", - "draftSequence", - "title", - "reply", - "disableScopedCategory" - ), - this.composerModel - ); - this.contentChanged(); - } else { - // eslint-disable-next-line no-console - console.error(`No method '${action}' found`); - } - }, - }, -}); + @action + onChange(value) { + const composerAction = `${camelize(value)}Selected`; + if (this[composerAction]) { + this[composerAction]( + this.composerModel.getProperties( + "draftKey", + "draftSequence", + "title", + "reply", + "disableScopedCategory" + ), + this.composerModel + ); + this.contentChanged(); + } else { + // eslint-disable-next-line no-console + console.error(`No method '${composerAction}' found`); + } + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/create-color-row.js b/app/assets/javascripts/select-kit/addon/components/create-color-row.js index d0eed697bbb..04ed95036db 100644 --- a/app/assets/javascripts/select-kit/addon/components/create-color-row.js +++ b/app/assets/javascripts/select-kit/addon/components/create-color-row.js @@ -1,12 +1,12 @@ import { schedule } from "@ember/runloop"; +import { classNames } from "@ember-decorators/component"; import { escapeExpression } from "discourse/lib/utilities"; import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row"; -export default SelectKitRowComponent.extend({ - classNames: ["create-color-row"], - +@classNames("create-color-row") +export default class CreateColorRow extends SelectKitRowComponent { didReceiveAttrs() { - this._super(...arguments); + super.didReceiveAttrs(...arguments); schedule("afterRender", () => { const color = escapeExpression(this.rowValue); @@ -14,5 +14,5 @@ export default SelectKitRowComponent.extend({ ? color : `#${color}`; }); - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/dropdown-select-box.js b/app/assets/javascripts/select-kit/addon/components/dropdown-select-box.js index 3ddf7d2dc45..d021d1d7b49 100644 --- a/app/assets/javascripts/select-kit/addon/components/dropdown-select-box.js +++ b/app/assets/javascripts/select-kit/addon/components/dropdown-select-box.js @@ -1,22 +1,22 @@ +import { classNames } from "@ember-decorators/component"; import SingleSelectComponent from "select-kit/components/single-select"; +import { pluginApiIdentifiers, selectKitOptions } from "./select-kit"; -export default SingleSelectComponent.extend({ - pluginApiIdentifiers: ["dropdown-select-box"], - classNames: ["dropdown-select-box"], - - selectKitOptions: { - autoFilterable: false, - filterable: false, - showFullTitle: true, - headerComponent: "dropdown-select-box/dropdown-select-box-header", - caretUpIcon: "caret-up", - caretDownIcon: "caret-down", - showCaret: false, - customStyle: null, - btnCustomClasses: null, - }, - +@classNames("dropdown-select-box") +@selectKitOptions({ + autoFilterable: false, + filterable: false, + showFullTitle: true, + headerComponent: "dropdown-select-box/dropdown-select-box-header", + caretUpIcon: "caret-up", + caretDownIcon: "caret-down", + showCaret: false, + customStyle: null, + btnCustomClasses: null, +}) +@pluginApiIdentifiers(["dropdown-select-box"]) +export default class DropdownSelectBox extends SingleSelectComponent { modifyComponentForRow() { return "dropdown-select-box/dropdown-select-box-row"; - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/dropdown-select-box/dropdown-select-box-header.js b/app/assets/javascripts/select-kit/addon/components/dropdown-select-box/dropdown-select-box-header.js index c115479de66..59bf4ec2ab6 100644 --- a/app/assets/javascripts/select-kit/addon/components/dropdown-select-box/dropdown-select-box-header.js +++ b/app/assets/javascripts/select-kit/addon/components/dropdown-select-box/dropdown-select-box-header.js @@ -1,32 +1,29 @@ import { computed } from "@ember/object"; import { readOnly } from "@ember/object/computed"; +import { classNameBindings, classNames } from "@ember-decorators/component"; import SingleSelectHeaderComponent from "select-kit/components/select-kit/single-select-header"; -export default SingleSelectHeaderComponent.extend({ - classNames: ["dropdown-select-box-header"], - classNameBindings: ["btnClassName", "btnStyleClass", "btnCustomClasses"], - showFullTitle: readOnly("selectKit.options.showFullTitle"), - customStyle: readOnly("selectKit.options.customStyle"), +@classNames("dropdown-select-box-header") +@classNameBindings("btnClassName", "btnStyleClass", "btnCustomClasses") +export default class DropdownSelectBoxHeader extends SingleSelectHeaderComponent { + @readOnly("selectKit.options.showFullTitle") showFullTitle; + @readOnly("selectKit.options.customStyle") customStyle; + @readOnly("selectKit.options.btnCustomClasses") btnCustomClasses; + @readOnly("selectKit.options.caretUpIcon") caretUpIcon; + @readOnly("selectKit.options.caretDownIcon") caretDownIcon; - btnCustomClasses: readOnly("selectKit.options.btnCustomClasses"), - - btnClassName: computed("showFullTitle", function () { + @computed("showFullTitle") + get btnClassName() { return `btn ${this.showFullTitle ? "btn-icon-text" : "no-text btn-icon"}`; - }), + } - btnStyleClass: computed("customStyle", function () { + @computed("customStyle") + get btnStyleClass() { return `${this.customStyle ? "" : "btn-default"}`; - }), + } - caretUpIcon: readOnly("selectKit.options.caretUpIcon"), - caretDownIcon: readOnly("selectKit.options.caretDownIcon"), - - caretIcon: computed( - "selectKit.isExpanded", - "caretUpIcon", - "caretDownIcon", - function () { - return this.selectKit.isExpanded ? this.caretUpIcon : this.caretDownIcon; - } - ), -}); + @computed("selectKit.isExpanded", "caretUpIcon", "caretDownIcon") + get caretIcon() { + return this.selectKit.isExpanded ? this.caretUpIcon : this.caretDownIcon; + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/dropdown-select-box/dropdown-select-box-row.js b/app/assets/javascripts/select-kit/addon/components/dropdown-select-box/dropdown-select-box-row.js index 24a4af89d28..f59b673676e 100644 --- a/app/assets/javascripts/select-kit/addon/components/dropdown-select-box/dropdown-select-box-row.js +++ b/app/assets/javascripts/select-kit/addon/components/dropdown-select-box/dropdown-select-box-row.js @@ -1,7 +1,8 @@ import { readOnly } from "@ember/object/computed"; +import { classNames } from "@ember-decorators/component"; import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row"; -export default SelectKitRowComponent.extend({ - classNames: ["dropdown-select-box-row"], - description: readOnly("item.description"), -}); +@classNames("dropdown-select-box-row") +export default class DropdownSelectBoxRow extends SelectKitRowComponent { + @readOnly("item.description") description; +} diff --git a/app/assets/javascripts/select-kit/addon/components/email-group-user-chooser-filter.js b/app/assets/javascripts/select-kit/addon/components/email-group-user-chooser-filter.js index 7bf3ba07a6a..c53fabca34c 100644 --- a/app/assets/javascripts/select-kit/addon/components/email-group-user-chooser-filter.js +++ b/app/assets/javascripts/select-kit/addon/components/email-group-user-chooser-filter.js @@ -1,9 +1,9 @@ import { action } from "@ember/object"; +import { classNames } from "@ember-decorators/component"; import MultiSelectFilterComponent from "select-kit/components/multi-select/multi-select-filter"; -export default MultiSelectFilterComponent.extend({ - classNames: ["email-group-user-chooser-filter"], - +@classNames("email-group-user-chooser-filter") +export default class EmailGroupUserChooserFilter extends MultiSelectFilterComponent { @action onPaste(event) { if (this.selectKit.options.maximum === 1) { @@ -35,5 +35,5 @@ export default MultiSelectFilterComponent.extend({ return false; } - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/email-group-user-chooser-row.js b/app/assets/javascripts/select-kit/addon/components/email-group-user-chooser-row.js index 316dfe1a3df..2b5c0363820 100644 --- a/app/assets/javascripts/select-kit/addon/components/email-group-user-chooser-row.js +++ b/app/assets/javascripts/select-kit/addon/components/email-group-user-chooser-row.js @@ -1,5 +1,5 @@ +import { classNames } from "@ember-decorators/component"; import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row"; -export default SelectKitRowComponent.extend({ - classNames: ["email-group-user-chooser-row"], -}); +@classNames("email-group-user-chooser-row") +export default class EmailGroupUserChooserRow extends SelectKitRowComponent {} diff --git a/app/assets/javascripts/select-kit/addon/components/email-group-user-chooser.js b/app/assets/javascripts/select-kit/addon/components/email-group-user-chooser.js index bea7b54d76f..162a67e339d 100644 --- a/app/assets/javascripts/select-kit/addon/components/email-group-user-chooser.js +++ b/app/assets/javascripts/select-kit/addon/components/email-group-user-chooser.js @@ -1,24 +1,28 @@ +import { classNameBindings, classNames } from "@ember-decorators/component"; +import { + pluginApiIdentifiers, + selectKitOptions, +} from "select-kit/components/select-kit"; import UserChooserComponent from "select-kit/components/user-chooser"; -export default UserChooserComponent.extend({ - pluginApiIdentifiers: ["email-group-user-chooser"], - classNames: ["email-group-user-chooser"], - classNameBindings: ["selectKit.options.fullWidthWrap:full-width-wrap"], - valueProperty: "id", - nameProperty: "name", +@classNames("email-group-user-chooser") +@classNameBindings("selectKit.options.fullWidthWrap:full-width-wrap") +@selectKitOptions({ + filterComponent: "email-group-user-chooser-filter", + fullWidthWrap: false, + autoWrap: false, +}) +@pluginApiIdentifiers(["email-group-user-chooser"]) +export default class EmailGroupUserChooser extends UserChooserComponent { + valueProperty = "id"; + nameProperty = "name"; modifyComponentForRow() { return "email-group-user-chooser-row"; - }, - - selectKitOptions: { - filterComponent: "email-group-user-chooser-filter", - fullWidthWrap: false, - autoWrap: false, - }, + } search() { - const superPromise = this._super(...arguments); + const superPromise = super.search(...arguments); if (!superPromise) { return; } @@ -45,5 +49,5 @@ export default UserChooserComponent.extend({ return { ...item, ...reconstructed }; }); }); - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/flair-chooser.js b/app/assets/javascripts/select-kit/addon/components/flair-chooser.js index f8eabd01246..7d6e54505e2 100644 --- a/app/assets/javascripts/select-kit/addon/components/flair-chooser.js +++ b/app/assets/javascripts/select-kit/addon/components/flair-chooser.js @@ -1,33 +1,32 @@ import { computed } from "@ember/object"; +import { classNames } from "@ember-decorators/component"; import ComboBoxComponent from "select-kit/components/combo-box"; +import { + pluginApiIdentifiers, + selectKitOptions, +} from "select-kit/components/select-kit"; -export default ComboBoxComponent.extend({ - pluginApiIdentifiers: ["flair-chooser"], - classNames: ["flair-chooser"], - - selectKitOptions: { - selectedNameComponent: "selected-flair", - }, - +@classNames("flair-chooser") +@selectKitOptions({ + selectedNameComponent: "selected-flair", +}) +@pluginApiIdentifiers(["flair-chooser"]) +export default class FlairChooser extends ComboBoxComponent { modifyComponentForRow() { return "flair-row"; - }, + } - selectedContent: computed( - "value", - "content.[]", - "selectKit.noneItem", - function () { - const content = (this.content || []).findBy( - this.selectKit.valueProperty, - this.value - ); + @computed("value", "content.[]", "selectKit.noneItem") + get selectedContent() { + const content = (this.content || []).findBy( + this.selectKit.valueProperty, + this.value + ); - if (content) { - return this.selectKit.modifySelection(content); - } else { - return this.selectKit.noneItem; - } + if (content) { + return this.selectKit.modifySelection(content); + } else { + return this.selectKit.noneItem; } - ), -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/flair-row.js b/app/assets/javascripts/select-kit/addon/components/flair-row.js index 8210655ef6c..d0ddacf4fce 100644 --- a/app/assets/javascripts/select-kit/addon/components/flair-row.js +++ b/app/assets/javascripts/select-kit/addon/components/flair-row.js @@ -1,5 +1,5 @@ +import { classNames } from "@ember-decorators/component"; import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row"; -export default SelectKitRowComponent.extend({ - classNames: ["flair-row"], -}); +@classNames("flair-row") +export default class FlairRow extends SelectKitRowComponent {} diff --git a/app/assets/javascripts/select-kit/addon/components/form-template-chooser.js b/app/assets/javascripts/select-kit/addon/components/form-template-chooser.js index cf1fcbc094a..8abf2b127ed 100644 --- a/app/assets/javascripts/select-kit/addon/components/form-template-chooser.js +++ b/app/assets/javascripts/select-kit/addon/components/form-template-chooser.js @@ -1,37 +1,41 @@ import { computed } from "@ember/object"; +import { classNames } from "@ember-decorators/component"; import FormTemplate from "discourse/models/form-template"; import MultiSelectComponent from "select-kit/components/multi-select"; +import { + pluginApiIdentifiers, + selectKitOptions, +} from "select-kit/components/select-kit"; -export default MultiSelectComponent.extend({ - pluginApiIdentifiers: ["form-template-chooser"], - classNames: ["form-template-chooser"], - selectKitOptions: { - none: "form_template_chooser.select_template", - }, - +@classNames("form-template-chooser") +@selectKitOptions({ + none: "form_template_chooser.select_template", +}) +@pluginApiIdentifiers("form-template-chooser") +export default class FormTemplateChooser extends MultiSelectComponent { init() { - this._super(...arguments); + super.init(...arguments); this.triggerSearch(); - }, + } didUpdateAttrs() { - this._super(...arguments); + super.didUpdateAttrs(...arguments); this.set("templatesLoaded", false); this.triggerSearch(); - }, + } @computed("templates") get content() { return this.templates; - }, + } search(filter) { if (this.get("templatesLoaded")) { - return this._super(filter); + return super.search(filter); } else { return this._fetchTemplates(); } - }, + } async _fetchTemplates() { if (this.get("loadingTemplates")) { @@ -62,9 +66,9 @@ export default MultiSelectComponent.extend({ }); return this.templates; - }, + } _sortTemplatesByName(templates) { return templates.sort((a, b) => a.name.localeCompare(b.name)); - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/future-date-input-selector.js b/app/assets/javascripts/select-kit/addon/components/future-date-input-selector.js index 664e4b67c29..f71232331a2 100644 --- a/app/assets/javascripts/select-kit/addon/components/future-date-input-selector.js +++ b/app/assets/javascripts/select-kit/addon/components/future-date-input-selector.js @@ -1,40 +1,45 @@ +import { action } from "@ember/object"; import { equal } from "@ember/object/computed"; import { isEmpty } from "@ember/utils"; +import { classNames } from "@ember-decorators/component"; import ComboBoxComponent from "select-kit/components/combo-box"; +import { + pluginApiIdentifiers, + selectKitOptions, +} from "select-kit/components/select-kit"; export const FORMAT = "YYYY-MM-DD HH:mmZ"; -export default ComboBoxComponent.extend({ - pluginApiIdentifiers: ["future-date-input-selector"], - classNames: ["future-date-input-selector"], - isCustom: equal("value", "custom"), - userTimezone: null, +@classNames("future-date-input-selector") +@selectKitOptions({ + autoInsertNoneItem: false, + headerComponent: + "future-date-input-selector/future-date-input-selector-header", +}) +@pluginApiIdentifiers("future-date-input-selector") +export default class FutureDateInputSelector extends ComboBoxComponent { + @equal("value", "custom") isCustom; - selectKitOptions: { - autoInsertNoneItem: false, - headerComponent: - "future-date-input-selector/future-date-input-selector-header", - }, + userTimezone = null; init() { - this._super(...arguments); + super.init(...arguments); this.userTimezone = this.currentUser.user_option.timezone; - }, + } modifyComponentForRow() { return "future-date-input-selector/future-date-input-selector-row"; - }, + } - actions: { - onChange(value) { - if (value !== "custom" && !isEmpty(value)) { - const { time } = this.content.find((x) => x.id === value); - if (time) { - this.onChangeInput?.(time.locale("en").format(FORMAT)); - } + @action + _onChange(value) { + if (value !== "custom" && !isEmpty(value)) { + const { time } = this.content.find((x) => x.id === value); + if (time) { + this.onChangeInput?.(time.locale("en").format(FORMAT)); } + } - this.onChange?.(value); - }, - }, -}); + this.onChange?.(value); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/future-date-input-selector/future-date-input-selector-header.js b/app/assets/javascripts/select-kit/addon/components/future-date-input-selector/future-date-input-selector-header.js index 24dc65b2b71..5ea539b97ca 100644 --- a/app/assets/javascripts/select-kit/addon/components/future-date-input-selector/future-date-input-selector-header.js +++ b/app/assets/javascripts/select-kit/addon/components/future-date-input-selector/future-date-input-selector-header.js @@ -1,5 +1,5 @@ +import { classNames } from "@ember-decorators/component"; import ComboBoxHeaderComponent from "select-kit/components/combo-box/combo-box-header"; -export default ComboBoxHeaderComponent.extend({ - classNames: "future-date-input-selector-header", -}); +@classNames("future-date-input-selector-header") +export default class FutureDateInputSelectorHeader extends ComboBoxHeaderComponent {} diff --git a/app/assets/javascripts/select-kit/addon/components/future-date-input-selector/future-date-input-selector-row.js b/app/assets/javascripts/select-kit/addon/components/future-date-input-selector/future-date-input-selector-row.js index 337d4f6a1bf..8c10eaa3ad7 100644 --- a/app/assets/javascripts/select-kit/addon/components/future-date-input-selector/future-date-input-selector-row.js +++ b/app/assets/javascripts/select-kit/addon/components/future-date-input-selector/future-date-input-selector-row.js @@ -1,5 +1,5 @@ +import { classNames } from "@ember-decorators/component"; import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row"; -export default SelectKitRowComponent.extend({ - classNames: ["future-date-input-selector-row"], -}); +@classNames("future-date-input-selector-row") +export default class FutureDateInputSelectorRow extends SelectKitRowComponent {} diff --git a/app/assets/javascripts/select-kit/addon/components/group-chooser.js b/app/assets/javascripts/select-kit/addon/components/group-chooser.js index f6f9bef550a..904ce932700 100644 --- a/app/assets/javascripts/select-kit/addon/components/group-chooser.js +++ b/app/assets/javascripts/select-kit/addon/components/group-chooser.js @@ -1,9 +1,13 @@ +import { classNames } from "@ember-decorators/component"; import MultiSelectComponent from "select-kit/components/multi-select"; +import { + pluginApiIdentifiers, + selectKitOptions, +} from "select-kit/components/select-kit"; -export default MultiSelectComponent.extend({ - pluginApiIdentifiers: ["group-chooser"], - classNames: ["group-chooser"], - selectKitOptions: { - allowAny: false, - }, -}); +@classNames("group-chooser") +@selectKitOptions({ + allowAny: false, +}) +@pluginApiIdentifiers("group-chooser") +export default class GroupChooser extends MultiSelectComponent {} diff --git a/app/assets/javascripts/select-kit/addon/components/group-dropdown.js b/app/assets/javascripts/select-kit/addon/components/group-dropdown.js index a04b6a7b235..5f0913330bc 100644 --- a/app/assets/javascripts/select-kit/addon/components/group-dropdown.js +++ b/app/assets/javascripts/select-kit/addon/components/group-dropdown.js @@ -1,26 +1,32 @@ -import { computed } from "@ember/object"; +import { action, computed } from "@ember/object"; import { gte, reads } from "@ember/object/computed"; +import { classNames } from "@ember-decorators/component"; import { setting } from "discourse/lib/computed"; import DiscourseURL from "discourse/lib/url"; import I18n from "discourse-i18n"; import ComboBoxComponent from "select-kit/components/combo-box"; +import { + pluginApiIdentifiers, + selectKitOptions, +} from "select-kit/components/select-kit"; -export default ComboBoxComponent.extend({ - pluginApiIdentifiers: ["group-dropdown"], - classNames: ["group-dropdown"], - content: reads("groupsWithShortcut"), - valueProperty: null, - nameProperty: null, - hasManyGroups: gte("content.length", 10), - enableGroupDirectory: setting("enable_group_directory"), +@classNames("group-dropdown") +@selectKitOptions({ + caretDownIcon: "caret-right", + caretUpIcon: "caret-down", + filterable: "hasManyGroups", +}) +@pluginApiIdentifiers("group-dropdown") +export default class GroupDropdown extends ComboBoxComponent { + @reads("groupsWithShortcut") content; + @gte("content.length", 10) hasManyGroups; + @setting("enable_group_directory") enableGroupDirectory; - selectKitOptions: { - caretDownIcon: "caret-right", - caretUpIcon: "caret-down", - filterable: "hasManyGroups", - }, + valueProperty = null; + nameProperty = null; - groupsWithShortcut: computed("groups.[]", function () { + @computed("groups.[]") + get groupsWithShortcut() { const shortcuts = []; if (this.enableGroupDirectory || this.get("currentUser.staff")) { @@ -28,15 +34,14 @@ export default ComboBoxComponent.extend({ } return shortcuts.concat(this.groups); - }), + } - actions: { - onChange(groupName) { - if ((this.groups || []).includes(groupName)) { - DiscourseURL.routeToUrl(`/g/${groupName}`); - } else { - DiscourseURL.routeToUrl(`/g`); - } - }, - }, -}); + @action + onChange(groupName) { + if ((this.groups || []).includes(groupName)) { + DiscourseURL.routeToUrl(`/g/${groupName}`); + } else { + DiscourseURL.routeToUrl(`/g`); + } + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/group-notifications-button.js b/app/assets/javascripts/select-kit/addon/components/group-notifications-button.js index 2fb720335fe..3bc302c0ed1 100644 --- a/app/assets/javascripts/select-kit/addon/components/group-notifications-button.js +++ b/app/assets/javascripts/select-kit/addon/components/group-notifications-button.js @@ -1,10 +1,13 @@ +import { classNames } from "@ember-decorators/component"; import NotificationOptionsComponent from "select-kit/components/notifications-button"; +import { + pluginApiIdentifiers, + selectKitOptions, +} from "select-kit/components/select-kit"; -export default NotificationOptionsComponent.extend({ - pluginApiIdentifiers: ["group-notifications-button"], - classNames: ["group-notifications-button"], - - selectKitOptions: { - i18nPrefix: "groups.notifications", - }, -}); +@classNames("group-notifications-button") +@selectKitOptions({ + i18nPrefix: "groups.notifications", +}) +@pluginApiIdentifiers("group-notifications-button") +export default class GroupNotificationsButton extends NotificationOptionsComponent {} diff --git a/app/assets/javascripts/select-kit/addon/components/icon-picker.js b/app/assets/javascripts/select-kit/addon/components/icon-picker.js index f88f5001e69..429526a8c27 100644 --- a/app/assets/javascripts/select-kit/addon/components/icon-picker.js +++ b/app/assets/javascripts/select-kit/addon/components/icon-picker.js @@ -1,4 +1,5 @@ -import { computed } from "@ember/object"; +import { action, computed } from "@ember/object"; +import { classNames } from "@ember-decorators/component"; import $ from "jquery"; import { ajax } from "discourse/lib/ajax"; import { isDevelopment } from "discourse-common/config/environment"; @@ -10,18 +11,20 @@ import { } from "discourse-common/lib/icon-library"; import FilterForMore from "select-kit/components/filter-for-more"; import MultiSelectComponent from "select-kit/components/multi-select"; -import { MAIN_COLLECTION } from "select-kit/components/select-kit"; +import { + MAIN_COLLECTION, + pluginApiIdentifiers, +} from "select-kit/components/select-kit"; const MORE_ICONS_COLLECTION = "MORE_ICONS_COLLECTION"; const MAX_RESULTS_RETURNED = 200; // Matches max returned results from icon_picker_search in svg_sprite_controller.rb -export default MultiSelectComponent.extend({ - pluginApiIdentifiers: ["icon-picker"], - classNames: ["icon-picker"], - +@classNames("icon-picker") +@pluginApiIdentifiers("icon-picker") +export default class IconPicker extends MultiSelectComponent { init() { - this._super(...arguments); + super.init(...arguments); this._cachedIconsList = null; this._resultCount = 0; @@ -31,13 +34,13 @@ export default MultiSelectComponent.extend({ } this.insertAfterCollection(MAIN_COLLECTION, MORE_ICONS_COLLECTION); - }, + } modifyComponentForCollection(collection) { if (collection === MORE_ICONS_COLLECTION) { return FilterForMore; } - }, + } modifyContentForCollection(collection) { if (collection === MORE_ICONS_COLLECTION) { @@ -45,11 +48,12 @@ export default MultiSelectComponent.extend({ shouldShowMoreTip: this._resultCount === MAX_RESULTS_RETURNED, }; } - }, + } - content: computed("value.[]", function () { + @computed("value.[]") + get content() { return makeArray(this.value).map(this._processIcon); - }), + } search(filter = "") { if (filter === "" && this._cachedIconsList?.length) { @@ -70,7 +74,7 @@ export default MultiSelectComponent.extend({ return icons; }); } - }, + } _processIcon(icon) { const iconName = typeof icon === "object" ? icon.id : icon, @@ -98,11 +102,11 @@ export default MultiSelectComponent.extend({ name: iconName, icon: strippedIconName, }; - }, + } willDestroyElement() { $("#svg-sprites .ajax-icon-holder").remove(); - this._super(...arguments); + super.willDestroyElement(...arguments); this._cachedIconsList = null; this._resultCount = 0; @@ -110,16 +114,15 @@ export default MultiSelectComponent.extend({ if (isDevelopment()) { enableMissingIconWarning(); } - }, + } - actions: { - onChange(value, item) { - if (this.selectKit.options.maximum === 1) { - value = value.length ? value[0] : null; - item = item.length ? item[0] : null; - } + @action + _onChange(value, item) { + if (this.selectKit.options.maximum === 1) { + value = value.length ? value[0] : null; + item = item.length ? item[0] : null; + } - this.onChange?.(value, item); - }, - }, -}); + this.onChange?.(value, item); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/list-setting.js b/app/assets/javascripts/select-kit/addon/components/list-setting.js index 9f076d330e7..078229687cd 100644 --- a/app/assets/javascripts/select-kit/addon/components/list-setting.js +++ b/app/assets/javascripts/select-kit/addon/components/list-setting.js @@ -1,40 +1,46 @@ import { computed } from "@ember/object"; import { readOnly } from "@ember/object/computed"; +import { classNames } from "@ember-decorators/component"; import { makeArray } from "discourse-common/lib/helpers"; import MultiSelectComponent from "select-kit/components/multi-select"; -import { MAIN_COLLECTION } from "select-kit/components/select-kit"; +import { + MAIN_COLLECTION, + pluginApiIdentifiers, + selectKitOptions, +} from "select-kit/components/select-kit"; -export default MultiSelectComponent.extend({ - pluginApiIdentifiers: ["list-setting"], - classNames: ["list-setting"], - choices: null, - nameProperty: null, - valueProperty: null, - content: readOnly("choices"), +@classNames("list-setting") +@selectKitOptions({ + filterable: true, + selectedChoiceComponent: "selectedChoiceComponent", +}) +@pluginApiIdentifiers("list-setting") +export default class ListSetting extends MultiSelectComponent { + choices = null; + nameProperty = null; + valueProperty = null; - selectKitOptions: { - filterable: true, - selectedChoiceComponent: "selectedChoiceComponent", - }, + @readOnly("choices") content; modifyComponentForRow(collection) { if (collection === MAIN_COLLECTION && this.settingName?.includes("color")) { return "create-color-row"; } - }, + } - selectedChoiceComponent: computed("settingName", function () { + @computed("settingName") + get selectedChoiceComponent() { if (this.settingName?.includes("color")) { return "selected-choice-color"; } else { return "selected-choice"; } - }), + } deselect(value) { this.onChangeChoices && this.onChangeChoices([...new Set([value, ...makeArray(this.choices)])]); - this._super(...arguments); - }, -}); + super.deselect(...arguments); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/mini-tag-chooser.js b/app/assets/javascripts/select-kit/addon/components/mini-tag-chooser.js index 62bc2acb6b0..ba700b02ee8 100644 --- a/app/assets/javascripts/select-kit/addon/components/mini-tag-chooser.js +++ b/app/assets/javascripts/select-kit/addon/components/mini-tag-chooser.js @@ -1,33 +1,45 @@ import { computed } from "@ember/object"; import { empty, or } from "@ember/object/computed"; +import { + attributeBindings, + classNameBindings, + classNames, +} from "@ember-decorators/component"; import { setting } from "discourse/lib/computed"; import { makeArray } from "discourse-common/lib/helpers"; import I18n from "discourse-i18n"; import MultiSelectComponent from "select-kit/components/multi-select"; +import { + pluginApiIdentifiers, + selectKitOptions, +} from "select-kit/components/select-kit"; import TagsMixin from "select-kit/mixins/tags"; -export default MultiSelectComponent.extend(TagsMixin, { - pluginApiIdentifiers: ["mini-tag-chooser"], - attributeBindings: ["selectKit.options.categoryId:category-id"], - classNames: ["mini-tag-chooser"], - classNameBindings: ["noTags"], - noTags: empty("value"), - maxTagSearchResults: setting("max_tag_search_results"), - maxTagsPerTopic: setting("max_tags_per_topic"), +@attributeBindings("selectKit.options.categoryId:category-id") +@classNames("mini-tag-chooser") +@classNameBindings("noTags") +@selectKitOptions({ + fullWidthOnMobile: true, + filterable: true, + caretDownIcon: "caretIcon", + caretUpIcon: "caretIcon", + termMatchesForbidden: false, + categoryId: null, + everyTag: false, + closeOnChange: false, + maximum: "maxTagsPerTopic", + autoInsertNoneItem: false, + useHeaderFilter: false, +}) +@pluginApiIdentifiers(["mini-tag-chooser"]) +export default class MiniTagChooser extends MultiSelectComponent.extend( + TagsMixin +) { + @empty("value") noTags; + @or("allowCreate", "site.can_create_tag") allowAnyTag; - selectKitOptions: { - fullWidthOnMobile: true, - filterable: true, - caretDownIcon: "caretIcon", - caretUpIcon: "caretIcon", - termMatchesForbidden: false, - categoryId: null, - everyTag: false, - closeOnChange: false, - maximum: "maxTagsPerTopic", - autoInsertNoneItem: false, - useHeaderFilter: false, - }, + @setting("max_tag_search_results") maxTagSearchResults; + @setting("max_tags_per_topic") maxTagsPerTopic; modifyComponentForRow(collection, item) { if (this.getValue(item) === this.selectKit.filter && !item.count) { @@ -35,7 +47,7 @@ export default MultiSelectComponent.extend(TagsMixin, { } return "tag-row"; - }, + } modifyNoSelection() { if (this.selectKit.options.minimum > 0) { @@ -48,18 +60,18 @@ export default MultiSelectComponent.extend(TagsMixin, { } else { return this.defaultItem(null, I18n.t("tagging.choose_for_topic")); } - }, + } - allowAnyTag: or("allowCreate", "site.can_create_tag"), - - caretIcon: computed("value.[]", "content.[]", function () { + @computed("value.[]", "content.[]") + get caretIcon() { const maximum = this.selectKit.options.maximum; return maximum && makeArray(this.value).length >= parseInt(maximum, 10) ? null : "plus"; - }), + } - content: computed("value.[]", function () { + @computed("value.[]") + get content() { let values = makeArray(this.value); if (this.selectKit.options.hiddenValues) { values = values.filter( @@ -67,7 +79,7 @@ export default MultiSelectComponent.extend(TagsMixin, { ); } return values.map((x) => this.defaultItem(x, x)); - }), + } search(filter) { const maximum = this.selectKit.options.maximum; @@ -92,7 +104,7 @@ export default MultiSelectComponent.extend(TagsMixin, { } return this.searchTags("/tags/filter/search", data, this._transformJson); - }, + } _transformJson(context, json) { if (context.isDestroyed || context.isDestroying) { @@ -123,5 +135,5 @@ export default MultiSelectComponent.extend(TagsMixin, { } return results.filter((r) => !makeArray(context.tags).includes(r.id)); - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/mini-tag-chooser/selected-collection.js b/app/assets/javascripts/select-kit/addon/components/mini-tag-chooser/selected-collection.js index 5276dde3796..52383708efd 100644 --- a/app/assets/javascripts/select-kit/addon/components/mini-tag-chooser/selected-collection.js +++ b/app/assets/javascripts/select-kit/addon/components/mini-tag-chooser/selected-collection.js @@ -1,12 +1,14 @@ import Component from "@ember/component"; import { computed } from "@ember/object"; import { reads } from "@ember/object/computed"; +import { tagName } from "@ember-decorators/component"; -export default Component.extend({ - tagName: "", - selectedTags: reads("collection.content.selectedTags.[]"), +@tagName("") +export default class SelectedCollection extends Component { + @reads("collection.content.selectedTags.[]") selectedTags; - tags: computed("selectedTags.[]", "selectKit.filter", function () { + @computed("selectedTags.[]", "selectKit.filter") + get tags() { if (!this.selectedTags) { return []; } @@ -24,5 +26,5 @@ export default Component.extend({ classNames: "selected-tag", }; }); - }), -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/multi-select/format-selected-content.js b/app/assets/javascripts/select-kit/addon/components/multi-select/format-selected-content.js index f369b7f23d6..ee7392e5424 100644 --- a/app/assets/javascripts/select-kit/addon/components/multi-select/format-selected-content.js +++ b/app/assets/javascripts/select-kit/addon/components/multi-select/format-selected-content.js @@ -1,14 +1,18 @@ import Component from "@ember/component"; import { computed } from "@ember/object"; +import { tagName } from "@ember-decorators/component"; import { makeArray } from "discourse-common/lib/helpers"; import UtilsMixin from "select-kit/mixins/utils"; -export default Component.extend(UtilsMixin, { - tagName: "", - content: null, - selectKit: null, +@tagName("") +export default class FormatSelectedContent extends Component.extend( + UtilsMixin +) { + content = null; + selectKit = null; - formattedContent: computed("content", function () { + @computed("content") + get formattedContent() { if (this.content) { return makeArray(this.content) .map((c) => this.getName(c)) @@ -16,5 +20,5 @@ export default Component.extend(UtilsMixin, { } else { return this.getName(this.selectKit.noneItem); } - }), -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/multi-select/multi-select-filter.js b/app/assets/javascripts/select-kit/addon/components/multi-select/multi-select-filter.js index b6c0afd3358..7bcbe6e8f3f 100644 --- a/app/assets/javascripts/select-kit/addon/components/multi-select/multi-select-filter.js +++ b/app/assets/javascripts/select-kit/addon/components/multi-select/multi-select-filter.js @@ -1,11 +1,11 @@ import { action } from "@ember/object"; import { isEmpty } from "@ember/utils"; +import { classNames } from "@ember-decorators/component"; import discourseComputed from "discourse-common/utils/decorators"; import SelectKitFilterComponent from "select-kit/components/select-kit/select-kit-filter"; -export default SelectKitFilterComponent.extend({ - classNames: ["multi-select-filter"], - +@classNames("multi-select-filter") +export default class MultiSelectFilter extends SelectKitFilterComponent { @discourseComputed("placeholder", "selectKit.hasSelection") computedPlaceholder(placeholder, hasSelection) { if (this.hidePlaceholderWithSelection && hasSelection) { @@ -13,7 +13,7 @@ export default SelectKitFilterComponent.extend({ } return isEmpty(placeholder) ? "" : placeholder; - }, + } @action onPaste(event) { @@ -33,5 +33,5 @@ export default SelectKitFilterComponent.extend({ return false; } - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/multi-select/multi-select-header.js b/app/assets/javascripts/select-kit/addon/components/multi-select/multi-select-header.js index 7f9f118f685..426de7c599a 100644 --- a/app/assets/javascripts/select-kit/addon/components/multi-select/multi-select-header.js +++ b/app/assets/javascripts/select-kit/addon/components/multi-select/multi-select-header.js @@ -1,21 +1,22 @@ import { computed } from "@ember/object"; import { reads } from "@ember/object/computed"; +import { + attributeBindings, + classNames, + tagName, +} from "@ember-decorators/component"; import SelectKitHeaderComponent from "select-kit/components/select-kit/select-kit-header"; -export default SelectKitHeaderComponent.extend({ - tagName: "summary", - classNames: ["multi-select-header"], - attributeBindings: ["ariaLabel:aria-label"], - caretUpIcon: reads("selectKit.options.caretUpIcon"), - caretDownIcon: reads("selectKit.options.caretDownIcon"), - ariaLabel: reads("selectKit.options.headerAriaLabel"), +@tagName("summary") +@classNames("multi-select-header") +@attributeBindings("ariaLabel:aria-label") +export default class MultiSelectHeader extends SelectKitHeaderComponent { + @reads("selectKit.options.caretUpIcon") caretUpIcon; + @reads("selectKit.options.caretDownIcon") caretDownIcon; + @reads("selectKit.options.headerAriaLabel") ariaLabel; - caretIcon: computed( - "selectKit.isExpanded", - "caretUpIcon", - "caretDownIcon", - function () { - return this.selectKit.isExpanded ? this.caretUpIcon : this.caretDownIcon; - } - ), -}); + @computed("selectKit.isExpanded", "caretUpIcon", "caretDownIcon") + get caretIcon() { + return this.selectKit.isExpanded ? this.caretUpIcon : this.caretDownIcon; + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/multi-select/selected-category.js b/app/assets/javascripts/select-kit/addon/components/multi-select/selected-category.js index 1d80f6fc9b8..4480eda8a2c 100644 --- a/app/assets/javascripts/select-kit/addon/components/multi-select/selected-category.js +++ b/app/assets/javascripts/select-kit/addon/components/multi-select/selected-category.js @@ -1,17 +1,18 @@ import { computed } from "@ember/object"; import { htmlSafe } from "@ember/template"; +import { classNames } from "@ember-decorators/component"; import { categoryBadgeHTML } from "discourse/helpers/category-link"; import SelectedNameComponent from "select-kit/components/selected-name"; -export default SelectedNameComponent.extend({ - classNames: ["selected-category"], - - badge: computed("item", function () { +@classNames("selected-category") +export default class SelectedCategory extends SelectedNameComponent { + @computed("item") + get badge() { return htmlSafe( categoryBadgeHTML(this.item, { allowUncategorized: true, link: false, }) ); - }), -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/multi-select/selected-color.js b/app/assets/javascripts/select-kit/addon/components/multi-select/selected-color.js index 4adb0196123..732c921399b 100644 --- a/app/assets/javascripts/select-kit/addon/components/multi-select/selected-color.js +++ b/app/assets/javascripts/select-kit/addon/components/multi-select/selected-color.js @@ -1,14 +1,14 @@ import { htmlSafe } from "@ember/template"; +import { classNames } from "@ember-decorators/component"; import discourseComputed from "discourse-common/utils/decorators"; import SelectedNameComponent from "select-kit/components/selected-name"; -export default SelectedNameComponent.extend({ - classNames: ["select-kit-selected-color"], - +@classNames("select-kit-selected-color") +export default class SelectedColor extends SelectedNameComponent { @discourseComputed("name") footerContent(name) { return htmlSafe( `` ); - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/none-category-row.js b/app/assets/javascripts/select-kit/addon/components/none-category-row.js index 1abf328a8c3..0616febf0ef 100644 --- a/app/assets/javascripts/select-kit/addon/components/none-category-row.js +++ b/app/assets/javascripts/select-kit/addon/components/none-category-row.js @@ -1,11 +1,11 @@ import { htmlSafe } from "@ember/template"; +import { classNames } from "@ember-decorators/component"; import { categoryBadgeHTML } from "discourse/helpers/category-link"; import discourseComputed from "discourse-common/utils/decorators"; import CategoryRowComponent from "select-kit/components/category-row"; -export default CategoryRowComponent.extend({ - classNames: "none category-row", - +@classNames("none category-row") +export default class NoneCategoryRow extends CategoryRowComponent { @discourseComputed("category") badgeForCategory(category) { return htmlSafe( @@ -15,5 +15,5 @@ export default CategoryRowComponent.extend({ hideParent: true, }) ); - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/notifications-button.js b/app/assets/javascripts/select-kit/addon/components/notifications-button.js index 46ac8437ac1..dd75dbf9ac2 100644 --- a/app/assets/javascripts/select-kit/addon/components/notifications-button.js +++ b/app/assets/javascripts/select-kit/addon/components/notifications-button.js @@ -1,25 +1,29 @@ import { computed, setProperties } from "@ember/object"; +import { classNames } from "@ember-decorators/component"; import { allLevels, buttonDetails } from "discourse/lib/notification-levels"; import I18n from "discourse-i18n"; import DropdownSelectBoxComponent from "select-kit/components/dropdown-select-box"; +import { + pluginApiIdentifiers, + selectKitOptions, +} from "select-kit/components/select-kit"; -export default DropdownSelectBoxComponent.extend({ - pluginApiIdentifiers: ["notifications-button"], - classNames: ["notifications-button"], - content: allLevels, - nameProperty: "key", - - selectKitOptions: { - autoFilterable: false, - filterable: false, - i18nPrefix: "", - i18nPostfix: "", - }, +@classNames("notifications-button") +@selectKitOptions({ + autoFilterable: false, + filterable: false, + i18nPrefix: "", + i18nPostfix: "", +}) +@pluginApiIdentifiers("notifications-button") +export default class NotificationsButton extends DropdownSelectBoxComponent { + content = allLevels; + nameProperty = "key"; getTitle(key) { const { i18nPrefix, i18nPostfix } = this.selectKit.options; return I18n.t(`${i18nPrefix}.${key}${i18nPostfix}.title`); - }, + } modifyComponentForRow(_, content) { if (content) { @@ -28,7 +32,7 @@ export default DropdownSelectBoxComponent.extend({ }); } return "notifications-button/notifications-button-row"; - }, + } modifySelection(content) { content = content || {}; @@ -39,9 +43,10 @@ export default DropdownSelectBoxComponent.extend({ icon: this.buttonForValue.icon, }); return content; - }, + } - buttonForValue: computed("value", function () { + @computed("value") + get buttonForValue() { return buttonDetails(this.value); - }), -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/notifications-button/notifications-button-row.js b/app/assets/javascripts/select-kit/addon/components/notifications-button/notifications-button-row.js index 82b35e64d58..4f4e2e71c3a 100644 --- a/app/assets/javascripts/select-kit/addon/components/notifications-button/notifications-button-row.js +++ b/app/assets/javascripts/select-kit/addon/components/notifications-button/notifications-button-row.js @@ -1,31 +1,36 @@ import { computed } from "@ember/object"; import { readOnly } from "@ember/object/computed"; +import { classNames } from "@ember-decorators/component"; import { escapeExpression } from "discourse/lib/utilities"; import I18n from "discourse-i18n"; import DropdownSelectBoxRowComponent from "select-kit/components/dropdown-select-box/dropdown-select-box-row"; -export default DropdownSelectBoxRowComponent.extend({ - classNames: ["notifications-button-row"], - i18nPrefix: readOnly("selectKit.options.i18nPrefix"), - i18nPostfix: readOnly("selectKit.options.i18nPostfix"), +@classNames("notifications-button-row") +export default class NotificationsButtonRow extends DropdownSelectBoxRowComponent { + @readOnly("selectKit.options.i18nPrefix") i18nPrefix; + @readOnly("selectKit.options.i18nPostfix") i18nPostfix; - label: computed("_start", function () { + @computed("_start") + get label() { return escapeExpression(I18n.t(`${this._start}.title`)); - }), + } - icons: computed("item.icon", function () { + @computed("item.icon") + get icons() { return [escapeExpression(this.item.icon)]; - }), + } - description: computed("_start", function () { + @computed("_start") + get description() { if (this.site && this.site.mobileView) { return null; } return escapeExpression(I18n.t(`${this._start}.description`)); - }), + } - _start: computed("i18nPrefix", "i18nPostfix", "rowName", function () { + @computed("i18nPrefix", "i18nPostfix", "rowName") + get _start() { return `${this.i18nPrefix}.${this.rowName}${this.i18nPostfix}`; - }), -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/notifications-filter.js b/app/assets/javascripts/select-kit/addon/components/notifications-filter.js index 80788e54959..a7babf8bb57 100644 --- a/app/assets/javascripts/select-kit/addon/components/notifications-filter.js +++ b/app/assets/javascripts/select-kit/addon/components/notifications-filter.js @@ -1,12 +1,18 @@ import { computed } from "@ember/object"; +import { classNames } from "@ember-decorators/component"; import I18n from "discourse-i18n"; import DropdownSelectBoxComponent from "select-kit/components/dropdown-select-box"; +import { selectKitOptions } from "select-kit/components/select-kit"; -export default DropdownSelectBoxComponent.extend({ - classNames: ["notifications-filter"], - nameProperty: "label", +@classNames("notifications-filter") +@selectKitOptions({ + headerComponent: "notifications-filter/notifications-filter-header", +}) +export default class NotificationsFilter extends DropdownSelectBoxComponent { + nameProperty = "label"; - content: computed(function () { + @computed + get content() { return [ { id: "all", @@ -21,9 +27,5 @@ export default DropdownSelectBoxComponent.extend({ label: I18n.t("user.user_notifications.filters.unread"), }, ]; - }), - - selectKitOptions: { - headerComponent: "notifications-filter/notifications-filter-header", - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/notifications-filter/notifications-filter-header.js b/app/assets/javascripts/select-kit/addon/components/notifications-filter/notifications-filter-header.js index 442adf3c952..37927e9b5a0 100644 --- a/app/assets/javascripts/select-kit/addon/components/notifications-filter/notifications-filter-header.js +++ b/app/assets/javascripts/select-kit/addon/components/notifications-filter/notifications-filter-header.js @@ -1,13 +1,14 @@ +import { classNames } from "@ember-decorators/component"; import { fmt } from "discourse/lib/computed"; import discourseComputed from "discourse-common/utils/decorators"; import DropdownSelectBoxHeaderComponent from "select-kit/components/dropdown-select-box/dropdown-select-box-header"; -export default DropdownSelectBoxHeaderComponent.extend({ - classNames: ["notifications-filter-header", "btn-flat"], - label: fmt("value", "user.user_notifications.filters.%@"), +@classNames("notifications-filter-header", "btn-flat") +export default class NotificationsFilterHeader extends DropdownSelectBoxHeaderComponent { + @fmt("value", "user.user_notifications.filters.%@") label; @discourseComputed("selectKit.isExpanded") caretIcon(isExpanded) { return isExpanded ? "caret-up" : "caret-down"; - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/period-chooser.js b/app/assets/javascripts/select-kit/addon/components/period-chooser.js index 13804ec0ab4..b714079bf55 100644 --- a/app/assets/javascripts/select-kit/addon/components/period-chooser.js +++ b/app/assets/javascripts/select-kit/addon/components/period-chooser.js @@ -1,36 +1,38 @@ +import { action } from "@ember/object"; import { oneWay, readOnly } from "@ember/object/computed"; +import { classNameBindings, classNames } from "@ember-decorators/component"; import I18n from "discourse-i18n"; import DropdownSelectBoxComponent from "select-kit/components/dropdown-select-box"; +import { selectKitOptions } from "select-kit/components/select-kit"; -export default DropdownSelectBoxComponent.extend({ - classNames: ["period-chooser"], - classNameBindings: ["showPeriods::hidden"], - content: oneWay("site.periods"), - value: readOnly("period"), - valueProperty: null, - nameProperty: null, - showPeriods: true, +@classNames("period-chooser") +@classNameBindings("showPeriods::hidden") +@selectKitOptions({ + filterable: false, + autoFilterable: false, + fullDay: "fullDay", + customStyle: true, + headerComponent: "period-chooser/period-chooser-header", + headerAriaLabel: I18n.t("period_chooser.aria_label"), +}) +export default class PeriodChooser extends DropdownSelectBoxComponent { + @oneWay("site.periods") content; + @readOnly("period") value; + + valueProperty = null; + nameProperty = null; + showPeriods = true; modifyComponentForRow() { return "period-chooser/period-chooser-row"; - }, + } - selectKitOptions: { - filterable: false, - autoFilterable: false, - fullDay: "fullDay", - customStyle: true, - headerComponent: "period-chooser/period-chooser-header", - headerAriaLabel: I18n.t("period_chooser.aria_label"), - }, - - actions: { - onChange(value) { - if (this.action) { - this.action(value); - } else { - this.onChange?.(value); - } - }, - }, -}); + @action + _onChange(value) { + if (this.action) { + this.action(value); + } else { + this.onChange?.(value); + } + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/period-chooser/period-chooser-header.js b/app/assets/javascripts/select-kit/addon/components/period-chooser/period-chooser-header.js index f57313a16e7..08a40500533 100644 --- a/app/assets/javascripts/select-kit/addon/components/period-chooser/period-chooser-header.js +++ b/app/assets/javascripts/select-kit/addon/components/period-chooser/period-chooser-header.js @@ -1,11 +1,11 @@ +import { classNames } from "@ember-decorators/component"; import discourseComputed from "discourse-common/utils/decorators"; import DropdownSelectBoxHeaderComponent from "select-kit/components/dropdown-select-box/dropdown-select-box-header"; -export default DropdownSelectBoxHeaderComponent.extend({ - classNames: ["period-chooser-header", "btn-flat"], - +@classNames("period-chooser-header", "btn-flat") +export default class PeriodChooserHeader extends DropdownSelectBoxHeaderComponent { @discourseComputed("selectKit.isExpanded") caretIcon(isExpanded) { return isExpanded ? "caret-up" : "caret-down"; - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/period-chooser/period-chooser-row.js b/app/assets/javascripts/select-kit/addon/components/period-chooser/period-chooser-row.js index a9617125c62..058474f02d4 100644 --- a/app/assets/javascripts/select-kit/addon/components/period-chooser/period-chooser-row.js +++ b/app/assets/javascripts/select-kit/addon/components/period-chooser/period-chooser-row.js @@ -1,12 +1,12 @@ +import { classNames } from "@ember-decorators/component"; import discourseComputed from "discourse-common/utils/decorators"; import I18n from "discourse-i18n"; import DropdownSelectBoxRowComponent from "select-kit/components/dropdown-select-box/dropdown-select-box-row"; -export default DropdownSelectBoxRowComponent.extend({ - classNames: ["period-chooser-row"], - +@classNames("period-chooser-row") +export default class PeriodChooserRow extends DropdownSelectBoxRowComponent { @discourseComputed("rowName") title(rowName) { return I18n.t(`filters.top.${rowName || "this_week"}`).title; - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/pinned-button.js b/app/assets/javascripts/select-kit/addon/components/pinned-button.js index 12328baddee..55b209772a2 100644 --- a/app/assets/javascripts/select-kit/addon/components/pinned-button.js +++ b/app/assets/javascripts/select-kit/addon/components/pinned-button.js @@ -1,12 +1,14 @@ import Component from "@ember/component"; +import { classNameBindings, classNames } from "@ember-decorators/component"; import discourseComputed from "discourse-common/utils/decorators"; import I18n from "discourse-i18n"; +import { pluginApiIdentifiers } from "select-kit/components/select-kit"; -export default Component.extend({ - pluginApiIdentifiers: ["pinned-button"], - descriptionKey: "help", - classNames: "pinned-button", - classNameBindings: ["isHidden"], +@classNames("pinned-button") +@classNameBindings("isHidden") +@pluginApiIdentifiers("pinned-button") +export default class PinnedButton extends Component { + descriptionKey = "help"; @discourseComputed("topic.pinned_globally", "pinned") reasonText(pinnedGlobally, pinned) { @@ -14,10 +16,10 @@ export default Component.extend({ const pinnedKey = pinned ? `pinned${globally}` : "unpinned"; const key = `topic_statuses.${pinnedKey}.help`; return I18n.t(key); - }, + } @discourseComputed("pinned", "topic.deleted", "topic.unpinned") isHidden(pinned, deleted, unpinned) { return deleted || (!pinned && !unpinned); - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/pinned-options.js b/app/assets/javascripts/select-kit/addon/components/pinned-options.js index 98084263235..35d7ed098ad 100644 --- a/app/assets/javascripts/select-kit/addon/components/pinned-options.js +++ b/app/assets/javascripts/select-kit/addon/components/pinned-options.js @@ -1,19 +1,22 @@ import { action, computed } from "@ember/object"; import { htmlSafe } from "@ember/template"; +import { classNames } from "@ember-decorators/component"; import I18n from "discourse-i18n"; import DropdownSelectBoxComponent from "select-kit/components/dropdown-select-box"; +import { + pluginApiIdentifiers, + selectKitOptions, +} from "select-kit/components/select-kit"; const UNPINNED = "unpinned"; const PINNED = "pinned"; -export default DropdownSelectBoxComponent.extend({ - pluginApiIdentifiers: ["pinned-options"], - classNames: ["pinned-options"], - - selectKitOptions: { - showCaret: true, - }, - +@classNames("pinned-options") +@selectKitOptions({ + showCaret: true, +}) +@pluginApiIdentifiers("pinned-options") +export default class PinnedOptions extends DropdownSelectBoxComponent { modifySelection(content) { const pinnedGlobally = this.get("topic.pinned_globally"); const pinned = this.value; @@ -26,9 +29,10 @@ export default DropdownSelectBoxComponent.extend({ content.name = state; content.icon = `thumbtack${state === UNPINNED ? " unpinned" : ""}`; return content; - }, + } - content: computed(function () { + @computed + get content() { const globally = this.topic.pinned_globally ? "_globally" : ""; return [ @@ -49,7 +53,7 @@ export default DropdownSelectBoxComponent.extend({ : I18n.t("topic_statuses.unpinned.help"), }, ]; - }), + } @action onChange(value) { @@ -60,5 +64,5 @@ export default DropdownSelectBoxComponent.extend({ } else { return topic.rePin(); } - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/search-advanced-category-chooser.js b/app/assets/javascripts/select-kit/addon/components/search-advanced-category-chooser.js index 09598e1d3e1..a678919d165 100644 --- a/app/assets/javascripts/select-kit/addon/components/search-advanced-category-chooser.js +++ b/app/assets/javascripts/select-kit/addon/components/search-advanced-category-chooser.js @@ -1,14 +1,17 @@ +import { classNames } from "@ember-decorators/component"; import CategoryChooserComponent from "select-kit/components/category-chooser"; +import { + pluginApiIdentifiers, + selectKitOptions, +} from "select-kit/components/select-kit"; -export default CategoryChooserComponent.extend({ - pluginApiIdentifiers: ["search-advanced-category-chooser"], - classNames: ["search-advanced-category-chooser"], - - selectKitOptions: { - allowUncategorized: true, - clearable: true, - none: "category.all", - displayCategoryDescription: false, - permissionType: null, - }, -}); +@classNames("search-advanced-category-chooser") +@selectKitOptions({ + allowUncategorized: true, + clearable: true, + none: "category.all", + displayCategoryDescription: false, + permissionType: null, +}) +@pluginApiIdentifiers("search-advanced-category-chooser") +export default class SearchAdvancedCategoryChooser extends CategoryChooserComponent {} diff --git a/app/assets/javascripts/select-kit/addon/components/select-kit/errors-collection.js b/app/assets/javascripts/select-kit/addon/components/select-kit/errors-collection.js index 44494409ab5..658729f33d0 100644 --- a/app/assets/javascripts/select-kit/addon/components/select-kit/errors-collection.js +++ b/app/assets/javascripts/select-kit/addon/components/select-kit/errors-collection.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 ErrorsCollection extends Component {} diff --git a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-body.js b/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-body.js index 728b3b2e7b0..93e35cdab34 100644 --- a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-body.js +++ b/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-body.js @@ -1,33 +1,34 @@ import Component from "@ember/component"; import { computed } from "@ember/object"; import { next } from "@ember/runloop"; +import { classNameBindings, classNames } from "@ember-decorators/component"; import { bind } from "discourse-common/utils/decorators"; -export default Component.extend({ - classNames: ["select-kit-body"], - classNameBindings: ["emptyBody:empty-body"], - - emptyBody: computed("selectKit.{filter,hasNoContent}", function () { +@classNames("select-kit-body") +@classNameBindings("emptyBody:empty-body") +export default class SelectKitBody extends Component { + @computed("selectKit.{filter,hasNoContent}") + get emptyBody() { return false; - }), + } didInsertElement() { - this._super(...arguments); + super.didInsertElement(...arguments); this.element.style.position = "relative"; document.addEventListener("click", this.handleClick, true); this.selectKit .mainElement() .addEventListener("keydown", this._handleKeydown, true); - }, + } willDestroyElement() { - this._super(...arguments); + super.willDestroyElement(...arguments); document.removeEventListener("click", this.handleClick, true); this.selectKit .mainElement() ?.removeEventListener("keydown", this._handleKeydown, true); - }, + } @bind handleClick(event) { @@ -40,7 +41,7 @@ export default Component.extend({ } this.selectKit.close(event); - }, + } @bind _handleKeydown(event) { @@ -59,5 +60,5 @@ export default Component.extend({ this.selectKit.close(event); }); - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-collection.js b/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-collection.js index be06ebf3b43..fc47d36e946 100644 --- a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-collection.js +++ b/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-collection.js @@ -1,19 +1,19 @@ import { cached } from "@glimmer/tracking"; import Component from "@ember/component"; import { action } from "@ember/object"; +import { tagName } from "@ember-decorators/component"; import { disableBodyScroll, enableBodyScroll, } from "discourse/lib/body-scroll-lock"; -export default Component.extend({ - tagName: "", - +@tagName("") +export default class SelectKitCollection extends Component { @cached get inModal() { const element = this.selectKit.mainElement(); return element.closest(".d-modal"); - }, + } @action lock(element) { @@ -22,10 +22,10 @@ export default Component.extend({ } disableBodyScroll(element); - }, + } @action unlock(element) { enableBodyScroll(element); - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-create-row.js b/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-create-row.js index 21df52df5a7..f12ec7219d2 100644 --- a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-create-row.js +++ b/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-create-row.js @@ -1,5 +1,5 @@ +import { classNames } from "@ember-decorators/component"; import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row"; -export default SelectKitRowComponent.extend({ - classNames: "create", -}); +@classNames("create") +export default class SelectKitCreateRow extends SelectKitRowComponent {} diff --git a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-filter.js b/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-filter.js index 61f09ca2fa6..888d115967a 100644 --- a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-filter.js +++ b/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-filter.js @@ -2,29 +2,33 @@ import Component from "@ember/component"; import { action, computed } from "@ember/object"; import { not } from "@ember/object/computed"; import { isPresent } from "@ember/utils"; +import { + attributeBindings, + classNameBindings, + classNames, +} from "@ember-decorators/component"; import discourseComputed from "discourse-common/utils/decorators"; import I18n from "discourse-i18n"; import UtilsMixin from "select-kit/mixins/utils"; -export default Component.extend(UtilsMixin, { - classNames: ["select-kit-filter"], - classNameBindings: ["isExpanded:is-expanded"], - attributeBindings: ["role"], - tabIndex: -1, +@classNames("select-kit-filter") +@classNameBindings("isExpanded:is-expanded") +@attributeBindings("role") +export default class SelectKitFilter extends Component.extend(UtilsMixin) { + tabIndex = -1; - isHidden: computed( + @not("isHidden") isExpanded; + @computed( "selectKit.options.{filterable,allowAny,autoFilterable}", - "content.[]", - function () { - return ( - !this.selectKit.options.filterable && - !this.selectKit.options.allowAny && - !this.selectKit.options.autoFilterable - ); - } - ), - - isExpanded: not("isHidden"), + "content.[]" + ) + get isHidden() { + return ( + !this.selectKit.options.filterable && + !this.selectKit.options.allowAny && + !this.selectKit.options.autoFilterable + ); + } @discourseComputed( "selectKit.options.filterPlaceholder", @@ -45,23 +49,23 @@ export default Component.extend(UtilsMixin, { ? "select_kit.filter_placeholder_with_any" : "select_kit.filter_placeholder" ); - }, + } @action - onPaste() {}, + onPaste() {} @action onInput(event) { this.selectKit.onInput(event); return true; - }, + } @action onKeyup(event) { event.preventDefault(); event.stopImmediatePropagation(); return true; - }, + } @action onKeydown(event) { @@ -131,5 +135,5 @@ export default Component.extend(UtilsMixin, { } this.selectKit.set("highlighted", null); - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-header.js b/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-header.js index 904334c6bc6..9d48fbf357f 100644 --- a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-header.js +++ b/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-header.js @@ -1,39 +1,44 @@ import Component from "@ember/component"; import { computed } from "@ember/object"; +import { + attributeBindings, + classNameBindings, + classNames, +} from "@ember-decorators/component"; import { makeArray } from "discourse-common/lib/helpers"; import UtilsMixin from "select-kit/mixins/utils"; -export default Component.extend(UtilsMixin, { - classNames: ["select-kit-header"], - classNameBindings: ["isFocused"], - attributeBindings: [ - "role", - "tabindex", - "selectedValue:data-value", - "selectedNames:data-name", - "buttonTitle:title", - "selectKit.options.autofocus:autofocus", - ], +@classNames("select-kit-header") +@classNameBindings("isFocused") +@attributeBindings( + "role", + "tabindex", + "selectedValue:data-value", + "selectedNames:data-name", + "buttonTitle:title", + "selectKit.options.autofocus:autofocus" +) +export default class SelectKitHeader extends Component.extend(UtilsMixin) { + selectKit = null; + role = "listbox"; + tabindex = 0; - selectKit: null, - - role: "listbox", - - tabindex: 0, - - selectedValue: computed("value", function () { + @computed("value") + get selectedValue() { return this.value === this.getValue(this.selectKit.noneItem) ? null : makeArray(this.value).join(","); - }), + } - selectedNames: computed("selectedContent.[]", function () { + @computed("selectedContent.[]") + get selectedNames() { return makeArray(this.selectedContent) .map((s) => this.getName(s)) .join(","); - }), + } - buttonTitle: computed("value", "selectKit.noneItem", function () { + @computed("value", "selectKit.noneItem") + get buttonTitle() { if ( !this.value && this.selectKit.noneItem && @@ -41,24 +46,25 @@ export default Component.extend(UtilsMixin, { ) { return this.selectKit.noneItem.title || this.selectKit.noneItem.name; } - }), + } - icons: computed("selectKit.options.{icon,icons}", function () { + @computed("selectKit.options.{icon,icons}") + get icons() { const icon = makeArray(this.selectKit.options.icon); const icons = makeArray(this.selectKit.options.icons); return icon.concat(icons).filter(Boolean); - }), + } didInsertElement() { - this._super(...arguments); + super.didInsertElement(...arguments); if (this.selectKit.options.autofocus) { this.set("isFocused", true); } - }, + } mouseDown() { return false; - }, + } click(event) { event.preventDefault(); @@ -71,13 +77,13 @@ export default Component.extend(UtilsMixin, { return false; } this.selectKit.toggle(event); - }, + } keyUp(event) { if (event.key === " ") { event.preventDefault(); } - }, + } keyDown(event) { if ( @@ -165,7 +171,7 @@ export default Component.extend(UtilsMixin, { return true; } } - }, + } _focusFilterInput() { const filterContainer = document.querySelector( @@ -178,5 +184,5 @@ export default Component.extend(UtilsMixin, { const filterInput = filterContainer.querySelector(".filter-input"); filterInput && filterInput.focus(); } - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-none-row.js b/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-none-row.js index 5006771a98e..681ea72d11f 100644 --- a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-none-row.js +++ b/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-none-row.js @@ -1,5 +1,5 @@ +import { classNames } from "@ember-decorators/component"; import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row"; -export default SelectKitRowComponent.extend({ - classNames: "none", -}); +@classNames("none") +export default class SelectKitNoneRow extends SelectKitRowComponent {} diff --git a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-row.js b/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-row.js index 04bc0907460..4528d95bf5d 100644 --- a/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-row.js +++ b/app/assets/javascripts/select-kit/addon/components/select-kit/select-kit-row.js @@ -3,81 +3,89 @@ import { action, computed } from "@ember/object"; import { reads } from "@ember/object/computed"; import { guidFor } from "@ember/object/internals"; import { dasherize } from "@ember/string"; +import { + attributeBindings, + classNameBindings, + classNames, + tagName, +} from "@ember-decorators/component"; import { makeArray } from "discourse-common/lib/helpers"; import I18n from "discourse-i18n"; import UtilsMixin from "select-kit/mixins/utils"; -export default Component.extend(UtilsMixin, { - classNames: ["select-kit-row"], - tagName: "li", - tabIndex: 0, - - attributeBindings: [ - "tabIndex", - "title", - "rowValue:data-value", - "rowName:data-name", - "index:data-index", - "role", - "ariaChecked:aria-checked", - "guid:data-guid", - "rowLang:lang", - ], - - classNameBindings: [ - "isHighlighted", - "isSelected", - "isNone", - "isNone:none", - "item.classNames", - ], - - index: 0, - role: "menuitemradio", +@classNames("select-kit-row") +@tagName("li") +@attributeBindings( + "tabIndex", + "title", + "rowValue:data-value", + "rowName:data-name", + "index:data-index", + "role", + "ariaChecked:aria-checked", + "guid:data-guid", + "rowLang:lang" +) +@classNameBindings( + "isHighlighted", + "isSelected", + "isNone", + "isNone:none", + "item.classNames" +) +export default class SelectKitRow extends Component.extend(UtilsMixin) { + tabIndex = 0; + index = 0; + role = "menuitemradio"; + @reads("item.lang") lang; didInsertElement() { - this._super(...arguments); + super.didInsertElement(...arguments); if (this.site.desktopView) { this.element.addEventListener("mouseenter", this.handleMouseEnter); this.element.addEventListener("focus", this.handleMouseEnter); } - }, + } willDestroyElement() { - this._super(...arguments); + super.willDestroyElement(...arguments); if (this.site.desktopView) { this.element.removeEventListener("mouseenter", this.handleMouseEnter); this.element.removeEventListener("focus", this.handleMouseEnter); } - }, + } - isNone: computed("rowValue", function () { + @computed("rowValue") + get isNone() { return this.rowValue === this.getValue(this.selectKit.noneItem); - }), + } - guid: computed("item", function () { + @computed("item") + get guid() { return guidFor(this.item); - }), + } - lang: reads("item.lang"), - - ariaChecked: computed("isSelected", function () { + @computed("isSelected") + get ariaChecked() { return this.isSelected ? "true" : "false"; - }), + } - title: computed("rowTitle", "item.title", "rowName", function () { + @computed("rowTitle", "item.title", "rowName") + get title() { return ( this.rowTitle || this.getProperty(this.item, "title") || this.rowName ); - }), + } - dasherizedTitle: computed("title", function () { + @computed("title") + get dasherizedTitle() { return dasherize((this.title || "").replace(".", "-")); - }), + } - label: computed("rowLabel", "item.label", "title", "rowName", function () { + @computed("rowLabel", "item.label", "title", "rowName") + get label() { const label = this.rowLabel || this.getProperty(this.item, "label") || @@ -92,10 +100,10 @@ export default Component.extend(UtilsMixin, { return I18n.t("select_kit.create", { content: label }); } return label; - }), + } didReceiveAttrs() { - this._super(...arguments); + super.didReceiveAttrs(...arguments); this.setProperties({ rowName: this.getName(this.item), @@ -104,25 +112,29 @@ export default Component.extend(UtilsMixin, { rowTitle: this.getProperty(this.item, "titleProperty"), rowLang: this.getProperty(this.item, "langProperty"), }); - }, + } - icons: computed("item.{icon,icons}", function () { + @computed("item.{icon,icons}") + get icons() { const icon = makeArray(this.getProperty(this.item, "icon")); const icons = makeArray(this.getProperty(this.item, "icons")); return icon.concat(icons).filter(Boolean); - }), + } - highlightedValue: computed("selectKit.highlighted", function () { + @computed("selectKit.highlighted") + get highlightedValue() { return this.getValue(this.selectKit.highlighted); - }), + } - isHighlighted: computed("rowValue", "highlightedValue", function () { + @computed("rowValue", "highlightedValue") + get isHighlighted() { return this.rowValue === this.highlightedValue; - }), + } - isSelected: computed("rowValue", "value", function () { + @computed("rowValue", "value") + get isSelected() { return this.rowValue === this.value; - }), + } @action handleMouseEnter() { @@ -130,24 +142,24 @@ export default Component.extend(UtilsMixin, { this.selectKit.onHover(this.rowValue, this.item); } return false; - }, + } click(event) { event.preventDefault(); event.stopPropagation(); this.selectKit.select(this.rowValue, this.item); return false; - }, + } mouseDown(event) { if (this.selectKit.options.preventHeaderFocus) { event.preventDefault(); } - }, + } focusIn(event) { event.stopImmediatePropagation(); - }, + } keyDown(event) { if (this.selectKit.isExpanded) { @@ -189,5 +201,5 @@ export default Component.extend(UtilsMixin, { } } } - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/select-kit/single-select-header.js b/app/assets/javascripts/select-kit/addon/components/select-kit/single-select-header.js index 4178f1d1519..267ce36c426 100644 --- a/app/assets/javascripts/select-kit/addon/components/select-kit/single-select-header.js +++ b/app/assets/javascripts/select-kit/addon/components/select-kit/single-select-header.js @@ -1,14 +1,18 @@ import { computed } from "@ember/object"; import { or } from "@ember/object/computed"; +import { + attributeBindings, + classNames, + tagName, +} from "@ember-decorators/component"; import I18n from "discourse-i18n"; import SelectKitHeaderComponent from "select-kit/components/select-kit/select-kit-header"; -import UtilsMixin from "select-kit/mixins/utils"; -export default SelectKitHeaderComponent.extend(UtilsMixin, { - tagName: "summary", - classNames: ["single-select-header"], - attributeBindings: ["name", "ariaLabel:aria-label"], - ariaLabel: or("selectKit.options.headerAriaLabel", "name"), +@tagName("summary") +@classNames("single-select-header") +@attributeBindings("name", "ariaLabel:aria-label") +export default class SingleSelectHeader extends SelectKitHeaderComponent { + @or("selectKit.options.headerAriaLabel", "name") ariaLabel; focusIn(event) { event.stopImmediatePropagation(); @@ -18,9 +22,10 @@ export default SelectKitHeaderComponent.extend(UtilsMixin, { header.parentNode.open = false; } }); - }, + } - name: computed("selectedContent.name", function () { + @computed("selectedContent.name") + get name() { if (this.selectedContent) { return I18n.t("select_kit.filter_by", { name: this.getName(this.selectedContent), @@ -28,5 +33,5 @@ export default SelectKitHeaderComponent.extend(UtilsMixin, { } else { return I18n.t("select_kit.select_to_filter"); } - }), -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/selected-choice-category.js b/app/assets/javascripts/select-kit/addon/components/selected-choice-category.js index 9dbef9d226c..5e3368f9194 100644 --- a/app/assets/javascripts/select-kit/addon/components/selected-choice-category.js +++ b/app/assets/javascripts/select-kit/addon/components/selected-choice-category.js @@ -1,18 +1,20 @@ import { computed } from "@ember/object"; import { htmlSafe } from "@ember/template"; +import { tagName } from "@ember-decorators/component"; import { categoryBadgeHTML } from "discourse/helpers/category-link"; import SelectedChoiceComponent from "select-kit/components/selected-choice"; -export default SelectedChoiceComponent.extend({ - tagName: "", - extraClass: "selected-choice-category", +@tagName("") +export default class SelectedChoiceCategory extends SelectedChoiceComponent { + extraClass = "selected-choice-category"; - badge: computed("item", function () { + @computed("item") + get badge() { return htmlSafe( categoryBadgeHTML(this.item, { allowUncategorized: true, link: false, }) ); - }), -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/selected-choice-color.js b/app/assets/javascripts/select-kit/addon/components/selected-choice-color.js index 21269a1b9b7..455ca49092b 100644 --- a/app/assets/javascripts/select-kit/addon/components/selected-choice-color.js +++ b/app/assets/javascripts/select-kit/addon/components/selected-choice-color.js @@ -1,20 +1,21 @@ import { computed } from "@ember/object"; import { schedule } from "@ember/runloop"; +import { tagName } from "@ember-decorators/component"; import { escapeExpression } from "discourse/lib/utilities"; import SelectedChoiceComponent from "select-kit/components/selected-choice"; -export default SelectedChoiceComponent.extend({ - tagName: "", +@tagName("") +export default class SelectedChoiceColor extends SelectedChoiceComponent { + extraClass = "selected-choice-color"; - extraClass: "selected-choice-color", - - escapedColor: computed("item", function () { + @computed("item") + get escapedColor() { const color = `${escapeExpression(this.item?.name || this.item)}`; return color.startsWith("#") ? color : `#${color}`; - }), + } didInsertElement() { - this._super(...arguments); + super.didInsertElement(...arguments); schedule("afterRender", () => { const element = document.querySelector( @@ -27,5 +28,5 @@ export default SelectedChoiceComponent.extend({ element.style.borderBottomColor = this.escapedColor; }); - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/selected-choice.js b/app/assets/javascripts/select-kit/addon/components/selected-choice.js index 5754e8e8e95..abf8b3b5053 100644 --- a/app/assets/javascripts/select-kit/addon/components/selected-choice.js +++ b/app/assets/javascripts/select-kit/addon/components/selected-choice.js @@ -1,34 +1,39 @@ import Component from "@ember/component"; import { computed } from "@ember/object"; import { guidFor } from "@ember/object/internals"; +import { tagName } from "@ember-decorators/component"; import UtilsMixin from "select-kit/mixins/utils"; -export default Component.extend(UtilsMixin, { - tagName: "", - item: null, - selectKit: null, - extraClass: null, - id: null, +@tagName("") +export default class SelectedChoice extends Component.extend(UtilsMixin) { + item = null; + selectKit = null; + extraClass = null; + id = null; init() { - this._super(...arguments); + super.init(...arguments); this.set("id", guidFor(this)); - }, + } - itemValue: computed("item", function () { + @computed("item") + get itemValue() { return this.getValue(this.item); - }), + } - itemName: computed("item", function () { + @computed("item") + get itemName() { return this.getName(this.item); - }), + } - mandatoryValuesArray: computed("item", function () { + @computed("item") + get mandatoryValuesArray() { return this.get("mandatoryValues")?.split("|") || []; - }), + } - readOnly: computed("item", function () { + @computed("item") + get readOnly() { return this.mandatoryValuesArray.includes(this.item.id); - }), -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/selected-color.js b/app/assets/javascripts/select-kit/addon/components/selected-color.js index dd2024b5f62..dfff0bd50a9 100644 --- a/app/assets/javascripts/select-kit/addon/components/selected-color.js +++ b/app/assets/javascripts/select-kit/addon/components/selected-color.js @@ -1,12 +1,12 @@ import { schedule } from "@ember/runloop"; +import { classNames } from "@ember-decorators/component"; import { escapeExpression } from "discourse/lib/utilities"; import SelectedNameComponent from "select-kit/components/selected-name"; -export default SelectedNameComponent.extend({ - classNames: ["select-kit-selected-color"], - +@classNames("select-kit-selected-color") +export default class SelectedColor extends SelectedNameComponent { didInsertElement() { - this._super(...arguments); + super.didInsertElement(...arguments); schedule("afterRender", () => { const element = document.querySelector( @@ -21,5 +21,5 @@ export default SelectedNameComponent.extend({ const color = escapeExpression(this.name); element.style.borderBottomColor = `#${color}`; }); - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/selected-flair.js b/app/assets/javascripts/select-kit/addon/components/selected-flair.js index 89313eca5e3..c3f32266fb6 100644 --- a/app/assets/javascripts/select-kit/addon/components/selected-flair.js +++ b/app/assets/javascripts/select-kit/addon/components/selected-flair.js @@ -1,5 +1,5 @@ +import { tagName } from "@ember-decorators/component"; import SelectedNameComponent from "select-kit/components/selected-name"; -export default SelectedNameComponent.extend({ - tagName: "", -}); +@tagName("") +export default class SelectedFlair extends SelectedNameComponent {} diff --git a/app/assets/javascripts/select-kit/addon/components/selected-name.js b/app/assets/javascripts/select-kit/addon/components/selected-name.js index cf55a094b99..31029054620 100644 --- a/app/assets/javascripts/select-kit/addon/components/selected-name.js +++ b/app/assets/javascripts/select-kit/addon/components/selected-name.js @@ -2,26 +2,29 @@ import Component from "@ember/component"; import { computed, get } from "@ember/object"; import { reads } from "@ember/object/computed"; import { guidFor } from "@ember/object/internals"; +import { tagName } from "@ember-decorators/component"; import { makeArray } from "discourse-common/lib/helpers"; import UtilsMixin from "select-kit/mixins/utils"; -export default Component.extend(UtilsMixin, { - tagName: "", - name: null, - value: null, - headerTitle: null, - headerLang: null, - headerLabel: null, - id: null, +@tagName("") +export default class SelectedName extends Component.extend(UtilsMixin) { + name = null; + value = null; + headerTitle = null; + headerLang = null; + headerLabel = null; + id = null; + + @reads("headerLang") lang; init() { - this._super(...arguments); + super.init(...arguments); this.set("id", guidFor(this)); - }, + } didReceiveAttrs() { - this._super(...arguments); + super.didReceiveAttrs(...arguments); // we can't listen on `item.nameProperty` given it's variable this.setProperties({ @@ -32,43 +35,46 @@ export default Component.extend(UtilsMixin, { value: this.item === this.selectKit.noneItem ? null : this.getValue(this.item), }); - }, + } - lang: reads("headerLang"), - - ariaLabel: computed("item", "sanitizedTitle", function () { + @computed("item", "sanitizedTitle") + get ariaLabel() { return this._safeProperty("ariaLabel", this.item) || this.sanitizedTitle; - }), + } // this might need a more advanced solution // but atm it's the only case we have to handle - sanitizedTitle: computed("title", function () { + @computed("title") + get sanitizedTitle() { return String(this.title).replace("…", ""); - }), + } - title: computed("headerTitle", "item", function () { + @computed("headerTitle", "item") + get title() { return ( this.headerTitle || this._safeProperty("title", this.item) || this.name || "" ); - }), + } - label: computed("headerLabel", "title", "name", function () { + @computed("headerLabel", "title", "name") + get label() { return ( this.headerLabel || this._safeProperty("label", this.item) || this.title || this.name ); - }), + } - icons: computed("item.{icon,icons}", function () { + @computed("item.{icon,icons}") + get icons() { const icon = makeArray(this._safeProperty("icon", this.item)); const icons = makeArray(this._safeProperty("icons", this.item)); return icon.concat(icons).filter(Boolean); - }), + } _safeProperty(name, content) { if (!content) { @@ -76,5 +82,5 @@ export default Component.extend(UtilsMixin, { } return get(content, name); - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/tag-chooser-row.js b/app/assets/javascripts/select-kit/addon/components/tag-chooser-row.js index 847621a6879..2efa8e2580f 100644 --- a/app/assets/javascripts/select-kit/addon/components/tag-chooser-row.js +++ b/app/assets/javascripts/select-kit/addon/components/tag-chooser-row.js @@ -1,5 +1,5 @@ +import { classNames } from "@ember-decorators/component"; import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row"; -export default SelectKitRowComponent.extend({ - classNames: ["tag-chooser-row"], -}); +@classNames("tag-chooser-row") +export default class TagChooserRow extends SelectKitRowComponent {} diff --git a/app/assets/javascripts/select-kit/addon/components/tag-chooser.js b/app/assets/javascripts/select-kit/addon/components/tag-chooser.js index ae3bfceee2f..5395e059f34 100644 --- a/app/assets/javascripts/select-kit/addon/components/tag-chooser.js +++ b/app/assets/javascripts/select-kit/addon/components/tag-chooser.js @@ -1,19 +1,27 @@ -import { computed } from "@ember/object"; +import { action, computed } from "@ember/object"; +import { attributeBindings, classNames } from "@ember-decorators/component"; import { makeArray } from "discourse-common/lib/helpers"; import MultiSelectComponent from "select-kit/components/multi-select"; +import { + pluginApiIdentifiers, + selectKitOptions, +} from "select-kit/components/select-kit"; import TagsMixin from "select-kit/mixins/tags"; -export default MultiSelectComponent.extend(TagsMixin, { - pluginApiIdentifiers: ["tag-chooser"], - classNames: ["tag-chooser"], - - selectKitOptions: { - filterable: true, - filterPlaceholder: "tagging.choose_for_topic", - limit: null, - allowAny: "canCreateTag", - maximum: "maximumTagCount", - }, +@classNames("tag-chooser") +@attributeBindings("categoryId") +@selectKitOptions({ + filterable: true, + filterPlaceholder: "tagging.choose_for_topic", + limit: null, + allowAny: "canCreateTag", + maximum: "maximumTagCount", +}) +@pluginApiIdentifiers("tag-chooser") +export default class TagChooser extends MultiSelectComponent.extend(TagsMixin) { + blockedTags = null; + excludeSynonyms = false; + excludeHasSynonyms = false; modifyComponentForRow(collection, item) { if (this.getValue(item) === this.selectKit.filter && !item.count) { @@ -21,63 +29,57 @@ export default MultiSelectComponent.extend(TagsMixin, { } return "tag-chooser-row"; - }, + } - blockedTags: null, - attributeBindings: ["categoryId"], - excludeSynonyms: false, - excludeHasSynonyms: false, - - canCreateTag: computed("site.can_create_tag", "allowCreate", function () { + @computed("site.can_create_tag", "allowCreate") + get canCreateTag() { return this.allowCreate && this.site.can_create_tag; - }), + } - maximumTagCount: computed( - "siteSettings.max_tags_per_topic", - "unlimitedTagCount", - function () { - if (!this.unlimitedTagCount) { - return parseInt( - this.options.limit || - this.options.maximum || - this.siteSettings.max_tags_per_topic, - 10 - ); - } - - return null; + @computed("siteSettings.max_tags_per_topic", "unlimitedTagCount") + get maximumTagCount() { + if (!this.unlimitedTagCount) { + return parseInt( + this.options.limit || + this.options.maximum || + this.siteSettings.max_tags_per_topic, + 10 + ); } - ), + + return null; + } init() { - this._super(...arguments); + super.init(...arguments); this.setProperties({ blockedTags: this.blockedTags || [], termMatchesForbidden: false, termMatchErrorMessage: null, }); - }, + } - value: computed("tags.[]", function () { + @computed("tags.[]") + get value() { return makeArray(this.tags).uniq(); - }), + } - content: computed("tags.[]", function () { + @computed("tags.[]") + get content() { return makeArray(this.tags) .uniq() .map((t) => this.defaultItem(t, t)); - }), + } - actions: { - onChange(value, items) { - if (this.onChange) { - this.onChange(value, items); - } else { - this.set("tags", value); - } - }, - }, + @action + _onChange(value, items) { + if (this.onChange) { + this.onChange(value, items); + } else { + this.set("tags", value); + } + } search(query) { const selectedTags = makeArray(this.tags).filter(Boolean); @@ -106,7 +108,7 @@ export default MultiSelectComponent.extend(TagsMixin, { } return this.searchTags("/tags/filter/search", data, this._transformJson); - }, + } _transformJson(context, json) { if (context.isDestroyed || context.isDestroying) { @@ -131,5 +133,5 @@ export default MultiSelectComponent.extend(TagsMixin, { } return results.uniqBy("id"); - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/tag-drop.js b/app/assets/javascripts/select-kit/addon/components/tag-drop.js index 93bcd65b7ce..4ac19de23e4 100644 --- a/app/assets/javascripts/select-kit/addon/components/tag-drop.js +++ b/app/assets/javascripts/select-kit/addon/components/tag-drop.js @@ -1,12 +1,17 @@ -import { computed } from "@ember/object"; +import { action, computed } from "@ember/object"; import { readOnly } from "@ember/object/computed"; +import { classNameBindings, classNames } from "@ember-decorators/component"; import { setting } from "discourse/lib/computed"; import DiscourseURL, { getCategoryAndTagUrl } from "discourse/lib/url"; import { makeArray } from "discourse-common/lib/helpers"; import I18n from "discourse-i18n"; import ComboBoxComponent from "select-kit/components/combo-box"; import FilterForMore from "select-kit/components/filter-for-more"; -import { MAIN_COLLECTION } from "select-kit/components/select-kit"; +import { + MAIN_COLLECTION, + pluginApiIdentifiers, + selectKitOptions, +} from "select-kit/components/select-kit"; import TagsMixin from "select-kit/mixins/tags"; export const NO_TAG_ID = "no-tags"; @@ -16,48 +21,45 @@ export const NONE_TAG = "none"; const MORE_TAGS_COLLECTION = "MORE_TAGS_COLLECTION"; -export default ComboBoxComponent.extend(TagsMixin, { - pluginApiIdentifiers: ["tag-drop"], - classNameBindings: ["tagClass"], - classNames: ["tag-drop"], - value: readOnly("tagId"), - maxTagSearchResults: setting("max_tag_search_results"), - sortTagsAlphabetically: setting("tags_sort_alphabetically"), - maxTagsInFilterList: setting("max_tags_in_filter_list"), - shouldShowMoreTags: computed( - "maxTagsInFilterList", - "topTags.[]", - "mainCollection.[]", - function () { - if (this.selectKit.filter?.length > 0) { - return this.mainCollection.length > this.maxTagsInFilterList; - } else { - return this.topTags.length > this.maxTagsInFilterList; - } - } - ), +@classNameBindings("tagClass") +@classNames("tag-drop") +@selectKitOptions({ + allowAny: false, + caretDownIcon: "caret-right", + caretUpIcon: "caret-down", + fullWidthOnMobile: true, + filterable: true, + headerComponent: "tag-drop/tag-drop-header", + autoInsertNoneItem: false, +}) +@pluginApiIdentifiers("tag-drop") +export default class TagDrop extends ComboBoxComponent.extend(TagsMixin) { + @setting("max_tag_search_results") maxTagSearchResults; + @setting("tags_sort_alphabetically") sortTagsAlphabetically; + @setting("max_tags_in_filter_list") maxTagsInFilterList; - selectKitOptions: { - allowAny: false, - caretDownIcon: "caret-right", - caretUpIcon: "caret-down", - fullWidthOnMobile: true, - filterable: true, - headerComponent: "tag-drop/tag-drop-header", - autoInsertNoneItem: false, - }, + @readOnly("tagId") value; + + @computed("maxTagsInFilterList", "topTags.[]", "mainCollection.[]") + get shouldShowMoreTags() { + if (this.selectKit.filter?.length > 0) { + return this.mainCollection.length > this.maxTagsInFilterList; + } else { + return this.topTags.length > this.maxTagsInFilterList; + } + } init() { - this._super(...arguments); + super.init(...arguments); this.insertAfterCollection(MAIN_COLLECTION, MORE_TAGS_COLLECTION); - }, + } modifyComponentForCollection(collection) { if (collection === MORE_TAGS_COLLECTION) { return FilterForMore; } - }, + } modifyContentForCollection(collection) { if (collection === MORE_TAGS_COLLECTION) { @@ -65,7 +67,7 @@ export default ComboBoxComponent.extend(TagsMixin, { shouldShowMoreTip: this.shouldShowMoreTags, }; } - }, + } modifyNoSelection() { if (this.tagId === NONE_TAG) { @@ -73,7 +75,7 @@ export default ComboBoxComponent.extend(TagsMixin, { } else { return this.defaultItem(ALL_TAGS_ID, I18n.t("tagging.selector_tags")); } - }, + } modifySelection(content) { if (this.tagId === NONE_TAG) { @@ -83,17 +85,19 @@ export default ComboBoxComponent.extend(TagsMixin, { } return content; - }, + } - tagClass: computed("tagId", function () { + @computed("tagId") + get tagClass() { return this.tagId ? `tag-${this.tagId}` : "tag_all"; - }), + } modifyComponentForRow() { return "tag-row"; - }, + } - shortcuts: computed("tagId", function () { + @computed("tagId") + get shortcuts() { const shortcuts = []; if (this.tagId) { @@ -117,29 +121,26 @@ export default ComboBoxComponent.extend(TagsMixin, { } return shortcuts; - }), + } - topTags: computed( - "currentCategory", - "site.category_top_tags.[]", - "site.top_tags.[]", - function () { - if (this.currentCategory && this.site.category_top_tags) { - return this.site.category_top_tags || []; - } - - return this.site.top_tags || []; + @computed("currentCategory", "site.category_top_tags.[]", "site.top_tags.[]") + get topTags() { + if (this.currentCategory && this.site.category_top_tags) { + return this.site.category_top_tags || []; } - ), - content: computed("topTags.[]", "shortcuts.[]", function () { + return this.site.top_tags || []; + } + + @computed("topTags.[]", "shortcuts.[]") + get content() { const topTags = this.topTags.slice(0, this.maxTagsInFilterList); if (this.sortTagsAlphabetically && topTags) { return this.shortcuts.concat(topTags.sort()); } else { return this.shortcuts.concat(makeArray(topTags)); } - }), + } search(filter) { if (filter) { @@ -157,7 +158,7 @@ export default ComboBoxComponent.extend(TagsMixin, { return this.defaultItem(tag, tag); }); } - }, + } _transformJson(context, json) { return json.results @@ -171,21 +172,20 @@ export default ComboBoxComponent.extend(TagsMixin, { content.pmCount = r.pm_count; return content; }); - }, + } - actions: { - onChange(tagId, tag) { - if (tagId === NO_TAG_ID) { - tagId = NONE_TAG; - } else if (tagId === ALL_TAGS_ID) { - tagId = null; - } else if (tag && tag.targetTagId) { - tagId = tag.targetTagId; - } + @action + onChange(tagId, tag) { + if (tagId === NO_TAG_ID) { + tagId = NONE_TAG; + } else if (tagId === ALL_TAGS_ID) { + tagId = null; + } else if (tag && tag.targetTagId) { + tagId = tag.targetTagId; + } - DiscourseURL.routeToUrl( - getCategoryAndTagUrl(this.currentCategory, !this.noSubcategories, tagId) - ); - }, - }, -}); + DiscourseURL.routeToUrl( + getCategoryAndTagUrl(this.currentCategory, !this.noSubcategories, tagId) + ); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/tag-drop/tag-drop-header.js b/app/assets/javascripts/select-kit/addon/components/tag-drop/tag-drop-header.js index ec95b655b27..1bd8b564f8b 100644 --- a/app/assets/javascripts/select-kit/addon/components/tag-drop/tag-drop-header.js +++ b/app/assets/javascripts/select-kit/addon/components/tag-drop/tag-drop-header.js @@ -1,5 +1,5 @@ +import { classNames } from "@ember-decorators/component"; import ComboBoxSelectBoxHeaderComponent from "select-kit/components/combo-box/combo-box-header"; -export default ComboBoxSelectBoxHeaderComponent.extend({ - classNames: "tag-drop-header", -}); +@classNames("tag-drop-header") +export default class TagDropHeader extends ComboBoxSelectBoxHeaderComponent {} diff --git a/app/assets/javascripts/select-kit/addon/components/tag-group-chooser.js b/app/assets/javascripts/select-kit/addon/components/tag-group-chooser.js index 65a2affe324..7ff2a872f6a 100644 --- a/app/assets/javascripts/select-kit/addon/components/tag-group-chooser.js +++ b/app/assets/javascripts/select-kit/addon/components/tag-group-chooser.js @@ -1,32 +1,39 @@ import { computed } from "@ember/object"; +import { classNames } from "@ember-decorators/component"; import { makeArray } from "discourse-common/lib/helpers"; import MultiSelectComponent from "select-kit/components/multi-select"; +import { + pluginApiIdentifiers, + selectKitOptions, +} from "select-kit/components/select-kit"; import TagsMixin from "select-kit/mixins/tags"; -export default MultiSelectComponent.extend(TagsMixin, { - pluginApiIdentifiers: ["tag-group-chooser"], - classNames: ["tag-group-chooser", "tag-chooser"], - - selectKitOptions: { - allowAny: false, - filterable: true, - filterPlaceholder: "category.tag_groups_placeholder", - limit: null, - }, - +@classNames("tag-group-chooser", "tag-chooser") +@selectKitOptions({ + allowAny: false, + filterable: true, + filterPlaceholder: "category.tag_groups_placeholder", + limit: null, +}) +@pluginApiIdentifiers("tag-group-chooser") +export default class TagGroupChooser extends MultiSelectComponent.extend( + TagsMixin +) { modifyComponentForRow() { return "tag-chooser-row"; - }, + } - value: computed("tagGroups.[]", function () { + @computed("tagGroups.[]") + get value() { return makeArray(this.tagGroups).uniq(); - }), + } - content: computed("tagGroups.[]", function () { + @computed("tagGroups.[]") + get content() { return makeArray(this.tagGroups) .uniq() .map((t) => this.defaultItem(t, t)); - }), + } search(query) { const data = { @@ -45,7 +52,7 @@ export default MultiSelectComponent.extend(TagsMixin, { }); } }); - }, + } _transformJson(context, json) { return json.results @@ -53,5 +60,5 @@ export default MultiSelectComponent.extend(TagsMixin, { .map((result) => { return { id: result.name, name: result.name, count: result.count }; }); - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/tag-notifications-button.js b/app/assets/javascripts/select-kit/addon/components/tag-notifications-button.js index 19b49da2a65..4a49ac8e627 100644 --- a/app/assets/javascripts/select-kit/addon/components/tag-notifications-button.js +++ b/app/assets/javascripts/select-kit/addon/components/tag-notifications-button.js @@ -1,11 +1,14 @@ +import { classNames } from "@ember-decorators/component"; import NotificationsButtonComponent from "select-kit/components/notifications-button"; +import { + pluginApiIdentifiers, + selectKitOptions, +} from "select-kit/components/select-kit"; -export default NotificationsButtonComponent.extend({ - pluginApiIdentifiers: ["tag-notifications-button"], - classNames: ["tag-notifications-button"], - - selectKitOptions: { - showFullTitle: false, - i18nPrefix: "tagging.notifications", - }, -}); +@classNames("tag-notifications-button") +@selectKitOptions({ + showFullTitle: false, + i18nPrefix: "tagging.notifications", +}) +@pluginApiIdentifiers("tag-notifications-button") +export default class TagNotificationsButton extends NotificationsButtonComponent {} diff --git a/app/assets/javascripts/select-kit/addon/components/tag-row.js b/app/assets/javascripts/select-kit/addon/components/tag-row.js index 3801867edbb..0b52bca8c71 100644 --- a/app/assets/javascripts/select-kit/addon/components/tag-row.js +++ b/app/assets/javascripts/select-kit/addon/components/tag-row.js @@ -1,11 +1,11 @@ +import { classNames } from "@ember-decorators/component"; import discourseComputed from "discourse-common/utils/decorators"; import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row"; -export default SelectKitRowComponent.extend({ - classNames: ["tag-row"], - +@classNames("tag-row") +export default class TagRow extends SelectKitRowComponent { @discourseComputed("item") isTag(item) { return item.id !== "no-tags" && item.id !== "all-tags"; - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/tags-intersection-chooser.js b/app/assets/javascripts/select-kit/addon/components/tags-intersection-chooser.js index 4e3719a0073..3dd64bdff2d 100644 --- a/app/assets/javascripts/select-kit/addon/components/tags-intersection-chooser.js +++ b/app/assets/javascripts/select-kit/addon/components/tags-intersection-chooser.js @@ -1,24 +1,25 @@ import { action } from "@ember/object"; +import { attributeBindings, classNames } from "@ember-decorators/component"; import DiscourseURL from "discourse/lib/url"; import { makeArray } from "discourse-common/lib/helpers"; import MiniTagChooser from "select-kit/components/mini-tag-chooser"; +import { pluginApiIdentifiers } from "select-kit/components/select-kit"; -export default MiniTagChooser.extend({ - pluginApiIdentifiers: ["tags-intersection-chooser"], - attributeBindings: ["selectKit.options.categoryId:category-id"], - classNames: ["tags-intersection-chooser"], - - mainTag: null, - additionalTags: null, +@attributeBindings("selectKit.options.categoryId:category-id") +@classNames("tags-intersection-chooser") +@pluginApiIdentifiers("tags-intersection-chooser") +export default class TagsIntersectionChooser extends MiniTagChooser { + mainTag = null; + additionalTags = null; didReceiveAttrs() { - this._super(...arguments); + super.didReceiveAttrs(...arguments); this.set( "value", makeArray(this.mainTag).concat(makeArray(this.additionalTags)) ); - }, + } @action onChange(tags) { @@ -39,5 +40,5 @@ export default MiniTagChooser.extend({ DiscourseURL.routeTo("/tags"); } } - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/timezone-input.js b/app/assets/javascripts/select-kit/addon/components/timezone-input.js index 28a0c25e6d9..bcb8f5f9d6f 100644 --- a/app/assets/javascripts/select-kit/addon/components/timezone-input.js +++ b/app/assets/javascripts/select-kit/addon/components/timezone-input.js @@ -1,29 +1,32 @@ +import { classNames } from "@ember-decorators/component"; import ComboBoxComponent from "select-kit/components/combo-box"; +import { + pluginApiIdentifiers, + selectKitOptions, +} from "select-kit/components/select-kit"; -export default ComboBoxComponent.extend({ - pluginApiIdentifiers: ["timezone-input"], - classNames: ["timezone-input"], - - selectKitOptions: { - filterable: true, - allowAny: false, - }, - +@classNames("timezone-input") +@selectKitOptions({ + filterable: true, + allowAny: false, +}) +@pluginApiIdentifiers("timezone-input") +export default class TimezoneInput extends ComboBoxComponent { get nameProperty() { return this.isLocalized ? "name" : null; - }, + } get valueProperty() { return this.isLocalized ? "value" : null; - }, + } get content() { return this.isLocalized ? moment.tz.localizedNames() : moment.tz.names(); - }, + } get isLocalized() { return ( moment.locale() !== "en" && typeof moment.tz.localizedNames === "function" ); - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/toolbar-popup-menu-options.js b/app/assets/javascripts/select-kit/addon/components/toolbar-popup-menu-options.js index bd6a262eadd..b8ec6c432cc 100644 --- a/app/assets/javascripts/select-kit/addon/components/toolbar-popup-menu-options.js +++ b/app/assets/javascripts/select-kit/addon/components/toolbar-popup-menu-options.js @@ -1,20 +1,23 @@ +import { classNames } from "@ember-decorators/component"; import { PLATFORM_KEY_MODIFIER } from "discourse/lib/keyboard-shortcuts"; import { translateModKey } from "discourse/lib/utilities"; import I18n from "discourse-i18n"; import DropdownSelectBoxComponent from "select-kit/components/dropdown-select-box"; +import { + pluginApiIdentifiers, + selectKitOptions, +} from "select-kit/components/select-kit"; -export default DropdownSelectBoxComponent.extend({ - pluginApiIdentifiers: ["toolbar-popup-menu-options"], - classNames: ["toolbar-popup-menu-options"], - - selectKitOptions: { - showFullTitle: false, - filterable: false, - autoFilterable: false, - preventHeaderFocus: true, - customStyle: true, - }, - +@classNames("toolbar-popup-menu-options") +@selectKitOptions({ + showFullTitle: false, + filterable: false, + autoFilterable: false, + preventHeaderFocus: true, + customStyle: true, +}) +@pluginApiIdentifiers("toolbar-popup-menu-options") +export default class ToolbarPopupMenuOptions extends DropdownSelectBoxComponent { modifyContent(contents) { return contents .map((content) => { @@ -54,5 +57,5 @@ export default DropdownSelectBoxComponent.extend({ } }) .filter(Boolean); - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/toolbar-popup-menu-options/toolbar-popup-menu-options-heading.js b/app/assets/javascripts/select-kit/addon/components/toolbar-popup-menu-options/toolbar-popup-menu-options-heading.js index 87d5ddb040f..0ba554f666a 100644 --- a/app/assets/javascripts/select-kit/addon/components/toolbar-popup-menu-options/toolbar-popup-menu-options-heading.js +++ b/app/assets/javascripts/select-kit/addon/components/toolbar-popup-menu-options/toolbar-popup-menu-options-heading.js @@ -1,3 +1,3 @@ import Component from "@ember/component"; -export default Component.extend({}); +export default class ToolbarPopupMenuOptionsHeading extends Component {} diff --git a/app/assets/javascripts/select-kit/addon/components/topic-chooser.js b/app/assets/javascripts/select-kit/addon/components/topic-chooser.js index 59cf6d1ffbe..b4dbcb6b374 100644 --- a/app/assets/javascripts/select-kit/addon/components/topic-chooser.js +++ b/app/assets/javascripts/select-kit/addon/components/topic-chooser.js @@ -1,25 +1,28 @@ import { isEmpty } from "@ember/utils"; +import { classNames } from "@ember-decorators/component"; import { searchForTerm } from "discourse/lib/search"; import ComboBoxComponent from "select-kit/components/combo-box"; +import { + pluginApiIdentifiers, + selectKitOptions, +} from "select-kit/components/select-kit"; -export default ComboBoxComponent.extend({ - pluginApiIdentifiers: ["topic-chooser"], - classNames: ["topic-chooser"], - - nameProperty: "fancy_title", - labelProperty: "title", - titleProperty: "title", - - selectKitOptions: { - clearable: true, - filterable: true, - filterPlaceholder: "choose_topic.title.placeholder", - additionalFilters: "", - }, +@classNames("topic-chooser") +@selectKitOptions({ + clearable: true, + filterable: true, + filterPlaceholder: "choose_topic.title.placeholder", + additionalFilters: "", +}) +@pluginApiIdentifiers("topic-chooser") +export default class TopicChooser extends ComboBoxComponent { + nameProperty = "fancy_title"; + labelProperty = "title"; + titleProperty = "title"; modifyComponentForRow() { return "topic-row"; - }, + } search(filter) { if (isEmpty(filter) && isEmpty(this.selectKit.options.additionalFilters)) { @@ -41,5 +44,5 @@ export default ComboBoxComponent.extend({ return results.posts.mapBy("topic"); } }); - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/topic-footer-mobile-dropdown.js b/app/assets/javascripts/select-kit/addon/components/topic-footer-mobile-dropdown.js index cf0c72c4332..90eb36287bd 100644 --- a/app/assets/javascripts/select-kit/addon/components/topic-footer-mobile-dropdown.js +++ b/app/assets/javascripts/select-kit/addon/components/topic-footer-mobile-dropdown.js @@ -1,18 +1,21 @@ +import { action } from "@ember/object"; +import { classNames } from "@ember-decorators/component"; import ComboBoxComponent from "select-kit/components/combo-box"; +import { + pluginApiIdentifiers, + selectKitOptions, +} from "select-kit/components/select-kit"; -export default ComboBoxComponent.extend({ - pluginApiIdentifiers: ["topic-footer-mobile-dropdown"], - classNames: ["topic-footer-mobile-dropdown"], - - selectKitOptions: { - none: "topic.controls", - filterable: false, - autoFilterable: false, - }, - - actions: { - onChange(value, item) { - item.action && item.action(); - }, - }, -}); +@classNames("topic-footer-mobile-dropdown") +@selectKitOptions({ + none: "topic.controls", + filterable: false, + autoFilterable: false, +}) +@pluginApiIdentifiers("topic-footer-mobile-dropdown") +export default class TopicFooterMobileDropdown extends ComboBoxComponent { + @action + onChange(value, item) { + item.action && item.action(); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/topic-notifications-button.js b/app/assets/javascripts/select-kit/addon/components/topic-notifications-button.js index 8cb9c26ebbd..8fc2121ae77 100644 --- a/app/assets/javascripts/select-kit/addon/components/topic-notifications-button.js +++ b/app/assets/javascripts/select-kit/addon/components/topic-notifications-button.js @@ -1,24 +1,26 @@ import Component from "@ember/component"; import { action, computed } from "@ember/object"; import { isEmpty } from "@ember/utils"; +import { classNameBindings, classNames } from "@ember-decorators/component"; import { NotificationLevels } from "discourse/lib/notification-levels"; import getURL from "discourse-common/lib/get-url"; import discourseComputed from "discourse-common/utils/decorators"; import I18n from "discourse-i18n"; -export default Component.extend({ - classNames: ["topic-notifications-button"], - classNameBindings: ["isLoading"], - appendReason: true, - showFullTitle: true, - notificationLevel: null, - topic: null, - showCaret: true, - isLoading: false, +@classNames("topic-notifications-button") +@classNameBindings("isLoading") +export default class TopicNotificationsButton extends Component { + appendReason = true; + showFullTitle = true; + notificationLevel = null; + topic = null; + showCaret = true; + isLoading = false; - icon: computed("isLoading", function () { + @computed("isLoading") + get icon() { return this.isLoading ? "spinner" : null; - }), + } @action changeTopicNotificationLevel(levelId) { @@ -28,7 +30,7 @@ export default Component.extend({ .updateNotifications(levelId) .finally(() => this.set("isLoading", false)); } - }, + } @discourseComputed( "topic", @@ -70,7 +72,7 @@ export default Component.extend({ basePath: getURL(""), }); } - }, + } // The user may have changed their category or tag tracking settings // since this topic was tracked/watched based on those settings in the @@ -112,5 +114,5 @@ export default Component.extend({ } return false; - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/topic-notifications-options.js b/app/assets/javascripts/select-kit/addon/components/topic-notifications-options.js index e4be1b1d185..8e795e1d8ba 100644 --- a/app/assets/javascripts/select-kit/addon/components/topic-notifications-options.js +++ b/app/assets/javascripts/select-kit/addon/components/topic-notifications-options.js @@ -1,19 +1,24 @@ import { computed } from "@ember/object"; +import { classNames } from "@ember-decorators/component"; import { topicLevels } from "discourse/lib/notification-levels"; import NotificationsButtonComponent from "select-kit/components/notifications-button"; +import { + pluginApiIdentifiers, + selectKitOptions, +} from "select-kit/components/select-kit"; -export default NotificationsButtonComponent.extend({ - pluginApiIdentifiers: ["topic-notifications-options"], - classNames: ["topic-notifications-options"], - content: topicLevels, +@classNames("topic-notifications-options") +@selectKitOptions({ + i18nPrefix: "topic.notifications", + i18nPostfix: "i18nPostfix", + showCaret: true, +}) +@pluginApiIdentifiers("topic-notifications-options") +export default class TopicNotificationsOptions extends NotificationsButtonComponent { + content = topicLevels; - selectKitOptions: { - i18nPrefix: "topic.notifications", - i18nPostfix: "i18nPostfix", - showCaret: true, - }, - - i18nPostfix: computed("topic.archetype", function () { + @computed("topic.archetype") + get i18nPostfix() { return this.topic.archetype === "private_message" ? "_pm" : ""; - }), -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/topic-row.js b/app/assets/javascripts/select-kit/addon/components/topic-row.js index 46d0df1f176..51c02080910 100644 --- a/app/assets/javascripts/select-kit/addon/components/topic-row.js +++ b/app/assets/javascripts/select-kit/addon/components/topic-row.js @@ -1,5 +1,5 @@ +import { classNames } from "@ember-decorators/component"; import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row"; -export default SelectKitRowComponent.extend({ - classNames: ["topic-row"], -}); +@classNames("topic-row") +export default class TopicRow extends SelectKitRowComponent {} diff --git a/app/assets/javascripts/select-kit/addon/components/user-chooser.js b/app/assets/javascripts/select-kit/addon/components/user-chooser.js index 5169d26fe2c..6fabc3422d0 100644 --- a/app/assets/javascripts/select-kit/addon/components/user-chooser.js +++ b/app/assets/javascripts/select-kit/addon/components/user-chooser.js @@ -1,58 +1,61 @@ import { computed } from "@ember/object"; import { isPresent } from "@ember/utils"; +import { classNames } from "@ember-decorators/component"; import userSearch, { eagerCompleteSearch, skipSearch, } from "discourse/lib/user-search"; import { makeArray } from "discourse-common/lib/helpers"; import MultiSelectComponent from "select-kit/components/multi-select"; +import { + pluginApiIdentifiers, + selectKitOptions, +} from "select-kit/components/select-kit"; export const CUSTOM_USER_SEARCH_OPTIONS = []; -export default MultiSelectComponent.extend({ - pluginApiIdentifiers: ["user-chooser"], - classNames: ["user-chooser"], - valueProperty: "username", +@classNames("user-chooser") +@selectKitOptions({ + topicId: undefined, + categoryId: undefined, + includeGroups: false, + allowedUsers: false, + includeMentionableGroups: false, + includeMessageableGroups: false, + allowEmails: false, + groupMembersOf: undefined, + excludeCurrentUser: false, + customSearchOptions: undefined, + excludedUsernames: undefined, +}) +@pluginApiIdentifiers("user-chooser") +export default class UserChooser extends MultiSelectComponent { + valueProperty = "username"; modifyComponentForRow() { return "user-chooser/user-row"; - }, + } - selectKitOptions: { - topicId: undefined, - categoryId: undefined, - includeGroups: false, - allowedUsers: false, - includeMentionableGroups: false, - includeMessageableGroups: false, - allowEmails: false, - groupMembersOf: undefined, - excludeCurrentUser: false, - customSearchOptions: undefined, - excludedUsernames: undefined, - }, - - content: computed("value.[]", function () { + @computed("value.[]") + get content() { return makeArray(this.value).map((x) => this.defaultItem(x, x)); - }), + } - excludedUsers: computed( + @computed( "value", "currentUser", - "selectKit.options.{excludeCurrentUser,excludedUsernames}", - { - get() { - const options = this.selectKit.options; - let usernames = makeArray(this.value); + "selectKit.options.{excludeCurrentUser,excludedUsernames}" + ) + get excludedUsers() { + const options = this.selectKit.options; + let usernames = makeArray(this.value); - if (this.currentUser && options.excludeCurrentUser) { - usernames = usernames.concat([this.currentUser.username]); - } - - return usernames.concat(options.excludedUsernames || []); - }, + if (this.currentUser && options.excludeCurrentUser) { + usernames = usernames.concat([this.currentUser.username]); } - ), + + return usernames.concat(options.excludedUsernames || []); + } search(filter = "") { filter = filter || ""; @@ -105,5 +108,5 @@ export default MultiSelectComponent.extend({ return result; } }); - }, -}); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/user-chooser/user-row.js b/app/assets/javascripts/select-kit/addon/components/user-chooser/user-row.js index 87acedef68f..0e7173ab86b 100644 --- a/app/assets/javascripts/select-kit/addon/components/user-chooser/user-row.js +++ b/app/assets/javascripts/select-kit/addon/components/user-chooser/user-row.js @@ -1,5 +1,5 @@ +import { classNames } from "@ember-decorators/component"; import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row"; -export default SelectKitRowComponent.extend({ - classNames: ["user-row"], -}); +@classNames("user-row") +export default class UserRow extends SelectKitRowComponent {} diff --git a/app/assets/javascripts/select-kit/addon/components/user-notifications-dropdown.js b/app/assets/javascripts/select-kit/addon/components/user-notifications-dropdown.js index af14288d2d7..1202a5ee4f4 100644 --- a/app/assets/javascripts/select-kit/addon/components/user-notifications-dropdown.js +++ b/app/assets/javascripts/select-kit/addon/components/user-notifications-dropdown.js @@ -1,28 +1,30 @@ -import { computed } from "@ember/object"; +import { action, computed } from "@ember/object"; import { service } from "@ember/service"; +import { classNames } from "@ember-decorators/component"; import IgnoreDurationModal from "discourse/components/modal/ignore-duration-with-username"; import { popupAjaxError } from "discourse/lib/ajax-error"; import I18n from "discourse-i18n"; import DropdownSelectBox from "select-kit/components/dropdown-select-box"; +import { selectKitOptions } from "select-kit/components/select-kit"; -export default DropdownSelectBox.extend({ - modal: service(), +@classNames("user-notifications", "user-notifications-dropdown") +@selectKitOptions({ + headerIcon: "userNotificationIcon", + showCaret: true, +}) +export default class UserNotificationsDropdown extends DropdownSelectBox { + @service modal; - classNames: ["user-notifications", "user-notifications-dropdown"], - - selectKitOptions: { - headerIcon: "userNotificationIcon", - showCaret: true, - }, - - userNotificationIcon: computed("mainCollection.[]", "value", function () { + @computed("mainCollection.[]", "value") + get userNotificationIcon() { return ( this.mainCollection && this.mainCollection.find((row) => row.id === this.value).icon ); - }), + } - content: computed(function () { + @computed + get content() { const content = []; content.push({ @@ -49,14 +51,16 @@ export default DropdownSelectBox.extend({ } return content; - }), + } changeToNormal() { this.updateNotificationLevel({ level: "normal" }).catch(popupAjaxError); - }, + } + changeToMuted() { this.updateNotificationLevel({ level: "mute" }).catch(popupAjaxError); - }, + } + changeToIgnored() { this.modal.show(IgnoreDurationModal, { model: { @@ -64,15 +68,14 @@ export default DropdownSelectBox.extend({ enableSelection: false, }, }); - }, + } - actions: { - onChange(level) { - this[level](); + @action + onChange(level) { + this[level](); - // hack but model.ignored/muted is not - // getting updated after updateNotificationLevel - this.set("value", level); - }, - }, -}); + // hack but model.ignored/muted is not + // getting updated after updateNotificationLevel + this.set("value", level); + } +} diff --git a/app/assets/javascripts/select-kit/addon/components/watched-words.js b/app/assets/javascripts/select-kit/addon/components/watched-words.js index 0ae5e11d78b..39da92e0644 100644 --- a/app/assets/javascripts/select-kit/addon/components/watched-words.js +++ b/app/assets/javascripts/select-kit/addon/components/watched-words.js @@ -1,20 +1,23 @@ import { computed } from "@ember/object"; +import { classNames } from "@ember-decorators/component"; import { makeArray } from "discourse-common/lib/helpers"; import MultiSelectComponent from "select-kit/components/multi-select"; +import { + pluginApiIdentifiers, + selectKitOptions, +} from "select-kit/components/select-kit"; -export default MultiSelectComponent.extend({ - pluginApiIdentifiers: ["watched-words"], - classNames: ["watched-word-input-field"], - - selectKitOptions: { - autoInsertNoneItem: false, - fullWidthOnMobile: true, - allowAny: true, - none: "admin.watched_words.form.words_or_phrases", - }, - +@classNames("watched-word-input-field") +@selectKitOptions({ + autoInsertNoneItem: false, + fullWidthOnMobile: true, + allowAny: true, + none: "admin.watched_words.form.words_or_phrases", +}) +@pluginApiIdentifiers("watched-words") +export default class WatchedWords extends MultiSelectComponent { @computed("value.[]") get content() { return makeArray(this.value).map((x) => this.defaultItem(x, x)); - }, -}); + } +}