From d7589561c0e29183ea6ac00d936b95d6978a2915 Mon Sep 17 00:00:00 2001 From: Michael Chadwick Date: Thu, 13 Nov 2025 16:10:50 -0800 Subject: [PATCH 01/16] show learners in session->offerings tables like SessionsGrid; match up column names for Ls and LGs --- .../addon/components/offering-manager.gjs | 11 +++++++++++ .../addon/components/session-offerings.gjs | 5 ++++- .../ilios-common/components/offering-manager.scss | 6 +++++- .../components/session-offerings-list.scss | 2 +- .../ilios-common/components/session-offerings.scss | 2 +- 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/packages/ilios-common/addon/components/offering-manager.gjs b/packages/ilios-common/addon/components/offering-manager.gjs index 088b5299c0..83e07ffcc7 100644 --- a/packages/ilios-common/addon/components/offering-manager.gjs +++ b/packages/ilios-common/addon/components/offering-manager.gjs @@ -18,6 +18,8 @@ import eq from 'ember-truth-helpers/helpers/eq'; import join from 'ilios-common/helpers/join'; import reverse from 'ilios-common/helpers/reverse'; import mapBy from 'ilios-common/helpers/map-by'; +import sortBy from 'ilios-common/helpers/sort-by'; +import truncate from 'ilios-common/helpers/truncate'; import TruncateText from 'ilios-common/components/truncate-text'; import OfferingUrlDisplay from 'ilios-common/components/offering-url-display'; import UserStatus from 'ilios-common/components/user-status'; @@ -138,6 +140,15 @@ export default class OfferingManagerComponent extends Component { @scrollToBottom={{false}} /> {{else}} +
+ {{#if @offering.allLearners.length}} + ({{@offering.allLearners.length}}) + {{/if}} + {{truncate (join ", " (mapBy "fullName" (sortBy "fullName" @offering.allLearners))) 25}} +
- {{t "general.groupName"}} + {{t "general.learners"}} +
+
+ {{t "general.learnerGroups"}}
{{t "general.location"}} diff --git a/packages/ilios-common/app/styles/ilios-common/components/offering-manager.scss b/packages/ilios-common/app/styles/ilios-common/components/offering-manager.scss index bbbbc275c2..eb07171a59 100644 --- a/packages/ilios-common/app/styles/ilios-common/components/offering-manager.scss +++ b/packages/ilios-common/app/styles/ilios-common/components/offering-manager.scss @@ -3,10 +3,14 @@ .offering-manager { @include m.font-size("small"); display: grid; - grid-template-columns: repeat(4, 1fr); + grid-template-columns: repeat(5, 1fr); margin-bottom: 0.5rem; padding-bottom: 0.5rem; + .offering-manager-learners { + padding-right: 1rem; + } + .offering-manager-learner-groups { ul { @include m.ilios-list-reset; diff --git a/packages/ilios-common/app/styles/ilios-common/components/session-offerings-list.scss b/packages/ilios-common/app/styles/ilios-common/components/session-offerings-list.scss index 845de4d3bc..ab5264b715 100644 --- a/packages/ilios-common/app/styles/ilios-common/components/session-offerings-list.scss +++ b/packages/ilios-common/app/styles/ilios-common/components/session-offerings-list.scss @@ -32,7 +32,7 @@ border-bottom: 1px dotted var(--grey); display: grid; grid-column: 1 / -1; - grid-template-columns: repeat(5, 1fr); + grid-template-columns: repeat(6, 1fr); margin-top: 1rem; .offering-block-time-time { diff --git a/packages/ilios-common/app/styles/ilios-common/components/session-offerings.scss b/packages/ilios-common/app/styles/ilios-common/components/session-offerings.scss index c1763a4fde..7b529f8fb2 100644 --- a/packages/ilios-common/app/styles/ilios-common/components/session-offerings.scss +++ b/packages/ilios-common/app/styles/ilios-common/components/session-offerings.scss @@ -27,7 +27,7 @@ background-color: var(--lightest-grey); display: grid; font-weight: 600; - grid-template-columns: repeat(5, 1fr); + grid-template-columns: repeat(6, 1fr); div { background-color: var(--blue); From d6f97eb992caa9aa0d121f11dc122221c483dc84 Mon Sep 17 00:00:00 2001 From: Michael Chadwick Date: Thu, 13 Nov 2025 16:42:00 -0800 Subject: [PATCH 02/16] fixed multiple class spacing render issue --- packages/ilios-common/addon/components/offering-manager.gjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ilios-common/addon/components/offering-manager.gjs b/packages/ilios-common/addon/components/offering-manager.gjs index 83e07ffcc7..9619e40230 100644 --- a/packages/ilios-common/addon/components/offering-manager.gjs +++ b/packages/ilios-common/addon/components/offering-manager.gjs @@ -120,7 +120,7 @@ export default class OfferingManagerComponent extends Component { }); , ); + assert.notOk(component.learners.isHidden, 'list of individual learners is displayed'); + assert.strictEqual(component.learnerGroups.length, 2, 'learner groups list has correct count'); assert.strictEqual( - component.learners, + component.learners.list, '(2) 1 guy M. Mc1son, 2 guy M. Mc2son', 'list of learners correct', ); @@ -76,4 +78,175 @@ module('Integration | Component | offering-manager', function (hooks) { 'second instructor name is correct', ); }); + + test('it renders with only learner groups', async function (assert) { + this.school = this.server.create('school'); + this.user = await setupAuthentication({ school: this.school }, true); + const users = this.server.createList('user', 2); + const today = DateTime.fromObject({ hour: 8 }); + const course = this.server.create('course'); + const sessionType = this.server.create('session-type'); + const session = this.server.create('session', { + course, + sessionType, + }); + const learnerGroup1 = this.server.create('learner-group'); + const learnerGroup2 = this.server.create('learner-group'); + const offering = this.server.create('offering', { + session, + startDate: today.toJSDate(), + endDate: today.plus({ hour: 1 }).toJSDate(), + room: 'room 123', + learnerGroups: [learnerGroup1, learnerGroup2], + instructors: [users[0], users[1]], + url: 'http://foo.com', + }); + + const offeringModel = await this.owner + .lookup('service:store') + .findRecord('offering', offering.id); + this.set('offering', offeringModel); + + await render( + , + ); + + assert.ok(component.learners.isHidden, 'list of individual learners not displayed'); + assert.strictEqual(component.learnerGroups.length, 2, 'learner groups list has correct count'); + assert.strictEqual( + component.learnerGroups[0].title, + 'learner group 0', + 'first learner group title is correct', + ); + assert.strictEqual( + component.learnerGroups[1].title, + 'learner group 1', + 'second learner group title is correct', + ); + assert.strictEqual(component.location, 'room 123', 'offering location is correct'); + assert.ok(component.hasUrl, 'offering has url'); + assert.strictEqual(component.url, 'http://foo.com/', 'url is correct'); + assert.strictEqual( + component.instructors[0].userNameInfo.fullName, + '1 guy M. Mc1son', + 'first instructor name is correct', + ); + assert.strictEqual( + component.instructors[1].userNameInfo.fullName, + '2 guy M. Mc2son', + 'second instructor name is correct', + ); + }); + + test('it renders with only individual learners', async function (assert) { + this.school = this.server.create('school'); + this.user = await setupAuthentication({ school: this.school }, true); + const users = this.server.createList('user', 4); + const today = DateTime.fromObject({ hour: 8 }); + const course = this.server.create('course'); + const sessionType = this.server.create('session-type'); + const session = this.server.create('session', { + course, + sessionType, + }); + const offering = this.server.create('offering', { + session, + startDate: today.toJSDate(), + endDate: today.plus({ hour: 1 }).toJSDate(), + room: 'room 123', + learners: [users[0], users[1]], + instructors: [users[2], users[3]], + url: 'http://foo.com', + }); + + const offeringModel = await this.owner + .lookup('service:store') + .findRecord('offering', offering.id); + this.set('offering', offeringModel); + + await render( + , + ); + + assert.notOk(component.learners.isHidden, 'list of individual learners is displayed'); + assert.strictEqual( + component.learners.list, + '(2) 1 guy M. Mc1son, 2 guy M. Mc2son', + 'list of learners correct', + ); + assert.strictEqual(component.learnerGroups.length, 1, 'learner groups list has correct count'); + assert.ok( + component.learnerGroups[0].displaysUsersIcon, + 'learner groups list first and only item is fa-users icon', + ); + assert.strictEqual(component.location, 'room 123', 'offering location is correct'); + assert.ok(component.hasUrl, 'offering has url'); + assert.strictEqual(component.url, 'http://foo.com/', 'url is correct'); + assert.strictEqual( + component.instructors[0].userNameInfo.fullName, + '3 guy M. Mc3son', + 'first instructor name is correct', + ); + assert.strictEqual( + component.instructors[1].userNameInfo.fullName, + '4 guy M. Mc4son', + 'second instructor name is correct', + ); + }); + + test('it renders with no individual learners or learner groups', async function (assert) { + this.school = this.server.create('school'); + this.user = await setupAuthentication({ school: this.school }, true); + const users = this.server.createList('user', 2); + const today = DateTime.fromObject({ hour: 8 }); + const course = this.server.create('course'); + const sessionType = this.server.create('session-type'); + const session = this.server.create('session', { + course, + sessionType, + }); + const offering = this.server.create('offering', { + session, + startDate: today.toJSDate(), + endDate: today.plus({ hour: 1 }).toJSDate(), + room: 'room 123', + instructors: [users[0], users[1]], + url: 'http://foo.com', + }); + + const offeringModel = await this.owner + .lookup('service:store') + .findRecord('offering', offering.id); + this.set('offering', offeringModel); + + await render( + , + ); + + assert.ok(component.learners.isHidden, 'list of individual learners is not displayed'); + assert.strictEqual(component.learnerGroups.length, 1, 'learner groups list has correct count'); + assert.ok( + component.learnerGroups[0].displaysUsersIcon, + 'learner groups list first and only item is fa-users icon', + ); + assert.strictEqual(component.location, 'room 123', 'offering location is correct'); + assert.ok(component.hasUrl, 'offering has url'); + assert.strictEqual(component.url, 'http://foo.com/', 'url is correct'); + assert.strictEqual( + component.instructors[0].userNameInfo.fullName, + '1 guy M. Mc1son', + 'first instructor name is correct', + ); + assert.strictEqual( + component.instructors[1].userNameInfo.fullName, + '2 guy M. Mc2son', + 'second instructor name is correct', + ); + }); }); From d3fc89d156a0cd896f87decefaeb0574d1727c75 Mon Sep 17 00:00:00 2001 From: Michael Chadwick Date: Wed, 26 Nov 2025 09:35:56 -0800 Subject: [PATCH 10/16] changed individual learners value check to use array instead of display string --- packages/ilios-common/addon/components/offering-manager.gjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ilios-common/addon/components/offering-manager.gjs b/packages/ilios-common/addon/components/offering-manager.gjs index a578888f72..1a1ccb7041 100644 --- a/packages/ilios-common/addon/components/offering-manager.gjs +++ b/packages/ilios-common/addon/components/offering-manager.gjs @@ -158,7 +158,7 @@ export default class OfferingManagerComponent extends Component { /> {{else}}
- {{#if this.sortedIndividualLearners.length}} + {{#if this.individualLearners.length}}
Date: Wed, 26 Nov 2025 11:08:00 -0800 Subject: [PATCH 11/16] removed individual learner count --- packages/ilios-common/addon/components/offering-manager.gjs | 3 --- .../tests/integration/components/offering-manager-test.gjs | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/ilios-common/addon/components/offering-manager.gjs b/packages/ilios-common/addon/components/offering-manager.gjs index 1a1ccb7041..48a0d83204 100644 --- a/packages/ilios-common/addon/components/offering-manager.gjs +++ b/packages/ilios-common/addon/components/offering-manager.gjs @@ -166,9 +166,6 @@ export default class OfferingManagerComponent extends Component { @setExpanded={{@setFadeTextExpanded}} as |ft| > - {{#if this.individualLearners.length}} - ({{this.individualLearners.length}}) - {{/if}} {{ft.text}} {{ft.controls}} diff --git a/packages/test-app/tests/integration/components/offering-manager-test.gjs b/packages/test-app/tests/integration/components/offering-manager-test.gjs index 328f152e38..1d120c2b28 100644 --- a/packages/test-app/tests/integration/components/offering-manager-test.gjs +++ b/packages/test-app/tests/integration/components/offering-manager-test.gjs @@ -51,7 +51,7 @@ module('Integration | Component | offering-manager', function (hooks) { assert.strictEqual(component.learnerGroups.length, 2, 'learner groups list has correct count'); assert.strictEqual( component.learners.list, - '(2) 1 guy M. Mc1son, 2 guy M. Mc2son', + '1 guy M. Mc1son, 2 guy M. Mc2son', 'list of learners correct', ); assert.strictEqual( @@ -175,7 +175,7 @@ module('Integration | Component | offering-manager', function (hooks) { assert.notOk(component.learners.isHidden, 'list of individual learners is displayed'); assert.strictEqual( component.learners.list, - '(2) 1 guy M. Mc1son, 2 guy M. Mc2son', + '1 guy M. Mc1son, 2 guy M. Mc2son', 'list of learners correct', ); assert.strictEqual(component.learnerGroups.length, 1, 'learner groups list has correct count'); From daa739dc4586ebc33401917fc5b1427156ae0e98 Mon Sep 17 00:00:00 2001 From: Michael Chadwick Date: Wed, 26 Nov 2025 11:46:11 -0800 Subject: [PATCH 12/16] switch out interim locale getter value for direct primaryLocale value --- .../ilios-common/addon/components/offering-manager.gjs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/ilios-common/addon/components/offering-manager.gjs b/packages/ilios-common/addon/components/offering-manager.gjs index 48a0d83204..9cad5cfdcd 100644 --- a/packages/ilios-common/addon/components/offering-manager.gjs +++ b/packages/ilios-common/addon/components/offering-manager.gjs @@ -51,11 +51,14 @@ export default class OfferingManagerComponent extends Component { return []; } return this.learnerGroups.slice().sort((learnerGroupA, learnerGroupB) => { - const locale = this.intl.get('locale'); if ('title:desc' === this.sortBy) { - return learnerGroupB.title.localeCompare(learnerGroupA.title, locale, { numeric: true }); + return learnerGroupB.title.localeCompare(learnerGroupA.title, this.intl.primaryLocale, { + numeric: true, + }); } - return learnerGroupA.title.localeCompare(learnerGroupB.title, locale, { numeric: true }); + return learnerGroupA.title.localeCompare(learnerGroupB.title, this.intl.primaryLocale, { + numeric: true, + }); }); } From 8a8573ae885d53822f262ecc6be64dcadd68b415 Mon Sep 17 00:00:00 2001 From: Michael Chadwick Date: Wed, 26 Nov 2025 11:57:23 -0800 Subject: [PATCH 13/16] switched to non-block version of FadeText as nothing non-default is being done with text or controls --- .../ilios-common/addon/components/offering-manager.gjs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/packages/ilios-common/addon/components/offering-manager.gjs b/packages/ilios-common/addon/components/offering-manager.gjs index 9cad5cfdcd..1cbc47d9e4 100644 --- a/packages/ilios-common/addon/components/offering-manager.gjs +++ b/packages/ilios-common/addon/components/offering-manager.gjs @@ -163,15 +163,7 @@ export default class OfferingManagerComponent extends Component {
{{#if this.individualLearners.length}}
- - {{ft.text}} - {{ft.controls}} - +
{{/if}}
From e184e4b16762cbec341bbe20d1af10da9f113a4e Mon Sep 17 00:00:00 2001 From: Michael Chadwick Date: Wed, 26 Nov 2025 12:00:11 -0800 Subject: [PATCH 14/16] scaled grid fr chunks up to avoid decimals --- .../ilios-common/components/session-offerings-list.scss | 4 ++-- .../app/styles/ilios-common/components/session-offerings.scss | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/ilios-common/app/styles/ilios-common/components/session-offerings-list.scss b/packages/ilios-common/app/styles/ilios-common/components/session-offerings-list.scss index afa5646673..b4b4f8877d 100644 --- a/packages/ilios-common/app/styles/ilios-common/components/session-offerings-list.scss +++ b/packages/ilios-common/app/styles/ilios-common/components/session-offerings-list.scss @@ -5,7 +5,7 @@ .offering-block { display: grid; - grid-template-columns: 1.5fr repeat(3, 2fr) 1fr; + grid-template-columns: 3fr repeat(3, 4fr) 2fr; margin-top: 1rem; .offering-form { @@ -32,7 +32,7 @@ border-bottom: 1px dotted var(--grey); display: grid; grid-column: 1 / -1; - grid-template-columns: 1.5fr repeat(3, 2fr) 1fr; + grid-template-columns: 3fr repeat(3, 4fr) 2fr; margin-top: 1rem; .offering-block-time-time { diff --git a/packages/ilios-common/app/styles/ilios-common/components/session-offerings.scss b/packages/ilios-common/app/styles/ilios-common/components/session-offerings.scss index 4b104df9fd..872084cf43 100644 --- a/packages/ilios-common/app/styles/ilios-common/components/session-offerings.scss +++ b/packages/ilios-common/app/styles/ilios-common/components/session-offerings.scss @@ -27,7 +27,7 @@ background-color: var(--lightest-grey); display: grid; font-weight: 600; - grid-template-columns: 1.5fr repeat(3, 2fr) 1fr; + grid-template-columns: 3fr repeat(3, 4fr) 2fr; div { background-color: var(--blue); From 03c4a8b2968ba72470b591ae28b1792ef21b6afe Mon Sep 17 00:00:00 2001 From: Michael Chadwick Date: Tue, 2 Dec 2025 11:10:19 -0800 Subject: [PATCH 15/16] removed hacky .sort() on relationship array and use proper .toSorted() method --- packages/ilios-common/addon/components/offering-manager.gjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ilios-common/addon/components/offering-manager.gjs b/packages/ilios-common/addon/components/offering-manager.gjs index 1cbc47d9e4..7cfff3fc16 100644 --- a/packages/ilios-common/addon/components/offering-manager.gjs +++ b/packages/ilios-common/addon/components/offering-manager.gjs @@ -50,7 +50,7 @@ export default class OfferingManagerComponent extends Component { if (!this.learnerGroups) { return []; } - return this.learnerGroups.slice().sort((learnerGroupA, learnerGroupB) => { + return this.learnerGroups.toSorted((learnerGroupA, learnerGroupB) => { if ('title:desc' === this.sortBy) { return learnerGroupB.title.localeCompare(learnerGroupA.title, this.intl.primaryLocale, { numeric: true, From be5b1d9c4baf619088ebaecccafce82edad4d702 Mon Sep 17 00:00:00 2001 From: Michael Chadwick Date: Tue, 2 Dec 2025 16:40:51 -0800 Subject: [PATCH 16/16] check array positive length instead of mere existence --- packages/ilios-common/addon/components/offering-manager.gjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ilios-common/addon/components/offering-manager.gjs b/packages/ilios-common/addon/components/offering-manager.gjs index 7cfff3fc16..ed2e410e15 100644 --- a/packages/ilios-common/addon/components/offering-manager.gjs +++ b/packages/ilios-common/addon/components/offering-manager.gjs @@ -72,7 +72,7 @@ export default class OfferingManagerComponent extends Component { } get sortedIndividualLearners() { - if (!this.individualLearners) { + if (!this.individualLearners.length) { return ''; }