<commit_before>import React from 'react';
import ReactDOM from 'react-dom';
import AuthStore from '../stores/AuthStore';
import MZBenchActions from '../actions/MZBenchActions';
import MZBenchWS from '../utils/MZBenchWS';
import Modal from './Modal.react';
import Menu, {SubMenu, MenuItem} from 'rc-menu';
import MZBenchRouter from '../utils/MZBenchRouter';
import LoadingSpinner from './LoadingSpinner.react';

class Auth extends React.Component {
    constructor(props) {
        super(props);
        this.state = this._resolveState();
        this.mounted = false;
        this._onChange = this._onChange.bind(this);
    }

    componentDidMount() {
        $(ReactDOM.findDOMNode(this.refs.authModal)).modal({backdrop: "static", show: true});
        this.mounted = true;
        AuthStore.onChange(this._onChange);
    }

    componentWillUnmount() {
        AuthStore.off(this._onChange);
        this.serverRequest.abort();
        MZBenchActions.unsubscribeBenchTimeline();
    }

    open() {
        $(ReactDOM.findDOMNode(this.refs.authModal)).modal("show");
    }

    close() {
        $(ReactDOM.findDOMNode(this.refs.authModal)).modal("hide");
    }

    _onChange() {
        this.setState(this._resolveState());
    }

    onSignOut(event) {
        let type = AuthStore.authType();
        event.preventDefault();

        if ("google2" == type) {
            let auth2 = window.gapi.auth2.getAuthInstance();
            auth2.signOut();
        }

        AuthStore.signOut();
    }

    onCreateToken(event) {
        event.preventDefault();
        $(ReactDOM.findDOMNode(this.refs.createTokenModal)).modal("show");
        this.setState({generatedToken: ""});
    }

    render() {
        let login = this.state.userLogin;
        let methods = this.state.supportedMethods;
        let modalWindow = (<div ref="authModal" className="modal fade">
                    <div className="modal-sign-in-dialog">
                        <div className="modal-content">
                            <div className="modal-header">
                                <h4 className="modal-title sign-in-header">{this.props.title}</h4>
                            </div>

                            <div className="modal-body">
                                {methods && methods.google ? <button type="button" className="btn btn-block btn-social btn-google" onClick={(event) => {event.preventDefault(); AuthStore.onGoogleSigninReq();}}>Google</button> : null}
                                {methods && methods.github ? <button type="button" className="btn btn-block btn-social btn-github" onClick={(event) => {event.preventDefault(); AuthStore.onGithubSigninReq(methods.github.url, methods.github.id);}}>GitHub</button> : null}
                            </div>
                        </div>
                    </div>
                </div>)

        let tokenGenWindow =
                (<Modal ref="createTokenModal" title="Generate a token for CLI utilites">
                    {this.state.generatedToken ?
                        <div className="auth-token-modal">
                            <p>Your secret token:</p> <pre>{this.state.generatedToken}</pre>
                            <p>Please copy-paste it to ~/.config/mzbench/token file in your home directory</p>
                        </div> :
                        <div className="auth-token-modal">
                            How long do you want the token to be valid:
                            <select ref="validTime" defaultValue="86400">
                                <option value="3600">an hour</option>
                                <option value="86400">a day</option>
                                <option value="2592000">a month</option>
                                <option value="31536000">a year</option>
                                <option value="0">forever</option>
                            </select>&nbsp;
                            <button type="button" className="btn btn-primary btn-sm" onClick={this.onGenerateToken.bind(this)}>Generate</button>
                        </div>
                    }
                </Modal>)
        return (
            <div>
                { (login != "") && (login != "anonymous") ?
                  <table className="signed-in-user-table"><tbody>
                    <tr><td>{this.state.userPic != "" ? <img src={this.state.userPic} height="38px"/> : null}</td>
                    <td>
                        <Menu mode='horizontal' openAnimation='slide-up'>
                           <SubMenu title={this.state.userName != "" ? this.state.userName : this.state.userLogin}>
                            <MenuItem>
                                <div><a href="#" onClick={this.onCreateToken.bind(this)}>Generate token</a></div>
                            </MenuItem>
                            <MenuItem>
                                <div><a href="#" onClick={this.onSignOut.bind(this)}>Sign out</a></div>
                            </MenuItem>
                          </SubMenu>
                        </Menu>
                    </td></tr>
                  </tbody></table> : null}
                {modalWindow}
                {tokenGenWindow}
                {methods == null && login == "" ? <LoadingSpinner>Loading...</LoadingSpinner> :
                    (login != "" ? this.props.children : null)}
            </div>
        );
    }

    onGenerateToken() {
        let tokenLifetime = this.refs.validTime.value;
        AuthStore.requestToken(tokenLifetime);
    }

    _resolveState() {
        let needShowSignIn = AuthStore.isAuthRequired();
        if (this.mounted) {
            needShowSignIn ? this.open() : this.close();
        }
        let support = AuthStore.supportedAuthMethods();


        return {
            supportedMethods: support,
            userLogin: AuthStore.userLogin(),
            userName: AuthStore.userName(),
            userPic: AuthStore.userPic(),
            generatedToken: AuthStore.getGeneratedToken()
        };
    }
};

Auth.propTypes = {
    title: React.PropTypes.string,
    onOk: React.PropTypes.func
};<commit_msg>Add spinner for signing in<commit_after>import React from 'react';
import ReactDOM from 'react-dom';
import AuthStore from '../stores/AuthStore';
import MZBenchActions from '../actions/MZBenchActions';
import MZBenchWS from '../utils/MZBenchWS';
import Modal from './Modal.react';
import Menu, {SubMenu, MenuItem} from 'rc-menu';
import MZBenchRouter from '../utils/MZBenchRouter';
import LoadingSpinner from './LoadingSpinner.react';

class Auth extends React.Component {
    constructor(props) {
        super(props);
        this.state = this._resolveState();
        this.state.wait_resp = false;
        this._onChange = this._onChange.bind(this);
        this.onAuthReq = this.onAuthReq.bind(this);
    }

    componentDidMount() {
        $(ReactDOM.findDOMNode(this.refs.authModal)).modal({backdrop: "static", show: true});
        AuthStore.onChange(this._onChange);
    }

    componentWillUnmount() {
        AuthStore.off(this._onChange);
        this.serverRequest.abort();
        MZBenchActions.unsubscribeBenchTimeline();
    }

    componentDidUpdate(oldProps, oldState) {
        this.state.authRequired ? this.open() : this.close();
    }

    open() {
        $(ReactDOM.findDOMNode(this.refs.authModal)).modal("show");
    }

    close() {
        $(ReactDOM.findDOMNode(this.refs.authModal)).modal("hide");
    }

    _onChange() {
        let s = this._resolveState();
        if (!this.state.authRequired && s.authRequired) s.wait_resp = false;
        this.setState(s);
    }

    onAuthReq(event, type) {
        event.preventDefault();
        this.setState({wait_resp: true});
        if (type == "google") {
            AuthStore.onGoogleSigninReq();
        } else if (type == "github") {
            let methods = this.state.supportedMethods;
            AuthStore.onGithubSigninReq(methods.github.url, methods.github.id);
        }
    }

    onSignOut(event) {
        let type = AuthStore.authType();
        event.preventDefault();

        if ("google2" == type) {
            let auth2 = window.gapi.auth2.getAuthInstance();
            auth2.signOut();
        }

        AuthStore.signOut();
    }

    onCreateToken(event) {
        event.preventDefault();
        $(ReactDOM.findDOMNode(this.refs.createTokenModal)).modal("show");
        this.setState({generatedToken: ""});
    }

    render() {
        let login = this.state.userLogin;
        let methods = this.state.supportedMethods;
        let modalWindow = (<div ref="authModal" className="modal fade">
                    <div className="modal-sign-in-dialog">
                        {
                            (!this.state.wait_resp) ?
                            <div className="modal-content">
                                <div className="modal-header">
                                    <h4 className="modal-title sign-in-header">{this.props.title}</h4>
                                </div>
                                <div className="modal-body">
                                    {methods && methods.google ? <button type="button" className="btn btn-block btn-social btn-google" onClick={(e) => this.onAuthReq(e, "google")}>Google</button> : null}
                                    {methods && methods.github ? <button type="button" className="btn btn-block btn-social btn-github" onClick={(e) => this.onAuthReq(e, "github")}>GitHub</button> : null}
                                </div>
                            </div> :
                            <div className="modal-content">
                                <div className="modal-header">
                                    <h4 className="modal-title sign-in-header">Signing in</h4>
                                </div>
                                <div className="modal-body text-center">
                                    <span className="glyphicon glyphicon-refresh glyphicon-spin"></span>
                                </div>
                            </div>
                        }
                    </div>
                </div>)

        let tokenGenWindow =
                (<Modal ref="createTokenModal" title="Generate a token for CLI utilites">
                    {this.state.generatedToken ?
                        <div className="auth-token-modal">
                            <p>Your secret token:</p> <pre>{this.state.generatedToken}</pre>
                            <p>Please copy-paste it to ~/.config/mzbench/token file in your home directory</p>
                        </div> :
                        <div className="auth-token-modal">
                            How long do you want the token to be valid:
                            <select ref="validTime" defaultValue="86400">
                                <option value="3600">an hour</option>
                                <option value="86400">a day</option>
                                <option value="2592000">a month</option>
                                <option value="31536000">a year</option>
                                <option value="0">forever</option>
                            </select>&nbsp;
                            <button type="button" className="btn btn-primary btn-sm" onClick={this.onGenerateToken.bind(this)}>Generate</button>
                        </div>
                    }
                </Modal>)
        return (
            <div>
                { (login != "") && (login != "anonymous") ?
                  <table className="signed-in-user-table"><tbody>
                    <tr><td>{this.state.userPic != "" ? <img src={this.state.userPic} height="38px"/> : null}</td>
                    <td>
                        <Menu mode='horizontal' openAnimation='slide-up'>
                           <SubMenu title={this.state.userName != "" ? this.state.userName : this.state.userLogin}>
                            <MenuItem>
                                <div><a href="#" onClick={this.onCreateToken.bind(this)}>Generate token</a></div>
                            </MenuItem>
                            <MenuItem>
                                <div><a href="#" onClick={this.onSignOut.bind(this)}>Sign out</a></div>
                            </MenuItem>
                          </SubMenu>
                        </Menu>
                    </td></tr>
                  </tbody></table> : null}
                {modalWindow}
                {tokenGenWindow}
                {methods == null && login == "" ? <LoadingSpinner>Loading...</LoadingSpinner> :
                    (login != "" ? this.props.children : null)}
            </div>
        );
    }

    onGenerateToken() {
        let tokenLifetime = this.refs.validTime.value;
        AuthStore.requestToken(tokenLifetime);
    }

    _resolveState() {
        return {
            authRequired: AuthStore.isAuthRequired(),
            supportedMethods: AuthStore.supportedAuthMethods(),
            userLogin: AuthStore.userLogin(),
            userName: AuthStore.userName(),
            userPic: AuthStore.userPic(),
            generatedToken: AuthStore.getGeneratedToken()
        };
    }
};

Auth.propTypes = {
    title: React.PropTypes.string,
    onOk: React.PropTypes.func
};
{'fraction_non_alphanumeric': 0.1315532888322208, 'fraction_numerical': 0.005850146253656341, 'mean_word_length': 1.5524502297090352, 'pattern_counts': {'":': 0, '<': 159, '<?xml version=': 0, '>': 163, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7239643', 'n_tokens_mistral': 3555, 'n_tokens_neox': 3395, 'n_words': 614}