<commit_before>import Map from 'shared/model/map';
import { isNil } from 'lodash';
import {
  BaseModel, identifiedBy, action, field,
  identifier, computed, observable,
} from 'shared/model';


@identifiedBy('grading/template')
class GradingTemplate extends BaseModel {

  // returns a formik errors object as described:
  // https://jaredpalmer.com/formik/docs/guides/validation
  static validate(tmpl, form) { // eslint-disable-line no-unused-vars
    return {};
  }

  @identifier id;
  @field name = '';
  @field task_plan_type;
  @field completion_weight = 0.9;
  @field correctness_weight = 0.1;
  @field deleted_at;
  @field auto_grading_feedback_on = 'answer';
  @field manual_grading_feedback_on = 'publish';
  @field late_work_penalty = 0.1;
  @field late_work_penalty_applied = 'daily';
  @field default_open_time = '00:01';
  @field default_due_time = '21:00';
  @field default_due_date_offset_days = 7;
  @field default_close_date_offset_days = 7;
  @observable map;

  @observable map = {};

  constructor(attrs, map) {
    super(attrs);
    this.map = map;

    if (this.isNew && this.isReading) {
      this.late_work_penalty_applied = 'immediately';
    }
    if (this.isNew && this.isHomework) {
      this.manual_grading_feedback_on = 'grade';
    }
  }

  @computed get isReading() {
    return 'reading' === this.task_plan_type;
  }

  @computed get isHomework() {
    return 'homework' === this.task_plan_type;
  }

  @computed get isLateWorkAccepted() {
    return this.late_work_penalty_applied !== 'never';
  }

  @computed get canRemove() {
    // a template can be removed as if there is at least one other with the same type
    return Boolean(this.map && this.map.array.find(t => t !== this && t.task_plan_type === this.task_plan_type));
  }

  get dataForSave() {
    const data = this.serialize();
    return data;
  }

  // called from api
  save() {
    return {
      id: this.id,
      courseId: this.map.course.id,
      data: this.dataForSave,
    };
  }

  @action onSaved({ data }) {
    this.update(data);
    if (!this.map.get(this.id)) {
      this.map.set(this.id, this);
    }
  }

  remove() {

  }

  onRemoved() {
    this.map.delete(this.id);
  }

  // Validate happens if template name, case insensitive, equals to any of the other template names.
  isDuplicateName(id, name) {
    return Boolean(this.map && this.map.array.some(t => t.id !== id && t.name.toLowerCase() === name.toLowerCase()));
  }
}


class GradingTemplates extends Map {

  static Model = GradingTemplate;

  constructor({ course }) {
    super();
    this.course = course;
  }
  
  @computed get undeleted() {
    return this.where(gt => isNil(gt.deleted_at));
  }

  newTemplate(attrs) {
    return new GradingTemplate(attrs, this);
  }

  // called by API
  fetch() {
    return { courseId: this.course.id };
  }

  @action onLoaded({ data }) {
    this.mergeModelData(data.items);
  }


}

export { GradingTemplate, GradingTemplates };
<commit_msg>don't remove, set deleted_at<commit_after>import Map from 'shared/model/map';
import { isNil } from 'lodash';
import {
  BaseModel, identifiedBy, action, field,
  identifier, computed, observable,
} from 'shared/model';


@identifiedBy('grading/template')
class GradingTemplate extends BaseModel {

  // returns a formik errors object as described:
  // https://jaredpalmer.com/formik/docs/guides/validation
  static validate(tmpl, form) { // eslint-disable-line no-unused-vars
    return {};
  }

  @identifier id;
  @field name = '';
  @field task_plan_type;
  @field completion_weight = 0.9;
  @field correctness_weight = 0.1;
  @field deleted_at;
  @field auto_grading_feedback_on = 'answer';
  @field manual_grading_feedback_on = 'publish';
  @field late_work_penalty = 0.1;
  @field late_work_penalty_applied = 'daily';
  @field default_open_time = '00:01';
  @field default_due_time = '21:00';
  @field default_due_date_offset_days = 7;
  @field default_close_date_offset_days = 7;
  @observable map;

  @observable map = {};

  constructor(attrs, map) {
    super(attrs);
    this.map = map;

    if (this.isNew && this.isReading) {
      this.late_work_penalty_applied = 'immediately';
    }
    if (this.isNew && this.isHomework) {
      this.manual_grading_feedback_on = 'grade';
    }
  }

  @computed get isReading() {
    return 'reading' === this.task_plan_type;
  }

  @computed get isHomework() {
    return 'homework' === this.task_plan_type;
  }

  @computed get isLateWorkAccepted() {
    return this.late_work_penalty_applied !== 'never';
  }

  @computed get canRemove() {
    // a template can be removed as if there is at least one other with the same type
    return Boolean(this.map && this.map.array.find(t => t !== this && t.task_plan_type === this.task_plan_type));
  }

  get dataForSave() {
    const data = this.serialize();
    return data;
  }

  // called from api
  save() {
    return {
      id: this.id,
      courseId: this.map.course.id,
      data: this.dataForSave,
    };
  }

  @action onSaved({ data }) {
    this.update(data);
    if (!this.map.get(this.id)) {
      this.map.set(this.id, this);
    }
  }

  remove() {}

  onRemoved() {
    this.deleted_at = (new Date()).toISOString();
  }

  // Validate happens if template name, case insensitive, equals to any of the other template names.
  isDuplicateName(id, name) {
    return Boolean(this.map && this.map.array.some(t => t.id !== id && t.name.toLowerCase() === name.toLowerCase()));
  }
}


class GradingTemplates extends Map {

  static Model = GradingTemplate;

  constructor({ course }) {
    super();
    this.course = course;
  }
  
  @computed get undeleted() {
    return this.where(gt => isNil(gt.deleted_at));
  }

  newTemplate(attrs) {
    return new GradingTemplate(attrs, this);
  }

  // called by API
  fetch() {
    return { courseId: this.course.id };
  }

  @action onLoaded({ data }) {
    this.mergeModelData(data.items);
  }


}

export { GradingTemplate, GradingTemplates };

{'fraction_non_alphanumeric': 0.13623430962343097, 'fraction_numerical': 0.005355648535564854, 'mean_word_length': 3.2564102564102564, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 2, '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': '4876503', 'n_tokens_mistral': 2117, 'n_tokens_neox': 2019, 'n_words': 463}