<commit_before>import * as React from "react";
import { TypeContext, LineBaseProps, LineBase, FormGroup } from "../Lines";
import { SearchMessage, MList, newMListElement } from "../Signum.Entities";
import { mlistItemContext } from "../TypeContext";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import DynamicComponent from "./DynamicComponent";
import { ErrorBoundary } from "../Components";
import { TitleManager, EntityBase } from "./EntityBase";

interface MultiValueLineProps extends LineBaseProps {
  ctx: TypeContext<MList<any>>;
  onRenderItem?: (ctx: TypeContext<any>) => React.ReactElement<any>;
  onCreate?: () => Promise<any[] | any | undefined>;
  addValueText?: string;
}

export class MultiValueLine extends LineBase<MultiValueLineProps, MultiValueLineProps> {
  calculateDefaultState(state: MultiValueLineProps) {
    if (state.ctx.value == undefined)
      state.ctx.value = [];

    super.calculateDefaultState(state);
  }

  handleDeleteValue = (index: number) => {
    const list = this.state.ctx.value;
    list.removeAt(index);
    this.setValue(list);
  }

  handleAddValue = (e: React.MouseEvent<any>) => {
    e.preventDefault();
    const list = this.state.ctx.value;
    const newValuePromise = this.state.onCreate == null ? this.defaultCreate() : this.state.onCreate();

    newValuePromise.then(v => {
      if (v === undefined)
        return;

      if (Array.isArray(v)) {
        list.push(...v.map(e => newMListElement(e)));
      }
      else {
        list.push(newMListElement(v));
      }

      this.setValue(list);
    }).done();
  }

  defaultCreate() {
    return Promise.resolve(null);
  }

  renderInternal() {

    const s = this.state;
    const list = this.state.ctx.value!;

    return (
      <FormGroup ctx={s.ctx} labelText={s.labelText}
        htmlAttributes={{ ...this.baseHtmlAttributes(), ...this.state.formGroupHtmlAttributes }}
        helpText={this.state.helpText}
        labelHtmlAttributes={s.labelHtmlAttributes}>
        <table className="sf-multi-value">
          <tbody>
            {
              mlistItemContext(s.ctx.subCtx({ formGroupStyle: "None" })).map((mlec, i) =>
                (<ErrorBoundary>
                  <MultiValueLineElement key={i}
                    ctx={mlec}
                    onRemove={e => { e.preventDefault(); this.handleDeleteValue(i); }}
                    onRenderItem={this.props.onRenderItem} />
                </ErrorBoundary>))
            }
            <tr >
              <td colSpan={4}>
                {!s.ctx.readOnly &&
                  <a href="#" title={TitleManager.useTitle ? this.props.addValueText || SearchMessage.AddValue.niceToString() : undefined}
                    className="sf-line-button sf-create"
                    onClick={this.handleAddValue}>
                    {EntityBase.createIcon}&nbsp;{this.props.addValueText || SearchMessage.AddValue.niceToString()}
                  </a>}
              </td>
            </tr>
          </tbody>
        </table>
      </FormGroup>
    );
  }
}

export interface MultiValueLineElementProps {
  ctx: TypeContext<any>;
  onRemove: (event: React.MouseEvent<any>) => void;
  onRenderItem?: (ctx: TypeContext<any>) => React.ReactElement<any>;
}

export class MultiValueLineElement extends React.Component<MultiValueLineElementProps> {
  render() {
    const ctx = this.props.ctx;

    return (
      <tr><commit_msg>fix MultiValueLine key<commit_after>import * as React from "react";
import { TypeContext, LineBaseProps, LineBase, FormGroup } from "../Lines";
import { SearchMessage, MList, newMListElement } from "../Signum.Entities";
import { mlistItemContext } from "../TypeContext";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import DynamicComponent from "./DynamicComponent";
import { ErrorBoundary } from "../Components";
import { TitleManager, EntityBase } from "./EntityBase";

interface MultiValueLineProps extends LineBaseProps {
  ctx: TypeContext<MList<any>>;
  onRenderItem?: (ctx: TypeContext<any>) => React.ReactElement<any>;
  onCreate?: () => Promise<any[] | any | undefined>;
  addValueText?: string;
}

export class MultiValueLine extends LineBase<MultiValueLineProps, MultiValueLineProps> {
  calculateDefaultState(state: MultiValueLineProps) {
    if (state.ctx.value == undefined)
      state.ctx.value = [];

    super.calculateDefaultState(state);
  }

  handleDeleteValue = (index: number) => {
    const list = this.state.ctx.value;
    list.removeAt(index);
    this.setValue(list);
  }

  handleAddValue = (e: React.MouseEvent<any>) => {
    e.preventDefault();
    const list = this.state.ctx.value;
    const newValuePromise = this.state.onCreate == null ? this.defaultCreate() : this.state.onCreate();

    newValuePromise.then(v => {
      if (v === undefined)
        return;

      if (Array.isArray(v)) {
        list.push(...v.map(e => newMListElement(e)));
      }
      else {
        list.push(newMListElement(v));
      }

      this.setValue(list);
    }).done();
  }

  defaultCreate() {
    return Promise.resolve(null);
  }

  renderInternal() {

    const s = this.state;
    const list = this.state.ctx.value!;

    return (
      <FormGroup ctx={s.ctx} labelText={s.labelText}
        htmlAttributes={{ ...this.baseHtmlAttributes(), ...this.state.formGroupHtmlAttributes }}
        helpText={this.state.helpText}
        labelHtmlAttributes={s.labelHtmlAttributes}>
        <table className="sf-multi-value">
          <tbody>
            {
              mlistItemContext(s.ctx.subCtx({ formGroupStyle: "None" })).map((mlec, i) =>
                <ErrorBoundary key={i}>
                  <MultiValueLineElement
                    ctx={mlec}
                    onRemove={e => { e.preventDefault(); this.handleDeleteValue(i); }}
                    onRenderItem={this.props.onRenderItem} />
                </ErrorBoundary>)
            }
            <tr >
              <td colSpan={4}>
                {!s.ctx.readOnly &&
                  <a href="#" title={TitleManager.useTitle ? this.props.addValueText || SearchMessage.AddValue.niceToString() : undefined}
                    className="sf-line-button sf-create"
                    onClick={this.handleAddValue}>
                    {EntityBase.createIcon}&nbsp;{this.props.addValueText || SearchMessage.AddValue.niceToString()}
                  </a>}
              </td>
            </tr>
          </tbody>
        </table>
      </FormGroup>
    );
  }
}

export interface MultiValueLineElementProps {
  ctx: TypeContext<any>;
  onRemove: (event: React.MouseEvent<any>) => void;
  onRenderItem?: (ctx: TypeContext<any>) => React.ReactElement<any>;
}

export class MultiValueLineElement extends React.Component<MultiValueLineElementProps> {
  render() {
    const ctx = this.props.ctx;

    return (
      <tr>
{'fraction_non_alphanumeric': 0.14024835646457268, 'fraction_numerical': 0.00029218407596785974, 'mean_word_length': 2.6241397564849125, 'pattern_counts': {'":': 0, '<': 59, '<?xml version=': 0, '>': 79, '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': '3391228', 'n_tokens_mistral': 1997, 'n_tokens_neox': 1971, 'n_words': 367}