<commit_before>import React from 'react'
import {connect} from 'react-redux'
import _, {isEmpty, isEqual, filter, map, find, sortBy, findIndex, isNumber, without} from 'lodash'
import {List} from 'material-ui'
import {push} from 'react-router-redux'
import {get} from 'lodash'
import {compose} from 'recompose'
import {graphql, gql} from 'react-apollo'
import {DragDropContext} from 'react-dnd'
import SiteTreeElement from './site_tree_element'
import HTML5Backend from 'react-dnd-html5-backend'
import {showNotification} from '../actions'
import {t} from '../common/utils'
import pages from '../graphql/pages.gql'

const documentIcon = <i className="mdi mdi-file-document" style={{fontSize: 24, top: 4, color: '#757575'}} />
const inactiveDocumentIcon = <i className="mdi mdi-file-document" style={{fontSize: 24, top: 4, color: '#757575', opacity: 0.7}} />

class Tree extends React.Component {
  constructor(props) {
    super(props)
    this.state = {}
  }

  move(id, after, d) {
    const self = this.state.pages.find(page => page.id === id)
    if (isNumber(after)) {
      const otherPages = without(this.state.pages, self)
      this.setState({pages: [...otherPages, {...self, position: after}]})
      return
    }
    let otherPages = this.state.pages.filter(page => page.parent !== self.parent)
    let pages = _(this.state.pages)
      .filter({parent: self.parent})
      .sortBy('position')
      .map((page, i) => ({...page, position: i}))
      .value()
    const other = findIndex(pages, {id: after})
    pages = pages.map(page => {
      if (page.id === self.id) {
        return {...page, position: other}
      } else if (page.position === other) {
        return {...page, position: page.position + (d < 0 ? 1 : -1)}
      } else if (page.position > other) {
        return {...page, position: page.position + 1}
      } else {
        return page
      }
    })
    this.setState({pages: [...otherPages, ...pages]})
  }

  commitMove(parent) {
    const pages = sortBy(filter(this.state.pages, {parent}), 'position')
    const optimisticResponse = pages.map(page => ({
      ...page,
      parent: {
        __typename: 'Page',
        id: page.parent
      }
    }))
    return this.props.saveOrder({
      variables: {pages: map(pages, 'id')},
      optimisticResponse: {
        __typename: 'Mutation',
        orderPages: optimisticResponse,
      },
    })
      .then(({data}) => {
        this.props.showNotification("Order saved")
      })
      .catch((error) => {
        this.props.showNotification("Ooops, could not save new page order")
      })
  }

  componentWillReceiveProps({pages}) {
    if (pages) {
      this.setState({pages})
    }
  }

  renderPage(page) {
    let props = {}
    const subPages = filter(this.state.pages, ({parent}) => parent === page.id)
    if (!isEmpty(subPages)) {
      props = {
        // primaryTogglesNestedList: true,
        initiallyOpen: this.props.fullPath.includes(page.id),
        nestedItems: map(sortBy(subPages, 'position'), this.renderPage.bind(this)),
      }
    }
    return (
      <SiteTreeElement
        leftIcon={page.published ? documentIcon : inactiveDocumentIcon}
        primaryText={t(page.title, this.props.locale)}
        key={page.id}
        id={page.id}
        position={page.position}
        parent={page.parent}
        move={this.move.bind(this)}
        commitMove={this.commitMove.bind(this)}
        style={{color: page.published ?  '#000' : '#888'}}
        onTouchTap={() => this.props.push(`/site/page/${page.id}`)}
        {...props}
      />
    )
  }

  render() {
    if (this.props.data.loading) {
      return null
    }
    const topPages = sortBy(this.props.pages.filter(page => !page.parent), 'position')
    return (
        <List>
          {topPages.map((page, id) => this.renderPage(page, id))}
        </List><commit_msg>fix dnd of root menu<commit_after>import React from 'react'
import {connect} from 'react-redux'
import _, {isEmpty, isEqual, filter, map, find, sortBy, findIndex, isNumber, without} from 'lodash'
import {List} from 'material-ui'
import {push} from 'react-router-redux'
import {get} from 'lodash'
import {compose} from 'recompose'
import {graphql, gql} from 'react-apollo'
import {DragDropContext} from 'react-dnd'
import SiteTreeElement from './site_tree_element'
import HTML5Backend from 'react-dnd-html5-backend'
import {showNotification} from '../actions'
import {t} from '../common/utils'
import pages from '../graphql/pages.gql'

const documentIcon = <i className="mdi mdi-file-document" style={{fontSize: 24, top: 4, color: '#757575'}} />
const inactiveDocumentIcon = <i className="mdi mdi-file-document" style={{fontSize: 24, top: 4, color: '#757575', opacity: 0.7}} />

class Tree extends React.Component {
  constructor(props) {
    super(props)
    this.state = {}
  }

  move(id, after, d) {
    const self = this.state.pages.find(page => page.id === id)
    if (isNumber(after)) {
      const otherPages = without(this.state.pages, self)
      this.setState({pages: [...otherPages, {...self, position: after}]})
      return
    }
    let otherPages = this.state.pages.filter(page => page.parent !== self.parent)
    let pages = _(this.state.pages)
      .filter({parent: self.parent})
      .sortBy('position')
      .map((page, i) => ({...page, position: i}))
      .value()
    const other = findIndex(pages, {id: after})
    pages = pages.map(page => {
      if (page.id === self.id) {
        return {...page, position: other}
      } else if (page.position === other) {
        return {...page, position: page.position + (d < 0 ? 1 : -1)}
      } else if (page.position > other) {
        return {...page, position: page.position + 1}
      } else {
        return page
      }
    })
    this.setState({pages: [...otherPages, ...pages]})
  }

  commitMove(parent) {
    const pages = sortBy(filter(this.state.pages, {parent}), 'position')
    const optimisticResponse = pages.map(page => ({
      ...page,
      parent: {
        __typename: 'Page',
        id: page.parent
      }
    }))
    return this.props.saveOrder({
      variables: {pages: map(pages, 'id')},
      optimisticResponse: {
        __typename: 'Mutation',
        orderPages: optimisticResponse,
      },
    })
      .then(({data}) => {
        this.props.showNotification("Order saved")
      })
      .catch((error) => {
        this.props.showNotification("Ooops, could not save new page order")
      })
  }

  componentWillReceiveProps({pages}) {
    if (pages) {
      this.setState({pages})
    }
  }

  renderPage(page) {
    let props = {}
    const subPages = filter(this.state.pages, ({parent}) => parent === page.id)
    if (!isEmpty(subPages)) {
      props = {
        // primaryTogglesNestedList: true,
        initiallyOpen: this.props.fullPath.includes(page.id),
        nestedItems: map(sortBy(subPages, 'position'), this.renderPage.bind(this)),
      }
    }
    return (
      <SiteTreeElement
        leftIcon={page.published ? documentIcon : inactiveDocumentIcon}
        primaryText={t(page.title, this.props.locale)}
        key={page.id}
        id={page.id}
        position={page.position}
        parent={page.parent}
        move={this.move.bind(this)}
        commitMove={this.commitMove.bind(this)}
        style={{color: page.published ?  '#000' : '#888'}}
        onTouchTap={() => this.props.push(`/site/page/${page.id}`)}
        {...props}
      />
    )
  }

  render() {
    if (this.props.data.loading) {
      return null
    }
    const topPages = sortBy(this.state.pages.filter(page => !page.parent), 'position')
    return (
        <List>
          {topPages.map((page, id) => this.renderPage(page, id))}
        </List>
{'fraction_non_alphanumeric': 0.16508760545100584, 'fraction_numerical': 0.008306294613887086, 'mean_word_length': 2.7065897065897064, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 37, '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': '4013045', 'n_tokens_mistral': 2485, 'n_tokens_neox': 2446, 'n_words': 547}