<commit_before>import _, { messages } from 'intl'
import ActionButton from 'action-button'
import ActionRowButton from 'action-row-button'
import isEmpty from 'lodash/isEmpty'
import map from 'lodash/map'
import propTypes from 'prop-types'
import React, { Component } from 'react'
import TabButton from 'tab-button'
import { ButtonGroup } from 'react-bootstrap-4/lib'
import { connectStore, noop } from 'utils'
import { Container, Row, Col } from 'grid'
import {
  createGetObjectsOfType,
  createSelector
} from 'selectors'
import { injectIntl } from 'react-intl'
import { SelectNetwork } from 'select-objects'

import {
  connectVif,
  createVmInterface,
  deleteVif,
  disconnectVif
} from 'xo'

@propTypes({
  onClose: propTypes.func,
  vm: propTypes.object.isRequired
})
@injectIntl
class NewVif extends Component {
  constructor (props) {
    super(props)
    this.state = {
      network: undefined
    }
  }
  _getNetworkPredicate = createSelector(
    () => {
      const { vm } = this.props
      return vm && vm.$pool
    },
    poolId => network => network.$pool === poolId
  )

  _selectNetwork = network => this.setState({network})

  _createVif = () => {
    const { vm, onClose = noop } = this.props
    const { mac, mtu } = this.refs
    const { network } = this.state
    return createVmInterface(vm, network, mac.value || undefined, mtu.value || String(network.MTU))
      .then(onClose)
  }

  render () {
    const formatMessage = this.props.intl.formatMessage
    return <form id='newVifForm'>
      <div className='form-group'>
        <SelectNetwork predicate={this._getNetworkPredicate()} onChange={this._selectNetwork} required />
      </div>
      <fieldset className='form-inline'>
        <div className='form-group'>
          <input type='text' ref='mac' placeholder={formatMessage(messages.vifMacLabel)} className='form-control' /> ({_('vifMacAutoGenerate')})
        </div>
        {' '}
        <div className='form-group'>
          <input type='text' ref='mtu' placeholder={formatMessage(messages.vifMtuLabel)} className='form-control' />
        </div>
        <span className='pull-right'>
          <ActionButton form='newVifForm' icon='add' btnStyle='primary' handler={this._createVif}>Create</ActionButton>
        </span>
      </fieldset>
    </form>
  }
}

@connectStore(() => {
  const vifs = createGetObjectsOfType('VIF').pick(
    (_, props) => props.vm.VIFs
  ).sort()
  const networks = createGetObjectsOfType('network').pick(
    createSelector(
      vifs,
      vifs => map(vifs, vif => vif.$network)
    )
  )

  return (state, props) => ({
    networks: networks(state, props),
    vifs: vifs(state, props)
  })
})
export default class TabNetwork extends Component {
  constructor (props) {
    super(props)
    this.state = {
      newVif: false
    }
  }

  _toggleNewVif = () => this.setState({
    newVif: !this.state.newVif
  })

  render () {
    const { newVif } = this.state
    const {
      networks,
      vifs,
      vm
    } = this.props

    return <Container>
      <Row>
        <Col className='text-xs-right'>
          <TabButton
            btnStyle='primary'
            handler={this._toggleNewVif}
            icon='add'
            labelId='vifCreateDeviceButton'
          />
        </Col>
      </Row>
      <Row>
        <Col>
          {newVif && <div><NewVif vm={vm} onClose={this._toggleNewVif} /><hr /></div>}
        </Col>
      </Row>
      <Row>
        <Col>
          {!isEmpty(vifs)
            ? <span>
              <table className='table' style={{ minWidth: '0' }}>
                <thead>
                  <tr><commit_msg>feat(newVif): select management network by default when adding a vif. Fixes #1425<commit_after>import _, { messages } from 'intl'
import ActionButton from 'action-button'
import ActionRowButton from 'action-row-button'
import isEmpty from 'lodash/isEmpty'
import map from 'lodash/map'
import propTypes from 'prop-types'
import React, { Component } from 'react'
import TabButton from 'tab-button'
import { ButtonGroup } from 'react-bootstrap-4/lib'
import { connectStore, noop } from 'utils'
import { Container, Row, Col } from 'grid'
import {
  createFinder,
  createGetObject,
  createGetObjectsOfType,
  createSelector
} from 'selectors'
import { injectIntl } from 'react-intl'
import { SelectNetwork } from 'select-objects'

import {
  connectVif,
  createVmInterface,
  deleteVif,
  disconnectVif
} from 'xo'

@propTypes({
  onClose: propTypes.func,
  vm: propTypes.object.isRequired
})
@connectStore(() => {
  const getHostMaster = createGetObject(
    (_, props) => props.pool && props.pool.master
  )
  const getPifs = createGetObjectsOfType('PIF').pick(
    (state, props) => {
      const hostMaster = getHostMaster(state, props)
      return hostMaster && hostMaster.$PIFs
    }
  )
  const getDefaultNetworkId = createSelector(
    createFinder(
      getPifs,
      [ pif => pif.management ]
    ),
    pif => pif && pif.$network
  )
  return {
    defaultNetworkId: getDefaultNetworkId
  }
})
@injectIntl
class NewVif extends Component {
  constructor (props) {
    super(props)
    this.state = {
      network: undefined
    }
  }
  _getNetworkPredicate = createSelector(
    () => {
      const { vm } = this.props
      return vm && vm.$pool
    },
    poolId => network => network.$pool === poolId
  )

  _selectNetwork = network => this.setState({network})

  _createVif = () => {
    const { vm, onClose = noop } = this.props
    const { mac, mtu } = this.refs
    const { network } = this.state
    return createVmInterface(vm, network, mac.value || undefined, mtu.value || String(network.MTU))
      .then(onClose)
  }

  render () {
    const formatMessage = this.props.intl.formatMessage
    return <form id='newVifForm'>
      <div className='form-group'>
        <SelectNetwork defaultValue={this.props.defaultNetworkId} predicate={this._getNetworkPredicate()} onChange={this._selectNetwork} required />
      </div>
      <fieldset className='form-inline'>
        <div className='form-group'>
          <input type='text' ref='mac' placeholder={formatMessage(messages.vifMacLabel)} className='form-control' /> ({_('vifMacAutoGenerate')})
        </div>
        {' '}
        <div className='form-group'>
          <input type='text' ref='mtu' placeholder={formatMessage(messages.vifMtuLabel)} className='form-control' />
        </div>
        <span className='pull-right'>
          <ActionButton form='newVifForm' icon='add' btnStyle='primary' handler={this._createVif}>Create</ActionButton>
        </span>
      </fieldset>
    </form>
  }
}

@connectStore(() => {
  const vifs = createGetObjectsOfType('VIF').pick(
    (_, props) => props.vm.VIFs
  ).sort()
  const networks = createGetObjectsOfType('network').pick(
    createSelector(
      vifs,
      vifs => map(vifs, vif => vif.$network)
    )
  )

  return (state, props) => ({
    networks: networks(state, props),
    vifs: vifs(state, props)
  })
})
export default class TabNetwork extends Component {
  constructor (props) {
    super(props)
    this.state = {
      newVif: false
    }
  }

  _toggleNewVif = () => this.setState({
    newVif: !this.state.newVif
  })

  render () {
    const { newVif } = this.state
    const {
      networks,
      pool,
      vifs,
      vm
    } = this.props

    return <Container>
      <Row>
        <Col className='text-xs-right'>
          <TabButton
            btnStyle='primary'
            handler={this._toggleNewVif}
            icon='add'
            labelId='vifCreateDeviceButton'
          />
        </Col>
      </Row>
      <Row>
        <Col>
          {newVif && <div><NewVif vm={vm} pool={pool} onClose={this._toggleNewVif} /><hr /></div>}
        </Col>
      </Row>
      <Row>
        <Col>
          {!isEmpty(vifs)
            ? <span>
              <table className='table' style={{ minWidth: '0' }}>
                <thead>
                  <tr>
{'fraction_non_alphanumeric': 0.13901854421597074, 'fraction_numerical': 0.0010092090324208402, 'mean_word_length': 2.6977611940298507, 'pattern_counts': {'":': 0, '<': 77, '<?xml version=': 0, '>': 104, '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': '4305519', 'n_tokens_mistral': 2509, 'n_tokens_neox': 2490, 'n_words': 539}