<commit_before>/* eslint-disable react/forbid-prop-types */
const React = require("react");
const _ = require("underscore");
const {StyleSheet, css} = require("aphrodite");

const ApiOptions = require("../perseus-api.jsx").Options;
const Changeable   = require("../mixins/changeable.jsx");
const GradedGroup = require("./graded-group.jsx").widget;
const {grayLight, gray76, tableBackgroundAccent, kaGreen, phoneMargin, negativePhoneMargin} = require("../styles/constants.js");

const Indicators = React.createClass({
    propTypes: {
        currentGroup: React.PropTypes.number.isRequired,
        numGroups: React.PropTypes.number.isRequired,
        onChangeCurrentGroup: React.PropTypes.func.isRequired,
    },
    render() {
        const items = [];
        for (let i = 0; i < this.props.numGroups; i++) {
            items.push(
                <div
                    key={i}
                    className={css(
                        styles.indicator,
                        i === this.props.currentGroup &&
                            styles.selectedIndicator
                    )}
                    onClick={() => this.props.onChangeCurrentGroup(i)}
                />
            );
        }
        return (
            <div className={css(styles.indicatorContainer)}>
                {items}
            </div>
        );
    },
});

// TODO(jared): find a better name for this :) and for GradedGroup; the names
// are currently a little confusing.
const GradedGroupSet = React.createClass({
    propTypes: {
        apiOptions: ApiOptions.propTypes,
        gradedGroups: React.PropTypes.array,
        trackInteraction: React.PropTypes.func.isRequired,
    },

    mixins: [Changeable],

    getDefaultProps() {
        return {
            gradedGroups: [],
        };
    },

    getInitialState() {
        return {
            currentGroup: 0,
        };
    },

    shouldComponentUpdate(nextProps, nextState) {
        return nextProps !== this.props || nextState !== this.state;
    },

    // Mobile API
    getInputPaths() {
        return this._childGroup.getInputPaths();
    },

    setInputValue(path, newValue, cb) {
        return this._childGroup.setInputValue(path, newValue, cb);
    },

    getAcceptableFormatsForInputPath(path) {
        return this._childGroup.getAcceptableFormatsForInputPath(path);
    },

    focus() {
        return this._childGroup.focus();
    },

    focusInputPath(path) {
        this._childGroup.focusPath(path);
    },

    blurInputPath(path) {
        this._childGroup.blurPath(path);
    },

    render() {
        const currentGroup = this.props.gradedGroups[this.state.currentGroup];
        if (!currentGroup) {
            return <span>No current group...</span>;
        }
        return <div className={css(styles.container)}>
            <div className={css(styles.top)}>
                <div className={css(styles.title)}>
                    {currentGroup.title}
                </div>
                <div className={css(styles.spacer)} />
                <Indicators
                    numGroups={this.props.gradedGroups.length}
                    currentGroup={this.state.currentGroup}
                    onChangeCurrentGroup={
                        currentGroup => this.setState({currentGroup})}
                />
            </div>
            <GradedGroup
                ref={comp => this._childGroup}
                {...this.props}
                {...currentGroup}
                transparentBackground={true}
                title={null}
            />
        </div>;
    },
});

const traverseChildWidgets = function(props, traverseRenderer) {
    // NOTE(jared): I have no idea how this works<commit_msg>Fix blur/focus issues with graded-group-set<commit_after>/* eslint-disable react/forbid-prop-types */
const React = require("react");
const _ = require("underscore");
const {StyleSheet, css} = require("aphrodite");

const ApiOptions = require("../perseus-api.jsx").Options;
const Changeable   = require("../mixins/changeable.jsx");
const GradedGroup = require("./graded-group.jsx").widget;
const {grayLight, gray76, tableBackgroundAccent, kaGreen, phoneMargin, negativePhoneMargin} = require("../styles/constants.js");

const Indicators = React.createClass({
    propTypes: {
        currentGroup: React.PropTypes.number.isRequired,
        numGroups: React.PropTypes.number.isRequired,
        onChangeCurrentGroup: React.PropTypes.func.isRequired,
    },
    render() {
        const items = [];
        for (let i = 0; i < this.props.numGroups; i++) {
            items.push(
                <div
                    key={i}
                    className={css(
                        styles.indicator,
                        i === this.props.currentGroup &&
                            styles.selectedIndicator
                    )}
                    onClick={() => this.props.onChangeCurrentGroup(i)}
                />
            );
        }
        return (
            <div className={css(styles.indicatorContainer)}>
                {items}
            </div>
        );
    },
});

// TODO(jared): find a better name for this :) and for GradedGroup; the names
// are currently a little confusing.
const GradedGroupSet = React.createClass({
    propTypes: {
        apiOptions: ApiOptions.propTypes,
        gradedGroups: React.PropTypes.array,
        trackInteraction: React.PropTypes.func.isRequired,
    },

    mixins: [Changeable],

    getDefaultProps() {
        return {
            gradedGroups: [],
        };
    },

    getInitialState() {
        return {
            currentGroup: 0,
        };
    },

    shouldComponentUpdate(nextProps, nextState) {
        return nextProps !== this.props || nextState !== this.state;
    },

    // Mobile API
    getInputPaths() {
        return this._childGroup.getInputPaths();
    },

    setInputValue(path, newValue, cb) {
        return this._childGroup.setInputValue(path, newValue, cb);
    },

    getAcceptableFormatsForInputPath(path) {
        return this._childGroup.getAcceptableFormatsForInputPath(path);
    },

    focus() {
        return this._childGroup.focus();
    },

    focusInputPath(path) {
        this._childGroup.focusInputPath(path);
    },

    blurInputPath(path) {
        this._childGroup.blurInputPath(path);
    },

    render() {
        const currentGroup = this.props.gradedGroups[this.state.currentGroup];
        if (!currentGroup) {
            return <span>No current group...</span>;
        }
        return <div className={css(styles.container)}>
            <div className={css(styles.top)}>
                <div className={css(styles.title)}>
                    {currentGroup.title}
                </div>
                <div className={css(styles.spacer)} />
                <Indicators
                    numGroups={this.props.gradedGroups.length}
                    currentGroup={this.state.currentGroup}
                    onChangeCurrentGroup={
                        currentGroup => this.setState({currentGroup})}
                />
            </div>
            <GradedGroup
                ref={comp => this._childGroup = comp}
                {...this.props}
                {...currentGroup}
                transparentBackground={true}
                title={null}
            />
        </div>;
    },
});

const traverseChildWidgets = function(props, traverseRenderer) {
    // NOTE(jared): I have no idea how this works
{'fraction_non_alphanumeric': 0.12344356674253582, 'fraction_numerical': 0.0010710938545990091, 'mean_word_length': 1.8338391502276177, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 37, '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': '6179913', 'n_tokens_mistral': 2030, 'n_tokens_neox': 1962, 'n_words': 358}