<commit_before>/*
 * decaffeinate suggestions:
 * DS102: Remove unnecessary code created because of implicit returns
 * DS104: Avoid inline assignments
 * DS205: Consider reworking code to avoid use of IIFEs
 * DS207: Consider shorter variations of null checks
 * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
 */
//#############################################################################
//
//    CoCalc: Collaborative Calculation in the Cloud
//
//    Copyright (C) 2016, Sagemath Inc.
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
//##############################################################################

// CoCalc libraries
const misc = require("smc-util/misc");
const { webapp_client } = require("../webapp_client");

import { is_different } from "smc-util/misc2";

// React libraries and components
import {
  Component,
  React,
  ReactDOM,
  rclass,
  rtypes,
  AppRedux,
  Rendered
} from "../app-framework";

const {
  Alert,
  Button,
  ButtonToolbar,
  ButtonGroup,
  FormGroup,
  FormControl,
  InputGroup,
  Row,
  Col,
  Grid,
  Panel,
  Well,
  Form
} = require("react-bootstrap");

// CoCalc components
import { WindowedList } from "../r_misc/windowed-list";
const { User } = require("../users");
const { MarkdownInput, SearchInput, TimeAgo } = require("../r_misc");
import { ErrorDisplay } from "../r_misc/error-display";
import { Icon } from "../r_misc/icon";
import { Space } from "../r_misc/space";
import { Tip } from "../r_misc/tip";

import { StudentAssignmentInfo, StudentAssignmentInfoHeader } from "./common";
import * as util from "./util";
import * as styles from "./styles";
import { ProjectMap, UserMap } from "../todo-types";
import {
  StudentsMap,
  AssignmentsMap,
  SortDescription,
  StudentRecord,
  CourseStore,
  IsGradingMap
} from "./store";
import { literal } from "../app-framework/literal";
import { redux } from "../frame-editors/generic/test/util";
import { CourseActions } from "./actions";
import { Set } from "immutable";

interface StudentNameDescription {
  full: string;
  first: string;
  last: string;
}

interface StudentsPanelReactProps {
  frame_id?: string; // used for state caching
  name: string;
  redux: AppRedux;
  project_id: string;
  students: StudentsMap;
  user_map: UserMap;
  project_map: ProjectMap;
  assignments: AssignmentsMap;
}

interface StudentsPanelReduxProps {
  expanded_students: Set<string>;
  active_student_sort?: SortDescription;
  get_student_name: (id: string) => string;
  active_feedback_edits: IsGradingMap;
}

interface StudentsPanelState {
  err?: string;
  search: string;
  add_search: string;
  add_searching: boolean;
  add_select?: any;
  existing_students?: any;
  selected_option_nodes?: any;
  show_deleted: boolean;
}

export const StudentsPanel = rclass<StudentsPanelReactProps>(
  class StudentsPanel extends Component<
    StudentsPanelReactProps & StudentsPanelReduxProps,
    StudentsPanelState
  > {
    // student_list not a list, but has one, plus some extra info.
    private student_list:
      | {
          students: any[];
          num_omitted: number;
          num_deleted: number;
        }
      | undefined = undefined;

    constructor(props) {
      super(props);
      this.state = {
        err: undefined,
        search: "",
        add_search: "",
        add_searching: false,
        add_select: undefined,
        existing_students: undefined,
        selected_option_nodes: undefined,
        show_deleted: false
      };
    }

    displayName: "CourseEditorStudents";

    static reduxProps = ({ name }) => {
      return {
        [name]: {
          expanded_students: rtypes.immutable.Set,
          et_a: rtypes.immutable.Map,
          get_student_name: rtypes.func,
          active_feedback_edits: rtypes.immutable.Map
        }
      };
    };<commit_msg>fix student sort (just broke it temporarily in this branch with fat fingers)<commit_after>/*
 * decaffeinate suggestions:
 * DS102: Remove unnecessary code created because of implicit returns
 * DS104: Avoid inline assignments
 * DS205: Consider reworking code to avoid use of IIFEs
 * DS207: Consider shorter variations of null checks
 * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
 */
//#############################################################################
//
//    CoCalc: Collaborative Calculation in the Cloud
//
//    Copyright (C) 2016, Sagemath Inc.
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
//##############################################################################

// CoCalc libraries
const misc = require("smc-util/misc");
const { webapp_client } = require("../webapp_client");

import { is_different } from "smc-util/misc2";

// React libraries and components
import {
  Component,
  React,
  ReactDOM,
  rclass,
  rtypes,
  AppRedux,
  Rendered
} from "../app-framework";

const {
  Alert,
  Button,
  ButtonToolbar,
  ButtonGroup,
  FormGroup,
  FormControl,
  InputGroup,
  Row,
  Col,
  Grid,
  Panel,
  Well,
  Form
} = require("react-bootstrap");

// CoCalc components
import { WindowedList } from "../r_misc/windowed-list";
const { User } = require("../users");
const { MarkdownInput, SearchInput, TimeAgo } = require("../r_misc");
import { ErrorDisplay } from "../r_misc/error-display";
import { Icon } from "../r_misc/icon";
import { Space } from "../r_misc/space";
import { Tip } from "../r_misc/tip";

import { StudentAssignmentInfo, StudentAssignmentInfoHeader } from "./common";
import * as util from "./util";
import * as styles from "./styles";
import { ProjectMap, UserMap } from "../todo-types";
import {
  StudentsMap,
  AssignmentsMap,
  SortDescription,
  StudentRecord,
  CourseStore,
  IsGradingMap
} from "./store";
import { literal } from "../app-framework/literal";
import { redux } from "../frame-editors/generic/test/util";
import { CourseActions } from "./actions";
import { Set } from "immutable";

interface StudentNameDescription {
  full: string;
  first: string;
  last: string;
}

interface StudentsPanelReactProps {
  frame_id?: string; // used for state caching
  name: string;
  redux: AppRedux;
  project_id: string;
  students: StudentsMap;
  user_map: UserMap;
  project_map: ProjectMap;
  assignments: AssignmentsMap;
}

interface StudentsPanelReduxProps {
  expanded_students: Set<string>;
  active_student_sort?: SortDescription;
  get_student_name: (id: string) => string;
  active_feedback_edits: IsGradingMap;
}

interface StudentsPanelState {
  err?: string;
  search: string;
  add_search: string;
  add_searching: boolean;
  add_select?: any;
  existing_students?: any;
  selected_option_nodes?: any;
  show_deleted: boolean;
}

export const StudentsPanel = rclass<StudentsPanelReactProps>(
  class StudentsPanel extends Component<
    StudentsPanelReactProps & StudentsPanelReduxProps,
    StudentsPanelState
  > {
    // student_list not a list, but has one, plus some extra info.
    private student_list:
      | {
          students: any[];
          num_omitted: number;
          num_deleted: number;
        }
      | undefined = undefined;

    constructor(props) {
      super(props);
      this.state = {
        err: undefined,
        search: "",
        add_search: "",
        add_searching: false,
        add_select: undefined,
        existing_students: undefined,
        selected_option_nodes: undefined,
        show_deleted: false
      };
    }

    displayName: "CourseEditorStudents";

    static reduxProps = ({ name }) => {
      return {
        [name]: {
          expanded_students: rtypes.immutable.Set,
          active_student_sort: rtypes.immutable.Map,
          get_student_name: rtypes.func,
          active_feedback_edits: rtypes.immutable.Map
        }
      };
    };
{'fraction_non_alphanumeric': 0.13998675204239347, 'fraction_numerical': 0.003974387281960698, 'mean_word_length': 3.3241050119331743, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 15, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, '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': '660383', 'n_tokens_mistral': 2651, 'n_tokens_neox': 2601, 'n_words': 782}