<commit_before>﻿
import * as React from 'react'
import { Modal, ModalProps, ModalClass, ButtonToolbar } from 'react-bootstrap'
import { openModal, IModalProps } from './Modals';
import { SelectorMessage } from './Signum.Entities'
import { TypeInfo } from './Reflection'


interface SelectorModalProps extends React.Props<SelectorModal>, IModalProps {
    options: { value: any; displayName: React.ReactChild; name: string }[];
    title: string;
    message: string;
}

export default class SelectorModal extends React.Component<SelectorModalProps, { show: boolean }>  {

    constructor(props: SelectorModalProps) {
        super(props);

        this.state = { show: true };
    }


    selectedValue: any;
    handleButtonClicked = (val: any) => {
        this.selectedValue = val;
        this.setState({ show: false });

    }

    handleCancelClicked = () => {
        this.setState({ show: false });
    }

    handleOnExited = () => {
        this.props.onExited!(this.selectedValue);
    }

    render() {
        return <Modal bsSize="sm" onHide={this.handleCancelClicked} show={this.state.show} onExited={this.handleOnExited} className="sf-selector-modal">
            <Modal.Header closeButton={true}>
                {this.props.title &&
                    <h4 className="modal-title">
                        {this.props.title}
                    </h4>
                }
            </Modal.Header>

            <Modal.Body>
                <div>
                    {this.props.message &&
                        <p>
                            {this.props.message}
                        </p>
                    }
                    {this.props.options.map((o, i) =>
                        <button key={i} type="button" onClick={() => this.handleButtonClicked(o.value) } name={o.value}
                            className="sf-chooser-button sf-close-button btn btn-default">
                            {o.displayName}
                        </button>) }
                </div>
            </Modal.Body>
        </Modal>;
    }

    static chooseElement<T>(options: T[], config?: SelectorConfig<T>): Promise<T | undefined> {

        const {display, name, title, message} = config!;

        if (options.length == 1)
            return Promise.resolve(options.single());

        if (options.length == 0)
            return Promise.resolve(undefined);

        return openModal<T>(<SelectorModal
            options={options.map(a => ({
                value: a,
                displayName: display ? display(a) : a.toString(),
                name: name ? name(a) : a.toString()
            }))}
            title={title || SelectorMessage.ChooseAValue.niceToString() }
            message={message || SelectorMessage.PleaseChooseAValueToContinue.niceToString()}/>);
    }

    static chooseType(options: TypeInfo[]): Promise<TypeInfo> {
        return SelectorModal.chooseElement(options,
            {
                display: a => a.niceName || "",
                name: a => a.name,
                title: SelectorMessage.TypeSelector.niceToString(),
                message: SelectorMessage.PleaseSelectAType.niceToString()
            });
    }
}

export interface SelectorConfig<T> {
    display?: (val: T) => React.ReactChild;
    name?: (val: T) => string; //For testing
    title?: string;
    message?: string
}


<commit_msg>SelectorModal with ReactChild<commit_after>﻿
import * as React from 'react'
import { Modal, ModalProps, ModalClass, ButtonToolbar } from 'react-bootstrap'
import { openModal, IModalProps } from './Modals';
import { SelectorMessage } from './Signum.Entities'
import { TypeInfo } from './Reflection'


interface SelectorModalProps extends React.Props<SelectorModal>, IModalProps {
    options: { value: any; displayName: React.ReactChild; name: string }[];
    title: React.ReactChild;
    message: React.ReactChild;
}

export default class SelectorModal extends React.Component<SelectorModalProps, { show: boolean }>  {

    constructor(props: SelectorModalProps) {
        super(props);

        this.state = { show: true };
    }


    selectedValue: any;
    handleButtonClicked = (val: any) => {
        this.selectedValue = val;
        this.setState({ show: false });

    }

    handleCancelClicked = () => {
        this.setState({ show: false });
    }

    handleOnExited = () => {
        this.props.onExited!(this.selectedValue);
    }

    render() {
        return <Modal bsSize="sm" onHide={this.handleCancelClicked} show={this.state.show} onExited={this.handleOnExited} className="sf-selector-modal">
            <Modal.Header closeButton={true}>
                {this.props.title &&
                    <h4 className="modal-title">
                        {this.props.title}
                    </h4>
                }
            </Modal.Header>

            <Modal.Body>
                <div>
                    {this.props.message &&
                        <p>
                            {this.props.message}
                        </p>
                    }
                    {this.props.options.map((o, i) =>
                        <button key={i} type="button" onClick={() => this.handleButtonClicked(o.value) } name={o.value}
                            className="sf-chooser-button sf-close-button btn btn-default">
                            {o.displayName}
                        </button>) }
                </div>
            </Modal.Body>
        </Modal>;
    }

    static chooseElement<T>(options: T[], config?: SelectorConfig<T>): Promise<T | undefined> {

        const {display, name, title, message} = config!;

        if (options.length == 1)
            return Promise.resolve(options.single());

        if (options.length == 0)
            return Promise.resolve(undefined);

        return openModal<T>(<SelectorModal
            options={options.map(a => ({
                value: a,
                displayName: display ? display(a) : a.toString(),
                name: name ? name(a) : a.toString()
            }))}
            title={title || SelectorMessage.ChooseAValue.niceToString() }
            message={message || SelectorMessage.PleaseChooseAValueToContinue.niceToString()}/>);
    }

    static chooseType(options: TypeInfo[]): Promise<TypeInfo> {
        return SelectorModal.chooseElement(options,
            {
                display: a => a.niceName || "",
                name: a => a.name,
                title: SelectorMessage.TypeSelector.niceToString(),
                message: SelectorMessage.PleaseSelectAType.niceToString()
            });
    }
}

export interface SelectorConfig<T> {
    display?: (val: T) => React.ReactChild;
    name?: (val: T) => string; //For testing
    title?: React.ReactChild;
    message?: React.ReactChild
}



{'fraction_non_alphanumeric': 0.13001179245283018, 'fraction_numerical': 0.0011792452830188679, 'mean_word_length': 1.871349978840457, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 69, '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': '6423530', 'n_tokens_mistral': 1871, 'n_tokens_neox': 1803, 'n_words': 370}