<commit_before>/**
 * @providesModule SearchForm
 * @flow
 */

import * as React from 'react'
import styled from 'styled-components'
import qs from 'qs'
import { reject, isEmpty } from 'ramda'

import { withRouter } from 'react-router-dom'
import { injectIntl, FormattedMessage } from 'react-intl'

import { Button, FormGroup, InputGroup, Intent } from '@blueprintjs/core'
import { CatalogSection, SectionTitle } from 'catalog/shared'
import KeywordsChooser from 'overview/keywords/KeywordsChooser'

import type { IntlShape } from 'react-intl'
import type { ContextRouter } from 'react-router-dom'
import type { Query } from 'catalog/search_results'
import type { Tag } from 'redux/state'

type Props = {| ...ContextRouter, params: Query, intl: IntlShape |}
type State = { q: string, libraries: string[], tags: Tag[] }
class SearchForm extends React.Component<Props, State> {
  state = {
    q: (this.props.params.q || []).join(' '),
    libraries: this.props.params.libraries,
    tags: makeDummyTags(this.props.params.tags),
  }

  get stateForSearchParams () {
    const { q, libraries, tags } = this.state
    return { q, libraries, tags: tags.map(tag => tag.name) }
  }

  componentDidUpdate (prevProps: Props) {
    if (
      this.props.params.q === prevProps.params.q &&
      this.props.params.libraries === prevProps.params.libraries
    ) {
      return
    }

    this.setState({
      q: (this.props.params.q || []).join(' '),
      libraries: this.props.params.libraries,
    })
  }

  handleChangeQuery = (e: SyntheticInputEvent<HTMLInputElement>) =>
    this.setState({ q: e.currentTarget.value })

  handleChangeTags = (tags: Tag[]) => this.setState({ tags })

  handleSubmit = (e: SyntheticEvent<HTMLFormElement>) => {
    e.preventDefault()
    this.props.history.push(getSearchPath(this.stateForSearchParams))
  }

  render () {
    const { q, tags } = this.state
    return (
      <CatalogSection className="pt-dark">
        <SectionTitle>
          <FormattedMessage id="search.refine" />
        </SectionTitle>

        <form onSubmit={this.handleSubmit}>
          <FormGroup>
            <InputGroup
              className="pt-fill"
              leftIcon="search"
              placeholder={this.props.intl.formatMessage({
                id: 'search.fullTextSearch',
              })}
              value={q}
              onChange={this.handleChangeQuery}
            />
          </FormGroup>

          <FormGroup label={<FormattedMessage id="catalog.keywords" />}>
            <KeywordsChooser tags={tags} onChange={this.handleChangeTags} />
          </FormGroup>

          <SubmitButton>
            <FormattedMessage id="search.search" />
          </SubmitButton>
        </form>
      </CatalogSection>
    )
  }
}
export default injectIntl(withRouter(SearchForm))

function makeDummyTags (names: ?(string[])) {
  return names ? names.map(name => ({ name, displayName: name })) : []<commit_msg>refactor: use hooks for search form<commit_after>/**
 * @providesModule SearchForm
 * @flow
 */

import * as React from 'react'
import styled from 'styled-components'
import qs from 'qs'
import { reject, isEmpty } from 'ramda'

import { withRouter } from 'react-router-dom'
import { injectIntl, FormattedMessage } from 'react-intl'

import { Button, FormGroup, InputGroup, Intent } from '@blueprintjs/core'
import { CatalogSection, SectionTitle } from 'catalog/shared'
import KeywordsChooser from 'overview/keywords/KeywordsChooser'

import type { IntlShape } from 'react-intl'
import type { ContextRouter } from 'react-router-dom'
import type { Query } from 'catalog/search_results/getQueryParams'
import type { Tag } from 'redux/state'

type Props = {| ...ContextRouter, params: Query, intl: IntlShape |}
function SearchForm ({ history, intl, params }: Props) {
  const queryFromUrl = (params.q || []).join(' ')
  const [query, setQuery] = React.useState(queryFromUrl)
  React.useEffect(() => setQuery(queryFromUrl), [params.query])

  const [tagObjects, setTagObjects] = React.useState(
    createTagObjects(params.tags)
  )

  function handleSubmit (e: SyntheticEvent<HTMLFormElement>) {
    e.preventDefault()
    const searchPath = getSearchPath({
      q: query,
      libraries: params.libraries,
      tags: tagObjects.map(tag => tag.name),
    })
    history.push(searchPath)
  }

  return (
    <CatalogSection className="pt-dark">
      <SectionTitle>
        <FormattedMessage id="search.refine" />
      </SectionTitle>

      <form onSubmit={handleSubmit}>
        <FormGroup>
          <InputGroup
            className="pt-fill"
            leftIcon="search"
            placeholder={intl.formatMessage({
              id: 'search.fullTextSearch',
            })}
            value={query}
            onChange={e => setQuery(e.target.value)}
          />
        </FormGroup>

        <FormGroup label={<FormattedMessage id="catalog.keywords" />}>
          <KeywordsChooser tags={tagObjects} onChange={setTagObjects} />
        </FormGroup>

        <SubmitButton>
          <FormattedMessage id="search.search" />
        </SubmitButton>
      </form>
    </CatalogSection>
  )
}

export default injectIntl(withRouter(SearchForm))

function createTagObjects (names: ?(string[])): Tag[] {
  return names ? names.map(name => ({ name, displayName: name })) : []
{'fraction_non_alphanumeric': 0.13495200451722192, 'fraction_numerical': 0.0, 'mean_word_length': 3.0227100681302046, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 50, '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': '5931029', 'n_tokens_mistral': 1595, 'n_tokens_neox': 1576, 'n_words': 353}