From 56a6b532f58aee4ddd5575d627ec0a60c12cf593 Mon Sep 17 00:00:00 2001 From: Stefan Topfstedt Date: Mon, 10 Aug 2026 08:10:38 -0700 Subject: [PATCH] replaces calls to RSVP.map() with native equivalents. --- .../app/components/learner-group/calendar.gjs | 61 +++++------ .../components/learner-group/list-item.gjs | 4 +- .../app/components/learner-group/root.gjs | 41 +++---- .../components/learner-group/upload-data.gjs | 8 +- .../app/components/learner-groups/root.gjs | 57 +++++----- .../components/program-year/competencies.gjs | 4 +- .../objective-list-item-expanded.gjs | 21 ++-- .../program-year/objective-list.gjs | 25 ++--- .../components/school/competencies-list.gjs | 17 +-- ...ualize-session-type-vocabularies-graph.gjs | 22 ++-- ...isualize-session-type-vocabulary-graph.gjs | 58 +++++----- .../visualizer-program-year-objectives.gjs | 68 +++++++----- .../frontend/app/utils/clone-learner-group.js | 18 ++-- packages/frontend/app/utils/sort-cohorts.js | 25 ++--- .../components/course/objective-list.gjs | 101 +++++++++--------- ...isualize-instructor-session-type-graph.gjs | 36 ++++--- .../visualize-instructor-term-graph.gjs | 54 +++++----- .../course/visualize-instructor.gjs | 24 +++-- .../course/visualize-instructors-graph.gjs | 29 ++--- .../course/visualize-objectives-graph.gjs | 101 ++++++++++-------- .../course/visualize-session-type-graph.gjs | 41 +++---- .../course/visualize-session-types-graph.gjs | 23 ++-- .../course/visualize-term-graph.gjs | 21 ++-- .../course/visualize-vocabularies-graph.gjs | 24 ++--- .../course/visualize-vocabulary-graph.gjs | 25 ++--- .../addon/components/dashboard/calendar.gjs | 49 +++++---- .../addon/components/detail-cohort-list.gjs | 35 +++--- .../components/detail-cohort-manager.gjs | 18 ++-- .../addon/components/detail-cohorts.gjs | 27 ++--- .../components/detail-learnergroups-list.gjs | 54 +++++----- .../addon/components/offering-calendar.gjs | 89 +++++++-------- .../addon/components/offering-form.gjs | 49 +++++---- ...session-offerings-time-block-offerings.gjs | 17 +-- ...sessions-grid-offering-table-offerings.gjs | 17 +-- .../addon/components/sessions-grid.gjs | 60 ++++++----- packages/ilios-common/addon/models/course.js | 41 +++---- .../addon/models/learner-group.js | 37 ++++--- .../routes/course-visualize-instructor.js | 4 +- .../routes/course-visualize-instructors.js | 7 +- .../routes/course-visualize-objectives.js | 3 +- .../routes/course-visualize-session-type.js | 7 +- .../routes/course-visualize-session-types.js | 3 +- .../addon/routes/course-visualize-term.js | 5 +- .../routes/course-visualize-vocabularies.js | 3 +- .../routes/course-visualize-vocabulary.js | 7 +- 45 files changed, 764 insertions(+), 676 deletions(-) diff --git a/packages/frontend/app/components/learner-group/calendar.gjs b/packages/frontend/app/components/learner-group/calendar.gjs index bc0a708abe..dca235d5ad 100644 --- a/packages/frontend/app/components/learner-group/calendar.gjs +++ b/packages/frontend/app/components/learner-group/calendar.gjs @@ -3,7 +3,6 @@ import { cached, tracked } from '@glimmer/tracking'; import { action } from '@ember/object'; import { service } from '@ember/service'; import { DateTime } from 'luxon'; -import { map } from 'rsvp'; import { mapBy } from 'ilios-common/utils/array-helpers'; import { TrackedAsyncData } from 'ember-async-data'; import ToggleYesno from 'ilios-common/components/toggle-yesno'; @@ -68,36 +67,38 @@ export default class LearnerGroupCalendarComponent extends Component { const flat = offerings.reduce((flattened, obj) => { return [...flattened, ...obj]; }, []); - return await map(flat, async (offering) => { - const session = await offering.session; - const sessionType = await session.sessionType; - const course = await session.course; - const school = await course.school; - const instructors = await offering.getAllInstructors(); - const instructorNames = instructors.map((instructor) => instructor.fullName); + return await Promise.all( + flat.map(async (offering) => { + const session = await offering.session; + const sessionType = await session.sessionType; + const course = await session.course; + const school = await course.school; + const instructors = await offering.getAllInstructors(); + const instructorNames = instructors.map((instructor) => instructor.fullName); - return new Event( - { - startDate: offering.startDate.toISOString(), - endDate: offering.endDate.toISOString(), - lastModified: offering.updatedAt.toISOString(), - courseTitle: course.title, - name: session.title, - offering: offering.id, - location: offering.room, - school: school.id, - color: sessionType.calendarColor, - prerequisites: [], - postrequisites: [], - isScheduled: session.isScheduled || course.isScheduled, - isPublished: session.isPublished && course.isPublished, - sessionTypeTitle: sessionType.title, - instructors: instructorNames, - }, - false, - showAsBlockedTime, - ); - }); + return new Event( + { + startDate: offering.startDate.toISOString(), + endDate: offering.endDate.toISOString(), + lastModified: offering.updatedAt.toISOString(), + courseTitle: course.title, + name: session.title, + offering: offering.id, + location: offering.room, + school: school.id, + color: sessionType.calendarColor, + prerequisites: [], + postrequisites: [], + isScheduled: session.isScheduled || course.isScheduled, + isPublished: session.isPublished && course.isPublished, + sessionTypeTitle: sessionType.title, + instructors: instructorNames, + }, + false, + showAsBlockedTime, + ); + }), + ); } @action diff --git a/packages/frontend/app/components/learner-group/list-item.gjs b/packages/frontend/app/components/learner-group/list-item.gjs index ac5b576a43..41074c437c 100644 --- a/packages/frontend/app/components/learner-group/list-item.gjs +++ b/packages/frontend/app/components/learner-group/list-item.gjs @@ -2,7 +2,7 @@ import Component from '@glimmer/component'; import { cached, tracked } from '@glimmer/tracking'; import { action } from '@ember/object'; import { task } from 'ember-concurrency'; -import { filter, map } from 'rsvp'; +import { filter } from 'rsvp'; import { TrackedAsyncData } from 'ember-async-data'; import { service } from '@ember/service'; import { LinkTo } from '@ember/routing'; @@ -107,7 +107,7 @@ export default class LearnerGroupListItemComponent extends Component { } async getSortedTitlesOfSubgroupsInNeedOfAccommodation(groups) { - const titles = await map(groups, (group) => group.getTitleWithParentTitles()); + const titles = await Promise.all(groups.map((group) => group.getTitleWithParentTitles())); return titles.sort().join(', '); } diff --git a/packages/frontend/app/components/learner-group/root.gjs b/packages/frontend/app/components/learner-group/root.gjs index bb50263290..2eea80fce8 100644 --- a/packages/frontend/app/components/learner-group/root.gjs +++ b/packages/frontend/app/components/learner-group/root.gjs @@ -3,7 +3,6 @@ import { cached, tracked } from '@glimmer/tracking'; import { action } from '@ember/object'; import ObjectProxy from '@ember/object/proxy'; import { service } from '@ember/service'; -import { map } from 'rsvp'; import { task } from 'ember-concurrency'; import pad from 'pad'; import { TrackedAsyncData } from 'ember-async-data'; @@ -322,15 +321,17 @@ export default class LearnerGroupRootComponent extends Component { const allDescendants = await topLevelGroup.getAllDescendants(); const treeGroups = [topLevelGroup, ...allDescendants]; const users = await learnerGroup.getUsersOnlyAtThisLevel(); - return await map(users, async (user) => { - const lowestGroupInTree = await user.getLowestMemberGroupInALearnerGroupTree(treeGroups); - return ObjectProxy.create({ - content: user, - lowestGroupInTree, - //special sorting property - lowestGroupInTreeTitle: lowestGroupInTree.title, - }); - }); + return await Promise.all( + users.map(async (user) => { + const lowestGroupInTree = await user.getLowestMemberGroupInALearnerGroupTree(treeGroups); + return ObjectProxy.create({ + content: user, + lowestGroupInTree, + //special sorting property + lowestGroupInTreeTitle: lowestGroupInTree.title, + }); + }), + ); } @cached @@ -353,15 +354,17 @@ export default class LearnerGroupRootComponent extends Component { const allDescendants = await topLevelGroup.getAllDescendants(); const treeGroups = [topLevelGroup, ...allDescendants]; const users = await topLevelGroup.getAllDescendantUsers(); - return await map(users, async (user) => { - const lowestGroupInTree = await user.getLowestMemberGroupInALearnerGroupTree(treeGroups); - return ObjectProxy.create({ - content: user, - lowestGroupInTree, - //special sorting property - lowestGroupInTreeTitle: lowestGroupInTree.title, - }); - }); + return await Promise.all( + users.map(async (user) => { + const lowestGroupInTree = await user.getLowestMemberGroupInALearnerGroupTree(treeGroups); + return ObjectProxy.create({ + content: user, + lowestGroupInTree, + //special sorting property + lowestGroupInTreeTitle: lowestGroupInTree.title, + }); + }), + ); } @cached diff --git a/packages/frontend/app/components/learner-group/upload-data.gjs b/packages/frontend/app/components/learner-group/upload-data.gjs index 3ccfd25597..055c7d0800 100644 --- a/packages/frontend/app/components/learner-group/upload-data.gjs +++ b/packages/frontend/app/components/learner-group/upload-data.gjs @@ -1,6 +1,5 @@ import Component from '@glimmer/component'; import { service } from '@ember/service'; -import { map } from 'rsvp'; import { task, timeout } from 'ember-concurrency'; import PapaParse from 'papaparse'; import { cached, tracked } from '@glimmer/tracking'; @@ -92,9 +91,8 @@ export default class LearnerGroupUploadDataComponent extends Component { async parseFile(proposedUsers) { const cohort = await this.args.learnerGroup.cohort; - const data = await map( - proposedUsers, - async ({ firstName, lastName, campusId, subGroupName }) => { + const data = await Promise.all( + proposedUsers.map(async ({ firstName, lastName, campusId, subGroupName }) => { const errors = []; const warnings = []; if (!firstName) { @@ -175,7 +173,7 @@ export default class LearnerGroupUploadDataComponent extends Component { hasWarning: warnings.length > 0, isValid: errors.length === 0, }; - }, + }), ); // flag duplicate users as such diff --git a/packages/frontend/app/components/learner-groups/root.gjs b/packages/frontend/app/components/learner-groups/root.gjs index 17930f37ba..dee2af73c3 100644 --- a/packages/frontend/app/components/learner-groups/root.gjs +++ b/packages/frontend/app/components/learner-groups/root.gjs @@ -6,7 +6,6 @@ import { TrackedAsyncData } from 'ember-async-data'; import { findById, findBy, sortBy } from 'ilios-common/utils/array-helpers'; import cloneLearnerGroup from '../../utils/clone-learner-group'; import { task } from 'ember-concurrency'; -import { map } from 'rsvp'; import { action } from '@ember/object'; import FaIcon from '@fortawesome/ember-fontawesome/components/fa-icon'; import { eq, gt, not } from 'ember-truth-helpers'; @@ -243,32 +242,36 @@ export default class LearnerGroupsRootComponent extends Component { if (!programs) { return null; } - const sortingPrograms = await map(programs, async (program) => { - const thisYear = new Date().getFullYear(); - const programYears = await program.programYears; - const sorters = await map(programYears, async (programYear) => { - const groupCount = (await programYear.cohort).hasMany('learnerGroups').ids().length; - return { - distanceFromThisYear: thisYear - Number(programYear.startYear), - groupCount, - }; - }); - return sorters.reduce( - (obj, sorter) => { - if (sorter.distanceFromThisYear < obj.distance) { - obj.distance = sorter.distanceFromThisYear; - } - obj.totalGroups += sorter.groupCount; - return obj; - }, - { - title: program.title, - program, - totalGroups: 0, - distance: 100, - }, - ); - }); + const sortingPrograms = await Promise.all( + programs.map(async (program) => { + const thisYear = new Date().getFullYear(); + const programYears = await program.programYears; + const sorters = await Promise.all( + programYears.map(async (programYear) => { + const groupCount = (await programYear.cohort).hasMany('learnerGroups').ids().length; + return { + distanceFromThisYear: thisYear - Number(programYear.startYear), + groupCount, + }; + }), + ); + return sorters.reduce( + (obj, sorter) => { + if (sorter.distanceFromThisYear < obj.distance) { + obj.distance = sorter.distanceFromThisYear; + } + obj.totalGroups += sorter.groupCount; + return obj; + }, + { + title: program.title, + program, + totalGroups: 0, + distance: 100, + }, + ); + }), + ); const sorted = sortingPrograms.sort((a, b) => { if (a.distance !== b.distance) { return a.distance - b.distance; diff --git a/packages/frontend/app/components/program-year/competencies.gjs b/packages/frontend/app/components/program-year/competencies.gjs index 4958c93d1d..ad44b8e6ab 100644 --- a/packages/frontend/app/components/program-year/competencies.gjs +++ b/packages/frontend/app/components/program-year/competencies.gjs @@ -1,5 +1,5 @@ import Component from '@glimmer/component'; -import { filter, map } from 'rsvp'; +import { filter } from 'rsvp'; import { task, timeout } from 'ember-concurrency'; import { service } from '@ember/service'; import { TrackedAsyncData } from 'ember-async-data'; @@ -84,7 +84,7 @@ export default class ProgramYearCompetenciesComponent extends Component { const program = await programYear.program; const school = await program.school; const competencies = await school.competencies; - const domains = await map(competencies, async (c) => c.getDomain()); + const domains = await Promise.all(competencies.map(async (c) => c.getDomain())); const programYearCompetencies = await programYear.competencies; return { program, school, competencies, domains, programYearCompetencies }; diff --git a/packages/frontend/app/components/program-year/objective-list-item-expanded.gjs b/packages/frontend/app/components/program-year/objective-list-item-expanded.gjs index 822baadbac..25edff0773 100644 --- a/packages/frontend/app/components/program-year/objective-list-item-expanded.gjs +++ b/packages/frontend/app/components/program-year/objective-list-item-expanded.gjs @@ -2,7 +2,6 @@ import Component from '@glimmer/component'; import { cached } from '@glimmer/tracking'; import { htmlSafe } from '@ember/template'; import { TrackedAsyncData } from 'ember-async-data'; -import { map } from 'rsvp'; import { findById } from 'ilios-common/utils/array-helpers'; import t from 'ember-intl/helpers/t'; import sortBy from 'ilios-common/helpers/sort-by'; @@ -24,15 +23,17 @@ export default class ProgramYearObjectiveListItemExpandedComponent extends Compo async getCourseObjects(programYearObjective) { const courseObjectives = await programYearObjective.courseObjectives; - const objectiveObjects = await map(courseObjectives, async (courseObjective) => { - const course = await courseObjective.course; - return { - title: courseObjective.title, - courseId: course.id, - courseTitle: course.title, - courseExternalId: course.externalId, - }; - }); + const objectiveObjects = await Promise.all( + courseObjectives.map(async (courseObjective) => { + const course = await courseObjective.course; + return { + title: courseObjective.title, + courseId: course.id, + courseTitle: course.title, + courseExternalId: course.externalId, + }; + }), + ); return objectiveObjects.reduce((set, obj) => { let existing = findById(set, obj.courseId); if (!existing) { diff --git a/packages/frontend/app/components/program-year/objective-list.gjs b/packages/frontend/app/components/program-year/objective-list.gjs index dcbbbc2e18..d91575339b 100644 --- a/packages/frontend/app/components/program-year/objective-list.gjs +++ b/packages/frontend/app/components/program-year/objective-list.gjs @@ -1,7 +1,6 @@ import Component from '@glimmer/component'; import { cached, tracked } from '@glimmer/tracking'; import { task, timeout } from 'ember-concurrency'; -import { map } from 'rsvp'; import { service } from '@ember/service'; import { TrackedAsyncData } from 'ember-async-data'; import { mapBy, uniqueValues } from 'ilios-common/utils/array-helpers'; @@ -72,19 +71,21 @@ export default class ProgramYearObjectiveListComponent extends Component { }); const parents = await Promise.all(mapBy(programYearCompetencies, 'parent')); const allDomains = uniqueValues([...domains, ...parents]).filter(Boolean); - return await map(allDomains, async (domain) => { - const competencies = (await domain.children).map((competency) => { + return await Promise.all( + allDomains.map(async (domain) => { + const competencies = (await domain.children).map((competency) => { + return { + id: competency.id, + title: competency.title, + }; + }); return { - id: competency.id, - title: competency.title, + id: domain.id, + title: domain.title, + competencies, }; - }); - return { - id: domain.id, - title: domain.title, - competencies, - }; - }); + }), + ); } downloadReport = task({ drop: true }, async () => { diff --git a/packages/frontend/app/components/school/competencies-list.gjs b/packages/frontend/app/components/school/competencies-list.gjs index c5b432cfec..93c1afb988 100644 --- a/packages/frontend/app/components/school/competencies-list.gjs +++ b/packages/frontend/app/components/school/competencies-list.gjs @@ -1,7 +1,6 @@ import Component from '@glimmer/component'; import { cached } from '@glimmer/tracking'; import { TrackedAsyncData } from 'ember-async-data'; -import { map } from 'rsvp'; import { sortBy } from 'ilios-common/utils/array-helpers'; import t from 'ember-intl/helpers/t'; import CompetenciesListItem from './competencies-list-item'; @@ -17,13 +16,15 @@ export default class SchoolCompetenciesListComponent extends Component { } async loadData(domains) { - return map(sortBy(domains, 'title'), async (domain) => { - const competencies = await domain.children; - return { - domain, - competencies: sortBy(competencies, 'title'), - }; - }); + return Promise.all( + sortBy(domains, 'title').map(async (domain) => { + const competencies = await domain.children; + return { + domain, + competencies: sortBy(competencies, 'title'), + }; + }), + ); }