<commit_before>import React, {Component} from 'react';
import PropTypes from 'prop-types';
import AllComponents from 'formiojs/components';
import Components from 'formiojs/components/Components';
import FormioFormBuilder from 'formiojs/FormBuilder';

Components.setComponents(AllComponents);

export default class FormBuilder extends Component {
  static defaultProps = {
    options: {},
    Builder: FormioFormBuilder
  };

  static propTypes = {
    form: PropTypes.object,
    options: PropTypes.object,
    onSaveComponent: PropTypes.func,
    onUpdateComponent: PropTypes.func,
    onDeleteComponent: PropTypes.func,
    onCancelComponent: PropTypes.func,
    onEditComponent: PropTypes.func,
    Builder: PropTypes.any
  };

  componentDidMount = () => {
    this.initializeBuilder(this.props);
  };

  componentWillUnmount = () => {
    if (this.builder !== undefined) {
      this.builder.instance.destroy(true);
    }
  };

  initializeBuilder = (props) => {
    const options = Object.assign({}, props.options);
    const form = Object.assign({}, props.form);
    const Builder = props.Builder;

    if (this.builder !== undefined) {
      this.builder.instance.destroy(true);
    }

    this.builder = new Builder(this.element.firstChild, form, options);
    this.builderReady = this.builder.ready;

    this.builderReady.then(() => {
      this.onChange();
      this.builder.instance.on('saveComponent', this.emit('onSaveComponent'));
      this.builder.instance.on('updateComponent', this.emit('onUpdateComponent'));
      this.builder.instance.on('removeComponent', this.emit('onDeleteComponent'));
      this.builder.instance.on('cancelComponent', this.emit('onCancelComponent'));
      this.builder.instance.on('editComponent', this.emit('onEditComponent'));
      this.builder.instance.on('addComponent', this.onChange);
      this.builder.instance.on('saveComponent', this.onChange);
      this.builder.instance.on('updateComponent', this.onChange);
      this.builder.instance.on('removeComponent', this.onChange);
      this.builder.instance.on('deleteComponent', this.onChange);
      this.builder.instance.on('pdfUploaded', this.onChange);
    });
  };

  componentWillReceiveProps = (nextProps) => {
    const {options, form} = this.props;

    if (
      (form.display !== nextProps.form.display)
      || (options !== nextProps.options)
      || (form.components !== nextProps.form.components)
    ) {
      this.initializeBuilder(nextProps);
    }
  };

  render = () => {
    return <div ref={element => this.element = element}>
      <div></div>
    </div>;
  };

  onChange = () => {
    if (this.props.hasOwnProperty('onChange') && typeof this.props.onChange === 'function') {
      this.props.onChange(this.builder.instance.form);
    }
  };

  emit = (funcName) => {
    return (...args) => {
      if (this.props.hasOwnProperty(funcName) && typeof (this.props[funcName]) === 'function') {
        this.props[funcName](...args);
      }
    };
  };
}<commit_msg>Converted FormBuilder Component to a Functional one<commit_after>import React, {useEffect} from 'react';
import PropTypes from 'prop-types';
import AllComponents from 'formiojs/components';
import Components from 'formiojs/components/Components';
import FormioFormBuilder from 'formiojs/FormBuilder';

Components.setComponents(AllComponents);

const FormBuilder = (props) => {
  let builder;
  let builderReady;
  let element;

  const emit = (funcName) => (...args) => {
    if (props.hasOwnProperty(funcName) && typeof (props[funcName]) === 'function') {
      props[funcName](...args);
    }
  };

  const onChange = () => {
    const {onChange} = props;
    if (onChange && typeof onChange === 'function') {
      onChange(builder.instance.form);
    }
  };

  const builderEvents = [
    {name: 'saveComponent', action: emit('onSaveComponent')},
    {name: 'updateComponent', action: emit('onUpdateComponent')},
    {name: 'removeComponent', action: emit('onDeleteComponent')},
    {name: 'cancelComponent', action: emit('onUpdateComponent')},
    {name: 'editComponent', action: emit('onEditComponent')},
    {name: 'addComponent', action: onChange},
    {name: 'saveComponent', action: onChange},
    {name: 'updateComponent', action: onChange},
    {name: 'removeComponent', action: onChange},
    {name: 'deleteComponent', action: onChange},
    {name: 'pdfUploaded', action: onChange},
  ];

  const initializeBuilder = (builderProps) => {
    let {options, form} = builderProps;
    const {Builder} = builderProps;
    options = Object.assign({}, options);
    form = Object.assign({}, form);

    builder = new Builder(element.firstChild, form, options);
    builderReady = builder.ready;

    builderReady.then(() => {
      onChange();
      builderEvents.forEach(({name, action}) => builder.instance.on(name, action));
    });
  };

  useEffect(() => {
    initializeBuilder(props);
    return () => builder ? builder.instance.destroy(true) : null;
  }, [builder]);

  useEffect(() => {
    initializeBuilder(props);
  }, [props.form.display, props.form.components, props.options]);

  return <div ref={el => element = el}>
    <div></div>
  </div>;
};

FormBuilder.defaultProps = {
  options: {},
  Builder: FormioFormBuilder
};

FormBuilder.propTypes = {
  form: PropTypes.object,
  options: PropTypes.object,
  onSaveComponent: PropTypes.func,
  onUpdateComponent: PropTypes.func,
  onDeleteComponent: PropTypes.func,
  onCancelComponent: PropTypes.func,
  onEditComponent: PropTypes.func,
  Builder: PropTypes.any
};

export default FormBuilder;
{'fraction_non_alphanumeric': 0.15446862075166337, 'fraction_numerical': 0.0, 'mean_word_length': 3.9047619047619047, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 32, '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': '3285711', 'n_tokens_mistral': 1614, 'n_tokens_neox': 1621, 'n_words': 321}