<commit_before>define('learning_resources', [
  'reactaddons', 'jquery', 'lodash', 'utils'], function (
  React, $, _, Utils) {
  'use strict';

  var StatusBox = Utils.StatusBox;

  var VocabularyOption = React.createClass({
    render: function () {
      var options = _.map(this.props.terms, function (term) {
        return <option key={term.slug}
                       value={term.slug}>
          {term.label}
        </option>;
      });

      return <div className="form-group">
        <label className="col-sm-6 control-label">
        {this.props.vocabulary.name}
          </label>
        <div className="col-sm-6">
          <select className="form-control" value={this.props.selectedTerm}
            onChange={this.handleChange}>
            <option key="" value=""></option>
            {options}
          </select>
        </div>
      </div>;
    },
    handleChange: function(e) {
      this.props.updateTerm(this.props.vocabulary.slug, e.target.value);
    }
  });

  var LearningResourcePanel = React.createClass({
    mixins: [React.addons.LinkedStateMixin],
    render: function () {
      var thiz = this;
      var vocabulariesAndTerms = this.state.vocabulariesAndTerms;
      var options = _.map(vocabulariesAndTerms, function (pair) {
        var updateTerm = function(vocabSlug, newTermSlug) {
          var newVocabulariesAndTerms = _.map(vocabulariesAndTerms,
            function(tuple) {
              if (vocabSlug === tuple.vocabulary.slug) {
                return {
                  vocabulary: tuple.vocabulary,
                  terms: tuple.terms,
                  selectedTerm: newTermSlug
                };
              } else {
                return tuple;
              }
            });

          thiz.setState({
            vocabulariesAndTerms: newVocabulariesAndTerms
          });
        };

        return <VocabularyOption
          vocabulary={pair.vocabulary}
          terms={pair.terms}
          selectedTerm={pair.selectedTerm}
          key={pair.vocabulary.slug}
          updateTerm={updateTerm}
          />;
      });

      return <div>
        <form className="form-horizontal">
          <StatusBox message={this.state.message} />
          <textarea className="form-control textarea-xml"
                    valueLink={this.linkState('contentXml')}
            />

          <p className="text-right">
            <a id="copy-textarea-xml" href="#"
               className="btn btn-white"
               onClick={this.selectXml}>Select XML</a>
            <a className="btn btn-primary pull-left"
               href={this.state.previewUrl} target="_blank">Preview</a>
          </p>

          {options}
          <div className="form-group form-desc">
            <label className="col-sm-12 control-label">Description</label>
              <textarea
                className="form-control col-sm-12 textarea-desc"
                valueLink={this.linkState('description')}>
              </textarea>
          </div>
          <p>
            <button className="btn btn-lg btn-primary"
                    onClick={this.saveForm}>
              Save
            </button>
          </p>
        </form>
      </div>;
    },
    selectXml: function (event) {
      event.preventDefault();
      $('.textarea-xml').select();
    },
    saveForm: function (event) {
      event.preventDefault();
      var thiz = this;

      var terms = _.map(this.state.vocabulariesAndTerms, function (tuple) {
          return tuple.selectedTerm;
        });
      terms = _.filter(terms, function(selectedTerm) {
        return selectedTerm;
      });

      var data = {
        terms: terms,
        description: this.state.description
      };

      $.ajax({
        url: "/api/v1/repositories/" + this.props.repoSlug +
        "/learning_resources/" +
        this.props.learningResourceId + "/",
        type: "PATCH",
        contentType: 'application/json',
        data: JSON.stringify(data)
      }).done(function () {
        thiz.setState({
          message: "Form saved successfully!"
        });
      }).fail(function () {
        thiz.setState({
          message: {error: "Unable to save form"}
        });
      });
    },
    componentDidMount: function () {
      var thiz = this;

      $.get("/api/v1/repositories/" + this.props.repoSlug +
        "/learning_resources/" +
        this.props.learningResourceId + "/").done(function (data) {
        if (!thiz.isMounted()) {
          // In time AJAX call happens component may become unmounted
          return;
        }

        var contentXml = data.content_xml;
        var learningResourceType = data.learning_resource_type;
        var description = data.description;
        var selectedTerms = data.terms;
        var previewUrl = data.preview_url;

        thiz.setState({
          contentXml: contentXml,
          message: undefined,
          description: description,
          previewUrl: previewUrl,
        });

        Utils.getVocabulariesAndTerms(
          thiz.props.repoSlug, learningResourceType)
          .then(function (results) {
          if (!thiz.isMounted()) {
            // In time AJAX call happens component may become unmounted
            return;
          }

          var vocabulariesAndTerms = _.map(results,
            function(tuple) {
              var vocabulary = tuple.vocabulary;
              var terms = tuple.terms;

              var selectedTerm = _.result(_.find(terms, function(term) {
                return _.includes(selectedTerms, term.slug);
              }), 'slug');

              return {
                vocabulary: vocabulary,
                terms: terms,
                selectedTerm: selectedTerm
              };
            });

          thiz.setState({
            vocabulariesAndTerms: vocabulariesAndTerms
          });
        }).fail(function () {
          thiz.setState({
            message: {
              error: "Unable to read information about learning resource."
            }
          });
        });

      }).fail(function () {
          thiz.setState({
            message: {
              error: "Unable to read information about learning resource."
            }
          });
        });
    },
    getInitialState: function () {
      return {
        contentXml: "",
        description: "",
        vocabulariesAndTerms: []
      };
    }
  });

  return {
    VocabularyOption: VocabularyOption,
    LearningResourcePanel: LearningResourcePanel,
    loader: function (repoSlug, learningResourceId, container) {
      // Unmount and remount the component to ensure that its state
      // is always up to date with the rest of the app.
      React.unmountComponentAtNode(container);
      React.render(<LearningResourcePanel
        repoSlug={repoSlug} learningResourceId={learningResourceId}
        />, container);
    }
  };
});
<commit_msg>Made XML preview box for a LearningResource should be read only<commit_after>define('learning_resources', [
  'reactaddons', 'jquery', 'lodash', 'utils'], function (
  React, $, _, Utils) {
  'use strict';

  var StatusBox = Utils.StatusBox;

  var VocabularyOption = React.createClass({
    render: function () {
      var options = _.map(this.props.terms, function (term) {
        return <option key={term.slug}
                       value={term.slug}>
          {term.label}
        </option>;
      });

      return <div className="form-group">
        <label className="col-sm-6 control-label">
        {this.props.vocabulary.name}
          </label>
        <div className="col-sm-6">
          <select className="form-control" value={this.props.selectedTerm}
            onChange={this.handleChange}>
            <option key="" value=""></option>
            {options}
          </select>
        </div>
      </div>;
    },
    handleChange: function(e) {
      this.props.updateTerm(this.props.vocabulary.slug, e.target.value);
    }
  });

  var LearningResourcePanel = React.createClass({
    mixins: [React.addons.LinkedStateMixin],
    render: function () {
      var thiz = this;
      var vocabulariesAndTerms = this.state.vocabulariesAndTerms;
      var options = _.map(vocabulariesAndTerms, function (pair) {
        var updateTerm = function(vocabSlug, newTermSlug) {
          var newVocabulariesAndTerms = _.map(vocabulariesAndTerms,
            function(tuple) {
              if (vocabSlug === tuple.vocabulary.slug) {
                return {
                  vocabulary: tuple.vocabulary,
                  terms: tuple.terms,
                  selectedTerm: newTermSlug
                };
              } else {
                return tuple;
              }
            });

          thiz.setState({
            vocabulariesAndTerms: newVocabulariesAndTerms
          });
        };

        return <VocabularyOption
          vocabulary={pair.vocabulary}
          terms={pair.terms}
          selectedTerm={pair.selectedTerm}
          key={pair.vocabulary.slug}
          updateTerm={updateTerm}
          />;
      });

      return <div>
        <form className="form-horizontal">
          <StatusBox message={this.state.message} />
          <textarea className="form-control textarea-xml"
                    readOnly="true"
                    valueLink={this.linkState('contentXml')}
            />

          <p className="text-right">
            <a id="copy-textarea-xml" href="#"
               className="btn btn-white"
               onClick={this.selectXml}>Select XML</a>
            <a className="btn btn-primary pull-left"
               href={this.state.previewUrl} target="_blank">Preview</a>
          </p>

          {options}
          <div className="form-group form-desc">
            <label className="col-sm-12 control-label">Description</label>
              <textarea
                className="form-control col-sm-12 textarea-desc"
                valueLink={this.linkState('description')}>
              </textarea>
          </div>
          <p>
            <button className="btn btn-lg btn-primary"
                    onClick={this.saveForm}>
              Save
            </button>
          </p>
        </form>
      </div>;
    },
    selectXml: function (event) {
      event.preventDefault();
      $('.textarea-xml').select();
    },
    saveForm: function (event) {
      event.preventDefault();
      var thiz = this;

      var terms = _.map(this.state.vocabulariesAndTerms, function (tuple) {
          return tuple.selectedTerm;
        });
      terms = _.filter(terms, function(selectedTerm) {
        return selectedTerm;
      });

      var data = {
        terms: terms,
        description: this.state.description
      };

      $.ajax({
        url: "/api/v1/repositories/" + this.props.repoSlug +
        "/learning_resources/" +
        this.props.learningResourceId + "/",
        type: "PATCH",
        contentType: 'application/json',
        data: JSON.stringify(data)
      }).done(function () {
        thiz.setState({
          message: "Form saved successfully!"
        });
      }).fail(function () {
        thiz.setState({
          message: {error: "Unable to save form"}
        });
      });
    },
    componentDidMount: function () {
      var thiz = this;

      $.get("/api/v1/repositories/" + this.props.repoSlug +
        "/learning_resources/" +
        this.props.learningResourceId + "/").done(function (data) {
        if (!thiz.isMounted()) {
          // In time AJAX call happens component may become unmounted
          return;
        }

        var contentXml = data.content_xml;
        var learningResourceType = data.learning_resource_type;
        var description = data.description;
        var selectedTerms = data.terms;
        var previewUrl = data.preview_url;

        thiz.setState({
          contentXml: contentXml,
          message: undefined,
          description: description,
          previewUrl: previewUrl,
        });

        Utils.getVocabulariesAndTerms(
          thiz.props.repoSlug, learningResourceType)
          .then(function (results) {
          if (!thiz.isMounted()) {
            // In time AJAX call happens component may become unmounted
            return;
          }

          var vocabulariesAndTerms = _.map(results,
            function(tuple) {
              var vocabulary = tuple.vocabulary;
              var terms = tuple.terms;

              var selectedTerm = _.result(_.find(terms, function(term) {
                return _.includes(selectedTerms, term.slug);
              }), 'slug');

              return {
                vocabulary: vocabulary,
                terms: terms,
                selectedTerm: selectedTerm
              };
            });

          thiz.setState({
            vocabulariesAndTerms: vocabulariesAndTerms
          });
        }).fail(function () {
          thiz.setState({
            message: {
              error: "Unable to read information about learning resource."
            }
          });
        });

      }).fail(function () {
          thiz.setState({
            message: {
              error: "Unable to read information about learning resource."
            }
          });
        });
    },
    getInitialState: function () {
      return {
        contentXml: "",
        description: "",
        vocabulariesAndTerms: []
      };
    }
  });

  return {
    VocabularyOption: VocabularyOption,
    LearningResourcePanel: LearningResourcePanel,
    loader: function (repoSlug, learningResourceId, container) {
      // Unmount and remount the component to ensure that its state
      // is always up to date with the rest of the app.
      React.unmountComponentAtNode(container);
      React.render(<LearningResourcePanel
        repoSlug={repoSlug} learningResourceId={learningResourceId}
        />, container);
    }
  };
});

{'fraction_non_alphanumeric': 0.11837353748374982, 'fraction_numerical': 0.0011555683952043912, 'mean_word_length': 1.731163708086785, 'pattern_counts': {'":': 0, '<': 75, '<?xml version=': 0, '>': 75, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 8}, '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': '4809115', 'n_tokens_mistral': 3799, 'n_tokens_neox': 3728, 'n_words': 743}