<commit_before>
$(document).ready(function() {
	$.getJSON('/backend/go/' + go_term['id'] + '/locus_details?callback=?', function(data) {
	  	var go_table = create_go_table(data);
	  	create_analyze_button("go_table_analyze", go_table, "" + go_term['display_name'] + " genes", true);
  	    create_download_button("go_table_download", go_table, go_term['display_name'] + "_annotations");

        if(go_term['descendant_locus_count'] > go_term['locus_count']) {
            create_show_child_button("go_table_show_children", go_table, data, '/backend/go/' + go_term['id'] + '/locus_details_all?callback=?', go_data_to_table, function(table_data) {
                var genes = {};
                for (var i=0; i < table_data.length; i++) {
                    genes[table_data[i][1]] = true;
                }
                set_up_header('go_table', table_data.length, 'entry', 'entries', Object.keys(genes).length, 'gene', 'genes');
            });
        }
	});

	$.getJSON('/backend/go/' + go_term['id'] + '/ontology_graph?callback=?', function(data) {
  		var cy = create_cytoscape_vis("cy", layout, graph_style, data);
        create_cy_download_button(cy, "cy_download", go_term['display_name'] + '_ontology')

        if(data['all_children'] != null && data['all_children'].length > 0) {
            var children_div = document.getElementById("children");
            var more_children_div = document.getElementById("children_see_more");
            for(var i=0; i < data['all_children'].length; i++) {
                var a = document.createElement('a');
                a.innerHTML = data['all_children'][i]['display_name'];
                a.href = data['all_children'][i]['link']

                if(i < 20) {
                    children_div.appendChild(a);
                }
                else {
                    more_children_div.appendChild(a);
                }

                if(i != data['all_children'].length-1) {
                    var comma = document.createElement('span');
                    comma.innerHTML = ' • ';
                    if(i < 20) {
                        children_div.appendChild(comma);
                    }
                    else {
                        more_children_div.appendChild(comma);
                    }
                }
            }

            if(data['all_children'].length <= 20) {
                $("#children_see_more_button").hide();
            }
        }
        else {
            $("#children_wrapper").hide()
        }
	});

});

function create_go_table(data) {
	var datatable = [];
	var genes = {};
	for (var i=0; i < data.length; i++) {
        datatable.push(go_data_to_table(data[i], i));
		genes[data[i]["locus"]["id"]] = true;
	}
    set_up_header('go_table', datatable.length, 'entry', 'entries', Object.keys(genes).length, 'gene', 'genes');

	var options = {};
	options["bPaginate"] = true;
	options["aaSorting"] = [[3, "asc"]];
	options["bDestroy"] = true;
	options["oLanguage"] = {"sEmptyTable": "No genes annotated directly to " + go_term['display_name']};
    options["aoColumns"] = [
            {"bSearchable":false, "bVisible":false}, //evidence_id
            {"bSearchable":false, "bVisible":false}, //analyze_id
            null, //gene
            {"bSearchable":false, "bVisible":false}, //gene systematic name
            null, //gene ontology term
            {"bSearchable":false, "bVisible":false}, //gene ontology term id
            null, //qualifier
            {"bSearchable":false, "bVisible":false}, //aspect
            {"bSearchable":false, "bVisible":false}, //method
            null, //evidence
            null, //source
            null, //assigned on
            null, //annotation_extension
            null // reference
            ];
    options["aaData"] = datatable;

    return create_table("go_table", options);
}

var graph_style = cytoscape.stylesheet()
	.selector('node')
	.css({
		'content': 'data(name)',
		'font-family': 'helvetica',
		'font-size': 14,
		'text-outline-width': 3,
		'text-valign': 'center',
		'width': 30,
		'height': 30,
		'border-color': '#fff',
		'background-color': "#43a0df",
		'text-outline-color': '#fff',
		'color': '#888'
	})
	.selector('edge')
	.css({
        'content': 'data(name)',
		'font-family': 'helvetica',
		'font-size': 12,
        'color': 'grey',
		'width': 2,
		'source-arrow-shape': 'triangle'
	})
	.selector("node[sub_type='FOCUS']")
	.css({
		'width': 30,
		'height': 30,
		'background-color': "#fade71",
		'text-outline-color': '#fff',
		'color': '#888'
	})
    .selector("node[id='NodeMoreChildren']")
	.css({
		'width': 30,
		'height': 30,
        'shape': 'rectangle'
	});
//	.selector("node[sub_type='HAS_CHILDREN']")
//	.css(
//		{'background-color': "#165782"
//	})
//	.selector("node[sub_type='HAS_DESCENDANTS']")
//	.css(
//		{'background-color': "#43a0df"
//	})
//	.selector("node[sub_type='NO_DESCENDANTS']")
//	.css(
//		{'background-color': "#c9e4f6"
//	});

var layout = {
    "name": "breadthfirst",
	"fit": true,
    "directed": true
};
<commit_msg>another cyto fix<commit_after>
$(document).ready(function() {
	$.getJSON('/backend/go/' + go_term['id'] + '/locus_details?callback=?', function(data) {
	  	var go_table = create_go_table(data);
	  	create_analyze_button("go_table_analyze", go_table, "" + go_term['display_name'] + " genes", true);
  	    create_download_button("go_table_download", go_table, go_term['display_name'] + "_annotations");

        if(go_term['descendant_locus_count'] > go_term['locus_count']) {
            create_show_child_button("go_table_show_children", go_table, data, '/backend/go/' + go_term['id'] + '/locus_details_all?callback=?', go_data_to_table, function(table_data) {
                var genes = {};
                for (var i=0; i < table_data.length; i++) {
                    genes[table_data[i][1]] = true;
                }
                set_up_header('go_table', table_data.length, 'entry', 'entries', Object.keys(genes).length, 'gene', 'genes');
            });
        }
	});

	$.getJSON('/backend/go/' + go_term['id'] + '/ontology_graph?callback=?', function(data) {
  		var cy = create_cytoscape_vis("cy", layout, graph_style, data, null, false, "goOntology");
        create_cy_download_button(cy, "cy_download", go_term['display_name'] + '_ontology')

        if(data['all_children'] != null && data['all_children'].length > 0) {
            var children_div = document.getElementById("children");
            var more_children_div = document.getElementById("children_see_more");
            for(var i=0; i < data['all_children'].length; i++) {
                var a = document.createElement('a');
                a.innerHTML = data['all_children'][i]['display_name'];
                a.href = data['all_children'][i]['link']

                if(i < 20) {
                    children_div.appendChild(a);
                }
                else {
                    more_children_div.appendChild(a);
                }

                if(i != data['all_children'].length-1) {
                    var comma = document.createElement('span');
                    comma.innerHTML = ' • ';
                    if(i < 20) {
                        children_div.appendChild(comma);
                    }
                    else {
                        more_children_div.appendChild(comma);
                    }
                }
            }

            if(data['all_children'].length <= 20) {
                $("#children_see_more_button").hide();
            }
        }
        else {
            $("#children_wrapper").hide()
        }
	});

});

function create_go_table(data) {
	var datatable = [];
	var genes = {};
	for (var i=0; i < data.length; i++) {
        datatable.push(go_data_to_table(data[i], i));
		genes[data[i]["locus"]["id"]] = true;
	}
    set_up_header('go_table', datatable.length, 'entry', 'entries', Object.keys(genes).length, 'gene', 'genes');

	var options = {};
	options["bPaginate"] = true;
	options["aaSorting"] = [[3, "asc"]];
	options["bDestroy"] = true;
	options["oLanguage"] = {"sEmptyTable": "No genes annotated directly to " + go_term['display_name']};
    options["aoColumns"] = [
            {"bSearchable":false, "bVisible":false}, //evidence_id
            {"bSearchable":false, "bVisible":false}, //analyze_id
            null, //gene
            {"bSearchable":false, "bVisible":false}, //gene systematic name
            null, //gene ontology term
            {"bSearchable":false, "bVisible":false}, //gene ontology term id
            null, //qualifier
            {"bSearchable":false, "bVisible":false}, //aspect
            {"bSearchable":false, "bVisible":false}, //method
            null, //evidence
            null, //source
            null, //assigned on
            null, //annotation_extension
            null // reference
            ];
    options["aaData"] = datatable;

    return create_table("go_table", options);
}

var graph_style = cytoscape.stylesheet()
	.selector('node')
	.css({
		'content': 'data(name)',
		'font-family': 'helvetica',
		'font-size': 14,
		'text-outline-width': 3,
		'text-valign': 'center',
		'width': 30,
		'height': 30,
		'border-color': '#fff',
		'background-color': "#43a0df",
		'text-outline-color': '#fff',
		'color': '#888'
	})
	.selector('edge')
	.css({
        'content': 'data(name)',
		'font-family': 'helvetica',
		'font-size': 12,
        'color': 'grey',
		'width': 2,
		'source-arrow-shape': 'triangle'
	})
	.selector("node[sub_type='FOCUS']")
	.css({
		'width': 30,
		'height': 30,
		'background-color': "#fade71",
		'text-outline-color': '#fff',
		'color': '#888'
	})
    .selector("node[id='NodeMoreChildren']")
	.css({
		'width': 30,
		'height': 30,
        'shape': 'rectangle'
	});
//	.selector("node[sub_type='HAS_CHILDREN']")
//	.css(
//		{'background-color': "#165782"
//	})
//	.selector("node[sub_type='HAS_DESCENDANTS']")
//	.css(
//		{'background-color': "#43a0df"
//	})
//	.selector("node[sub_type='NO_DESCENDANTS']")
//	.css(
//		{'background-color': "#c9e4f6"
//	});

var layout = {
    "name": "breadthfirst",
	"fit": true,
    "directed": true
};
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react'
import GMap from 'shared/components/addon/maps/gmap'
import { isEmpty } from 'lodash'
import moment from 'moment'
import { getFileName, getFileExt, checkImageFile } from 'shared/utils/file-utils'
import classNames from 'classnames'
import { PostPropArray } from 'shared/utils/forms'
import { at } from 'lodash'
import { Link } from 'react-router'
import { originLocaleName, fixLocaleName } from 'shared/utils/locale-utils'
import Linkify from 'react-linkify'
import ADContent from './ADContent'
import Carousel from 'nuka-carousel'
import { Lightbox } from 'shared/components/addon/lightbox'
import {
  toMoment,
  isBetween,
  isPastDay,
  toShortDate,
  toYear
} from 'shared/utils/date-utils'
import {
  ShareButtons,
  generateShareIcon
} from 'react-share'

let swal
if (process.env.BROWSER) {
  swal = require('sweetalert')
}

let line
if (process.env.BROWSER) {
  line = require('react-line-social')
}

export default class Post extends Component {

  static propTypes = {
    auth: PropTypes.object.isRequired,
    post: PropTypes.object.isRequired,
    moreList: PropTypes.object.isRequired,
    map: PropTypes.object.isRequired,
    remove: PropTypes.func.isRequired,
    _T: PropTypes.func.isRequired,
    defaultLocale: PropTypes.string.isRequired,
    shareInfo: PropTypes.object.isRequired
  }

  static contextTypes = {
    history: PropTypes.object.isRequired
  }

  constructor (props) {
    super(props)

    this.releaseTimeout = undefined
  }

  componentWillUnmount () {
    if (this.op) {
      clearTimeout(this.releaseTimeout)
    }
  }

  removeTags (html) {
    const pattern = /(<([^>]+)>)/ig;
    return html.replace(pattern , '')
  }

  parseContent (content) {
    const ent = require('ent')
    const linkProps = {
      'target': '_blank'
    }
    if (content) {
      return (
        content.replace(/^\"|\"$/g, '').split('\n').map((t, i) => {
          return t === ''
            ?

            :
<Linkify properties={linkProps}>{ent.decode(this.removeTags(t))}</Linkify>

        })
      )
    }
  }

  deletePost = () => {
    const { post, remove, _T } = this.props
    const { detail } = post
    const { transitionTo, createLocation } = this.context.history
    swal({
      title: _T('post.detail.delete.title'),
      text: _T('post.detail.delete.text'),
      type: 'warning',
      showCancelButton: true,
      confirmButtonText: _T('post.detail.delete.confirm'),
      cancelButtonText: _T('post.detail.delete.cancel'),
      closeOnConfirm: false,
      showLoaderOnConfirm: true
    }, () => {
      Promise.all([
        remove(detail.id)
      ]).then((res) => {
        if (res[0].type === 'REMOVE_POST_COMPLETED') {
          swal({
            title: _T('post.detail.delete.ok.title'),
            text: _T('post.detail.delete.ok.text'),
            type: 'success',
            confirmButtonText: _T('post.detail.delete.ok.confirm'),
            closeOnConfirm: true
          }, () => {
            transitionTo(createLocation('/w'))
          })
        } else {
          swal(_T('post.detail.delete.err.title')
            , _T('post.detail.delete.err.text'),
            'error')
        }
      })
    })
  }

  handleImgClick (src, event) {
    Lightbox.show(

    )
  }

  renderDetailProp (detail) {
    return (

        {at(PostPropArray(originLocaleName(this.props.defaultLocale)), detail.prop)}

    )
  }

  renderRegisterInfo (detail) {
    if (!detail.url) return

    const Translate = require('react-translate-component')
    const open = toMoment(detail.openDate)
    const close = toMoment(detail.closeDate)
    const now = moment()

    if (now.isBetween(open, close)) {
      return (

            <Translate content="post.detail.open" />

      )
    } else if (now.isAfter(close)) {
      return (

            <Translate content="post.detail.close" />

      )
    }
  }

  renderImageAttachments () {
    const { detail } = this.props.post
    const files = typeof detail.file !== 'undefined'
      ? JSON.parse(detail.file)
      : []

    const imgs = []
    files && files.map(function (file) {
      if (checkImageFile(file)) {
        imgs.push(file)
      }
    })
    if (!isEmpty(imgs)) {
      return (

          <Carousel cellAlign="center" slideWidth="100%">
          {
            imgs.map(function (link) {
              if (checkImageFile(link)) {
                const src = '/uploads/' + link
                return (

                )
              } else {
                return (
)
              }
            }.bind(this))
          }
          </Carousel>

      )
    }

    return (

    )
  }

  renderLineShare () {
    if (line) {
      return
<line.Share type={'c'} />

    } else {
      return

    }
  }

  renderMoreList () {
    const { titleList, isFetching } = this.props.moreList
    if (isFetching) {
      return (

      )
    } else {
      return (

            { !isEmpty(titleList) && titleList.map(function (item, i) {
              return (

                  <Link to={`/w/${item.id}`}>

                      { toShortDate(item.startDate) }

                    { item.title }
                  </Link>

              )})
            }

      )
    }
  }

  render () {
    const Translate = require('react-translate-component')
    const { defaultLocale } = this.props

    if (!isEmpty(this.props.post.errors)) {
      return (

              <Translate content="post.detail.noexist" />

      )
    } else {
      const directionMode = true
      const {
        FacebookShareButton,
        GooglePlusShareButton,
        LinkedinShareButton,
        TwitterShareButton,
        PinterestShareButton,
        VKShareButton
      } = ShareButtons
      const FacebookIcon = generateShareIcon('facebook')
      const TwitterIcon = generateShareIcon('twitter')
      const GooglePlusIcon = generateShareIcon('google')
      const LinkedinIcon = generateShareIcon('linkedin')
      const { shareInfo } = this.props
      const shareIconSize = 32

      const { detail } = this.props.post
      const { content } = detail
      const files = typeof detail.file !== 'undefined'
        ? JSON.parse(detail.file)
        : []

      const detailClass = classNames('content', { hide: !detail.id })

      const finalContent = this.parseContent(content)

      const eventDate = (detail.startDate === detail.endDate)
      ? toShortDate(detail.endDate)
      : toShortDate(detail.startDate) + ' - ' + toShortDate(detail.endDate)

      let eventEndYear =
        toYear(detail.endDate) > toYear(new Date())
        ? toYear(detail.endDate)
        : null

      const eventStartYear =
        toYear(detail.startDate) < toYear(new Date())
        ? toYear(detail.startDate)
        : null

      if (eventStartYear && toYear(detail.endDate) === toYear(new Date())) {
        eventEndYear = <Translate content="post.detail.this_year" />
      }

      const mainClasses = classNames(
        'ui',
        'two',
        'column',
        'post',
        'detail',
        'stackable',
        'has-header',
        'grid',
        'container'
      )

      return (

                  {this.props.post.isFetching && !detail.id &&

                  }

                    {eventDate && (

                          {eventDate}

                      )}

                      {eventStartYear && (

                          {eventStartYear}
                          { eventEndYear
                            && <Translate content="post.detail.start" /> }

                      )}
                      {eventEndYear && (

                            <Translate content="post.detail.end" /> {eventEndYear}

                      )}

                      {detail.title}

                      {finalContent}
                      { files && !isEmpty(files)
                        &&

                          <Translate content="post.detail.attachments" />

 }

                      {
                        files && !isEmpty(files)
                        && files.map(function (file, i) {
                          return (

                                      { getFileName(file) }

                          )
                        })
                      }

                      <FacebookShareButton {...shareInfo}>
                        <FacebookIcon size={shareIconSize} round />
                      </FacebookShareButton>
                      <GooglePlusShareButton {...shareInfo}>
                        <GooglePlusIcon size={shareIconSize} round />
                      </GooglePlusShareButton>
                      <LinkedinShareButton {...shareInfo}>
                        <LinkedinIcon size={shareIconSize} round />
                      </LinkedinShareButton> |
                      <TwitterShareButton {...shareInfo}>
                        <TwitterIcon size={shareIconSize} round />
                      </TwitterShareButton>
                      { this.renderLineShare(fixLocaleName(defaultLocale)) }

                        {this.renderDetailProp(detail)}

                  {!isEmpty(detail.uid)
                    && this.props.auth.user.id === detail.uid &&

                      <Link
                        className="ui basic green button"
                        to={`/post/${detail.id}/edit`}>
                        <Translate content="post.detail.edit" />
                      </Link>

                        <Translate content="post.detail.delete.confirm" />

                  }

                { this.renderImageAttachments() }

                {this.renderRegisterInfo(detail)}

              {(detail.cid > 0) && (

                <Link
                  className="ui orange fluid large top attached button"
                  to={`/c/${detail.cid}`}>
                  {detail.ocname}
                </Link>

              )}

                { (detail.lat && detail.lat) &&
                <GMap
                  ref="gmap"
                  {...this.props.map}
                  directionMode={directionMode}
                  defaultLocale={this.props.defaultLocale}
                />
                }
                {this.renderMoreList()}

                <ADContent />

      )
    }
  }
}
<commit_msg>Remove google plus share button<commit_after>import React, { Component, PropTypes } from 'react'
import GMap from 'shared/components/addon/maps/gmap'
import { isEmpty } from 'lodash'
import moment from 'moment'
import { getFileName, getFileExt, checkImageFile } from 'shared/utils/file-utils'
import classNames from 'classnames'
import { PostPropArray } from 'shared/utils/forms'
import { at } from 'lodash'
import { Link } from 'react-router'
import { originLocaleName, fixLocaleName } from 'shared/utils/locale-utils'
import Linkify from 'react-linkify'
import ADContent from './ADContent'
import Carousel from 'nuka-carousel'
import { Lightbox } from 'shared/components/addon/lightbox'
import {
  toMoment,
  isBetween,
  isPastDay,
  toShortDate,
  toYear
} from 'shared/utils/date-utils'
import {
  ShareButtons,
  generateShareIcon
} from 'react-share'

let swal
if (process.env.BROWSER) {
  swal = require('sweetalert')
}

let line
if (process.env.BROWSER) {
  line = require('react-line-social')
}

export default class Post extends Component {

  static propTypes = {
    auth: PropTypes.object.isRequired,
    post: PropTypes.object.isRequired,
    moreList: PropTypes.object.isRequired,
    map: PropTypes.object.isRequired,
    remove: PropTypes.func.isRequired,
    _T: PropTypes.func.isRequired,
    defaultLocale: PropTypes.string.isRequired,
    shareInfo: PropTypes.object.isRequired
  }

  static contextTypes = {
    history: PropTypes.object.isRequired
  }

  constructor (props) {
    super(props)

    this.releaseTimeout = undefined
  }

  componentWillUnmount () {
    if (this.op) {
      clearTimeout(this.releaseTimeout)
    }
  }

  removeTags (html) {
    const pattern = /(<([^>]+)>)/ig;
    return html.replace(pattern , '')
  }

  parseContent (content) {
    const ent = require('ent')
    const linkProps = {
      'target': '_blank'
    }
    if (content) {
      return (
        content.replace(/^\"|\"$/g, '').split('\n').map((t, i) => {
          return t === ''
            ?

            :
<Linkify properties={linkProps}>{ent.decode(this.removeTags(t))}</Linkify>

        })
      )
    }
  }

  deletePost = () => {
    const { post, remove, _T } = this.props
    const { detail } = post
    const { transitionTo, createLocation } = this.context.history
    swal({
      title: _T('post.detail.delete.title'),
      text: _T('post.detail.delete.text'),
      type: 'warning',
      showCancelButton: true,
      confirmButtonText: _T('post.detail.delete.confirm'),
      cancelButtonText: _T('post.detail.delete.cancel'),
      closeOnConfirm: false,
      showLoaderOnConfirm: true
    }, () => {
      Promise.all([
        remove(detail.id)
      ]).then((res) => {
        if (res[0].type === 'REMOVE_POST_COMPLETED') {
          swal({
            title: _T('post.detail.delete.ok.title'),
            text: _T('post.detail.delete.ok.text'),
            type: 'success',
            confirmButtonText: _T('post.detail.delete.ok.confirm'),
            closeOnConfirm: true
          }, () => {
            transitionTo(createLocation('/w'))
          })
        } else {
          swal(_T('post.detail.delete.err.title')
            , _T('post.detail.delete.err.text'),
            'error')
        }
      })
    })
  }

  handleImgClick (src, event) {
    Lightbox.show(

    )
  }

  renderDetailProp (detail) {
    return (

        {at(PostPropArray(originLocaleName(this.props.defaultLocale)), detail.prop)}

    )
  }

  renderRegisterInfo (detail) {
    if (!detail.url) return

    const Translate = require('react-translate-component')
    const open = toMoment(detail.openDate)
    const close = toMoment(detail.closeDate)
    const now = moment()

    if (now.isBetween(open, close)) {
      return (

            <Translate content="post.detail.open" />

      )
    } else if (now.isAfter(close)) {
      return (

            <Translate content="post.detail.close" />

      )
    }
  }

  renderImageAttachments () {
    const { detail } = this.props.post
    const files = typeof detail.file !== 'undefined'
      ? JSON.parse(detail.file)
      : []

    const imgs = []
    files && files.map(function (file) {
      if (checkImageFile(file)) {
        imgs.push(file)
      }
    })
    if (!isEmpty(imgs)) {
      return (

          <Carousel cellAlign="center" slideWidth="100%">
          {
            imgs.map(function (link) {
              if (checkImageFile(link)) {
                const src = '/uploads/' + link
                return (

                )
              } else {
                return (
)
              }
            }.bind(this))
          }
          </Carousel>

      )
    }

    return (

    )
  }

  renderLineShare () {
    if (line) {
      return
<line.Share type={'c'} />

    } else {
      return

    }
  }

  renderMoreList () {
    const { titleList, isFetching } = this.props.moreList
    if (isFetching) {
      return (

      )
    } else {
      return (

            { !isEmpty(titleList) && titleList.map(function (item, i) {
              return (

                  <Link to={`/w/${item.id}`}>

                      { toShortDate(item.startDate) }

                    { item.title }
                  </Link>

              )})
            }

      )
    }
  }

  render () {
    const Translate = require('react-translate-component')
    const { defaultLocale } = this.props

    if (!isEmpty(this.props.post.errors)) {
      return (

              <Translate content="post.detail.noexist" />

      )
    } else {
      const directionMode = true
      const {
        FacebookShareButton,
        GooglePlusShareButton,
        LinkedinShareButton,
        TwitterShareButton,
        PinterestShareButton,
        VKShareButton
      } = ShareButtons
      const FacebookIcon = generateShareIcon('facebook')
      const TwitterIcon = generateShareIcon('twitter')
      const LinkedinIcon = generateShareIcon('linkedin')
      const { shareInfo } = this.props
      const shareIconSize = 32

      const { detail } = this.props.post
      const { content } = detail
      const files = typeof detail.file !== 'undefined'
        ? JSON.parse(detail.file)
        : []

      const detailClass = classNames('content', { hide: !detail.id })

      const finalContent = this.parseContent(content)

      const eventDate = (detail.startDate === detail.endDate)
      ? toShortDate(detail.endDate)
      : toShortDate(detail.startDate) + ' - ' + toShortDate(detail.endDate)

      let eventEndYear =
        toYear(detail.endDate) > toYear(new Date())
        ? toYear(detail.endDate)
        : null

      const eventStartYear =
        toYear(detail.startDate) < toYear(new Date())
        ? toYear(detail.startDate)
        : null

      if (eventStartYear && toYear(detail.endDate) === toYear(new Date())) {
        eventEndYear = <Translate content="post.detail.this_year" />
      }

      const mainClasses = classNames(
        'ui',
        'two',
        'column',
        'post',
        'detail',
        'stackable',
        'has-header',
        'grid',
        'container'
      )

      return (

                  {this.props.post.isFetching && !detail.id &&

                  }

                    {eventDate && (

                          {eventDate}

                      )}

                      {eventStartYear && (

                          {eventStartYear}
                          { eventEndYear
                            && <Translate content="post.detail.start" /> }

                      )}
                      {eventEndYear && (

                            <Translate content="post.detail.end" /> {eventEndYear}

                      )}

                      {detail.title}

                      {finalContent}
                      { files && !isEmpty(files)
                        &&

                          <Translate content="post.detail.attachments" />

 }

                      {
                        files && !isEmpty(files)
                        && files.map(function (file, i) {
                          return (

                                      { getFileName(file) }

                          )
                        })
                      }

                      <FacebookShareButton {...shareInfo}>
                        <FacebookIcon size={shareIconSize} round />
                      </FacebookShareButton>
                      <LinkedinShareButton {...shareInfo}>
                        <LinkedinIcon size={shareIconSize} round />
                      </LinkedinShareButton> |
                      <TwitterShareButton {...shareInfo}>
                        <TwitterIcon size={shareIconSize} round />
                      </TwitterShareButton>
                      { this.renderLineShare(fixLocaleName(defaultLocale)) }

                        {this.renderDetailProp(detail)}

                  {!isEmpty(detail.uid)
                    && this.props.auth.user.id === detail.uid &&

                      <Link
                        className="ui basic green button"
                        to={`/post/${detail.id}/edit`}>
                        <Translate content="post.detail.edit" />
                      </Link>

                        <Translate content="post.detail.delete.confirm" />

                  }

                { this.renderImageAttachments() }

                {this.renderRegisterInfo(detail)}

              {(detail.cid > 0) && (

                <Link
                  className="ui orange fluid large top attached button"
                  to={`/c/${detail.cid}`}>
                  {detail.ocname}
                </Link>

              )}

                { (detail.lat && detail.lat) &&
                <GMap
                  ref="gmap"
                  {...this.props.map}
                  directionMode={directionMode}
                  defaultLocale={this.props.defaultLocale}
                />
                }
                {this.renderMoreList()}

                <ADContent />

      )
    }
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright 2015-2016 OpenCB
 *
 * 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 {LitElement, html, nothing} from "lit";
import UtilsNew from "../../core/utilsNew.js";
import LitUtils from "./utils/lit-utils.js";
import "./opencga-facet-result-view.js";
import "./opencga-active-filters.js";
import "./forms/select-field-filter.js";
import "./opencb-facet-results.js";
import "./facet-filter.js";
import "../loading-spinner.js";
import "./tool-header.js";

export default class OpencgaBrowser extends LitElement {

    constructor() {
        super();
        this.#init();
    }

    createRenderRoot() {
        return this;
    }

    static get properties() {
        return {
            resource: {
                type: String
            },
            opencgaSession: {
                type: Object
            },
            cellbaseClient: {
                type: Object
            },
            query: {
                type: Object
            },
            // query object sent to Opencga client (includes this.selectedFacet serialised)
            facetQuery: {
                type: Object
            },
            // complex object that keeps track of the values of all facets
            selectedFacet: {
                type: Object
            },
            config: {
                type: Object
            }
        };
    }

    #init() {
        this._prefix = "facet" + UtilsNew.randomString(6);

        this.query = {};
        this.preparedQuery = {};
        this.executedQuery = {};

        this.activeView = "";

        this.activeFilterAlias = {};

        this.selectedFacet = {};
        this.preparedFacetQueryFormatted = {};
        this.detail = {};
    }

    firstUpdated() {
        $(".bootstrap-select", this).selectpicker();
        UtilsNew.initTooltip(this);
    }

    update(changedProperties) {
        if (changedProperties.has("opencgaSession")) {
            this.opencgaSessionObserver();
        }

        if (changedProperties.has("query")) {
            this.queryObserver();
        }

        if (changedProperties.has("selectedFacet")) {
            this.facetQueryBuilder();
        }

        if (changedProperties.has("config")) {
            this.configObserver();
        }

        super.update(changedProperties);
    }

    opencgaSessionObserver() {
        if (this?.opencgaSession?.study?.fqn) {
            this.query = {
                study: this.opencgaSession.study.fqn,
            };
            this.preparedQuery = {
                study: this.opencgaSession.study.fqn,
            };
            this.facetQuery = null;
            this.preparedFacetQueryFormatted = null;
        }
    }

    queryObserver() {
        if (this?.opencgaSession?.study?.fqn) {
            // NOTE UtilsNew.objectCompare avoid repeating remote requests.
            if (!UtilsNew.objectCompare(this.query, this._query)) {
                this._query = this.query;
                if (this.query) {
                    this.preparedQuery = {study: this.opencgaSession.study.fqn, ...this.query};
                    this.executedQuery = {study: this.opencgaSession.study.fqn, ...this.query};
                } else {
                    this.preparedQuery = {study: this.opencgaSession.study.fqn};
                    this.executedQuery = {study: this.opencgaSession.study.fqn};
                }
                // onServerFilterChange() in opencga-active-filters fires an activeFilterChange event when the Filter dropdown is used
                LitUtils.dispatchCustomEvent(this, "queryChange", undefined, {
                    ...this.preparedQuery,
                });
                this.detail = {};
            }
        }
    }

    configObserver() {
        if (this.config?.views) {
            const defaultActiveView = this.config.views.find(view => view.active);
            if (defaultActiveView) {
                this.activeView = defaultActiveView.id;
            }
        }
    }

    facetQueryBuilder() {
        this.facetQuery = null;

        if (Object.keys(this.selectedFacet).length) {
            this.executedFacetQueryFormatted = {...this.preparedFacetQueryFormatted};

            this.facetQuery = {
                ...this.preparedQuery,
                study: this.opencgaSession.study.fqn,
                field: Object.values(this.preparedFacetQueryFormatted).map(v => v.formatted).join(";")
            };
            this.changeView("facet-tab");
        }
    }

    notifySearch(query) {
        LitUtils.dispatchCustomEvent(this, "querySearch", undefined, {
            query: query
        });
    }

    async onRun() {
        // NOTE notifySearch() triggers this chain: notifySearch -> onQueryFilterSearch() on iva-app.js -> this.queries updated -> queryObserver() in opencga-browser
        // queryObserver() here stops the repetition of the remote request by checking if it has changed
        // TODO do the same with facetQuery
        this.query = {...this.preparedQuery};
        // updates this.queries in iva-app
        this.notifySearch(this.preparedQuery);

        this.facetQueryBuilder();
    }

    onFilterChange(e) {
        this.query = e.detail;
    }

    changeView(id) {
        this.activeView = id;
        this.requestUpdate();
    }

    onQueryFilterChange(e) {
        // console.log("onQueryFilterChange")
        this.preparedQuery = e.detail.query;
        this.requestUpdate();
    }

    // TODO review
    // this is used only in case of Search button inside filter component. Only in Clinical Analysis Browser.
    onQueryFilterSearch(e) {
        LitUtils.dispatchCustomEvent(this, "querySearch", undefined, {
            query: e.detail.query,
        });
    }

    onActiveFilterChange(e) {
        // console.log("onActiveFilterChange");
        this.preparedQuery = {study: this.opencgaSession.study.fqn, ...e.detail};
        this.query = {study: this.opencgaSession.study.fqn, ...e.detail};
        this.facetQueryBuilder();
    }

    onActiveFilterClear() {
        // console.log("onActiveFilterClear");
        this.query = {study: this.opencgaSession.study.fqn};
        this.preparedQuery = {...this.query};
        this.facetQueryBuilder();
    }

    onFacetQueryChange(e) {
        // console.log("onFacetQueryChange");
        this.preparedFacetQueryFormatted = e.detail.value;
        // this.facetQueryBuilder();
        this.requestUpdate();
    }

    onActiveFacetChange(e) {
        this.selectedFacet = {...e.detail};
        this.preparedFacetQueryFormatted = {...e.detail};
        // this.onRun(); // TODO the query should be repeated every action on active-filter (delete, clear, load from Saved filter)
        this.facetQueryBuilder();
        this.requestUpdate();
    }

    onActiveFacetClear() {
        this.selectedFacet = {};
        this.onRun();
        this.requestUpdate();
    }

    onClickRow(e, resource) {
        this.detail = {
            ...this.detail,
            [resource]: e.detail.row,
        };
        this.requestUpdate();
    }

    renderView() {
        if (!this.config.views) {
            return html`No view has been configured`;
        }

        return this.config.views.map(view => html`

                ${view.render({
                    opencgaSession: this.opencgaSession,
                    config: this.config,
                    executedQuery: this.executedQuery,
                    detail: this.detail,
                    resource: this.resource,
                    facetQuery: this.facetQuery,
                    facetResults: this.facetResults,
                    eventNotifyName: this.eventNotifyName,
                    active: this.activeView === view.id,
                    onClickRow: (e, eventName) => this.onClickRow(e, eventName),
                })}

        `);
    }

    renderfilter() {
        if (typeof this.config?.filter?.render !== "function") {
            return html`${nothing}`;
        }

        return html`

                ${this.config.filter.render({
                    opencgaSession: this.opencgaSession,
                    config: this.config,
                    query: this.query,
                    onQueryFilterChange: this.onQueryFilterChange,
                    onQueryFilterSearch: this.onQueryFilterSearch,
                })}

        `;
    }

    renderAggregation() {
        if (typeof this.config?.aggregation?.render !== "function") {
            return html`${nothing}`;
        }

        return html `

                ${this.config.aggregation.render({
                    config: this.config,
                    selectedFacet: this.selectedFacet,
                    onFacetQueryChange: this.onFacetQueryChange,
                })}

        `;
    }

    renderButtonViews() {
        return html `

                    ${(this.config.views || []).map(view => html`
                        <button
                            type="button"
                            class="btn btn-success content-pills ${this.activeView === view.id ? "active" : ""}"
                            ?disabled=${view.disabled}
                            @click="${() => this.changeView(view.id)}">

                            ${view.name}
                        </button>
                    `)}

        `;
    }

    render() {
        if (!this.opencgaSession?.study?.fqn) {
            return html`

No public projects available to browse. Please login to continue

            `;
        }

        return html`
            <tool-header
                .title="${this.config.title}"
                .icon="${this.config.icon}">
            </tool-header>

                        <button type="button" class="btn btn-primary ripple" @click="${this.onRun}">

                            ${this.config.searchButtonText || "Search"}
                        </button>

                            Filters

                        ${this.config.aggregation ? html`

                                Aggregation

                        ` : null}

                        ${this.renderfilter()}
                        ${this.renderAggregation()}

                    ${this.renderButtonViews()}

                        <opencga-active-filters
                            facetActive
                            .resource="${this.resource}"
                            .opencgaSession="${this.opencgaSession}"
                            .defaultStudy="${this.opencgaSession?.study?.fqn}"
                            .query="${this.preparedQuery}"
                            .executedQuery="${this.executedQuery}"
                            .facetQuery="${this.preparedFacetQueryFormatted}"
                            .executedFacetQuery="${this.executedFacetQueryFormatted}"
                            .alias="${this.activeFilterAlias}"
                            .config="${this.config.activeFilters}"
                            .filters="${this.config.filter.examples}"
                            @activeFilterChange="${this.onActiveFilterChange}"
                            @activeFilterClear="${this.onActiveFilterClear}"
                            @activeFacetChange="${this.onActiveFacetChange}"
                            @activeFacetClear="${this.onActiveFacetClear}">
                        </opencga-active-filters>

                            ${this.renderView()}

        `;
    }

}

customElements.define("opencga-browser", OpencgaBrowser);
<commit_msg>wc: minor ui improvements in opencga-browser #TASK-615<commit_after>/*
 * Copyright 2015-2016 OpenCB
 *
 * 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 {LitElement, html, nothing} from "lit";
import UtilsNew from "../../core/utilsNew.js";
import LitUtils from "./utils/lit-utils.js";
import "./opencga-facet-result-view.js";
import "./opencga-active-filters.js";
import "./forms/select-field-filter.js";
import "./opencb-facet-results.js";
import "./facet-filter.js";
import "../loading-spinner.js";
import "./tool-header.js";

export default class OpencgaBrowser extends LitElement {

    constructor() {
        super();
        this.#init();
    }

    createRenderRoot() {
        return this;
    }

    static get properties() {
        return {
            resource: {
                type: String
            },
            opencgaSession: {
                type: Object
            },
            cellbaseClient: {
                type: Object
            },
            query: {
                type: Object
            },
            // query object sent to Opencga client (includes this.selectedFacet serialised)
            facetQuery: {
                type: Object
            },
            // complex object that keeps track of the values of all facets
            selectedFacet: {
                type: Object
            },
            config: {
                type: Object
            }
        };
    }

    #init() {
        this._prefix = "facet" + UtilsNew.randomString(6);

        this.query = {};
        this.preparedQuery = {};
        this.executedQuery = {};

        this.activeView = "";

        this.activeFilterAlias = {};

        this.selectedFacet = {};
        this.preparedFacetQueryFormatted = {};
        this.detail = {};
    }

    firstUpdated() {
        $(".bootstrap-select", this).selectpicker();
        UtilsNew.initTooltip(this);
    }

    update(changedProperties) {
        if (changedProperties.has("opencgaSession")) {
            this.opencgaSessionObserver();
        }

        if (changedProperties.has("query")) {
            this.queryObserver();
        }

        if (changedProperties.has("selectedFacet")) {
            this.facetQueryBuilder();
        }

        if (changedProperties.has("config")) {
            this.configObserver();
        }

        super.update(changedProperties);
    }

    opencgaSessionObserver() {
        if (this?.opencgaSession?.study?.fqn) {
            this.query = {
                study: this.opencgaSession.study.fqn,
            };
            this.preparedQuery = {
                study: this.opencgaSession.study.fqn,
            };
            this.facetQuery = null;
            this.preparedFacetQueryFormatted = null;
        }
    }

    queryObserver() {
        if (this?.opencgaSession?.study?.fqn) {
            // NOTE UtilsNew.objectCompare avoid repeating remote requests.
            if (!UtilsNew.objectCompare(this.query, this._query)) {
                this._query = this.query;
                if (this.query) {
                    this.preparedQuery = {study: this.opencgaSession.study.fqn, ...this.query};
                    this.executedQuery = {study: this.opencgaSession.study.fqn, ...this.query};
                } else {
                    this.preparedQuery = {study: this.opencgaSession.study.fqn};
                    this.executedQuery = {study: this.opencgaSession.study.fqn};
                }
                // onServerFilterChange() in opencga-active-filters fires an activeFilterChange event when the Filter dropdown is used
                LitUtils.dispatchCustomEvent(this, "queryChange", undefined, {
                    ...this.preparedQuery,
                });
                this.detail = {};
            }
        }
    }

    configObserver() {
        if (this.config?.views) {
            const defaultActiveView = this.config.views.find(view => view.active);
            if (defaultActiveView) {
                this.activeView = defaultActiveView.id;
            }
        }
    }

    facetQueryBuilder() {
        this.facetQuery = null;

        if (Object.keys(this.selectedFacet).length) {
            this.executedFacetQueryFormatted = {...this.preparedFacetQueryFormatted};

            this.facetQuery = {
                ...this.preparedQuery,
                study: this.opencgaSession.study.fqn,
                field: Object.values(this.preparedFacetQueryFormatted).map(v => v.formatted).join(";")
            };
            this.changeView("facet-tab");
        }
    }

    notifySearch(query) {
        LitUtils.dispatchCustomEvent(this, "querySearch", undefined, {
            query: query
        });
    }

    async onRun() {
        // NOTE notifySearch() triggers this chain: notifySearch -> onQueryFilterSearch() on iva-app.js -> this.queries updated -> queryObserver() in opencga-browser
        // queryObserver() here stops the repetition of the remote request by checking if it has changed
        // TODO do the same with facetQuery
        this.query = {...this.preparedQuery};
        // updates this.queries in iva-app
        this.notifySearch(this.preparedQuery);

        this.facetQueryBuilder();
    }

    onFilterChange(e) {
        this.query = e.detail;
    }

    changeView(id) {
        this.activeView = id;
        this.requestUpdate();
    }

    onQueryFilterChange(e) {
        // console.log("onQueryFilterChange")
        this.preparedQuery = e.detail.query;
        this.requestUpdate();
    }

    // TODO review
    // this is used only in case of Search button inside filter component. Only in Clinical Analysis Browser.
    onQueryFilterSearch(e) {
        LitUtils.dispatchCustomEvent(this, "querySearch", undefined, {
            query: e.detail.query,
        });
    }

    onActiveFilterChange(e) {
        // console.log("onActiveFilterChange");
        this.preparedQuery = {study: this.opencgaSession.study.fqn, ...e.detail};
        this.query = {study: this.opencgaSession.study.fqn, ...e.detail};
        this.facetQueryBuilder();
    }

    onActiveFilterClear() {
        // console.log("onActiveFilterClear");
        this.query = {study: this.opencgaSession.study.fqn};
        this.preparedQuery = {...this.query};
        this.facetQueryBuilder();
    }

    onFacetQueryChange(e) {
        // console.log("onFacetQueryChange");
        this.preparedFacetQueryFormatted = e.detail.value;
        // this.facetQueryBuilder();
        this.requestUpdate();
    }

    onActiveFacetChange(e) {
        this.selectedFacet = {...e.detail};
        this.preparedFacetQueryFormatted = {...e.detail};
        // this.onRun(); // TODO the query should be repeated every action on active-filter (delete, clear, load from Saved filter)
        this.facetQueryBuilder();
        this.requestUpdate();
    }

    onActiveFacetClear() {
        this.selectedFacet = {};
        this.onRun();
        this.requestUpdate();
    }

    onClickRow(e, resource) {
        this.detail = {
            ...this.detail,
            [resource]: e.detail.row,
        };
        this.requestUpdate();
    }

    renderView() {
        if (!this.config.views) {
            return html`No view has been configured`;
        }

        return this.config.views.map(view => html`

                ${view.render({
                    opencgaSession: this.opencgaSession,
                    config: this.config,
                    executedQuery: this.executedQuery,
                    detail: this.detail,
                    resource: this.resource,
                    facetQuery: this.facetQuery,
                    facetResults: this.facetResults,
                    eventNotifyName: this.eventNotifyName,
                    active: this.activeView === view.id,
                    onClickRow: (e, eventName) => this.onClickRow(e, eventName),
                })}

        `);
    }

    renderfilter() {
        if (typeof this.config?.filter?.render !== "function") {
            return html`${nothing}`;
        }

        return html`

                ${this.config.filter.render({
                    opencgaSession: this.opencgaSession,
                    config: this.config,
                    query: this.query,
                    onQueryFilterChange: this.onQueryFilterChange,
                    onQueryFilterSearch: this.onQueryFilterSearch,
                })}

        `;
    }

    renderAggregation() {
        if (typeof this.config?.aggregation?.render !== "function") {
            return html`${nothing}`;
        }

        return html `

                ${this.config.aggregation.render({
                    config: this.config,
                    selectedFacet: this.selectedFacet,
                    onFacetQueryChange: this.onFacetQueryChange,
                })}

        `;
    }

    renderButtonViews() {
        return html `

                    ${(this.config.views || []).map(view => html`
                        <button
                            type="button"
                            class="btn btn-success content-pills ${this.activeView === view.id ? "active" : ""}"
                            ?disabled=${view.disabled}
                            @click="${() => this.changeView(view.id)}">

                            ${view.name}
                        </button>
                    `)}

        `;
    }

    render() {
        if (!this.opencgaSession?.study?.fqn) {
            return html`

No public projects available to browse. Please login to continue

            `;
        }

        return html`
            <tool-header
                .title="${this.config.title}"
                .icon="${this.config.icon}">
            </tool-header>

                        <button type="button" class="btn btn-primary btn-block" @click="${this.onRun}">

                            ${this.config.searchButtonText || "Search"}
                        </button>

                            Filters

                        ${this.config.aggregation ? html`

                                Aggregation

                        ` : null}

                        ${this.renderfilter()}
                        ${this.renderAggregation()}

                    ${this.renderButtonViews()}

                        <opencga-active-filters
                            facetActive
                            .resource="${this.resource}"
                            .opencgaSession="${this.opencgaSession}"
                            .defaultStudy="${this.opencgaSession?.study?.fqn}"
                            .query="${this.preparedQuery}"
                            .executedQuery="${this.executedQuery}"
                            .facetQuery="${this.preparedFacetQueryFormatted}"
                            .executedFacetQuery="${this.executedFacetQueryFormatted}"
                            .alias="${this.activeFilterAlias}"
                            .config="${this.config.activeFilters}"
                            .filters="${this.config.filter.examples}"
                            @activeFilterChange="${this.onActiveFilterChange}"
                            @activeFilterClear="${this.onActiveFilterClear}"
                            @activeFacetChange="${this.onActiveFacetChange}"
                            @activeFacetClear="${this.onActiveFacetClear}">
                        </opencga-active-filters>

                            ${this.renderView()}

        `;
    }

}

customElements.define("opencga-browser", OpencgaBrowser);
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */
var config = require("../config");
var urls = require("./urls");
var random = require("./random");
var responseLib = require("./response");
var async = require('async');
var request = require("request");

module.exports = {
    create: function(collection, numberOfEntities, cb) {
        var url = urls.appendOrgCredentials(urls.appUrl() + collection);
        var requestArray = []
        geos = random.geo(config.location, 2000, numberOfEntities);
        // console.log(geos);
        for (var i = 0; i < numberOfEntities; i++) {
            requestArray.push({
                consistentProperty: "somethingConsistent",
                randomProperty: "somethingRandom - " + random.randomString(10),
                intProperty: random.randomNumber(5),
                optionsProperty: random.abc(),
                location: geos[i],
                title: "A Tale of Two Cities"
            });
        }
        request.post({
            url: url,
            json: true,
            body: requestArray
        }, function(e, r, body) {
            var error = responseLib.getError(e, r);
            cb(error, error ? error : body);
        });
    },
    createEach: function(collection, numberOfEntities, cb) {
        var url = urls.appendOrgCredentials(urls.appUrl() + collection);
        var requestArray = []
        geos = random.geo(config.location, 2000, numberOfEntities);
        // console.log(geos);
        for (var i = 0; i < numberOfEntities; i++) {
            requestArray.push({
                consistentProperty: "somethingConsistent",
                randomProperty: "somethingRandom - " + random.randomString(10),
                intProperty: random.randomNumber(5),
                optionsProperty: random.abc(),
                location: geos[i],
                title: "A Tale of Two Cities"
            });
        }
        var returnBody = [];
        async.each(requestArray, function(options, cb) {
            request.post({
                url: url,
                json: true,
                body: options
            }, function(e, r, body) {
                var error = responseLib.getError(e, r);
                !error && returnBody.push(body.entities[0]);
                cb(error, error ? error : body.entities[0]);
            });
        }, function(err,bodies) {
           cb(err,returnBody);
        });

    },
    deleteAll: function(collection, cb) {
        var url = urls.appendOrgCredentials(urls.appUrl() + collection);
        deleteAllEntities(collection, function(e) {
            request.get({
                url: url,
                json: true
            }, function(e, r, body) {
                var error = responseLib.getError(e, r);
                cb(error, error ? error : body);
            })
        })
    },
    update: function(collection, uuid, body, cb) {
        var url = urls.appendOrgCredentials(urls.appUrl() + collection + "/" + uuid);
        request.put({
            url: url,
            body: body,
            json: true
        }, function(e, r, body) {
            var error = responseLib.getError(e, r);
            cb(error, error ? error : body);
        })
    },
    get: function(collection, numberOfEntities, cb) {
        var url = urls.appendOrgCredentials(urls.appUrl() + collection + "?limit=" + numberOfEntities.toString());
        request.get({
            url: url,
            json: true
        }, function(e, r, body) {
            var error = responseLib.getError(e, r);
            cb(error, error ? error : body);
        })
    },
    getByUuid: function(collection, uuid, cb) {
        var url = urls.appendOrgCredentials(urls.appUrl() + collection + "/"+uuid);
        request.get({
            url: url,
            json: true
        }, function(e, r, body) {
            var error = responseLib.getError(e, r);
            cb(error, error ? error : body);
        })
    },
    getWithQuery: function(collection, query, numberOfEntities, cb) {
        var url = urls.appendOrgCredentials(urls.appUrl() + collection + "?ql=" + encodeURIComponent(query) + "&limit=" + numberOfEntities.toString());
        request.get({
            url: url,
            json: true
        }, function(e, r, body) {
            var error = responseLib.getError(e, r);
            cb(error, error ? error : body);
        })
    }
};

function deleteAllEntities(collection, cb) {
    var url = urls.appendOrgCredentials(urls.appUrl() + collection);
    request.get({
        url: url,
        json: true
    }, function(e, r, body) {
        if (body.count === undefined) {
            cb("The 'count' property is not defined at " + url);
        } else if (body.count > 0) {
            var deletes = [];
            for (var i = 0; i < body.count; i++) {
                deletes.push({
                    url: urls.appendOrgCredentials(urls.appUrl() + collection + "/" + body.entities[i].uuid),
                    json: true
                });
            }
            async.each(deletes, function(options, cb) {
                request.del(options, function(e) {
                    cb(e);
                });
            }, function(err) {
                setTimeout(function() {
                    deleteAllEntities(collection, function(e) {
                        cb(e);
                    });
                }, 600); // Mandatory, since it seems to not retrieve entities if you make a request in < 600ms
            });
        } else {
            cb();
        }
    });
}
<commit_msg>integration tests: handle null<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */
var config = require("../config");
var urls = require("./urls");
var random = require("./random");
var responseLib = require("./response");
var async = require('async');
var request = require("request");

module.exports = {
    create: function(collection, numberOfEntities, cb) {
        var url = urls.appendOrgCredentials(urls.appUrl() + collection);
        var requestArray = []
        geos = random.geo(config.location, 2000, numberOfEntities);
        // console.log(geos);
        for (var i = 0; i < numberOfEntities; i++) {
            requestArray.push({
                consistentProperty: "somethingConsistent",
                randomProperty: "somethingRandom - " + random.randomString(10),
                intProperty: random.randomNumber(5),
                optionsProperty: random.abc(),
                location: geos[i],
                title: "A Tale of Two Cities"
            });
        }
        request.post({
            url: url,
            json: true,
            body: requestArray
        }, function(e, r, body) {
            var error = responseLib.getError(e, r);
            cb(error, error ? error : body);
        });
    },
    createEach: function(collection, numberOfEntities, cb) {
        var url = urls.appendOrgCredentials(urls.appUrl() + collection);
        var requestArray = []
        geos = random.geo(config.location, 2000, numberOfEntities);
        // console.log(geos);
        for (var i = 0; i < numberOfEntities; i++) {
            requestArray.push({
                consistentProperty: "somethingConsistent",
                randomProperty: "somethingRandom - " + random.randomString(10),
                intProperty: random.randomNumber(5),
                optionsProperty: random.abc(),
                location: geos[i],
                title: "A Tale of Two Cities"
            });
        }
        var returnBody = [];
        async.each(requestArray, function(options, cb) {
            request.post({
                url: url,
                json: true,
                body: options
            }, function(e, r, body) {
                var error = responseLib.getError(e, r);
                var entity = body && body.entities ? body.entities.pop() : null;
                entity &&  returnBody.push(entity);
                cb(error, error ? error : entity);
            });
        }, function(err,bodies) {
           cb(err,returnBody);
        });

    },
    deleteAll: function(collection, cb) {
        var url = urls.appendOrgCredentials(urls.appUrl() + collection);
        deleteAllEntities(collection, function(e) {
            request.get({
                url: url,
                json: true
            }, function(e, r, body) {
                var error = responseLib.getError(e, r);
                cb(error, error ? error : body);
            })
        })
    },
    update: function(collection, uuid, body, cb) {
        var url = urls.appendOrgCredentials(urls.appUrl() + collection + "/" + uuid);
        request.put({
            url: url,
            body: body,
            json: true
        }, function(e, r, body) {
            var error = responseLib.getError(e, r);
            cb(error, error ? error : body);
        })
    },
    get: function(collection, numberOfEntities, cb) {
        var url = urls.appendOrgCredentials(urls.appUrl() + collection + "?limit=" + numberOfEntities.toString());
        request.get({
            url: url,
            json: true
        }, function(e, r, body) {
            var error = responseLib.getError(e, r);
            cb(error, error ? error : body);
        })
    },
    getByUuid: function(collection, uuid, cb) {
        var url = urls.appendOrgCredentials(urls.appUrl() + collection + "/"+uuid);
        request.get({
            url: url,
            json: true
        }, function(e, r, body) {
            var error = responseLib.getError(e, r);
            cb(error, error ? error : body);
        })
    },
    getWithQuery: function(collection, query, numberOfEntities, cb) {
        var url = urls.appendOrgCredentials(urls.appUrl() + collection + "?ql=" + encodeURIComponent(query) + "&limit=" + numberOfEntities.toString());
        request.get({
            url: url,
            json: true
        }, function(e, r, body) {
            var error = responseLib.getError(e, r);
            cb(error, error ? error : body);
        })
    }
};

function deleteAllEntities(collection, cb) {
    var url = urls.appendOrgCredentials(urls.appUrl() + collection);
    request.get({
        url: url,
        json: true
    }, function(e, r, body) {
        if (body.count === undefined) {
            cb("The 'count' property is not defined at " + url);
        } else if (body.count > 0) {
            var deletes = [];
            for (var i = 0; i < body.count; i++) {
                deletes.push({
                    url: urls.appendOrgCredentials(urls.appUrl() + collection + "/" + body.entities[i].uuid),
                    json: true
                });
            }
            async.each(deletes, function(options, cb) {
                request.del(options, function(e) {
                    cb(e);
                });
            }, function(err) {
                setTimeout(function() {
                    deleteAllEntities(collection, function(e) {
                        cb(e);
                    });
                }, 600); // Mandatory, since it seems to not retrieve entities if you make a request in < 600ms
            });
        } else {
            cb();
        }
    });
}
<|endoftext|>


<commit_before>'use strict';
angular.module('wegas.models.sessions', [])
.service('SessionsModel', function ($http, $q, Auth) {

    var model = this,
    managedSessions = null,
    playedSessions = null;

    var findSession = function(sessions, id){
        return _.find(sessions, function (s) { return s.id == id; });
    }
    /* Get all managed sessions */
    model.getManagedSessions = function () {
        var deferred = $q.defer();
        if(managedSessions != null){
            deferred.resolve(managedSessions);
        }else{
            managedSessions = [];
            $http.get(ServiceURL + "rest/GameModel/Game?view=EditorExtended").success(function(data){
                data.forEach(function(session){
                    // Si la session est en team.
                    if(!session.properties.freeForAll){
                        var teams = session.teams;
                        // Pour chaque team.
                        teams.forEach(function(team){
                            // Contrôle si il s'agit d'une debug team.
                            if(team["@class"] == "DebugTeam"){
                                // Enlève la debug team de la liste des teams.
                                session.teams = _.without(session.teams, _.findWhere(session.teams, {id: team.id}));
                            }
                        });
                    // Si la session est en individuel.
                    }else{
                        var teams = session.teams,
                            players = [];
                        // Pour chaque teams.
                        teams.forEach(function(team){
                            // Contrôle que la team n'est pas une debug team.
                            if(team["@class"] != "DebugTeam"){
                                // Pour chaques players.
                                team.players.forEach(function(player){
                                    // Ajoute le player à la liste des joueurs.
                                    players.push(player);
                                });
                            }
                        });
                        // Ajoute la liste des joueurs à la session.
                        session.players = players;
                        // Enlève la liste des teams à la session.
                        delete session.teams;
                    }
                });
                managedSessions = data;
                deferred.resolve(managedSessions);
            }).error(function(data){
                managedSessions = [];
                managedSessions.push({
                    id: 1,
                    name: "lorem ipsum",
                    createdTime: "17.03.2015",
                    comments: "no comment"
                });
                deferred.resolve(managedSessions);
            });
        }
        return deferred.promise;
    };

    /* Return a specific session based on her id */
    model.getManagedSession = function(id){
        var deferred = $q.defer();
        if (managedSessions == null) {
            model.getManagedSessions().then(function(data){
                var session = findSession(managedSessions, id);
                deferred.resolve(session);
            });
        } else {
            var session = findSession(managedSessions, id);
            deferred.resolve(session);
        }
        return deferred.promise;
    };

    /* Crée une nouvelle session managée */
    model.createManagedSession = function(sessionName, scenarioId){
        var deferred = $q.defer();
        Auth.getAuthenticatedUser().then(function(user){
            if(user != null) {
                /* Todo Check Values ? */
                var newSession = {
                    "@class": "Game",
                    "gameModelId": scenarioId,
                    "name": sessionName
                };
                $http.post(ServiceURL + "rest/GameModel/Game/"+ user.id, newSession).success(function(data){
                    console.log(data);
                    managedSessions.push({
                        id : data.id,
                        name : data.name,
                        createdTime : data.createdTime,
                        comments : "",
                        icon : {
                            color: "orange",
                            name: "gamepad"
                        }
                    });
                    deferred.resolve(managedSessions[data.id]);
                }).error(function(data){
                    /* TODO - Improve error mgt */
                    deferred.resolve(null);
                });
            }else{
                deferred.resolve(null);
            }
        });
        return deferred.promise;
    };

    model.updateNameSession = function(sessionToSet){
        var deferred = $q.defer();
        var sessionBeforeChange = findSession(managedSessions, sessionToSet.id);
        if(sessionBeforeChange != undefined){
            sessionBeforeChange.name = sessionToSet.name;
            $http.put(ServiceURL + "rest/GameModel/Game/"+ sessionToSet.id, sessionBeforeChange).success(function(data){
                deferred.resolve(data);
            }).error(function(data){
                deferred.resolve(data);
            });
        }
        return deferred.promise;
    };

    model.updateCommentsSession = function(sessionToSet){
        var deferred = $q.defer();
        var sessionBeforeChange = findSession(managedSessions, sessionToSet.id);
        if(sessionBeforeChange != undefined){
            scenarioBeforeChange = sessionBeforeChange.gameModel;
            scenarioBeforeChange.comments = sessionToSet.comments;
            $http.put(ServiceURL + "rest/Public/GameModel/"+ scenarioBeforeChange.id, scenarioBeforeChange).success(function(data){
                deferred.resolve(data);
            }).error(function(data){
                deferred.resolve(data);
            });
        }
        return deferred.promise;
    };

    /* Return all played sessions */
    model.getPlayedSessions = function () {
        var deferred = $q.defer();
        Auth.getAuthenticatedUser().then(function(user){
            if(user != null){
                if(playedSessions != null){
                    deferred.resolve(playedSessions);
                } else {
                    playedSessions = [];
                    $http.get(ServiceURL + "rest/RegisteredGames/"+ user.id).success(function(data){
                        playedSessions = data
                        deferred.resolve(playedSessions);
                    }).error(function(data){
                        playedSessions = [];
                        deferred.resolve(playedSessions);
                    });
                }
            } else {
                deferred.resolve(playedSessions);
            }
        });
        return deferred.promise;
    };

    /* Retourne la session jouée correspondant à l'id, undefined sinon. */
    model.getPlayedSession = function(id){
        var deferred = $q.defer();
        if(playedSessions == null){
            model.getPlayedSessions().then(function(data){
                var session = findSession(playedSessions, id);
                deferred.resolve(session);
            });
        }else{
            var session = findSession(playedSessions, id);
            deferred.resolve(session);
        }
        return deferred.promise;
    };

    model.joinSession = function (token) {
        var deferred = $q.defer();

        Auth.getAuthenticatedUser().then(function(user) {
            if(user != null) {
                if(playedSessions == null) {
                    model.getPlayedSessions().then(function(data){
                        model.joinSession(token);
                    });
                } else {
                    model.getPlayedSessions().then(function(data){
                        $http.get(ServiceURL + "rest/GameModel/Game/JoinGame/"+ token).success(function(data){
                            playedSessions.push(data[0]);
                            deferred.resolve(playedSessions);
                        }).error(function(data){
                            deferred.resolve(playedSessions);
                        });
                    });
                }

            } else {
                deferred.resolve(playedSessions);
            }
        });
        return deferred.promise;
    }

    model.clearCache = function(){
        managedSessions = null;
        playedSessions = null;
    };
})
;
<commit_msg>Meilleur stabilité des demandes de sessions avec cache<commit_after>'use strict';
angular.module('wegas.models.sessions', [])
.service('SessionsModel', function ($http, $q, $interval, Auth) {
    /* Namespace for model accessibility. */
    var model = this,
    /* Caches for data */
    managedSessions = null,
    playedSessions = null;
    /* Tools to prevent asynchronous error. */
    managedSessionsLoading = false,
    waitManagedSessions = null,

    /* Return a session in a sessions cache. */
    findSession = function(sessions, id){
        return _.find(sessions, function (s) { return s.id == id; });
    },
    /* Format players in a list, individualy or grouped by team. */
    formatPlayers = function(data){
        data.forEach(function(session){
            if(!session.properties.freeForAll){
                var teams = session.teams;
                teams.forEach(function(team){
                    if(team["@class"] == "DebugTeam"){
                        session.teams = _.without(session.teams, _.findWhere(session.teams, {id: team.id}));
                    }
                });
            }else{
                var teams = session.teams,
                    players = [];
                teams.forEach(function(team){
                    if(team["@class"] != "DebugTeam"){
                        team.players.forEach(function(player){
                            players.push(player);
                        });
                    }
                });
                session.players = players;
                delete session.teams;
            }
        });
        return data;
    },

    /* Call the REST service for getting managed sessions. */
    cacheManagedSessions = function () {
        var deferred = $q.defer();
        console.log("Load HTTP");
        $http.get(ServiceURL + "rest/GameModel/Game?view=EditorExtended").success(function(data){
            data = formatPlayers(data);
            managedSessions = data;
            console.log("Data loadded");
            deferred.resolve(managedSessions);
        }).error(function(data){
            managedSessions = [];
            deferred.resolve(managedSessions);
        });
        return deferred.promise;
    },

    /* Stop waiting for simultanate sessions asking. */
    stopWaiting = function(waitFunction){
        $interval.cancel(waitFunction);
    },

    /* Do wait during data loading. */
    waitForManagedSessions = function(){
        var deferred = $q.defer();
        waitManagedSessions = $interval(function() {
            if(!managedSessionsLoading){
                stopWaiting(waitManagedSessions);
                deferred.resolve(true)
            }
        }, 500);
        return deferred.promise;
    };

    /* Ask for all managed sessions. */
    model.getManagedSessions = function(){
        var deferred = $q.defer();
        if(managedSessionsLoading){
            waitForManagedSessions.then(function(){
                deferred.resolve(managedSessions);
            });
        }else{
            if(managedSessions != null){
                deferred.resolve(managedSessions);
            }else{
                managedSessionsLoading = true;
                cacheManagedSessions().then(function(){
                    deferred.resolve(managedSessions);
                    managedSessionsLoading = false;
                });
            }
        }
        return deferred.promise;
    };

    /* Ask for one managed session. */
    model.getManagedSession = function(id){
        var deferred = $q.defer(),
            session;
        if(managedSessionsLoading){
            waitForManagedSessions().then(function(){
                session = findSession(managedSessions, id);
                deferred.resolve(session);
            });
        }else{
            if(managedSessions == null) {
                model.getManagedSessions().then(function(){
                    session = findSession(managedSessions, id);
                    deferred.resolve(managedSessions);
                });
            }else{
                session = findSession(managedSessions, id);
                deferred.resolve(session);
            }
        }
        return deferred.promise;
    };

    /* Create a new session. */
    model.createManagedSession = function(sessionName, scenarioId){
        var deferred = $q.defer();
        Auth.getAuthenticatedUser().then(function(user){
            if(user != null) {
                /* Todo Check Values ? */
                var newSession = {
                    "@class": "Game",
                    "gameModelId": scenarioId,
                    "name": sessionName
                };
                $http.post(ServiceURL + "rest/GameModel/Game/"+ user.id, newSession).success(function(data){
                    console.log(data);
                    managedSessions.push(data);
                    deferred.resolve(data);
                }).error(function(data){
                    /* TODO - Improve error mgt */
                    deferred.resolve(null);
                });
            }else{
                deferred.resolve(null);
            }
        });
        return deferred.promise;
    };

    /* Update a name of a session. */
    model.updateNameSession = function(sessionToSet){
        var deferred = $q.defer();
        var sessionBeforeChange = findSession(managedSessions, sessionToSet.id);
        if(sessionBeforeChange != undefined){
            sessionBeforeChange.name = sessionToSet.name;
            $http.put(ServiceURL + "rest/GameModel/Game/"+ sessionToSet.id, sessionBeforeChange).success(function(data){
                deferred.resolve(data);
            }).error(function(data){
                deferred.resolve(data);
            });
        }
        return deferred.promise;
    };

    /* Update the comment of a session. */
    model.updateCommentsSession = function(sessionToSet){
        var deferred = $q.defer();
        var sessionBeforeChange = findSession(managedSessions, sessionToSet.id);
        if(sessionBeforeChange != undefined){
            scenarioBeforeChange = sessionBeforeChange.gameModel;
            scenarioBeforeChange.comments = sessionToSet.comments;
            $http.put(ServiceURL + "rest/Public/GameModel/"+ scenarioBeforeChange.id, scenarioBeforeChange).success(function(data){
                deferred.resolve(data);
            }).error(function(data){
                deferred.resolve(data);
            });
        }
        return deferred.promise;
    };

    /* Return all played sessions */
    model.getPlayedSessions = function () {
        var deferred = $q.defer();
        Auth.getAuthenticatedUser().then(function(user){
            if(user != null){
                if(playedSessions != null){
                    deferred.resolve(playedSessions);
                } else {
                    playedSessions = [];
                    $http.get(ServiceURL + "rest/RegisteredGames/"+ user.id).success(function(data){
                        playedSessions = data
                        deferred.resolve(playedSessions);
                    }).error(function(data){
                        playedSessions = [];
                        deferred.resolve(playedSessions);
                    });
                }
            } else {
                deferred.resolve(playedSessions);
            }
        });
        return deferred.promise;
    };

    /* Get a played session form id, undefined otherwise. */
    model.getPlayedSession = function(id){
        var deferred = $q.defer();
        if(playedSessions == null){
            model.getPlayedSessions().then(function(data){
                var session = findSession(playedSessions, id);
                deferred.resolve(session);
            });
        }else{
            var session = findSession(playedSessions, id);
            deferred.resolve(session);
        }
        return deferred.promise;
    };

    /* Join a session for current player */
    model.joinSession = function (token) {
        var deferred = $q.defer();

        Auth.getAuthenticatedUser().then(function(user) {
            if(user != null) {
                if(playedSessions == null) {
                    model.getPlayedSessions().then(function(data){
                        model.joinSession(token);
                    });
                } else {
                    model.getPlayedSessions().then(function(data){
                        $http.get(ServiceURL + "rest/GameModel/Game/JoinGame/"+ token).success(function(data){
                            playedSessions.push(data[0]);
                            deferred.resolve(playedSessions);
                        }).error(function(data){
                            deferred.resolve(playedSessions);
                        });
                    });
                }

            } else {
                deferred.resolve(playedSessions);
            }
        });
        return deferred.promise;
    }

    /* Remove data from sessions caches */
    model.clearCache = function(){
        managedSessions = null;
        playedSessions = null;
    };
})
;
<|endoftext|>


<commit_before>(function () {
  'use strict';

  angular.module('janusHangouts')
    .factory('Feed', ['$timeout', 'DataChannelService', feedFactory]);

  function feedFactory($timeout, DataChannelService) {
    return function(attrs) {
      attrs = attrs || {};
      var that = this;

      this.id = attrs.id || 0;
      this.display = attrs.display || null;
      this.pluginHandle = attrs.pluginHandle || null;
      this.stream = attrs.stream || null;
      this.isPublisher = attrs.isPublisher || false;

      this.audioEnabled = true;
      this.videoEnabled = true;
      this.speaking = false;

      this.setEnabledTrack = function(type, enabled) {
        var that = this;
        if (this.isPublisher) {
          // We need to use $timeout function just to let AngularJS know
          // about changes in the feed.
          $timeout(function() {
            var track = getTrack(type);
            track.enabled = enabled;
            that[type + "Enabled"] = enabled;
            DataChannelService.sendStatus(this);
          });
        } else {
          if (type === "audio" && enabled === false) {
            DataChannelService.sendMuteRequest(this);
          }
        }
      };

      this.setSpeaking = function(speaking) {
        var that = this;
        // We need to use $timeout function just to let AngularJS know
        // about changes in the feed.
        $timeout(function() {
          that.speaking = speaking;
          DataChannelService.sendStatus(this);
        });
      }

      this.getStatus = function() {
        return {
          audioEnabled: that.audioEnabled,
          videoEnabled: that.videoEnabled,
          speaking:     that.speaking,
          display:      that.display
        };
      }

      // Update local representation of the feed (used to process
      // information sent by the remote peer)
      this.setStatus = function(attrs) {
        // We need to use $timeout function just to let AngularJS know
        // about changes in the feed.
        var that = this;
        $timeout(function() {
          _.assign(that, attrs);
        });
      };

      this.hasAudio = function() {
        var that = this;
        return (getTrack('audio') !== null);
      }

      this.hasVideo = function() {
        var that = this;
        return (getTrack('video') !== null);
      }

      function getTrack(type) {
        if(that.stream === null || that.stream === undefined) {
          return null;
        }
        var func = "get" + _.capitalize(type) + "Tracks";
        if(that.stream[func]() === null || that.stream[func]() === undefined) {
          return null;
        }
        var track = that.stream[func]()[0];
        if(track === undefined) {
          return null;
        }
        return track;
      }
    };
  }
})();
<commit_msg>Fix two scope issues in FeedsFactory<commit_after>(function () {
  'use strict';

  angular.module('janusHangouts')
    .factory('Feed', ['$timeout', 'DataChannelService', feedFactory]);

  function feedFactory($timeout, DataChannelService) {
    return function(attrs) {
      attrs = attrs || {};
      var that = this;

      this.id = attrs.id || 0;
      this.display = attrs.display || null;
      this.pluginHandle = attrs.pluginHandle || null;
      this.stream = attrs.stream || null;
      this.isPublisher = attrs.isPublisher || false;

      this.audioEnabled = true;
      this.videoEnabled = true;
      this.speaking = false;

      this.setEnabledTrack = function(type, enabled) {
        var that = this;
        if (this.isPublisher) {
          // We need to use $timeout function just to let AngularJS know
          // about changes in the feed.
          $timeout(function() {
            var track = getTrack(type);
            track.enabled = enabled;
            that[type + "Enabled"] = enabled;
            DataChannelService.sendStatus(that);
          });
        } else {
          if (type === "audio" && enabled === false) {
            DataChannelService.sendMuteRequest(this);
          }
        }
      };

      this.setSpeaking = function(speaking) {
        var that = this;
        // We need to use $timeout function just to let AngularJS know
        // about changes in the feed.
        $timeout(function() {
          that.speaking = speaking;
          DataChannelService.sendStatus(that);
        });
      }

      this.getStatus = function() {
        return {
          audioEnabled: that.audioEnabled,
          videoEnabled: that.videoEnabled,
          speaking:     that.speaking,
          display:      that.display
        };
      }

      // Update local representation of the feed (used to process
      // information sent by the remote peer)
      this.setStatus = function(attrs) {
        // We need to use $timeout function just to let AngularJS know
        // about changes in the feed.
        var that = this;
        $timeout(function() {
          _.assign(that, attrs);
        });
      };

      this.hasAudio = function() {
        var that = this;
        return (getTrack('audio') !== null);
      }

      this.hasVideo = function() {
        var that = this;
        return (getTrack('video') !== null);
      }

      function getTrack(type) {
        if(that.stream === null || that.stream === undefined) {
          return null;
        }
        var func = "get" + _.capitalize(type) + "Tracks";
        if(that.stream[func]() === null || that.stream[func]() === undefined) {
          return null;
        }
        var track = that.stream[func]()[0];
        if(track === undefined) {
          return null;
        }
        return track;
      }
    };
  }
})();
<|endoftext|>


<commit_before>(function () {

    angular
            .module('app')
            .controller('InvitesController', ['$mdDialog', '$scope','HttpService',
                InvitesController
            ]);

    function InvitesController($mdDialog, $scope, HttpService,
            PatientListController) {
        var vm = this;

        vm.invite = {
            role: '',
            email: ''
        }

        vm.role = [
            {
                name: "Patient"
            },
            {
                name: "Doctor"
            },

            {
                name: "Volunteer"
            },
            {
                name: "Chief"
            }
        ];

//        vm.invites = [
//            {
//                name: "ivan",
//                email: "a@a"
//            },
//            {
//                name: "petr",
//                email: "b@b"
//            }
//
//        ];

        vm.invitePerson = function () {
            //TODO: check empty
            HttpService.postInvite(vm.invite)
                    .then(function () {

                    });
        };

        vm.showInvites = function (ev) {
            HttpService.getInvitesList()
                    .then(function (invites) {
                        vm.invites = invites;
                    });
            $mdDialog.show({
                controller: DialogController,
                templateUrl: 'dialog1.tmpl.html',
                parent: angular.element(document.body),
                targetEvent: ev,
                clickOutsideToClose: true
            });
        };

        function DialogController($mdDialog) {
            this.hide = function () {
                $mdDialog.hide();
            };

            this.cancel = function () {
                alert("here");
                $mdDialog.cancel();
            };

            this.answer = function (answer) {
                $mdDialog.hide(answer);
            };
        }
        ;

        function deleteInvite(item) {
            alert("item " + item);
            vm.invites = vm.invites.splice(vm.invites.indexOf(item), 1);
        }
        ;
    }

})();<commit_msg>fix invite<commit_after>(function () {

    angular
            .module('app')
            .controller('InvitesController', ['$mdDialog', '$scope','HttpService',
                InvitesController
            ]);

    function InvitesController($mdDialog, $scope, HttpService,
            PatientListController) {
        var vm = this;

        vm.invite = {
            role: '',
            email: ''
        }

        vm.role = [
            {
                name: "patient"
            },
            {
                name: "doctor"
            },

            {
                name: "volunteer"
            },
            {
                name: "chief"
            }
        ];

//        vm.invites = [
//            {
//                name: "ivan",
//                email: "a@a"
//            },
//            {
//                name: "petr",
//                email: "b@b"
//            }
//
//        ];

        vm.invitePerson = function () {
            //TODO: check empty
            HttpService.postInvite(vm.invite)
                    .then(function () {

                    });
        };

        vm.showInvites = function (ev) {
            HttpService.getInvitesList()
                    .then(function (invites) {
                        vm.invites = invites;
                    });
            $mdDialog.show({
                controller: DialogController,
                templateUrl: 'dialog1.tmpl.html',
                parent: angular.element(document.body),
                targetEvent: ev,
                clickOutsideToClose: true
            });
        };

        function DialogController($mdDialog) {
            this.hide = function () {
                $mdDialog.hide();
            };

            this.cancel = function () {
                alert("here");
                $mdDialog.cancel();
            };

            this.answer = function (answer) {
                $mdDialog.hide(answer);
            };
        }
        ;

        function deleteInvite(item) {
            alert("item " + item);
            vm.invites = vm.invites.splice(vm.invites.indexOf(item), 1);
        }
        ;
    }

})();<|endoftext|>


<commit_before>// Factory to add, remove, edit and delete maintenence requests:
( function(){
  'use strict';

  angular.module( 'dolmen.services', [ 'firebase' ] )
  .service( 'Maintenance', [
    '$rootScope',
    'FBDolmen',
    '$firebaseArray',
    '$firebaseObject',
    function( $rootScope, FBDolmen, $firebaseArray, $firebaseObject ) {
    var maintObj = { };
    var ref = new Firebase( FBDolmen + '/requests' );
    maintObj.getRequests = function( oid ){
      ref.orderByChild( 'oid' ).equalTo( oid ).on( 'value', function( res ){
        var reqList = res.val();
        maintObj.requests = reqList;
        $rootScope.$broadcast( 'requestsRetrieved' );
      });
    };
    maintObj.addRequest = function( request ){
      // from firebase docs:
      var list = $firebaseArray(ref);
      list.$add( request ).then(function(ref) {
        var id = ref.key();
        list.$indexFor(id); // returns location in the array
      });
    };
    maintObj.updateRequest = function( request ){
      var reqRef = new Firebase( FBDolmen + '/requests/' + request.dbId );
      var req = $firebaseObject( reqRef );
      req.address = request.address;
      req.status = request.status;
      req.description = request.description;
      req.tenant = req.tenant;
      req.phone = req.phone;
      return req.$save();
    };
    return maintObj;
  }]);

  })();
<commit_msg>adding date key and fixing tenant and phone values<commit_after>// Factory to add, remove, edit and delete maintenence requests:
( function(){
  'use strict';

  angular.module( 'dolmen.services', [ 'firebase' ] )
  .service( 'Maintenance', [
    '$rootScope',
    'FBDolmen',
    '$firebaseArray',
    '$firebaseObject',
    function( $rootScope, FBDolmen, $firebaseArray, $firebaseObject ) {
    var maintObj = { };
    var ref = new Firebase( FBDolmen + '/requests' );
    maintObj.getRequests = function( oid ){
      ref.orderByChild( 'oid' ).equalTo( oid ).on( 'value', function( res ){
        var reqList = res.val();
        maintObj.requests = reqList;
        $rootScope.$broadcast( 'requestsRetrieved' );
      });
    };
    maintObj.addRequest = function( request ){
      // from firebase docs:
      var list = $firebaseArray(ref);
      list.$add( request ).then(function(ref) {
        var id = ref.key();
        list.$indexFor(id); // returns location in the array
      });
    };
    maintObj.updateRequest = function( request ){
      var reqRef = new Firebase( FBDolmen + '/requests/' +  request.dbId );
      var req = $firebaseObject( reqRef );
      req.date = request.date;
      req.address = request.address;
      req.status = request.status;
      req.description = request.description;
      req.tenant = request.tenant;
      req.phone = request.phone;
      return req.$save();
    };
    return maintObj;
  }]);

  })();
<|endoftext|>