<commit_before>import * as React from "react"
import { clone } from "../clientUtils/Util"
import { computed, action, observable } from "mobx"
import { observer } from "mobx-react"
import { Grapher } from "../grapher/core/Grapher"
import {
    EditableList,
    EditableListItem,
    EditableListItemProps,
    ColorBox,
    SelectField,
    Section,
} from "./Forms"
import { ChartEditor } from "./ChartEditor"
import { faArrowsAltV } from "@fortawesome/free-solid-svg-icons/faArrowsAltV"
import { faTimes } from "@fortawesome/free-solid-svg-icons/faTimes"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { EntityName } from "../coreTable/OwidTableConstants"
import { EntitySelectionMode } from "../grapher/core/GrapherConstants"

interface EntityItemProps extends EditableListItemProps {
    grapher: Grapher
    entityName: EntityName
}

@observer
class EntityItem extends React.Component<EntityItemProps> {
    @observable.ref isChoosingColor: boolean = false

    @computed get table() {
        return this.props.grapher.table
    }

    @computed get color() {
        return this.table.getColorForEntityName(this.props.entityName)
    }

    @action.bound onColor(color: string | undefined) {
        if (!color) return

        const { grapher } = this.props
        grapher.selectedEntityColors[this.props.entityName] = color
        grapher.legacyConfigAsAuthored.selectedEntityColors = {
            ...grapher.legacyConfigAsAuthored.selectedEntityColors,
            [this.props.entityName]: color,
        }

        grapher.rebuildInputOwidTable()
    }

    @action.bound onRemove() {
        // todo
        // this.props.grapher.deselect(this.props.entityName)
    }

    render() {
        const { props, color } = this
        const { entityName, ...rest } = props

        return (
            <EditableListItem
                className="EditableListItem"
                key={entityName}
                {...rest}
            >
                <div>
                    <div>
                        <FontAwesomeIcon icon={faArrowsAltV} />
                    </div>
                    <ColorBox color={color} onColor={this.onColor} />
                    {entityName}
                </div>
                <div className="clickable" onClick={this.onRemove}>
                    <FontAwesomeIcon icon={faTimes} />
                </div>
            </EditableListItem>
        )
    }
}

@observer
class KeysSection extends React.Component<{ grapher: Grapher }> {
    @observable.ref dragKey?: EntityName

    @action.bound onAddKey(entityName: EntityName) {
        this.props.grapher.selection.selectEntity(entityName)
    }

    @action.bound onStartDrag(key: EntityName) {
        this.dragKey = key

        const onDrag = action(() => {
            this.dragKey = undefined
            window.removeEventListener("mouseup", onDrag)
        })

        window.addEventListener("mouseup", onDrag)
    }

    @action.bound onMouseEnter(targetKey: EntityName) {
        if (!this.dragKey || targetKey === this.dragKey) return

        const selectedKeys = clone(
            this.props.grapher.selection.selectedEntityNames
        )
        const dragIndex = selectedKeys.indexOf(this.dragKey)
        const targetIndex = selectedKeys.indexOf(targetKey)
        selectedKeys.splice(dragIndex, 1)
        selectedKeys.splice(targetIndex, 0, this.dragKey)
        this.props.grapher.selection.setSelectedEntities(selectedKeys)
    }

    render() {
        const { grapher } = this.props
        const { selection } = grapher
        const { unselectedEntityNames, selectedEntityNames } = selection

        return (
            <Section name="Data to show">
                <SelectField
                    onValue={this.onAddKey}
                    value="Select data"
                    options={["Select data"].concat(unselectedEntityNames)}
                    optionLabels={["Select data"].concat(unselectedEntityNames)}
                />
                <EditableList>
                    {selectedEntityNames.map((key) => (
                        <EntityItem
                            key={key}
                            grapher={grapher}
                            entityName={key}
                            onMouseDown={() => this.onStartDrag(key)}
                            onMouseEnter={() => this.onMouseEnter(key)}
                        /><commit_msg>fix(admin): removing entities from selection is possible again<commit_after>import * as React from "react"
import { clone } from "../clientUtils/Util"
import { computed, action, observable } from "mobx"
import { observer } from "mobx-react"
import { Grapher } from "../grapher/core/Grapher"
import {
    EditableList,
    EditableListItem,
    EditableListItemProps,
    ColorBox,
    SelectField,
    Section,
} from "./Forms"
import { ChartEditor } from "./ChartEditor"
import { faArrowsAltV } from "@fortawesome/free-solid-svg-icons/faArrowsAltV"
import { faTimes } from "@fortawesome/free-solid-svg-icons/faTimes"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { EntityName } from "../coreTable/OwidTableConstants"
import { EntitySelectionMode } from "../grapher/core/GrapherConstants"

interface EntityItemProps extends EditableListItemProps {
    grapher: Grapher
    entityName: EntityName
    onRemove?: () => void
}

@observer
class EntityItem extends React.Component<EntityItemProps> {
    @observable.ref isChoosingColor: boolean = false

    @computed get table() {
        return this.props.grapher.table
    }

    @computed get color() {
        return this.table.getColorForEntityName(this.props.entityName)
    }

    @action.bound onColor(color: string | undefined) {
        if (!color) return

        const { grapher } = this.props
        grapher.selectedEntityColors[this.props.entityName] = color
        grapher.legacyConfigAsAuthored.selectedEntityColors = {
            ...grapher.legacyConfigAsAuthored.selectedEntityColors,
            [this.props.entityName]: color,
        }

        grapher.rebuildInputOwidTable()
    }

    @action.bound onRemove() {
        this.props.onRemove?.()
    }

    render() {
        const { props, color } = this
        const { entityName, onRemove, ...rest } = props

        return (
            <EditableListItem
                className="EditableListItem"
                key={entityName}
                {...rest}
            >
                <div>
                    <div>
                        <FontAwesomeIcon icon={faArrowsAltV} />
                    </div>
                    <ColorBox color={color} onColor={this.onColor} />
                    {entityName}
                </div>
                <div className="clickable" onClick={this.onRemove}>
                    <FontAwesomeIcon icon={faTimes} />
                </div>
            </EditableListItem>
        )
    }
}

@observer
class KeysSection extends React.Component<{ grapher: Grapher }> {
    @observable.ref dragKey?: EntityName

    @action.bound onAddKey(entityName: EntityName) {
        this.props.grapher.selection.selectEntity(entityName)
    }

    @action.bound onStartDrag(key: EntityName) {
        this.dragKey = key

        const onDrag = action(() => {
            this.dragKey = undefined
            window.removeEventListener("mouseup", onDrag)
        })

        window.addEventListener("mouseup", onDrag)
    }

    @action.bound onMouseEnter(targetKey: EntityName) {
        if (!this.dragKey || targetKey === this.dragKey) return

        const selectedKeys = clone(
            this.props.grapher.selection.selectedEntityNames
        )
        const dragIndex = selectedKeys.indexOf(this.dragKey)
        const targetIndex = selectedKeys.indexOf(targetKey)
        selectedKeys.splice(dragIndex, 1)
        selectedKeys.splice(targetIndex, 0, this.dragKey)
        this.props.grapher.selection.setSelectedEntities(selectedKeys)
    }

    render() {
        const { grapher } = this.props
        const { selection } = grapher
        const { unselectedEntityNames, selectedEntityNames } = selection

        return (
            <Section name="Data to show">
                <SelectField
                    onValue={this.onAddKey}
                    value="Select data"
                    options={["Select data"].concat(unselectedEntityNames)}
                    optionLabels={["Select data"].concat(unselectedEntityNames)}
                />
                <EditableList>
                    {selectedEntityNames.map((entityName) => (
                        <EntityItem
                            key={entityName}
                            grapher={grapher}
                            entityName={entityName}
                            onRemove={() =>
                                selection.deselectEntity(entityName)
                            }
                            onMouseDown={() => this.onStartDrag(entityName)}
                            onMouseEnter={() => this.onMouseEnter(entityName)}
                        />
{'fraction_non_alphanumeric': 0.10391184573002755, 'fraction_numerical': 0.00044077134986225897, 'mean_word_length': 1.9457968192145407, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 47, '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': '4917371', 'n_tokens_mistral': 2472, 'n_tokens_neox': 2395, 'n_words': 453}