<commit_before>import React from "react";
import CX from "classnames";
import PropTypes from "prop-types";
import { map, sortBy } from "lodash-es";
import { Badge, ListGroup } from "react-bootstrap";
import { connect } from "react-redux";

import { byteSize } from "../../utils";
import { hideUploadOverlay } from "../actions";
import { Flex, FlexItem, ListGroupItem, ProgressBar } from "../../base";

const UploadItem = ({ localId, name, progress, size}) => (
    <ListGroupItem key={localId}>
        <ProgressBar bsStyle={progress === 100 ? "primary" : "success"} now={progress} affixed />
        <Flex>
            <FlexItem grow={1}>
                {name}
            </FlexItem>
            <FlexItem shrink={0} grow={0} pad={15}>
                {byteSize(size)}
            </FlexItem>
        </Flex>
    </ListGroupItem>
);

class UploadOverlay extends React.Component {

    componentWillReceiveProps (nextProps) {
        if (nextProps.uploadsComplete !== this.props.uploadsComplete && nextProps.uploadsComplete) {
            window.removeEventListener("beforeunload", this.handlePageLeave);
        } else if (nextProps.uploadsComplete !== this.props.uploadsComplete && !nextProps.uploadsComplete) {
            window.addEventListener("beforeunload", this.handlePageLeave);
        }
    }

    handlePageLeave = (e) => {
        const message = "Upload(s) still in progress";
        e.returnValue = message;
        return message;
    };

    render () {

        const classNames = CX("upload-overlay", {hidden: !this.props.showUploadOverlay});
        const uploadComponents = map(sortBy(this.props.uploads, "progress").reverse(), upload =>
            upload.progress === 100 ? <div key={upload.localId} /> : <UploadItem key={upload.localId} {...upload} />
        );

        const content = this.props.uploadsComplete ? null : (
            <div className={classNames}>
                <div className="upload-overlay-content">
                    <h5>
                        <span>
                            <strong>Uploads</strong> <Badge>{uploadComponents.length}</Badge>
                        </span>
                        <button type="button" className="close pullRight" onClick={this.props.onClose}>
                            <span>&times;</span>
                        </button>
                    </h5>
                    <ListGroup style={{height: "auto", maxHeight: "175px", overflowX: "hidden"}}>
                        {uploadComponents}
                    </ListGroup>
                </div>
            </div>
        );

        return <div>{content}</div>;
    }
}

UploadOverlay.propTypes = {
    uploads: PropTypes.arrayOf(PropTypes.object),
    showUploadOverlay: PropTypes.bool,
    uploadsComplete: PropTypes.bool,
    onClose: PropTypes.func
};
<commit_msg>Fix upload list<commit_after>import React from "react";
import CX from "classnames";
import PropTypes from "prop-types";
import { map, sortBy } from "lodash-es";
import { Badge, ListGroup } from "react-bootstrap";
import { connect } from "react-redux";

import { byteSize } from "../../utils";
import { hideUploadOverlay } from "../actions";
import { Flex, FlexItem, ListGroupItem, ProgressBar } from "../../base";

const UploadItem = ({ localId, name, progress, size}) => (
    <ListGroupItem key={localId}>
        <ProgressBar bsStyle={progress === 100 ? "primary" : "success"} now={progress} affixed />
        <Flex>
            <FlexItem grow={1}>
                {name}
            </FlexItem>
            <FlexItem shrink={0} grow={0} pad={15}>
                {byteSize(size)}
            </FlexItem>
        </Flex>
    </ListGroupItem>
);

class UploadOverlay extends React.Component {

    componentWillReceiveProps (nextProps) {
        if (nextProps.uploadsComplete !== this.props.uploadsComplete && nextProps.uploadsComplete) {
            window.removeEventListener("beforeunload", this.handlePageLeave);
        } else if (nextProps.uploadsComplete !== this.props.uploadsComplete && !nextProps.uploadsComplete) {
            window.addEventListener("beforeunload", this.handlePageLeave);
        }
    }

    handlePageLeave = (e) => {
        const message = "Upload(s) still in progress";
        e.returnValue = message;
        return message;
    };

    render () {

        const classNames = CX("upload-overlay", {hidden: !this.props.showUploadOverlay});
        const uploadComponents = [];

        map(sortBy(this.props.uploads, "progress").reverse(), upload => {
            if (upload.progress !== 100) {
                uploadComponents.push(<UploadItem key={upload.localId} {...upload} />);
            }
            return upload;
        });

        const content = this.props.uploadsComplete ? null : (
            <div className={classNames}>
                <div className="upload-overlay-content">
                    <h5>
                        <span>
                            <strong>Uploads</strong> <Badge>{uploadComponents.length}</Badge>
                        </span>
                        <button type="button" className="close pullRight" onClick={this.props.onClose}>
                            <span>&times;</span>
                        </button>
                    </h5>
                    <ListGroup style={{height: "auto", maxHeight: "175px", overflowX: "hidden"}}>
                        {uploadComponents}
                    </ListGroup>
                </div>
            </div>
        );

        return <div>{content}</div>;
    }
}

UploadOverlay.propTypes = {
    uploads: PropTypes.arrayOf(PropTypes.object),
    showUploadOverlay: PropTypes.bool,
    uploadsComplete: PropTypes.bool,
    onClose: PropTypes.func
};

{'fraction_non_alphanumeric': 0.13680154142581888, 'fraction_numerical': 0.005605184795936241, 'mean_word_length': 2.078167115902965, 'pattern_counts': {'":': 0, '<': 64, '<?xml version=': 0, '>': 70, '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': '1781814', 'n_tokens_mistral': 1567, 'n_tokens_neox': 1485, 'n_words': 325}