-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove common Course render modifiers #8274
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,54 +1,50 @@ | ||
<div | ||
class="course-header" | ||
data-test-course-header | ||
{{did-insert (perform this.load)}} | ||
{{did-update this.revertTitleChanges}} | ||
> | ||
{{#unless this.load.isRunning}} | ||
<span class="title" data-test-title> | ||
{{#if @editable}} | ||
<EditableField | ||
@value={{this.courseTitle}} | ||
@save={{perform this.changeTitle}} | ||
@close={{this.revertTitleChanges}} | ||
@saveOnEnter={{true}} | ||
@onEditingStatusChange={{set this "isEditingTitle"}} | ||
@closeOnEscape={{true}} as |isSaving| | ||
> | ||
<input | ||
aria-label={{t "general.courseTitle"}} | ||
disabled={{isSaving}} | ||
type="text" | ||
value={{this.courseTitle}} | ||
{{on "input" (pick "target.value" (set this "courseTitle"))}} | ||
{{on "keypress" (fn this.addErrorDisplayFor "courseTitle")}} | ||
> | ||
<ValidationError @validatable={{this}} @property="courseTitle" /> | ||
</EditableField> | ||
{{else}} | ||
<h2> | ||
{{#if @course.locked}} | ||
<FaIcon @icon="lock" /> | ||
{{/if}} | ||
{{@course.title}} | ||
</h2> | ||
{{/if}} | ||
{{#unless this.isEditingTitle}} | ||
<h3 class="academic-year" data-test-academic-year> | ||
{{#if this.academicYearCrossesCalendarYearBoundaries}} | ||
{{@course.year}} - {{add @course.year 1}} | ||
{{else}} | ||
{{@course.year}} | ||
{{/if}} | ||
</h3> | ||
{{/unless}} | ||
</span> | ||
<div class="course-publication"> | ||
{{#if @editable}} | ||
<Course::PublicationMenu @course={{@course}} /> | ||
{{else}} | ||
<PublicationStatus @item={{@course}} @showIcon={{true}} @showText={{true}} /> | ||
{{/if}} | ||
</div> | ||
{{/unless}} | ||
</div> | ||
<div class="course-header" data-test-course-header> | ||
<span class="title" data-test-title> | ||
{{#if @editable}} | ||
<EditableField | ||
@value={{this.courseTitle}} | ||
@save={{perform this.changeTitle}} | ||
@close={{this.revertTitleChanges}} | ||
@saveOnEnter={{true}} | ||
@onEditingStatusChange={{set this "isEditingTitle"}} | ||
@closeOnEscape={{true}} | ||
as |isSaving| | ||
> | ||
<input | ||
aria-label={{t "general.courseTitle"}} | ||
disabled={{isSaving}} | ||
type="text" | ||
value={{this.courseTitle}} | ||
{{on "input" (pick "target.value" (set this "courseTitle"))}} | ||
{{on "keypress" (fn this.addErrorDisplayFor "courseTitle")}} | ||
/> | ||
<ValidationError @validatable={{this}} @property="courseTitle" /> | ||
</EditableField> | ||
{{else}} | ||
<h2> | ||
{{#if @course.locked}} | ||
<FaIcon @icon="lock" /> | ||
{{/if}} | ||
{{@course.title}} | ||
</h2> | ||
{{/if}} | ||
{{#unless this.isEditingTitle}} | ||
<h3 class="academic-year" data-test-academic-year> | ||
{{#if this.academicYearCrossesCalendarYearBoundaries}} | ||
{{@course.year}} | ||
- | ||
{{add @course.year 1}} | ||
{{else}} | ||
{{@course.year}} | ||
{{/if}} | ||
</h3> | ||
{{/unless}} | ||
</span> | ||
<div class="course-publication"> | ||
{{#if @editable}} | ||
<Course::PublicationMenu @course={{@course}} /> | ||
{{else}} | ||
<PublicationStatus @item={{@course}} @showIcon={{true}} @showText={{true}} /> | ||
{{/if}} | ||
</div> | ||
</div> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,45 +1,39 @@ | ||
<div | ||
class="course-objective-list" | ||
data-test-course-objective-list | ||
{{did-insert (perform this.load)}} | ||
{{did-update (perform this.load) @course}} | ||
> | ||
{{#if this.isSorting}} | ||
<ObjectiveSortManager | ||
@subject={{@course}} | ||
@close={{set this "isSorting" false}} | ||
/> | ||
{{/if}} | ||
|
||
{{#if (and this.courseObjectiveCount (not this.isSorting))}} | ||
{{#if (and @editable (gt this.courseObjectiveCount 1))}} | ||
<button | ||
class="sort-button" | ||
type="button" | ||
{{on "click" (set this "isSorting" true)}} | ||
data-test-sort | ||
> | ||
{{t "general.sortObjectives"}} | ||
</button> | ||
<div class="course-objective-list" data-test-course-objective-list> | ||
{{#if this.courseSessionsLoaded}} | ||
{{#if this.isSorting}} | ||
<ObjectiveSortManager @subject={{@course}} @close={{set this "isSorting" false}} /> | ||
{{/if}} | ||
<div class="grid-row headers" data-test-headers> | ||
<span class="grid-item" data-test-header>{{t "general.description"}}</span> | ||
<span class="grid-item" data-test-header>{{t "general.parentObjectives"}}</span> | ||
<span class="grid-item" data-test-header>{{t "general.vocabularyTerms"}}</span> | ||
<span class="grid-item" data-test-header>{{t "general.meshTerms"}}</span> | ||
<span class="actions grid-item" data-test-header>{{t "general.actions"}}</span> | ||
</div> | ||
{{#if (and (is-array this.courseObjectives) this.cohortObjectivesLoaded)}} | ||
{{#each this.courseObjectives as |courseObjective|}} | ||
<Course::ObjectiveListItem | ||
@courseObjective={{courseObjective}} | ||
@editable={{@editable}} | ||
@cohortObjectives={{this.cohortObjectives}} | ||
@course={{@course}} | ||
/> | ||
{{/each}} | ||
{{else}} | ||
<Course::ObjectiveListLoading @count={{this.courseObjectiveCount}} /> | ||
|
||
{{#if (and this.courseObjectiveCount (not this.isSorting))}} | ||
{{#if (and @editable (gt this.courseObjectiveCount 1))}} | ||
<button | ||
class="sort-button" | ||
type="button" | ||
{{on "click" (set this "isSorting" true)}} | ||
data-test-sort | ||
> | ||
{{t "general.sortObjectives"}} | ||
</button> | ||
{{/if}} | ||
<div class="grid-row headers" data-test-headers> | ||
<span class="grid-item" data-test-header>{{t "general.description"}}</span> | ||
<span class="grid-item" data-test-header>{{t "general.parentObjectives"}}</span> | ||
<span class="grid-item" data-test-header>{{t "general.vocabularyTerms"}}</span> | ||
<span class="grid-item" data-test-header>{{t "general.meshTerms"}}</span> | ||
<span class="actions grid-item" data-test-header>{{t "general.actions"}}</span> | ||
</div> | ||
{{#if (and (is-array this.courseObjectives) this.cohortObjectivesLoaded)}} | ||
{{#each this.courseObjectives as |courseObjective|}} | ||
<Course::ObjectiveListItem | ||
@courseObjective={{courseObjective}} | ||
@editable={{@editable}} | ||
@cohortObjectives={{this.cohortObjectives}} | ||
@course={{@course}} | ||
/> | ||
{{/each}} | ||
{{else}} | ||
<Course::ObjectiveListLoading @count={{this.courseObjectiveCount}} /> | ||
{{/if}} | ||
{{/if}} | ||
{{/if}} | ||
</div> | ||
</div> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,5 @@ | ||
import Component from '@glimmer/component'; | ||
import { cached, tracked } from '@glimmer/tracking'; | ||
import { restartableTask } from 'ember-concurrency'; | ||
import { map } from 'rsvp'; | ||
import { service } from '@ember/service'; | ||
import { TrackedAsyncData } from 'ember-async-data'; | ||
|
@@ -12,6 +11,19 @@ export default class CourseObjectiveListComponent extends Component { | |
@service dataLoader; | ||
@tracked isSorting = false; | ||
|
||
@cached | ||
get courseSessionsData() { | ||
return new TrackedAsyncData(this.getCourseSessions(this.args.course)); | ||
} | ||
|
||
get courseSessions() { | ||
return this.courseSessionsData.isResolved ? this.courseSessionsData.value : null; | ||
} | ||
|
||
get courseSessionsLoaded() { | ||
return this.courseSessionsData.isResolved; | ||
} | ||
|
||
@cached | ||
get courseObjectivesAsyncData() { | ||
return new TrackedAsyncData(this.args.course.courseObjectives); | ||
|
@@ -27,7 +39,7 @@ export default class CourseObjectiveListComponent extends Component { | |
} | ||
|
||
get courseObjectives() { | ||
if (this.load.lastSuccessful && this.courseObjectivesAsync) { | ||
if (this.courseSessionsLoaded && this.courseObjectivesAsync) { | ||
return this.courseObjectivesAsync.slice().sort(sortableByPosition); | ||
} | ||
|
||
|
@@ -39,7 +51,7 @@ export default class CourseObjectiveListComponent extends Component { | |
} | ||
|
||
get courseCohorts() { | ||
if (this.load.lastSuccessful && this.courseCohortsAsync) { | ||
if (this.courseSessionsLoaded && this.courseCohortsAsync) { | ||
return this.courseCohortsAsync; | ||
} | ||
|
||
|
@@ -67,10 +79,9 @@ export default class CourseObjectiveListComponent extends Component { | |
return this.args.course.hasMany('courseObjectives').ids().length; | ||
} | ||
|
||
load = restartableTask(async () => { | ||
//pre-load all session data as well to get access to child objectives | ||
await this.dataLoader.loadCourseSessions(this.args.course.id); | ||
}); | ||
async getCourseSessions(course) { | ||
await this.dataLoader.loadCourseSessions(course.id); | ||
} | ||
Comment on lines
+82
to
+84
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think all of this can be scrapped without replacement. will send a follow-up PR for this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I ventured a guess that this could be done further upstream somehow (in the course route?), but wasn't sure how. |
||
|
||
async getCohortObjectives(cohorts, intl) { | ||
return await map(cohorts, async (cohort) => { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔥🔥 🔥 XHTML 🔥🔥 🔥