mirror of
https://github.com/discourse/discourse.git
synced 2026-08-05 18:57:20 -05:00
DEV: Replace deprecated Ember's array sortBy with sort (#34998)
This Pull Request introduces changes that replace the use of .sortBy with .sort combined with compare from @ember/utils. This update aims to modernize and standardize sorting operations throughout the codebase. **Main Changes:** * Replaced .sortBy with .sort and compare in various components, controllers, and services to improve sorting practices. * Updated sorting logic to handle optional chaining (?.) for increased robustness. * Adjusted sorting logic, including reversing, in some cases for more clarity and correctness. * Added a new deprecation workflow entry to handle sortBy deprecation logs (discourse.native-array-extensions.sortBy).
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import Component from "@glimmer/component";
|
||||
import { concat } from "@ember/helper";
|
||||
import { action } from "@ember/object";
|
||||
import { compare } from "@ember/utils";
|
||||
import { eq } from "truth-helpers";
|
||||
import ConditionalLoadingSection from "discourse/components/conditional-loading-section";
|
||||
import DButton from "discourse/components/d-button";
|
||||
@@ -23,7 +24,7 @@ export default class DashboardProblems extends Component {
|
||||
}
|
||||
|
||||
get problems() {
|
||||
return this.args.problems.sortBy("priority");
|
||||
return this.args.problems.sort((a, b) => compare(a?.priority, b?.priority));
|
||||
}
|
||||
|
||||
<template>
|
||||
|
||||
@@ -3,6 +3,7 @@ import { action } from "@ember/object";
|
||||
import { alias, empty, sort } from "@ember/object/computed";
|
||||
import { next } from "@ember/runloop";
|
||||
import { service } from "@ember/service";
|
||||
import { compare } from "@ember/utils";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
import discourseComputed from "discourse/lib/decorators";
|
||||
import { grantableBadges } from "discourse/lib/grant-badge-utils";
|
||||
@@ -70,7 +71,7 @@ export default class AdminUserBadgesController extends Controller {
|
||||
}
|
||||
});
|
||||
|
||||
return expanded.sortBy("granted_at").reverse();
|
||||
return expanded.sort((a, b) => compare(b?.granted_at, a?.granted_at)); // sort descending
|
||||
}
|
||||
|
||||
@action
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import Component from "@ember/component";
|
||||
import { concat } from "@ember/helper";
|
||||
import { computed } from "@ember/object";
|
||||
import { compare } from "@ember/utils";
|
||||
import { attributeBindings } from "@ember-decorators/component";
|
||||
import DButton from "discourse/components/d-button";
|
||||
import concatClass from "discourse/helpers/concat-class";
|
||||
@@ -17,10 +18,14 @@ export default class AnonymousTopicFooterButtons extends Component {
|
||||
|
||||
@computed("allButtons.[]")
|
||||
get buttons() {
|
||||
return this.allButtons
|
||||
.filterBy("anonymousOnly", true)
|
||||
.sortBy("priority")
|
||||
.reverse();
|
||||
return (
|
||||
this.allButtons
|
||||
.filterBy("anonymousOnly", true)
|
||||
.sort((a, b) => compare(a?.priority, b?.priority))
|
||||
// Reversing the array is necessary because when priorities are not set,
|
||||
// we want to show the most recently added item first
|
||||
.reverse()
|
||||
);
|
||||
}
|
||||
|
||||
<template>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import Component from "@ember/component";
|
||||
import { hash } from "@ember/helper";
|
||||
import { filter } from "@ember/object/computed";
|
||||
import { compare } from "@ember/utils";
|
||||
import { classNameBindings, tagName } from "@ember-decorators/component";
|
||||
// A breadcrumb including category drop downs
|
||||
import PluginOutlet from "discourse/components/plugin-outlet";
|
||||
@@ -87,7 +88,9 @@ export default class BreadCrumbs extends Component {
|
||||
return parentCategories;
|
||||
}
|
||||
|
||||
return parentCategories.sortBy("totalTopicCount").reverse();
|
||||
return parentCategories.sort(
|
||||
(a, b) => compare(b?.totalTopicCount, a?.totalTopicCount) // sort descending
|
||||
);
|
||||
}
|
||||
|
||||
@discourseComputed("category")
|
||||
|
||||
@@ -4,6 +4,7 @@ import { concat, fn } from "@ember/helper";
|
||||
import { on } from "@ember/modifier";
|
||||
import { action } from "@ember/object";
|
||||
import { service } from "@ember/service";
|
||||
import { compare } from "@ember/utils";
|
||||
import { eq, not } from "truth-helpers";
|
||||
import DButton from "discourse/components/d-button";
|
||||
import DModal from "discourse/components/d-modal";
|
||||
@@ -32,7 +33,7 @@ export default class ReorderCategories extends Component {
|
||||
@tracked highlightedCategoryId = null;
|
||||
|
||||
get sortedEntries() {
|
||||
return this.entries.sortBy("position");
|
||||
return this.entries.sort((a, b) => compare(a?.position, b?.position));
|
||||
}
|
||||
|
||||
reorder(from) {
|
||||
@@ -41,7 +42,9 @@ export default class ReorderCategories extends Component {
|
||||
position: category.position,
|
||||
}));
|
||||
|
||||
return this.createEntries([...from.sortBy("position")]);
|
||||
return this.createEntries([
|
||||
...from.sort((a, b) => compare(a?.position, b?.position)),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,6 +4,7 @@ import { concat, hash } from "@ember/helper";
|
||||
import { computed } from "@ember/object";
|
||||
import { alias, or } from "@ember/object/computed";
|
||||
import { getOwner } from "@ember/owner";
|
||||
import { compare } from "@ember/utils";
|
||||
import { attributeBindings } from "@ember-decorators/component";
|
||||
import { eq, gt } from "truth-helpers";
|
||||
import BookmarkMenu from "discourse/components/bookmark-menu";
|
||||
@@ -50,12 +51,16 @@ export default class TopicFooterButtons extends Component {
|
||||
|
||||
@computed("inlineButtons.[]", "inlineDropdowns.[]")
|
||||
get inlineActionables() {
|
||||
return this.inlineButtons
|
||||
.filterBy("dropdown", false)
|
||||
.filterBy("anonymousOnly", false)
|
||||
.concat(this.inlineDropdowns)
|
||||
.sortBy("priority")
|
||||
.reverse();
|
||||
return (
|
||||
this.inlineButtons
|
||||
.filterBy("dropdown", false)
|
||||
.filterBy("anonymousOnly", false)
|
||||
.concat(this.inlineDropdowns)
|
||||
.sort((a, b) => compare(a?.priority, b?.priority))
|
||||
// Reversing the array is necessary because when priorities are not set,
|
||||
// we want to show the most recently added item first
|
||||
.reverse()
|
||||
);
|
||||
}
|
||||
|
||||
@computed("topic")
|
||||
|
||||
@@ -5,7 +5,7 @@ import { alias, and, gt, gte, not, or } from "@ember/object/computed";
|
||||
import { LinkTo } from "@ember/routing";
|
||||
import { dasherize } from "@ember/string";
|
||||
import { htmlSafe } from "@ember/template";
|
||||
import { isEmpty } from "@ember/utils";
|
||||
import { compare, isEmpty } from "@ember/utils";
|
||||
import {
|
||||
attributeBindings,
|
||||
classNameBindings,
|
||||
@@ -160,7 +160,7 @@ export default class UserCardContents extends CardContentsBase {
|
||||
const userFields = this.get("user.user_fields");
|
||||
return siteUserFields
|
||||
.filterBy("show_on_user_card", true)
|
||||
.sortBy("position")
|
||||
.sort((a, b) => compare(a?.position, b?.position))
|
||||
.map((field) => {
|
||||
set(field, "dasherized_name", dasherize(field.get("name")));
|
||||
const value = userFields ? userFields[field.get("id")] : null;
|
||||
|
||||
@@ -2,7 +2,7 @@ import Controller from "@ember/controller";
|
||||
import EmberObject, { action } from "@ember/object";
|
||||
import { readOnly } from "@ember/object/computed";
|
||||
import { service } from "@ember/service";
|
||||
import { isEmpty } from "@ember/utils";
|
||||
import { compare, isEmpty } from "@ember/utils";
|
||||
import FeatureTopicOnProfileModal from "discourse/components/modal/feature-topic-on-profile";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
@@ -60,10 +60,12 @@ export default class ProfileController extends Controller {
|
||||
siteUserFields = siteUserFields.filterBy("editable", true);
|
||||
}
|
||||
|
||||
return siteUserFields.sortBy("position").map((field) => {
|
||||
const value = this.model.user_fields?.[field.id.toString()];
|
||||
return EmberObject.create({ field, value });
|
||||
});
|
||||
return siteUserFields
|
||||
.sort((a, b) => compare(a?.position, b?.position))
|
||||
.map((field) => {
|
||||
const value = this.model.user_fields?.[field.id.toString()];
|
||||
return EmberObject.create({ field, value });
|
||||
});
|
||||
}
|
||||
|
||||
@discourseComputed("currentUser.needs_required_fields_check")
|
||||
|
||||
@@ -3,7 +3,7 @@ import EmberObject, { action, computed, set } from "@ember/object";
|
||||
import { and, equal, gt, not, or, readOnly } from "@ember/object/computed";
|
||||
import { service } from "@ember/service";
|
||||
import { dasherize } from "@ember/string";
|
||||
import { isEmpty } from "@ember/utils";
|
||||
import { compare, isEmpty } from "@ember/utils";
|
||||
import CanCheckEmailsHelper from "discourse/lib/can-check-emails-helper";
|
||||
import { setting } from "discourse/lib/computed";
|
||||
import discourseComputed from "discourse/lib/decorators";
|
||||
@@ -161,7 +161,7 @@ export default class UserController extends Controller {
|
||||
const userFields = this.get("model.user_fields");
|
||||
return siteUserFields
|
||||
.filterBy("show_on_profile", true)
|
||||
.sortBy("position")
|
||||
.sort((a, b) => compare(a?.position, b?.position))
|
||||
.map((field) => {
|
||||
set(field, "dasherized_name", dasherize(field.get("name")));
|
||||
const value = userFields
|
||||
|
||||
@@ -273,6 +273,10 @@ const DeprecationWorkflow = new DiscourseDeprecationWorkflow([
|
||||
handler: "log",
|
||||
matchId: "discourse.native-array-extensions.rejectBy",
|
||||
},
|
||||
{
|
||||
handler: "log",
|
||||
matchId: "discourse.native-array-extensions.sortBy",
|
||||
},
|
||||
{
|
||||
handler: "log",
|
||||
matchId: "discourse.native-array-extensions.without",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { tracked } from "@glimmer/tracking";
|
||||
import { isEmpty } from "@ember/utils";
|
||||
import { compare, isEmpty } from "@ember/utils";
|
||||
import { TrackedArray } from "@ember-compat/tracked-built-ins";
|
||||
import { i18n } from "discourse-i18n";
|
||||
|
||||
@@ -95,13 +95,15 @@ export default class UserFieldsValidationHelper {
|
||||
if (userFields) {
|
||||
const getValidationVisible = () => this.validationVisible;
|
||||
this.userFields = new TrackedArray(
|
||||
userFields.sortBy("position").map((f) => {
|
||||
return new TrackedUserField({
|
||||
field: f,
|
||||
getValidationVisible,
|
||||
getAccountPassword: this.getAccountPassword,
|
||||
});
|
||||
})
|
||||
userFields
|
||||
.sort((a, b) => compare(a?.position, b?.position))
|
||||
.map((f) => {
|
||||
return new TrackedUserField({
|
||||
field: f,
|
||||
getValidationVisible,
|
||||
getAccountPassword: this.getAccountPassword,
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { tracked } from "@glimmer/tracking";
|
||||
import { warn } from "@ember/debug";
|
||||
import { computed, get } from "@ember/object";
|
||||
import { service } from "@ember/service";
|
||||
import { compare } from "@ember/utils";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import discourseComputed from "discourse/lib/decorators";
|
||||
import { getOwnerWithFallback } from "discourse/lib/get-owner";
|
||||
@@ -398,7 +399,7 @@ export default class Category extends RestModel {
|
||||
}
|
||||
}
|
||||
|
||||
return data.sortBy("read_restricted");
|
||||
return data.sort((a, b) => compare(a?.read_restricted, b?.read_restricted));
|
||||
}
|
||||
|
||||
static async asyncHierarchicalSearch(term, opts) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import Service, { service } from "@ember/service";
|
||||
import { compare } from "@ember/utils";
|
||||
import { TrackedSet } from "@ember-compat/tracked-built-ins";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import { isTesting } from "discourse/lib/environment";
|
||||
@@ -24,7 +25,9 @@ export default class UserTips extends Service {
|
||||
}
|
||||
|
||||
const newId = tipsArray
|
||||
.sortBy("priority")
|
||||
.sort((a, b) => compare(a?.priority, b?.priority))
|
||||
// Reversing the array is necessary because when priorities are not set,
|
||||
// we want to show the most recently added tip first
|
||||
.reverse()
|
||||
.find((tip) => this.canSeeUserTip(tip.id))?.id;
|
||||
|
||||
|
||||
+6
-1
@@ -4,6 +4,7 @@ import { fn } from "@ember/helper";
|
||||
import { action } from "@ember/object";
|
||||
import { LinkTo } from "@ember/routing";
|
||||
import { service } from "@ember/service";
|
||||
import { compare } from "@ember/utils";
|
||||
import DButton from "discourse/components/d-button";
|
||||
import replaceEmoji from "discourse/helpers/replace-emoji";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
@@ -17,7 +18,11 @@ export default class AdminChatIncomingWebhooksList extends Component {
|
||||
@tracked loading = false;
|
||||
|
||||
get sortedWebhooks() {
|
||||
return this.args.webhooks?.sortBy("updated_at").reverse() || [];
|
||||
return (
|
||||
this.args.webhooks?.sort(
|
||||
(a, b) => compare(b?.updated_at, a?.updated_at) // sort descending
|
||||
) || []
|
||||
);
|
||||
}
|
||||
|
||||
@action
|
||||
|
||||
+2
-1
@@ -4,6 +4,7 @@ import { fn } from "@ember/helper";
|
||||
import { on } from "@ember/modifier";
|
||||
import { action } from "@ember/object";
|
||||
import { service } from "@ember/service";
|
||||
import { compare } from "@ember/utils";
|
||||
import { eq } from "truth-helpers";
|
||||
import { i18n } from "discourse-i18n";
|
||||
import roundTime from "../../lib/round-time";
|
||||
@@ -53,7 +54,7 @@ export default class GroupTimezones extends Component {
|
||||
});
|
||||
|
||||
groupedTimezones = groupedTimezones
|
||||
.sortBy("offset")
|
||||
.sort((a, b) => compare(a?.offset, b?.offset))
|
||||
.filter((g) => g.members.length);
|
||||
|
||||
let newDayIndex;
|
||||
|
||||
+4
-1
@@ -1,6 +1,7 @@
|
||||
import Controller from "@ember/controller";
|
||||
import { action } from "@ember/object";
|
||||
import { service } from "@ember/service";
|
||||
import { compare } from "@ember/utils";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
import discourseComputed from "discourse/lib/decorators";
|
||||
@@ -16,7 +17,9 @@ export default class AdminPluginsShowDiscourseGamificationLeaderboardsIndexContr
|
||||
|
||||
@discourseComputed("model.leaderboards.@each.updatedAt")
|
||||
sortedLeaderboards(leaderboards) {
|
||||
return leaderboards?.sortBy("updatedAt").reverse() || [];
|
||||
return (
|
||||
leaderboards?.sort((a, b) => compare(b?.updatedAt, a?.updatedAt)) || []
|
||||
);
|
||||
}
|
||||
|
||||
@action
|
||||
|
||||
Reference in New Issue
Block a user