<commit_before><script type='text/jsx'>
  /** @jsx React.DOM */

  var FileTable = React.createClass({
    propTypes: {
      // Ensures that components are being used correctly
      columns: React.PropTypes.array
    },

    getDefaultProps: function() {
      // Defines the columns used for the table and whether they
      // are sortable searchable. The default initially sorted
      // column is the first sortable column in the array.
      return {
        columns: [
          {
            id: 'file_name',
            content: '<%= j raw I18n.t(:'browse_submissions.filename') %>',
            sortable: true,
            compare: compare_anchor_text
          },
          {
            id: 'last_modified_date',
            content: '<%= j raw I18n.t(:'browse_submissions.last_revised') %>',
            sortable: true
          },
          {
            id: 'revision_by',
            content: '<%= j raw I18n.t(:'browse_submissions.revised_by') %>',
            sortable: true
          },
        ]
      };
    },

    getInitialState: function() {
      return {
        error: null,
        files: [],
        selected_files: [],
        data_files: [],
      };
    },

    componentWillMount: function() {
      this.refresh();
    },

    updateSelectedFiles: function(files) {
      this.setState({ selected_files: files });
    },

    // Asks for new info from backend and sets props accordingly.
    refresh: function() {
      // Show working indicator.
      document.getElementById('working').style.display = '';

      this.setState({ selected_files: [] });

      jQuery.ajax({
        url: '<%= populate_file_manager_react_assignment_submissions_path %>',
        method: 'GET',
        dataType: 'json',
        success: function(data) {
          this.setState({
            files: data,
            errors: null
          });
        }.bind(this),
        error: function(xhr, status, text) {
          var error = text + ':' + xhr.responseText;
          this.setState({ error: error });
        }.bind(this),
        // Close working indicator.
        complete: function() {
          document.getElementById('working').style.display = 'none';
        }
      });
    },

    onError: function(error) {
      this.setState({ error: error });
    },

    render: function() {
      var files_data = this.state.files.map(function(file, i) {
        var f = {};

        f.id = i;
        f.file_name = file[1].name;
        f.last_modified_date = file[1].last_modified_date;
        f.revision_by = file[1].user_id;
        f.last_modified_revision = file[1].last_modified_revision;

        return f;
      }.bind(this));

      return (
        <div>
          <% unless !@grouping.is_valid? || @grouping.repository_external_commits_only? %>
            <FileManagerActionBox
              selected_files={this.state.selected_files}
              data_file={files_data}
              onError={this.onError}
              parentRefresh={this.refresh.bind(this)} />
          <% end %>

          <Table data={files_data}
            columns={this.props.columns}
            selectable={true}
            onSelectedRowsChange={this.updateSelectedFiles} />

          <ErrorDiv error={this.state.error} />
        </div>
      );
    }
  });

  var FileManagerActionBox = React.createClass({
    propTypes: {
      selected_files: React.PropTypes.array,
      data_file: React.PropTypes.array
    },

    accessById: function(id) {
      var data_file = this.props.data_file;
      for (var i = 0; i < data_file.length; i++) {
        if (data_file[i].id === id) {
          return data_file[i];
        }
      }
    },

    accessThroughArray: function() {
      return this.props.selected_files.map(function(id) {
        return this.accessById(id).file_name;
      }.bind(this));
    },

    getFileRevisions: function() {
      var revs = {}

      this.props.selected_files.forEach(function(id) {
        var file = this.accessById(id);
        revs[file.file_name] = file.last_modified_revision;
      }.bind(this));

      return revs;
    },

    deleteFiles: function(e) {
      e.preventDefault();

      var delete_file = this.accessThroughArray();
      var file_revisions = this.getFileRevisions();
      jQuery.ajax({
        url: '<%= update_files_assignment_submissions_path(@assignment.id) %>',
        method: 'POST',
        data: {
          delete_files: delete_file,
          file_revisions: file_revisions
        },
        success: function(data) {
          this.props.parentRefresh();
        }.bind(this),
        error: function(xhr, status, text) {
          var error = text + ': ' + xhr.responseText;
          this.props.onError(error);
        }.bind(this)
      });
    },

    openModal: function(e) {
      e.preventDefault();
      <% if (@grouping.is_valid? && !@grouping.repository_external_commits_only?) %>
        modal_addnew.open();
        set_onbeforeunload(true);
      <% end %>
    },

    render: function() {
      return (
        <div className='react_buttons'>
          <button onClick={this.openModal}>
            <%= j raw I18n.t('add_new') %>
          </button>
          <button onClick={this.deleteFiles}>
            <%= j raw I18n.t('delete') %>
          </button>
        </div>
      );
    }
  });

  React.renderComponent(<FileTable/>, document.getElementById('file_table'));
</script>

<script type='text/javascript'>
//<![CDATA[

  /*
   * Do the same as what would be done server side in terms
   * of filename sanitation. Warn the user what would happen
   * if submit is pressed.
   * See also: public/javascripts/file_manager.js
   */
  function sanitized_filename_check(file_input) {
    var file_name = file_input.value.replace(/^.*[\\\/]/, '');
    var sanitized_filename = file_name.replace(/<%= SubmissionFile::FILENAME_SANITIZATION_REGEXP.source %>/g,
      '<%= SubmissionFile::SUBSTITUTION_CHAR %>');
    if (file_name !== sanitized_filename) {
      var msg = <%= raw(I18n.t('student.submission.filename_sanitization_js_warning')) %>;
      if (!confirm(msg)) {
        file_input.value = '';
      };
    }
  }

  /*
   * Check that new_file_name is the same as file_name. Otherwise
   * refuse to accept the new filename. Note that this is called
   * on the replace file upload button.
   * See also: public/javascripts/file_manager.js
   */
  function check_change_of_filename(file_name, new_file_name, file_input) {
    var new_file_name = normalize_filename(new_file_name);
    if (file_name !== new_file_name) {
      alert(<%= raw(I18n.t('student.submission.replace_file_js_error')) %>);
      file_input.value = '';
    }
  }
//]]>
</script>
<commit_msg>file-manager: reset checkboxes on delete<commit_after><script type='text/jsx'>
  /** @jsx React.DOM */

  var FileTable = React.createClass({
    propTypes: {
      // Ensures that components are being used correctly
      columns: React.PropTypes.array
    },

    getDefaultProps: function() {
      // Defines the columns used for the table and whether they
      // are sortable searchable. The default initially sorted
      // column is the first sortable column in the array.
      return {
        columns: [
          {
            id: 'file_name',
            content: '<%= j raw I18n.t(:'browse_submissions.filename') %>',
            sortable: true,
            compare: compare_anchor_text
          },
          {
            id: 'last_modified_date',
            content: '<%= j raw I18n.t(:'browse_submissions.last_revised') %>',
            sortable: true
          },
          {
            id: 'revision_by',
            content: '<%= j raw I18n.t(:'browse_submissions.revised_by') %>',
            sortable: true
          },
        ]
      };
    },

    getInitialState: function() {
      return {
        error: null,
        files: [],
        selected_files: [],
        data_files: [],
      };
    },

    componentWillMount: function() {
      this.refresh();
    },

    updateSelectedFiles: function(files) {
      this.setState({ selected_files: files });
    },

    // Asks for new info from backend and sets props accordingly.
    refresh: function() {
      // Show working indicator.
      document.getElementById('working').style.display = '';

      this.setState({ selected_files: [] });

      jQuery.ajax({
        url: '<%= populate_file_manager_react_assignment_submissions_path %>',
        method: 'GET',
        dataType: 'json',
        success: function(data) {
          this.setState({
            files: data,
            errors: null
          });
        }.bind(this),
        error: function(xhr, status, text) {
          var error = text + ':' + xhr.responseText;
          this.setState({ error: error });
        }.bind(this),
        // Close working indicator.
        complete: function() {
          document.getElementById('working').style.display = 'none';
        }
      });
    },

    onError: function(error) {
      this.setState({ error: error });
    },

    resetTable: function() {
      this.refs.table.clearCheckboxes();
      this.refresh();
    },

    render: function() {
      var files_data = this.state.files.map(function(file, i) {
        var f = {};

        f.id = i;
        f.file_name = file[1].name;
        f.last_modified_date = file[1].last_modified_date;
        f.revision_by = file[1].user_id;
        f.last_modified_revision = file[1].last_modified_revision;

        return f;
      }.bind(this));

      return (
        <div>
          <% unless !@grouping.is_valid? || @grouping.repository_external_commits_only? %>
            <FileManagerActionBox
              selected_files={this.state.selected_files}
              data_file={files_data}
              onError={this.onError}
              resetTable={this.resetTable} />
          <% end %>

          <Table data={files_data}
            columns={this.props.columns}
            selectable={true}
            onSelectedRowsChange={this.updateSelectedFiles}
            ref="table" />

          <ErrorDiv error={this.state.error} />
        </div>
      );
    }
  });

  var FileManagerActionBox = React.createClass({
    propTypes: {
      selected_files: React.PropTypes.array,
      data_file: React.PropTypes.array
    },

    accessById: function(id) {
      var data_file = this.props.data_file;
      for (var i = 0; i < data_file.length; i++) {
        if (data_file[i].id === id) {
          return data_file[i];
        }
      }
    },

    accessThroughArray: function() {
      return this.props.selected_files.map(function(id) {
        return this.accessById(id).file_name;
      }.bind(this));
    },

    getFileRevisions: function() {
      var revs = {}

      this.props.selected_files.forEach(function(id) {
        var file = this.accessById(id);
        revs[file.file_name] = file.last_modified_revision;
      }.bind(this));

      return revs;
    },

    deleteFiles: function(e) {
      e.preventDefault();

      var delete_file = this.accessThroughArray();
      var file_revisions = this.getFileRevisions();
      jQuery.ajax({
        url: '<%= update_files_assignment_submissions_path(@assignment.id) %>',
        method: 'POST',
        data: {
          delete_files: delete_file,
          file_revisions: file_revisions
        },
        success: function(data) {
          this.props.resetTable();
        }.bind(this),
        error: function(xhr, status, text) {
          var error = text + ': ' + xhr.responseText;
          this.props.onError(error);
        }.bind(this)
      });
    },

    openModal: function(e) {
      e.preventDefault();
      <% if (@grouping.is_valid? && !@grouping.repository_external_commits_only?) %>
        modal_addnew.open();
        set_onbeforeunload(true);
      <% end %>
    },

    render: function() {
      return (
        <div className='react_buttons'>
          <button onClick={this.openModal}>
            <%= j raw I18n.t('add_new') %>
          </button>
          <button onClick={this.deleteFiles}>
            <%= j raw I18n.t('delete') %>
          </button>
        </div>
      );
    }
  });

  React.renderComponent(<FileTable/>, document.getElementById('file_table'));
</script>

<script type='text/javascript'>
//<![CDATA[

  /*
   * Do the same as what would be done server side in terms
   * of filename sanitation. Warn the user what would happen
   * if submit is pressed.
   * See also: public/javascripts/file_manager.js
   */
  function sanitized_filename_check(file_input) {
    var file_name = file_input.value.replace(/^.*[\\\/]/, '');
    var sanitized_filename = file_name.replace(/<%= SubmissionFile::FILENAME_SANITIZATION_REGEXP.source %>/g,
      '<%= SubmissionFile::SUBSTITUTION_CHAR %>');
    if (file_name !== sanitized_filename) {
      var msg = <%= raw(I18n.t('student.submission.filename_sanitization_js_warning')) %>;
      if (!confirm(msg)) {
        file_input.value = '';
      };
    }
  }

  /*
   * Check that new_file_name is the same as file_name. Otherwise
   * refuse to accept the new filename. Note that this is called
   * on the replace file upload button.
   * See also: public/javascripts/file_manager.js
   */
  function check_change_of_filename(file_name, new_file_name, file_input) {
    var new_file_name = normalize_filename(new_file_name);
    if (file_name !== new_file_name) {
      alert(<%= raw(I18n.t('student.submission.replace_file_js_error')) %>);
      file_input.value = '';
    }
  }
//]]>
</script>

{'fraction_non_alphanumeric': 0.13512913490712647, 'fraction_numerical': 0.0028121068600606824, 'mean_word_length': 2.142059986049756, 'pattern_counts': {'":': 0, '<': 69, '<?xml version=': 0, '>': 67, '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': '2891334', 'n_tokens_mistral': 4181, 'n_tokens_neox': 4006, 'n_words': 785}