<commit_before>/**
 *
 * @author thea
 * @version $Id$
 */
Ext.namespace( 'Gemma' );

/**
 *
 * Displays a small number of elements from the set with links to the set's page and to an editor
 *
 * @class Gemma.ExperimentSetPreview
 * @xtype Gemma.ExperimentSetPreview
 */
Gemma.ExperimentSetPreview = Ext
   .extend(
      Gemma.SetPreview,
      {

         /**
          * update the contents of the experiment preview box
          *
          * @memberOf Gemma.ExperimentSetPreview
          * @private
          * @param {Number[]}
          *           ids an array of experimentIds to use to populate preview
          */
         _loadExperimentPreviewFromIds : function( ids ) {
            // this.entityIds = ids;
            // load some experiments to display
            var limit = (ids.length < this.preview_size) ? ids.length : this.preview_size;
            var previewIds = ids.slice( 0, limit );

            ExpressionExperimentController.loadExpressionExperiments( previewIds, {
               callback : function( ees ) {
                  this.loadPreview( ees, ids.length );
               }.createDelegate( this ),
               errorHandler : Gemma.genericErrorHandler
            } );
         },

         /**
          * @memberOf Gemma.ExperimentSetPreview
          */
         reset : function() {
            this.resetPreview();
            // this.entityIds = null;
            this.previewContent.setTitle( null );
            this.selectedSetValueObject = null;
         },

         /**
          * @public update the contents of the experiment preview box
          *
          * @param {ExperimentValueSetObject[]}
          *           experimentSet populate preview with members
          * @memberOf Gemma.ExperimentSetPreview
          */
         loadExperimentPreviewFromExperimentSet : function( eeSet ) {

            this.setSelectedSetValueObject( eeSet );
            var ids = eeSet.expressionExperimentIds;

            if ( ids.length > 0 ) {
               this._loadExperimentPreviewFromIds( ids );
            } else if ( eeSet.id > 0 ) {
               // fetch from server.
               ExpressionExperimentSetController.getExperimentsInSet.apply( this, [ eeSet.id, this.preview_size, {
                  callback : function( experiments ) {
                     this.loadPreview( experiments, this.selectedSetValueObject.size );
                     this.fireEvent( 'previewLoaded', experiments );
                  }.createDelegate( this ),
                  errorHandler : Gemma.genericErrorHandler
               } ] );
            } else {
               alert( "Could not load" );
            }

         },

         /**
          * @memberOf Gemma.ExperimentSetPreview
          * @param mode
          */
         setMode : function( mode ) {
            this.mode = mode;
            this.updateTitle();
         },

         hideUnanalyzedDatasets : false,

         /**
          * Whether we are in coexpression or differential expression mode
          */
         mode : 'coex',

         /**
          * public don't use params if you want to update name based on this.selectedEntityOrGroup
          *
          * @memberOf Gemma.ExperimentSetPreview
          * @param {Object}
          *           selectedSet
          *
          */
         updateTitle : function() {
            // debugger;
            var selectedSet = this.selectedSetValueObject;

            if ( typeof selectedSet == undefined || selectedSet == null ) {
               return;
            }

            // if an experiment group page exists for this set, make title a link

            // note that normally the ids are not filled in, so we just use the size.
            var size = selectedSet.size > 0 ? selectedSet.size : selectedSet.expressionExperimentIds.length;
            var numWithCoex = selectedSet.numWithCoexpressionAnalysis;
            var numWithDiffex = selectedSet.numWithDifferentialExpressionAnalysis;

            if ( !(selectedSet instanceof SessionBoundExpressionExperimentSetValueObject) ) {
               name = '' + selectedSet.name + '';
            } else {
               name = selectedSet.name;
            }

            var usableSize = 0;
            if ( this.mode == 'coex' ) {
               usableSize = numWithCoex > 0 ? numWithCoex : 0;
            } else {
               usableSize = numWithDiffex > 0 ? numWithDiffex : 0;
            }

            // Whether the data sets have coexpression and/or differential expression available
            this.previewContent.setTitle( '' + name
               + '
' + usableSize
               + (size > 1 ? " experiments" : " experiment ") + ' of ' + size + ' have '
               + (this.mode == 'coex' ? 'co' : 'diff. ') + 'expression available' );
            // + (this.hideUnanalyzedDatasets ? '
Unanalyzed experiments
            // hidden'
            // : '') ); // NOTE this refers to those lacking both Coex and Diff analyses. The notice might be confusing,
            // not
            // necessary?

         },

         /**
          * Given the current selection, when the user selects another result from the combo: we merge it in
          *
          * @private
          * @param combo
          * @param record
          * @param index
          * @returns
          */
         _addToPreviewedSet : function( combo, record, index ) {
            // FIXME see GeneSetPreview._addToPreviewedSet and harmonize.
            var rvo = record.get( 'resultValueObject' );

            if ( rvo instanceof SessionBoundExpressionExperimentSetValueObject ) {
               this._appendAndUpdate( combo, rvo );
            } else if ( rvo instanceof ExpressionExperimentValueObject ) {
               this._appendAndUpdate( combo, rvo );
            } else {
               // this shouldn't usually be happening? I mean, we should already have the ids.
               ExpressionExperimentSetController.getExperimentIdsInSet( rvo.id, {
                  callback : function( expIds ) {
                     rvo.expressionExperimentIds = expIds;
                     this._appendAndUpdate( combo, rvo );
                  }.createDelegate( this ),
                  errorHandler : Gemma.genericErrorHandler
               } );
            }

         },

         /**
          * @memberOf Gemma.ExperimentSetPreview
          * @param combo
          * @param valueObject
          * @private
          */
         _appendAndUpdate : function( combo, valueObject ) {
            var allIds = this.selectedSetValueObject.expressionExperimentIds;

            var newIds = [];
            if ( valueObject instanceof ExpressionExperimentValueObject ) {
               newIds.push( valueObject.id );
            } else {
               newIds = valueObject.expressionExperimentIds;
            }

            // don't add duplicates
            var added = false;
            for (var i = 0; i < newIds.length; i++) {
               if ( allIds.indexOf( newIds[i] ) < 0 ) {
                  allIds.push( newIds[i] );
                  added = true;
               }
            }

            if ( !added ) {
               this.fireEvent( 'doneModification' );
               return;
            }

            var editedGroup;

            if ( this.selectedSetValueObject instanceof SessionBoundExpressionExperimentSetValueObject ) {
               /*
                * Don't wipe it, just add on.
                */
               editedGroup = this.selectedSetValueObject;
               editedGroup.modified = true;
               editedGroup.expressionExperimentIds = allIds;
               editedGroup.size = editedGroup.expressionExperimentIds.length;

               ExpressionExperimentSetController.updateSessionGroups( [ editedGroup ], // returns
               // SessionBoundExpressionExperimentSetValueObject collection
               // added
               {
                  callback : function( eeSets ) {

                     this._loadExperimentPreviewFromIds( editedGroup.expressionExperimentIds ); // async
                     this.setSelectedSetValueObject( editedGroup );
                     this.updateTitle();
                     this.withinSetExperimentCombo.reset();
                     this.withinSetExperimentCombo.blur();

                     this.fireEvent( 'experimentListModified', editedGroup );
                     this.fireEvent( 'doneModification' );

                  }.createDelegate( this ),
                  errorHandler : Gemma.genericErrorHandler
               } );

            } else {
               // A group based on a database-bound group.
               editedGroup = new SessionBoundExpressionExperimentSetValueObject();
               editedGroup.id = null;

               var currentTime = new Date();
               var hours = currentTime.getHours();
               var minutes = currentTime.getMinutes();
               if ( minutes < 10 ) {
                  minutes = "0" + minutes;
               }
               var time = '(' + hours + ':' + minutes + ') ';

               editedGroup.name = time + " Custom Experiment Group";
               editedGroup.description = "Temporary experiment group created " + currentTime.toString();

               editedGroup.expressionExperimentIds = allIds;
               editedGroup.taxonId = record.get( 'taxonId' );
               editedGroup.taxonName = record.get( 'taxonName' );
               editedGroup.size = editedGroup.expressionExperimentIds.length;
               editedGroup.modified = true;
               editedGroup.isPublic = false;

               /*
                *
                */
               debugger;
               var oldnumCoex = this.selectedSetValueObject.numWithCoexpressionAnalysis;
               var oldnumDiffEx = this.selectedSetValueObject.numWithDifferentialExpressionAnalysis;

               editedGroup.numWithCoexpressionAnalysis = -1; // TODO
               editedGroup.numWithDifferentialExpressionAnalysis = -1; // TODO

               ExpressionExperimentSetController.addSessionGroup( editedGroup, true, {
                  callback : function( newValueObject ) {

                     this.setSelectedSetValueObject( newValueObject );
                     this.loadExperimentPreviewFromExperimentSet( newValueObject );

                     this.updateTitle();
                     this.withinSetExperimentCombo.reset();
                     this.withinSetExperimentCombo.blur();

                     this.fireEvent( 'experimentListModified', newValueObject );
                     this.fireEvent( 'doneModification' );

                  }.createDelegate( this ),
                  errorHandler : Gemma.genericErrorHandler
               } );
            }
         },

         /**
          * @Override
          * @memberOf Gemma.ExperimentSetPreview
          */
         initComponent : function() {

            this.withinSetExperimentCombo = new Gemma.ExperimentAndExperimentGroupCombo( {
               width : 300,
               style : 'margin:10px',
               hideTrigger : true,
               emptyText : 'Add experiments to your group'
            } );

            this.withinSetExperimentCombo.setTaxonId( this.taxonId );

            this.withinSetExperimentCombo.on( 'select', this._addToPreviewedSet, this );

            Ext
               .apply(
                  this,
                  {
                     selectionEditor : new Gemma.ExpressionExperimentMembersGrid( {
                        name : 'selectionEditor',
                        hideHeaders : true,
                        frame : false,
                        width : 500,
                        height : 500
                     } ),
                     /*
                      * I'm hiding experiments that have neither coexpression nor differential expression analysis.
                      */
                     defaultTpl : new Ext.XTemplate(
                        '<tpl for=".">'
                           + '<tpl if="!this.hideUnanalyzedDatasets || hasCoexpressionAnalysis || hasDifferentialExpressionAnalysis">'
                           + '
'
                           + '<a target="_blank" href="/Gemma/expressionExperiment/showExpressionExperiment.html?id=',
                        '{id}"',
                        ' ext:qtip="'
                           + '<tpl if="hasCoexpressionAnalysis">Has coexpression analysis&nbsp</tpl> '
                           + '<tpl if="hasDifferentialExpressionAnalysis">Has differential expression analysis</tpl>'
                           + '">{shortName}  {name} ({taxon}) '
                           + '<tpl if="hasCoexpressionAnalysis">C</tpl> <tpl if="hasDifferentialExpressionAnalysis">D</tpl>
</tpl></tpl>',
                        // FIXME bind the tooltip to the 'C D' not the experiment link
                        {
                           hideUnanalyzedDatasets : this.hideUnanalyzedDatasets
                        } ),

                     defaultPreviewTitle : "Experiment Selection Preview",

                     addingCombo : this.withinSetExperimentCombo

                  } );

            Gemma.ExperimentSetPreview.superclass.initComponent.call( this );

            this.selectionEditor.on( 'experimentListModified', function( newSet ) {
               if ( typeof newSet.expressionExperimentIds !== 'undefined' && typeof newSet.name !== 'undefined' ) {
                  this._loadExperimentPreviewFromIds( newSet.expressionExperimentIds );
                  this.setSelectedSetValueObject( newSet );
                  this.updateTitle();
               }
               this.fireEvent( 'experimentListModified', newSet );
            }, this );

         }

      } );

Ext.reg( 'Gemma.ExperimentSetPreview', Gemma.ExperimentSetPreview );<commit_msg>stray debugger<commit_after>/**
 *
 * @author thea
 * @version $Id$
 */
Ext.namespace( 'Gemma' );

/**
 *
 * Displays a small number of elements from the set with links to the set's page and to an editor
 *
 * @class Gemma.ExperimentSetPreview
 * @xtype Gemma.ExperimentSetPreview
 */
Gemma.ExperimentSetPreview = Ext
   .extend(
      Gemma.SetPreview,
      {

         /**
          * update the contents of the experiment preview box
          *
          * @memberOf Gemma.ExperimentSetPreview
          * @private
          * @param {Number[]}
          *           ids an array of experimentIds to use to populate preview
          */
         _loadExperimentPreviewFromIds : function( ids ) {
            // this.entityIds = ids;
            // load some experiments to display
            var limit = (ids.length < this.preview_size) ? ids.length : this.preview_size;
            var previewIds = ids.slice( 0, limit );

            ExpressionExperimentController.loadExpressionExperiments( previewIds, {
               callback : function( ees ) {
                  this.loadPreview( ees, ids.length );
               }.createDelegate( this ),
               errorHandler : Gemma.genericErrorHandler
            } );
         },

         /**
          * @memberOf Gemma.ExperimentSetPreview
          */
         reset : function() {
            this.resetPreview();
            // this.entityIds = null;
            this.previewContent.setTitle( null );
            this.selectedSetValueObject = null;
         },

         /**
          * @public update the contents of the experiment preview box
          *
          * @param {ExperimentValueSetObject[]}
          *           experimentSet populate preview with members
          * @memberOf Gemma.ExperimentSetPreview
          */
         loadExperimentPreviewFromExperimentSet : function( eeSet ) {

            this.setSelectedSetValueObject( eeSet );
            var ids = eeSet.expressionExperimentIds;

            if ( ids.length > 0 ) {
               this._loadExperimentPreviewFromIds( ids );
            } else if ( eeSet.id > 0 ) {
               // fetch from server.
               ExpressionExperimentSetController.getExperimentsInSet.apply( this, [ eeSet.id, this.preview_size, {
                  callback : function( experiments ) {
                     this.loadPreview( experiments, this.selectedSetValueObject.size );
                     this.fireEvent( 'previewLoaded', experiments );
                  }.createDelegate( this ),
                  errorHandler : Gemma.genericErrorHandler
               } ] );
            } else {
               alert( "Could not load" );
            }

         },

         /**
          * @memberOf Gemma.ExperimentSetPreview
          * @param mode
          */
         setMode : function( mode ) {
            this.mode = mode;
            this.updateTitle();
         },

         hideUnanalyzedDatasets : false,

         /**
          * Whether we are in coexpression or differential expression mode
          */
         mode : 'coex',

         /**
          * public don't use params if you want to update name based on this.selectedEntityOrGroup
          *
          * @memberOf Gemma.ExperimentSetPreview
          * @param {Object}
          *           selectedSet
          *
          */
         updateTitle : function() {
            // debugger;
            var selectedSet = this.selectedSetValueObject;

            if ( typeof selectedSet == undefined || selectedSet == null ) {
               return;
            }

            // if an experiment group page exists for this set, make title a link

            // note that normally the ids are not filled in, so we just use the size.
            var size = selectedSet.size > 0 ? selectedSet.size : selectedSet.expressionExperimentIds.length;
            var numWithCoex = selectedSet.numWithCoexpressionAnalysis;
            var numWithDiffex = selectedSet.numWithDifferentialExpressionAnalysis;

            if ( !(selectedSet instanceof SessionBoundExpressionExperimentSetValueObject) ) {
               name = '' + selectedSet.name + '';
            } else {
               name = selectedSet.name;
            }

            var usableSize = 0;
            if ( this.mode == 'coex' ) {
               usableSize = numWithCoex > 0 ? numWithCoex : 0;
            } else {
               usableSize = numWithDiffex > 0 ? numWithDiffex : 0;
            }

            // Whether the data sets have coexpression and/or differential expression available
            this.previewContent.setTitle( '' + name
               + '
' + usableSize
               + (size > 1 ? " experiments" : " experiment ") + ' of ' + size + ' have '
               + (this.mode == 'coex' ? 'co' : 'diff. ') + 'expression available' );
            // + (this.hideUnanalyzedDatasets ? '
Unanalyzed experiments
            // hidden'
            // : '') ); // NOTE this refers to those lacking both Coex and Diff analyses. The notice might be confusing,
            // not
            // necessary?

         },

         /**
          * Given the current selection, when the user selects another result from the combo: we merge it in
          *
          * @private
          * @param combo
          * @param record
          * @param index
          * @returns
          */
         _addToPreviewedSet : function( combo, record, index ) {
            // FIXME see GeneSetPreview._addToPreviewedSet and harmonize.
            var rvo = record.get( 'resultValueObject' );

            if ( rvo instanceof SessionBoundExpressionExperimentSetValueObject ) {
               this._appendAndUpdate( combo, rvo );
            } else if ( rvo instanceof ExpressionExperimentValueObject ) {
               this._appendAndUpdate( combo, rvo );
            } else {
               // this shouldn't usually be happening? I mean, we should already have the ids.
               ExpressionExperimentSetController.getExperimentIdsInSet( rvo.id, {
                  callback : function( expIds ) {
                     rvo.expressionExperimentIds = expIds;
                     this._appendAndUpdate( combo, rvo );
                  }.createDelegate( this ),
                  errorHandler : Gemma.genericErrorHandler
               } );
            }

         },

         /**
          * @memberOf Gemma.ExperimentSetPreview
          * @param combo
          * @param valueObject
          * @private
          */
         _appendAndUpdate : function( combo, valueObject ) {
            var allIds = this.selectedSetValueObject.expressionExperimentIds;

            var newIds = [];
            if ( valueObject instanceof ExpressionExperimentValueObject ) {
               newIds.push( valueObject.id );
            } else {
               newIds = valueObject.expressionExperimentIds;
            }

            // don't add duplicates
            var added = false;
            for (var i = 0; i < newIds.length; i++) {
               if ( allIds.indexOf( newIds[i] ) < 0 ) {
                  allIds.push( newIds[i] );
                  added = true;
               }
            }

            if ( !added ) {
               this.fireEvent( 'doneModification' );
               return;
            }

            var editedGroup;

            if ( this.selectedSetValueObject instanceof SessionBoundExpressionExperimentSetValueObject ) {
               /*
                * Don't wipe it, just add on.
                */
               editedGroup = this.selectedSetValueObject;
               editedGroup.modified = true;
               editedGroup.expressionExperimentIds = allIds;
               editedGroup.size = editedGroup.expressionExperimentIds.length;

               ExpressionExperimentSetController.updateSessionGroups( [ editedGroup ], // returns
               // SessionBoundExpressionExperimentSetValueObject collection
               // added
               {
                  callback : function( eeSets ) {

                     this._loadExperimentPreviewFromIds( editedGroup.expressionExperimentIds ); // async
                     this.setSelectedSetValueObject( editedGroup );
                     this.updateTitle();
                     this.withinSetExperimentCombo.reset();
                     this.withinSetExperimentCombo.blur();

                     this.fireEvent( 'experimentListModified', editedGroup );
                     this.fireEvent( 'doneModification' );

                  }.createDelegate( this ),
                  errorHandler : Gemma.genericErrorHandler
               } );

            } else {
               // A group based on a database-bound group.
               editedGroup = new SessionBoundExpressionExperimentSetValueObject();
               editedGroup.id = null;

               var currentTime = new Date();
               var hours = currentTime.getHours();
               var minutes = currentTime.getMinutes();
               if ( minutes < 10 ) {
                  minutes = "0" + minutes;
               }
               var time = '(' + hours + ':' + minutes + ') ';

               editedGroup.name = time + " Custom Experiment Group";
               editedGroup.description = "Temporary experiment group created " + currentTime.toString();

               editedGroup.expressionExperimentIds = allIds;
               editedGroup.taxonId = record.get( 'taxonId' );
               editedGroup.taxonName = record.get( 'taxonName' );
               editedGroup.size = editedGroup.expressionExperimentIds.length;
               editedGroup.modified = true;
               editedGroup.isPublic = false;

               /*
                *
                */
               // debugger;
               var oldnumCoex = this.selectedSetValueObject.numWithCoexpressionAnalysis;
               var oldnumDiffEx = this.selectedSetValueObject.numWithDifferentialExpressionAnalysis;

               editedGroup.numWithCoexpressionAnalysis = -1; // TODO
               editedGroup.numWithDifferentialExpressionAnalysis = -1; // TODO

               ExpressionExperimentSetController.addSessionGroup( editedGroup, true, {
                  callback : function( newValueObject ) {

                     this.setSelectedSetValueObject( newValueObject );
                     this.loadExperimentPreviewFromExperimentSet( newValueObject );

                     this.updateTitle();
                     this.withinSetExperimentCombo.reset();
                     this.withinSetExperimentCombo.blur();

                     this.fireEvent( 'experimentListModified', newValueObject );
                     this.fireEvent( 'doneModification' );

                  }.createDelegate( this ),
                  errorHandler : Gemma.genericErrorHandler
               } );
            }
         },

         /**
          * @Override
          * @memberOf Gemma.ExperimentSetPreview
          */
         initComponent : function() {

            this.withinSetExperimentCombo = new Gemma.ExperimentAndExperimentGroupCombo( {
               width : 300,
               style : 'margin:10px',
               hideTrigger : true,
               emptyText : 'Add experiments to your group'
            } );

            this.withinSetExperimentCombo.setTaxonId( this.taxonId );

            this.withinSetExperimentCombo.on( 'select', this._addToPreviewedSet, this );

            Ext
               .apply(
                  this,
                  {
                     selectionEditor : new Gemma.ExpressionExperimentMembersGrid( {
                        name : 'selectionEditor',
                        hideHeaders : true,
                        frame : false,
                        width : 500,
                        height : 500
                     } ),
                     /*
                      * I'm hiding experiments that have neither coexpression nor differential expression analysis.
                      */
                     defaultTpl : new Ext.XTemplate(
                        '<tpl for=".">'
                           + '<tpl if="!this.hideUnanalyzedDatasets || hasCoexpressionAnalysis || hasDifferentialExpressionAnalysis">'
                           + '
'
                           + '<a target="_blank" href="/Gemma/expressionExperiment/showExpressionExperiment.html?id=',
                        '{id}"',
                        ' ext:qtip="'
                           + '<tpl if="hasCoexpressionAnalysis">Has coexpression analysis&nbsp</tpl> '
                           + '<tpl if="hasDifferentialExpressionAnalysis">Has differential expression analysis</tpl>'
                           + '">{shortName}  {name} ({taxon}) '
                           + '<tpl if="hasCoexpressionAnalysis">C</tpl> <tpl if="hasDifferentialExpressionAnalysis">D</tpl>
</tpl></tpl>',
                        // FIXME bind the tooltip to the 'C D' not the experiment link
                        {
                           hideUnanalyzedDatasets : this.hideUnanalyzedDatasets
                        } ),

                     defaultPreviewTitle : "Experiment Selection Preview",

                     addingCombo : this.withinSetExperimentCombo

                  } );

            Gemma.ExperimentSetPreview.superclass.initComponent.call( this );

            this.selectionEditor.on( 'experimentListModified', function( newSet ) {
               if ( typeof newSet.expressionExperimentIds !== 'undefined' && typeof newSet.name !== 'undefined' ) {
                  this._loadExperimentPreviewFromIds( newSet.expressionExperimentIds );
                  this.setSelectedSetValueObject( newSet );
                  this.updateTitle();
               }
               this.fireEvent( 'experimentListModified', newSet );
            }, this );

         }

      } );

Ext.reg( 'Gemma.ExperimentSetPreview', Gemma.ExperimentSetPreview );<|endoftext|>


<commit_before>define([
    'bluebird',
    'jquery',
    'kbwidget',
    'kbaseAuthenticatedWidget',
    'narrativeConfig',
    'kb_service/utils',
    'kb_common/html',
    'kbase-client-api'
], function (
    Promise,
    $,
    KBWidget,
    kbaseAuthenticatedWidget,
    Config,
    ServiceUtils,
    html
) {
    'use strict';
    return KBWidget({
        name: 'kbaseDefaultObjectView',
        parent: kbaseAuthenticatedWidget,
        options: {
            upas: []
        },

        init: function(options) {
            this._super(options);
        },

        /**
         * Renders upas. With magic sauce.
         */
        render: function(upas) {
            var htmlProm = null;
            if (!this.token) {
                // some generic not-logged-in message
                htmlProm = this.renderMessage('Not logged in.');
            }
            else if (!upas) {
                // some generic placeholder
                htmlProm = this.renderMessage('No objects to display!');
            }
            else {
                htmlProm = this.fetchObjectInfo(upas)
                    .then((objectInfo) => {
                        let renderedObjects = objectInfo.infos.map((info) => {
                            return this.renderObjectInfo(ServiceUtils.objectInfoToObject(info));
                        });
                        return renderedObjects.join();
                    });
            }
            htmlProm.then((html) => {
                this.$elem.append(html);
            });
        },

        /**
         * Returns a div containing the message with a little formatting (margin, etc.).
         * if 'error', then it wraps in a Bootstrap error color element.
         */
        renderMessage: function(msg, isError) {
            return Promise.try(() => {
                return 'msg';
            });
        },

        /**
         * Fetches object info from a list of upas.
         */
        fetchObjectInfo: function(upas) {
            let ws = new Workspace(Config.url('workspace'), {token: this.token}),
                     objInfoInputs = upas.map((upa) => {
                        return {'ref': upa};
                     });
            return Promise.resolve(ws.get_object_info3({
                objects: objInfoInputs,
                includeMetadata: 1
            }));
        },

        /**
         * Takes in the result of a successful get_object_info3 call and renders the thing.
         */
        renderObjectInfo: function(objInfo) {
            let t = html.tag,
                div = t('div'),
                span = t('span'),
                b = t('b'),
                i = t('i'),
                a = t('a'),
                message = div({
                    class: 'alert alert-warning'
                }, [
                    'Objects of type ',
                    b(objInfo.typeModule + '.' + objInfo.typeName),
                    'don\'t have a view associated with them',
                    '
',
                    'High level object information is below.'
                ]),
                infoDiv = div({
                    style: {
                        marginTop: '5px',
                        padding: '5px'
                    }
                }, [
                    div([
                        b(objInfo.name),
                        ' - ',
                        span({
                            style: {
                                color: 'grey'
                            }
                        }, objInfo.ref),
                    ]),
                    div([
                        'Saved ',
                        objInfo.saveDate.toLocaleString(),
                        ' by ',
                        objInfo.saved_by
                    ]),
                    div('Approximately ' + objInfo.size.toLocaleString() + ' bytes'),
                    div({
                        style: {
                            marginLeft: '10px'
                        }
                    }, [
                        div([
                            a({
                                class: 'btn btn-xs btn-default',
                                href: '/#dataview/' + objInfo.ref,
                                target: '_lp'
                            }, [
                                span({
                                    class: 'fa fa-binoculars',
                                })
                            ]),
                            ' Explore data landing page'
                        ]),
                        div([
                            a({
                                class: 'btn btn-xs btn-default',
                                href: '/#objgraphview/' + objInfo.ref,
                                target: '_objgraph'
                            }, [
                                span({
                                    class: 'fa fa-sitemap fa-rotate-90'
                                })
                            ]),
                            ' View data provenance and relationships'
                        ])
                    ]),
                    div({
                        style: {
                            marginTop: '10px'
                        }
                    }, [
                        b('Type: ' + objInfo.typeModule + '.' + objInfo.typeName)
                    ]),
                    div({
                        style: {
                            marginLeft: '10px'
                        }
                    }, [
                        div([
                            a({
                                class: 'btn btn-xs btn-default',
                                href: '/#spec/module/' + objInfo.typeModule,
                                target: '_module'
                            }, [
                                span({
                                    class: 'fa fa-external-link-square'
                                })
                            ]),
                            ' View ',
                            i(objInfo.typeModule),
                            ' module info'
                        ]),
                        div([
                            a({
                                class: 'btn btn-xs btn-default',
                                href: '/#spec/type/' + objInfo.type,
                                target: '_typespec'
                            }, [
                                span({
                                    class: 'fa fa-external-link-square'
                                })
                            ]),
                            ' View ',
                            i(objInfo.typeModule),
                            '.',
                            i(objInfo.typeName),
                            ' type spec'
                        ])
                    ]),
                ]);

            return div([
                div(message),
                infoDiv
            ]);
        },

        loggedInCallback: function(event, auth) {
            this.token = auth.token;
            this.render(this.options.upas.upas);
            return this;
        },

        loggedOutCallback: function(event, auth) {
            this.token = null;
            this.render();
            return this;
        }
    });
});<commit_msg>add a missing space<commit_after>define([
    'bluebird',
    'jquery',
    'kbwidget',
    'kbaseAuthenticatedWidget',
    'narrativeConfig',
    'kb_service/utils',
    'kb_common/html',
    'kbase-client-api'
], function (
    Promise,
    $,
    KBWidget,
    kbaseAuthenticatedWidget,
    Config,
    ServiceUtils,
    html
) {
    'use strict';
    return KBWidget({
        name: 'kbaseDefaultObjectView',
        parent: kbaseAuthenticatedWidget,
        options: {
            upas: []
        },

        init: function(options) {
            this._super(options);
        },

        /**
         * Renders upas. With magic sauce.
         */
        render: function(upas) {
            var htmlProm = null;
            if (!this.token) {
                // some generic not-logged-in message
                htmlProm = this.renderMessage('Not logged in.');
            }
            else if (!upas) {
                // some generic placeholder
                htmlProm = this.renderMessage('No objects to display!');
            }
            else {
                htmlProm = this.fetchObjectInfo(upas)
                    .then((objectInfo) => {
                        let renderedObjects = objectInfo.infos.map((info) => {
                            return this.renderObjectInfo(ServiceUtils.objectInfoToObject(info));
                        });
                        return renderedObjects.join();
                    });
            }
            htmlProm.then((html) => {
                this.$elem.append(html);
            });
        },

        /**
         * Returns a div containing the message with a little formatting (margin, etc.).
         * if 'error', then it wraps in a Bootstrap error color element.
         */
        renderMessage: function(msg, isError) {
            return Promise.try(() => {
                return 'msg';
            });
        },

        /**
         * Fetches object info from a list of upas.
         */
        fetchObjectInfo: function(upas) {
            let ws = new Workspace(Config.url('workspace'), {token: this.token}),
                     objInfoInputs = upas.map((upa) => {
                        return {'ref': upa};
                     });
            return Promise.resolve(ws.get_object_info3({
                objects: objInfoInputs,
                includeMetadata: 1
            }));
        },

        /**
         * Takes in the result of a successful get_object_info3 call and renders the thing.
         */
        renderObjectInfo: function(objInfo) {
            let t = html.tag,
                div = t('div'),
                span = t('span'),
                b = t('b'),
                i = t('i'),
                a = t('a'),
                message = div({
                    class: 'alert alert-warning'
                }, [
                    'Objects of type ',
                    b(objInfo.typeModule + '.' + objInfo.typeName),
                    ' don\'t have a view associated with them',
                    '
',
                    'High level object information is below.'
                ]),
                infoDiv = div({
                    style: {
                        marginTop: '5px',
                        padding: '5px'
                    }
                }, [
                    div([
                        b(objInfo.name),
                        ' - ',
                        span({
                            style: {
                                color: 'grey'
                            }
                        }, objInfo.ref),
                    ]),
                    div([
                        'Saved ',
                        objInfo.saveDate.toLocaleString(),
                        ' by ',
                        objInfo.saved_by
                    ]),
                    div('Approximately ' + objInfo.size.toLocaleString() + ' bytes'),
                    div({
                        style: {
                            marginLeft: '10px'
                        }
                    }, [
                        div([
                            a({
                                class: 'btn btn-xs btn-default',
                                href: '/#dataview/' + objInfo.ref,
                                target: '_lp'
                            }, [
                                span({
                                    class: 'fa fa-binoculars',
                                })
                            ]),
                            ' Explore data landing page'
                        ]),
                        div([
                            a({
                                class: 'btn btn-xs btn-default',
                                href: '/#objgraphview/' + objInfo.ref,
                                target: '_objgraph'
                            }, [
                                span({
                                    class: 'fa fa-sitemap fa-rotate-90'
                                })
                            ]),
                            ' View data provenance and relationships'
                        ])
                    ]),
                    div({
                        style: {
                            marginTop: '10px'
                        }
                    }, [
                        b('Type: ' + objInfo.typeModule + '.' + objInfo.typeName)
                    ]),
                    div({
                        style: {
                            marginLeft: '10px'
                        }
                    }, [
                        div([
                            a({
                                class: 'btn btn-xs btn-default',
                                href: '/#spec/module/' + objInfo.typeModule,
                                target: '_module'
                            }, [
                                span({
                                    class: 'fa fa-external-link-square'
                                })
                            ]),
                            ' View ',
                            i(objInfo.typeModule),
                            ' module info'
                        ]),
                        div([
                            a({
                                class: 'btn btn-xs btn-default',
                                href: '/#spec/type/' + objInfo.type,
                                target: '_typespec'
                            }, [
                                span({
                                    class: 'fa fa-external-link-square'
                                })
                            ]),
                            ' View ',
                            i(objInfo.typeModule),
                            '.',
                            i(objInfo.typeName),
                            ' type spec'
                        ])
                    ]),
                ]);

            return div([
                div(message),
                infoDiv
            ]);
        },

        loggedInCallback: function(event, auth) {
            this.token = auth.token;
            this.render(this.options.upas.upas);
            return this;
        },

        loggedOutCallback: function(event, auth) {
            this.token = null;
            this.render();
            return this;
        }
    });
});<|endoftext|>


<commit_before>var $ = require('jquery');
var _ = require('underscore');
var Backbone = require('backbone');
var template = require('./slider.tpl');
require('jquery');
require('jquery-ui');

Backbone.Form.editors.Slider = Backbone.Form.editors.Base.extend({

  tagName: 'ul',
  className: 'CDB-OptionInput-container CDB-OptionInput-container--noMargin',

  options: {
    direction: '',
    labels: [0, 5, 10]
  },

  events: {
    focus: function () {
      this.trigger('focus', this);
    },
    blur: function () {
      this.trigger('blur', this);
    }
  },

  initialize: function (opts) {
    Backbone.Form.editors.Base.prototype.initialize.call(this, opts);

    this._setOptions(opts);

    if (!this.options.labels) {
      throw new Error('labels is required');
    }

    if (this.options.values && this.options.labels.length !== this.options.values.length) {
      throw new Error('values and labels should have the same length');
    }

    this._values = this.options.values;
    this._labels = this.options.labels;

    this._initViews();
  },

  _initViews: function () {
    this.$el.html(
      template({
        direction: this.options.direction,
        value: this.value
      })
    );

    var step = this._getStepPercentage();
    this._ticks = this._getTicks(step);

    this.$('.js-slider').slider({
      range: 'min',
      value: this._ticks[this.value],
      step: step,
      orientation: 'horizontal',
      disabled: this.options.disabled,
      slide: this._onSlideChange.bind(this),
      stop: this._onSlideStop.bind(this)
    });

    this._addTicks(step);
    this._updateUI(this.value);
  },

  _updateUI: function (value) {
    if (!value) {
      value = 0;
    }

    this._updateLabel(value);
    this._highlightTick(value);
  },

  _getTickIndex: function () {
    var v = 0;

    if (this.value) {
      v = +this.value.toFixed(2);
    }

    return this._ticks.indexOf(v);
  },

  _addTicks: function (step) {
    _.each(this._ticks, function (amount) {
      $('

')
        .css('left', amount + '%')
        .appendTo(this.$('.js-slider'));
    }, this);
  },

  _highlightTick: function (tickID) {
    this.$('.js-tick').removeClass('is-highlighted');
    $(this.$('.js-tick').get(tickID)).addClass('is-highlighted');
  },

  _updateLabel: function (tickID) {
    this.$('.js-label').text(this._labels[tickID]);
  },

  _getTicks: function (step) {
    return [0].concat(_(this._labels.length - 1).times(function (n) {
      return +(step * (n + 1)).toFixed(2);
    }));
  },

  _getStepPercentage: function () {
    return (100 / (this._labels.length - 1));
  },

  _onSlideChange: function (ev, ui) {
    this.value = ui.value;

    this._updateUI(this._getTickIndex());
  },

  _onSlideStop: function (ev, ui) {
    this.trigger('change', this);
  },

  _hasSlider: function () {
    return this.$('.js-slider').data('ui-slider');
  },

  getValue: function () {
    var value = this._values ? this._values[this._getTickIndex()] : this._getTickIndex();
    return (this.value === '') ? null : value;
  },

  setValue: function (value) {
    this.$('.js-slider').slider('value', value);
    this.value = value;
  },

  _destroySlider: function () {
    if (this._hasSlider()) {
      this.$('.js-slider').slider('destroy');
    }
  },

  remove: function () {
    this._destroySlider();
    Backbone.Form.editors.Base.prototype.remove.apply(this);
  },

  clean: function () {
    this.$el.remove();
  }
});
<commit_msg>Returns right initial value<commit_after>var $ = require('jquery');
var _ = require('underscore');
var Backbone = require('backbone');
var template = require('./slider.tpl');
require('jquery');
require('jquery-ui');

Backbone.Form.editors.Slider = Backbone.Form.editors.Base.extend({

  tagName: 'ul',
  className: 'CDB-OptionInput-container CDB-OptionInput-container--noMargin',

  options: {
    direction: '',
    labels: [0, 5, 10]
  },

  events: {
    focus: function () {
      this.trigger('focus', this);
    },
    blur: function () {
      this.trigger('blur', this);
    }
  },

  initialize: function (opts) {
    Backbone.Form.editors.Base.prototype.initialize.call(this, opts);

    this._setOptions(opts);

    if (!this.options.labels) {
      throw new Error('labels is required');
    }

    if (this.options.values && this.options.labels.length !== this.options.values.length) {
      throw new Error('values and labels should have the same length');
    }

    this._values = this.options.values;
    this._labels = this.options.labels;

    this._initViews();
  },

  _initViews: function () {
    this.$el.html(
      template({
        direction: this.options.direction,
        value: this.value
      })
    );

    var step = this._getStepPercentage();
    this._ticks = this._getTicks(step);

    this.$('.js-slider').slider({
      range: 'min',
      value: this._ticks[this.value],
      step: step,
      orientation: 'horizontal',
      disabled: this.options.disabled,
      slide: this._onSlideChange.bind(this),
      stop: this._onSlideStop.bind(this)
    });

    this._addTicks(step);
    this._updateUI(this._getInitialValue());
  },

  _getInitialValue: function () {
    var value = this.value;

    if (this._values) {
      value = this._values.indexOf(this.value);

      if (value === -1) {
        value = 0;
      }
    }
  },

  _updateUI: function (value) {
    if (!value) {
      value = 0;
    }

    this._updateLabel(value);
    this._highlightTick(value);
  },

  _getTickIndex: function () {
    var v = 0;

    if (this.value) {
      v = +this.value.toFixed(2);
    }

    return this._ticks.indexOf(v);
  },

  _addTicks: function (step) {
    _.each(this._ticks, function (amount) {
      $('

')
        .css('left', amount + '%')
        .appendTo(this.$('.js-slider'));
    }, this);
  },

  _highlightTick: function (tickID) {
    this.$('.js-tick').removeClass('is-highlighted');
    $(this.$('.js-tick').get(tickID)).addClass('is-highlighted');
  },

  _updateLabel: function (tickID) {
    this.$('.js-label').text(this._labels[tickID]);
  },

  _getTicks: function (step) {
    return [0].concat(_(this._labels.length - 1).times(function (n) {
      return +(step * (n + 1)).toFixed(2);
    }));
  },

  _getStepPercentage: function () {
    return (100 / (this._labels.length - 1));
  },

  _onSlideChange: function (ev, ui) {
    this.value = ui.value;

    this._updateUI(this._getTickIndex());
  },

  _onSlideStop: function (ev, ui) {
    this.trigger('change', this);
  },

  _hasSlider: function () {
    return this.$('.js-slider').data('ui-slider');
  },

  getValue: function () {
    var value = this._values ? this._values[this._getTickIndex()] : this._getTickIndex();
    return (this.value === '') ? null : value;
  },

  setValue: function (value) {
    this.$('.js-slider').slider('value', value);
    this.value = value;
  },

  _destroySlider: function () {
    if (this._hasSlider()) {
      this.$('.js-slider').slider('destroy');
    }
  },

  remove: function () {
    this._destroySlider();
    Backbone.Form.editors.Base.prototype.remove.apply(this);
  },

  clean: function () {
    this.$el.remove();
  }
});
<|endoftext|>


<commit_before>var $ = require('jquery');
var _ = require('underscore');
var cdb = require('cartodb.js');
var CoreView = require('backbone/core-view');
var defaultTemplate = require('./paginator-template.tpl');
var MINCATEGORIES = 5;

/**
 *  Display paginator for category widget
 *
 */

module.exports = CoreView.extend({
  options: {
    itemsPerPage: 6,
    template: defaultTemplate,
    paginator: false
  },

  className: 'CDB-Widget-nav CDB-Widget-contentSpaced',

  events: {
    'click .js-searchToggle': '_onSearchClicked',
    'click .js-next': '_onNextPage',
    'click .js-prev': '_onPrevPage'
  },

  initialize: function () {
    this.dataviewModel = this.options.dataviewModel;
    this.widgetModel = this.options.widgetModel;
    this._$target = this.options.$target;
    this.model = new cdb.core.Model({
      page: 1
    });
    this._initBinds();
  },

  render: function () {
    this.clearSubViews();
    this.$el.empty();
    var categoriesCount = this.dataviewModel.getCount();

    if (categoriesCount > MINCATEGORIES) {
      var template = this.options.template;

      this.$el.html(
        template({
          showPaginator: this.options.paginator,
          currentPage: this.model.get('page'),
          categoriesCount: categoriesCount,
          pages: this._totalPages()
        })
      );
    } else {
      this.model.set('page', 1);
    }
    this._scrollToPage();

    return this;
  },

  _initBinds: function () {
    $(window).bind('resize.' + this.cid, _.bind(this._scrollToPage, this));
    this.model.bind('change:page', this.render, this);
    this.dataviewModel.bind('change:categoriesCount', this.render, this);
    this.dataviewModel.bind('change:data change:searchData', function () {
      this._setPage();
      this.render();
    }, this);
    this.widgetModel.bind('change:search', this.toggle, this);
    this.add_related_model(this.dataviewModel);
    this.add_related_model(this.widgetModel);
  },

  // If current page doesn't exist due to a data change, we should reset it
  _setPage: function () {
    var pages = this._totalPages();

    if (this.model.get('page') > (pages - 1)) {
      this.model.set({ page: 1 }, { silent: true });
    }
  },

  _onSearchClicked: function () {
    this.widgetModel.setupSearch();
  },

  _scrollToPage: function () {
    var page = this.model.get('page');
    var pageWidth = this._$target.find('.CDB-Widget-listGroup').first().outerWidth();
    var currentPageIndex = page - 1;

    this._$target.css('margin-left', -(currentPageIndex * pageWidth));
  },

  _onPrevPage: function () {
    this._changePage(-1);
  },

  _onNextPage: function () {
    this._changePage(1);
  },

  _changePage: function (step) {
    var totalPages = this._totalPages();
    var currentPage = this.model.get('page');
    var nextPage = currentPage + step;

    if (nextPage > totalPages) {
      nextPage = 1;
    }

    if (nextPage < 1) {
      nextPage = totalPages;
    }

    this.model.set('page', nextPage);
  },

  _totalPages: function () {
    return Math.ceil(this.dataviewModel.getSize() / this.options.itemsPerPage);
  },

  toggle: function () {
    this[ this.widgetModel.isSearchEnabled() ? 'hide' : 'show' ]();
  },

  hide: function () {
    this.$el.addClass('is-hidden');
  },

  show: function () {
    this.$el.removeClass('is-hidden');
  },

  clean: function () {
    $(window).unbind('resize.' + this.cid);
    CoreView.prototype.clean.call(this);
  }
});
<commit_msg>Change _setPage logic<commit_after>var $ = require('jquery');
var _ = require('underscore');
var cdb = require('cartodb.js');
var CoreView = require('backbone/core-view');
var defaultTemplate = require('./paginator-template.tpl');
var MINCATEGORIES = 5;

/**
 *  Display paginator for category widget
 *
 */

module.exports = CoreView.extend({
  options: {
    itemsPerPage: 6,
    template: defaultTemplate,
    paginator: false
  },

  className: 'CDB-Widget-nav CDB-Widget-contentSpaced',

  events: {
    'click .js-searchToggle': '_onSearchClicked',
    'click .js-next': '_onNextPage',
    'click .js-prev': '_onPrevPage'
  },

  initialize: function () {
    this.dataviewModel = this.options.dataviewModel;
    this.widgetModel = this.options.widgetModel;
    this._$target = this.options.$target;
    this.model = new cdb.core.Model({
      page: 1
    });
    this._initBinds();
  },

  render: function () {
    this.clearSubViews();
    this.$el.empty();
    var categoriesCount = this.dataviewModel.getCount();

    if (categoriesCount > MINCATEGORIES) {
      var template = this.options.template;

      this.$el.html(
        template({
          showPaginator: this.options.paginator,
          currentPage: this.model.get('page'),
          categoriesCount: categoriesCount,
          pages: this._totalPages()
        })
      );
    } else {
      this.model.set('page', 1);
    }
    this._scrollToPage();

    return this;
  },

  _initBinds: function () {
    $(window).bind('resize.' + this.cid, _.bind(this._scrollToPage, this));
    this.model.bind('change:page', this.render, this);
    this.dataviewModel.bind('change:categoriesCount', this.render, this);
    this.dataviewModel.bind('change:data change:searchData', function () {
      this._setPage();
      this.render();
    }, this);
    this.widgetModel.bind('change:search', this.toggle, this);
    this.add_related_model(this.dataviewModel);
    this.add_related_model(this.widgetModel);
  },

  // If current page doesn't exist due to a data change, we should reset it
  _setPage: function () {
    var pages = this._totalPages();

    if (this.model.get('page') > pages || this.model.get('page') < 1) {
      this.model.set({ page: 1 }, { silent: true });
    }
  },

  _onSearchClicked: function () {
    this.widgetModel.setupSearch();
  },

  _scrollToPage: function () {
    var page = this.model.get('page');
    var pageWidth = this._$target.find('.CDB-Widget-listGroup').first().outerWidth();
    var currentPageIndex = page - 1;

    this._$target.css('margin-left', -(currentPageIndex * pageWidth));
  },

  _onPrevPage: function () {
    this._changePage(-1);
  },

  _onNextPage: function () {
    this._changePage(1);
  },

  _changePage: function (step) {
    var totalPages = this._totalPages();
    var currentPage = this.model.get('page');
    var nextPage = currentPage + step;

    if (nextPage > totalPages) {
      nextPage = 1;
    }

    if (nextPage < 1) {
      nextPage = totalPages;
    }

    this.model.set('page', nextPage);
  },

  _totalPages: function () {
    return Math.ceil(this.dataviewModel.getSize() / this.options.itemsPerPage);
  },

  toggle: function () {
    this[ this.widgetModel.isSearchEnabled() ? 'hide' : 'show' ]();
  },

  hide: function () {
    this.$el.addClass('is-hidden');
  },

  show: function () {
    this.$el.removeClass('is-hidden');
  },

  clean: function () {
    $(window).unbind('resize.' + this.cid);
    CoreView.prototype.clean.call(this);
  }
});
<|endoftext|>


<commit_before>// based on http://stackoverflow.com/a/13106698
jQuery.fn.highlight = function () {
    $(this).each(function () {
        var el = $(this);
        $("<div/>")
        .width(el.outerWidth())
        .height(el.outerHeight())
        .css({
            "position": "absolute",
            "left": el.offset().left,
            "top": el.offset().top,
            "background-color": "red",
            "opacity": ".7",
            "z-index": "9999999"
        }).appendTo('body').fadeOut(3000).queue(function () { $(this).remove(); });
    });
};
<commit_msg>bug with $ in highlight function<commit_after>(function($, window, document) {

  // based on http://stackoverflow.com/a/13106698
  $.fn.highlight = function() {
    $(this).each(function() {
      var el = $(this);
      $("<div/>").width(el.outerWidth()).height(el.outerHeight()).css({
        "position" : "absolute",
        "left" : el.offset().left,
        "top" : el.offset().top,
        "background-color" : "red",
        "opacity" : ".7",
        "z-index" : "9999999"
      }).appendTo('body').fadeOut(3000).queue(function() {
        $(this).remove();
      });
    });
  };

})(jQuery, window, document);<|endoftext|>


<commit_before><commit_msg>fabini v0 done<commit_after>import Plotly from 'plotly'; // plotly core only
import {Spinner} from 'spin.js';

var target = document.getElementById('spinner_graph');
var spinner_plot = new Spinner({scale: 0.5});
spinner_plot.spin(target);

var graph = document.getElementById('graph');
var layout = {
    grid: {rows: 1, columns: 2, xgap: 0.1, subplots:[['xy','x2y']]},
    margin: {l: 40, b: 40, t: 30, r: 0},
    showlegend: false, xaxis: {title: 'mᵉ [mₑ]'},
    xaxis2: {title: 'mʰ [mₑ]'}, yaxis: {title: 'SLME|1000nm [%]'},
}

var graph_columns = [['mᵉ', 'SLME|1000nm'], ['mʰ', 'SLME|1000nm']];
var markers = [
    {color: '#B087D6', size: 10, line: {width: 1, color: 'black'}},
    {color: '#538F71', size: 10, line: {width: 1, color: 'black'}},
]
var names = ['SLME vs mᵉ', 'SLME vs mʰ']
var api_url = window.api['host'] + 'projects/screening_inorganic_pv/graph';
var gets = $.map(graph_columns, function(columns) {
    return $.get({
        url: api_url, data: {'columns': columns.join(',')},
        headers: window.api['headers']
    });
})

$.when.apply($, gets).done(function() {
    var data = [];
    $.each(arguments, function(index, response) {
        var r = response[0];
        data.push({
            x: r[0]['y'], y: r[1]['y'], text: r[1]['text'],
            name: names[index], mode: 'markers', type: 'scatter',
            marker: markers[index], xaxis: 'x'+(index+1), yaxis: 'y'
        });
    });
    Plotly.plot(graph, data, layout, {displayModeBar: true});
    graph.on('plotly_click', function(d){
        var cid = d.points[0].text;
        var url = '/explorer/' + cid;
        window.open(url, '_blank');
    });
    spinner_plot.stop();
});
<|endoftext|>


<commit_before>/// <binding BeforeBuild='pre-build, strip-typescript-reference-paths' AfterBuild='build-typescript, post-build' />

require('babel-polyfill');

var babel = require('gulp-babel');
var bundler = require('aurelia-bundler');
var del = require('del');
var gulp = require('gulp');
var runSequence = require('run-sequence');
var sourcemaps = require('gulp-sourcemaps');
var strip = require('gulp-strip-comments');
var typescript = require('gulp-typescript');

var config = {
    force: true,
    baseURL: './wwwroot',
    configPath: './wwwroot/config.js',
    bundles: {
        'dist/app-build': {
            includes: [
                '*.js',
                '*.html!text',
                '*.css!text',
                'bootstrap/css/bootstrap.css!text'
            ],
            options: {
                inject: true,
                minify: true
            }
        },

        'dist/aurelia': {
            includes: [
                'aurelia-bootstrapper',
                'aurelia-event-aggregator',
                'aurelia-fetch-client',
                'aurelia-framework',
                'aurelia-history-browser',
                'aurelia-loader-default',
                'aurelia-logging-console',
                'aurelia-router',
                'aurelia-templating-binding',
                'aurelia-templating-resources',
                'aurelia-templating-router',
                'aurelia-http-client',
                'aurelia-polyfills'
            ],

            options: {
                'inject': true,
                'minify': true,
                'depCache': true
            }
        }
    }
};

gulp.task('copy-apps', function () {
    return gulp.src('../../Apps/**/Web/**/*').pipe(gulp.dest('wwwroot/dist/Apps/'));
});

gulp.task('copy-sitecommon', function () {
    gulp.src('../../SiteCommon/Web/**/*').pipe(gulp.dest('wwwroot/dist/SiteCommon/Web'));
});

gulp.task('copy-src', function () {
    return gulp.src('src/**/*').pipe(gulp.dest('wwwroot/dist/'));
});

gulp.task('clean-dist', function () {
    return del(['wwwroot/dist']);
});

gulp.task('pre-build', function (callback) {
    runSequence('clean-dist', ['copy-apps', 'copy-sitecommon', 'copy-src'], callback);
});

gulp.task('strip-typescript-reference-paths', function (callback) {
    gulp.src('wwwroot/dist/**/*.ts').pipe(strip.text({ trim: true })).pipe(gulp.dest('wwwroot/dist'));
});

gulp.task('build-typescript', function () {
    return gulp.src(['wwwroot/**/*.ts', 'typings/**.*'])
        //.pipe(sourcemaps.init({ loadMaps: true }))
        .pipe(typescript({
            alwaysStrict: true,
            emitDecoratorMetadata: true,
            experimentalDecorators: true,
            forceConsistentCasingInFileNames: true,
            noImplicitAny: true,
            noImplicitReturns: true,
            noImplicitThis: true,
            noUnusedLocals: true,
            noUnusedParameters: true,
            removeComments: true,
            //sourceMap: true,
            target: 'es6'
        }))
        .pipe(babel({
            plugins: ['transform-runtime'],
            presets: ['es2015']
        }))
        //.pipe(sourcemaps.write('.', {
        //    includeContent: false,
        //    sourceRoot: '/'
        //}))
        .pipe(gulp.dest('wwwroot/'));
});

gulp.task('post-build', function (callback) {
    return bundler.bundle(config);
    //return bundler.unbundle(config);
});<commit_msg>task runner clean<commit_after>/// <binding BeforeBuild='pre-build, strip-typescript-reference-paths' AfterBuild='build-typescript, post-build' Clean='clean-dist' />

require('babel-polyfill');

var babel = require('gulp-babel');
var bundler = require('aurelia-bundler');
var del = require('del');
var gulp = require('gulp');
var runSequence = require('run-sequence');
var sourcemaps = require('gulp-sourcemaps');
var strip = require('gulp-strip-comments');
var typescript = require('gulp-typescript');

var config = {
    force: true,
    baseURL: './wwwroot',
    configPath: './wwwroot/config.js',
    bundles: {
        'dist/app-build': {
            includes: [
                '*.js',
                '*.html!text',
                '*.css!text',
                'bootstrap/css/bootstrap.css!text'
            ],
            options: {
                inject: true,
                minify: true
            }
        },

        'dist/aurelia': {
            includes: [
                'aurelia-bootstrapper',
                'aurelia-event-aggregator',
                'aurelia-fetch-client',
                'aurelia-framework',
                'aurelia-history-browser',
                'aurelia-loader-default',
                'aurelia-logging-console',
                'aurelia-router',
                'aurelia-templating-binding',
                'aurelia-templating-resources',
                'aurelia-templating-router',
                'aurelia-http-client',
                'aurelia-polyfills'
            ],

            options: {
                'inject': true,
                'minify': true,
                'depCache': true
            }
        }
    }
};

gulp.task('copy-apps', function () {
    return gulp.src('../../Apps/**/Web/**/*').pipe(gulp.dest('wwwroot/dist/Apps/'));
});

gulp.task('copy-sitecommon', function () {
    gulp.src('../../SiteCommon/Web/**/*').pipe(gulp.dest('wwwroot/dist/SiteCommon/Web'));
});

gulp.task('copy-src', function () {
    return gulp.src('src/**/*').pipe(gulp.dest('wwwroot/dist/'));
});

gulp.task('clean-dist', function () {
    return del(['wwwroot/dist']);
});

gulp.task('pre-build', function (callback) {
    runSequence('clean-dist', ['copy-apps', 'copy-sitecommon', 'copy-src'], callback);
});

gulp.task('strip-typescript-reference-paths', function (callback) {
    gulp.src('wwwroot/dist/**/*.ts').pipe(strip.text({ trim: true })).pipe(gulp.dest('wwwroot/dist'));
});

gulp.task('build-typescript', function () {
    return gulp.src(['wwwroot/**/*.ts', 'typings/**.*'])
        //.pipe(sourcemaps.init({ loadMaps: true }))
        .pipe(typescript({
            alwaysStrict: true,
            emitDecoratorMetadata: true,
            experimentalDecorators: true,
            forceConsistentCasingInFileNames: true,
            noImplicitAny: true,
            noImplicitReturns: true,
            noImplicitThis: true,
            noUnusedLocals: true,
            noUnusedParameters: true,
            removeComments: true,
            //sourceMap: true,
            target: 'es6'
        }))
        .pipe(babel({
            plugins: ['transform-runtime'],
            presets: ['es2015']
        }))
        //.pipe(sourcemaps.write('.', {
        //    includeContent: false,
        //    sourceRoot: '/'
        //}))
        .pipe(gulp.dest('wwwroot/'));
});

gulp.task('post-build', function (callback) {
    return bundler.bundle(config);
    //return bundler.unbundle(config);
});<|endoftext|>


<commit_before>openerp.google_calendar = function(instance) {
    var _t = instance.web._t,
       _lt = instance.web._lt;
    var QWeb = instance.web.qweb;

    instance.web_calendar.CalendarView.include({
        view_loading: function(r) {
            var self = this;
            this.$el.on('click', 'div.oe_cal_sync_button', function() {
                self.sync_calendar(r);
            });
            return this._super(r);
        },
        sync_calendar: function(res, button) {
            var self = this;
            var context = instance.web.pyeval.eval('context');
            //$('div.oe_cal_sync_button').hide();
            $('div.oe_cal_sync_button').prop('disabled', true);

            self.rpc('/google_calendar/sync_data', {
                arch: res.arch,
                fields: res.fields,
                model: res.model,
                fromurl: window.location.href,
                local_context: context
            }).done(function(o) {
                if (o.status === "need_auth") {
                    alert(_t("You will be redirected on gmail to authorize your Odoo to access your calendar !"));
                    instance.web.redirect(o.url);
                }
                else if (o.status === "need_config_from_admin"){
                    if (!_.isUndefined(o.action) && parseInt(o.action)){
                        if (confirm(_t("An admin need to configure Google Synchronization before to use it, do you want to configure it now ? !"))){
                            self.do_action(o.action);
                        }
                    }
                    else{
                        alert(_t("An admin need to configure Google Synchronization before to use it !"));
                    }
                }
                else if (o.status === "need_refresh"){
                    self.$calendar.fullCalendar('refetchEvents');
                }
                else if (o.status === "need_reset"){
                    if (confirm(_t("The account that you are trying to synchronize (" + o.info.new_name + "), is not the same that the last one used \
(" + o.info.old_name + "! )" + "\r\n\r\nDo you want remove all references from the old account ?"))){

                        self.rpc('/google_calendar/remove_references', {
                            model:res.model,
                            local_context:context
                        }).done(function(o) {
                            if (o.status === "OK") {
                                alert(_t("All old references have been deleted. You can now restart the synchronization"));
                            }
                            else if (o.status === "KO") {
                                alert(_t("An error has occured when we was removing all old references. Please retry or contact your administrator."));
                            }
                            //else NOP
                        });
                    }
                }
            }).always(function(o) { $('div.oe_cal_sync_button').prop('disabled',false); });
        }
    });

    instance.web_calendar.CalendarView.include({
        extraSideBar: function() {
            this._super();
            if (this.dataset.model == "calendar.event") {
                this.$el.find('.oe_calendar_filter').prepend(QWeb.render('GoogleCalendar.buttonSynchro'));
            }
        }
    });

};
<commit_msg>[FIX] google_calendar: cleanup/spellcheck translatable terms<commit_after>openerp.google_calendar = function(instance) {
    var _t = instance.web._t,
       _lt = instance.web._lt;
    var QWeb = instance.web.qweb;

    instance.web_calendar.CalendarView.include({
        view_loading: function(r) {
            var self = this;
            this.$el.on('click', 'div.oe_cal_sync_button', function() {
                self.sync_calendar(r);
            });
            return this._super(r);
        },
        sync_calendar: function(res, button) {
            var self = this;
            var context = instance.web.pyeval.eval('context');
            //$('div.oe_cal_sync_button').hide();
            $('div.oe_cal_sync_button').prop('disabled', true);

            self.rpc('/google_calendar/sync_data', {
                arch: res.arch,
                fields: res.fields,
                model: res.model,
                fromurl: window.location.href,
                local_context: context
            }).done(function(o) {
                if (o.status === "need_auth") {
                    alert(_t("You will be redirected to Google to authorize access to your calendar!"));
                    instance.web.redirect(o.url);
                }
                else if (o.status === "need_config_from_admin"){
                    if (!_.isUndefined(o.action) && parseInt(o.action)){
                        if (confirm(_t("The Google Synchronization needs to be configured before you can use it, do you want to do it now?"))) {
                            self.do_action(o.action);
                        }
                    }
                    else{
                        alert(_t("An administrator needs to configure Google Synchronization before you can use it!"));
                    }
                }
                else if (o.status === "need_refresh"){
                    self.$calendar.fullCalendar('refetchEvents');
                }
                else if (o.status === "need_reset"){
                    var confirm_text1 = _t("The account you are trying to synchronize (%s) is not the same as the last one used (%s)!");
                    var confirm_text2 = _t("In order to do this, you first need to disconnect all existing events from the old account.");
                    var confirm_text3 = _t("Do you want to do this now?");
                    var text = _.str.sprintf(confirm_text1 + "\n" + confirm_text2 + "\n\n" + confirm_text3, o.info.new_name, o.info.old_name);
                    if (confirm(text)) {
                        self.rpc('/google_calendar/remove_references', {
                            model:res.model,
                            local_context:context
                        }).done(function(o) {
                            if (o.status === "OK") {
                                alert(_t("All events have been disconnected from your previous account. You can now restart the synchronization"));
                            }
                            else if (o.status === "KO") {
                                alert(_t("An error occured while disconnecting events from your previous account. Please retry or contact your administrator."));
                            }
                            //else NOP
                        });
                    }
                }
            }).always(function(o) { $('div.oe_cal_sync_button').prop('disabled',false); });
        }
    });

    instance.web_calendar.CalendarView.include({
        extraSideBar: function() {
            this._super();
            if (this.dataset.model == "calendar.event") {
                this.$el.find('.oe_calendar_filter').prepend(QWeb.render('GoogleCalendar.buttonSynchro'));
            }
        }
    });

};
<|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 App = require('app');
var db = require('utils/db');

/**
 * By Step 6, we have the following information stored in App.db and set on this
 * controller by the router:
 *
 *   hosts: App.db.hosts (list of all hosts the user selected in Step 3)
 *   selectedServiceNames: App.db.selectedServiceNames (the services that the user selected in Step 4)
 *   masterComponentHosts: App.db.masterComponentHosts (master-components-to-hosts mapping the user selected in Step 5)
 *
 * Step 6 will set the following information in App.db:
 *   slaveComponentHosts: App.db.slaveComponentHosts (slave-components-to-hosts mapping the user selected in Step 6)
 *
 */
App.WizardStep6Controller = Em.Controller.extend({

  hosts: [],

  headers: [],

  /**
   * true - assign ZK, HB
   * false - slaves and clients
   */
  isMasters: false,

  components:require('data/service_components'),

  isAddHostWizard: function(){
    return this.get('content.controllerName') === 'addHostController';
  }.property('content.controllerName'),

  clearError: function () {
    var self = this;
    var isError = false;
    var err = true;
    var hosts = this.get('hosts');
    var headers = this.get('headers');
    headers.forEach(function(header) {
      var all_false = true;
      hosts.forEach(function(host) {
        var checkboxes = host.get('checkboxes');
        all_false &= !checkboxes.findProperty('title', header.get('label')).checked;
      });
      err &= all_false;
    });

    if (!err) {
      this.set('errorMessage', '');
    }

    if(this.get('isAddHostWizard')) {
      if (this.get('isMasters')) {
        this.set('errorMessage', '');
      }
      else {
        hosts.forEach(function(host) {
          isError = false;
          headers.forEach(function(header) {
            isError |= host.get('checkboxes').findProperty('title', header.get('label')).checked;
          });
          isError = !isError;
          if (isError) {
            return;
          }
          else {
            self.set('errorMessage', '');
          }
        });
      }
    }
  },

  /**
   * Check whether current host is currently selected as master
   * @param hostName
   * @return {Boolean}
   */
  hasMasterComponents: function (hostName) {
    return this.get('content.masterComponentHosts').someProperty('hostName', hostName);
  },

  clearStep: function () {
    this.set('hosts', []);
    this.set('headers', []);
    this.clearError();
  },

  /**
   * Enable some service for all hosts
   * @param event
   */
  selectAllNodes: function(event) {
    this.setAllNodes(event.context.label, true);
  },

  /**
   * Disable some services for all hosts
   * @param event
   */
  deselectAllNodes: function(event) {
    this.setAllNodes(event.context.label, false);
  },

  /**
   * Enable/disable some service for all hosts
   * @param {String} label - service name
   * @param {Boolean} checked - true - enable, false - disable
   */
  setAllNodes: function(label, checked) {
    this.get('hosts').forEach(function(host) {
      host.get('checkboxes').forEach(function(checkbox) {
        if (checkbox.get('title') === label) {
          checkbox.set('checked', checked);
        }
      });
    });
  },

  /**
   * Return whether service was selected or not
   * @param name serviceName
   * @return {*}
   */
  isServiceSelected: function(name) {
    return this.get('content.services').findProperty('serviceName', name).get('isSelected');
  },

  /**
   * Checkbox check callback
   * @param {String} title
   */
  checkCallback: function(title) {

    var header = this.get('headers').findProperty('label', title);
    var hosts = this.get('hosts');
    var allTrue = true;
    var allFalse = true;
    hosts.forEach(function(host) {
      host.get('checkboxes').forEach(function(cb) {
        if (cb.get('title') === title) {
          allTrue &= cb.get('checked');
          allFalse &= !cb.get('checked');
        }
      });
    });
    header.set('allChecked', allTrue);
    header.set('noChecked', allFalse);
    this.clearError();
  },

  getComponentDisplayName: function(componentName) {
    return this.get('components').findProperty('component_name', componentName).display_name
  },

  loadStep: function () {

    var self = this;

    console.log("WizardStep6Controller: Loading step6: Assign Slaves");
    this.clearStep();

    var headers = [];

    if (this.get('isMasters')) {
      if (this.isServiceSelected('HBASE')) {
        headers.pushObject(Em.Object.create({
          name: 'HBASE_MASTER',
          label: self.getComponentDisplayName('HBASE_MASTER')
        }));
      }
      if (this.isServiceSelected('ZOOKEEPER')) {
        headers.pushObject(Em.Object.create({
         name:'ZOOKEEPER_SERVER',
         label: self.getComponentDisplayName('ZOOKEEPER_SERVER')
       }));
      }
    }
    else {
      headers.pushObject(Ember.Object.create({
        name: 'DATANODE',
        label: self.getComponentDisplayName('DATANODE')
      }));
      if (this.isServiceSelected('MAPREDUCE')) {
        headers.pushObject(Em.Object.create({
          name:'TASKTRACKER',
          label: self.getComponentDisplayName('TASKTRACKER')
        }));
      }
      if (this.isServiceSelected('HBASE')) {
        headers.pushObject(Em.Object.create({
          name:'HBASE_REGIONSERVER',
          label: self.getComponentDisplayName('HBASE_REGIONSERVER')
        }));
      }
      headers.pushObject(Ember.Object.create({
        name: 'CLIENT',
        label: self.getComponentDisplayName('CLIENT')
      }));
    }

    headers.forEach(function(header) {
      header.setProperties({ allChecked: false, noChecked: true });
    });

    this.get('headers').pushObjects(headers);

    this.render();
    if (this.get('isMasters')) {
      if(this.get('content.missMasterStep')) {
        App.router.send('next');
      }
    }
    else {
      if(this.get('content.missSlavesStep')) {
        App.router.send('next');
      }
    }
  },

  /**
   * Get active host names
   * @return {Array}
   */
  getHostNames: function () {
    var hostInfo = this.get('content.hosts');
    var hostNames = [];
    for (var index in hostInfo) {
      if (hostInfo[index].bootStatus === 'REGISTERED') {
        hostNames.push(hostInfo[index].name);
      }
    }
    return hostNames;
  },

  /**
   * Load all data needed for this module. Then it automatically renders in template
   * @return {Ember.Set}
   */
  render: function () {
    var hostsObj = Em.Set.create();
    var allHosts = this.getHostNames();

    var self = this;
    allHosts.forEach(function (_hostName) {

      var obj = Em.Object.create({
        hostName: _hostName,
        isMaster: false,
        checkboxes: []
      });

      self.get('headers').forEach(function(header) {
        obj.checkboxes.pushObject(Em.Object.create({
          title: header.label,
          checked: false,
          installed: false
        }));
      });

      hostsObj.push(obj);
    });

    if (this.get('isMasters')) {
      hostsObj = this.renderMasters(hostsObj);
    }
    else {
      hostsObj = this.renderSlaves(hostsObj);
    }

    hostsObj.forEach(function (host) {
      this.get('hosts').pushObject(host);
    }, this);
    this.get('headers').forEach(function(header) {
      self.checkCallback(header.get('label'));
    });
  },

  /**
   *
   * @param hostsObj
   * @return {*}
   */
  renderSlaves: function(hostsObj) {
    var allHosts = this.getHostNames();
    var slaveComponents = this.get('content.slaveComponentHosts');
    if (!slaveComponents) { // we are at this page for the first time
      hostsObj.forEach(function(host) {
        host.isMaster = this.hasMasterComponents(host.hostName);
      }, this);
    }
    else {
      this.get('headers').forEach(function(header) {
        var nodes = slaveComponents.findProperty('componentName', header.get('name'));
        if (nodes) {
          nodes.hosts.forEach(function (_node) {
            var node = hostsObj.findProperty('hostName', _node.hostName);
            if (node) {
              node.get('checkboxes').findProperty('title', header.get('label')).set('checked', true);
              node.get('checkboxes').findProperty('title', header.get('label')).set('installed', _node.isInstalled);
            }
          });
        }
      });
      allHosts.forEach(function (_hostname) {
        var host = hostsObj.findProperty('hostName', _hostname);
        if (host) {
          host.set('isMaster', this.hasMasterComponents(_hostname));
        }
      }, this);
    }
    return hostsObj;
  },

  /**
   *
   * @param hostsObj
   * @return {*}
   */
  renderMasters: function(hostsObj) {
    var self = this;
    var masterComponentHosts = this.get('content.masterComponentHosts');
    console.warn('masterComponentHosts', masterComponentHosts);

    if (masterComponentHosts) {
      masterComponentHosts.forEach(function(item) {
        var host = hostsObj.findProperty('hostName', item.hostName);
        if (host) {
          host.get('checkboxes').findProperty('title', item.display_name).set('checked', true);
        }
      });
    }

    return hostsObj;
  },

  /**
   * Return list of master components for specified hostname
   * @param hostName
   * @return {*}
   */
  getMasterComponentsForHost: function (hostName) {
    return this.get('content.masterComponentHosts').filterProperty('hostName', hostName).mapProperty('component');
  },

  /**
   * Validate form. Return do we have errors or not
   * @return {Boolean}
   */
  validate: function () {
    var isError = false;
    var hosts = this.get('hosts');
    var headers = this.get('headers');
    if(this.get('isAddHostWizard')) {
      for(var i = 0; i < hosts.length; i++) {
        var checkboxes = hosts[i].get('checkboxes');
        isError = false;
        headers.forEach(function(header) {
          isError |= checkboxes.findProperty('title', header.get('label')).checked;
        });
        isError = !isError;
        if (isError) {
          this.set('errorMessage', Em.I18n.t('installer.step6.error.mustSelectOneForHost'));
          break;
        }
      }
    }
    else {

      headers.forEach(function(header) {
        var all_false = true;
        hosts.forEach(function(host) {
          var checkboxes = host.get('checkboxes');
          all_false = all_false && !checkboxes.findProperty('title', header.get('label')).checked;
        });
        isError = isError || all_false;
      });
      if (isError) {
        this.set('errorMessage', Em.I18n.t('installer.step6.error.mustSelectOne'));
      }
    }

    return !isError;
  }

});
<commit_msg>AMBARI-1578. Add host wizard - support assignment of "ZooKeeper Server" and "HBase Master". (yusaku)<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 App = require('app');
var db = require('utils/db');

/**
 * By Step 6, we have the following information stored in App.db and set on this
 * controller by the router:
 *
 *   hosts: App.db.hosts (list of all hosts the user selected in Step 3)
 *   selectedServiceNames: App.db.selectedServiceNames (the services that the user selected in Step 4)
 *   masterComponentHosts: App.db.masterComponentHosts (master-components-to-hosts mapping the user selected in Step 5)
 *
 * Step 6 will set the following information in App.db:
 *   slaveComponentHosts: App.db.slaveComponentHosts (slave-components-to-hosts mapping the user selected in Step 6)
 *
 */
App.WizardStep6Controller = Em.Controller.extend({

  hosts: [],

  headers: [],

  /**
   * true - assign ZK, HB
   * false - slaves and clients
   */
  isMasters: false,

  components:require('data/service_components'),

  isAddHostWizard: function(){
    return this.get('content.controllerName') === 'addHostController';
  }.property('content.controllerName'),

  clearError: function () {
    var self = this;
    var isError = false;
    var err = true;
    var hosts = this.get('hosts');
    var headers = this.get('headers');
    headers.forEach(function(header) {
      var all_false = true;
      hosts.forEach(function(host) {
        var checkboxes = host.get('checkboxes');
        all_false &= !checkboxes.findProperty('title', header.get('label')).checked;
      });
      err &= all_false;
    });

    if (!err) {
      this.set('errorMessage', '');
    }

    if(this.get('isAddHostWizard')) {
      if (this.get('isMasters')) {
        this.set('errorMessage', '');
      }
      else {
        hosts.forEach(function(host) {
          isError = false;
          headers.forEach(function(header) {
            isError |= host.get('checkboxes').findProperty('title', header.get('label')).checked;
          });
          isError = !isError;
          if (isError) {
            return;
          }
          else {
            self.set('errorMessage', '');
          }
        });
      }
    }
  },

  /**
   * Check whether current host is currently selected as master
   * @param hostName
   * @return {Boolean}
   */
  hasMasterComponents: function (hostName) {
    return this.get('content.masterComponentHosts').someProperty('hostName', hostName);
  },

  clearStep: function () {
    this.set('hosts', []);
    this.set('headers', []);
    this.clearError();
  },

  /**
   * Enable some service for all hosts
   * @param event
   */
  selectAllNodes: function(event) {
    this.setAllNodes(event.context.label, true);
  },

  /**
   * Disable some services for all hosts
   * @param event
   */
  deselectAllNodes: function(event) {
    this.setAllNodes(event.context.label, false);
  },

  /**
   * Enable/disable some service for all hosts
   * @param {String} label - service name
   * @param {Boolean} checked - true - enable, false - disable
   */
  setAllNodes: function(label, checked) {
    this.get('hosts').forEach(function(host) {
      host.get('checkboxes').forEach(function(checkbox) {
        if (checkbox.get('title') === label) {
          checkbox.set('checked', checked);
        }
      });
    });
  },

  /**
   * Return whether service was selected or not
   * @param name serviceName
   * @return {*}
   */
  isServiceSelected: function(name) {
    return this.get('content.services').findProperty('serviceName', name).get('isSelected');
  },

  /**
   * Checkbox check callback
   * @param {String} title
   */
  checkCallback: function(title) {

    var header = this.get('headers').findProperty('label', title);
    var hosts = this.get('hosts');
    var allTrue = true;
    var allFalse = true;
    hosts.forEach(function(host) {
      host.get('checkboxes').forEach(function(cb) {
        if (cb.get('title') === title) {
          allTrue &= cb.get('checked');
          allFalse &= !cb.get('checked');
        }
      });
    });
    header.set('allChecked', allTrue);
    header.set('noChecked', allFalse);
    this.clearError();
  },

  getComponentDisplayName: function(componentName) {
    return this.get('components').findProperty('component_name', componentName).display_name
  },

  loadStep: function () {

    var self = this;

    console.log("WizardStep6Controller: Loading step6: Assign Slaves");
    this.clearStep();

    var headers = [];

    if (this.get('isMasters')) {
      if (this.isServiceSelected('HBASE')) {
        headers.pushObject(Em.Object.create({
          name: 'HBASE_MASTER',
          label: self.getComponentDisplayName('HBASE_MASTER')
        }));
      }
      if (this.isServiceSelected('ZOOKEEPER')) {
        headers.pushObject(Em.Object.create({
         name:'ZOOKEEPER_SERVER',
         label: self.getComponentDisplayName('ZOOKEEPER_SERVER')
       }));
      }
    }
    else {
      headers.pushObject(Ember.Object.create({
        name: 'DATANODE',
        label: self.getComponentDisplayName('DATANODE')
      }));
      if (this.isServiceSelected('MAPREDUCE')) {
        headers.pushObject(Em.Object.create({
          name:'TASKTRACKER',
          label: self.getComponentDisplayName('TASKTRACKER')
        }));
      }
      if (this.isServiceSelected('HBASE')) {
        headers.pushObject(Em.Object.create({
          name:'HBASE_REGIONSERVER',
          label: self.getComponentDisplayName('HBASE_REGIONSERVER')
        }));
      }
      headers.pushObject(Ember.Object.create({
        name: 'CLIENT',
        label: self.getComponentDisplayName('CLIENT')
      }));
    }

    headers.forEach(function(header) {
      header.setProperties({ allChecked: false, noChecked: true });
    });

    this.get('headers').pushObjects(headers);

    this.render();
    if (this.get('isMasters')) {
      if(this.get('content.missMasterStep')) {
        App.router.send('next');
      }
    }
    else {
      if(this.get('content.missSlavesStep')) {
        App.router.send('next');
      }
    }
  },

  /**
   * Get active host names
   * @return {Array}
   */
  getHostNames: function () {
    var hostInfo = this.get('content.hosts');
    var hostNames = [];
    for (var index in hostInfo) {
      if (hostInfo[index].bootStatus === 'REGISTERED') {
        hostNames.push(hostInfo[index].name);
      }
    }
    return hostNames;
  },

  /**
   * Load all data needed for this module. Then it automatically renders in template
   */
  render: function () {
    var hostsObj = Em.Set.create();
    var allHosts = this.getHostNames();

    var self = this;
    allHosts.forEach(function (_hostName) {

      var obj = Em.Object.create({
        hostName: _hostName,
        isMaster: false,
        checkboxes: []
      });

      self.get('headers').forEach(function(header) {
        obj.checkboxes.pushObject(Em.Object.create({
          title: header.label,
          checked: false,
          installed: false
        }));
      });

      hostsObj.push(obj);
    });

    if (this.get('isMasters')) {
      hostsObj = this.renderMasters(hostsObj);
    }
    else {
      hostsObj = this.renderSlaves(hostsObj);
    }

    hostsObj.forEach(function (host) {
      this.get('hosts').pushObject(host);
    }, this);
    this.get('headers').forEach(function(header) {
      self.checkCallback(header.get('label'));
    });
  },

  /**
   *
   * @param hostsObj
   * @return {*}
   */
  renderSlaves: function(hostsObj) {
    var self = this;
    var allHosts = this.getHostNames();
    var headers = this.get('headers');
    var slaveComponents = this.get('content.slaveComponentHosts');
    if (!slaveComponents) { // we are at this page for the first time
      var client_is_set = false;
      hostsObj.forEach(function(host) {
        host.isMaster = self.hasMasterComponents(host.hostName);
        var checkboxes = host.get('checkboxes');
        checkboxes.setEach('checked', !host.isMaster);
        checkboxes.findProperty('title', headers.findProperty('name', 'CLIENT').get('label')).set('checked', false);
        // First not Master should have Client (only first!)
        if (!client_is_set) {
          var checkboxDatanode = checkboxes.findProperty('title', headers.findProperty('name', 'DATANODE').get('label'));
          if (checkboxDatanode && checkboxDatanode.get('checked')) {
            checkboxes.findProperty('title', headers.findProperty('name', 'CLIENT').get('label')).set('checked', true);
            client_is_set = true;
          }
        }
      });
    }
    else {
      this.get('headers').forEach(function(header) {
        var nodes = slaveComponents.findProperty('componentName', header.get('name'));
        if (nodes) {
          nodes.hosts.forEach(function (_node) {
            var node = hostsObj.findProperty('hostName', _node.hostName);
            if (node) {
              node.get('checkboxes').findProperty('title', header.get('label')).set('checked', true);
              node.get('checkboxes').findProperty('title', header.get('label')).set('installed', _node.isInstalled);
            }
          });
        }
      });
      allHosts.forEach(function (_hostname) {
        var host = hostsObj.findProperty('hostName', _hostname);
        if (host) {
          host.set('isMaster', this.hasMasterComponents(_hostname));
        }
      }, this);
    }
    return hostsObj;
  },

  /**
   *
   * @param hostsObj
   * @return {*}
   */
  renderMasters: function(hostsObj) {
    var self = this;
    var masterComponentHosts = this.get('content.masterComponentHosts');
    console.warn('masterComponentHosts', masterComponentHosts);

    if (masterComponentHosts) {
      masterComponentHosts.forEach(function(item) {
        var host = hostsObj.findProperty('hostName', item.hostName);
        if (host) {
          host.get('checkboxes').findProperty('title', item.display_name).set('checked', true);
        }
      });
    }

    return hostsObj;
  },

  /**
   * Return list of master components for specified hostname
   * @param hostName
   * @return {*}
   */
  getMasterComponentsForHost: function (hostName) {
    return this.get('content.masterComponentHosts').filterProperty('hostName', hostName).mapProperty('component');
  },

  /**
   * Validate form. Return do we have errors or not
   * @return {Boolean}
   */
  validate: function () {
    var isError = false;
    var hosts = this.get('hosts');
    var headers = this.get('headers');
    if(this.get('isAddHostWizard')) {
      for(var i = 0; i < hosts.length; i++) {
        var checkboxes = hosts[i].get('checkboxes');
        isError = false;
        headers.forEach(function(header) {
          isError |= checkboxes.findProperty('title', header.get('label')).checked;
        });
        isError = !isError;
        if (isError) {
          this.set('errorMessage', Em.I18n.t('installer.step6.error.mustSelectOneForHost'));
          break;
        }
      }
    }
    else {

      headers.forEach(function(header) {
        var all_false = true;
        hosts.forEach(function(host) {
          var checkboxes = host.get('checkboxes');
          all_false = all_false && !checkboxes.findProperty('title', header.get('label')).checked;
        });
        isError = isError || all_false;
      });
      if (isError) {
        this.set('errorMessage', Em.I18n.t('installer.step6.error.mustSelectOne'));
      }
    }

    return !isError;
  }

});
<|endoftext|>