<commit_before>import React, { Component, PropTypes } from 'react';
import Portal from 'react-portal';
import ReactDOM from 'react-dom';
import { Raw } from 'slate';
import { Dropdown, Menu, Button } from 'antd';
import { sortBy } from 'lodash';
import classNames from 'classnames';

export default (options = {}) => Block => {
  let { actions, manual, remove, move, type, add } = options;
  if (!actions) actions = () => [];
  return class BlockToolbarDecorator extends Component {
    static slate = Block.slate;
    static propTypes = {
      isFocused: PropTypes.bool,
      children: PropTypes.node,
      actions: PropTypes.array,
    }
    static defaultProps = {
      actions: [],
    }
    state = { menu: null };
    componentDidMount() {
      if (manual) return;
      const rect = ReactDOM.findDOMNode(this).getBoundingClientRect();
      this.setToolbarPosition(rect);
    }
    componentDidUpdate() {
      this.componentDidMount();
    }
    setToolbarPosition = (rect) => {
      const { menu } = this.state;
      if (!menu) return;
      if (!rect) return;
      const top = (rect.top + window.scrollY) - menu.offsetHeight;
      const left = rect.left + window.scrollX - menu.offsetWidth / 2 + rect.width / 2; // eslint-disable-line
      menu.style.opacity = 1;
      menu.style.top = `${top - 3}px`;
      menu.style.left = `${left}px`;
    }
    onOpen = ({ firstChild: menu }) => {
      this.setState({ menu });
    }
    onClick = action => e => {
      e.preventDefault();
      action();
    }
    renderAction = (props) => {
      const { toggle, type, active, icon, separated, options, right } = props;
      if (options) {
        const menu = (
          <Menu onClick={toggle}>
            {options.map(({ value, label }) => <Menu.Item key={value}>{label}</Menu.Item>)}
          </Menu>
        );
        return (
          <Dropdown overlay={menu} key={type}>
            <Button key={type} type="ghost" size="small" className={classNames('slate-toolbar-button', { separated, right })} data-active={active}>
              <i className={`fa fa-${icon}`} /> <i className="fa fa-caret-down" />
            </Button>
          </Dropdown>
        );
      }
      return (
        <Button key={type} type="ghost" size="small" className={classNames('slate-toolbar-button', { separated, right })} onMouseDown={this.onClick(toggle)} data-active={active}>
          <i className={`fa fa-${icon}`} />
        </Button>
      );
    }
    onChangeType = ({ key }) => {
      const { editor, readOnly, node, state } = this.props;
      const blockTypes = editor.props.sidebarTypes || [];
      const newBlock = (blockTypes.find(({ type }) => type === key) || node);
      editor.onChange(
        state
          .transform()
          .setNodeByKey(node.key, { type: newBlock.type, isVoid: newBlock.isVoid })
          .apply()
      );
    }
    renderToolbar = (styles = {}) => {
      const { editor, readOnly, node } = this.props;
      if (readOnly) return null;<commit_msg>Toolbar-Dropdown aufgebohrt: - Es wird nun per Haken angezeigt, welches Item gewählt wurde (dafür muss dem Object noch active: true mitgegeben werden). - Sind 10 oder mehr Items als Options angegeben, wird ein Modal geöffnet statt dem Dropdown. Dies kann man auch per „showModal“ provozieren. - per „multi: true“ kann man auch das Modal öffnen, dort kann man dann aber mehrere Items auswählen. Die Toggle-Funktion bekommt dann natürlich einen Array zurück. - Man kann dem einzelnen Option-Objekt nun noch weitere Werte neben value, label, active mitgeben. Diese werden dann in der Tabelle im Modal als zusätzliche Spalte angezeigt (nur im Modal, nicht im Dropdown!)<commit_after>import React, { Component, PropTypes } from 'react';
import Portal from 'react-portal';
import ReactDOM from 'react-dom';
import { Raw } from 'slate';
import { Dropdown, Menu, Button, Icon, Modal, Table } from 'antd';
import { sortBy } from 'lodash';
import classNames from 'classnames';
import capitalize from 'capitalize';

export default (options = {}) => Block => {
  let { actions, manual, remove, move, type, add } = options;
  if (!actions) actions = () => [];
  return class BlockToolbarDecorator extends Component {
    static slate = Block.slate;
    static propTypes = {
      isFocused: PropTypes.bool,
      children: PropTypes.node,
      actions: PropTypes.array,
    }
    static defaultProps = {
      actions: [],
    }

    state = { menu: null, modal: {} };

    componentDidMount() {
      if (manual) return;
      const rect = ReactDOM.findDOMNode(this).getBoundingClientRect();
      this.setToolbarPosition(rect);
    }

    componentDidUpdate() {
      this.componentDidMount();
    }

    setToolbarPosition = (rect) => {
      const { menu } = this.state;
      if (!menu) return;
      if (!rect) return;
      const top = (rect.top + window.scrollY) - menu.offsetHeight;
      const left = rect.left + window.scrollX - menu.offsetWidth / 2 + rect.width / 2; // eslint-disable-line
      menu.style.opacity = 1;
      menu.style.top = `${top - 3}px`;
      menu.style.left = `${left}px`;
    }

    onOpen = ({ firstChild: menu }) => {
      this.setState({ menu });
    }

    onClick = action => e => {
      e.preventDefault();
      action();
    }

    renderAction = (props) => {
      const { toggle, type, active, icon, separated, options, right, multi, showModal } = props;
      const { modal } = this.state;

      if (options && options.length < 10 && !multi && !showModal) {
        const menu = (
          <Menu onClick={toggle}>
            {options.map(({ value, label, active }) => active ? (
              <Menu.Item key={value} style={{ fontWeight: 'bold' }}><Icon type="check" /> {label}</Menu.Item>
            ) : (
              <Menu.Item key={value}>{label}</Menu.Item>
            )
            )}
          </Menu>
        );

        return (
          <Dropdown overlay={menu} key={type}>
            <Button key={type} type="ghost" size="small" className={classNames('slate-toolbar-button', { separated, right })} data-active={active}>
              <i className={`fa fa-${icon}`} /> <i className="fa fa-caret-down" />
            </Button>
          </Dropdown>
        );
      } else if (options) {
        let attributes;
        const selectedRowKeys = [];
        const data = options.map(({ value, label, active, ...rest }) => {
          attributes = rest;

          if (active) {
            selectedRowKeys.push(value);
          }

          return {
            key: value,
            name: label,
            ...rest
          };
        });
        const columns = Object.keys(attributes).map(key => ({
          title: capitalize(key),
          dataIndex: key,
        }));
        const rowSelection = multi ? {
          type: 'select',
          selectedRowKeys,
          onChange: (selectedRowKeys, selectedRows) => toggle(selectedRows),
        } : {
          type: 'radio',
          selectedRowKeys,
          onChange: (selectedRowKeys, selectedRows) => toggle(selectedRows[0]),
        };

        return (
          <div>
            <Button key={type} type="ghost" size="small" className={classNames('slate-toolbar-button', { separated, right })} onClick={() => this.setState({ modal: { ...modal, [type]: true } })} data-active={active}>
              <i className={`fa fa-${icon}`} />
            </Button>

            <Modal
              title="Bitte wählen"
              visible={modal[type]}
              onOk={() => this.setState({ modal: { ...modal, [type]: false } })}
              onCancel={() => this.setState({ modal: { ...modal, [type]: false } })}
            >
              <Table
                dataSource={data}
                columns={[{
                  title: 'Name',
                  dataIndex: 'name',
                },
                  ...columns,
                ]}
                rowSelection={rowSelection}
                size="middle"
                pagination={false}
              />
            </Modal>
          </div>
        );
      }

      return (
        <Button key={type} type="ghost" size="small" className={classNames('slate-toolbar-button', { separated, right })} onMouseDown={this.onClick(toggle)} data-active={active}>
          <i className={`fa fa-${icon}`} />
        </Button>
      );
    }

    onChangeType = ({ key }) => {
      const { editor, readOnly, node, state } = this.props;
      const blockTypes = editor.props.sidebarTypes || [];
      const newBlock = (blockTypes.find(({ type }) => type === key) || node);
      editor.onChange(
        state
          .transform()
          .setNodeByKey(node.key, { type: newBlock.type, isVoid: newBlock.isVoid })
          .apply()
      );
    }

    renderToolbar = (styles = {}) => {
      const { editor, readOnly, node } = this.props;
      if (readOnly) return null;
{'fraction_non_alphanumeric': 0.14867456288776085, 'fraction_numerical': 0.0014664410603496898, 'mean_word_length': 2.1800573888091823, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 71, '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': '4137863', 'n_tokens_mistral': 2565, 'n_tokens_neox': 2582, 'n_words': 655}