ilios/frontend

View on GitHub
packages/ilios-common/addon/components/course/objective-list.js

Summary

Maintainability
A
0 mins
Test Coverage
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';
import sortableByPosition from 'ilios-common/utils/sortable-by-position';
import { findById } from 'ilios-common/utils/array-helpers';
export default class CourseObjectiveListComponent extends Component {
  @service store;
  @service intl;
  @service dataLoader;
  @tracked isSorting = false;

  @cached
  get courseObjectivesAsyncData() {
    return new TrackedAsyncData(this.args.course.courseObjectives);
  }

  @cached
  get courseCohortsAsyncData() {
    return new TrackedAsyncData(this.args.course.cohorts);
  }

  get courseObjectivesAsync() {
    return this.courseObjectivesAsyncData.isResolved ? this.courseObjectivesAsyncData.value : null;
  }

  get courseObjectives() {
    if (this.load.lastSuccessful && this.courseObjectivesAsync) {
      return this.courseObjectivesAsync.slice().sort(sortableByPosition);
    }

    return undefined;
  }

  get courseCohortsAsync() {
    return this.courseCohortsAsyncData.isResolved ? this.courseCohortsAsyncData.value : null;
  }

  get courseCohorts() {
    if (this.load.lastSuccessful && this.courseCohortsAsync) {
      return this.courseCohortsAsync;
    }

    return [];
  }

  @cached
  get cohortObjectivesData() {
    return new TrackedAsyncData(this.getCohortObjectives(this.courseCohorts, this.intl));
  }

  get cohortObjectives() {
    return this.cohortObjectivesData.isResolved ? this.cohortObjectivesData.value : [];
  }

  get cohortObjectivesLoaded() {
    return this.cohortObjectivesData.isResolved;
  }

  get courseObjectiveCount() {
    if (this.courseObjectives) {
      return this.courseObjectives.length;
    }

    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 getCohortObjectives(cohorts, intl) {
    return await map(cohorts, async (cohort) => {
      const programYear = await cohort.programYear;
      const program = await programYear.program;
      const school = await program.school;
      const allowMultipleCourseObjectiveParents = await school.getConfigValue(
        'allowMultipleCourseObjectiveParents',
      );
      const objectives = await programYear.programYearObjectives;
      const objectiveObjects = await map(objectives, async (objective) => {
        let competencyId = 0;
        let competencyTitle = intl.t('general.noAssociatedCompetency');
        let competencyParent = null;
        const competency = await objective.competency;
        if (competency) {
          competencyId = competency.id;
          competencyTitle = competency.title;
          competencyParent = await competency.parent;
        }
        return {
          id: objective.id,
          title: objective.title,
          active: objective.active,
          competencyId,
          competencyTitle,
          competencyParent,
          cohortId: cohort.id,
        };
      });
      const competencies = objectiveObjects.reduce((set, obj) => {
        let existing = findById(set, obj.competencyId);
        if (!existing) {
          existing = {
            id: obj.competencyId,
            title: obj.competencyTitle,
            objectives: [],
            parent: obj.competencyParent,
          };
          set.push(existing);
        }
        existing.objectives.push(obj);
        return set;
      }, []);

      return {
        title: `${program.title} ${cohort.title}`,
        id: cohort.id,
        allowMultipleParents: allowMultipleCourseObjectiveParents,
        competencies,
      };
    });
  }
}