<commit_before>/*
Copyright 2016 First People's Cultural Council

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React, { Component, PropTypes } from 'react'
import Immutable, { List, Map } from 'immutable'
import classNames from 'classnames'
import ImageGallery from 'react-image-gallery'
import provide from 'react-redux-provide'
import selectn from 'selectn'

import ConfGlobal from 'conf/local.js'

import RaisedButton from 'material-ui/lib/raised-button'

import ProviderHelpers from 'common/ProviderHelpers'
import StringHelpers from 'common/StringHelpers'
import UIHelpers from 'common/UIHelpers'

import PromiseWrapper from 'views/components/Document/PromiseWrapper'
import AuthorizationFilter from 'views/components/Document/AuthorizationFilter'

import withActions from 'views/hoc/view/with-actions'

const DetailsViewWithActions = withActions(PromiseWrapper, true)

//Stylesheet
import '!style-loader!css-loader!react-image-gallery/build/image-gallery.css'
import IntlService from 'views/services/intl'

const intl = IntlService.instance
@provide
export default class Gallery extends React.Component {
  static propTypes = {
    splitWindowPath: PropTypes.array.isRequired,
    windowPath: PropTypes.string.isRequired,
    pushWindowPath: PropTypes.func.isRequired,
    changeTitleParams: PropTypes.func.isRequired,
    overrideBreadcrumbs: PropTypes.func.isRequired,
    computeLogin: PropTypes.object.isRequired,
    fetchGallery: PropTypes.func.isRequired,
    computeGallery: PropTypes.object.isRequired,
    fetchDialect2: PropTypes.func.isRequired,
    computeDialect2: PropTypes.object.isRequired,
    routeParams: PropTypes.object.isRequired,
    deleteGallery: PropTypes.func.isRequired,
    publishGallery: PropTypes.func.isRequired,
    askToPublishGallery: PropTypes.func.isRequired,
    unpublishGallery: PropTypes.func.isRequired,
    askToUnpublishGallery: PropTypes.func.isRequired,
    enableGallery: PropTypes.func.isRequired,
    askToEnableGallery: PropTypes.func.isRequired,
    disableGallery: PropTypes.func.isRequired,
    askToDisableGallery: PropTypes.func.isRequired,
  }

  constructor(props, context) {
    super(props, context)
    ;['_onNavigateRequest'].forEach((method) => (this[method] = this[method].bind(this)))
  }

  _getGalleryPath(props = null) {
    if (props == null) {
      props = this.props
    }

    if (StringHelpers.isUUID(props.routeParams.galleryName)) {
      return props.routeParams.galleryName
    } else {
      return props.routeParams.dialect_path + '/Portal/' + StringHelpers.clean(props.routeParams.galleryName)
    }
  }

  fetchData(newProps) {
    newProps.fetchGallery(this._getGalleryPath())
    newProps.fetchDialect2(newProps.routeParams.dialect_path)
  }

  _onNavigateRequest(path) {
    this.props.pushWindowPath(path)
  }

  // Fetch data on initial render
  componentDidMount() {
    this.fetchData(this.props)
  }

  componentDidUpdate(prevProps, prevState) {
    let gallery = selectn('response', ProviderHelpers.getEntry(this.props.computeGallery, this._getGalleryPath()))
    let title = selectn('properties.dc:title', gallery)
    let uid = selectn('uid', gallery)

    if (title && selectn('pageTitleParams.galleryName', this.props.properties) != title) {
      this.props.changeTitleParams({ galleryName: title })
      this.props.overrideBreadcrumbs({ find: uid, replace: 'pageTitleParams.galleryName' })
    }
  }

  render() {
    const images = []

    const computeDialect2 = ProviderHelpers.getEntry(this.props.computeDialect2, this.props.routeParams.dialect_path)
    const computeGallery = ProviderHelpers.getEntry(this.props.computeGallery, this._getGalleryPath())
    ;(selectn('response.contextParameters.gallery.related_pictures', computeGallery) || []).map(function(picture) {
      let image = { original: UIHelpers.getThumbnail(picture, 'Medium'), description: picture['dc:description'] }
      images.push(image)
    })

    const computeEntities = Immutable.fromJS([
      {
        id: this._getGalleryPath(),
        entity: this.props.computeGallery,
      },
    ])

    return (
      <DetailsViewWithActions
        labels={{ single: 'Gallery' }}
        itemPath={this._getGalleryPath()}
        actions={['workflow', 'edit', 'publish-toggle', 'enable-toggle', 'publish']}
        publishAction={this.props.publishGallery}
        unpublishAction={this.props.unpublishGallery}
        askToPublishAction={this.props.askToPublishGallery}
        askToUnpublishAction={this.props.askToUnpublishGallery}
        enableAction={this.props.enableGallery}
        askToEnableAction={this.props.askToEnableGallery}
        disableAction={this.props.disableGallery}
        askToDisableAction={this.props.askToDisableGallery}
        deleteAction={this.props.deleteGallery}
        onNavigateRequest={this._onNavigateRequest}
        computeItem={computeGallery}
        permissionEntry={computeDialect2}
        renderOnError={true}
        computeEntities={computeEntities}
        {...this.props}
      >
        <div className="row">
          <div className="col-xs-12" style={{ textAlign: 'center' }}>
            <h1>{selectn('response.title', computeGallery)}</h1>
            <p>{selectn('response.properties.dc:description', computeGallery)}</p>
            <div className={classNames('col-xs-12', 'col-md-4', 'col-md-offset-4')}>
              <div>
                <ImageGallery
                  ref={(i) => (this._imageGallery = i)}
                  items={images}
                  slideInterval={2000}
                  showFullscreenButton={true}
                  showThumbnails={false}
                  showBullets={true}
                />
              </div>
            </div>
          </div>
        </div>
      </DetailsViewWithActions>
    )
  }
}<commit_msg>Reduxed/Linted: `<Gallery />`<commit_after>/*
Copyright 2016 First People's Cultural Council

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React, { PropTypes } from 'react'
import Immutable from 'immutable'
import classNames from 'classnames'
import ImageGallery from 'react-image-gallery'

// REDUX
import { connect } from 'react-redux'
// REDUX: actions/dispatch/func
import { askToDisableGallery } from 'providers/redux/reducers/fv'
import { askToEnableGallery } from 'providers/redux/reducers/fv'
import { askToPublishGallery } from 'providers/redux/reducers/fv'
import { askToUnpublishGallery } from 'providers/redux/reducers/fv'
import { changeTitleParams } from 'providers/redux/reducers/fv'
import { disableGallery } from 'providers/redux/reducers/fv'
import { deleteGallery } from 'providers/redux/reducers/fv'
import { fetchDialect2 } from 'providers/redux/reducers/fv'
import { fetchGallery } from 'providers/redux/reducers/fv'
import { overrideBreadcrumbs } from 'providers/redux/reducers/fv'
import { publishGallery } from 'providers/redux/reducers/fv'
import { pushWindowPath } from 'providers/redux/reducers/fv'
import { unpublishGallery } from 'providers/redux/reducers/fv'
import { enableGallery } from 'providers/redux/reducers/fv'

import selectn from 'selectn'
import ProviderHelpers from 'common/ProviderHelpers'
import StringHelpers from 'common/StringHelpers'
import UIHelpers from 'common/UIHelpers'
import PromiseWrapper from 'views/components/Document/PromiseWrapper'
import withActions from 'views/hoc/view/with-actions'

const DetailsViewWithActions = withActions(PromiseWrapper, true)

//Stylesheet
import '!style-loader!css-loader!react-image-gallery/build/image-gallery.css'

const { array, func, object, string } = PropTypes

export class Gallery extends React.Component {
  static propTypes = {
    routeParams: object.isRequired,
    // REDUX: reducers/state
    computeDialect2: object.isRequired,
    computeGallery: object.isRequired,
    computeLogin: object.isRequired,
    properties: object.isRequired,
    splitWindowPath: array.isRequired,
    windowPath: string.isRequired,
    // REDUX: actions/dispatch/func
    askToDisableGallery: func.isRequired,
    askToEnableGallery: func.isRequired,
    askToPublishGallery: func.isRequired,
    askToUnpublishGallery: func.isRequired,
    changeTitleParams: func.isRequired,
    disableGallery: func.isRequired,
    deleteGallery: func.isRequired,
    fetchDialect2: func.isRequired,
    fetchGallery: func.isRequired,
    overrideBreadcrumbs: func.isRequired,
    publishGallery: func.isRequired,
    pushWindowPath: func.isRequired,
    unpublishGallery: func.isRequired,
    enableGallery: func.isRequired,
  }

  constructor(props, context) {
    super(props, context)
    ;['_onNavigateRequest'].forEach((method) => (this[method] = this[method].bind(this)))
  }

  _getGalleryPath(props = null) {
    const _props = props == null ? this.props : props

    if (StringHelpers.isUUID(_props.routeParams.galleryName)) {
      return _props.routeParams.galleryName
    }
    return _props.routeParams.dialect_path + '/Portal/' + StringHelpers.clean(_props.routeParams.galleryName)
  }

  fetchData(newProps) {
    newProps.fetchGallery(this._getGalleryPath())
    newProps.fetchDialect2(newProps.routeParams.dialect_path)
  }

  _onNavigateRequest(path) {
    this.props.pushWindowPath(path)
  }

  // Fetch data on initial render
  componentDidMount() {
    this.fetchData(this.props)
  }

  componentDidUpdate(/*prevProps, prevState*/) {
    const gallery = selectn('response', ProviderHelpers.getEntry(this.props.computeGallery, this._getGalleryPath()))
    const title = selectn('properties.dc:title', gallery)
    const uid = selectn('uid', gallery)

    if (title && selectn('pageTitleParams.galleryName', this.props.properties) != title) {
      this.props.changeTitleParams({ galleryName: title })
      this.props.overrideBreadcrumbs({ find: uid, replace: 'pageTitleParams.galleryName' })
    }
  }

  render() {
    const images = []

    const computeDialect2 = ProviderHelpers.getEntry(this.props.computeDialect2, this.props.routeParams.dialect_path)
    const computeGallery = ProviderHelpers.getEntry(this.props.computeGallery, this._getGalleryPath())
    const toMap = selectn('response.contextParameters.gallery.related_pictures', computeGallery) || []
    toMap.map((picture) => {
      const image = { original: UIHelpers.getThumbnail(picture, 'Medium'), description: picture['dc:description'] }
      images.push(image)
    })

    const computeEntities = Immutable.fromJS([
      {
        id: this._getGalleryPath(),
        entity: this.props.computeGallery,
      },
    ])

    return (
      <DetailsViewWithActions
        labels={{ single: 'Gallery' }}
        itemPath={this._getGalleryPath()}
        actions={['workflow', 'edit', 'publish-toggle', 'enable-toggle', 'publish']}
        publishAction={this.props.publishGallery}
        unpublishAction={this.props.unpublishGallery}
        askToPublishAction={this.props.askToPublishGallery}
        askToUnpublishAction={this.props.askToUnpublishGallery}
        enableAction={this.props.enableGallery}
        askToEnableAction={this.props.askToEnableGallery}
        disableAction={this.props.disableGallery}
        askToDisableAction={this.props.askToDisableGallery}
        deleteAction={this.props.deleteGallery}
        onNavigateRequest={this._onNavigateRequest}
        computeItem={computeGallery}
        permissionEntry={computeDialect2}
        renderOnError
        computeEntities={computeEntities}
        {...this.props}
      >
        <div className="row">
          <div className="col-xs-12" style={{ textAlign: 'center' }}>
            <h1>{selectn('response.title', computeGallery)}</h1>
            <p>{selectn('response.properties.dc:description', computeGallery)}</p>
            <div className={classNames('col-xs-12', 'col-md-4', 'col-md-offset-4')}>
              <div>
                <ImageGallery
                  ref={(i) => (this._imageGallery = i)}
                  items={images}
                  slideInterval={2000}
                  showFullscreenButton
                  showThumbnails={false}
                  showBullets
                />
              </div>
            </div>
          </div>
        </div>
      </DetailsViewWithActions>
    )
  }
}

// REDUX: reducers/state
const mapStateToProps = (state /*, ownProps*/) => {
  const { fvDialect, fvGallery, navigation, nuxeo, windowPath } = state

  const { computeGallery } = fvGallery
  const { properties } = navigation
  const { computeLogin } = nuxeo
  const { computeDialect2 } = fvDialect
  const { splitWindowPath, _windowPath } = windowPath

  return {
    computeDialect2,
    computeGallery,
    computeLogin,
    properties,
    splitWindowPath,
    windowPath: _windowPath,
  }
}

// REDUX: actions/dispatch/func
const mapDispatchToProps = {
  askToDisableGallery,
  askToEnableGallery,
  askToPublishGallery,
  askToUnpublishGallery,
  changeTitleParams,
  disableGallery,
  deleteGallery,
  enableGallery,
  fetchDialect2,
  fetchGallery,
  overrideBreadcrumbs,
  publishGallery,
  pushWindowPath,
  unpublishGallery,
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Gallery)
{'fraction_non_alphanumeric': 0.10786964565248328, 'fraction_numerical': 0.003984630710118116, 'mean_word_length': 3.708542713567839, 'pattern_counts': {'":': 0, '<': 34, '<?xml version=': 0, '>': 40, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '1466096', 'n_tokens_mistral': 4220, 'n_tokens_neox': 4140, 'n_words': 824}