<commit_before>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { propType } from 'graphql-anywhere';
import { graphql } from 'react-apollo';

import mapErrors from 'react/util/mapErrors';
import compactObject from 'react/util/compactObject';

import manageBlockFragment from 'react/components/ManageBlock/fragments/manageBlock';
import updateBlockMutation from 'react/components/ManageBlock/mutations/updateBlock';

import Box from 'react/components/UI/Box';
import ErrorAlert from 'react/components/UI/ErrorAlert';
import TitledDialog from 'react/components/UI/TitledDialog';
import { Input, Textarea, Label, LabelledInput } from 'react/components/UI/Inputs';

class ManageBlock extends PureComponent {
  static propTypes = {
    block: propType(manageBlockFragment).isRequired,
    updateBlock: PropTypes.func.isRequired,
    onDone: PropTypes.func.isRequired,
    autoFocus: PropTypes.oneOf(['title', 'description', 'body']),
  }

  static defaultProps = {
    autoFocus: 'title',
  }

  state = {
    mode: 'resting',
    title: null,
    description: null,
    content: null,
    errorMessage: null,
  }

  componentDidMount() {
    const { autoFocus } = this.props;

    setTimeout(() => {
      const element = {
        title: this.titleRef,
        description: this.descriptionRef,
        body: this.bodyRef,
      }[autoFocus];

      element.current.focus();
    }, 0);
  }

  titleRef = React.createRef()
  descriptionRef = React.createRef()
  bodyRef = React.createRef()

  handleErrors = (err) => {
    this.setState({
      mode: 'error',
      ...mapErrors(err),
    });
  }

  updateBlock = (e) => {
    e.preventDefault();

    const { block, updateBlock, onDone } = this.props;
    const { title, description, content } = this.state;

    const variables = compactObject({
      id: block.id,
      title,
      description,
      content,
    });

    this.setState({ mode: 'updating' });

    return updateBlock({ variables })
      .then(() => onDone())
      .catch(this.handleErrors);
  }

  handleInput = fieldName => ({ target: { value: fieldValue } }) => {
    this.setState({ [fieldName]: fieldValue });
  }

  handleTitle = this.handleInput('title')<commit_msg>Adds a callback to denote whether there are changes pending<commit_after>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { propType } from 'graphql-anywhere';
import { graphql } from 'react-apollo';

import mapErrors from 'react/util/mapErrors';
import compactObject from 'react/util/compactObject';

import manageBlockFragment from 'react/components/ManageBlock/fragments/manageBlock';
import updateBlockMutation from 'react/components/ManageBlock/mutations/updateBlock';

import Box from 'react/components/UI/Box';
import ErrorAlert from 'react/components/UI/ErrorAlert';
import TitledDialog from 'react/components/UI/TitledDialog';
import { Input, Textarea, Label, LabelledInput } from 'react/components/UI/Inputs';

class ManageBlock extends PureComponent {
  static propTypes = {
    block: propType(manageBlockFragment).isRequired,
    updateBlock: PropTypes.func.isRequired,
    onDone: PropTypes.func.isRequired,
    onChangePending: PropTypes.func,
    autoFocus: PropTypes.oneOf(['title', 'description', 'body']),
  }

  static defaultProps = {
    onChangePending: () => {},
    autoFocus: 'title',
  }

  state = {
    mode: 'resting',
    title: null,
    description: null,
    content: null,
    errorMessage: null,
  }

  componentDidMount() {
    const { autoFocus } = this.props;

    setTimeout(() => {
      const element = {
        title: this.titleRef,
        description: this.descriptionRef,
        body: this.bodyRef,
      }[autoFocus];

      element.current.focus();
    }, 0);
  }

  titleRef = React.createRef()
  descriptionRef = React.createRef()
  bodyRef = React.createRef()

  handleErrors = (err) => {
    this.setState({
      mode: 'error',
      ...mapErrors(err),
    });
  }

  updateBlock = (e) => {
    e.preventDefault();

    const {
      block, updateBlock, onDone, onChangePending,
    } = this.props;
    const { title, description, content } = this.state;

    const variables = compactObject({
      id: block.id,
      title,
      description,
      content,
    });

    this.setState({ mode: 'updating' });

    return updateBlock({ variables })
      .then(() => {
        onChangePending(false);
        return onDone();
      })
      .catch(this.handleErrors);
  }

  handleInput = fieldName => ({ target: { value: fieldValue } }) => {
    const { onChangePending } = this.props;

    onChangePending(true);

    this.setState({ [fieldName]: fieldValue });
  }

  handleTitle = this.handleInput('title')
{'fraction_non_alphanumeric': 0.13230639375395653, 'fraction_numerical': 0.00042202996412745304, 'mean_word_length': 3.3566176470588234, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 16, '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': '2748953', 'n_tokens_mistral': 1411, 'n_tokens_neox': 1399, 'n_words': 320}