<commit_before>import * as React from 'react'
import {
  FilterOptionParsed, QueryDescription, QueryToken, SubTokensOptions,
  isList, isFilterGroupOptionParsed
} from '../FindOptions'
import { ValueLine, FormGroup } from '../Lines'
import { Binding, IsByAll, getTypeInfos, toMomentFormat } from '../Reflection'
import { TypeContext } from '../TypeContext'
import "./FilterBuilder.css"
import { createFilterValueControl, MultiValue } from './FilterBuilder';
import { SearchMessage } from '../Signum.Entities';

interface PinnedFilterBuilderProps {
  filterOptions: FilterOptionParsed[];
  queryDescription: QueryDescription;
  onFiltersChanged?: (filters: FilterOptionParsed[]) => void;
}
export default class PinnedFilterBuilder extends React.Component<PinnedFilterBuilderProps>{

  render() {
    var allPinned = getAllPinned(this.props.filterOptions);

    if (allPinned.length == 0)
      return null;

    return (
      <div className="row mt-3 mb-3">
        {
          allPinned
            .groupBy(a => (a.pinned!.column || 0).toString())
            .orderBy(gr => parseInt(gr.key))
            .map(gr => <div className="col-sm-3" key={gr.key}>
              {gr.elements.orderBy(a => a.pinned!.row).map((f, i) => <div key={i}>{this.renderValue(f)}</div>)}
            </div>)
        }
      </div>
    );
  }

  renderValue(filter: FilterOptionParsed) {

    const f = filter;
    const readOnly = f.frozen;
    const ctx = new TypeContext<any>(undefined, { formGroupStyle: "Basic", readOnly: readOnly, formSize: "Small" }, undefined as any, Binding.create(f, a => a.value));

    var labelText = f.pinned!.label || f.token && f.token.niceName;

    if (isFilterGroupOptionParsed(f)) {
      return <ValueLine ctx={ctx} type={{ name: "string" }} onChange={() => this.handleValueChange(f)} labelText={labelText || SearchMessage.Search.niceToString()} />
    }

    if (isList(f.operation!))
      return (
        <FormGroup ctx={ctx} labelText={labelText}>
          <MultiValue values={f.value} readOnly={readOnly} onChange={() => this.handleValueChange(f)}
            onRenderItem={ctx => createFilterValueControl(ctx, f.token!, () => this.handleValueChange(f))} />
        </FormGroup>
      );

    return createFilterValueControl(ctx, f.token!, () => this.handleValueChange(f), labelText);
  }

  timeoutWriteText?: number | null;<commit_msg>add extraSmall to PinnedFilterBuilder<commit_after>import * as React from 'react'
import {
  FilterOptionParsed, QueryDescription, QueryToken, SubTokensOptions,
  isList, isFilterGroupOptionParsed
} from '../FindOptions'
import { ValueLine, FormGroup } from '../Lines'
import { Binding, IsByAll, getTypeInfos, toMomentFormat } from '../Reflection'
import { TypeContext } from '../TypeContext'
import "./FilterBuilder.css"
import { createFilterValueControl, MultiValue } from './FilterBuilder';
import { SearchMessage } from '../Signum.Entities';
import { classes } from '../Globals';

interface PinnedFilterBuilderProps {
  filterOptions: FilterOptionParsed[];
  onFiltersChanged?: (filters: FilterOptionParsed[]) => void;
  extraSmall?: boolean;
}
export default class PinnedFilterBuilder extends React.Component<PinnedFilterBuilderProps>{

  render() {
    var allPinned = getAllPinned(this.props.filterOptions);

    if (allPinned.length == 0)
      return null;

    return (
      <div className={classes("row", this.props.extraSmall ? "" : "mt-3 mb-3")}>
        {
          allPinned
            .groupBy(a => (a.pinned!.column || 0).toString())
            .orderBy(gr => parseInt(gr.key))
            .map(gr => <div className="col-sm-3" key={gr.key}>
              {gr.elements.orderBy(a => a.pinned!.row).map((f, i) => <div key={i}>{this.renderValue(f)}</div>)}
            </div>)
        }
      </div>
    );
  }

  renderValue(filter: FilterOptionParsed) {

    const f = filter;
    const readOnly = f.frozen;
    const ctx = new TypeContext<any>(undefined, { formGroupStyle: "Basic", readOnly: readOnly, formSize: this.props.extraSmall ? "ExtraSmall" : "Small" }, undefined as any, Binding.create(f, a => a.value));

    var labelText = f.pinned!.label || f.token && f.token.niceName;

    if (isFilterGroupOptionParsed(f)) {
      return <ValueLine ctx={ctx} type={{ name: "string" }} onChange={() => this.handleValueChange(f)} labelText={labelText || SearchMessage.Search.niceToString()} />
    }

    if (isList(f.operation!))
      return (
        <FormGroup ctx={ctx} labelText={labelText}>
          <MultiValue values={f.value} readOnly={readOnly} onChange={() => this.handleValueChange(f)}
            onRenderItem={ctx => createFilterValueControl(ctx, f.token!, () => this.handleValueChange(f))} />
        </FormGroup>
      );

    return createFilterValueControl(ctx, f.token!, () => this.handleValueChange(f), labelText);
  }

  timeoutWriteText?: number | null;
{'fraction_non_alphanumeric': 0.1528006589785832, 'fraction_numerical': 0.002059308072487644, 'mean_word_length': 3.586402266288952, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 51, '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': '7318241', 'n_tokens_mistral': 1474, 'n_tokens_neox': 1454, 'n_words': 315}