<commit_before>import Map from 'shared/model/map';
import moment from 'moment-timezone';
import { readonly } from 'core-decorators';
import { computed, action, observable } from 'mobx';
import { filter, groupBy, sortBy, pickBy } from 'lodash';
import { TimeStore } from '../flux/time';
import Task from './student/task';
import ResearchSurveys from './research-surveys';

const MAX_POLLING_ATTEMPTS = 10;
const POLL_SECONDS = 30;

export class CourseStudentTasks extends Map {
  @readonly static Model = Task;

  @observable researchSurveys;
  @observable expecting_assignments_count = 0;

  constructor(courseId) {
    super();
    this.courseId = courseId;
  }

  @computed get byWeek() {
    const weeks = groupBy(this.array, event => moment(event.due_at).startOf('isoweek').format('YYYYW'));
    const sorted = {};
    for (let weekId in weeks) {
      const events = weeks[weekId];
      sorted[weekId] = sortBy(events, 'due_at');
    }
    return sorted;
  }

  @computed get pastEventsByWeek() {
    const thisWeek = moment(TimeStore.getNow()).startOf('isoweek').format('YYYYW');
    return pickBy(this.byWeek, (events, week) => week < thisWeek);
  }

  weeklyEventsForDay(day) {
    return this.byWeek[moment(day).startOf('isoweek').format('YYYYW')] || [];
  }

  // Returns events who's due date has not passed
  upcomingEvents(now = TimeStore.getNow()) {
    return sortBy(filter(this.array, event => event.due_at > now), 'due_at');
  }

  // note: the response also contains limited course and role information but they're currently unused
  onLoaded({ data: { tasks, research_surveys } }) {
    this.researchSurveys = research_surveys ? new ResearchSurveys(research_surveys) : null;
    this.mergeModelData(tasks);
  }
}

class StudentTasks extends Map {

  forCourseId(courseId) {
    let courseMap = this.get(courseId);
    if (!courseMap) {
      courseMap = new CourseStudentTasks(courseId);
      this.set(courseId, courseMap);
    }
    return courseMap;
  }

}

const studentTasks = new StudentTasks;
export default studentTasks;
<commit_msg>Use WW format specifier so weeks are sorted correctly<commit_after>import Map from 'shared/model/map';
import moment from 'moment-timezone';
import { readonly } from 'core-decorators';
import { computed, action, observable } from 'mobx';
import { filter, groupBy, sortBy, pickBy } from 'lodash';
import { TimeStore } from '../flux/time';
import Task from './student/task';
import ResearchSurveys from './research-surveys';

const MAX_POLLING_ATTEMPTS = 10;
const POLL_SECONDS = 30;

export class CourseStudentTasks extends Map {
  @readonly static Model = Task;

  @observable researchSurveys;
  @observable expecting_assignments_count = 0;

  constructor(courseId) {
    super();
    this.courseId = courseId;
  }

  @computed get byWeek() {
    const weeks = groupBy(this.array, event => moment(event.due_at).startOf('isoweek').format('YYYYWW'));
    const sorted = {};
    for (let weekId in weeks) {
      const events = weeks[weekId];
      sorted[weekId] = sortBy(events, 'due_at');
    }
    return sorted;
  }

  @computed get pastEventsByWeek() {
    const thisWeek = moment(TimeStore.getNow()).startOf('isoweek').format('YYYYWW');
    return pickBy(this.byWeek, (events, week) => week < thisWeek);
  }

  weeklyEventsForDay(day) {
    return this.byWeek[moment(day).startOf('isoweek').format('YYYYWW')] || [];
  }

  // Returns events who's due date has not passed
  upcomingEvents(now = TimeStore.getNow()) {
    return sortBy(filter(this.array, event => event.due_at > now), 'due_at');
  }

  // note: the response also contains limited course and role information but they're currently unused
  onLoaded({ data: { tasks, research_surveys } }) {
    this.researchSurveys = research_surveys ? new ResearchSurveys(research_surveys) : null;
    this.mergeModelData(tasks);
  }
}

class StudentTasks extends Map {

  forCourseId(courseId) {
    let courseMap = this.get(courseId);
    if (!courseMap) {
      courseMap = new CourseStudentTasks(courseId);
      this.set(courseId, courseMap);
    }
    return courseMap;
  }

}

const studentTasks = new StudentTasks;
export default studentTasks;

{'fraction_non_alphanumeric': 0.12581032412965187, 'fraction_numerical': 0.0024009603841536613, 'mean_word_length': 4.111656441717791, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 11, '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': '344813', 'n_tokens_mistral': 1343, 'n_tokens_neox': 1299, 'n_words': 334}