Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
d758956
show learners in session->offerings tables like SessionsGrid; match u…
michaelchadwick Nov 14, 2025
d6f97eb
fixed multiple class spacing render issue
michaelchadwick Nov 14, 2025
4cedaae
added learners to OfferingManager page-object
michaelchadwick Nov 14, 2025
b4d63db
added basic offering-manager integration test
michaelchadwick Nov 14, 2025
0ed31ec
changed column header to be Individual Learners to reflect actual data
michaelchadwick Nov 20, 2025
0ea8fb1
show all individual learners and contain in a FadeText so it truncate…
michaelchadwick Nov 21, 2025
eec75a1
moved learners to same column as learner groups and changed column he…
michaelchadwick Nov 26, 2025
41ddb0c
fixed test to show full list of learners since we are not truncating …
michaelchadwick Nov 26, 2025
fd6695f
offering-manager integration test now checks for all possibilities: o…
michaelchadwick Nov 26, 2025
d3fc89d
changed individual learners value check to use array instead of displ…
michaelchadwick Nov 26, 2025
34e197f
removed individual learner count
michaelchadwick Nov 26, 2025
daa739d
switch out interim locale getter value for direct primaryLocale value
michaelchadwick Nov 26, 2025
8a8573a
switched to non-block version of FadeText as nothing non-default is b…
michaelchadwick Nov 26, 2025
e184e4b
scaled grid fr chunks up to avoid decimals
michaelchadwick Nov 26, 2025
03c4a8b
removed hacky .sort() on relationship array and use proper .toSorted(…
michaelchadwick Dec 2, 2025
be5b1d9
check array positive length instead of mere existence
michaelchadwick Dec 3, 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
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
create,
clickable,
hasClass,
isHidden,
isVisible,
property,
text,
Expand All @@ -14,6 +15,11 @@ import offeringForm from './offering-form';

const definition = {
scope: '[data-test-offering-manager]',
learners: {
scope: '.offering-manager-learners',
list: text(),
isHidden: isHidden(),
},
learnerGroups: collection('.offering-manager-learner-groups li', {
title: text(),
expandTooltip: triggerable('mouseover'),
Expand All @@ -22,6 +28,7 @@ const definition = {
isTooltipVisible: isVisible('.ilios-tooltip', {
resetScope: true,
}),
displaysUsersIcon: hasClass('fa-users', 'svg'),
}),
location: text('[data-test-location]'),
url: property('href', '[data-test-url] a'),
Expand Down
161 changes: 95 additions & 66 deletions packages/ilios-common/addon/components/offering-manager.gjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { cached, tracked } from '@glimmer/tracking';
import { task, timeout } from 'ember-concurrency';
import { modifier } from 'ember-modifier';
import { TrackedAsyncData } from 'ember-async-data';
import { mapBy, sortBy } from 'ilios-common/utils/array-helpers';
import OfferingForm from 'ilios-common/components/offering-form';
import toggle from 'ilios-common/helpers/toggle';
import mouseHoverToggle from 'ilios-common/modifiers/mouse-hover-toggle';
Expand All @@ -14,10 +15,11 @@ import t from 'ember-intl/helpers/t';
import and from 'ember-truth-helpers/helpers/and';
import includes from 'ilios-common/helpers/includes';
import IliosTooltip from 'ilios-common/components/ilios-tooltip';
import mapBy0 from 'ilios-common/helpers/map-by';
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 FadeText from 'ilios-common/components/fade-text';
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';
Expand All @@ -40,33 +42,66 @@ export default class OfferingManagerComponent extends Component {
return new TrackedAsyncData(this.args.offering.learnerGroups);
}

@cached
get sessionData() {
return new TrackedAsyncData(this.args.offering?.session);
get learnerGroups() {
return this.learnerGroupsData.isResolved ? this.learnerGroupsData.value : null;
}

@cached
get courseData() {
return new TrackedAsyncData(this.session?.course);
get sortedLearnerGroups() {
if (!this.learnerGroups) {
return [];
}
return this.learnerGroups.toSorted((learnerGroupA, learnerGroupB) => {
if ('title:desc' === this.sortBy) {
return learnerGroupB.title.localeCompare(learnerGroupA.title, this.intl.primaryLocale, {
numeric: true,
});
}
return learnerGroupA.title.localeCompare(learnerGroupB.title, this.intl.primaryLocale, {
numeric: true,
});
});
}

@cached
get cohortsData() {
return new TrackedAsyncData(this.course?.cohorts);
get individualLearnersData() {
return new TrackedAsyncData(this.args.offering.learners);
}

get learnerGroups() {
return this.learnerGroupsData.isResolved ? this.learnerGroupsData.value : null;
get individualLearners() {
return this.individualLearnersData.isResolved ? this.individualLearnersData.value : [];
}

get sortedIndividualLearners() {
if (!this.individualLearners.length) {
return '';
}

return mapBy(sortBy(this.individualLearners, 'fullName'), 'fullName').join(', ');
}

@cached
get sessionData() {
return new TrackedAsyncData(this.args.offering?.session);
}

get session() {
return this.sessionData.isResolved ? this.sessionData.value : null;
}

@cached
get courseData() {
return new TrackedAsyncData(this.session?.course);
}

get course() {
return this.courseData.isResolved ? this.courseData.value : null;
}

@cached
get cohortsData() {
return new TrackedAsyncData(this.course?.cohorts);
}

get cohorts() {
return this.cohortsData.isResolved ? this.cohortsData.value : null;
}
Expand All @@ -91,19 +126,6 @@ export default class OfferingManagerComponent extends Component {
return this.args.offering.save();
}

get sortedLearnerGroups() {
if (!this.learnerGroups) {
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 learnerGroupA.title.localeCompare(learnerGroupB.title, locale, { numeric: true });
});
}

@action
toggleHover(id) {
if (this.hoveredGroups.includes(id)) {
Expand All @@ -118,7 +140,7 @@ export default class OfferingManagerComponent extends Component {
});
<template>
<div
class="offering-manager {{if this.showRemoveConfirmation 'show-remove-confirmation'}}"
class="offering-manager{{if this.showRemoveConfirmation ' show-remove-confirmation'}}"
data-test-offering-manager
...attributes
>
Expand All @@ -138,48 +160,55 @@ export default class OfferingManagerComponent extends Component {
@scrollToBottom={{false}}
/>
{{else}}
<div class="offering-manager-learner-groups">
<ul>
{{#each this.sortedLearnerGroups as |learnerGroup|}}
<li
{{this.setLearnerGroupElement learnerGroup.id}}
{{mouseHoverToggle (fn this.toggleHover learnerGroup.id)}}
>
{{learnerGroup.title}}
{{#if learnerGroup.needsAccommodation}}
<FaIcon
@icon="universal-access"
@title={{t "general.accommodationIsRequiredForLearnersInThisGroup"}}
/>
{{/if}}
{{#unless learnerGroup.isTopLevelGroup}}
{{#if
(and
(get this (concat "learnerGroupElement" learnerGroup.id))
(includes learnerGroup.id this.hoveredGroups)
)
}}
<IliosTooltip
@target={{get this (concat "learnerGroupElement" learnerGroup.id)}}
>
<strong>
{{if
(eq learnerGroup.allParents.length 1)
(t "general.parentGroup")
(t "general.parentGroups")
}}:
</strong>
{{join " » " (reverse (mapBy "title" learnerGroup.allParents))}}
</IliosTooltip>
<div class="offering-manager-learners-and-learner-groups">
{{#if this.individualLearners.length}}
<div class="offering-manager-learners">
<FadeText @text={{this.sortedIndividualLearners}} />
</div>
{{/if}}
<div class="offering-manager-learner-groups">
<ul>
{{#each this.sortedLearnerGroups as |learnerGroup|}}
<li
{{this.setLearnerGroupElement learnerGroup.id}}
{{mouseHoverToggle (fn this.toggleHover learnerGroup.id)}}
>
{{learnerGroup.title}}
{{#if learnerGroup.needsAccommodation}}
<FaIcon
@icon="universal-access"
@title={{t "general.accommodationIsRequiredForLearnersInThisGroup"}}
/>
{{/if}}
{{/unless}}
</li>
{{else}}
<li>
<FaIcon @icon="users" />
</li>
{{/each}}
</ul>
{{#unless learnerGroup.isTopLevelGroup}}
{{#if
(and
(get this (concat "learnerGroupElement" learnerGroup.id))
(includes learnerGroup.id this.hoveredGroups)
)
}}
<IliosTooltip
@target={{get this (concat "learnerGroupElement" learnerGroup.id)}}
>
<strong>
{{if
(eq learnerGroup.allParents.length 1)
(t "general.parentGroup")
(t "general.parentGroups")
}}:
</strong>
{{join " » " (reverse (mapBy0 "title" learnerGroup.allParents))}}
</IliosTooltip>
{{/if}}
{{/unless}}
</li>
{{else}}
<li>
<FaIcon @icon="users" />
</li>
{{/each}}
</ul>
</div>
</div>
<div class="offering-manager-location">
<TruncateText @text={{@offering.room}} @length={{10}} data-test-location />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export default class SessionOfferingsComponent extends Component {
{{t "general.dateTime"}}
</div>
<div>
{{t "general.groupName"}}
{{t "general.learnersAndLearnerGroups"}}
</div>
<div>
{{t "general.location"}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
.offering-manager {
@include m.font-size("small");
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-columns: repeat(3, 2fr) 1fr;
margin-bottom: 0.5rem;
padding-bottom: 0.5rem;

.offering-manager-learners {
padding: 0 1rem 1rem 0;
}

.offering-manager-learner-groups {
ul {
@include m.ilios-list-reset;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

.offering-block {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-columns: 3fr repeat(3, 4fr) 2fr;
margin-top: 1rem;

.offering-form {
Expand All @@ -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: 3fr repeat(3, 4fr) 2fr;
margin-top: 1rem;

.offering-block-time-time {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
background-color: var(--lightest-grey);
display: grid;
font-weight: 600;
grid-template-columns: repeat(5, 1fr);
grid-template-columns: 3fr repeat(3, 4fr) 2fr;

div {
background-color: var(--blue);
Expand Down
Loading