<commit_before>import React from 'react'
import NavBar from './NavBar'

/* eslint-disable complexity */
/* eslint-disable max-depth */
/* eslint-disable no-lonely-if */
function getNextState(state, mostRight, winWidth) {
  const {showLabel, showLabelMinWidth, showToolSwitcher, showToolSwitcherMinWidth} = state
  const mostRightIsVisible = mostRight && mostRight <= winWidth
  const nextState = {winWidth}

  if (mostRightIsVisible) {
    // most-right element is within viewport
    if (showLabel) {
      if (showLabelMinWidth === -1 || winWidth < showLabelMinWidth) {
        nextState.showLabelMinWidth = winWidth
      }
    } else if (showLabelMinWidth < winWidth) {
      nextState.showLabel = true
    }

    if (showToolSwitcher) {
      if (showToolSwitcherMinWidth === -1 || winWidth < showToolSwitcherMinWidth) {
        nextState.showToolSwitcherMinWidth = winWidth
      }
    } else if (showToolSwitcherMinWidth < winWidth) {
      nextState.showToolSwitcher = true
    }
  } else {
    // most-right element is NOT within viewport
    if (showLabel) {
      nextState.showLabel = false
    } else if (showToolSwitcher) {
      nextState.showToolSwitcher = false
    }
  }

  return nextState
}
/* eslint-enable complexity */
/* eslint-enable max-depth */
/* eslint-enable no-lonely-if */

class NavBarContainer extends React.PureComponent {
  state = {
    showLabel: false,
    showLabelMinWidth: -1,
    showToolSwitcher: false,
    showToolSwitcherMinWidth: -1,
    winWidth: -1
  }

  loginStatusElement = null
  searchElement = null
  tickAnimFrameId = null

  componentDidMount() {
    // Start an animation frame loop to check whether elements within the NavBar
    // exits the viewport at any time.
    this.tick()
  }

  /* eslint-disable complexity */
  componentDidUpdate(prevProps, prevState) {
    const {showLabel, showLabelMinWidth, showToolSwitcher, showToolSwitcherMinWidth} = this.state
    const didShowLabel = showLabelMinWidth === -1 && !prevState.showLabel && showLabel
    const didShowToolSwitcher =
      showToolSwitcherMinWidth === -1 && !prevState.showToolSwitcher && showToolSwitcher
    const didHideLabel = showToolSwitcherMinWidth === -1 && prevState.showLabel && !showLabel

    if (didShowLabel || didShowToolSwitcher || didHideLabel) {
      this.handleCustomResize(window.innerWidth)
    }
  }
  /* eslint-enable complexity */

  componentWillUnmount() {
    if (this.io) {
      this.io.disconnect()
      this.io = null
    }

    if (this.tickAnimFrameId) {
      window.cancelAnimatioNFrame(this.tickAnimFrameId)
      this.tickAnimFrameId = null
    }
  }

  tick = () => {
    this.handleFrame()
    this.tickAnimFrameId = window.requestAnimationFrame(this.tick)
  }

  handleFrame() {
    const winWidth = window.innerWidth
    if (winWidth !== this.state.winWidth) {
      this.handleCustomResize(winWidth)
    }
  }

  handleCustomResize(winWidth) {
    if (this.loginStatusElement) {
      const {showToolSwitcher} = this.state
      // console.log(this.searchElement)
      const mostRightRect = showToolSwitcher
        ? this.loginStatusElement.getBoundingClientRect()
        : this.searchElement.getBoundingClientRect()
      this.setState(state => {
        const nextState = getNextState(state, mostRightRect.left + mostRightRect.width, winWidth)
        // console.log(nextState)
        return nextState
      })
    }
  }

  handleSetLoginStatusElement = element => {
    this.loginStatusElement = element
  }

  handleSetSearchElement = element => {
    this.searchElement = element
  }

  render() {
    const {showLabel, showToolSwitcher} = this.state

    return (
      <NavBar
        {...this.props}
        onSetLoginStatusElement={this.handleSetLoginStatusElement}
        onSetSearchElement={this.handleSetSearchElement}
        showLabel={showLabel}
        showToolSwitcher={showToolSwitcher}
      />
    )
  }
}

export default NavBarContainer
<commit_msg>[default-layout] Fix misspelled function name<commit_after>import React from 'react'
import NavBar from './NavBar'

/* eslint-disable complexity */
/* eslint-disable max-depth */
/* eslint-disable no-lonely-if */
function getNextState(state, mostRight, winWidth) {
  const {showLabel, showLabelMinWidth, showToolSwitcher, showToolSwitcherMinWidth} = state
  const mostRightIsVisible = mostRight && mostRight <= winWidth
  const nextState = {winWidth}

  if (mostRightIsVisible) {
    // most-right element is within viewport
    if (showLabel) {
      if (showLabelMinWidth === -1 || winWidth < showLabelMinWidth) {
        nextState.showLabelMinWidth = winWidth
      }
    } else if (showLabelMinWidth < winWidth) {
      nextState.showLabel = true
    }

    if (showToolSwitcher) {
      if (showToolSwitcherMinWidth === -1 || winWidth < showToolSwitcherMinWidth) {
        nextState.showToolSwitcherMinWidth = winWidth
      }
    } else if (showToolSwitcherMinWidth < winWidth) {
      nextState.showToolSwitcher = true
    }
  } else {
    // most-right element is NOT within viewport
    if (showLabel) {
      nextState.showLabel = false
    } else if (showToolSwitcher) {
      nextState.showToolSwitcher = false
    }
  }

  return nextState
}
/* eslint-enable complexity */
/* eslint-enable max-depth */
/* eslint-enable no-lonely-if */

class NavBarContainer extends React.PureComponent {
  state = {
    showLabel: false,
    showLabelMinWidth: -1,
    showToolSwitcher: false,
    showToolSwitcherMinWidth: -1,
    winWidth: -1
  }

  loginStatusElement = null
  searchElement = null
  tickAnimFrameId = null

  componentDidMount() {
    // Start an animation frame loop to check whether elements within the NavBar
    // exits the viewport at any time.
    this.tick()
  }

  /* eslint-disable complexity */
  componentDidUpdate(prevProps, prevState) {
    const {showLabel, showLabelMinWidth, showToolSwitcher, showToolSwitcherMinWidth} = this.state
    const didShowLabel = showLabelMinWidth === -1 && !prevState.showLabel && showLabel
    const didShowToolSwitcher =
      showToolSwitcherMinWidth === -1 && !prevState.showToolSwitcher && showToolSwitcher
    const didHideLabel = showToolSwitcherMinWidth === -1 && prevState.showLabel && !showLabel

    if (didShowLabel || didShowToolSwitcher || didHideLabel) {
      this.handleCustomResize(window.innerWidth)
    }
  }
  /* eslint-enable complexity */

  componentWillUnmount() {
    if (this.io) {
      this.io.disconnect()
      this.io = null
    }

    if (this.tickAnimFrameId) {
      window.cancelAnimationFrame(this.tickAnimFrameId)
      this.tickAnimFrameId = null
    }
  }

  tick = () => {
    this.handleFrame()
    this.tickAnimFrameId = window.requestAnimationFrame(this.tick)
  }

  handleFrame() {
    const winWidth = window.innerWidth
    if (winWidth !== this.state.winWidth) {
      this.handleCustomResize(winWidth)
    }
  }

  handleCustomResize(winWidth) {
    if (this.loginStatusElement) {
      const {showToolSwitcher} = this.state
      // console.log(this.searchElement)
      const mostRightRect = showToolSwitcher
        ? this.loginStatusElement.getBoundingClientRect()
        : this.searchElement.getBoundingClientRect()
      this.setState(state => {
        const nextState = getNextState(state, mostRightRect.left + mostRightRect.width, winWidth)
        // console.log(nextState)
        return nextState
      })
    }
  }

  handleSetLoginStatusElement = element => {
    this.loginStatusElement = element
  }

  handleSetSearchElement = element => {
    this.searchElement = element
  }

  render() {
    const {showLabel, showToolSwitcher} = this.state

    return (
      <NavBar
        {...this.props}
        onSetLoginStatusElement={this.handleSetLoginStatusElement}
        onSetSearchElement={this.handleSetSearchElement}
        showLabel={showLabel}
        showToolSwitcher={showToolSwitcher}
      />
    )
  }
}

export default NavBarContainer
<|endoftext|>


<commit_before>'use strict';

angular.module('mean.icu.data.inboxservice', [])
    .service('InboxService', function(ApiUri, $http, $stateParams, $i18next, WarningsService, UsersService
    ) {
        const EntityPrefix = '/inbox';
        let users = [];
        UsersService.getAll().then( allUsers => {
          users = allUsers;
        });

        function getUpdateEntities(activities) {
            return $http.post(ApiUri + EntityPrefix, activities)
                .then(result => {
                        WarningsService.setWarning(result.headers().warning);
                        return result.data;
                    },err => console.error(err)
                );
        }

      function getActivityDescription (activity) {
        let creator = activity.creator.name;
        switch (activity.updateField){
          case 'create' :
            return `${creator} ${$i18next('created')} ${activity.entityObj.title}`;
            break;
          case 'star' :
            return `${creator} ${$i18next('updatedStar')}`;
            break;
          case 'tags' :
            return `${creator} ${$i18next('updatedTagsTo')} ${activity.current}`;
            break;
          case 'due' :
            return `${creator} ${$i18next('changedDueDateTo')} ${moment(activity.entityObj.due).format('DD/MM/YYYY')}`;
            break;
          case 'deadline' :
            return `${creator} ${$i18next('changedDeadlineTo')} ${moment(activity.entityObj.startDate).format('DD/MM/YYYY')} - ${moment(activity.entityObj.endDate).format('DD/MM/YYYY')}`;
            break;
          case 'status' :
            return `${creator} ${$i18next('changedStatusTo')} ${activity.current}`;
            break;
          case 'title' :
            return `${creator} ${$i18next('changedTitleTo')} ${activity.current}`;
            break;
          case 'assign' :
            return `${creator} ${$i18next('assigned')} ${ getUser(activity.current).username }`;
            break;
          case 'location' :
            return `${creator} ${$i18next('changedLocationTo')} ${activity.current}`;
            break;
          case 'color' :
            return `${creator} ${$i18next('updatedColor')} ${activity.current}`;
            break;
          case 'description' :
            return `${creator} ${$i18next('updatedDescription')} ${activity.current}`;
            break;
          case 'comment' :
            return `${creator} ${$i18next('leavedComment')} ${activity.current}`;
            break;
          case 'attachment' :
            return `${creator} ${$i18next('addedAttachment')} ${activity.current}`;
            break;
          case 'watchers' :
            return `${creator} ${$i18next('changedWatchers')}`;
            break;
          case 'assign' :
            return `${creator} ${$i18next('assigned')} ${activity.current.username} ${$i18next('to')} ${activity.entityObj.title}`;
            break;
        }
      }

      function getUser(userId){
        return users.find( user => user._id === userId)
      }

        return {
          getUpdateEntities,
          getActivityDescription,
        };
    });
<commit_msg>fixed due date showing in details pane<commit_after>'use strict';

angular.module('mean.icu.data.inboxservice', [])
    .service('InboxService', function(ApiUri, $http, $stateParams, $i18next, WarningsService, UsersService
    ) {
        const EntityPrefix = '/inbox';
        let users = [];
        UsersService.getAll().then( allUsers => {
          users = allUsers;
        });

        function getUpdateEntities(activities) {
            return $http.post(ApiUri + EntityPrefix, activities)
                .then(result => {
                        WarningsService.setWarning(result.headers().warning);
                        return result.data;
                    },err => console.error(err)
                );
        }

      function getActivityDescription (activity) {
        let creator = activity.creator.name;
        switch (activity.updateField){
          case 'create' :
            return `${creator} ${$i18next('created')} ${activity.entityObj.title}`;
            break;
          case 'star' :
            return `${creator} ${$i18next('updatedStar')}`;
            break;
          case 'tags' :
            return `${creator} ${$i18next('updatedTagsTo')} ${activity.current}`;
            break;
          case 'due' :
            return `${creator} ${$i18next('changedDueDateTo')} ${moment( activity.current ).format('DD/MM/YYYY')}`;
            break;
          case 'deadline' :
            return `${creator} ${$i18next('changedDeadlineTo')} ${moment(activity.entityObj.startDate).format('DD/MM/YYYY')} - ${moment(activity.entityObj.endDate).format('DD/MM/YYYY')}`;
            break;
          case 'status' :
            return `${creator} ${$i18next('changedStatusTo')} ${activity.current}`;
            break;
          case 'title' :
            return `${creator} ${$i18next('changedTitleTo')} ${activity.current}`;
            break;
          case 'assign' :
            return `${creator} ${$i18next('assigned')} ${ getUser(activity.current).username }`;
            break;
          case 'location' :
            return `${creator} ${$i18next('changedLocationTo')} ${activity.current}`;
            break;
          case 'color' :
            return `${creator} ${$i18next('updatedColor')} ${activity.current}`;
            break;
          case 'description' :
            return `${creator} ${$i18next('updatedDescription')} ${activity.current}`;
            break;
          case 'comment' :
            return `${creator} ${$i18next('leavedComment')} ${activity.current}`;
            break;
          case 'attachment' :
            return `${creator} ${$i18next('addedAttachment')} ${activity.current}`;
            break;
          case 'watchers' :
            return `${creator} ${$i18next('changedWatchers')}`;
            break;
          case 'assign' :
            return `${creator} ${$i18next('assigned')} ${activity.current.username} ${$i18next('to')} ${activity.entityObj.title}`;
            break;
        }
      }

      function getUser(userId){
        return users.find( user => user._id === userId)
      }

        return {
          getUpdateEntities,
          getActivityDescription,
        };
    });
<|endoftext|>


<commit_before>import React from "react"

exports.modifyHeadComponents = (args, pluginOptions) => {
  let offsetY = 0
  if (pluginOptions.offsetY) {
    offsetY = pluginOptions.offsetY
  }

  const styles = `
    .anchor {
      float: left;
      padding-right: 4px;
      margin-left: -20px;
    }
    h1 .anchor svg,
    h2 .anchor svg,
    h3 .anchor svg,
    h4 .anchor svg,
    h5 .anchor svg,
    h6 .anchor svg {
      visibility: hidden;
    }
    h1:hover .anchor svg,
    h2:hover .anchor svg,
    h3:hover .anchor svg,
    h4:hover .anchor svg,
    h5:hover .anchor svg,
    h6:hover .anchor svg {
      visibility: visible;
    }
  `

  const script = `
    document.addEventListener("DOMContentLoaded", function(event) {
      var hash = location.hash.replace('#', '')
      if (hash !== '') {
        var element = document.getElementById(hash)
        if (element) {
          var offset = element.offsetTop
          window.scrollTo(0, offset - ${offsetY})
        }
      }
    })
  `

  return [
    <style type="text/css">{styles}</style>,
    <script dangerouslySetInnerHTML={{ __html: script }} />,
  ]
}
<commit_msg>Wait for the browser to finish rendering before scrolling<commit_after>import React from "react"

exports.modifyHeadComponents = (args, pluginOptions) => {
  let offsetY = 0
  if (pluginOptions.offsetY) {
    offsetY = pluginOptions.offsetY
  }

  const styles = `
    .anchor {
      float: left;
      padding-right: 4px;
      margin-left: -20px;
    }
    h1 .anchor svg,
    h2 .anchor svg,
    h3 .anchor svg,
    h4 .anchor svg,
    h5 .anchor svg,
    h6 .anchor svg {
      visibility: hidden;
    }
    h1:hover .anchor svg,
    h2:hover .anchor svg,
    h3:hover .anchor svg,
    h4:hover .anchor svg,
    h5:hover .anchor svg,
    h6:hover .anchor svg {
      visibility: visible;
    }
  `

  const script = `
    document.addEventListener("DOMContentLoaded", function(event) {
      var hash = location.hash.replace('#', '')
      if (hash !== '') {
        var element = document.getElementById(hash)
        if (element) {
          var offset = element.offsetTop
          // Wait for the browser to finish rendering before scrolling.
          setTimeout((function() {
            window.scrollTo(0, offset - ${offsetY})
          }), 0)
        }
      }
    })
  `

  return [
    <style type="text/css">{styles}</style>,
    <script dangerouslySetInnerHTML={{ __html: script }} />,
  ]
}
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { Sigil } from '~/logic/lib/sigil';
import { cite } from '~/logic/lib/util';
import moment from 'moment';
import { Box, Text, Row } from '@tlon/indigo-react';
import RichText from '~/views/components/RichText';

export const CommentItem = (props) => {
  const content = props.post.contents[0].text;
  const timeSent =
    moment.unix(props.post['time-sent'] / 1000).format('hh:mm a');

  const showAvatar = props.avatar && !props.hideAvatars;
  const showNickname = props.nickname && !props.hideNicknames;
  const img = showAvatar
    ?
    : <Sigil
        ship={`~${props.post.author}`}
        size={36}
        color={`#${props.color}`}
        classes={(!!props.member ? 'mix-blend-diff' : '')}
      />;

  return (
    <Box width="100%" py={3} opacity={props.pending ? '0.6' : '1'}>
      <Row backgroundColor='white'>
        {img}
        <Row fontSize={0} alignItems="center" ml={2}>
          <Text mono={!props.hasNickname} title={props.post.author}>
            {showNickname ? props.nickname : cite(props.post.author)}
          </Text>
          <Text gray ml={2}>{timeSent}</Text>
        </Row>
        <Text display="block" py={3} fontSize={1}>
          <RichText remoteContentPolicy={props.remoteContentPolicy}>
            {content}
          </RichText>
        </Text>
      </Row>
    </Box>
  );
}

<commit_msg>interface: comment item renders properly<commit_after>import React, { Component } from 'react';
import { Sigil } from '~/logic/lib/sigil';
import { cite } from '~/logic/lib/util';
import moment from 'moment';
import { Box, Text, Row } from '@tlon/indigo-react';
import RichText from '~/views/components/RichText';

export const CommentItem = (props) => {
  const content = props.post.contents[0].text;
  const timeSent =
    moment.unix(props.post['time-sent'] / 1000).format('hh:mm a');

  const showAvatar = props.avatar && !props.hideAvatars;
  const showNickname = props.nickname && !props.hideNicknames;
  const img = showAvatar
    ?
    : <Sigil
        ship={`~${props.post.author}`}
        size={36}
        color={`#${props.color}`}
        classes={(!!props.member ? 'mix-blend-diff' : '')}
      />;

  return (
    <Box width="100%" py={3} opacity={props.pending ? '0.6' : '1'}>
      <Row backgroundColor='white'>
        {img}
        <Row fontSize={0} alignItems="center" ml={2}>
          <Text mono={!props.hasNickname} title={props.post.author}>
            {showNickname ? props.nickname : cite(props.post.author)}
          </Text>
          <Text gray ml={2}>{timeSent}</Text>
        </Row>
      </Row>
      <Row>
        <Text display="block" py={3} fontSize={1}>
          <RichText remoteContentPolicy={props.remoteContentPolicy}>
            {content}
          </RichText>
        </Text>
      </Row>
    </Box>
  );
}

<|endoftext|>


<commit_before>/*
 * This file is part of the GOsa project -  http://gosa-project.org
 *
 * Copyright:
 *    (C) 2010-2017 GONICUS GmbH, Germany, http://www.gonicus.de
 *
 * License:
 *    LGPL-2.1: http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * See the LICENSE file in the project's top-level directory for details.
 */

/**
* Generic settings editor.
*/
qx.Class.define("gosa.ui.settings.Editor", {
  extend : qx.ui.core.Widget,

  /*
  *****************************************************************************
     CONSTRUCTOR
  *****************************************************************************
  */
  construct : function(namespace) {
    this.base(arguments);
    this._setLayout(new qx.ui.layout.VBox());
    this.setNamespace(namespace);

    this.addListenerOnce("appear", this.__initTable, this);
  },

  /*
  *****************************************************************************
     PROPERTIES
  *****************************************************************************
  */
  properties : {
    title: {
      check: "String",
      nullable: true,
      apply: "_applyTitle"
    },

    namespace: {
      check: "String",
      init: "",
      apply: "_applyNamespace"
    }
  },

  /*
  *****************************************************************************
     MEMBERS
  *****************************************************************************
  */
  members : {
    __handler: null,

    // overridden
    _createChildControlImpl: function(id) {
      var control;

      switch(id) {
        case "title":
          control = new qx.ui.basic.Label(this.tr("Editor"));
          this._add(control);
          break;

        case "table":
          var propertyEditor_resizeBehaviour = {
            tableColumnModel : function(obj) {
              return new qx.ui.table.columnmodel.Resize(obj);
            }
          };
          control = new qx.ui.table.Table(null, propertyEditor_resizeBehaviour);
          this._add(control, {flex: 1});
          break;
      }

      return control || this.base(arguments, id);
    },

    // property apply
    _applyNamespace: function(value) {
      this.__handler = gosa.data.SettingsRegistry.getHandlerForPath(value);
    },

    __initTable: function() {

      var itemInfos = this.__handler.getItemInfos();
      var tableData = [];
      Object.getOwnPropertyNames(itemInfos).forEach(function(path) {
        var options = {};
        if (itemInfos[path].type) {
          options.type = itemInfos[path].type;
          if (options.type === "boolean" && qx.lang.Type.isString(itemInfos[path].value)) {
            itemInfos[path].value = itemInfos[path].value.toLowerCase() === "true";
          }
        }
        if (itemInfos[path].options) {
          options.options = itemInfos[path].options;
        }
        tableData.push([path, itemInfos[path].title||path, itemInfos[path].value, options]);
      }, this);

      // create the  "meta" cell renderer object
      var propertyCellRendererFactory = new qx.ui.table.cellrenderer.Dynamic(this.__propertyCellRendererFactoryFunc);

      // create a "meta" cell editor object
      var propertyCellEditorFactory = new qx.ui.table.celleditor.Dynamic(this.__propertyCellEditorFactoryFunc);

      // create table
      var propertyEditor_tableModel = new qx.ui.table.model.Simple();
      propertyEditor_tableModel.setColumns(
      [
        this.tr('Path'),
        this.tr('Title'),
        this.tr('Value')
      ]);

      var propertyEditor = this.getChildControl("table");
      propertyEditor.setTableModel(propertyEditor_tableModel);

      // remove decor
      propertyEditor.setDecorator(null);

      // layout
      propertyEditor.setColumnVisibilityButtonVisible(false);
      propertyEditor.setKeepFirstVisibleRowComplete(true);
      propertyEditor.setStatusBarVisible(false);

      // selection mode
      propertyEditor.getSelectionModel().setSelectionMode(qx.ui.table.selection.Model.SINGLE_SELECTION);

      // Get the table column model
      var tcm = propertyEditor.getTableColumnModel();

      // first table columns is not visible, has the key
      tcm.setColumnVisible(0, false);
      propertyEditor_tableModel.sortByColumn(0, true);

      // second column has the label

      // third column for editing the value and has special cell renderers
      // and cell editors
      propertyEditor_tableModel.setColumnEditable(2, true);
      tcm.setDataCellRenderer(2, propertyCellRendererFactory);
      tcm.setCellEditorFactory(2, propertyCellEditorFactory);

      // fourth column is not visible, has the metadata

      // set data
      propertyEditor.getTableModel().setData(tableData);

      var model = propertyEditor.getTableModel();
      // create event listener for data change event. this would normally
      // send the data back to the server etc.
      propertyEditor.getTableModel().addListener("dataChanged", function(event) {
        if ( !(event instanceof qx.event.type.Data)) {
          return;
        }
        var changedData = event.getData();

        // get changed data
        var key = model.getValue(0,changedData.firstRow);
        var value = model.getValue(changedData.firstColumn, changedData.firstRow);

        gosa.io.Rpc.getInstance().cA("changeSetting", this.getNamespace()+"."+key, value)
        .catch(gosa.ui.dialogs.Error.show);
      }, this);

      return propertyEditor;
    },

    __propertyCellRendererFactoryFunc : function (cellInfo)
    {
      var table = cellInfo.table;
      var tableModel = table.getTableModel();
      var rowData = tableModel.getRowData(cellInfo.row);
      var metaData = rowData[3];
      var renderer;

      for ( var cmd in metaData ) {

        switch ( cmd ) {
          case "type":

            switch ( metaData['type'])
            {
              case "boolean":
                return new qx.ui.table.cellrenderer.Boolean;

              case "password":
                return new qx.ui.table.cellrenderer.Password;
            }
            break;

          case "options":
            renderer = new qx.ui.table.cellrenderer.Replace;
            var replaceMap = {};
            metaData['options'].forEach(function(row){
              if (row instanceof Array)
              {
                replaceMap[row[0]]=row[2];
              }
            });
            renderer.setReplaceMap(replaceMap);
            renderer.addReversedReplaceMap();
            return renderer;
        }
      }
      return new qx.ui.table.cellrenderer.Default();
    },

    // cell editor factory function
    // returns a cellEditorFactory instance based on data in the row itself
    __propertyCellEditorFactoryFunc: function (cellInfo) {
      var table = cellInfo.table;
      var tableModel = table.getTableModel();
      var rowData = tableModel.getRowData(cellInfo.row);
      var metaData = rowData[3];
      var cellEditor = new qx.ui.table.celleditor.TextField;
      var validationFunc = null;

      for ( var cmd in metaData )
      {
        switch ( cmd )
        {
          case "options":
            if (metaData.editable)
            {
              cellEditor = new qx.ui.table.celleditor.ComboBox();
            }
            else
            {
              cellEditor = new qx.ui.table.celleditor.SelectBox();
            }
            cellEditor.setListData( metaData['options'] );
            break;

          case "editable":
            break;

          case "type":
            switch ( metaData['type'] )
            {
              case "password":
                cellEditor = new qx.ui.table.celleditor.PasswordField;
                break;

              case "boolean":
                cellEditor = new qx.ui.table.celleditor.CheckBox;
                break;

              case "email":
                cellEditor.setValidationFunction (
                function( newValue, oldValue )
                {
                  var re = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*\.(\w{2}|(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum))$/;
                  if ( re.test(newValue) )
                  {
                    return newValue;
                  }
                  alert("You did not enter a valid email address");
                  return oldValue;
                });
                break;
            }
            break;

          case "regExp":
            cellEditor.setValidationFunction (
            function( newValue, oldValue )
            {
              var re = new RegExp(metaData['regExp']);
              if ( re.test(newValue) )
              {
                return newValue;
              }
              alert(metaData['failMsg']);
              return oldValue;
            });
            break;

          case "validationFunc":
            cellEditor.setValidationFunction (metaData['validationFunc']);
            break;

          case "required":
            validationFunc = function( newValue, oldValue )
            {
              if (! newValue)
              {
                alert(this.tr("You need to supply a value here"));
                return oldValue;
              }
              return newValue;
            };
            break;
        }
      }
      return cellEditor;
    },

    // property apply
    _applyTitle: function(value) {
      var control = this.getChildControl("title");
      if (value) {
        control.setValue(value);
        control.show();
      } else {
        control.exclude();
      }
    }
  }
});<commit_msg>add filter to settings table<commit_after>/*
 * This file is part of the GOsa project -  http://gosa-project.org
 *
 * Copyright:
 *    (C) 2010-2017 GONICUS GmbH, Germany, http://www.gonicus.de
 *
 * License:
 *    LGPL-2.1: http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * See the LICENSE file in the project's top-level directory for details.
 */

/**
* Generic settings editor.
*/
qx.Class.define("gosa.ui.settings.Editor", {
  extend : qx.ui.core.Widget,

  /*
  *****************************************************************************
     CONSTRUCTOR
  *****************************************************************************
  */
  construct : function(namespace) {
    this.base(arguments);
    this._setLayout(new qx.ui.layout.VBox());
    this.setNamespace(namespace);

    this._createChildControl("filter");

    this.addListenerOnce("appear", this.__initTable, this);
  },

  /*
  *****************************************************************************
     PROPERTIES
  *****************************************************************************
  */
  properties : {
    title: {
      check: "String",
      nullable: true,
      apply: "_applyTitle"
    },

    namespace: {
      check: "String",
      init: "",
      apply: "_applyNamespace"
    }
  },

  /*
  *****************************************************************************
     MEMBERS
  *****************************************************************************
  */
  members : {
    __handler: null,

    // overridden
    _createChildControlImpl: function(id) {
      var control;

      switch(id) {
        case "title":
          control = new qx.ui.basic.Label(this.tr("Editor"));
          this._addAt(control, 0);
          break;

        case "filter":
          control = new qx.ui.form.TextField().set({
            placeholder : this.tr("Search .."),
            liveUpdate : true,
            allowGrowX : true
          });
          control.addListener("changeValue", this._applyFilter, this);
          this._addAt(control, 1);
          break;

        case "table":
          var propertyEditor_resizeBehaviour = {
            tableColumnModel : function(obj) {
              return new qx.ui.table.columnmodel.Resize(obj);
            }
          };
          control = new qx.ui.table.Table(null, propertyEditor_resizeBehaviour);
          this._addAt(control, 2, {flex: 1});
          break;
      }

      return control || this.base(arguments, id);
    },

    _applyFilter: function() {
      var filtered = this._tableData;
      var searchValue = this.getChildControl("filter").getValue();
      if (searchValue && searchValue.length > 2) {
        var options = {
          shouldSort: true,
          threshold: 0.4,
          tokenize: true,
          keys: ["0", "1"]
        };
        var fuse = new Fuse(filtered, options);
        filtered = fuse.search(searchValue);
        console.log(filtered);
        this.getChildControl("table").getTableModel().setData(filtered);
      } else {
        this.getChildControl("table").getTableModel().setData(this._tableData);
      }
    },

    // property apply
    _applyNamespace: function(value) {
      this.__handler = gosa.data.SettingsRegistry.getHandlerForPath(value);
    },

    __initTable: function() {
      var itemInfos = this.__handler.getItemInfos();
      var tableData = this._tableData = [];
      Object.getOwnPropertyNames(itemInfos).forEach(function(path) {
        var options = {};
        if (itemInfos[path].type) {
          options.type = itemInfos[path].type;
          if (options.type === "boolean" && qx.lang.Type.isString(itemInfos[path].value)) {
            itemInfos[path].value = itemInfos[path].value.toLowerCase() === "true";
          }
        }
        if (itemInfos[path].options) {
          options.options = itemInfos[path].options;
        }
        tableData.push([path, itemInfos[path].title||path, itemInfos[path].value, options]);
      }, this);

      // create the  "meta" cell renderer object
      var propertyCellRendererFactory = new qx.ui.table.cellrenderer.Dynamic(this.__propertyCellRendererFactoryFunc);

      // create a "meta" cell editor object
      var propertyCellEditorFactory = new qx.ui.table.celleditor.Dynamic(this.__propertyCellEditorFactoryFunc);

      // create table
      var propertyEditor_tableModel = new qx.ui.table.model.Simple();
      propertyEditor_tableModel.setColumns(
      [
        this.tr('Path'),
        this.tr('Title'),
        this.tr('Value')
      ]);

      var propertyEditor = this.getChildControl("table");
      propertyEditor.setTableModel(propertyEditor_tableModel);

      // remove decor
      propertyEditor.setDecorator(null);

      // layout
      propertyEditor.setColumnVisibilityButtonVisible(false);
      propertyEditor.setKeepFirstVisibleRowComplete(true);
      propertyEditor.setStatusBarVisible(false);

      // selection mode
      propertyEditor.getSelectionModel().setSelectionMode(qx.ui.table.selection.Model.SINGLE_SELECTION);

      // Get the table column model
      var tcm = propertyEditor.getTableColumnModel();

      propertyEditor_tableModel.sortByColumn(0, true);

      // second column has the label

      // third column for editing the value and has special cell renderers
      // and cell editors
      propertyEditor_tableModel.setColumnEditable(2, true);
      tcm.setDataCellRenderer(2, propertyCellRendererFactory);
      tcm.setCellEditorFactory(2, propertyCellEditorFactory);

      // set data
      propertyEditor.getTableModel().setData(tableData);

      var model = propertyEditor.getTableModel();
      // create event listener for data change event. this would normally
      // send the data back to the server etc.
      propertyEditor.getTableModel().addListener("dataChanged", function(event) {
        if ( !(event instanceof qx.event.type.Data)) {
          return;
        }
        var changedData = event.getData();

        // get changed data
        var key = model.getValue(0,changedData.firstRow);
        var value = model.getValue(changedData.firstColumn, changedData.firstRow);

        gosa.io.Rpc.getInstance().cA("changeSetting", this.getNamespace()+"."+key, value)
        .catch(gosa.ui.dialogs.Error.show);
      }, this);

      return propertyEditor;
    },

    __propertyCellRendererFactoryFunc : function (cellInfo)
    {
      var table = cellInfo.table;
      var tableModel = table.getTableModel();
      var rowData = tableModel.getRowData(cellInfo.row);
      var metaData = rowData[3];
      var renderer;

      for ( var cmd in metaData ) {

        switch ( cmd ) {
          case "type":

            switch ( metaData['type'])
            {
              case "boolean":
                return new qx.ui.table.cellrenderer.Boolean;

              case "password":
                return new qx.ui.table.cellrenderer.Password;
            }
            break;

          case "options":
            renderer = new qx.ui.table.cellrenderer.Replace;
            var replaceMap = {};
            metaData['options'].forEach(function(row){
              if (row instanceof Array)
              {
                replaceMap[row[0]]=row[2];
              }
            });
            renderer.setReplaceMap(replaceMap);
            renderer.addReversedReplaceMap();
            return renderer;
        }
      }
      return new qx.ui.table.cellrenderer.Default();
    },

    // cell editor factory function
    // returns a cellEditorFactory instance based on data in the row itself
    __propertyCellEditorFactoryFunc: function (cellInfo) {
      var table = cellInfo.table;
      var tableModel = table.getTableModel();
      var rowData = tableModel.getRowData(cellInfo.row);
      var metaData = rowData[3];
      var cellEditor = new qx.ui.table.celleditor.TextField;
      var validationFunc = null;

      for ( var cmd in metaData )
      {
        switch ( cmd )
        {
          case "options":
            if (metaData.editable)
            {
              cellEditor = new qx.ui.table.celleditor.ComboBox();
            }
            else
            {
              cellEditor = new qx.ui.table.celleditor.SelectBox();
            }
            cellEditor.setListData( metaData['options'] );
            break;

          case "editable":
            break;

          case "type":
            switch ( metaData['type'] )
            {
              case "password":
                cellEditor = new qx.ui.table.celleditor.PasswordField;
                break;

              case "boolean":
                cellEditor = new qx.ui.table.celleditor.CheckBox;
                break;

              case "email":
                cellEditor.setValidationFunction (
                function( newValue, oldValue )
                {
                  var re = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*\.(\w{2}|(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum))$/;
                  if ( re.test(newValue) )
                  {
                    return newValue;
                  }
                  alert("You did not enter a valid email address");
                  return oldValue;
                });
                break;
            }
            break;

          case "regExp":
            cellEditor.setValidationFunction (
            function( newValue, oldValue )
            {
              var re = new RegExp(metaData['regExp']);
              if ( re.test(newValue) )
              {
                return newValue;
              }
              alert(metaData['failMsg']);
              return oldValue;
            });
            break;

          case "validationFunc":
            cellEditor.setValidationFunction (metaData['validationFunc']);
            break;

          case "required":
            validationFunc = function( newValue, oldValue )
            {
              if (! newValue)
              {
                alert(this.tr("You need to supply a value here"));
                return oldValue;
              }
              return newValue;
            };
            break;
        }
      }
      return cellEditor;
    },

    // property apply
    _applyTitle: function(value) {
      var control = this.getChildControl("title");
      if (value) {
        control.setValue(value);
        control.show();
      } else {
        control.exclude();
      }
    }
  }
});<|endoftext|>


<commit_before>
// observer/listener pattern handling selection event on plots
function CaseSelectObserver() {
    this.funcs = {};
    this.caseId = null;
}
CaseSelectObserver.prototype = {
    subscribe: function(listener,func,fire) {
        this.funcs[listener] = func;
        if (fire)
            func.call(window,this.caseId);
    },
    fireSelection: function(caseId,source,targets,forceFire) {
        if (!forceFire&&compareAssociativeArrays(caseId,this.caseId)) return;

        var pre = this.caseId;
        this.caseId = caseId;
        for (var listener in this.funcs) {
            if (targets&&(targets!=listener&&!targets[listener])) continue;
            if (listener==source) continue;
            var func = this.funcs[listener];
            func.call(window,caseId,pre);
        }
    }
};

function nrKeysAssociativeArrays(a) {
    if (a==null) return 0;
    var i = 0;
    for (var key in a) i++;
    return i;
}

function compareAssociativeArrays(a, b) {
    if (a == b) return true;
    if ((typeof a)!=(typeof {})||(typeof b)!=(typeof {})) return false;
    if (nrKeysAssociativeArrays(a) != nrKeysAssociativeArrays(b)) return false;
    for (var key in a) {
        if (a[key] != b[key]) {
            return false;
        }
    }
    return true;
}

var plotAllClinicalData = false;
var smallPlotCachedDt = null;

// replot small
function resetSmallPlots(dt) {
    if (dt) smallPlotCachedDt = dt;
    else dt = smallPlotCachedDt;

    var divNum = 1;
    var hidden = false;
    for (var i=1; i<dt.getNumberOfColumns(); i++) {
        if (selectedCol(dt,i))
            plotData(divNum++,dt,i);
        else
            hidden = true;
    }

    if (plotAllClinicalData) {
        var start = divNum;
        for (var i=1; i<dt.getNumberOfColumns(); i++) {
            if (!selectedCol(dt,i))
                plotData(divNum++,dt,i);
        }

        var div = getSmallPlotDiv(divNum++);
        $(div).removeClass("small-plot-div");
        $(div).html("<button class='vertical-center-in-a-div' onclick='togglePlotAllOrSelect("+start+","+divNum+");'><< less</button>");
    } else if (hidden) {
        var div = getSmallPlotDiv(divNum);
        $(div).removeClass("small-plot-div");
        $(div).html("<button class='vertical-center-in-a-div' onclick='togglePlotAllOrSelect("+divNum+","+(divNum+1)+");'>more >></button>");
    }
}

function togglePlotAllOrSelect(divRemoveFirst, divRemoveLast) {
    for (var i=divRemoveFirst; i<divRemoveLast; i++) {
        removeSmallPlotDiv(i);
    }
    plotAllClinicalData = !plotAllClinicalData;
    resetSmallPlots();
}

function selectedCol(dt,col) {
    var c = dt.getColumnLabel(col);
    return c.toLowerCase().match(/(^age)|(gender)|(survival)|(grade)|(stage)|(histology)|(disease state)|(score)|(mutation_count)|(copy_number_altered_fraction)/);
}

// draw datatable
function drawDataTable(tableId,dt,caseMap) {
    // set headers
    var nCol = dt.getNumberOfColumns();
    var headers = [];
    var isColNum = [];
    for (var col=0; col<nCol; col++) {
        headers.push(getNiceHeader(dt.getColumnLabel(col)));
        isColNum.push(dt.getColumnType(col)==='number');
    }
    $('#'+tableId+' thead tr').html(""+headers.join("	")+"	");

    // format data
    var data = [];
    var nRow = dt.getNumberOfRows();
    for (var row=0; row<nRow; row++) {
        var dRow = [];
        for (var col=0; col<nCol; col++) {
            var val = dt.getValue(row,col);
            if (val && isColNum[col]) {
                val = cbio.util.toPrecision(val,3,0.01);
            }
            dRow.push(val);
        }
        data.push(dRow);
    }

    var oTable = $('#'+tableId).dataTable( {
        "sDom": '<"H"<"clinical-table-name">fr>t<"F"<"datatable-paging"pil>>',
        "bJQueryUI": true,
        "bDestroy": true,
        "aaData": data,
        "aoColumnDefs":[
            {// id
                "aTargets": [ 0 ],
                "sClass": "center-align-td",
                "mDataProp": function(source,type,value) {
                    if (type==='set') {
                        source[0]=value;
                    } else if (type==='display') {
                        return formatPatientLink(source[0]);
                    } else {
                        return source[0];
                    }
                }
            }
        ],
        "oLanguage": {
            "sInfo": "  (_START_ to _END_ of _TOTAL_)  ",
            "sLengthMenu": "Show _MENU_ per page"
        },
        "iDisplayLength": 25,
        "aLengthMenu": [[5,10, 25, 50, 100, -1], [5, 10, 25, 50, 100, "All"]]
    });

    oTable.css("width","100%");

    csObs.subscribe(tableId,function(caseId) {
        if (caseId==null) {
            oTable.fnFilter('', 0,true);
        } else if ((typeof caseId)==(typeof '')) {
            oTable.fnFilter("^"+caseId+"$",0,true);
        } else if ((typeof caseId)==(typeof {})) {
            var ids = [];
            for (var id in caseId) {
                ids.push(id);
            }
            oTable.fnFilter("(^"+ids.join("$)|(^")+"$)",0,true);
        }
    },true);

    $('#'+tableId+' tbody tr').live('click', function () {
        var nTds = $('td', this);
        var caseId = $(nTds[0]).text();
        csObs.fireSelection(caseId,tableId);
    } );
}

function getHeaderMap(dataTable) {
    var map = {};
    var cols = dataTable.getNumberOfColumns();
    for (var i=0; i<cols; i++) {
        map[dataTable.getColumnLabel(i)] = i;
    }
    return map;
}

function getCaseMap(dataTable) {
    var map = {};
    var rows = dataTable.getNumberOfRows();
    for (var i=0; i<rows; i++) {
        map[dataTable.getValue(i,0)] = i;
    }
    return map;
}

function makeContInxArray(start,end) {
    var ix = [];
    for (var i=start; i<=end; i++) {
        ix.push(i);
    }
    return ix;
}

function calcHistogram(dt,col,bins,caseIdsFilter) {
    var hist = [[dt.getColumnLabel(col),'# patients']];
    var caseIdHistMap = {};
    var histCaseIdMap = {};
    var rows = dt.getNumberOfRows();
    var t = dt.getColumnType(col);
    if (t=="number") {
        if (bins==null) bins = 10;
        if ((typeof bins)==(typeof 1)) {
            var r = dt.getColumnRange(col);
            var step = Math.pow(10,Math.floor(Math.log((r.max-r.min)/2)*Math.LOG10E));
            var start = step*Math.floor(r.min/step);
            bins = [];
            for (var bin=start; bin<=r.max; bin+=step) {
                bins.push(bin);
            }
        }

        var count = [];
        for (var i=0; i<=bins.length; i++) {
            count.push([]);
        }
        count.push([]); //unknown

        for (var r=0; r<rows; r++) {
            var caseId = dt.getValue(r,0);
            if (caseIdsFilter && !caseIdsFilter[caseId]) continue;
            var v = dt.getValue(r,col);
            var i;
            if (v==null) {
                i = bins.length+1;
            } else {
                for (i=0; i<bins.length; i++) {
                    if (bins[i]>=v) break;
                }
            }
            count[i].push(caseId);
            caseIdHistMap[caseId]=i;
        }

        hist.push(['<='+bins[0],count[0].length]);
        histCaseIdMap[0]=count[0];
        var i=1;
        for (; i<bins.length; i++) {
            hist.push([bins[i-1]+'~'+bins[i],count[i].length]);
            histCaseIdMap[i]=count[i];
        }
        hist.push(['>'+bins[bins.length-1],count[i].length]);
        histCaseIdMap[i]=count[i];
        if (count[++i].length>0) { // including unknow if positive
            hist.push(['Unknown',count[i].length]);
            histCaseIdMap[i]=count[i];
        }
    } else {
        var count = {};
        for (var r=0; r<rows; r++) {
            var caseId = dt.getValue(r,0);
            if (caseIdsFilter && !caseIdsFilter[caseId]) continue;
            var v = dt.getValue(r,col);
            if (v==null) v="Unknown";
            if(count[v]==null) count[v] = [];
            count[v].push(caseId);
        }
        var row=0;
        for (var key in count) {
            var c = count[key];
            hist.push([key,c.length]);
            histCaseIdMap[row]=c;
            for (var i=0; i<c.length; i++)
                caseIdHistMap[c[i]]=row;
            row++;
        }
    }
    return [hist,caseIdHistMap,histCaseIdMap];
}

function plotData(divNum,dt,col,caseIds) {
    var c = getNiceHeader(dt.getColumnLabel(col));
    var div = getSmallPlotDiv(divNum,c);
    var t = dt.getColumnType(col);
    var nCases = nrKeysAssociativeArrays(caseIds);
    var hist = calcHistogram(dt,col,getBins(dt,col),nCases>0?caseIds:null);
    var columnChart = t=='number';
    var chart = columnChart ?
        new google.visualization.ColumnChart(div) :
        new google.visualization.PieChart(div);
    google.visualization.events.addListener(chart, 'select', function(e){
        var s = chart.getSelection();
        var caseIds = {};
        var empty = true;
        for (var i=0; i<s.length; i++) {
            var ids = hist[2][s[i].row];
            for (var j=0; j<ids.length; j++) {
                caseIds[ids[j]] = true;
                empty = false;
            }
        }

        // if empty, update all plots including myself
        csObs.fireSelection(caseIds,empty?null:div.id);
    });
    google.visualization.events.addListener(chart, 'ready', function(e){
        csObs.subscribe(div.id,function(caseId,preCaseId) {
            if (caseId==null) {
                if (preCaseId==null) {
                    return;
                } else if ((typeof preCaseId)==(typeof '')) {
                    chart.setSelection();
                } else if ((typeof preCaseId)==(typeof {})) {
                    plotData(divNum,dt,col,caseId);
                }
            } else if ((typeof caseId)==(typeof '')) {
                var ix = hist[1][caseId];
                chart.setSelection(ix==null?null:[{'row': ix}]);
            } else if ((typeof caseId)==(typeof {})) {
                plotData(divNum,dt,col,caseId);
            }
        },(typeof caseIds)==='undefined');
    });
    var options = columnChart ?
        {
            hAxis: {title: dt.getColumnLabel(col)},
            vAxis: {title: '# of Patients'},
            legend: {position: 'none'}
        }
        :
        {'pieSliceText' : 'value'}
        ;
    chart.draw(google.visualization.arrayToDataTable(hist[0]),options);
    return chart;
}

function getBins(dt,col) {
    var c = dt.getColumnLabel(col);
    if (c=='age_at_diagnosis') {
        return [20,30,40,50,60,70,80];
    }
    if (c.match(/_months$/)) {
        return [12,24,36,48,60,72,84,96];
    }
    return null;
}

function getSmallPlotDiv(divNum,legend) {
    var div = document.getElementById('small-plot-div-'+divNum);
    if (div!=null) return div;

    var td = $('#small-plot-td-'+divNum);
    if (td.length==0) {
        var irow = Math.ceil(divNum/4);
        if (divNum%4==1) {
            $('#summary-plot-table').append('

');
            $('#small-plot-tr-'+irow).html('	');
        } else {
            $('#small-plot-tr-'+irow).append('	');
        }
        td = $('#small-plot-td-'+divNum);
    }

    var htm = '
'+'
';
    if (legend) {
        htm = '<fieldset><legend style="color:blue;font-weight:bold;">'+legend+'</legend>'
               + htm + '</fieldset>';
    }

    td.html(htm);
    return document.getElementById('small-plot-div-'+divNum);
}

function removeSmallPlotDiv(divNum) {
    $('#small-plot-td-'+divNum).html("");
}

function getNiceHeader(header) {
    var ret = header.replace(/_/g,' ');
    ret = ret.charAt(0).toUpperCase() + ret.slice(1);
    return ret;
}<commit_msg>alignment tweaks<commit_after>
// observer/listener pattern handling selection event on plots
function CaseSelectObserver() {
    this.funcs = {};
    this.caseId = null;
}
CaseSelectObserver.prototype = {
    subscribe: function(listener,func,fire) {
        this.funcs[listener] = func;
        if (fire)
            func.call(window,this.caseId);
    },
    fireSelection: function(caseId,source,targets,forceFire) {
        if (!forceFire&&compareAssociativeArrays(caseId,this.caseId)) return;

        var pre = this.caseId;
        this.caseId = caseId;
        for (var listener in this.funcs) {
            if (targets&&(targets!=listener&&!targets[listener])) continue;
            if (listener==source) continue;
            var func = this.funcs[listener];
            func.call(window,caseId,pre);
        }
    }
};

function nrKeysAssociativeArrays(a) {
    if (a==null) return 0;
    var i = 0;
    for (var key in a) i++;
    return i;
}

function compareAssociativeArrays(a, b) {
    if (a == b) return true;
    if ((typeof a)!=(typeof {})||(typeof b)!=(typeof {})) return false;
    if (nrKeysAssociativeArrays(a) != nrKeysAssociativeArrays(b)) return false;
    for (var key in a) {
        if (a[key] != b[key]) {
            return false;
        }
    }
    return true;
}

var plotAllClinicalData = false;
var smallPlotCachedDt = null;

// replot small
function resetSmallPlots(dt) {
    if (dt) smallPlotCachedDt = dt;
    else dt = smallPlotCachedDt;

    var divNum = 1;
    var hidden = false;
    for (var i=1; i<dt.getNumberOfColumns(); i++) {
        if (selectedCol(dt,i))
            plotData(divNum++,dt,i);
        else
            hidden = true;
    }

    if (plotAllClinicalData) {
        var start = divNum;
        for (var i=1; i<dt.getNumberOfColumns(); i++) {
            if (!selectedCol(dt,i))
                plotData(divNum++,dt,i);
        }

        var div = getSmallPlotDiv(divNum++);
        $(div).removeClass("small-plot-div");
        $(div).html("<button class='vertical-center-in-a-div' onclick='togglePlotAllOrSelect("+start+","+divNum+");'><< less</button>");
    } else if (hidden) {
        var div = getSmallPlotDiv(divNum);
        $(div).removeClass("small-plot-div");
        $(div).html("<button class='vertical-center-in-a-div' onclick='togglePlotAllOrSelect("+divNum+","+(divNum+1)+");'>more >></button>");
    }
}

function togglePlotAllOrSelect(divRemoveFirst, divRemoveLast) {
    for (var i=divRemoveFirst; i<divRemoveLast; i++) {
        removeSmallPlotDiv(i);
    }
    plotAllClinicalData = !plotAllClinicalData;
    resetSmallPlots();
}

function selectedCol(dt,col) {
    var c = dt.getColumnLabel(col);
    return c.toLowerCase().match(/(^age)|(gender)|(survival)|(grade)|(stage)|(histology)|(disease state)|(score)|(mutation_count)|(copy_number_altered_fraction)/);
}

// draw datatable
function drawDataTable(tableId,dt,caseMap) {
    // set headers
    var nCol = dt.getNumberOfColumns();
    var headers = [];
    var isColNum = [];
    for (var col=0; col<nCol; col++) {
        headers.push(getNiceHeader(dt.getColumnLabel(col)));
        isColNum.push(dt.getColumnType(col)==='number');
    }
    $('#'+tableId+' thead tr').html(""+headers.join("	")+"	");

    // format data
    var data = [];
    var nRow = dt.getNumberOfRows();
    for (var row=0; row<nRow; row++) {
        var dRow = [];
        for (var col=0; col<nCol; col++) {
            var val = dt.getValue(row,col);
            if (val && isColNum[col]) {
                val = cbio.util.toPrecision(val,3,0.01);
            }
            dRow.push(val);
        }
        data.push(dRow);
    }

    var oTable = $('#'+tableId).dataTable( {
        "sDom": '<"H"<"clinical-table-name">fr>t<"F"<"datatable-paging"pil>>',
        "bJQueryUI": true,
        "bDestroy": true,
        "aaData": data,
        "aoColumnDefs":[
            {// id
                "aTargets": [ 0 ],
                "mDataProp": function(source,type,value) {
                    if (type==='set') {
                        source[0]=value;
                    } else if (type==='display') {
                        return formatPatientLink(source[0]);
                    } else {
                        return source[0];
                    }
                }
            }
        ],
        "oLanguage": {
            "sInfo": "  (_START_ to _END_ of _TOTAL_)  ",
            "sLengthMenu": "Show _MENU_ per page"
        },
        "iDisplayLength": 25,
        "aLengthMenu": [[5,10, 25, 50, 100, -1], [5, 10, 25, 50, 100, "All"]]
    });

    oTable.css("width","100%");

    csObs.subscribe(tableId,function(caseId) {
        if (caseId==null) {
            oTable.fnFilter('', 0,true);
        } else if ((typeof caseId)==(typeof '')) {
            oTable.fnFilter("^"+caseId+"$",0,true);
        } else if ((typeof caseId)==(typeof {})) {
            var ids = [];
            for (var id in caseId) {
                ids.push(id);
            }
            oTable.fnFilter("(^"+ids.join("$)|(^")+"$)",0,true);
        }
    },true);

    $('#'+tableId+' tbody tr').live('click', function () {
        var nTds = $('td', this);
        var caseId = $(nTds[0]).text();
        csObs.fireSelection(caseId,tableId);
    } );
}

function getHeaderMap(dataTable) {
    var map = {};
    var cols = dataTable.getNumberOfColumns();
    for (var i=0; i<cols; i++) {
        map[dataTable.getColumnLabel(i)] = i;
    }
    return map;
}

function getCaseMap(dataTable) {
    var map = {};
    var rows = dataTable.getNumberOfRows();
    for (var i=0; i<rows; i++) {
        map[dataTable.getValue(i,0)] = i;
    }
    return map;
}

function makeContInxArray(start,end) {
    var ix = [];
    for (var i=start; i<=end; i++) {
        ix.push(i);
    }
    return ix;
}

function calcHistogram(dt,col,bins,caseIdsFilter) {
    var hist = [[dt.getColumnLabel(col),'# patients']];
    var caseIdHistMap = {};
    var histCaseIdMap = {};
    var rows = dt.getNumberOfRows();
    var t = dt.getColumnType(col);
    if (t=="number") {
        if (bins==null) bins = 10;
        if ((typeof bins)==(typeof 1)) {
            var r = dt.getColumnRange(col);
            var step = Math.pow(10,Math.floor(Math.log((r.max-r.min)/2)*Math.LOG10E));
            var start = step*Math.floor(r.min/step);
            bins = [];
            for (var bin=start; bin<=r.max; bin+=step) {
                bins.push(bin);
            }
        }

        var count = [];
        for (var i=0; i<=bins.length; i++) {
            count.push([]);
        }
        count.push([]); //unknown

        for (var r=0; r<rows; r++) {
            var caseId = dt.getValue(r,0);
            if (caseIdsFilter && !caseIdsFilter[caseId]) continue;
            var v = dt.getValue(r,col);
            var i;
            if (v==null) {
                i = bins.length+1;
            } else {
                for (i=0; i<bins.length; i++) {
                    if (bins[i]>=v) break;
                }
            }
            count[i].push(caseId);
            caseIdHistMap[caseId]=i;
        }

        hist.push(['<='+bins[0],count[0].length]);
        histCaseIdMap[0]=count[0];
        var i=1;
        for (; i<bins.length; i++) {
            hist.push([bins[i-1]+'~'+bins[i],count[i].length]);
            histCaseIdMap[i]=count[i];
        }
        hist.push(['>'+bins[bins.length-1],count[i].length]);
        histCaseIdMap[i]=count[i];
        if (count[++i].length>0) { // including unknow if positive
            hist.push(['Unknown',count[i].length]);
            histCaseIdMap[i]=count[i];
        }
    } else {
        var count = {};
        for (var r=0; r<rows; r++) {
            var caseId = dt.getValue(r,0);
            if (caseIdsFilter && !caseIdsFilter[caseId]) continue;
            var v = dt.getValue(r,col);
            if (v==null) v="Unknown";
            if(count[v]==null) count[v] = [];
            count[v].push(caseId);
        }
        var row=0;
        for (var key in count) {
            var c = count[key];
            hist.push([key,c.length]);
            histCaseIdMap[row]=c;
            for (var i=0; i<c.length; i++)
                caseIdHistMap[c[i]]=row;
            row++;
        }
    }
    return [hist,caseIdHistMap,histCaseIdMap];
}

function plotData(divNum,dt,col,caseIds) {
    var c = getNiceHeader(dt.getColumnLabel(col));
    var div = getSmallPlotDiv(divNum,c);
    var t = dt.getColumnType(col);
    var nCases = nrKeysAssociativeArrays(caseIds);
    var hist = calcHistogram(dt,col,getBins(dt,col),nCases>0?caseIds:null);
    var columnChart = t=='number';
    var chart = columnChart ?
        new google.visualization.ColumnChart(div) :
        new google.visualization.PieChart(div);
    google.visualization.events.addListener(chart, 'select', function(e){
        var s = chart.getSelection();
        var caseIds = {};
        var empty = true;
        for (var i=0; i<s.length; i++) {
            var ids = hist[2][s[i].row];
            for (var j=0; j<ids.length; j++) {
                caseIds[ids[j]] = true;
                empty = false;
            }
        }

        // if empty, update all plots including myself
        csObs.fireSelection(caseIds,empty?null:div.id);
    });
    google.visualization.events.addListener(chart, 'ready', function(e){
        csObs.subscribe(div.id,function(caseId,preCaseId) {
            if (caseId==null) {
                if (preCaseId==null) {
                    return;
                } else if ((typeof preCaseId)==(typeof '')) {
                    chart.setSelection();
                } else if ((typeof preCaseId)==(typeof {})) {
                    plotData(divNum,dt,col,caseId);
                }
            } else if ((typeof caseId)==(typeof '')) {
                var ix = hist[1][caseId];
                chart.setSelection(ix==null?null:[{'row': ix}]);
            } else if ((typeof caseId)==(typeof {})) {
                plotData(divNum,dt,col,caseId);
            }
        },(typeof caseIds)==='undefined');
    });
    var options = columnChart ?
        {
            hAxis: {title: dt.getColumnLabel(col)},
            vAxis: {title: '# of Patients'},
            legend: {position: 'none'}
        }
        :
        {'pieSliceText' : 'value'}
        ;
    chart.draw(google.visualization.arrayToDataTable(hist[0]),options);
    return chart;
}

function getBins(dt,col) {
    var c = dt.getColumnLabel(col);
    if (c=='age_at_diagnosis') {
        return [20,30,40,50,60,70,80];
    }
    if (c.match(/_months$/)) {
        return [12,24,36,48,60,72,84,96];
    }
    return null;
}

function getSmallPlotDiv(divNum,legend) {
    var div = document.getElementById('small-plot-div-'+divNum);
    if (div!=null) return div;

    var td = $('#small-plot-td-'+divNum);
    if (td.length==0) {
        var irow = Math.ceil(divNum/4);
        if (divNum%4==1) {
            $('#summary-plot-table').append('

');
            $('#small-plot-tr-'+irow).html('	');
        } else {
            $('#small-plot-tr-'+irow).append('	');
        }
        td = $('#small-plot-td-'+divNum);
    }

    var htm = '
'+'
';
    if (legend) {
        htm = '<fieldset><legend style="color:blue;font-weight:bold;">'+legend+'</legend>'
               + htm + '</fieldset>';
    }

    td.html(htm);
    return document.getElementById('small-plot-div-'+divNum);
}

function removeSmallPlotDiv(divNum) {
    $('#small-plot-td-'+divNum).html("");
}

function getNiceHeader(header) {
    var ret = header.replace(/_/g,' ');
    ret = ret.charAt(0).toUpperCase() + ret.slice(1);
    return ret;
}<|endoftext|>


<commit_before>//electron entry-point

const REACT_DEVELOPER_TOOLS = require('electron-devtools-installer').REACT_DEVELOPER_TOOLS;
var installExtension = require('electron-devtools-installer').default;
var app = require('electron').app;
var BrowserWindow = require('electron').BrowserWindow;
var path = require( "path" );

if (process.env.NODE_ENV === 'development') {
  require('electron-debug')(); // eslint-disable-line global-require
}

app.on('ready',function() {

installExtension(REACT_DEVELOPER_TOOLS)
  .then((name) => console.log(`Added Extension:  ${name}`))
  .catch((err) => console.log('An error occurred: ', err));

  var mainWindow = new BrowserWindow({
    width: 1200,
    height: 600
  });
  mainWindow.loadURL('file://' + __dirname + '/src/index-electron.html');

  mainWindow.webContents.on('did-finish-load', () => {
    mainWindow.show();
    mainWindow.focus();
  });

  mainWindow.on('closed', () => {
    mainWindow = null;
  });

  if (process.env.NODE_ENV === 'development') {
    mainWindow.openDevTools();
  }

});
<commit_msg>Load react-devtools in dev env only<commit_after>//electron entry-point
var app = require('electron').app;
var BrowserWindow = require('electron').BrowserWindow;
var path = require( "path" );

if (process.env.NODE_ENV === 'development') {
  require('electron-debug')(); // eslint-disable-line global-require
}

app.on('ready',function() {

if(process.env.NODE_ENV === 'development') {
  const REACT_DEVELOPER_TOOLS = require('electron-devtools-installer').REACT_DEVELOPER_TOOLS;
  var installExtension = require('electron-devtools-installer').default;
  installExtension(REACT_DEVELOPER_TOOLS)
  .then((name) => console.log(`Added Extension:  ${name}`))
  .catch((err) => console.log('An error occurred: ', err));
}

  var mainWindow = new BrowserWindow({
    width: 1200,
    height: 600
  });
  mainWindow.loadURL('file://' + __dirname + '/src/index-electron.html');

  mainWindow.webContents.on('did-finish-load', () => {
    mainWindow.show();
    mainWindow.focus();
  });

  mainWindow.on('closed', () => {
    mainWindow = null;
  });

  if (process.env.NODE_ENV === 'development') {
    mainWindow.openDevTools();
  }

});
<|endoftext|>


<commit_before>'use strict';

if(process.env.NEW_RELIC_APP_NAME) {
  require('newrelic');
}

// dependencies
var express = require('express')
  , app = express()
  , server = require('http').createServer(app)
  , ioServer = require('socket.io').listen(server)
  , path = require('path');
// valid api keys

var gridProperties = {
  dimensions: 32
};

// Get our modules
var ApiKeyHandler = require('./apikeyhandler')
  , clientValidator = require('./clientvalidator')
  , Grid = require('./grid');

var grid = new Grid(gridProperties.dimensions);

// core app logic
var port = process.env.PORT || 9001;
server.listen(port);

app.use(express.static(path.normalize(__dirname +  '/../dist/')));

app.get('/', function (req, res) {
  res.sendfile(path.normalize(__dirname +  '/../dist/index.html'));
});

// optimizations for production
if(process.env.NODE_ENV === 'production') {

  ioServer.enable('browser client minification');
  ioServer.enable('browser client etag');
  ioServer.enable('browser client gzip');
  ioServer.set('log level', 1);
  ioServer.set('transports', [
      'websocket'
    , 'htmlfile'
    , 'xhr-polling'
    , 'jsonp-polling'
    ]);

}
ioServer.set('log level', 1);

// describe client connection
ioServer.sockets.on('connection', function (socket) {
  ApiKeyHandler.newKey(socket, null, function (socket) { // DIRTY FIX ME
    console.log('api keys registered:\n' + ApiKeyHandler.ApiKeys.size());
    socket.emit('server ready', { gridArray: grid.gridMatrix });
    //Socket listener for user click
    socket.on('clicked', function (data) {
      console.log('***\n' + socket.id + ' clicked');
      if(clientValidator(data, gridProperties.dimensions)) {
        new ApiKeyHandler(socket, data.apiKey, function() {
          grid.updateGrid(socket, data);
        });
      } else {
        console.warn('warning: user provided invalid data: %s %s %s %s', data.row, data.col, data.color, data.apiKey);
      }
    });
    socket.on('disconnect', function() {
      ApiKeyHandler.delete(socket.id);
      console.log('api keys registered:\n' + ApiKeyHandler.ApiKeys.size());
    });
  });
});
<commit_msg>removed old socket.io 0.9 stuff<commit_after>'use strict';

if(process.env.NEW_RELIC_APP_NAME) {
  require('newrelic');
}

// dependencies
var express = require('express')
  , app = express()
  , server = require('http').createServer(app)
  , ioServer = require('socket.io').listen(server)
  , path = require('path');
// valid api keys

var gridProperties = {
  dimensions: 32
};

// Get our modules
var ApiKeyHandler = require('./apikeyhandler')
  , clientValidator = require('./clientvalidator')
  , Grid = require('./grid');

var grid = new Grid(gridProperties.dimensions);

// core app logic
var port = process.env.PORT || 9001;
server.listen(port);

app.use(express.static(path.normalize(__dirname +  '/../dist/')));

app.get('/', function (req, res) {
  res.sendfile(path.normalize(__dirname +  '/../dist/index.html'));
});

// describe client connection
ioServer.sockets.on('connection', function (socket) {
  ApiKeyHandler.newKey(socket, null, function (socket) { // DIRTY FIX ME
    console.log('api keys registered:\n' + ApiKeyHandler.ApiKeys.size());
    socket.emit('server ready', { gridArray: grid.gridMatrix });
    //Socket listener for user click
    socket.on('clicked', function (data) {
      console.log('***\n' + socket.id + ' clicked');
      if(clientValidator(data, gridProperties.dimensions)) {
        new ApiKeyHandler(socket, data.apiKey, function() {
          grid.updateGrid(socket, data);
        });
      } else {
        console.warn('warning: user provided invalid data: %s %s %s %s', data.row, data.col, data.color, data.apiKey);
      }
    });
    socket.on('disconnect', function() {
      ApiKeyHandler.delete(socket.id);
      console.log('api keys registered:\n' + ApiKeyHandler.ApiKeys.size());
    });
  });
});
<|endoftext|>


<commit_before>/*
 JSONCache version 0.0.1

 Author: Kimmo Puputti (kpuputti at gmail)

 See README.rst at https://github.com/kpuputti/JSONCache
 for requirements and usage.
*/
(function(i){var a={version:"0.0.1",debug:!0,prefix:"JSONCache",keySeparator:" "},e=function(){if(a.debug&&window.console){var b=Array.prototype.slice.call(arguments);b.unshift("JSONCache:");console.log.apply(console,b)}};a.browserOk=function(){var b=window.JSON&&typeof window.JSON.parse==="function"&&typeof window.JSON.stringify==="function",c;try{c="localStorage"in window&&window.localStorage!==null}catch(a){c=!1}return b&&c}();var d={};d.settings=a;d.getJSONProxy=function(b,a){i.getJSON(b,
a)};d.getCachedJSON=function(b,c){var f=c.success,g=a.prefix+a.keySeparator+"data"+a.keySeparator+b,h=window.localStorage[g];h?(e("Value found from cache for url:",b),f(JSON.parse(h))):(e("Value not found in cache fetching data from url:",b),d.getJSONProxy(b,function(a){e("Fetched data, adding to cache for url:",b);window.localStorage[g]=JSON.stringify(a);f(a)}))};window.JSONCache=d})(jQuery);
<commit_msg>Built new version.<commit_after>/*
 JSONCache version 0.0.1

 Author: Kimmo Puputti (kpuputti at gmail)

 See README.rst at https://github.com/kpuputti/JSONCache
 for requirements and usage.
*/
(function(i){var c={version:"0.0.1",debug:!0,prefix:"JSONCache",keySeparator:" "},e=function(){if(c.debug&&window.console){var b=Array.prototype.slice.call(arguments);b.unshift("JSONCache:");console.log.apply(console,b)}};c.browserOk=function(){var b=window.JSON&&typeof window.JSON.parse==="function"&&typeof window.JSON.stringify==="function",a;try{a="localStorage"in window&&window.localStorage!==null}catch(c){a=!1}return b&&a}();var d={};d.settings=c;d.getJSONProxy=function(b,a){i.ajax(b,a)};
d.getCachedJSON=function(b,a){var f=a.success,g=c.prefix+c.keySeparator+"data"+c.keySeparator+b,h=window.localStorage[g];h?(e("Value found from cache for url:",b),f(JSON.parse(h))):(e("Value not found in cache fetching data from url:",b),a.success=function(a){e("Fetched data, adding to cache for url:",b);window.localStorage[g]=JSON.stringify(a);f(a)},a.dataType="json",d.getJSONProxy(b,a))};window.JSONCache=d})(jQuery);
<|endoftext|>


<commit_before>/*
 * Idempotent migration script goes here.
 * Please try to avoid using migration script and instead make special treament in the code!
 */

// BRCD-576 (Deactivate / reactivate payment gateway)
db.subscribers.find({type: 'account', payment_gateway: {$exists: 1}, 'payment_gateway.active': {$exists: 0}}).forEach(
		function (obj) {
			var ele = {active: obj.payment_gateway};
			obj.payment_gateway = ele;
			db.subscribers.save(obj);
		}
);

// BRCD-594 (Override product price in plan / plan includes products - migration script)
//  run over rates
//  fill gropus dictionary
//  move override prices from rate to plan
var gruopD = {};
db.rates.find({'to': {$gt: new Date()}}).forEach(function (product) {
	var rates = product.rates;
	for (var type in rates) {
		for (var planKey in rates[type]) {
			if (planKey == "groups") {
				for (var gruop in rates[type][planKey]) {
					var groupName = rates[type][planKey][gruop];
					if (!gruopD.hasOwnProperty(groupName)) {
						gruopD[groupName] = [];
					}
					var alreadyExist = false;
					for (var i = 0; i < gruopD[groupName].length; i++) {
						if (gruopD[groupName][i] == product.key)
							alreadyExist = true;
					}
					if (!alreadyExist)
						gruopD[groupName].push(product.key);
				}
				delete rates[type][planKey];
			} else if (planKey != "BASE") {
				planDoc = db.plans.findOne({'name': planKey, 'to': {$gt: new Date()}});
				if (planDoc != null) {
					if (!planDoc.hasOwnProperty('rates')) {
						planDoc['rates'] = {};
					}
					if (!planDoc['rates'].hasOwnProperty(product.key)) {
						planDoc['rates'][product.key] = {};
					}
					planDoc['rates'][product.key][type] = rates[type][planKey];
				}
				db.plans.save(planDoc);
				delete rates[type][planKey];
			}
		}
	}
	product.rates = rates;
	db.rates.save(product);
});
//  run over plans
//  add rates array to each group
db.plans.find({'to': {$gt: new Date()}}).forEach(function (plan) {
	if (plan.hasOwnProperty("include")) {
		var groupsInPlan = plan.include.groups;
		for (var group in groupsInPlan) {
			if (gruopD.hasOwnProperty(group)) {
				groupsInPlan[group]["rates"] = gruopD[group];
			}
		}
		plan.include.groups = groupsInPlan;
		db.plans.save(plan);
	}
});
//  run over services
//  add rates array to each group
db.services.find({'to': {$gt: new Date()}}).forEach(function (service) {
	if (service.hasOwnProperty("include")) {
		var groupsInService = service.include.groups;
		for (var group in groupsInService) {
			if (gruopD.hasOwnProperty(group)) {
				groupsInService[group]["rates"] = gruopD[group];
			}
		}
		service.include.groups = groupsInService;
		db.services.save(service);
	}
});

// Add zip code account system field if it doesn't yet exist
var lastConfig = db.config.find().sort({_id: -1}).limit(1).pretty()[0];
delete lastConfig['_id'];
var found_zip_code = false;
lastConfig.subscribers.account.fields.forEach(function (field) {
	if (field.field_name == "zip_code") {
		found_zip_code = true;
		field.unique = false;
		field.generated = false;
		field.editable = true;
		field.mandatory = true;
		field.system = true;
		field.show_in_list = false;
		field.display = true;
	}
})
if (!found_zip_code) {
	lastConfig.subscribers.account.fields.push({
		"field_name": "zip_code",
		"title": "Zip code",
		"generated": false,
		"unique": false,
		"editable": true,
		"mandatory": true,
		"system": true,
		"show_in_list": false,
		"display": true
	});
}

var found_tax_field = false;
lastConfig.rates.fields.forEach(function (field) {
	if (field.field_name == "tax") {
		found_tax_field = true;
	}
})
if (!found_tax_field) {
	lastConfig.rates.fields.push({
		"field_name": "tax",
	});
}

db.config.insert(lastConfig);

// BRCD-614
var serviceDic = {}
db.subscribers.find({type: "subscriber", services: {$ne: [], $exists: 1}}).forEach(function (obj) {
	var services = [];
	for (var i in obj.services) {
		var srvname = obj.services[i].name ? obj.services[i].name : obj.services[i];
		var dicKey = srvname + obj.sid;
		if (!serviceDic[dicKey]) {
			serviceDic[dicKey] = {name: srvname, from: obj.from, to: obj.to};
		} else {
			if (obj.from < serviceDic[dicKey].from) {
				serviceDic[dicKey].from = obj.from;
			}
			if (obj.to > serviceDic[dicKey].to) {
				serviceDic[dicKey].to = obj.to;
			}
		}

	}
});
db.subscribers.find({type: "subscriber", services: {$ne: [], $exists: 1}}).forEach(function (obj) {
	var services = [];
	for (var i in obj.services) {
		var srvname = obj.services[i].name ? obj.services[i].name : obj.services[i];
		var dicKey = srvname + obj.sid;
		services.push({name: srvname, from: serviceDic[dicKey].from, to: serviceDic[dicKey].to});
	}
	obj.services = services;
	db.subscribers.save(obj);
});

db.balances.dropIndex('sid_1_from_1_to_1_priority_1');
db.balances.ensureIndex( { aid: 1, sid: 1, from: 1, to: 1, priority: 1 },{ unique: true, background: true });<commit_msg>BRCD-646: add migration script to move "pricing.tax" in config to "taxation.vat"<commit_after>/*
 * Idempotent migration script goes here.
 * Please try to avoid using migration script and instead make special treament in the code!
 */

// BRCD-576 (Deactivate / reactivate payment gateway)
db.subscribers.find({type: 'account', payment_gateway: {$exists: 1}, 'payment_gateway.active': {$exists: 0}}).forEach(
		function (obj) {
			var ele = {active: obj.payment_gateway};
			obj.payment_gateway = ele;
			db.subscribers.save(obj);
		}
);

// BRCD-594 (Override product price in plan / plan includes products - migration script)
//  run over rates
//  fill gropus dictionary
//  move override prices from rate to plan
var gruopD = {};
db.rates.find({'to': {$gt: new Date()}}).forEach(function (product) {
	var rates = product.rates;
	for (var type in rates) {
		for (var planKey in rates[type]) {
			if (planKey == "groups") {
				for (var gruop in rates[type][planKey]) {
					var groupName = rates[type][planKey][gruop];
					if (!gruopD.hasOwnProperty(groupName)) {
						gruopD[groupName] = [];
					}
					var alreadyExist = false;
					for (var i = 0; i < gruopD[groupName].length; i++) {
						if (gruopD[groupName][i] == product.key)
							alreadyExist = true;
					}
					if (!alreadyExist)
						gruopD[groupName].push(product.key);
				}
				delete rates[type][planKey];
			} else if (planKey != "BASE") {
				planDoc = db.plans.findOne({'name': planKey, 'to': {$gt: new Date()}});
				if (planDoc != null) {
					if (!planDoc.hasOwnProperty('rates')) {
						planDoc['rates'] = {};
					}
					if (!planDoc['rates'].hasOwnProperty(product.key)) {
						planDoc['rates'][product.key] = {};
					}
					planDoc['rates'][product.key][type] = rates[type][planKey];
				}
				db.plans.save(planDoc);
				delete rates[type][planKey];
			}
		}
	}
	product.rates = rates;
	db.rates.save(product);
});
//  run over plans
//  add rates array to each group
db.plans.find({'to': {$gt: new Date()}}).forEach(function (plan) {
	if (plan.hasOwnProperty("include")) {
		var groupsInPlan = plan.include.groups;
		for (var group in groupsInPlan) {
			if (gruopD.hasOwnProperty(group)) {
				groupsInPlan[group]["rates"] = gruopD[group];
			}
		}
		plan.include.groups = groupsInPlan;
		db.plans.save(plan);
	}
});
//  run over services
//  add rates array to each group
db.services.find({'to': {$gt: new Date()}}).forEach(function (service) {
	if (service.hasOwnProperty("include")) {
		var groupsInService = service.include.groups;
		for (var group in groupsInService) {
			if (gruopD.hasOwnProperty(group)) {
				groupsInService[group]["rates"] = gruopD[group];
			}
		}
		service.include.groups = groupsInService;
		db.services.save(service);
	}
});

// Add zip code account system field if it doesn't yet exist
var lastConfig = db.config.find().sort({_id: -1}).limit(1).pretty()[0];
delete lastConfig['_id'];
var found_zip_code = false;
lastConfig.subscribers.account.fields.forEach(function (field) {
	if (field.field_name == "zip_code") {
		found_zip_code = true;
		field.unique = false;
		field.generated = false;
		field.editable = true;
		field.mandatory = true;
		field.system = true;
		field.show_in_list = false;
		field.display = true;
	}
})
if (!found_zip_code) {
	lastConfig.subscribers.account.fields.push({
		"field_name": "zip_code",
		"title": "Zip code",
		"generated": false,
		"unique": false,
		"editable": true,
		"mandatory": true,
		"system": true,
		"show_in_list": false,
		"display": true
	});
}

var found_tax_field = false;
lastConfig.rates.fields.forEach(function (field) {
	if (field.field_name == "tax") {
		found_tax_field = true;
	}
})
if (!found_tax_field) {
	lastConfig.rates.fields.push({
		"field_name": "tax",
	});
}

db.config.insert(lastConfig);

// BRCD-614
var serviceDic = {}
db.subscribers.find({type: "subscriber", services: {$ne: [], $exists: 1}}).forEach(function (obj) {
	var services = [];
	for (var i in obj.services) {
		var srvname = obj.services[i].name ? obj.services[i].name : obj.services[i];
		var dicKey = srvname + obj.sid;
		if (!serviceDic[dicKey]) {
			serviceDic[dicKey] = {name: srvname, from: obj.from, to: obj.to};
		} else {
			if (obj.from < serviceDic[dicKey].from) {
				serviceDic[dicKey].from = obj.from;
			}
			if (obj.to > serviceDic[dicKey].to) {
				serviceDic[dicKey].to = obj.to;
			}
		}

	}
});
db.subscribers.find({type: "subscriber", services: {$ne: [], $exists: 1}}).forEach(function (obj) {
	var services = [];
	for (var i in obj.services) {
		var srvname = obj.services[i].name ? obj.services[i].name : obj.services[i];
		var dicKey = srvname + obj.sid;
		services.push({name: srvname, from: serviceDic[dicKey].from, to: serviceDic[dicKey].to});
	}
	obj.services = services;
	db.subscribers.save(obj);
});

db.balances.dropIndex('sid_1_from_1_to_1_priority_1');
db.balances.ensureIndex( { aid: 1, sid: 1, from: 1, to: 1, priority: 1 },{ unique: true, background: true });

// BRCD-646
var lastConfig = db.config.find().sort({_id: -1}).limit(1).pretty()[0];
delete lastConfig['_id'];
var pricingVat = lastConfig.pricing.vat;
delete lastConfig['pricing']['vat'];
lastConfig.taxation = {};
lastConfig.taxation.vat = pricingVat;
lastConfig.taxation.tax_type = "vat";
db.config.insert(lastConfig);
<|endoftext|>


<commit_before>var chalk = require('chalk');

module.exports = function (shipit) {
  require('shipit-deploy')(shipit)
  require('shipit-shared')(shipit);
  require('shipit-npm')(shipit);

  shipit.initConfig({
    default: {
      npm: {
        remote: true,
        triggerEvent: 'sharedEnd'
      },

      shared: {
        overwrite: true,
        dirs: [
          'node_modules',
          'log'
        ],
        files: [
          '.env',
          'tmp/foreverPidFile'
        ]
      },

      workspace: 'tmp/build',
      deployTo: '/home/budget-staging/Budget-Public-Staging',
      repositoryUrl: 'https://github.com/JumpStartGeorgia/Georgian-Budget-Public',
      ignores: [
        '.git',
        'node_modules',
        'shipitfile.js',
        'Dockerfile',
        'docker-compose.yml',
        'test'
      ],
      rsync: ['--del'],
      keepReleases: 5,
      shallowClone: true
    },
    staging: {
      servers: 'budget-staging@alpha.jumpstart.ge'
    },
    production: {
    }
  });

  shipit.on('npm_installed', function() {
    shipit.start('build')
  })

  shipit.blTask('build', function() {
    shipit.log('Running npm build to build project')
    return shipit.remote(
      `node -v && cd ${shipit.releasePath} && npm run build`
    ).then(function() {
      shipit.log(chalk.green('npm build complete'));
    }).catch(function(e) {
      shipit.log(chalk.red(e));
    })
  })

  shipit.on('published', function() {
    shipit.start('start_server')
  })

  shipit.blTask('start_server', function() {
    shipit.log('Starting node server')
    return shipit.remote(
      `node -v && cd /home/budget-staging/Budget-Public-Staging/current && pm2 startOrRestart config/pm2.json`
    )
  })
}
<commit_msg>Removed tmp/foreverPidFile from shared deploy files.<commit_after>var chalk = require('chalk');

module.exports = function (shipit) {
  require('shipit-deploy')(shipit)
  require('shipit-shared')(shipit);
  require('shipit-npm')(shipit);

  shipit.initConfig({
    default: {
      npm: {
        remote: true,
        triggerEvent: 'sharedEnd'
      },

      shared: {
        overwrite: true,
        dirs: [
          'node_modules',
          'log'
        ],
        files: [
          '.env'
        ]
      },

      workspace: 'tmp/build',
      deployTo: '/home/budget-staging/Budget-Public-Staging',
      repositoryUrl: 'https://github.com/JumpStartGeorgia/Georgian-Budget-Public',
      ignores: [
        '.git',
        'node_modules',
        'shipitfile.js',
        'Dockerfile',
        'docker-compose.yml',
        'test'
      ],
      rsync: ['--del'],
      keepReleases: 5,
      shallowClone: true
    },
    staging: {
      servers: 'budget-staging@alpha.jumpstart.ge'
    },
    production: {
    }
  });

  shipit.on('npm_installed', function() {
    shipit.start('build')
  })

  shipit.blTask('build', function() {
    shipit.log('Running npm build to build project')
    return shipit.remote(
      `node -v && cd ${shipit.releasePath} && npm run build`
    ).then(function() {
      shipit.log(chalk.green('npm build complete'));
    }).catch(function(e) {
      shipit.log(chalk.red(e));
    })
  })

  shipit.on('published', function() {
    shipit.start('start_server')
  })

  shipit.blTask('start_server', function() {
    shipit.log('Starting node server')
    return shipit.remote(
      `node -v && cd /home/budget-staging/Budget-Public-Staging/current && pm2 startOrRestart config/pm2.json`
    )
  })
}
<|endoftext|>