<commit_before>import Component from '@glimmer/component';
import { inject as service } from '@ember/service';
import { tracked } from '@glimmer/tracking';
import { use } from 'ember-could-get-used-to-this';
import ResolveAsyncValue from 'ilios-common/classes/resolve-async-value';
import PermissionChecker from 'ilios/classes/permission-checker';
import { dropTask } from 'ember-concurrency';
import { map } from 'rsvp';
import cloneLearnerGroup from 'ilios/utils/clone-learner-group';
import { action } from '@ember/object';

export default class LearnerGroupsRootComponent extends Component {
  @service currentUser;
  @service store;
  @service dataLoader;
  @service intl;
  @tracked showNewLearnerGroupForm = false;
  @tracked savedLearnerGroup;
  @tracked totalGroupsToSave;
  @tracked currentGroupsSaved;

  learnerGroupPromises = new Map();

  @use user = new ResolveAsyncValue(() => [this.currentUser.getModel()]);
  @use canCreate = new PermissionChecker(() => ['canCreateLearnerGroup', this.selectedSchool]);
  @use programs = new ResolveAsyncValue(() => [this.selectedSchool.programs]);
  @use defaultSelectedProgram = new ResolveAsyncValue(() => [
    this.findBestDefaultProgram(this.programs),
  ]);
  @use programYears = new ResolveAsyncValue(() => [this.selectedProgram?.programYears]);
  @use selectedCohort = new ResolveAsyncValue(() => [this.cohortLoadingPromise]);
  @use learnerGroups = new ResolveAsyncValue(() => [
    this.selectedCohort?.rootLevelLearnerGroups,
    [],
  ]);

  get newLearnerGroup() {
    //ensure we only show groups that haven't been deleted
    return this.learnerGroups?.includes(this.savedLearnerGroup) ? this.savedLearnerGroup : null;
  }

  get cohortLoadingPromise() {
    const id = this.selectedProgramYear?.belongsTo('cohort').id();
    if (id) {
      return this.dataLoader.loadCohortLearnerGroups(id);
    }

    return undefined;
  }

  get isLoaded() {
    return Boolean(this.selectedCohort);
  }

  get selectedSchool() {
    const schoolId = this.args.schoolId ?? this.user?.belongsTo('school').id();

    const school = this.args.schools.findBy('id', schoolId) ?? this.args.schools.firstObject;
    //trigger a pre-load of the data we need to load an individual group in this school
    this.dataLoader.loadInstructorGroupsForSchool(school.id);
    return school;
  }

  get selectedProgram() {
    if (!this.programs) {
      return null;
    }
    if (this.args.programId) {
      return this.programs.findBy('id', this.args.programId);
    }

    return this.defaultSelectedProgram;
  }

  get selectedProgramYear() {
    if (!this.programYears) {
      return null;
    }
    if (this.args.programYearId) {
      return this.programYears.findBy('id', this.args.programYearId);
    }

    return this.programYears.sortBy('startYear').lastObject;
  }

  get filteredLearnerGroups() {
    if (!this.learnerGroups) {
      return [];
    }
    if (!this.args.titleFilter) {
      return this.learnerGroups.toArray();
    }
    const filter = this.args.titleFilter.trim().toLowerCase();
    return this.learnerGroups.filter((learnerGroup) => {
      return learnerGroup.title && learnerGroup.title.trim().toLowerCase().includes(filter);
    });
  }

  @dropTask
  *saveNewLearnerGroup(title, fillWithCohort) {
    const group = this.store.createRecord('learner-group', {
      title,
      cohort: this.selectedCohort,
    });
    if (fillWithCohort) {
      const users = (yield this.selectedCohort.users).toArray();
      group.set('users', users);<commit_msg>replaces usage of deprecated cohort::rootLevelLearnerGroups resource.<commit_after>import Component from '@glimmer/component';
import { inject as service } from '@ember/service';
import { tracked } from '@glimmer/tracking';
import { use } from 'ember-could-get-used-to-this';
import ResolveAsyncValue from 'ilios-common/classes/resolve-async-value';
import PermissionChecker from 'ilios/classes/permission-checker';
import { dropTask } from 'ember-concurrency';
import { map } from 'rsvp';
import cloneLearnerGroup from 'ilios/utils/clone-learner-group';
import { action } from '@ember/object';

export default class LearnerGroupsRootComponent extends Component {
  @service currentUser;
  @service store;
  @service dataLoader;
  @service intl;
  @tracked showNewLearnerGroupForm = false;
  @tracked savedLearnerGroup;
  @tracked totalGroupsToSave;
  @tracked currentGroupsSaved;

  learnerGroupPromises = new Map();

  @use user = new ResolveAsyncValue(() => [this.currentUser.getModel()]);
  @use canCreate = new PermissionChecker(() => ['canCreateLearnerGroup', this.selectedSchool]);
  @use programs = new ResolveAsyncValue(() => [this.selectedSchool.programs]);
  @use defaultSelectedProgram = new ResolveAsyncValue(() => [
    this.findBestDefaultProgram(this.programs),
  ]);
  @use programYears = new ResolveAsyncValue(() => [this.selectedProgram?.programYears]);
  @use selectedCohort = new ResolveAsyncValue(() => [this.cohortLoadingPromise]);
  @use learnerGroups = new ResolveAsyncValue(() => [this.selectedCohort?.learnerGroups]);

  get newLearnerGroup() {
    //ensure we only show groups that haven't been deleted
    return this.rootLevelLearnerGroups?.includes(this.savedLearnerGroup)
      ? this.savedLearnerGroup
      : null;
  }

  get cohortLoadingPromise() {
    const id = this.selectedProgramYear?.belongsTo('cohort').id();
    if (id) {
      return this.dataLoader.loadCohortLearnerGroups(id);
    }

    return undefined;
  }

  get isLoaded() {
    return Boolean(this.selectedCohort);
  }

  get selectedSchool() {
    const schoolId = this.args.schoolId ?? this.user?.belongsTo('school').id();

    const school = this.args.schools.findBy('id', schoolId) ?? this.args.schools.firstObject;
    //trigger a pre-load of the data we need to load an individual group in this school
    this.dataLoader.loadInstructorGroupsForSchool(school.id);
    return school;
  }

  get selectedProgram() {
    if (!this.programs) {
      return null;
    }
    if (this.args.programId) {
      return this.programs.findBy('id', this.args.programId);
    }

    return this.defaultSelectedProgram;
  }

  get selectedProgramYear() {
    if (!this.programYears) {
      return null;
    }
    if (this.args.programYearId) {
      return this.programYears.findBy('id', this.args.programYearId);
    }

    return this.programYears.sortBy('startYear').lastObject;
  }

  get rootLevelLearnerGroups() {
    if (!this.learnerGroups) {
      return [];
    }
    return this.learnerGroups.filter((learnerGroup) => !learnerGroup.belongsTo('parent').id());
  }

  get filteredLearnerGroups() {
    if (!this.args.titleFilter) {
      return this.rootLevelLearnerGroups.toArray();
    }
    const filter = this.args.titleFilter.trim().toLowerCase();
    return this.rootLevelLearnerGroups.filter((learnerGroup) => {
      return learnerGroup.title && learnerGroup.title.trim().toLowerCase().includes(filter);
    });
  }

  @dropTask
  *saveNewLearnerGroup(title, fillWithCohort) {
    const group = this.store.createRecord('learner-group', {
      title,
      cohort: this.selectedCohort,
    });
    if (fillWithCohort) {
      const users = (yield this.selectedCohort.users).toArray();
      group.set('users', users);
{'fraction_non_alphanumeric': 0.12887663680220537, 'fraction_numerical': 0.0, 'mean_word_length': 4.0564459930313586, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3502691', 'n_tokens_mistral': 2260, 'n_tokens_neox': 2187, 'n_words': 457}