Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
99f039f
DEV: Refactor `EditBadgeGroupings` to use `@trackedArray` and native …
megothss Oct 29, 2025
cfebc7e
DEV: Replace `pushObject` with native `push` in `admin-flags-form`
megothss Nov 6, 2025
27a9b2e
DEV: Replace `pushObject` with `push` and migrate to `@trackedArray`
megothss Nov 6, 2025
67c32d4
DEV: Refactor `edit-category-tags` to use native methods and `@tracke…
megothss Nov 6, 2025
8e405c8
DEV: Migrate `webhook-events` to use `@trackedArray` and native `push`
megothss Nov 6, 2025
f5484c7
DEV: Replace `pushObject` with `push` and migrate to `TrackedArray`
megothss Nov 6, 2025
a28deab
DEV: Migrate `admin-user-badges` to `@trackedArray` and native methods
megothss Nov 6, 2025
22004d5
DEV: Use unique key for tracked properties in `tracked-tools`
megothss Nov 7, 2025
bd63cf9
Merge branch 'main' into dev/no-more-array-pushObject
megothss Nov 7, 2025
f24a7e3
DEV: Update `tracked-tools` to use `TrackedDescriptor` for reactivity
megothss Nov 10, 2025
89266b0
Merge branch 'main' into dev/no-more-array-pushObject
megothss Nov 12, 2025
05926fb
DEV: Replace `pushObject` with native `push` in `admin-user` model
megothss Nov 13, 2025
6a48b82
DEV: Migrate `color-scheme` to `@trackedArray` and native methods
megothss Nov 13, 2025
91a98ba
DEV: Replace `pushObject` with native `push` in `color-scheme` model
megothss Nov 13, 2025
f1d0502
DEV: Migrate `theme` model to `@trackedArray` and native array methods
megothss Nov 13, 2025
95c6df5
DEV: Replace `pushObject` with native `push` in `admin.backups.logs`
megothss Nov 13, 2025
e316888
DEV: Replace `pushObject` with native `push` in `site-setting` model
megothss Nov 13, 2025
8afc9c7
DEV: Migrate `flags` component to `@trackedArray` and native array me…
megothss Nov 13, 2025
fdf0050
DEV: Replace `objectAt` with native array indexing in `user-fields-list`
megothss Nov 13, 2025
c106d88
DEV: Migrate `uploaded-image-list` to `@trackedArray` and native methods
megothss Nov 13, 2025
e2512b3
DEV: Migrate `admin/dashboard` to `@trackedArray` and modern methods
megothss Nov 13, 2025
564e416
DEV: Migrate `edit-category` components to `@trackedArray` and modern…
megothss Nov 13, 2025
ad01e7a
DEV: Migrate `emoji-value-list` to modern Glimmer component and methods
megothss Nov 13, 2025
ec0c6e3
Merge branch 'main' into dev/no-more-array-pushObject
megothss Nov 13, 2025
a4b41d2
DEV: Migrate `webhook-event-chooser` to modern array handling methods
megothss Nov 13, 2025
97702c8
DEV: Migrate `admin-emojis` to `@trackedArray` and modern methods
megothss Nov 13, 2025
2a01e4f
DEV: Migrate `admin/backups` route to `@trackedArray` and modern methods
megothss Nov 14, 2025
799a63c
DEV: Replace `addObject` with `addUniqueValueToArray` in `setting-obj…
megothss Nov 14, 2025
3cdf4cb
DEV: Migrate `admin-permalinks` to `@trackedArray` and modern methods
megothss Nov 14, 2025
5e273e8
DEV: Refactor `admin-permalinks` template for clarity and alignment
megothss Nov 14, 2025
671e18d
DEV: Migrate `screened-ip-addresses` to `@trackedArray` and modern me…
megothss Nov 14, 2025
ec72f09
DEV: Extend array utility functions with selector support for uniqueness
megothss Nov 14, 2025
3f7d493
DEV: Migrate `secret-value-list` to Glimmer component and modern methods
megothss Nov 14, 2025
fb52cc3
DEV: Rename `removeAt` to `removeItem` in `simple-list` component
megothss Nov 14, 2025
c215036
DEV: Migrate `value-list` to `@trackedArray` and modern array methods
megothss Nov 14, 2025
e5f9549
DEV: Add `@changeValueCallback` tests to `secret-value-list` integration
megothss Nov 14, 2025
612e7cb
DEV: Remove legacy `admin-web-hooks` controllers for modernization
megothss Nov 14, 2025
8761e67
DEV: Add pagination and loading spinner to `webhooks-list` template
megothss Nov 14, 2025
f8a9f07
DEV: Migrate `admin-embedding` controller to modern Ember.js patterns
megothss Nov 14, 2025
4ef82b6
DEV: Migrate `schema-setting/editor` to `@trackedArray` and native me…
megothss Nov 14, 2025
f3e236a
DEV: Migrate invites handling to `@trackedArray` and native methods
megothss Nov 17, 2025
48709d0
DEV: Migrate `grant-badge` modal to `@trackedArray` and modern array …
megothss Nov 17, 2025
13a1c32
DEV: Migrate sidebar management to `@trackedArray` and modern methods
megothss Nov 17, 2025
94a49cd
DEV: Replace `insertAt` with `splice` in `user-menu` component
megothss Nov 17, 2025
950e9df
DEV: Refactor bookmark selection to use modern array utilities
megothss Nov 17, 2025
d30e26a
DEV: Replace `addObject` with `Set` in `composer-user-selector`
megothss Nov 17, 2025
5585c7c
DEV: Migrate `ComposerMessages` to `@trackedArray` and modern array u…
megothss Nov 17, 2025
df5008a
DEV: Migrate `user` model and `ignored-user-list` to modern array uti…
megothss Nov 17, 2025
054dd26
DEV: Migrate `TopicDetails` to `@trackedArray` and modernize array ha…
megothss Nov 17, 2025
a6949d5
DEV: Refactor `mount-widget` to modernize array handling
megothss Nov 17, 2025
2faa300
DEV: Replace `objectAt` with modern array indexing in `scrolling-post…
megothss Nov 17, 2025
08bb215
DEV: Use `@trackedArray` and modern utilities in `tag-info` component
megothss Nov 17, 2025
bbde1b7
DEV: Use modern array utilities in `track-selected` component
megothss Nov 17, 2025
c509a3a
DEV: Refactor `user-notification-schedule` to modernize array handling
megothss Nov 17, 2025
231b131
DEV: Migrate `group` model and logs management to modern array utils
megothss Nov 17, 2025
4402a36
DEV: Use `@trackedArray` and modern utilities in `GroupIndexController`
megothss Nov 17, 2025
791878a
DEV: Use `@trackedArray` for `rejectedEmails` in `InvitesController`
megothss Nov 17, 2025
f8dd942
DEV: Use `@trackedArray` and modern utilities in `user` model
megothss Nov 17, 2025
126ad22
DEV: Replace `removeObject` with `removeValueFromArray` in invites co…
megothss Nov 17, 2025
ba88281
DEV: Use `@trackedArray` and modern utilities in `topic` model
megothss Nov 17, 2025
76c0804
DEV: Replace legacy array methods in topic list component
megothss Nov 17, 2025
f3da5a0
DEV: Update `topic` controller to use modern array utilities
megothss Nov 17, 2025
438cff6
DEV: Replace `insertAt` with `splice` in user notifications array
megothss Nov 17, 2025
930ff50
DEV: Use `@trackedArray` for `links` in `SidebarSection`
megothss Nov 17, 2025
93165fa
DEV: Replace `pushObject` with native `push` in `composer-upload.js`
megothss Nov 17, 2025
c792af2
DEV: Use `@trackedArray` for `bookmarks` and replace `pushObject` in …
megothss Nov 17, 2025
85c7925
DEV: Replace `popObject` and `unshiftObject` with native methods in `…
megothss Nov 17, 2025
c8c6163
DEV: Replace `pushObject` with native `push` in `topic-bookmark-manag…
megothss Nov 17, 2025
7bcd5f1
DEV: Use `@trackedArray` and modern utilities in `Category` model
megothss Nov 17, 2025
7afc362
DEV: Use `@trackedArray` for `bookmarks` and replace `pushObject` in …
megothss Nov 17, 2025
13513b3
DEV: Replace legacy array methods in `Site` model with modern utilities
megothss Nov 17, 2025
c57db05
DEV: Use `@trackedArray` and modern utilities in `TopicDetails`
megothss Nov 17, 2025
df772ce
DEV: Use `@trackedArray` and replace legacy methods in `TopicList`
megothss Nov 17, 2025
9014f51
DEV: Use `@trackedArray` and modern utilities in `User` model
megothss Nov 17, 2025
b125f10
DEV: Replace `removeObjects` with `removeValuesFromArray` in `TopicList`
megothss Nov 17, 2025
664b8a7
DEV: Replace `removeObjects` with `removeValuesFromArray` in `Topic` …
megothss Nov 17, 2025
c45c266
DEV: Replace `removeObject` with `removeValueFromArray` in `UserStrea…
megothss Nov 17, 2025
f91d6f3
DEV: Replace `removeObjects` with `removeValuesFromArray` in `categor…
megothss Nov 17, 2025
75cbfc3
DEV: Replace `pushObject` with `push` in `composer` service
megothss Nov 17, 2025
e4859d1
DEV: Replace `addObject` with `addUniqueValueToArray` in test helper
megothss Nov 17, 2025
46c09fa
DEV: Replace `pushObject` and `removeObject` with modern utilities in…
megothss Nov 17, 2025
ba87314
DEV: Replace legacy array methods with modern utilities in tests
megothss Nov 17, 2025
37c8e63
DEV: Enable logging deprecations for all Ember array deprecated methods
megothss Nov 17, 2025
1f5497b
DEV: Allow `@trackedArray` to support `undefined` as a valid value
megothss Nov 18, 2025
2a9b2f8
DEV: Replace `store.createRecord` with `Topic.create` in `Topic` model
megothss Nov 18, 2025
31b88dc
DEV: Update `mount-widget` to use `.content` for child components
megothss Nov 18, 2025
0985683
DEV: Replace legacy decorators with native getters and tracked objects
megothss Nov 18, 2025
94d82ff
DEV: Replace alias with native getter for `selectedPostsCount`
megothss Nov 18, 2025
f5c1c4d
DEV: Replace `@discourseComputed` with native getter in `topic` contr…
megothss Nov 18, 2025
4b4efb2
DEV: Refactor `Site` model to use modern getters and `@trackedArray`
megothss Nov 18, 2025
8d7c5f2
DEV: Use modern arrow function syntax in `user-notification-schedule`
megothss Nov 18, 2025
99c0b8f
DEV: Replace `@discourseComputed` with native getters in controllers
megothss Nov 19, 2025
d1c222e
DEV: Replace `TrackedArray` with `@trackedArray` in `sidebar-section-…
megothss Nov 19, 2025
8d65ac7
Merge branch 'main' into dev/no-more-array-ember-methods
megothss Nov 19, 2025
9d2938f
Apply suggestion from code review
megothss Nov 26, 2025
0fa6976
Merge branch 'main' into dev/no-more-array-ember-methods
megothss Nov 26, 2025
8947485
Apply changes for benchmark PR
ofir-frd Dec 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/locales/client.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8411,6 +8411,7 @@ en:
experimental: "Experimental"
secret_list:
invalid_input: "Input fields cannot be empty or contain vertical bar character."
already_exists: "Entry for %{key} already exists."
default_categories:
modal_description:
one: "Would you like to apply this change historically? This will change preferences for %{count} existing user."
Expand Down
35 changes: 20 additions & 15 deletions frontend/discourse/admin/components/admin-config-areas/flags.gjs
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { action } from "@ember/object";
import { service } from "@ember/service";
import AdminFlagItem from "discourse/admin/components/admin-flag-item";
import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
import { removeValueFromArray } from "discourse/lib/array-tools";
import { bind } from "discourse/lib/decorators";
import { trackedArray } from "discourse/lib/tracked-tools";
import { i18n } from "discourse-i18n";

export default class AdminConfigAreasFlags extends Component {
@service site;

@tracked flags = this.site.flagTypes;
@trackedArray flags = this.site.flagTypes;

@bind
isFirstFlag(flag) {
Expand All @@ -24,7 +25,7 @@ export default class AdminConfigAreasFlags extends Component {
}

@action
moveFlagCallback(flag, direction) {
async moveFlagCallback(flag, direction) {
const fallbackFlags = [...this.flags];

const flags = this.flags;
Expand All @@ -39,23 +40,27 @@ export default class AdminConfigAreasFlags extends Component {

this.flags = flags;

return ajax(`/admin/config/flags/${flag.id}/reorder/${direction}`, {
type: "PUT",
}).catch((error) => {
try {
await ajax(`/admin/config/flags/${flag.id}/reorder/${direction}`, {
type: "PUT",
});
} catch (error) {
this.flags = fallbackFlags;
return popupAjaxError(error);
});
}
}

@action
deleteFlagCallback(flag) {
return ajax(`/admin/config/flags/${flag.id}`, {
type: "DELETE",
})
.then(() => {
this.flags.removeObject(flag);
})
.catch((error) => popupAjaxError(error));
async deleteFlagCallback(flag) {
try {
await ajax(`/admin/config/flags/${flag.id}`, {
type: "DELETE",
});

removeValueFromArray(this.flags, flag);
} catch (error) {
popupAjaxError(error);
}
}

<template>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default class AdminConfigAreasUserFieldsList extends Component {
moveUp(field) {
const idx = this.sortedFields.indexOf(field);
if (idx) {
const prev = this.sortedFields.objectAt(idx - 1);
const prev = this.sortedFields[idx - 1];
const prevPos = prev.get("position");

prev.update({ position: field.get("position") });
Expand All @@ -40,7 +40,7 @@ export default class AdminConfigAreasUserFieldsList extends Component {
moveDown(field) {
const idx = this.sortedFields.indexOf(field);
if (idx > -1) {
const next = this.sortedFields.objectAt(idx + 1);
const next = this.sortedFields[idx + 1];
const nextPos = next.get("position");

next.update({ position: field.get("position") });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import GroupSelector from "discourse/components/group-selector";
import PluginOutlet from "discourse/components/plugin-outlet";
import lazyHash from "discourse/helpers/lazy-hash";
import { popupAjaxError } from "discourse/lib/ajax-error";
import { trackedArray } from "discourse/lib/tracked-tools";
import CategorySelector from "discourse/select-kit/components/category-selector";
import TagChooser from "discourse/select-kit/components/tag-chooser";
import { eq } from "discourse/truth-helpers";
Expand All @@ -25,11 +26,11 @@ export default class AdminConfigAreasWebhookForm extends Component {

@tracked loadingExtras = true;

@tracked webhookEventTypes = [];
@tracked defaultEventTypes = {};
@tracked groupedEventTypes = {};
@tracked contentTypes = [];
@tracked deliveryStatuses = [];
@trackedArray webhookEventTypes = [];

constructor() {
super(...arguments);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { action } from "@ember/object";
import { service } from "@ember/service";
import AdminConfigAreaEmptyList from "discourse/admin/components/admin-config-area-empty-list";
import WebhookItem from "discourse/admin/components/webhook-item";
import ConditionalLoadingSpinner from "discourse/components/conditional-loading-spinner";
import LoadMore from "discourse/components/load-more";
import { popupAjaxError } from "discourse/lib/ajax-error";
import { removeValueFromArray } from "discourse/lib/array-tools";
import { i18n } from "discourse-i18n";
Expand Down Expand Up @@ -31,33 +33,44 @@ export default class AdminConfigAreasWebhooksList extends Component {
<template>
<div class="container admin-api_keys">
{{#if this.webhooks.content}}
<table class="d-table admin-web_hooks__items">
<thead class="d-table__header">
<tr class="d-table__row">
<th class="d-table__header-cell">{{i18n
"admin.web_hooks.delivery_status.title"
}}</th>
<th class="d-table__header-cell">{{i18n
"admin.web_hooks.payload_url"
}}</th>
<th class="d-table__header-cell">{{i18n
"admin.web_hooks.description_label"
}}</th>
<th class="d-table__header-cell">{{i18n
"admin.web_hooks.controls"
}}</th>
</tr>
</thead>
<tbody class="d-table__body">
{{#each this.webhooks.content as |webhook|}}
<WebhookItem
@webhook={{webhook}}
@deliveryStatuses={{this.webhooks.extras.delivery_statuses}}
@destroy={{this.destroyWebhook}}
/>
{{/each}}
</tbody>
</table>
<LoadMore @action={{this.webhooks.loadMore}}>
<table class="d-table admin-web_hooks__items">
<thead class="d-table__header">
<tr class="d-table__row">
<th class="d-table__header-cell">{{i18n
"admin.web_hooks.delivery_status.title"
}}</th>
<th class="d-table__header-cell">{{i18n
"admin.web_hooks.payload_url"
}}</th>
<th class="d-table__header-cell">{{i18n
"admin.web_hooks.description_label"
}}</th>
<th class="d-table__header-cell">{{i18n
"admin.web_hooks.controls"
}}</th>
</tr>
</thead>
<tbody class="d-table__body">
{{#each this.webhooks.content as |webhook|}}
<WebhookItem
@webhook={{webhook}}
@deliveryStatuses={{this.webhooks.extras.delivery_statuses}}
@destroy={{this.destroyWebhook}}
/>
{{/each}}
{{#if this.webhooks.loadingMore}}
<tr class="d-table__row">
<td class="d-table__cell" colspan="4">
<ConditionalLoadingSpinner
@condition={{this.webhooks.loadingMore}}
/>
</td>
</tr>
{{/if}}
</tbody>
</table>
</LoadMore>
{{else}}
<AdminConfigAreaEmptyList
@ctaLabel="admin.web_hooks.add"
Expand Down
2 changes: 1 addition & 1 deletion frontend/discourse/admin/components/admin-flags-form.gjs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export default class AdminFlagsForm extends Component {
type: "POST",
data,
});
this.site.flagTypes.pushObject(response.flag);
this.site.flagTypes.push(response.flag);
this.router.transitionTo("adminConfig.flags");
} catch (error) {
popupAjaxError(error);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export default class AdminUserFieldsForm extends Component {
this.originalRequirement = data.requirement;

if (isNew) {
this.adminUserFields.userFields.pushObject(this.args.userField);
this.adminUserFields.userFields.push(this.args.userField);
}

this.router.transitionTo("adminUserFields.index");
Expand Down
7 changes: 5 additions & 2 deletions frontend/discourse/admin/components/dashboard-problems.gjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import concatClass from "discourse/helpers/concat-class";
import icon from "discourse/helpers/d-icon";
import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
import { removeValueFromArray } from "discourse/lib/array-tools";
import { eq } from "discourse/truth-helpers";
import { i18n } from "discourse-i18n";

Expand All @@ -17,14 +18,16 @@ export default class DashboardProblems extends Component {
async dismissProblem(problem) {
try {
await ajax(`/admin/admin_notices/${problem.id}`, { type: "DELETE" });
this.args.problems.removeObject(problem);
removeValueFromArray(this.args.problems, problem);
} catch (error) {
popupAjaxError(error);
}
}

get problems() {
return this.args.problems.sort((a, b) => compare(a?.priority, b?.priority));
return this.args.problems.toSorted((a, b) =>
compare(a?.priority, b?.priority)
);
}

<template>
Expand Down
16 changes: 6 additions & 10 deletions frontend/discourse/admin/components/edit-category-security.gjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { buildCategoryPanel } from "discourse/admin/components/edit-category-pan
import CategoryPermissionRow from "discourse/components/category-permission-row";
import PluginOutlet from "discourse/components/plugin-outlet";
import lazyHash from "discourse/helpers/lazy-hash";
import discourseComputed from "discourse/lib/decorators";
import PermissionType from "discourse/models/permission-type";
import ComboBox from "discourse/select-kit/components/combo-box";
import { i18n } from "discourse-i18n";
Expand All @@ -17,23 +16,20 @@ export default class EditCategorySecurity extends buildCategoryPanel(

@not("selectedGroup") noGroupSelected;

@discourseComputed("[email protected]_type")
everyonePermission(permissions) {
return permissions.find((p) => p.group_name === "everyone");
get everyonePermission() {
return this.category.permissions.find((p) => p.group_name === "everyone");
}

@discourseComputed("[email protected]_type")
everyoneGrantedFull() {
get everyoneGrantedFull() {
return (
this.everyonePermission &&
this.everyonePermission.permission_type === PermissionType.FULL
);
}

@discourseComputed("everyonePermission")
minimumPermission(everyonePermission) {
return everyonePermission
? everyonePermission.permission_type
get minimumPermission() {
return this.everyonePermission
? this.everyonePermission.permission_type
: PermissionType.READONLY;
}

Expand Down
3 changes: 2 additions & 1 deletion frontend/discourse/admin/components/edit-category-tab.gjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { empty } from "@ember/object/computed";
import { scheduleOnce } from "@ember/runloop";
import { underscore } from "@ember/string";
import { classNameBindings, tagName } from "@ember-decorators/component";
import { addUniqueValueToArray } from "discourse/lib/array-tools";
import { propertyEqual } from "discourse/lib/computed";
import discourseComputed from "discourse/lib/decorators";
import getURL from "discourse/lib/get-url";
Expand Down Expand Up @@ -43,7 +44,7 @@ export default class EditCategoryTab extends Component {
}

_addToCollection() {
this.panels.addObject(this.tabClassName);
addUniqueValueToArray(this.panels, this.tabClassName);
}

@discourseComputed("params.slug", "params.parentSlug")
Expand Down
5 changes: 3 additions & 2 deletions frontend/discourse/admin/components/edit-category-tags.gjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { LinkTo } from "@ember/routing";
import { buildCategoryPanel } from "discourse/admin/components/edit-category-panel";
import DButton from "discourse/components/d-button";
import TextField from "discourse/components/text-field";
import { removeValueFromArray } from "discourse/lib/array-tools";
import TagChooser from "discourse/select-kit/components/tag-chooser";
import TagGroupChooser from "discourse/select-kit/components/tag-group-chooser";
import { i18n } from "discourse-i18n";
Expand All @@ -25,14 +26,14 @@ export default class EditCategoryTags extends buildCategoryPanel("tags") {

@action
addRequiredTagGroup() {
this.category.required_tag_groups.pushObject({
this.category.required_tag_groups.push({
min_count: 1,
});
}

@action
deleteRequiredTagGroup(rtg) {
this.category.required_tag_groups.removeObject(rtg);
removeValueFromArray(this.category.required_tag_groups, rtg);
}

<template>
Expand Down
Loading
Loading