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

    angular.module('chaise.configure-viewer', ['chaise.config'])

    .constant('appName', 'viewer')

    .run(['$rootScope', function ($rootScope) {
        // When the configuration module's run block emits the `configuration-done` event, attach the app to the DOM
        $rootScope.$on("configuration-done", function () {

            angular.element(document).ready(function(){
                angular.bootstrap(document.getElementById("viewer"), ["chaise.viewer"]);
            });
        });
    }]);

    var client;

    angular.module('chaise.viewer', [
        'ermrestjs',
        'ngSanitize',
        'chaise.alerts',
        'chaise.filters',
        'ngCookies',
        'chaise.authen',
        'chaise.errors',
        'chaise.delete',
        'chaise.modal',
        'chaise.navbar',
        'chaise.utils',
        'ui.select',
        'ui.bootstrap',
        'ng.deviceDetector'
    ])

    .config(['$provide', function($provide) {
        $provide.decorator('$templateRequest', ['ConfigUtils', 'UriUtils', '$delegate', function (ConfigUtils, UriUtils, $delegate) {
            return ConfigUtils.decorateTemplateRequest($delegate, UriUtils.chaiseDeploymentPath());
        }]);
    }])

    // Configure the context info from the URI
    .config(['context', 'UriUtilsProvider', function configureContext(context, UriUtilsProvider) {
        var utils = UriUtilsProvider.$get();

        // Parse the URL
        utils.setOrigin();
        utils.parseURLFragment(window.location, context);

        // should we allow for improper URLs here?
        // what if there are 2 filters and the id filter is the second one.
        // Is that improper or should it be parsed and ignore the other filter?
        var filter = context.filter.filters[0];
        if (filter.type === "BinaryPredicate" &&
            filter.operator === "=" &&
            filter.column.toLowerCase() === "id") {
            context.imageID = filter.value;
        }

        console.log('Context', context);
        // TODO: Check if context has everything it needs before proceeding. If not, Bad Request
    }])

    // set the chasie-config property
    .config(['headInjectorProvider', function (headInjectorProvider) {

        headInjectorProvider.$get().setupHead();
    }])

    // Configure all tooltips to be attached to the body by default. To attach a
    // tooltip on the element instead, set the `tooltip-append-to-body` attribute
    // to `false` on the element.
    .config(['$uibTooltipProvider', function($uibTooltipProvider) {
        $uibTooltipProvider.options({appendToBody: true});
    }])

    .config(['userProvider', 'context', 'SessionProvider', 'ConfigUtilsProvider', function configureUser(userProvider, context, SessionProvider, ConfigUtilsProvider) {
        var chaiseConfig = ConfigUtilsProvider.$get().getConfigJSON();
        SessionProvider.$get().getSession().then(function success(session) {
            // there's no active session
            if (!session) return;

            var groups = chaiseConfig.userGroups || context.groups;
            // session.attributes is an array of objects that have a display_name and id
            // We MUST use the id field to check for role inclusion as it is the unique identifier
            var attributes = session.attributes.map(function(attribute) { return attribute.id });
            var user = userProvider.$get();
            user.session = session;

// TODO Let's try to extract this setup to unclutter *.app.js
            // Need to check if using the new web authen
            // if so, there will be a client object with a combination of any or all of the following: display_name, full_name, and email
            // first priority id display_name
            if (session.client.display_name) {
                user.name = session.client.display_name;
            // full_name is second priority
            } else if (session.client.full_name) {
                user.name = session.client.full_name;
            // fallback if no display_name or full_name
            } else if (session.client.email) {
                user.name = session.client.email;
            // Case for old web authen where client is a string
            } else {
                user.name = session.client
            }

            if (attributes.indexOf(groups.curators) > -1) {
                user.role = 'curator';
            } else if (attributes.indexOf(groups.annotators) > -1) {
                user.role = 'annotator';
            } else if (attributes.indexOf(groups.users) > -1) {
                user.role = 'user';
            } else {
                user.role = null;
            }

            console.log('User: ', user);
            return;
        }, function error(response) {
            throw response;
        });
    }])

    // Hydrate values providers and set up iframe
    .run(['ConfigUtils', 'ERMrest', 'logActions', '$window', 'context', 'image', 'annotations', 'comments', 'anatomies', 'user', 'MathUtils', function runApp(ConfigUtils, ERMrest, logActions, $window, context, image, annotations, comments, anatomies, user, MathUtils) {
        var origin = $window.location.origin;
        var iframe = $window.frames[0];
        var annotoriousReady = false;
        var chaiseReady = false;
        var arrows = [];
        var rectangles = [];
        var sections = [];

        ConfigUtils.getContextJSON().server.catalogs.get(context.catalogID).then(function success(catalog) {
            var schema = catalog.schemas.get(context.schemaName);
            // So the schema and tables can be accessed in controllers
            context.schema = schema;
            console.log('Schema: ', schema);
            if (schema) {
                var table = schema.tables.get(context.tableName);
                // BinaryPredicate(column, operator, value) is used for building a filter
                // This predicate is used to get the image based on the id of the image the user is navigating to
                var imagePath = new ERMrest.DataPath(table);
                var imagePathColumn = imagePath.context.columns.get('id');
                var imageFilter = new ERMrest.BinaryPredicate(imagePathColumn, ERMrest.OPERATOR.EQUAL, context.imageID);

                var contextHeaderParams = {
                    catalog: context.catalogID,
                    schema_table: context.schemaName + ":" + context.tableName,
                    filter: "id=" + context.imageID,
                    action: logActions.viewerMain
                };

                if (context.queryParams && context.queryParams.ppid) {
                    contextHeaderParams.ppid = context.queryParams.ppid;
                }

                if (context.queryParams && context.queryParams.pcid) {
                    contextHeaderParams.pcid = context.queryParams.pcid;
                }
                imagePath.filter(imageFilter).entity.get(contextHeaderParams).then(function success(entity) {
                    image.entity = entity[0];
                    var waterMark = context.queryParams.waterMark;
                    if (waterMark === undefined) {
                    	waterMark = '';
                    } else {
                    	waterMark = '&waterMark=' + waterMark;
                    }
                    console.log('uri='+image.entity.uri + waterMark);
                    // Test scene 3
                    var params = window.location.href.split("?");
                    if(params.length > 1){
                        /* HACK: Remove the hardcoded the url for openseadragon-viewer as currently it is being served from demo/chaise-osd. It should be
                          changed to /openseadragon-viewer which should be in the same directory as chaise. Reason for this: Currently the master of openseadragon-viewer
                          is not upto date with the branch svg-on-tif.
                        */
                        console.log("Origin", origin);
                        image.entity.uri = origin+"/~vipul/openseadragon-viewer/index.html?" + params[1];
                        // image.entity.uri = origin+"/demo/chaise-osd/openseadragon-viewer/index.html?" + params[1];
                    }

                    // image.entity.uri = image.entity.uri + "&url=data/Q-296R_all_contours_cw_named.svg";
                    console.log('replace uri = '+image.entity.uri + waterMark)
                    iframe.location.replace(image.entity.uri + waterMark);
                    console.log('Image: ', image);

                    var annotationTable = schema.tables.get('annotation');
                    var annotationPath = imagePath.extend(annotationTable).datapath;
                    var contextHeaderParams = {
                        catalog: context.catalogID,
                        schema_table: context.schemaName + ":annotation",
                        filter: "id=" + context.imageID,
                        action: logActions.viewerAnnotation
                    };
                    annotationPath.filter(imageFilter).entity.get(contextHeaderParams).then(function success(_annotations) {
                        var length = _annotations.length;
                        for (var i = 0; i < length; i++) {
                            _annotations[i].table = annotationPath.context.table.name;
                            var annotation = _annotations[i];
                            if (!annotation.config) {
                                annotation.config = {};
                            }
                            annotations.push(annotation);
                        }
                        chaiseReady = true;

                        if (annotoriousReady && chaiseReady) {
                            iframe.postMessage({messageType: 'loadAnnotations', content: annotations}, origin);
                        }
                        console.log('Annotations: ', annotations);

                        var commentTable = schema.tables.get('annotation_comment');
                        var commentPath = annotationPath.extend(commentTable).datapath;
                        var contextHeaderParams = {
                            catalog: context.catalogID,
                            schema_table: context.schemaName + ":annotation_comment",
                            filter: "id=" + context.imageID,
                            action: logActions.viewerComment
                        };

                        // Get all the comments for this image
                        // Nest comments fetch in annotations so annotations will be fetched and loaded to the DOM before the comments
                        commentPath.filter(imageFilter).entity.get(contextHeaderParams).then(function success(_comments){
                            var length = _comments.length;
                            for (var i = 0; i < length; i++) {
                                _comments[i].table = commentPath.context.table.name;
                                var annotationId = _comments[i].annotation_id;
                                if (!comments[annotationId]) {
                                    comments[annotationId] = [];
                                }
                                comments[annotationId].push(_comments[i]);
                            }
                            console.log('Comments: ', comments);
                        }, function error(response) {
                            console.log(response);
                        });

                    }, function error(response) {
                        throw response;
                    });
                }, function error(response) {
                    throw response;
                });

                // Get all rows from "anatomy" table
                var anatomyTable = schema.tables.get('anatomy');
                var anatomyPath = new ERMrest.DataPath(anatomyTable);
                var contextHeaderParams = {
                    catalog: context.catalogID,
                    schema_table: context.schemaName + ":anatomy",
                    action: logActions.viewerAnatomy
                };
                anatomyPath.entity.get(contextHeaderParams).then(function success(_anatomies) {
                    anatomies.push('No Anatomy');
                    var length = _anatomies.length;
                    for (var j = 0; j < length; j++) {
                        anatomies.push(_anatomies[j].term);
                    }
                    anatomies.sort(function sortAnatomies(a, b) {
                        a = a.toLowerCase();
                        b = b.toLowerCase();
                        if (a < b) {
                            return -1;
                        } else if (a > b) {
                            return 1;
                        } else {
                            return 0;
                        }
                    });
                }, function error(response) {
                    throw response;
                });
            }
        }, function error(response) {
          console.log(response);
        });

        // Set up a listener for all "message" events
        $window.addEventListener('message', function(event) {
            if (event.origin === origin) {
                if (event.data.messageType == 'annotoriousReady') {
                    annotoriousReady = event.data.content;
                    if (annotoriousReady && chaiseReady) {
                        iframe.postMessage({messageType: 'loadAnnotations', content: annotations}, origin);
                    }
                } else if (event.data.messageType == 'dismissChannels') {
                  window.console.log("XXX pull off the channels filtering pullout..");
/*
<button ng-click="osd.filterChannels();" class="btn btn-success" ng-class="{'pick':!osd.filterChannelsAreHidden}" type="button" role="button" title="channel filtering" id="filter-btn">
*/
                  var btnptr = $('#filter-btn');
                  btnptr.click();
                }
                // should really capture the 'unhandled' message type here..
            } else {
                console.log('Invalid event origin. Event origin: ', origin, '. Expected origin: ', window.location.origin);
            }
        });

        // Initialize Bootstrap tooltips
        $(document).ready(function(){
            $('[data-toggle="tooltip"]').tooltip({
                placement: 'bottom',
                container: 'body',
                html: true
            });
        });
    }]);

    // Refresh the page when the window's hash changes. Needed because Angular
    // normally doesn't refresh page when hash changes.
    window.onhashchange = function() {
        if (window.location.hash != '#undefined') {
            location.reload();
        } else {
            history.replaceState("", document.title, window.location.pathname);
            location.reload();
        }
        function goBack() {
            window.location.hash = window.location.lasthash[window.location.lasthash.length-1];
            window.location.lasthash.pop();
        }
    }
})();
<commit_msg>Removed comments<commit_after>(function() {
    'use strict';

    angular.module('chaise.configure-viewer', ['chaise.config'])

    .constant('appName', 'viewer')

    .run(['$rootScope', function ($rootScope) {
        // When the configuration module's run block emits the `configuration-done` event, attach the app to the DOM
        $rootScope.$on("configuration-done", function () {

            angular.element(document).ready(function(){
                angular.bootstrap(document.getElementById("viewer"), ["chaise.viewer"]);
            });
        });
    }]);

    var client;

    angular.module('chaise.viewer', [
        'ermrestjs',
        'ngSanitize',
        'chaise.alerts',
        'chaise.filters',
        'ngCookies',
        'chaise.authen',
        'chaise.errors',
        'chaise.delete',
        'chaise.modal',
        'chaise.navbar',
        'chaise.utils',
        'ui.select',
        'ui.bootstrap',
        'ng.deviceDetector'
    ])

    .config(['$provide', function($provide) {
        $provide.decorator('$templateRequest', ['ConfigUtils', 'UriUtils', '$delegate', function (ConfigUtils, UriUtils, $delegate) {
            return ConfigUtils.decorateTemplateRequest($delegate, UriUtils.chaiseDeploymentPath());
        }]);
    }])

    // Configure the context info from the URI
    .config(['context', 'UriUtilsProvider', function configureContext(context, UriUtilsProvider) {
        var utils = UriUtilsProvider.$get();

        // Parse the URL
        utils.setOrigin();
        utils.parseURLFragment(window.location, context);

        // should we allow for improper URLs here?
        // what if there are 2 filters and the id filter is the second one.
        // Is that improper or should it be parsed and ignore the other filter?
        var filter = context.filter.filters[0];
        if (filter.type === "BinaryPredicate" &&
            filter.operator === "=" &&
            filter.column.toLowerCase() === "id") {
            context.imageID = filter.value;
        }

        console.log('Context', context);
        // TODO: Check if context has everything it needs before proceeding. If not, Bad Request
    }])

    // set the chasie-config property
    .config(['headInjectorProvider', function (headInjectorProvider) {

        headInjectorProvider.$get().setupHead();
    }])

    // Configure all tooltips to be attached to the body by default. To attach a
    // tooltip on the element instead, set the `tooltip-append-to-body` attribute
    // to `false` on the element.
    .config(['$uibTooltipProvider', function($uibTooltipProvider) {
        $uibTooltipProvider.options({appendToBody: true});
    }])

    .config(['userProvider', 'context', 'SessionProvider', 'ConfigUtilsProvider', function configureUser(userProvider, context, SessionProvider, ConfigUtilsProvider) {
        var chaiseConfig = ConfigUtilsProvider.$get().getConfigJSON();
        SessionProvider.$get().getSession().then(function success(session) {
            // there's no active session
            if (!session) return;

            var groups = chaiseConfig.userGroups || context.groups;
            // session.attributes is an array of objects that have a display_name and id
            // We MUST use the id field to check for role inclusion as it is the unique identifier
            var attributes = session.attributes.map(function(attribute) { return attribute.id });
            var user = userProvider.$get();
            user.session = session;

// TODO Let's try to extract this setup to unclutter *.app.js
            // Need to check if using the new web authen
            // if so, there will be a client object with a combination of any or all of the following: display_name, full_name, and email
            // first priority id display_name
            if (session.client.display_name) {
                user.name = session.client.display_name;
            // full_name is second priority
            } else if (session.client.full_name) {
                user.name = session.client.full_name;
            // fallback if no display_name or full_name
            } else if (session.client.email) {
                user.name = session.client.email;
            // Case for old web authen where client is a string
            } else {
                user.name = session.client
            }

            if (attributes.indexOf(groups.curators) > -1) {
                user.role = 'curator';
            } else if (attributes.indexOf(groups.annotators) > -1) {
                user.role = 'annotator';
            } else if (attributes.indexOf(groups.users) > -1) {
                user.role = 'user';
            } else {
                user.role = null;
            }

            console.log('User: ', user);
            return;
        }, function error(response) {
            throw response;
        });
    }])

    // Hydrate values providers and set up iframe
    .run(['ConfigUtils', 'ERMrest', 'logActions', '$window', 'context', 'image', 'annotations', 'comments', 'anatomies', 'user', 'MathUtils', function runApp(ConfigUtils, ERMrest, logActions, $window, context, image, annotations, comments, anatomies, user, MathUtils) {
        var origin = $window.location.origin;
        var iframe = $window.frames[0];
        var annotoriousReady = false;
        var chaiseReady = false;
        var arrows = [];
        var rectangles = [];
        var sections = [];

        ConfigUtils.getContextJSON().server.catalogs.get(context.catalogID).then(function success(catalog) {
            var schema = catalog.schemas.get(context.schemaName);
            // So the schema and tables can be accessed in controllers
            context.schema = schema;
            console.log('Schema: ', schema);
            if (schema) {
                var table = schema.tables.get(context.tableName);
                // BinaryPredicate(column, operator, value) is used for building a filter
                // This predicate is used to get the image based on the id of the image the user is navigating to
                var imagePath = new ERMrest.DataPath(table);
                var imagePathColumn = imagePath.context.columns.get('id');
                var imageFilter = new ERMrest.BinaryPredicate(imagePathColumn, ERMrest.OPERATOR.EQUAL, context.imageID);

                var contextHeaderParams = {
                    catalog: context.catalogID,
                    schema_table: context.schemaName + ":" + context.tableName,
                    filter: "id=" + context.imageID,
                    action: logActions.viewerMain
                };

                if (context.queryParams && context.queryParams.ppid) {
                    contextHeaderParams.ppid = context.queryParams.ppid;
                }

                if (context.queryParams && context.queryParams.pcid) {
                    contextHeaderParams.pcid = context.queryParams.pcid;
                }
                imagePath.filter(imageFilter).entity.get(contextHeaderParams).then(function success(entity) {
                    image.entity = entity[0];
                    var waterMark = context.queryParams.waterMark;
                    if (waterMark === undefined) {
                    	waterMark = '';
                    } else {
                    	waterMark = '&waterMark=' + waterMark;
                    }
                    console.log('uri='+image.entity.uri + waterMark);
                    // Test scene 3
                    var params = image.entity.uri.split("?");
                    if(params.length > 1){
                        image.entity.uri = origin+"/openseadragon-viewer/index.html?" + params[1];
                        // image.entity.uri = origin+"/demo/chaise-osd/openseadragon-viewer/index.html?" + params[1];
                    }

                    // image.entity.uri = image.entity.uri + "&url=data/Q-296R_all_contours_cw_named.svg";
                    console.log('replace uri = '+image.entity.uri + waterMark)
                    iframe.location.replace(image.entity.uri + waterMark);
                    console.log('Image: ', image);

                    var annotationTable = schema.tables.get('annotation');
                    var annotationPath = imagePath.extend(annotationTable).datapath;
                    var contextHeaderParams = {
                        catalog: context.catalogID,
                        schema_table: context.schemaName + ":annotation",
                        filter: "id=" + context.imageID,
                        action: logActions.viewerAnnotation
                    };
                    annotationPath.filter(imageFilter).entity.get(contextHeaderParams).then(function success(_annotations) {
                        var length = _annotations.length;
                        for (var i = 0; i < length; i++) {
                            _annotations[i].table = annotationPath.context.table.name;
                            var annotation = _annotations[i];
                            if (!annotation.config) {
                                annotation.config = {};
                            }
                            annotations.push(annotation);
                        }
                        chaiseReady = true;

                        if (annotoriousReady && chaiseReady) {
                            iframe.postMessage({messageType: 'loadAnnotations', content: annotations}, origin);
                        }
                        console.log('Annotations: ', annotations);

                        var commentTable = schema.tables.get('annotation_comment');
                        var commentPath = annotationPath.extend(commentTable).datapath;
                        var contextHeaderParams = {
                            catalog: context.catalogID,
                            schema_table: context.schemaName + ":annotation_comment",
                            filter: "id=" + context.imageID,
                            action: logActions.viewerComment
                        };

                        // Get all the comments for this image
                        // Nest comments fetch in annotations so annotations will be fetched and loaded to the DOM before the comments
                        commentPath.filter(imageFilter).entity.get(contextHeaderParams).then(function success(_comments){
                            var length = _comments.length;
                            for (var i = 0; i < length; i++) {
                                _comments[i].table = commentPath.context.table.name;
                                var annotationId = _comments[i].annotation_id;
                                if (!comments[annotationId]) {
                                    comments[annotationId] = [];
                                }
                                comments[annotationId].push(_comments[i]);
                            }
                            console.log('Comments: ', comments);
                        }, function error(response) {
                            console.log(response);
                        });

                    }, function error(response) {
                        throw response;
                    });
                }, function error(response) {
                    throw response;
                });

                // Get all rows from "anatomy" table
                var anatomyTable = schema.tables.get('anatomy');
                var anatomyPath = new ERMrest.DataPath(anatomyTable);
                var contextHeaderParams = {
                    catalog: context.catalogID,
                    schema_table: context.schemaName + ":anatomy",
                    action: logActions.viewerAnatomy
                };
                anatomyPath.entity.get(contextHeaderParams).then(function success(_anatomies) {
                    anatomies.push('No Anatomy');
                    var length = _anatomies.length;
                    for (var j = 0; j < length; j++) {
                        anatomies.push(_anatomies[j].term);
                    }
                    anatomies.sort(function sortAnatomies(a, b) {
                        a = a.toLowerCase();
                        b = b.toLowerCase();
                        if (a < b) {
                            return -1;
                        } else if (a > b) {
                            return 1;
                        } else {
                            return 0;
                        }
                    });
                }, function error(response) {
                    throw response;
                });
            }
        }, function error(response) {
          console.log(response);
        });

        // Set up a listener for all "message" events
        $window.addEventListener('message', function(event) {
            if (event.origin === origin) {
                if (event.data.messageType == 'annotoriousReady') {
                    annotoriousReady = event.data.content;
                    if (annotoriousReady && chaiseReady) {
                        iframe.postMessage({messageType: 'loadAnnotations', content: annotations}, origin);
                    }
                } else if (event.data.messageType == 'dismissChannels') {
                  window.console.log("XXX pull off the channels filtering pullout..");
                  var btnptr = $('#filter-btn');
                  btnptr.click();
                }
                // should really capture the 'unhandled' message type here..
            } else {
                console.log('Invalid event origin. Event origin: ', origin, '. Expected origin: ', window.location.origin);
            }
        });

        // Initialize Bootstrap tooltips
        $(document).ready(function(){
            $('[data-toggle="tooltip"]').tooltip({
                placement: 'bottom',
                container: 'body',
                html: true
            });
        });
    }]);

    // Refresh the page when the window's hash changes. Needed because Angular
    // normally doesn't refresh page when hash changes.
    window.onhashchange = function() {
        if (window.location.hash != '#undefined') {
            location.reload();
        } else {
            history.replaceState("", document.title, window.location.pathname);
            location.reload();
        }
        function goBack() {
            window.location.hash = window.location.lasthash[window.location.lasthash.length-1];
            window.location.lasthash.pop();
        }
    }
})();
<|endoftext|>


<commit_before>angular.module('plus.cpview', [])

.controller('CpViewController', ['$scope', '$window', 'repository',  function($scope, $window, repository) {

  $scope.selectedCp = selectionCp;
  $scope.selectedParticipant = selParticipant;

  repository.getAllCps()           // TODO: Revisit
    .success(function(result) {
      $scope.cps = result;
    });

  $scope.participantList =[];

  $scope.onCpSelect = function(selected, redirect) {
    if ($scope.selectedCp.id != "null" && redirect != false ) {
      var url = "CPDashboardAction.do?isSystemDashboard=true";
      $('#cpFrameNew').attr('src',url);
	}

    $scope.selectedCp = {id: selected.id, shortTitle: selected.text};

    repository.getRegisteredParticipants(selected.id, "").success(function(result) {
      $scope.participantList = [];
      for (var i = 0; i < result.length; ++i) {
        var participant = {
          id: result[i].id + "," + result[i].cprId,
          name: result[i].lastName + "," + result[i].firstName + '(' + result[i].ppId + ')'
        }
        $scope.participantList.push(participant);
      }
    });

    $scope.selectedParticipant={};
    $scope.tree=[];
  };

  $scope.registerParticipant = function() {
    $scope.selectedParticipant={};
    $scope.tree = [];
    var url = "QueryParticipant.do?operation=add&pageOf=pageOfParticipantCPQuery&clearConsentSession=true&cpSearchCpId=" +
               $scope.selectedCp.id + "&refresh=true";
    $('#cpFrameNew').attr('src',url);
  }

  $scope.onParticipantSelect = function(selected, selectedScg) {
    var ids = selected.id.split(',');
    var participantId = ids[0], cprId = ids[1];
    $scope.selectedCprId = cprId;
    $scope.tree=[];

    if (!selectedScg) {
      var url = "QueryParticipantSearchForView.do?pageOf=newParticipantViewPage&operation=edit&cpSearchCpId=" +
                 $scope.selectedCp.id + "&id=" + participantId;
      $('#cpFrameNew').attr('src',url);
    }

    $scope.selectedParticipant = selected;
    return repository.getCollectionGroups($scope.selectedCprId).then(function(result) {
      var image;
      var collectionStatus;

      var tree = [];
      var scgs = result.data;
      for (var i = 0; i < scgs.length; ++i) {
        var scg = scgs[i];
        tree.push(
          {
        	  id: scg.instanceType + scg.id + scg.eventId,
              level: 1,
  			  scgId: scg.id,
              type: 'scg',
              name: $scope.getScgLabel(scg),
              collectionStatus: $scope.getStatusIcon(scg.collectionStatus),
              tooltip: $scope.getScgTooltip(scg),
              eventId: scg.eventId,
  			  instance: scg.instanceType,
              nodes: [],
              state: 'closed'
          });
      }
      $scope.tree = tree;
      return tree;
    });
  }

  $scope.viewParticipant = function(){
    var participantId = $scope.selectedParticipant.id.split(',')[0];
    var participantId
    var url = "QueryParticipantSearchForView.do?pageOf=newParticipantViewPage&operation=edit&cpSearchCpId=" +
              $scope.selectedCp.id + "&id=" + participantId;
    $('#cpFrameNew').attr('src',url);
  }

  if ($scope.selectedParticipant && $scope.selectedParticipant.id != -1) {
    $scope.onCpSelect({id: $scope.selectedCp.id, text: $scope.selectedCp.shortTitle});
    var scgTreeQ = $scope.onParticipantSelect(selParticipant, selectedScg);
    scgTreeQ.then(function() { $scope.handleDirectObjectLoad(); });
  }

  $scope.handleDirectObjectLoad = function(displayNode) {
    if (!selectedScg) {
      return;
    }

    var scgNode = null;
    var tree = $scope.tree;
    for (var i = 0; i < tree.length; i++) {
      if (tree[i].scgId == selectedScg.id) {
        scgNode = tree[i];
        break;
      }
    }

    if (!selectedSpecimen && displayNode != false) {
      $scope.displayNode(scgNode);
      return;
    }

    scgNode.state = 'opened';
    var scgId = selectedScg.id;

    repository.getSpecimens(scgId).success(function(result) {
      scgNode.nodes = $scope.getSpecimenTree(result);
      scgNode.childrenProbed = true;
      if (scgNode.nodes.length == 0) {
        scgNode.state = 'disabled';
      }

      var path = [];
      $scope.getSpecimenNodePath(selectedSpecimen, scgNode.nodes, path);

      var j = 0;
      var currNode = scgNode;
      for (var i = 0; i < path.length; ++i) {
        currNode.state = 'opened';
        var nodes = currNode.nodes;
        for (var j = 0; j < nodes.length; ++j) {
          if (path[i] == nodes[j].id) {
            currNode = nodes[j];
            break;
          }
        }
      }
      if (displayNode != false) {
    	  $scope.displayNode(currNode);
      }
    });
  };

  $scope.getSpecimenNodePath = function(specimen, specimens, path) {
    for (var i = 0; i < specimens.length; ++i) {
      path.push(specimens[i].id);
      if (specimen.id == specimens[i].specimenId) {
    	specimens[i].state = 'opened';
        return true;
      }

      if ($scope.getSpecimenNodePath(specimen, specimens[i].nodes, path)) {
        return true;
      }

      path.pop();
    }

    return false;
  };

  $scope.getSpecimenTree = function(specimens) {
    var specimenNodes = [];

    if (specimens == null || specimens == undefined) {
      return specimenNodes;
    }

    for (var i = 0; i < specimens.length; ++i) {
      var specimen = specimens[i];
      var name = $scope.getSpecimenName(specimen);
      var specimenNode = {
    		  id: specimen.instanceType + specimen.id + specimen.requirementId,
    	        name: name,
    	        tooltip: 'Label: ' + name + ' Type: ' + specimen.specimenType,
    	        collectionStatus: $scope.getStatusIcon(specimen.collectionStatus),
    	        type: 'specimen',
    	        instance: specimen.instanceType,
    			specimenId: specimen.id,
    			scgId: specimen.scgId,
    			parentId: specimen.parentId,
    			requirementId: specimen.requirementId,
    	        nodes: $scope.getSpecimenTree(specimen.children),
    	        specimenType: specimen.specimenType,
    	        state: 'closed'
      }

      specimenNode.childrenProbed = true;
      if (specimenNode.nodes.length == 0) {
        specimenNode.state = 'disabled';
      }
      specimenNodes.push(specimenNode);
    }

    return specimenNodes;
  };

  $scope.getSpecimenName = function(specimen) {
    var name = specimen.label ? specimen.label : specimen.specimenClass;
    if (specimen.requirementLabel) {
      name = name + "(" + specimen.requirementLabel + ")";
    } else {
        name = name + "(" + specimen.specimenType + ")";
    }
    return name;
  };

  $scope.onNodeToggle = function(data) {
    if (data.state == 'closed') {
      data.state = 'opened';

      if (data.childrenProbed == undefined) {
    	  var scgId = data.scgId;
          if (data.type == 'scg') {
  		  var objectType="";

  	if(data.instance == 'cpe'){
  		objectType = 'cpe';
  		scgId = data.eventId;
  	}
          repository.getSpecimens(scgId,objectType).success(function(result) {
            data.nodes = $scope.getSpecimenTree(result);
            data.childrenProbed = true;
            if (data.nodes.length == 0) {
              data.state = 'disabled';
            }
          });
        }
      }
    } else if (data.state == 'opened') {
      data.state = 'closed';
    }
  };

  $scope.displayNode = function(data) {
    $scope.selectedNode = data;

    if(data.type == 'scg') {
    	var participantId = $scope.selectedParticipant.id.split(',')[0];
        var ids = data.id.split(',');
  	  var url="QuerySpecimenCollectionGroupSearch.do?pageOf=pageOfSpecimenCollectionGroupCPQueryEdit&refresh=false&operation=edit&id="
          	 + data.scgId + "&cpSearchCpId=" + $scope.selectedCp.id + "&clickedNodeId="+ data.scgId;
  	  if(data.instance=='cpe')
  	  {
  		url="SpecimenCollectionGroup.do?operation=add&pageOf=pageOfSpecimenCollectionGroupCPQuery&cpId="+$scope.selectedCp.id+"&pId="+participantId+"&requestFrom=participantView&cpeId="+data.eventId;
  	  }
      $('#cpFrameNew').attr('src',url);
    } else if(data.type == 'specimen'){
      var ids = data.id.split(',');
      var url = "QuerySpecimenSearch.do?pageOf=pageOfNewSpecimenCPQuery&operation=edit&id=" + data.specimenId +
      "&refresh=false& " + "cpSearchCpId=" + $scope.selectedCp.id;
		if(data.instance=='requirement')
		{
		url="QueryCreateSpecimenFromRequirement.do?scgId="+data.scgId+"&parentId="+data.parentId+"&requirementId="+data.requirementId;
		}
      $('#cpFrameNew').attr('src',url);
    }
  }

  $scope.getStatusIcon = function(collectionStatus) {
    var statusIcon;
    if(collectionStatus == 'Complete' || collectionStatus == 'Collected') {
      statusIcon = 'fa fa-circle complete';
    } else if(collectionStatus == 'Not Collected') {
      statusIcon = 'fa fa-circle not-collected';
    } else if (collectionStatus == 'Distributed') {
      statusIcon = 'fa fa-circle distributed';
    } else {
      statusIcon = 'fa fa-circle pending';
    }
    return statusIcon;
  };

  $scope.getScgLabel = function(scg) {
    var date1 = scg.receivedDate ? scg.receivedDate : scg.registrationDate;
	var date = new Date(date1);
    return "T" + scg.eventPoint + ": " + scg.collectionPointLabel + ": " + date.format("d-m-Y");
  }

  $scope.getScgTooltip = function(scg) {
    var date1 = scg.receivedDate ? scg.receivedDate : scg.registrationDate;
    var date = new Date(date1);
    var htmlToolTip =
    	"

" +
    	  "
Event Point : 	"+ scg.eventPoint + " (" + scg.collectionPointLabel  + ") "+ "
" +
    	  "
Received date: 	"+ date.format("d-m-Y") + "
" +
    	"

";

    return htmlToolTip;
  }
}]);

<commit_msg>changes for CP specific dashboard<commit_after>angular.module('plus.cpview', [])

.controller('CpViewController', ['$scope', '$window', 'repository',  function($scope, $window, repository) {

  $scope.selectedCp = selectionCp;
  $scope.selectedParticipant = selParticipant;

  repository.getAllCps()           // TODO: Revisit
    .success(function(result) {
      $scope.cps = result;
    });

  $scope.participantList =[];

  $scope.onCpSelect = function(selected, redirect) {
    if (selected.id != "null" && redirect != false ) {
      var url = "CPDashboardAction.do?isSystemDashboard=false&cpSearchCpId="+selected.id;
      $('#cpFrameNew').attr('src',url);
	}

    $scope.selectedCp = {id: selected.id, shortTitle: selected.text};

    repository.getRegisteredParticipants(selected.id, "").success(function(result) {
      $scope.participantList = [];
      for (var i = 0; i < result.length; ++i) {
        var participant = {
          id: result[i].id + "," + result[i].cprId,
          name: result[i].lastName + "," + result[i].firstName + '(' + result[i].ppId + ')'
        }
        $scope.participantList.push(participant);
      }
    });

    $scope.selectedParticipant={};
    $scope.tree=[];
  };

  $scope.registerParticipant = function() {
    $scope.selectedParticipant={};
    $scope.tree = [];
    var url = "QueryParticipant.do?operation=add&pageOf=pageOfParticipantCPQuery&clearConsentSession=true&cpSearchCpId=" +
               $scope.selectedCp.id + "&refresh=true";
    $('#cpFrameNew').attr('src',url);
  }

  $scope.onParticipantSelect = function(selected, selectedScg) {
    var ids = selected.id.split(',');
    var participantId = ids[0], cprId = ids[1];
    $scope.selectedCprId = cprId;
    $scope.tree=[];

    if (!selectedScg) {
      var url = "QueryParticipantSearchForView.do?pageOf=newParticipantViewPage&operation=edit&cpSearchCpId=" +
                 $scope.selectedCp.id + "&id=" + participantId;
      $('#cpFrameNew').attr('src',url);
    }

    $scope.selectedParticipant = selected;
    return repository.getCollectionGroups($scope.selectedCprId).then(function(result) {
      var image;
      var collectionStatus;

      var tree = [];
      var scgs = result.data;
      for (var i = 0; i < scgs.length; ++i) {
        var scg = scgs[i];
        tree.push(
          {
        	  id: scg.instanceType + scg.id + scg.eventId,
              level: 1,
  			  scgId: scg.id,
              type: 'scg',
              name: $scope.getScgLabel(scg),
              collectionStatus: $scope.getStatusIcon(scg.collectionStatus),
              tooltip: $scope.getScgTooltip(scg),
              eventId: scg.eventId,
  			  instance: scg.instanceType,
              nodes: [],
              state: 'closed'
          });
      }
      $scope.tree = tree;
      return tree;
    });
  }

  $scope.viewParticipant = function(){
    var participantId = $scope.selectedParticipant.id.split(',')[0];
    var participantId
    var url = "QueryParticipantSearchForView.do?pageOf=newParticipantViewPage&operation=edit&cpSearchCpId=" +
              $scope.selectedCp.id + "&id=" + participantId;
    $('#cpFrameNew').attr('src',url);
  }

  if ($scope.selectedParticipant && $scope.selectedParticipant.id != -1) {
    $scope.onCpSelect({id: $scope.selectedCp.id, text: $scope.selectedCp.shortTitle});
    var scgTreeQ = $scope.onParticipantSelect(selParticipant, selectedScg);
    scgTreeQ.then(function() { $scope.handleDirectObjectLoad(); });
  }

  $scope.handleDirectObjectLoad = function(displayNode) {
    if (!selectedScg) {
      return;
    }

    var scgNode = null;
    var tree = $scope.tree;
    for (var i = 0; i < tree.length; i++) {
      if (tree[i].scgId == selectedScg.id) {
        scgNode = tree[i];
        break;
      }
    }

    if (!selectedSpecimen && displayNode != false) {
      $scope.displayNode(scgNode);
      return;
    }

    scgNode.state = 'opened';
    var scgId = selectedScg.id;

    repository.getSpecimens(scgId).success(function(result) {
      scgNode.nodes = $scope.getSpecimenTree(result);
      scgNode.childrenProbed = true;
      if (scgNode.nodes.length == 0) {
        scgNode.state = 'disabled';
      }

      var path = [];
      $scope.getSpecimenNodePath(selectedSpecimen, scgNode.nodes, path);

      var j = 0;
      var currNode = scgNode;
      for (var i = 0; i < path.length; ++i) {
        currNode.state = 'opened';
        var nodes = currNode.nodes;
        for (var j = 0; j < nodes.length; ++j) {
          if (path[i] == nodes[j].id) {
            currNode = nodes[j];
            break;
          }
        }
      }
      if (displayNode != false) {
    	  $scope.displayNode(currNode);
      }
    });
  };

  $scope.getSpecimenNodePath = function(specimen, specimens, path) {
    for (var i = 0; i < specimens.length; ++i) {
      path.push(specimens[i].id);
      if (specimen.id == specimens[i].specimenId) {
    	specimens[i].state = 'opened';
        return true;
      }

      if ($scope.getSpecimenNodePath(specimen, specimens[i].nodes, path)) {
        return true;
      }

      path.pop();
    }

    return false;
  };

  $scope.getSpecimenTree = function(specimens) {
    var specimenNodes = [];

    if (specimens == null || specimens == undefined) {
      return specimenNodes;
    }

    for (var i = 0; i < specimens.length; ++i) {
      var specimen = specimens[i];
      var name = $scope.getSpecimenName(specimen);
      var specimenNode = {
    		  id: specimen.instanceType + specimen.id + specimen.requirementId,
    	        name: name,
    	        tooltip: 'Label: ' + name + ' Type: ' + specimen.specimenType,
    	        collectionStatus: $scope.getStatusIcon(specimen.collectionStatus),
    	        type: 'specimen',
    	        instance: specimen.instanceType,
    			specimenId: specimen.id,
    			scgId: specimen.scgId,
    			parentId: specimen.parentId,
    			requirementId: specimen.requirementId,
    	        nodes: $scope.getSpecimenTree(specimen.children),
    	        specimenType: specimen.specimenType,
    	        state: 'closed'
      }

      specimenNode.childrenProbed = true;
      if (specimenNode.nodes.length == 0) {
        specimenNode.state = 'disabled';
      }
      specimenNodes.push(specimenNode);
    }

    return specimenNodes;
  };

  $scope.getSpecimenName = function(specimen) {
    var name = specimen.label ? specimen.label : specimen.specimenClass;
    if (specimen.requirementLabel) {
      name = name + "(" + specimen.requirementLabel + ")";
    } else {
        name = name + "(" + specimen.specimenType + ")";
    }
    return name;
  };

  $scope.onNodeToggle = function(data) {
    if (data.state == 'closed') {
      data.state = 'opened';

      if (data.childrenProbed == undefined) {
    	  var scgId = data.scgId;
          if (data.type == 'scg') {
  		  var objectType="";

  	if(data.instance == 'cpe'){
  		objectType = 'cpe';
  		scgId = data.eventId;
  	}
          repository.getSpecimens(scgId,objectType).success(function(result) {
            data.nodes = $scope.getSpecimenTree(result);
            data.childrenProbed = true;
            if (data.nodes.length == 0) {
              data.state = 'disabled';
            }
          });
        }
      }
    } else if (data.state == 'opened') {
      data.state = 'closed';
    }
  };

  $scope.displayNode = function(data) {
    $scope.selectedNode = data;

    if(data.type == 'scg') {
    	var participantId = $scope.selectedParticipant.id.split(',')[0];
        var ids = data.id.split(',');
  	  var url="QuerySpecimenCollectionGroupSearch.do?pageOf=pageOfSpecimenCollectionGroupCPQueryEdit&refresh=false&operation=edit&id="
          	 + data.scgId + "&cpSearchCpId=" + $scope.selectedCp.id + "&clickedNodeId="+ data.scgId;
  	  if(data.instance=='cpe')
  	  {
  		url="SpecimenCollectionGroup.do?operation=add&pageOf=pageOfSpecimenCollectionGroupCPQuery&cpId="+$scope.selectedCp.id+"&pId="+participantId+"&requestFrom=participantView&cpeId="+data.eventId;
  	  }
      $('#cpFrameNew').attr('src',url);
    } else if(data.type == 'specimen'){
      var ids = data.id.split(',');
      var url = "QuerySpecimenSearch.do?pageOf=pageOfNewSpecimenCPQuery&operation=edit&id=" + data.specimenId +
      "&refresh=false& " + "cpSearchCpId=" + $scope.selectedCp.id;
		if(data.instance=='requirement')
		{
		url="QueryCreateSpecimenFromRequirement.do?scgId="+data.scgId+"&parentId="+data.parentId+"&requirementId="+data.requirementId;
		}
      $('#cpFrameNew').attr('src',url);
    }
  }

  $scope.getStatusIcon = function(collectionStatus) {
    var statusIcon;
    if(collectionStatus == 'Complete' || collectionStatus == 'Collected') {
      statusIcon = 'fa fa-circle complete';
    } else if(collectionStatus == 'Not Collected') {
      statusIcon = 'fa fa-circle not-collected';
    } else if (collectionStatus == 'Distributed') {
      statusIcon = 'fa fa-circle distributed';
    } else {
      statusIcon = 'fa fa-circle pending';
    }
    return statusIcon;
  };

  $scope.getScgLabel = function(scg) {
    var date1 = scg.receivedDate ? scg.receivedDate : scg.registrationDate;
	var date = new Date(date1);
    return "T" + scg.eventPoint + ": " + scg.collectionPointLabel + ": " + date.format("d-m-Y");
  }

  $scope.getScgTooltip = function(scg) {
    var date1 = scg.receivedDate ? scg.receivedDate : scg.registrationDate;
    var date = new Date(date1);
    var htmlToolTip =
    	"

" +
    	  "
Event Point : 	"+ scg.eventPoint + " (" + scg.collectionPointLabel  + ") "+ "
" +
    	  "
Received date: 	"+ date.format("d-m-Y") + "
" +
    	"

";

    return htmlToolTip;
  }
}]);<|endoftext|>


<commit_before>view = Backbone.View.extend();

view.prototype.events = {
    'slidechange .slider': 'updateTotal',
    'change select[name=format]': 'updateCustom',
    'keyup input[name=bounds],\
        input[name=width],\
        input[name=height]': 'updateSize',
    'change input[name=bounds],\
        input[name=width],\
        input[name=height]': 'updateSize',
    'click input[type=submit]': 'save',
    'click .cancel': 'close'
};

view.prototype.initialize = function(options) {
    if (!options.type) throw new Error('No type provided.');
    if (!options.model) throw new Error('No export model provided.');
    if (!options.project) throw new Error('No project model provided.');

    _(this).bindAll(
        'render',
        'close',
        'save',
        'mapZoom',
        'updateCustom',
        'updateTotal',
        'updateSize');
    this.sm = new SphericalMercator;
    this.type = options.type;
    this.title = options.title;
    this.project = options.project;
    this.success = options.success || function() {};
    this.cancel = options.cancel || function() {};

    // No need to load or check anything if editing project.
    if (this.project === this.model) return this.render();

    // Check whether an existing export with this ID exists and is in progress.
    Bones.utils.fetch({
        existing: new models.Export({id:this.model.id}),
        config: new models.Config()
    }, _(function(err, models) {
        if (err && err.status !== 404) {
            new views.Modal(err);
            return this.cancel();
        }
        if (!err && _(['processing','waiting']).include(models.existing.get('status'))) {
            new views.Modal(new Error('Export already in progress.'));
            return this.cancel();
        }
        this.config = models.config;
        this.render();
    }).bind(this));
};

view.prototype.close = function() {
    this.cancel();
    return false;
};

view.prototype.render = function() {
    $(this.el).html(templates.Metadata(this));

    this.model.set({zooms:[
        this.project.get('minzoom'),
        this.project.get('maxzoom')
    ]}, {silent:true});
    Bones.utils.sliders(this.$('.slider'), this.model);

    var center = this.project.get('center');
    var bounds = this.project.get('bounds');
    var extent = [
        new com.modestmaps.Location(bounds[1], bounds[0]),
        new com.modestmaps.Location(bounds[3], bounds[2])
    ];
    this.map = new com.modestmaps.Map('meta-map',
        new wax.mm.connector(this.project.attributes));

    wax.mm.zoomer(this.map).appendTo(this.map.parent);
    this.map.setExtent(extent);

    if (this.$('input[name=bounds]').size()) {
        this.boxselector = wax.mm.boxselector(this.map, {}, _(function(data) {
            var s = _(data).chain().pluck('lat').min().value().toFixed(4);
            var n = _(data).chain().pluck('lat').max().value().toFixed(4);
            var w = _(data).chain().pluck('lon').min().value().toFixed(4) % 360;
            var e = _(data).chain().pluck('lon').max().value().toFixed(4) % 360;
            if (w < -180) w += 360; else if (w > 180) w -= 360;
            if (e < -180) e += 360; else if (e > 180) e -= 360;
            this.$('input[name=bounds]').val([w,s,e,n].join(','));
            if (this.$('input[name=width]').size()) this.updateSize();
        }).bind(this));
        this.boxselector.extent(extent);
    }
    if (this.$('input[name=center]').size()) {
        var first = true;
        this.pointselector = wax.mm.pointselector(this.map, {}, _(function(data) {
            var point = data.pop();
            var x = point.lon.toFixed(4) % 360;
            var y = point.lat.toFixed(4);
            var z = first ? center[2] : this.map.getZoom();
            if (x < -180) x += 360; else if (x > 180) x -= 360;
            this.$('input[name=center]').val([x,y,z].join(','));

            var loc = this.pointselector.locations();
            while (loc.length > 1) {
                this.pointselector.deleteLocation(loc[0]);
                loc = this.pointselector.locations();
            }
            $(loc[0].pointDiv).text('Z'+z);
            first = false;
        }).bind(this));
        this.pointselector.addLocation(new com.modestmaps.Location(center[1],center[0]));
    }

    // Update state of custom format field.
    if (this.$('select[name=format]').size()) this.updateCustom();

    // Update total tiles
    if (this.$('.slider').size()) this.updateTotal();

    // Set up map zoom display.
    this.map.addCallback('zoomed', this.mapZoom);
    this.map.addCallback('panned', this.mapZoom);
    this.map.addCallback('extentset', this.mapZoom);
    this.mapZoom({element: this.map.div});

    return this;
};

// Set zoom display.
view.prototype.mapZoom = function(e) {
    this.$('.zoom-display .zoom').text(this.map.getZoom());
};

view.prototype.updateCustom = function(ev) {
    if (this.$('select[name=format]').val() === '') {
        this.$('.dependent').show();
    } else {
        this.$('.dependent').hide();
    }
};

view.prototype.updateTotal = function(attributes) {
    var sm = this.sm;
    var attr = Bones.utils.form(this.$('form'), this.model);
    var bbox = _(attr.bounds.split(',')).map(parseFloat);
    var total = _(_.range(attr.zooms[0],attr.zooms[1]+1)).reduce(function(memo, z) {
        var b = sm.xyz(bbox, z);
        memo += Math.abs((b.maxX - b.minX + 1) * (b.maxY - b.minY + 1));
        return memo;
    }, 0);
    this.$('.totaltiles').text((function(num) {
        for (var num = parseInt(num, 0).toString(), i = num.length - 3; i > 0; i -= 3) {
            num = num.substring(0, i) + ',' + num.substring(i);
        }
        return num;
    })(total));
    this.$('.totalsize').text((function(num) {
        num = num || 0;
        if (num >= 1e12) return '1000 GB+';
        if (num >= 1e10) return '100 GB+';
        if (num >= 1e9) return '1 GB+';
        if (num >= 1e8) return '100 MB+';
        if (num >= 1e7) return '10 MB+';
        if (num >= 1e6) return '1 MB+';
        return '1 MB';
    })(total * 1000));
};

// Update size fields based on bbox ratio.
view.prototype.updateSize = function(ev) {
    var bounds = _(this.$('input[name=bounds]').val().split(',')).map(parseFloat);
    var nwLoc = new com.modestmaps.Location(bounds[3], bounds[0]);
    var seLoc = new com.modestmaps.Location(bounds[1], bounds[2]);
    var nw = this.map.locationPoint(nwLoc);
    var se = this.map.locationPoint(seLoc);
    var aspect = (Math.round(se.x) - Math.round(nw.x)) /
        (Math.round(se.y) - Math.round(nw.y));

    var target = $((ev || {}).currentTarget);
    if (target.attr('name') && target.attr('name') === 'bounds')
        this.boxselector.extent([nwLoc, seLoc], true);

    switch (target.attr('name')) {
    case 'height':
        var h = parseInt(this.$('input[name=height]').val(), 10);
        if (_(h).isNumber() && _(aspect).isNumber())
            this.$('input[name=width]').val(Math.round(h * aspect));
        break;
    case 'width':
    default:
        var w = parseInt(this.$('input[name=width]').val(), 10);
        if (_(w).isNumber() && _(aspect).isNumber())
            this.$('input[name=height]').val(Math.round(w / aspect));
        break;
    };
    // Update total tiles.
    if (this.type === 'tiles') this.updateTotal();
};

view.prototype.save = function() {
    var attr = Bones.utils.form(this.$('form'), this.model);
    var save = attr._saveProject;
    var error = function(m, e) { new views.Modal(e); };

    // Massage values.
    if (attr.filename) attr.filename = attr.filename + '.' + this.model.get('format');
    if (attr.bounds) attr.bounds = _(attr.bounds.split(',')).map(parseFloat);
    if (attr.center) attr.center = _(attr.center.split(',')).map(parseFloat);
    if (attr.zooms) attr.minzoom = attr.zooms[0];
    if (attr.zooms) attr.maxzoom = attr.zooms[1];
    if (attr.format) attr.format = attr.format || attr.format_custom;
    if (attr.height) attr.height = parseInt(attr.height,10);
    if (attr.width) attr.width = parseInt(attr.width,10);
    delete attr.zooms;
    delete attr.format_custom;
    delete attr._saveProject;
    attr = _(attr).reduce(function(memo, val, key) {
        var allowEmpty = ['description', 'attribution'];
        if (val !== '' || _(allowEmpty).include(key)) memo[key] = val;
        return memo;
    }, {});

    // Project settings.
    if (this.model === this.project) {
        if (!this.project.set(attr, {error:error})) return false;
        this.project.save({}, { success:this.success, error:error});
        return false;
    }

    // Exports.
    switch (this.model.get('format')) {
    case 'sync':
        if (!this.model.set({
            id: this.project.id,
            name: this.project.get('name') || this.project.id
        }, {error:error})) return false;
        break;
    case 'mbtiles':
        if (!this.model.set({
            filename: attr.filename,
            bbox: attr.bounds,
            minzoom: attr.minzoom,
            maxzoom: attr.maxzoom
        }, {error:error})) return false;
        break;
    case 'png':
    case 'pdf':
    case 'svg':
        if (!this.model.set({
            filename: attr.filename,
            bbox: attr.bounds,
            width: attr.width,
            height: attr.height
        }, {error:error})) return false;
        break;
    }

    // Just save the export.
    if (!save) return this.model.save({}, this) && false;

    // Save export and then project.
    delete attr.filename;
    delete attr.width;
    delete attr.height;
    if (!this.project.set(attr, {error:error})) return false;
    Bones.utils.serial([
    _(function(next) {
        this.model.save({}, { success:next, error:this.error });
    }).bind(this),
    _(function(next) {
        this.project.save({}, this);
    }).bind(this)]);
    return false;
};

<commit_msg>Fix custom format saving.<commit_after>view = Backbone.View.extend();

view.prototype.events = {
    'slidechange .slider': 'updateTotal',
    'change select[name=format]': 'updateCustom',
    'keyup input[name=bounds],\
        input[name=width],\
        input[name=height]': 'updateSize',
    'change input[name=bounds],\
        input[name=width],\
        input[name=height]': 'updateSize',
    'click input[type=submit]': 'save',
    'click .cancel': 'close'
};

view.prototype.initialize = function(options) {
    if (!options.type) throw new Error('No type provided.');
    if (!options.model) throw new Error('No export model provided.');
    if (!options.project) throw new Error('No project model provided.');

    _(this).bindAll(
        'render',
        'close',
        'save',
        'mapZoom',
        'updateCustom',
        'updateTotal',
        'updateSize');
    this.sm = new SphericalMercator;
    this.type = options.type;
    this.title = options.title;
    this.project = options.project;
    this.success = options.success || function() {};
    this.cancel = options.cancel || function() {};

    // No need to load or check anything if editing project.
    if (this.project === this.model) return this.render();

    // Check whether an existing export with this ID exists and is in progress.
    Bones.utils.fetch({
        existing: new models.Export({id:this.model.id}),
        config: new models.Config()
    }, _(function(err, models) {
        if (err && err.status !== 404) {
            new views.Modal(err);
            return this.cancel();
        }
        if (!err && _(['processing','waiting']).include(models.existing.get('status'))) {
            new views.Modal(new Error('Export already in progress.'));
            return this.cancel();
        }
        this.config = models.config;
        this.render();
    }).bind(this));
};

view.prototype.close = function() {
    this.cancel();
    return false;
};

view.prototype.render = function() {
    $(this.el).html(templates.Metadata(this));

    this.model.set({zooms:[
        this.project.get('minzoom'),
        this.project.get('maxzoom')
    ]}, {silent:true});
    Bones.utils.sliders(this.$('.slider'), this.model);

    var center = this.project.get('center');
    var bounds = this.project.get('bounds');
    var extent = [
        new com.modestmaps.Location(bounds[1], bounds[0]),
        new com.modestmaps.Location(bounds[3], bounds[2])
    ];
    this.map = new com.modestmaps.Map('meta-map',
        new wax.mm.connector(this.project.attributes));

    wax.mm.zoomer(this.map).appendTo(this.map.parent);
    this.map.setExtent(extent);

    if (this.$('input[name=bounds]').size()) {
        this.boxselector = wax.mm.boxselector(this.map, {}, _(function(data) {
            var s = _(data).chain().pluck('lat').min().value().toFixed(4);
            var n = _(data).chain().pluck('lat').max().value().toFixed(4);
            var w = _(data).chain().pluck('lon').min().value().toFixed(4) % 360;
            var e = _(data).chain().pluck('lon').max().value().toFixed(4) % 360;
            if (w < -180) w += 360; else if (w > 180) w -= 360;
            if (e < -180) e += 360; else if (e > 180) e -= 360;
            this.$('input[name=bounds]').val([w,s,e,n].join(','));
            if (this.$('input[name=width]').size()) this.updateSize();
        }).bind(this));
        this.boxselector.extent(extent);
    }
    if (this.$('input[name=center]').size()) {
        var first = true;
        this.pointselector = wax.mm.pointselector(this.map, {}, _(function(data) {
            var point = data.pop();
            var x = point.lon.toFixed(4) % 360;
            var y = point.lat.toFixed(4);
            var z = first ? center[2] : this.map.getZoom();
            if (x < -180) x += 360; else if (x > 180) x -= 360;
            this.$('input[name=center]').val([x,y,z].join(','));

            var loc = this.pointselector.locations();
            while (loc.length > 1) {
                this.pointselector.deleteLocation(loc[0]);
                loc = this.pointselector.locations();
            }
            $(loc[0].pointDiv).text('Z'+z);
            first = false;
        }).bind(this));
        this.pointselector.addLocation(new com.modestmaps.Location(center[1],center[0]));
    }

    // Update state of custom format field.
    if (this.$('select[name=format]').size()) this.updateCustom();

    // Update total tiles
    if (this.$('.slider').size()) this.updateTotal();

    // Set up map zoom display.
    this.map.addCallback('zoomed', this.mapZoom);
    this.map.addCallback('panned', this.mapZoom);
    this.map.addCallback('extentset', this.mapZoom);
    this.mapZoom({element: this.map.div});

    return this;
};

// Set zoom display.
view.prototype.mapZoom = function(e) {
    this.$('.zoom-display .zoom').text(this.map.getZoom());
};

view.prototype.updateCustom = function(ev) {
    if (this.$('select[name=format]').val() === '') {
        this.$('.dependent').show();
    } else {
        this.$('.dependent').hide();
    }
};

view.prototype.updateTotal = function(attributes) {
    var sm = this.sm;
    var attr = Bones.utils.form(this.$('form'), this.model);
    var bbox = _(attr.bounds.split(',')).map(parseFloat);
    var total = _(_.range(attr.zooms[0],attr.zooms[1]+1)).reduce(function(memo, z) {
        var b = sm.xyz(bbox, z);
        memo += Math.abs((b.maxX - b.minX + 1) * (b.maxY - b.minY + 1));
        return memo;
    }, 0);
    this.$('.totaltiles').text((function(num) {
        for (var num = parseInt(num, 0).toString(), i = num.length - 3; i > 0; i -= 3) {
            num = num.substring(0, i) + ',' + num.substring(i);
        }
        return num;
    })(total));
    this.$('.totalsize').text((function(num) {
        num = num || 0;
        if (num >= 1e12) return '1000 GB+';
        if (num >= 1e10) return '100 GB+';
        if (num >= 1e9) return '1 GB+';
        if (num >= 1e8) return '100 MB+';
        if (num >= 1e7) return '10 MB+';
        if (num >= 1e6) return '1 MB+';
        return '1 MB';
    })(total * 1000));
};

// Update size fields based on bbox ratio.
view.prototype.updateSize = function(ev) {
    var bounds = _(this.$('input[name=bounds]').val().split(',')).map(parseFloat);
    var nwLoc = new com.modestmaps.Location(bounds[3], bounds[0]);
    var seLoc = new com.modestmaps.Location(bounds[1], bounds[2]);
    var nw = this.map.locationPoint(nwLoc);
    var se = this.map.locationPoint(seLoc);
    var aspect = (Math.round(se.x) - Math.round(nw.x)) /
        (Math.round(se.y) - Math.round(nw.y));

    var target = $((ev || {}).currentTarget);
    if (target.attr('name') && target.attr('name') === 'bounds')
        this.boxselector.extent([nwLoc, seLoc], true);

    switch (target.attr('name')) {
    case 'height':
        var h = parseInt(this.$('input[name=height]').val(), 10);
        if (_(h).isNumber() && _(aspect).isNumber())
            this.$('input[name=width]').val(Math.round(h * aspect));
        break;
    case 'width':
    default:
        var w = parseInt(this.$('input[name=width]').val(), 10);
        if (_(w).isNumber() && _(aspect).isNumber())
            this.$('input[name=height]').val(Math.round(w / aspect));
        break;
    };
    // Update total tiles.
    if (this.type === 'tiles') this.updateTotal();
};

view.prototype.save = function() {
    var attr = Bones.utils.form(this.$('form'), this.model);
    var save = attr._saveProject;
    var error = function(m, e) { new views.Modal(e); };

    // Massage values.
    if (attr.filename) attr.filename = attr.filename + '.' + this.model.get('format');
    if (attr.bounds) attr.bounds = _(attr.bounds.split(',')).map(parseFloat);
    if (attr.center) attr.center = _(attr.center.split(',')).map(parseFloat);
    if (attr.zooms) attr.minzoom = attr.zooms[0];
    if (attr.zooms) attr.maxzoom = attr.zooms[1];
    if (attr.format || attr.format_custom) attr.format = attr.format || attr.format_custom;
    if (attr.height) attr.height = parseInt(attr.height,10);
    if (attr.width) attr.width = parseInt(attr.width,10);
    delete attr.zooms;
    delete attr.format_custom;
    delete attr._saveProject;
    attr = _(attr).reduce(function(memo, val, key) {
        var allowEmpty = ['description', 'attribution'];
        if (val !== '' || _(allowEmpty).include(key)) memo[key] = val;
        return memo;
    }, {});

    // Project settings.
    if (this.model === this.project) {
        if (!this.project.set(attr, {error:error})) return false;
        this.project.save({}, { success:this.success, error:error});
        return false;
    }

    // Exports.
    switch (this.model.get('format')) {
    case 'sync':
        if (!this.model.set({
            id: this.project.id,
            name: this.project.get('name') || this.project.id
        }, {error:error})) return false;
        break;
    case 'mbtiles':
        if (!this.model.set({
            filename: attr.filename,
            bbox: attr.bounds,
            minzoom: attr.minzoom,
            maxzoom: attr.maxzoom
        }, {error:error})) return false;
        break;
    case 'png':
    case 'pdf':
    case 'svg':
        if (!this.model.set({
            filename: attr.filename,
            bbox: attr.bounds,
            width: attr.width,
            height: attr.height
        }, {error:error})) return false;
        break;
    }

    // Just save the export.
    if (!save) return this.model.save({}, this) && false;

    // Save export and then project.
    delete attr.filename;
    delete attr.width;
    delete attr.height;
    if (!this.project.set(attr, {error:error})) return false;
    Bones.utils.serial([
    _(function(next) {
        this.model.save({}, { success:next, error:this.error });
    }).bind(this),
    _(function(next) {
        this.project.save({}, this);
    }).bind(this)]);
    return false;
};

<|endoftext|>


<commit_before>var opts = {
    lines: 13, // The number of lines to draw
    length: 20, // The length of each line
    width: 10, // The line thickness
    radius: 30, // The radius of the inner circle
    corners: 1, // Corner roundness (0..1)
    rotate: 0, // The rotation offset
    direction: 1, // 1: clockwise, -1: counterclockwise
    color: '#000', // #rgb or #rrggbb or array of colors
    speed: 1, // Rounds per second
    trail: 60, // Afterglow percentage
    shadow: false, // Whether to render a shadow
    hwaccel: false, // Whether to use hardware acceleration
    className: 'spinner', // The CSS class to assign to the spinner
    zIndex: 2e9, // The z-index (defaults to 2000000000)
    top: 'auto', // Top position relative to parent in px
    left: 'auto' // Left position relative to parent in px
};
var spinner = new Spinner(opts);
var token;
var pageNumber = 1;
var curReport;

function loginSpin() {
    spinner.stop();
    $('#signinSection').find('input, button').prop("disabled", true);
    spinner.spin(document.getElementById('signinSection'));
}

function loginUnspin() {
    spinner.stop();
    $('#signinSection').find('input, button').prop("disabled", false);
}

function setToken(token) {
    this.token = token;
    var date = new Date();
    setCookie("token", token, date.getTime() + (2 * 24 * 60 * 60 * 1000));
}
function gotoMain()
{
    window.location.href = server_base + "main.jsp";
}
function doLogin()
{
    loginSpin();
    var user = $("#loginEmail").val();
    var password = $("#loginPassword").val();
    $.ajax({
        type: "POST",
        url: server_base + "rest/auth/login/" + user,
        data: password,
        contentType: "TEXT/PLAIN",
        success: function (msg)
        {
            loginUnspin();
            if (msg.error != "")
            {
                alert(msg.error);
            } else {
                setToken(msg.token);
                gotoMain();
            }
        }
        }).fail(function (jqXHR, textStatus, errorThrown)
            {
                loginUnspin();
                alert(errorThrown);
            });
}
function loadReportList() {
    token = getCookie("token");
    $.ajax({
        type: "GET",
        url: server_base + "rest/auth/reports/" + token,
        success: function (msg)
        {
            if (!msg.error)
            {
                loadReportListData(msg);
            } else {
                ajaxFail(null, null, msg.error);
            }
        }
    }).fail(ajaxFail);
};
function loadReportListData(data)
{
    var reportDDList = $("#reportDropdownList");
    reportDDList.find("li:not(.hidden)").remove();
    data.forEach(function (report)
    {
        var template = reportDDList.find("li.hidden").clone();
        template.removeClass("hidden");
        reportDDList.append(template);
        template.html(""+report+"");
    });
}
function resetDisplay() {
    $('#kaguraMain,#kaguraContactUs,#kaguraAbout,#reportMain').addClass("hidden");
}
function resetReportConfig()
{
    $('#reportTableHeader>tr:not(.hidden)').remove();
    $('#reportTableBody>tr:not(.hidden)').remove();
    $('#reportTableBody>tr>td:not(.hidden)').remove();
    $('#paramPanel>div:not(.hidden)').remove();
}
function resetReport()
{
    $('#reportTableBody>tr:not(.hidden)').remove();
}
function loadReport(reportId)
{
    resetDisplay();
    resetReportConfig();
    resetReport();
    $('#reportTitle').text(reportId);
    spinner.stop();
    var reportMain = $('#reportMain');
    reportMain.removeClass("hidden");
    spinner.spin(document.getElementById('reportMain'));
    $.ajax({
        type: "GET",
        contentType: "application/json; charset=utf-8",
        url: server_base + "rest/report/" + token + "/" + reportId + "/details",
        success: function (msg)
        {
            if (msg.error)
            {
                ajaxFail(null, null, msg.error);
            }
            if (msg.extra.reportName)
            {
                $("#reportTitle").text(msg.extra.reportName);
            }
            if (msg.extra.description)
            {
                $("#reportDescription").text(msg.extra.description);
            }
            var reportImage = $("#reportImage");
            if (msg.extra.image)
            {
                reportImage.prop('src', msg.extra.image);
                reportImage.removeClass("hidden");
            } else {
                reportImage.addClass("hidden");
            }
            var reportTableHeader = $("#reportTableHeader");
            var reportTableBody = $("#reportTableBody");
            var templateTr = reportTableHeader.find("tr").clone();
            templateTr.removeClass("hidden");
            reportTableHeader.append(templateTr);
            msg.columns.forEach(function (column)
            {
                var templateTh = templateTr.find("th.hidden").clone();
                templateTh.text(column.name);
                templateTh.removeClass("hidden");
                templateTr.append(templateTh);
                var templateRow = reportTableBody.find("tr.hidden");
                templateRow.removeClass("hidden");
                var templateTd = templateRow.find("td.hidden").clone();
                templateTd.removeClass("hidden");
                templateRow.append(templateTd);
                templateTd.attr("name", column.name);
                if (column.styleType == "text")
                {
                } else if (column.styleType == "numbers")
                {
                }
                templateRow.addClass("hidden");
            });
            var paramPanel = $('#paramPanel');
            var inputParamFieldTemplate = $('#inputParamFieldTemplate');
            msg.params.forEach(function (param)
            {
                var template = inputParamFieldTemplate.clone();
                template.removeAttr("id");
                template.removeClass("hidden");
                template.addClass("parameterField");
                var label = template.find("label");
                label.text(param.name);
                var paramIdField = template.find("span[name='paramId']");
                paramIdField.text(param.id);
                var paramId = param.id + "Param";
                label.prop("for", paramId);
                var input = template.find("input");
                if ("number" == param.type.toLowerCase())
                {
                    input.prop("id", paramId);
                    input.prop("type", "number");
                    input.val(param.value);
                    input.prop("placeholder", param.placeholder);
                    input.addClass("parameterFieldInput");
                } else if ("boolean" == param.type.toLowerCase())
                {
                    var options = "<option value='' "+(param.value == "" ? "selected" : "")+">Select one</option>" +
                        "<option value='true' "+(param.value == "true" ? "selected" : "")+">Yes</option>" +
                        "<option value='false' "+(param.value == "false" ? "selected" : "")+">No</option>";
                    input.replaceWith("<select id='"+paramId+"' class=\"parameterFieldInput\">"+options+"</select>");
                } else if ("combo" == param.type.toLowerCase())
                {
                    var options = "<option value='' "+(param.value == "" ? "selected" : "")+">Select one</option>";
                    param.values.forEach(function (value)
                    {
                        options = options + "<option value='"+value+"' "+(param.value == value ? "selected" : "")+">"+value+"</option>";
                    });
                    input.replaceWith("<select id='"+paramId+"' class=\"parameterFieldInput\">"+options+"</select>");
                } else if ("manycombo" == param.type.toLowerCase())
                {
                    var options = "<option value='' "+(param.value == null || param.value.length == 0 ? "selected" : "")+">Select one</option>";
                    param.values.forEach(function (value)
                    {
                        options = options + "<option value='"+value+"' "+((param.value != null  && param.value.contains(value)) ? "selected" : "")+">"+value+"</option>";
                    });
                    input.replaceWith("<select id='"+paramId+"' class=\"parameterFieldInput\" multiple>"+options+"</select>");
                } else //if ("string" == param.type.toLowerCase())
                {
                    input.prop("id", paramId);
                    input.val(param.value);
                    input.prop("placeholder", param.placeholder);
                    input.addClass("parameterFieldInput");
                }
                var help = template.find("p[name='help']");
                help.text(param.help);
                template.insertBefore('#runReportButton');
            });
            spinner.stop();
            pageNumber = 1;
            curReport = reportId;
        }
    }).fail(ajaxFail);
}
function displayMain()
{
    resetDisplay();
    $('#kaguraMain').removeClass("hidden");
}
function displayContactUs()
{
    resetDisplay();
    $('#kaguraContactUs').removeClass("hidden");
}
function displayAbout()
{
    resetDisplay();
    $('#kaguraAbout').removeClass("hidden");
}
function exportReport(fileType, all)
{
    var values = "page=" + pageNumber;
    if (all)
    {
        values = values + "&allpages=true";
    } else {
        values = values + "&page=" + pageNumber;
    }
    values = values + "&" + buildParameters();
    window.open(server_base + "rest/report/" + token + "/" + curReport + "/export."+fileType+"?" + values);
}

function buildParameters() {
    var params = {};
    $('div.parameterField:not(.hidden)').each(function (index, divfield) {
        var param = $(divfield).find("span[name='paramId']").text();
        var value = $(divfield).find(".parameterFieldInput").val();
        params[param] = value;
    });
    var encParams = encodeURIComponent(JSON.stringify(params));
    return encParams;
}
function runReport()
{
    resetReport();
    spinner.stop();
    spinner.spin(document.getElementById('reportMain'));
    $('#reportPageNumber').text(pageNumber);
    var values = "page=" + pageNumber;
    var encParams = buildParameters();
    resetReport();
    $.ajax({
        type: "GET",
        url: server_base + "rest/report/" + token + "/" + curReport + "/run?" + values + "&parameters=" + encParams,
        success: function (msg)
        {
            var reportTableBody = $("#reportTableBody");
            var templateRow = reportTableBody.find("tr.hidden");
            msg.rows.forEach(function (row)
            {
                var rowInstance = templateRow.clone();
                rowInstance.removeClass("hidden");
                reportTableBody.append(rowInstance);
                rowInstance.find("td.hidden").remove();
                Object.keys(row).forEach(function (key)
                {
                    rowInstance.find("td[name='"+key+"']").text(row[key]);
                })
            });
            spinner.stop();
        }
    }).fail(ajaxFail);
}

function prevPage()
{
    pageNumber = Math.max(pageNumber - 1, 1);
    runReport();
}

function nextPage()
{
    pageNumber = pageNumber + 1;
    runReport();
}

function logout()
{
    setCookie("token", "",1);
    window.location = server_base + "index.jsp";
}

function ajaxFail(jqXHR, textStatus, errorThrown)
{
    if (errorThrown == "Not Found")
    {
        alert("Can not find reporting backend, please ensure report server is running.");
    } else if (errorThrown == "Authentication failure")
    {
        alert("Session expired.");
        logout();
    } else {
        alert(errorThrown);
    }
}<commit_msg>Floating point numbers are now "numbers."<commit_after>var opts = {
    lines: 13, // The number of lines to draw
    length: 20, // The length of each line
    width: 10, // The line thickness
    radius: 30, // The radius of the inner circle
    corners: 1, // Corner roundness (0..1)
    rotate: 0, // The rotation offset
    direction: 1, // 1: clockwise, -1: counterclockwise
    color: '#000', // #rgb or #rrggbb or array of colors
    speed: 1, // Rounds per second
    trail: 60, // Afterglow percentage
    shadow: false, // Whether to render a shadow
    hwaccel: false, // Whether to use hardware acceleration
    className: 'spinner', // The CSS class to assign to the spinner
    zIndex: 2e9, // The z-index (defaults to 2000000000)
    top: 'auto', // Top position relative to parent in px
    left: 'auto' // Left position relative to parent in px
};
var spinner = new Spinner(opts);
var token;
var pageNumber = 1;
var curReport;

function loginSpin() {
    spinner.stop();
    $('#signinSection').find('input, button').prop("disabled", true);
    spinner.spin(document.getElementById('signinSection'));
}

function loginUnspin() {
    spinner.stop();
    $('#signinSection').find('input, button').prop("disabled", false);
}

function setToken(token) {
    this.token = token;
    var date = new Date();
    setCookie("token", token, date.getTime() + (2 * 24 * 60 * 60 * 1000));
}
function gotoMain()
{
    window.location.href = server_base + "main.jsp";
}
function doLogin()
{
    loginSpin();
    var user = $("#loginEmail").val();
    var password = $("#loginPassword").val();
    $.ajax({
        type: "POST",
        url: server_base + "rest/auth/login/" + user,
        data: password,
        contentType: "TEXT/PLAIN",
        success: function (msg)
        {
            loginUnspin();
            if (msg.error != "")
            {
                alert(msg.error);
            } else {
                setToken(msg.token);
                gotoMain();
            }
        }
        }).fail(function (jqXHR, textStatus, errorThrown)
            {
                loginUnspin();
                alert(errorThrown);
            });
}
function loadReportList() {
    token = getCookie("token");
    $.ajax({
        type: "GET",
        url: server_base + "rest/auth/reports/" + token,
        success: function (msg)
        {
            if (!msg.error)
            {
                loadReportListData(msg);
            } else {
                ajaxFail(null, null, msg.error);
            }
        }
    }).fail(ajaxFail);
};
function loadReportListData(data)
{
    var reportDDList = $("#reportDropdownList");
    reportDDList.find("li:not(.hidden)").remove();
    data.forEach(function (report)
    {
        var template = reportDDList.find("li.hidden").clone();
        template.removeClass("hidden");
        reportDDList.append(template);
        template.html(""+report+"");
    });
}
function resetDisplay() {
    $('#kaguraMain,#kaguraContactUs,#kaguraAbout,#reportMain').addClass("hidden");
}
function resetReportConfig()
{
    $('#reportTableHeader>tr:not(.hidden)').remove();
    $('#reportTableBody>tr:not(.hidden)').remove();
    $('#reportTableBody>tr>td:not(.hidden)').remove();
    $('#paramPanel>div:not(.hidden)').remove();
}
function resetReport()
{
    $('#reportTableBody>tr:not(.hidden)').remove();
}
function loadReport(reportId)
{
    resetDisplay();
    resetReportConfig();
    resetReport();
    $('#reportTitle').text(reportId);
    spinner.stop();
    var reportMain = $('#reportMain');
    reportMain.removeClass("hidden");
    spinner.spin(document.getElementById('reportMain'));
    $.ajax({
        type: "GET",
        contentType: "application/json; charset=utf-8",
        url: server_base + "rest/report/" + token + "/" + reportId + "/details",
        success: function (msg)
        {
            if (msg.error)
            {
                ajaxFail(null, null, msg.error);
            }
            if (msg.extra.reportName)
            {
                $("#reportTitle").text(msg.extra.reportName);
            }
            if (msg.extra.description)
            {
                $("#reportDescription").text(msg.extra.description);
            }
            var reportImage = $("#reportImage");
            if (msg.extra.image)
            {
                reportImage.prop('src', msg.extra.image);
                reportImage.removeClass("hidden");
            } else {
                reportImage.addClass("hidden");
            }
            var reportTableHeader = $("#reportTableHeader");
            var reportTableBody = $("#reportTableBody");
            var templateTr = reportTableHeader.find("tr").clone();
            templateTr.removeClass("hidden");
            reportTableHeader.append(templateTr);
            msg.columns.forEach(function (column)
            {
                var templateTh = templateTr.find("th.hidden").clone();
                templateTh.text(column.name);
                templateTh.removeClass("hidden");
                templateTr.append(templateTh);
                var templateRow = reportTableBody.find("tr.hidden");
                templateRow.removeClass("hidden");
                var templateTd = templateRow.find("td.hidden").clone();
                templateTd.removeClass("hidden");
                templateRow.append(templateTd);
                templateTd.attr("name", column.name);
                if (column.styleType == "text")
                {
                } else if (column.styleType == "numbers")
                {
                }
                templateRow.addClass("hidden");
            });
            var paramPanel = $('#paramPanel');
            var inputParamFieldTemplate = $('#inputParamFieldTemplate');
            msg.params.forEach(function (param)
            {
                var template = inputParamFieldTemplate.clone();
                template.removeAttr("id");
                template.removeClass("hidden");
                template.addClass("parameterField");
                var label = template.find("label");
                label.text(param.name);
                var paramIdField = template.find("span[name='paramId']");
                paramIdField.text(param.id);
                var paramId = param.id + "Param";
                label.prop("for", paramId);
                var input = template.find("input");
                if ("number" == param.type.toLowerCase())
                {
                    input.prop("id", paramId);
                    input.prop("type", "number");
                    input.prop("step", "any");
                    input.val(param.value);
                    input.prop("placeholder", param.placeholder);
                    input.addClass("parameterFieldInput");
                } else if ("boolean" == param.type.toLowerCase())
                {
                    var options = "<option value='' "+(param.value == "" ? "selected" : "")+">Select one</option>" +
                        "<option value='true' "+(param.value == "true" ? "selected" : "")+">Yes</option>" +
                        "<option value='false' "+(param.value == "false" ? "selected" : "")+">No</option>";
                    input.replaceWith("<select id='"+paramId+"' class=\"parameterFieldInput\">"+options+"</select>");
                } else if ("combo" == param.type.toLowerCase())
                {
                    var options = "<option value='' "+(param.value == "" ? "selected" : "")+">Select one</option>";
                    param.values.forEach(function (value)
                    {
                        options = options + "<option value='"+value+"' "+(param.value == value ? "selected" : "")+">"+value+"</option>";
                    });
                    input.replaceWith("<select id='"+paramId+"' class=\"parameterFieldInput\">"+options+"</select>");
                } else if ("manycombo" == param.type.toLowerCase())
                {
                    var options = "<option value='' "+(param.value == null || param.value.length == 0 ? "selected" : "")+">Select one</option>";
                    param.values.forEach(function (value)
                    {
                        options = options + "<option value='"+value+"' "+((param.value != null  && param.value.contains(value)) ? "selected" : "")+">"+value+"</option>";
                    });
                    input.replaceWith("<select id='"+paramId+"' class=\"parameterFieldInput\" multiple>"+options+"</select>");
                } else //if ("string" == param.type.toLowerCase())
                {
                    input.prop("id", paramId);
                    input.val(param.value);
                    input.prop("placeholder", param.placeholder);
                    input.addClass("parameterFieldInput");
                }
                var help = template.find("p[name='help']");
                help.text(param.help);
                template.insertBefore('#runReportButton');
            });
            spinner.stop();
            pageNumber = 1;
            curReport = reportId;
        }
    }).fail(ajaxFail);
}
function displayMain()
{
    resetDisplay();
    $('#kaguraMain').removeClass("hidden");
}
function displayContactUs()
{
    resetDisplay();
    $('#kaguraContactUs').removeClass("hidden");
}
function displayAbout()
{
    resetDisplay();
    $('#kaguraAbout').removeClass("hidden");
}
function exportReport(fileType, all)
{
    var values = "page=" + pageNumber;
    if (all)
    {
        values = values + "&allpages=true";
    } else {
        values = values + "&page=" + pageNumber;
    }
    values = values + "&" + buildParameters();
    window.open(server_base + "rest/report/" + token + "/" + curReport + "/export."+fileType+"?" + values);
}

function buildParameters() {
    var params = {};
    $('div.parameterField:not(.hidden)').each(function (index, divfield) {
        var param = $(divfield).find("span[name='paramId']").text();
        var value = $(divfield).find(".parameterFieldInput").val();
        params[param] = value;
    });
    var encParams = encodeURIComponent(JSON.stringify(params));
    return encParams;
}
function runReport()
{
    resetReport();
    spinner.stop();
    spinner.spin(document.getElementById('reportMain'));
    $('#reportPageNumber').text(pageNumber);
    var values = "page=" + pageNumber;
    var encParams = buildParameters();
    resetReport();
    $.ajax({
        type: "GET",
        url: server_base + "rest/report/" + token + "/" + curReport + "/run?" + values + "&parameters=" + encParams,
        success: function (msg)
        {
            var reportTableBody = $("#reportTableBody");
            var templateRow = reportTableBody.find("tr.hidden");
            msg.rows.forEach(function (row)
            {
                var rowInstance = templateRow.clone();
                rowInstance.removeClass("hidden");
                reportTableBody.append(rowInstance);
                rowInstance.find("td.hidden").remove();
                Object.keys(row).forEach(function (key)
                {
                    rowInstance.find("td[name='"+key+"']").text(row[key]);
                })
            });
            spinner.stop();
        }
    }).fail(ajaxFail);
}

function prevPage()
{
    pageNumber = Math.max(pageNumber - 1, 1);
    runReport();
}

function nextPage()
{
    pageNumber = pageNumber + 1;
    runReport();
}

function logout()
{
    setCookie("token", "",1);
    window.location = server_base + "index.jsp";
}

function ajaxFail(jqXHR, textStatus, errorThrown)
{
    if (errorThrown == "Not Found")
    {
        alert("Can not find reporting backend, please ensure report server is running.");
    } else if (errorThrown == "Authentication failure")
    {
        alert("Session expired.");
        logout();
    } else {
        alert(errorThrown);
    }
}<|endoftext|>


<commit_before>var express = require("express");
var app = express();
var passport = require('passport');
var FacebookStrategy = require('passport-facebook').Strategy;

app.configure(function() {
  app.use(express.static('public'));
  app.use(express.cookieParser());
  app.use(express.bodyParser());
  app.use(express.session({ secret: process.env.SUPER_SECRET_SESSIONS_KEY}));
  app.use(passport.initialize());
  app.use(passport.session());
  app.use(app.router);
});

passport.use(new FacebookStrategy({
    clientID: process.env.FACEBOOK_APP_ID,
    clientSecret: process.env.FACEBOOK_APP_SECRET,
    callbackURL: "http://energiesbalanced.herokuapp.com/auth/facebook/callback"
  },
  function(accessToken, refreshToken, profile, done) {
    done(null, profile);
  }
));

passport.serializeUser(function(user, done) {
  done(null, user);
});

passport.deserializeUser(function(user, done) {
    done(null, user);
});

app.get('/session', function(req, response){
  response.send({session: req.session});
});

// Redirect the user to Facebook for authentication.  When complete,
// Facebook will redirect the user back to the application at
//     /auth/facebook/callback
app.get('/auth/facebook', passport.authenticate('facebook'));

// Facebook will redirect the user to this URL after approval.  Finish the
// authentication process by attempting to obtain an access token.  If
// access was granted, the user will be logged in.  Otherwise,
// authentication has failed.
app.get('/auth/facebook/callback',
  passport.authenticate('facebook', {
  	successRedirect: '/',
    failureRedirect: '/login'
  }, function(req, resp){
  	   console.log("auth successful");
  }));

app.use(express.logger());
app.use(express.static(__dirname + '/public'));
var port = process.env.PORT || 5000;
app.listen(port, function() {
  console.log("Listening on " + port);
});<commit_msg>fix fb auth 4<commit_after>var express = require("express");
var app = express();
var passport = require('passport');
var FacebookStrategy = require('passport-facebook').Strategy;

app.configure(function() {
  app.use(express.static('public'));
  app.use(express.cookieParser());
  app.use(express.bodyParser());
  app.use(express.session({ secret: process.env.SUPER_SECRET_SESSIONS_KEY}));
  app.use(passport.initialize());
  app.use(passport.session());
  app.use(app.router);
});

passport.use(new FacebookStrategy({
    clientID: process.env.FACEBOOK_APP_ID,
    clientSecret: process.env.FACEBOOK_APP_SECRET,
    callbackURL: "http://energiesbalanced.herokuapp.com/auth/facebook/callback"
  },
  function(accessToken, refreshToken, profile, done) {
    done(null, profile);
  }
));

passport.serializeUser(function(user, done) {
  done(null, user);
});

passport.deserializeUser(function(user, done) {
    done(null, user);
});

app.get('/session', function(req, response){
  response.send({session: req.session});
});

// Redirect the user to Facebook for authentication.  When complete,
// Facebook will redirect the user back to the application at
//     /auth/facebook/callback
app.get('/auth/facebook', passport.authenticate('facebook'));

// Facebook will redirect the user to this URL after approval.  Finish the
// authentication process by attempting to obtain an access token.  If
// access was granted, the user will be logged in.  Otherwise,
// authentication has failed.
app.get('/auth/facebook/callback',
  passport.authenticate('facebook', {
  	successRedirect: '/',
    failureRedirect: '/login'
  }));

app.use(express.logger());
app.use(express.static(__dirname + '/public'));
var port = process.env.PORT || 5000;
app.listen(port, function() {
  console.log("Listening on " + port);
});<|endoftext|>