<commit_before>/*
Copyright (c) 2014, EDINA.
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this
   list of conditions and the following disclaimer in the documentation and/or
   other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software must
   display the following acknowledgement: This product includes software
   developed by the EDINA.
4. Neither the name of the EDINA nor the names of its contributors may be used to
   endorse or promote products derived from this software without specific prior
   written permission.

THIS SOFTWARE IS PROVIDED BY EDINA ''AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL EDINA BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
*/

"use strict";

/* global Connection */

define(['ui', 'map', 'utils', './cache', './database'], function(// jshint ignore:line
    ui, map, utils, cache, webdb){
    var MAX_NO_OF_SAVED_MAPS = 3;

    /**
     * Map with local storage caching.
     * @params options:
     *   url - TMS URL
     */
    var getMapWithLocalStorage = function(url){
        var layer;
        if(url === undefined){
            url = utils.getMapSettings().url;
        }
        if(map.isBaseLayerTMS()){
            layer = new FGBMapWithLocalStorage({url: map.getTMSURL(url)});
        }
        else{
            layer = new OSMMapWithLocalStorage({
                url: url+'/${z}/${x}/${y}.png'
            });
        }

        return layer;
    };

    /**
     * FGB Map with local storage caching.
     * @params options:
     *   url - TMS URL
     */
    var FGBMapWithLocalStorage = OpenLayers.Class(OpenLayers.Layer.TMS, {
        initialize: function(options) {
            var baseLayer = map.getBaseLayer();
            this.serviceVersion = baseLayer.serviceVersion;
            this.layername = baseLayer.layername;
            this.type = baseLayer.type;

            // this boolean determines which overriden method is called getURLasync
            // or getURL. Using getURLasync was causing the application to freeze,
            // often getting a ANR
            this.async = typeof(webdb) !== 'undefined';

            this.isBaseLayer = true;
            OpenLayers.Layer.TMS.prototype.initialize.apply(
                this,
                [baseLayer.name, options.url, {}]
            );
        },
        getURLasync: function(bounds, callback, scope) {
            var url = OpenLayers.Layer.TMS.prototype.getURL.apply(this, [bounds]);
            var data = url.match(/\/(\d+)/g).join("").split("/");
            webdb.getCachedTilePath( callback, scope, data[2], data[3] , data[1], url);
        },
        getURL: function(bounds) {
            return OpenLayers.Layer.TMS.prototype.getURL.apply(this, [bounds]);
        },
    });

    /**
     * OSM Map with local storage caching.
     * @params options:
     *     url            - TMS URL
     */
    var OSMMapWithLocalStorage = OpenLayers.Class(OpenLayers.Layer.OSM, {
        initialize: function(options) {

            // this boolean determines which overriden method is called getURLasync
            // or getURL. Using getURLasync was causing the application to freeze,
            // often getting a ANR
            this.async = typeof(webdb) !== 'undefined';
            this.type = 'png';
            if (options.url === "undefined/${z}/${x}/${y}.png") {
                this.url = [
                    'http://a.tile.openstreetmap.org/${z}/${x}/${y}.png',
                    'http://b.tile.openstreetmap.org/${z}/${x}/${y}.png',
                    'http://c.tile.openstreetmap.org/${z}/${x}/${y}.png'
                ];
            }
            else{
                this.url = [
                    options.url,
                    options.url.replace("a.", "b."),
                    options.url.replace("a.", "c.")
                ];
            }

            OpenLayers.Layer.OSM.prototype.initialize.apply(
                this,
                []
            );
        },
        getURLasync: function(bounds, callback, scope) {
            var url = OpenLayers.Layer.OSM.prototype.getURL.apply(this, [bounds]);
            var urlData = OpenLayers.Layer.XYZ.prototype.getXYZ.apply(this, [bounds]);
            webdb.getCachedTilePath( callback, scope, urlData.x, urlData.y , urlData.z, url);
        }
    });

    // create layer on map for showing saved map extent
    var savedMapsLayer = map.addLayer({
        id: 'savedMaps',
        style:{colour: 'red'},
        visible:false
    });

    /**
     * Show saved maps screen.
     */
    var offlineMapsPage = function(){
        var maps = cache.getSavedMaps();
        var selectedSavedMap;
        var count = 0;

        ui.mapPage('saved-maps-map');

        if(maps){
            // build saved maps list
            $.each(maps, function(index, value){
                /*jshint multistr: true */
                $('#saved-maps-list-list').append(
                    '
<fieldset class="ui-grid-b"> \

\
                         \

' + index + '
\

\

\

\

\

\
                       </fieldset>\

').trigger('create');
                ++count;
            });
        }

        if(count === 0){
            $('#saved-maps-list').html('
No saved maps - go to Download to create saved maps
');
        }
        else if(count < MAX_NO_OF_SAVED_MAPS){
            $('#saved-maps-list').append('
Download more maps
');
        }

        // display a saved map on main map
        var displayOnMap = function(){
            var name = selectedSavedMap.find('h3').text();
            var details = cache.getSavedMapDetails(name);
            if(details){
                map.showBBox({
                    'layer': savedMapsLayer,
                    'bounds': details.bounds,
                    'poi': details.poi
                });
            }
        };

        // context menu popup
        $('#saved-maps-list-popup').bind({
            // populate popup with map name
            popupafteropen: $.proxy(function(event, ui) {
                selectedSavedMap.toBeDeleted = false;
                $('#saved-maps-list-popup [data-role="divider"]').text(
                    selectedSavedMap.find('h3').text());
            }, this),
            popupafterclose: $.proxy(function() {
                if(selectedSavedMap.toBeDeleted){
                    // this hack is in the documentation for chaining popups:
                    // http://jquerymobile.com/demos/1.2.0/docs/pages/popup/index.html
                    setTimeout( function(){
                        $('#saved-maps-delete-popup').popup('open');
                    }, 100);
                }
            }, this)
        });

        $('#saved-maps-list-popup-view').click(function(event){
            // view selected
            $.mobile.changePage('map.html');
            displayOnMap();
        });
        $('#saved-maps-list-popup-delete').click($.proxy(function(event){
            // delete selected
            selectedSavedMap.toBeDeleted = true;
            $('#saved-maps-list-popup').popup('close');
        }, this));
        $('#saved-maps-delete-popup').bind({
            // populate delete dialog with map name
            popupafteropen: $.proxy(function(event, ui) {
                $('#saved-maps-delete-popup-name').text(
                    selectedSavedMap.find('h3').text());
            }, this)
        });
        $('#saved-maps-delete-popup-confirm').click($.proxy(function(event){
            // confirm map delete
            cache.deleteSavedMapDetails(selectedSavedMap.find('h3').text());
            map.removeAllFeatures(savedMapsLayer);
            $('#saved-maps-delete-popup').popup("close");
            $(selectedSavedMap).slideUp('slow');
        }, this));

        // click on a saved map
        var taphold = false;
        $('.saved-map-click').on(
            'tap',
            function(event){
                if(!taphold){
                    selectedSavedMap = $(event.target).parents('li');
                    displayOnMap();
                }
                else{
                    // taphold has been lifted
                    taphold = false;

                    // prevent popup dialog closing
                    event.preventDefault();
                }
            }
        );

        // press and hold on a saved map
        $('.saved-map-click').on(
            'taphold',
            function(event){
                selectedSavedMap = $(event.target).parents('li');
                $('#saved-maps-list-popup').popup('open', {positionTo: 'origin'});
                taphold = true;
            }
        );

        // make map list scrollable on touch screens
        utils.touchScroll('#saved-maps-list');

        $('#saved-maps-list-list').listview('refresh');

        // show first map on list
        selectedSavedMap = $('#saved-maps-list li:first');
        displayOnMap();

        savedMapsLayer.setVisibility(true);
    };

    /**
     * Save Map Name dialog.
     */
    var saveMapNamePage = function(){
        var dlSize = cache.totalNumberOfTilesToDownload(
            map.getZoomLevels().current,
            $('#saved-map-name-dialog-save-to').val()) * cache.AV_TILE_SIZE;

        var saveMap = false;

        $('#save-map-name-dialog-info').html(
            '
' + $('#cache-save-details-text-stats').text() + '
');

        $('#saved-map-name-dialog-text').val(new Date().toLocaleString().substr(0, 24));
        $('#saved-map-name-dialog-save-to').val($("#cache-slider").val());
        $('#saved-map-name-dialog-btn').click($.proxy(function(){
            $('.ui-dialog').dialog('close');
            saveMap = true;
        }, this));

        // use pageremove on save map name screen otherwise attaching the
        // showPageLoadingMsg to the page is problematic
        $('#save-map-name-dialog').on(
            'pageremove',
            function(){
                if(saveMap){
                    if(cache.saveMap($('#saved-map-name-dialog-text').val(),
                                     map.getZoomLevels().current,
                                     $('#saved-map-name-dialog-save-to').val())){
                    }
                }
            }
        );
    };

    /**
     * Initialise save map page.
     */
    var saveMapPage = function(){
        $('#cache-slider').bind(
            'change',
            $.proxy(cache.previewImagesChange, cache));
        $('#cache-save-slider .ui-slider-handle').bind(
            'vmousedown',
            $.proxy(cache.previewImagesMouseDown, cache));
        $('#cache-save-slider .ui-slider-handle').bind(
            'vmouseup',
            $.proxy(cache.previewImagesMouseUp, cache));

        map.removeAllFeatures(savedMapsLayer);

        $('#cache-controls').hide();
        $('#cache-preview').hide();
        $('#save-map-buttons').show();

        map.hideAnnotateLayer();
        map.hideRecordsLayer();

        var connection = utils.getConnectionStatus();
        if(utils.isMobileApp &&
           (connection.val === Connection.UNKNOWN ||
            connection.val === Connection.CELL_2G ||
            connection.val === Connection.NONE)){
            console.debug('current connection: ' + connection.str);
            utils.inform("You will need a decent network connection to use this functionality.");
        }

        $('#save-map-buttons-ok').click(function(){
            $('#cache-controls').show();
            $('#save-map-buttons').hide();
        });

        // initialise slider values according to zoom level
        setSliderValues();

        map.registerZoom(function(){
            setSliderValues();
        }, this);

        $('#cache-save-details-zoom-level-but').val('1');

        if(cache.getSavedMapsCount() < MAX_NO_OF_SAVED_MAPS){
            $('#save-map-buttons-ok').removeClass('ui-disabled');
        }
        else{
            $('#save-map-buttons-ok').addClass('ui-disabled');

            setTimeout(function(){
                utils.inform('You have reached the maximum number of saved maps.');
            }, 1000);
        }

        // attach map to save-map-map div
        ui.mapPage('save-map-map');
    };

    /**
     * Set cache slider values depending on map resolution.
     */
    var setSliderValues = function(){
        var zooms = map.getZoomLevels();

        if(zooms.current === zooms.max){
            $('#cache-slider').slider("disable");
        }
        else{
            $('#cache-slider').slider("enable");
        }

        $('#cache-slider').attr('min', zooms.current);
        $('#cache-slider').attr('max', zooms.max);
        $("#cache-save-slider input").val(zooms.current).slider("refresh");

        cache.setSaveStats(zooms.current, zooms.current);
    };

    if(typeof(webdb) !== 'undefined'){
        if(localStorage.getItem(webdb.DATABASE_CREATED) !== "true"){
            webdb.createTablesIfRequired();
        }
    }

    $(document).on('pageinit', '#saved-maps-page', offlineMapsPage);
    $(document).on('pageshow', '#saved-maps-page', function(){
        map.updateSize();
    });

    $(document).on('pageshow', '#save-map-page', saveMapPage);
    $(document).on('pageinit', '#save-map-name-dialog', saveMapNamePage);

    // adding stylesheet to beginning of head
    $('head').prepend('<link rel="stylesheet" href="plugins/offline-maps/css/style.css" type="text/css" />');

    $(document).on('change', '#settings-mapserver-url', function(){
        map.switchBaseLayer(
            getMapWithLocalStorage(
                $('#settings-mapserver-url option:selected').val())
        );
    });

    map.switchBaseLayer(getMapWithLocalStorage(utils.getMapServerUrl()));
});
<commit_msg>Update navigation events to jquery mobile 1.4 ref: http://jquerymobile.com/upgrade-guide/1.4/#navigation<commit_after>/*
Copyright (c) 2014, EDINA.
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this
   list of conditions and the following disclaimer in the documentation and/or
   other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software must
   display the following acknowledgement: This product includes software
   developed by the EDINA.
4. Neither the name of the EDINA nor the names of its contributors may be used to
   endorse or promote products derived from this software without specific prior
   written permission.

THIS SOFTWARE IS PROVIDED BY EDINA ''AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL EDINA BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
*/

"use strict";

/* global Connection */

define(['ui', 'map', 'utils', './cache', './database'], function(// jshint ignore:line
    ui, map, utils, cache, webdb){
    var MAX_NO_OF_SAVED_MAPS = 3;

    /**
     * Map with local storage caching.
     * @params options:
     *   url - TMS URL
     */
    var getMapWithLocalStorage = function(url){
        var layer;
        if(url === undefined){
            url = utils.getMapSettings().url;
        }
        if(map.isBaseLayerTMS()){
            layer = new FGBMapWithLocalStorage({url: map.getTMSURL(url)});
        }
        else{
            layer = new OSMMapWithLocalStorage({
                url: url+'/${z}/${x}/${y}.png'
            });
        }

        return layer;
    };

    /**
     * FGB Map with local storage caching.
     * @params options:
     *   url - TMS URL
     */
    var FGBMapWithLocalStorage = OpenLayers.Class(OpenLayers.Layer.TMS, {
        initialize: function(options) {
            var baseLayer = map.getBaseLayer();
            this.serviceVersion = baseLayer.serviceVersion;
            this.layername = baseLayer.layername;
            this.type = baseLayer.type;

            // this boolean determines which overriden method is called getURLasync
            // or getURL. Using getURLasync was causing the application to freeze,
            // often getting a ANR
            this.async = typeof(webdb) !== 'undefined';

            this.isBaseLayer = true;
            OpenLayers.Layer.TMS.prototype.initialize.apply(
                this,
                [baseLayer.name, options.url, {}]
            );
        },
        getURLasync: function(bounds, callback, scope) {
            var url = OpenLayers.Layer.TMS.prototype.getURL.apply(this, [bounds]);
            var data = url.match(/\/(\d+)/g).join("").split("/");
            webdb.getCachedTilePath( callback, scope, data[2], data[3] , data[1], url);
        },
        getURL: function(bounds) {
            return OpenLayers.Layer.TMS.prototype.getURL.apply(this, [bounds]);
        },
    });

    /**
     * OSM Map with local storage caching.
     * @params options:
     *     url            - TMS URL
     */
    var OSMMapWithLocalStorage = OpenLayers.Class(OpenLayers.Layer.OSM, {
        initialize: function(options) {

            // this boolean determines which overriden method is called getURLasync
            // or getURL. Using getURLasync was causing the application to freeze,
            // often getting a ANR
            this.async = typeof(webdb) !== 'undefined';
            this.type = 'png';
            if (options.url === "undefined/${z}/${x}/${y}.png") {
                this.url = [
                    'http://a.tile.openstreetmap.org/${z}/${x}/${y}.png',
                    'http://b.tile.openstreetmap.org/${z}/${x}/${y}.png',
                    'http://c.tile.openstreetmap.org/${z}/${x}/${y}.png'
                ];
            }
            else{
                this.url = [
                    options.url,
                    options.url.replace("a.", "b."),
                    options.url.replace("a.", "c.")
                ];
            }

            OpenLayers.Layer.OSM.prototype.initialize.apply(
                this,
                []
            );
        },
        getURLasync: function(bounds, callback, scope) {
            var url = OpenLayers.Layer.OSM.prototype.getURL.apply(this, [bounds]);
            var urlData = OpenLayers.Layer.XYZ.prototype.getXYZ.apply(this, [bounds]);
            webdb.getCachedTilePath( callback, scope, urlData.x, urlData.y , urlData.z, url);
        }
    });

    // create layer on map for showing saved map extent
    var savedMapsLayer = map.addLayer({
        id: 'savedMaps',
        style:{colour: 'red'},
        visible:false
    });

    /**
     * Show saved maps screen.
     */
    var offlineMapsPage = function(){
        var maps = cache.getSavedMaps();
        var selectedSavedMap;
        var count = 0;

        ui.mapPage('saved-maps-map');

        if(maps){
            // build saved maps list
            $.each(maps, function(index, value){
                /*jshint multistr: true */
                $('#saved-maps-list-list').append(
                    '
<fieldset class="ui-grid-b"> \

\
                         \

' + index + '
\

\

\

\

\

\
                       </fieldset>\

').trigger('create');
                ++count;
            });
        }

        if(count === 0){
            $('#saved-maps-list').html('
No saved maps - go to Download to create saved maps
');
        }
        else if(count < MAX_NO_OF_SAVED_MAPS){
            $('#saved-maps-list').append('
Download more maps
');
        }

        // display a saved map on main map
        var displayOnMap = function(){
            var name = selectedSavedMap.find('h3').text();
            var details = cache.getSavedMapDetails(name);
            if(details){
                map.showBBox({
                    'layer': savedMapsLayer,
                    'bounds': details.bounds,
                    'poi': details.poi
                });
            }
        };

        // context menu popup
        $('#saved-maps-list-popup').bind({
            // populate popup with map name
            popupafteropen: $.proxy(function(event, ui) {
                selectedSavedMap.toBeDeleted = false;
                $('#saved-maps-list-popup [data-role="divider"]').text(
                    selectedSavedMap.find('h3').text());
            }, this),
            popupafterclose: $.proxy(function() {
                if(selectedSavedMap.toBeDeleted){
                    // this hack is in the documentation for chaining popups:
                    // http://jquerymobile.com/demos/1.2.0/docs/pages/popup/index.html
                    setTimeout( function(){
                        $('#saved-maps-delete-popup').popup('open');
                    }, 100);
                }
            }, this)
        });

        $('#saved-maps-list-popup-view').click(function(event){
            // view selected
            $.mobile.changePage('map.html');
            displayOnMap();
        });
        $('#saved-maps-list-popup-delete').click($.proxy(function(event){
            // delete selected
            selectedSavedMap.toBeDeleted = true;
            $('#saved-maps-list-popup').popup('close');
        }, this));
        $('#saved-maps-delete-popup').bind({
            // populate delete dialog with map name
            popupafteropen: $.proxy(function(event, ui) {
                $('#saved-maps-delete-popup-name').text(
                    selectedSavedMap.find('h3').text());
            }, this)
        });
        $('#saved-maps-delete-popup-confirm').click($.proxy(function(event){
            // confirm map delete
            cache.deleteSavedMapDetails(selectedSavedMap.find('h3').text());
            map.removeAllFeatures(savedMapsLayer);
            $('#saved-maps-delete-popup').popup("close");
            $(selectedSavedMap).slideUp('slow');
        }, this));

        // click on a saved map
        var taphold = false;
        $('.saved-map-click').on(
            'tap',
            function(event){
                if(!taphold){
                    selectedSavedMap = $(event.target).parents('li');
                    displayOnMap();
                }
                else{
                    // taphold has been lifted
                    taphold = false;

                    // prevent popup dialog closing
                    event.preventDefault();
                }
            }
        );

        // press and hold on a saved map
        $('.saved-map-click').on(
            'taphold',
            function(event){
                selectedSavedMap = $(event.target).parents('li');
                $('#saved-maps-list-popup').popup('open', {positionTo: 'origin'});
                taphold = true;
            }
        );

        // make map list scrollable on touch screens
        utils.touchScroll('#saved-maps-list');

        $('#saved-maps-list-list').listview('refresh');

        // show first map on list
        selectedSavedMap = $('#saved-maps-list li:first');
        displayOnMap();

        savedMapsLayer.setVisibility(true);
    };

    /**
     * Save Map Name dialog.
     */
    var saveMapNamePage = function(){
        var dlSize = cache.totalNumberOfTilesToDownload(
            map.getZoomLevels().current,
            $('#saved-map-name-dialog-save-to').val()) * cache.AV_TILE_SIZE;

        var saveMap = false;

        $('#save-map-name-dialog-info').html(
            '
' + $('#cache-save-details-text-stats').text() + '
');

        $('#saved-map-name-dialog-text').val(new Date().toLocaleString().substr(0, 24));
        $('#saved-map-name-dialog-save-to').val($("#cache-slider").val());
        $('#saved-map-name-dialog-btn').click($.proxy(function(){
            $('.ui-dialog').dialog('close');
            saveMap = true;
        }, this));

        // use pageremove on save map name screen otherwise attaching the
        // showPageLoadingMsg to the page is problematic
        $('#save-map-name-dialog').on(
            'pagecontainerremove',
            function(){
                if(saveMap){
                    if(cache.saveMap($('#saved-map-name-dialog-text').val(),
                                     map.getZoomLevels().current,
                                     $('#saved-map-name-dialog-save-to').val())){
                    }
                }
            }
        );
    };

    /**
     * Initialise save map page.
     */
    var saveMapPage = function(){
        $('#cache-slider').bind(
            'change',
            $.proxy(cache.previewImagesChange, cache));
        $('#cache-save-slider .ui-slider-handle').bind(
            'vmousedown',
            $.proxy(cache.previewImagesMouseDown, cache));
        $('#cache-save-slider .ui-slider-handle').bind(
            'vmouseup',
            $.proxy(cache.previewImagesMouseUp, cache));

        map.removeAllFeatures(savedMapsLayer);

        $('#cache-controls').hide();
        $('#cache-preview').hide();
        $('#save-map-buttons').show();

        map.hideAnnotateLayer();
        map.hideRecordsLayer();

        var connection = utils.getConnectionStatus();
        if(utils.isMobileApp &&
           (connection.val === Connection.UNKNOWN ||
            connection.val === Connection.CELL_2G ||
            connection.val === Connection.NONE)){
            console.debug('current connection: ' + connection.str);
            utils.inform("You will need a decent network connection to use this functionality.");
        }

        $('#save-map-buttons-ok').click(function(){
            $('#cache-controls').show();
            $('#save-map-buttons').hide();
        });

        // initialise slider values according to zoom level
        setSliderValues();

        map.registerZoom(function(){
            setSliderValues();
        }, this);

        $('#cache-save-details-zoom-level-but').val('1');

        if(cache.getSavedMapsCount() < MAX_NO_OF_SAVED_MAPS){
            $('#save-map-buttons-ok').removeClass('ui-disabled');
        }
        else{
            $('#save-map-buttons-ok').addClass('ui-disabled');

            setTimeout(function(){
                utils.inform('You have reached the maximum number of saved maps.');
            }, 1000);
        }

        // attach map to save-map-map div
        ui.mapPage('save-map-map');
    };

    /**
     * Set cache slider values depending on map resolution.
     */
    var setSliderValues = function(){
        var zooms = map.getZoomLevels();

        if(zooms.current === zooms.max){
            $('#cache-slider').slider("disable");
        }
        else{
            $('#cache-slider').slider("enable");
        }

        $('#cache-slider').attr('min', zooms.current);
        $('#cache-slider').attr('max', zooms.max);
        $("#cache-save-slider input").val(zooms.current).slider("refresh");

        cache.setSaveStats(zooms.current, zooms.current);
    };

    if(typeof(webdb) !== 'undefined'){
        if(localStorage.getItem(webdb.DATABASE_CREATED) !== "true"){
            webdb.createTablesIfRequired();
        }
    }

    $(document).on('pagecreate', '#saved-maps-page', offlineMapsPage);
    $(document).on('pagecontainershow', '#saved-maps-page', function(){
        map.updateSize();
    });

    $(document).on('pagecontainershow', '#save-map-page', saveMapPage);
    $(document).on('pagecreate', '#save-map-name-dialog', saveMapNamePage);

    // adding stylesheet to beginning of head
    $('head').prepend('<link rel="stylesheet" href="plugins/offline-maps/css/style.css" type="text/css" />');

    $('body').pagecontainer('change', '#settings-mapserver-url', function(){
        map.switchBaseLayer(
            getMapWithLocalStorage(
                $('#settings-mapserver-url option:selected').val())
        );
    });

    map.switchBaseLayer(getMapWithLocalStorage(utils.getMapServerUrl()));
});
<|endoftext|>


<commit_before>require('backbone-base');
require('backbone-forms');

var
  _ = require('lodash'),
  backbone = require('backbone'),
  DataFilesEditor = require('./data-files-editor'),
  NameEditor = require('./name-editor'),
  ValidationReportView = require('./validation-report'),
  UploadView = require('./upload');

module.exports = backbone.BaseView.extend(backbone.Form.prototype).extend({
  activate: function(state) {
    backbone.BaseView.prototype.activate.call(this, state);

    if((_.isUndefined(state) || state) && _.isEmpty(this.layout))
      this.render();

    // Do not allow chuld view (upload widget) to change parent — just catch its events
    this.layout.upload.on('upload-started', this.loading, this);

    this.layout.upload.on('parse-complete', function(csvData) {
      this.fields.files.setValue((this.fields.files.getValue() || []).concat(csvData))
      this.loading(false);
    }, this);

    return this;
  },

  events: {
    'click [data-id=create]': function() { this.validate(); return false; }
  },

  initialize: function(options) {
    backbone.BaseView.prototype.initialize.call(this, options);
    backbone.Form.prototype.initialize.call(this, options);
  },

  loading: function(state) {
    var
      isLoading = _.isUndefined(state) || state;

    this.$('[data-id=submit]').toggleClass('form-button--loading', isLoading);
    this.$('[data-id=upload-in-progress]').prop('hidden', !isLoading);
    this.$('[data-id=create]').prop('hidden', isLoading);
    return this;
  },

  render: function() {
    backbone.Form.prototype.render.call(this);
    this.layout.upload = (new UploadView({el: this.$('[data-id=upload]'), parent: this})).render();

    this.layout.validationReport = (new ValidationReportView({
      container: '[data-id=content]',
      el: this.$('[data-id="validation-report"]')
    })).render();

    return this;
  },

  schema: {
    name: {
      label: 'Name your Data Package',
      type: NameEditor,
      validators: [{type: 'required', message: 'Your data package should have a name'}],
      urlBase: 'https://openspending.org/'
    },

    files: {
      type: DataFilesEditor,
      validators: [{type: 'required', message: 'You need to upload at least one data file'}],

      // Incapsulate editor errors reporting routine in param to ensure generic use
      reporter: function(errors) { window.APP.layout.createDp.layout.form.layout.validationReport.reset(errors).activate(); },

      // Same for uploader — ensure generic use
      uploader: function(file) { window.APP.layout.createDp.layout.form.layout.upload.uploadLocalFile(file); }
    }
  },

  template: window.TEMPLATES['create-dp/form.hbs']
});
<commit_msg>Fixed misspelling<commit_after>require('backbone-base');
require('backbone-forms');

var
  _ = require('lodash'),
  backbone = require('backbone'),
  DataFilesEditor = require('./data-files-editor'),
  NameEditor = require('./name-editor'),
  ValidationReportView = require('./validation-report'),
  UploadView = require('./upload');

module.exports = backbone.BaseView.extend(backbone.Form.prototype).extend({
  activate: function(state) {
    backbone.BaseView.prototype.activate.call(this, state);

    if((_.isUndefined(state) || state) && _.isEmpty(this.layout))
      this.render();

    // Do not allow child view (upload widget) to change parent — just catch its events
    this.layout.upload.on('upload-started', this.loading, this);

    this.layout.upload.on('parse-complete', function(csvData) {
      this.fields.files.setValue((this.fields.files.getValue() || []).concat(csvData))
      this.loading(false);
    }, this);

    return this;
  },

  events: {
    'click [data-id=create]': function() { this.validate(); return false; }
  },

  initialize: function(options) {
    backbone.BaseView.prototype.initialize.call(this, options);
    backbone.Form.prototype.initialize.call(this, options);
  },

  loading: function(state) {
    var
      isLoading = _.isUndefined(state) || state;

    this.$('[data-id=submit]').toggleClass('form-button--loading', isLoading);
    this.$('[data-id=upload-in-progress]').prop('hidden', !isLoading);
    this.$('[data-id=create]').prop('hidden', isLoading);
    return this;
  },

  render: function() {
    backbone.Form.prototype.render.call(this);
    this.layout.upload = (new UploadView({el: this.$('[data-id=upload]'), parent: this})).render();

    this.layout.validationReport = (new ValidationReportView({
      container: '[data-id=content]',
      el: this.$('[data-id="validation-report"]')
    })).render();

    return this;
  },

  schema: {
    name: {
      label: 'Name your Data Package',
      type: NameEditor,
      validators: [{type: 'required', message: 'Your data package should have a name'}],
      urlBase: 'https://openspending.org/'
    },

    files: {
      type: DataFilesEditor,
      validators: [{type: 'required', message: 'You need to upload at least one data file'}],

      // Incapsulate editor errors reporting routine in param to ensure generic use
      reporter: function(errors) { window.APP.layout.createDp.layout.form.layout.validationReport.reset(errors).activate(); },

      // Same for uploader — ensure generic use
      uploader: function(file) { window.APP.layout.createDp.layout.form.layout.upload.uploadLocalFile(file); }
    }
  },

  template: window.TEMPLATES['create-dp/form.hbs']
});
<|endoftext|>


<commit_before>//how many tokens are needed to continue from a level
var tokensNeeded = {
    5: 2,
    6: 3
};

//sorts based on the "data-value" attribute
$.tablesorter.addParser({
    id: "data-value",
    is: function (s) {
        return false;
    },
    format: function (string, table, cell) {
        return $(cell).data("value");
    },
    type: "numeric"
});

requestJSON("/getPlayer?summoner=" + getURLParameter("summoner") + "&region=" + getURLParameter("region"), function (data) {
    document.getElementById("summonerName").appendChild(document.createTextNode(data.player.name));
    document.getElementById("summonerIcon").src = data.player.icon;
    var table = document.createElement("table");
    table.id = "table";
    table.className = "table well well-sm";

    var tbody = document.createElement("tbody");

    var totalLevel = 0, totalPoints = 0, totalChests = 0;
    data.champions.forEach(function (champion) {
        totalLevel += champion.level;
        totalPoints += champion.points;
        totalChests += champion.chest ? 1 : 0;

        var tr = document.createElement("tr");

        var name = document.createElement("td");
        var a = document.createElement("a");
        a.href = "/champion?champion=" + champion.id;
        a.appendChild(document.createTextNode(champion.name));
        name.appendChild(a);
        tr.appendChild(name);

        var level = document.createElement("td");
        level.appendChild(document.createTextNode(champion.level));
        tr.appendChild(level);

        var points = document.createElement("td");
        points.appendChild(document.createTextNode(formatNumber(champion.points)));
        points.dataset.value = champion.points;
        tr.appendChild(points);

        var chest = document.createElement("td");
        var chestImg = document.createElement("img");
        chestImg.src = "chest.png";
        chestImg.className = champion.chest ? "chest" : "notEarned chest";
        chest.appendChild(chestImg);
        chest.dataset.value = champion.chest ? 1 : 0;
        tr.appendChild(chest);

        var lastPlayed = document.createElement("td");
        lastPlayed.appendChild(document.createTextNode(makeTime(champion.lastPlayed)));
        lastPlayed.dataset.value = champion.lastPlayed;
        lastPlayed.dataset.toggle = "tooltip";
        lastPlayed.title = new moment(champion.lastPlayed).from(new moment());
        tr.appendChild(lastPlayed);

        var progress = document.createElement("td");
        if (champion.level === 7) {
            progress.appendChild(document.createTextNode("Completed"));
            progress.dataset.value = 300;
        } else if (champion.level === 5 || champion.level === 6) {
            for (var i = 0; i < tokensNeeded[champion.level]; i++) {
                var token = document.createElement("img");
                token.src = "token.png";
                token.className = i < champion.tokens ? "token" : "token notEarned";
                progress.appendChild(token);
            }
            //hacky solution to organize things.
            progress.dataset.value = ((champion.level - 4) * 100) + (champion.tokens / tokensNeeded[champion.level]);
        } else {
            //I don't like Bootstrap's progress bars
            var outer = document.createElement("div");
            outer.className = "progressBar-outer";
            var inner = document.createElement("div");
            inner.className = "progressBar-inner";
            var pct = Math.round(champion.pointsSinceLastLevel / (champion.pointsSinceLastLevel + champion.pointsNeeded) * 10000) / 100;
            inner.style.width = pct + "%";
            outer.dataset.toggle = "tooltip";
            outer.title = champion.pointsSinceLastLevel + "/" + (champion.pointsSinceLastLevel + champion.pointsNeeded) + " (" + pct + "%)";
            progress.dataset.value = pct;
            outer.appendChild(inner);
            progress.appendChild(outer);
        }
        tr.appendChild(progress);

        tbody.appendChild(tr);
    });

    var thead = document.createElement("thead");
    var columns = ["Champion", "Mastery Level", "Mastery Points", "Chest Earned", "Last Played", "Progress"];
    var labels = document.createElement("tr");
    columns.forEach(function (column) {
        var th = document.createElement("th");
        th.appendChild(document.createTextNode(column));
        //used for sorting arrows
        th.appendChild(document.createElement("span"));
        labels.appendChild(th);
    });
    thead.appendChild(labels);
    table.appendChild(thead);

    table.appendChild(tbody);

    var tfoot = document.createElement("tfoot");
    var totalsRow = document.createElement("tr");

    [
        data.champions.length + " champions",
        formatNumber(totalLevel),
        formatNumber(totalPoints),
        totalChests + "/" + data.champions.length,
        "",
        ""
    ].forEach(function (total) {
        var th = document.createElement("th");
        th.appendChild(document.createTextNode(total));
        totalsRow.appendChild(th);
    });

    tfoot.appendChild(totalsRow);
    table.appendChild(tfoot);

    document.getElementById("content").appendChild(table);

    $("#table").tablesorter({
        headers: {
            3: {sorter: "data-value"},
            4: {sorter: "data-value"},
            5: {sorter: "data-value"}
        },
        //primary level, secondary points
        sortList: [[1, 1], [2, 1]]
    });
}, {
    400: function (message) {
        error("Invalid request", message);
    },
    404: function (message) {
        error("Summoner not found", message);
    },
    500: function (message) {
        error("Server error", message);
    },
    0: function (message, code) {
        error("An unknown error has occured", message + " (" + code + ")");
    }
});

function makeTime(timestamp) {
    return new moment(timestamp).format("MMM D YYYY, h:mm:ss a");
}

<commit_msg>Fix previous commit<commit_after>//how many tokens are needed to continue from a level
var tokensNeeded = {
    5: 2,
    6: 3
};

//sorts based on the "data-value" attribute
$.tablesorter.addParser({
    id: "data-value",
    is: function (s) {
        return false;
    },
    format: function (string, table, cell) {
        return $(cell).data("value");
    },
    type: "numeric"
});

requestJSON("/getPlayer?summoner=" + getURLParameter("summoner") + "&region=" + getURLParameter("region"), function (data) {
    document.getElementById("summonerName").appendChild(document.createTextNode(data.player.name));
    document.getElementById("summonerIcon").src = data.player.icon;
    var table = document.createElement("table");
    table.id = "table";
    table.className = "table well well-sm";

    var tbody = document.createElement("tbody");

    var totalLevel = 0, totalPoints = 0, totalChests = 0;
    data.champions.forEach(function (champion) {
        totalLevel += champion.level;
        totalPoints += champion.points;
        totalChests += champion.chest ? 1 : 0;

        var tr = document.createElement("tr");

        var name = document.createElement("td");
        var a = document.createElement("a");
        a.href = "/champion?champion=" + champion.id;
        a.appendChild(document.createTextNode(champion.name));
        name.appendChild(a);
        tr.appendChild(name);

        var level = document.createElement("td");
        level.appendChild(document.createTextNode(champion.level));
        tr.appendChild(level);

        var points = document.createElement("td");
        points.appendChild(document.createTextNode(formatNumber(champion.points)));
        points.dataset.value = champion.points;
        tr.appendChild(points);

        var chest = document.createElement("td");
        var chestImg = document.createElement("img");
        chestImg.src = "chest.png";
        chestImg.className = champion.chest ? "chest" : "notEarned chest";
        chest.appendChild(chestImg);
        chest.dataset.value = champion.chest ? 1 : 0;
        tr.appendChild(chest);

        var lastPlayed = document.createElement("td");
        lastPlayed.appendChild(document.createTextNode(makeTime(champion.lastPlayed)));
        lastPlayed.dataset.value = champion.lastPlayed;
        lastPlayed.dataset.toggle = "tooltip";
        lastPlayed.title = new moment(champion.lastPlayed).from(new moment());
        tr.appendChild(lastPlayed);

        var progress = document.createElement("td");
        if (champion.level === 7) {
            progress.appendChild(document.createTextNode("Completed"));
            progress.dataset.value = 300;
        } else if (champion.level === 5 || champion.level === 6) {
            for (var i = 0; i < tokensNeeded[champion.level]; i++) {
                var token = document.createElement("img");
                token.src = "token.png";
                token.className = i < champion.tokens ? "token" : "token notEarned";
                progress.appendChild(token);
            }
            //hacky solution to organize things.
            progress.dataset.value = ((champion.level - 4) * 100) + (champion.tokens / tokensNeeded[champion.level]);
        } else {
            //I don't like Bootstrap's progress bars
            var outer = document.createElement("div");
            outer.className = "progressBar-outer";
            var inner = document.createElement("div");
            inner.className = "progressBar-inner";
            var pct = Math.round(champion.pointsSinceLastLevel / (champion.pointsSinceLastLevel + champion.pointsNeeded) * 10000) / 100;
            inner.style.width = pct + "%";
            outer.dataset.toggle = "tooltip";
            outer.title = champion.pointsSinceLastLevel + "/" + (champion.pointsSinceLastLevel + champion.pointsNeeded) + " (" + pct + "%)";
            progress.dataset.value = pct;
            outer.appendChild(inner);
            progress.appendChild(outer);
        }
        tr.appendChild(progress);

        tbody.appendChild(tr);
    });

    var thead = document.createElement("thead");
    var columns = ["Champion", "Mastery Level", "Mastery Points", "Chest Earned", "Last Played", "Progress"];
    var labels = document.createElement("tr");
    columns.forEach(function (column) {
        var th = document.createElement("th");
        th.appendChild(document.createTextNode(column));
        //used for sorting arrows
        th.appendChild(document.createElement("span"));
        labels.appendChild(th);
    });
    thead.appendChild(labels);
    table.appendChild(thead);

    table.appendChild(tbody);

    var tfoot = document.createElement("tfoot");
    var totalsRow = document.createElement("tr");

    [
        data.champions.length + " champions",
        formatNumber(totalLevel),
        formatNumber(totalPoints),
        totalChests + "/" + data.champions.length,
        "",
        ""
    ].forEach(function (total) {
        var th = document.createElement("th");
        th.appendChild(document.createTextNode(total));
        totalsRow.appendChild(th);
    });

    tfoot.appendChild(totalsRow);
    table.appendChild(tfoot);

    document.getElementById("content").appendChild(table);

    $("#table").tablesorter({
        headers: {
            2: {sorter: "data-value"},
            3: {sorter: "data-value"},
            4: {sorter: "data-value"},
            5: {sorter: "data-value"}
        },
        //primary level, secondary points
        sortList: [[1, 1], [2, 1]]
    });
}, {
    400: function (message) {
        error("Invalid request", message);
    },
    404: function (message) {
        error("Summoner not found", message);
    },
    500: function (message) {
        error("Server error", message);
    },
    0: function (message, code) {
        error("An unknown error has occured", message + " (" + code + ")");
    }
});

function makeTime(timestamp) {
    return new moment(timestamp).format("MMM D YYYY, h:mm:ss a");
}

<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import { MIN_PAYPAL_AMOUNT, MAX_PAYPAL_AMOUNT } from '@proton/shared/lib/constants';
import { doNotWindowOpen } from '@proton/shared/lib/helpers/browser';
import paypalSvg from '@proton/styles/assets/img/bank-icons/paypal.svg';
import { c } from 'ttag';

import { Alert, DoNotWindowOpenAlertError, Price, Loader } from '../../components';
import PayPalButton from './PayPalButton';

const PayPalView = ({ type, amount, currency, paypal, paypalCredit }) => {
    if (type === 'payment' && amount < MIN_PAYPAL_AMOUNT) {
        return (
            <Alert type="error">
                {c('Error').t`Amount below minimum.`} {`(${(<Price currency={currency}>{MIN_PAYPAL_AMOUNT}</Price>)})`}
            </Alert>
        );
    }

    if (amount > MAX_PAYPAL_AMOUNT) {
        return <Alert type="error">{c('Error').t`Amount above the maximum.`}</Alert>;
    }

    if (doNotWindowOpen()) {
        return <DoNotWindowOpenAlertError />;
    }

    const clickHere = (
        <PayPalButton
            shape="outline"
            color="norm"
            flow={type}
            key="click-here"
            size="small"
            paypal={paypalCredit}
            amount={amount}
        >
            {c('Link').t`click here`}
        </PayPalButton>
    );

    return (

            {paypal.loading ? (
                <>
                    <Loader />
                    <Alert>{c('Info').t`Please verify the payment in the new tab.`}</Alert>
                </>
            ) : null}
            {!paypal.loadingVerification && ['signup', 'subscription', 'invoice', 'credit'].includes(type) ? (
                <>
                    <Alert>
                        {c('Info')
                            .t`We will redirect you to PayPal in a new browser tab to complete this transaction. If you use any pop-up blockers, please disable them to continue.`}
                    </Alert>

                    <Alert>
                        {c('Info')
                            .t`You must have a credit card or bank account linked with your PayPal account. If your PayPal account doesn't have that, please click on the button below.`}

                        {clickHere}
                    </Alert>
                </>
            ) : null}
            {!paypal.loadingVerification && type === 'update' ? (
                <>
                    <Alert>
                        {c('Info')
                            .t`This will enable PayPal to be used to pay for your Proton subscription. We will redirect you to PayPal in a new browser tab. If you use any pop-up blockers, please disable them to continue.`}
                    </Alert>

                    <Alert>{c('Info')
                        .t`You must have a credit card or bank account linked with your PayPal account in order to add it as a payment method.`}</Alert>
                </>
            ) : null}
            {!paypal.loadingVerification && ['donation', 'human-verification'].includes(type) ? (
                <>
                    <Alert>
                        {c('Info')
                            .t`We will redirect you to PayPal in a new browser tab to complete this transaction. If you use any pop-up blockers, please disable them to continue.`}
                    </Alert>

                </>
            ) : null}

    );
};

PayPalView.propTypes = {
    type: PropTypes.oneOf(['signup', 'subscription', 'invoice', 'donation', 'credit', 'update', 'human-verification']),
    amount: PropTypes.number.isRequired,
    currency: PropTypes.string.isRequired,
    paypal: PropTypes.object.isRequired,
    paypalCredit: PropTypes.object.isRequired,
};

export default PayPalView;
<commit_msg>Remove PayPal image from 'Payment details' section<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import { MIN_PAYPAL_AMOUNT, MAX_PAYPAL_AMOUNT } from '@proton/shared/lib/constants';
import { doNotWindowOpen } from '@proton/shared/lib/helpers/browser';
import paypalSvg from '@proton/styles/assets/img/bank-icons/paypal.svg';
import { c } from 'ttag';

import { Alert, DoNotWindowOpenAlertError, Price, Loader } from '../../components';
import PayPalButton from './PayPalButton';

const PayPalView = ({ type, amount, currency, paypal, paypalCredit }) => {
    if (type === 'payment' && amount < MIN_PAYPAL_AMOUNT) {
        return (
            <Alert type="error">
                {c('Error').t`Amount below minimum.`} {`(${(<Price currency={currency}>{MIN_PAYPAL_AMOUNT}</Price>)})`}
            </Alert>
        );
    }

    if (amount > MAX_PAYPAL_AMOUNT) {
        return <Alert type="error">{c('Error').t`Amount above the maximum.`}</Alert>;
    }

    if (doNotWindowOpen()) {
        return <DoNotWindowOpenAlertError />;
    }

    const clickHere = (
        <PayPalButton
            shape="outline"
            color="norm"
            flow={type}
            key="click-here"
            size="small"
            paypal={paypalCredit}
            amount={amount}
        >
            {c('Link').t`click here`}
        </PayPalButton>
    );

    return (

            {paypal.loading ? (
                <>
                    <Loader />
                    <Alert>{c('Info').t`Please verify the payment in the new tab.`}</Alert>
                </>
            ) : null}
            {!paypal.loadingVerification && ['signup', 'subscription', 'invoice', 'credit'].includes(type) ? (
                <>
                    <Alert>
                        {c('Info')
                            .t`We will redirect you to PayPal in a new browser tab to complete this transaction. If you use any pop-up blockers, please disable them to continue.`}
                    </Alert>
                    <Alert>
                        {c('Info')
                            .t`You must have a credit card or bank account linked with your PayPal account. If your PayPal account doesn't have that, please click on the button below.`}

                        {clickHere}
                    </Alert>
                </>
            ) : null}
            {!paypal.loadingVerification && type === 'update' ? (
                <>
                    <Alert>
                        {c('Info')
                            .t`This will enable PayPal to be used to pay for your Proton subscription. We will redirect you to PayPal in a new browser tab. If you use any pop-up blockers, please disable them to continue.`}
                    </Alert>

                    <Alert>{c('Info')
                        .t`You must have a credit card or bank account linked with your PayPal account in order to add it as a payment method.`}</Alert>
                </>
            ) : null}
            {!paypal.loadingVerification && ['donation', 'human-verification'].includes(type) ? (
                <>
                    <Alert>
                        {c('Info')
                            .t`We will redirect you to PayPal in a new browser tab to complete this transaction. If you use any pop-up blockers, please disable them to continue.`}
                    </Alert>

                </>
            ) : null}

    );
};

PayPalView.propTypes = {
    type: PropTypes.oneOf(['signup', 'subscription', 'invoice', 'donation', 'credit', 'update', 'human-verification']),
    amount: PropTypes.number.isRequired,
    currency: PropTypes.string.isRequired,
    paypal: PropTypes.object.isRequired,
    paypalCredit: PropTypes.object.isRequired,
};

export default PayPalView;
<|endoftext|>


<commit_before>import template from './userLanding.html';
import formReadDialogTemplate from '../formRead/formReadDialog.html';
import comparisonFormTemplate from './requireComparisonFormDialog.html';
import enableContactMeTemplate from './enableContactMeDialog.html';

class UserLandingController {
  constructor($location, $mdDialog, $mdPanel, loomApi, lodash, moment, recruitUnitUtil, jwtHelper, globals, recruitUnitConfig) {
    "ngInject";
    console.log("in UserLandingController");
    this.moment = moment;
    this.$mdDialog = $mdDialog;
    this.recruitUnitUtil = recruitUnitUtil;
    this.loomApi = loomApi;

    this.username = globals.username;
    this.userguid = globals.userguid;
    this.roles = globals.roles;
    this.id = globals.id;
    this.myContentListArray = globals.myContentListArray;
		this.jobItemDocsArray = globals.jobItemDocsArray;
    this.myContentListPassCount = globals.myContentListPassCount;
    this.myContentListFailCount = globals.myContentListFailCount;
    this.isDeveloper = globals.isDeveloper;

    this._mdPanel = $mdPanel;
    this.openFrom = 'button';
    this.closeTo = 'button';

    var token = jwtHelper.decodeToken(recruitUnitUtil.Util.getLocalUser().token);
    //console.log(recruitUnitConfig);
    if (typeof token.userGuid != 'undefined') {
      if (recruitUnitConfig.APP_ENV != 'prod') {
				var serverUrl = recruitUnitConfig.APP_PROTOCOL + recruitUnitConfig.APP_HOST + ":" + recruitUnitConfig.APP_PORT;
				this.unitTestFormUrl = serverUrl + recruitUnitConfig.PATH_USER + token.userGuid + "/form";
			} else {
				var serverUrl = recruitUnitConfig.APP_PROTOCOL + recruitUnitConfig.APP_HOST;
				this.unitTestFormUrl = serverUrl + recruitUnitConfig.PATH_USER + token.userGuid + "/form";
      }
    }

    //check if the user has a comparison test form and is a developer. Show alert dialog if not
    //todo: might need to move this to the canActivate?
    if (this.recruitUnitUtil.Util.getLocalUser().token !== null) {
      var decodedToken = jwtHelper.decodeToken(this.recruitUnitUtil.Util.getLocalUser().token);
      if (decodedToken.isComparisonFormEnabled) {
        console.log("User has a comparison form enabled");
      } else if (decodedToken.roles.indexOf(this.recruitUnitUtil.Constants.DEVELOPER_ROLE) != -1) {
        this.showPanel();
      }
    }
  }

  $routerOnActivate(next, previous){
    this.useremail = next.params.email;
    console.log("route param email:" + this.useremail);
  }

  showFormDetailDialog($event, item){
    console.log("in showFormDetailDialog");
    console.log("item:");
    console.log(item);
    var id, isPass, isPartialPass = "";
    if (item.model == "RecruitUnitJobDescription"){
      id = item._id;
      isPass = "";
      isPartialPass = "";
		} else {
			id = item.id;
			isPass = item.isPass;
			isPartialPass = item.isPartialPass;
		}

    this.$mdDialog.show({
      controller: 'formReadController',
      controllerAs: 'formRead',
      locals: {
        'jobDetailFormId': id,
        'isItemPass': isPartialPass || isPass ? true : false,
        'payFrequencyOptions': [
          {id: "Permanent", value: "annual salary"},
          {id: "Contract", value: "daily rate"}
        ]
      },
      bindToController: true,
      template: formReadDialogTemplate,
      parent: angular.element(document.body),
      targetEvent: $event,
      clickOutsideToClose: true,
      fullscreen: false
    });
  }

  deleteItem(docId, index){
    console.log("delete id:" + docId + ",index:" + index);
    //todo: ensure the update can only change the users own document
    var controllerId = "/services/recruitunit/articles/recruitUnitContentService.controller.js";
    var jobItemModel = "/models/RecruitUnit.Job.All.js";
    var localToken = this.recruitUnitUtil.Util.getLocalUser().token;
    this.loomApi.Article.updateArticle(docId, controllerId, jobItemModel, {"published": false}, localToken).then(angular.bind(this, function (result) {
      console.log("Delete result:");
      console.log(result);
      if (result.success) {
        this.myContentListArray.splice(index, 1);
      }
    }));
  }

  formatUnixDateToNow(unixTime){
    return this.moment.unix(unixTime).from();
  }

  viewItem(id){
    //console.log("view id:" + id);
    $location.path("/user/" + this.useremail + "/form/" + id);
  }

  searchUser(searchJson){
    var comparisonRulesDocId = "";
    var localToken = this.recruitUnitUtil.Util.getLocalUser().token;

    this.loomApi.Article.getUserTestResults(searchJson, localToken).then(angular.bind(this, function (listMyTestContentResult) {
      console.log("getUserTestResults:");
      console.log(listMyTestContentResult);
      if (typeof listMyTestContentResult !== 'undefined') {
        this.myContentListArray = lodash.sortBy(listMyTestContentResult, 'document.createdDate').reverse();
        this.myContentListPassCount = lodash.filter(listMyTestContentResult, {'testResult': {'isPass': true}}).length + lodash.filter(listMyTestContentResult, {'testResult': {'isPartialPass': true}}).length;
        this.myContentListFailCount = listMyTestContentResult.length - this.myContentListPassCount;

        return true; //return canActivate state once results are available
      }
    }));
  }

  navigateToUserRules(useremail){
    console.log("navigateToUserRules [" + useremail + "]");
    console.log("redirect to path [" + this.recruitUnitUtil.Constants.PATH_USER + useremail + this.recruitUnitUtil.Constants.PATH_COMPARISONRULESFORM + "]");
    this.recruitUnitUtil.Util.redirectUserToPath(this.recruitUnitUtil.Constants.PATH_USER + useremail + this.recruitUnitUtil.Constants.PATH_COMPARISONRULESFORM);
  }

  getDeveloperEmailAddress(docId, isDeveloper, displayDevEmail){
    if (!isDeveloper && displayDevEmail) {
      var localToken = this.recruitUnitUtil.Util.getLocalUser().token;

      return this.loomApi.User.getDevEmailFromDocId(docId, localToken).then(angular.bind(this, function (result) {
        return typeof result.email !== "undefined" ? result.email : result.message;
      }));
    }
  }

  showPanel(){
    console.log("in showPanel");
    var panelPosition = this._mdPanel.newPanelPosition()
      .absolute()
      .center();
    var panelAnimation = this._mdPanel.newPanelAnimation();
    panelAnimation.openFrom({top: 0, left: 0});
    panelAnimation.closeTo({top: document.documentElement.clientHeight, left: 0});
    panelAnimation.withAnimation(this._mdPanel.animation.SCALE);

    var config = {
      attachTo: angular.element(document.body),
      controller: 'genericDialogController',
      controllerAs: 'requireComparisonFormDialog',
      locals: {
        'useremail': this.recruitUnitUtil.Util.getLocalUser().email,
        'navigateToUserRules': this.navigateToUserRules
      },
      position: panelPosition,
      animation: panelAnimation,
      template: comparisonFormTemplate,
      hasBackdrop: true,
      panelClass: 'generic-dialog',
      zIndex: 150,
      clickOutsideToClose: true,
      escapeToClose: true,
      focusOnOpen: true
    }

    this._mdPanel.open(config);
  }

  toggleContactMeDialog($event, id, displayDevEmail, repeatScope){
    console.log("in toggleContactMeDialog");

    var panelPosition = this._mdPanel.newPanelPosition()
      .absolute()
      .center();
    var panelAnimation = this._mdPanel.newPanelAnimation();
    panelAnimation.openFrom({top: 0, left: 0});
    panelAnimation.closeTo({top: document.documentElement.clientHeight, left: 0});
    panelAnimation.withAnimation(this._mdPanel.animation.SCALE);

    var config = {
      attachTo: angular.element(document.body),
      controller: 'genericDialogController',
      controllerAs: 'contactMeDialog',
      locals: {
        'docId': id,
        'isDisplayDevEmail': displayDevEmail,
        'isDeveloper': this.isDeveloper,
        'developerEmailAddress': this.getDeveloperEmailAddress(id, this.isDeveloper, displayDevEmail),
        itemScope: repeatScope
      },
      bindToController: true,
      position: panelPosition,
      animation: panelAnimation,
      template: enableContactMeTemplate,
      hasBackdrop: true,
      panelClass: 'generic-dialog',
      zIndex: 150,
      clickOutsideToClose: true,
      escapeToClose: true,
      focusOnOpen: true
    }

    this._mdPanel.open(config);
  }

}

export default {
  controller: UserLandingController,
  controllerAs: 'userLanding',
  template: template,
  $canActivate: function($nextInstruction, recruitUnitUtil, jwtHelper, loomApi, globals, lodash, recruitUnitConfig){
    "ngInject";
    console.log("in UserLandingController canActivate");
    //console.log(recruitUnitConfig);

    if (recruitUnitUtil.Util.isLocalUserAvailable()) {
      var token = jwtHelper.decodeToken(recruitUnitUtil.Util.getLocalUser().token);
      var tokenUsername = token.username;
      var tokenRoles = token.roles;
      var requestedUsername = $nextInstruction.params.email;

      var serverUrl = recruitUnitUtil.Constants.APP_PROTOCOL + recruitUnitUtil.Constants.APP_HOST + ":" + recruitUnitUtil.Constants.APP_PORT;

      return recruitUnitUtil.Util.isUserAuthenticated(tokenUsername, recruitUnitUtil.Util.getLocalUser().token).then(angular.bind(this, function (result) {
        if (result == false) {
          recruitUnitUtil.Util.redirectUserToPath(recruitUnitUtil.Constants.PATH_HOME);// todo: get path from constant;
          recruitUnitUtil.Util.deleteUserAuth();
        } else if (tokenUsername != requestedUsername) {
          recruitUnitUtil.Util.redirectUserToPath(recruitUnitUtil.Constants.PATH_USER + tokenUsername);
        } else if (result.success) {
          //set user details returned from the jwt
          globals.roles = result.data.roles;
          globals.id = result.data.id;
          globals.username = result.data.displayName;
          globals.userGuid = result.data.userGuid;
          globals.userFormUrl = serverUrl + recruitUnitUtil.Constants.PATH_USER + globals.userGuid + "/form";

          if (tokenRoles.indexOf("recruiter") != -1){
            globals.isDeveloper = false;
            // var searchJson = {
            //   "authorEmail": tokenUsername
            // };
            var localToken = recruitUnitUtil.Util.getLocalUser().token;

            var selector = {
							"selector": {
								"model": "RecruitUnitJobDescription",
								"authorEmail": tokenUsername
							}
						};
            //ToDo: these 2 api calls can be consolidated into a single call
						return loomApi.Article.find(selector, localToken).then(angular.bind(this, function (result) {
							  console.log("find results:");
							  console.log(result.docs);
                if (typeof result.docs !== 'undefined' && result.docs.length > 0) {
                      globals.jobItemDocsArray = lodash.sortBy(result.docs, 'createdDate').reverse();

                      //parse recruiter JobDescription results and find matching developer JobItems
                      return result.docs.length; //return canActivate state once results are available
                } else {
                  return true;
                }
            })).then(angular.bind(this, function (result) {
              if (result > 0) {
								return loomApi.Article.getUserTestResults(null, localToken).then(angular.bind(this, function (listMyTestContentResult) {
									console.log("getUserTestResults:");
									if (typeof listMyTestContentResult !== 'undefined') {
										globals.myContentListArray = lodash.sortBy(listMyTestContentResult, 'document.createdDate').reverse();
										//globals.myContentListPassCount = lodash.filter(listMyTestContentResult, {'testResult': {'isPass': true}}).length + lodash.filter(listMyTestContentResult, {'testResult': {'isPartialPass': true}}).length;
										//globals.myContentListFailCount = listMyTestContentResult.length - globals.myContentListPassCount;

										return true; //return canActivate state once results are available
									}
								}));
							}
              return result;
            }));

						// No longer require user test results as we'll be returning list from search results.
            // return loomApi.Article.getUserTestResults(searchJson, localToken).then(angular.bind(this, function (listMyTestContentResult) {
            //   console.log("getUserTestResults:");
            //   console.log(listMyTestContentResult);
            //   if (typeof listMyTestContentResult !== 'undefined') {
            //     globals.myContentListArray = lodash.sortBy(listMyTestContentResult, 'document.createdDate').reverse();
            //     globals.myContentListPassCount = lodash.filter(listMyTestContentResult, {'testResult': {'isPass': true}}).length + lodash.filter(listMyTestContentResult, {'testResult': {'isPartialPass': true}}).length;
            //     globals.myContentListFailCount = listMyTestContentResult.length - globals.myContentListPassCount;
						//
            //     return true; //return canActivate state once results are available
            //   }
            // }));
            return true;
          } else if (tokenRoles.indexOf("developer") != -1){
            globals.isDeveloper = true;
            var searchJson = {
              "submitTo": globals.userGuid
            };
						var selector = {
							"selector": {
								"model": "RecruitUnitComparisonTest",
								"authorEmail": tokenUsername
							}
						};
            var localToken = recruitUnitUtil.Util.getLocalUser().token;
            return loomApi.Article.getUserComparisonTestResults(searchJson, localToken).then(angular.bind(this, function (listMyTestContentResult) {
              console.log("getUserTestResults:");
              console.log(listMyTestContentResult);
              if (typeof listMyTestContentResult !== 'undefined') {
								globals.jobItemDocsArray = lodash.sortBy(listMyTestContentResult, 'document.createdDate').reverse();
                //globals.myContentListPassCount = lodash.filter(listMyTestContentResult, {'testResult': {'isPass': true}}).length + lodash.filter(listMyTestContentResult, {'testResult': {'isPartialPass': true}}).length;
                //globals.myContentListFailCount = listMyTestContentResult.length - globals.myContentListPassCount;

                return true; //return canActivate state once results are available
              }
            })).then(angular.bind(this, function (result) {
							if (result > 0) {
								return loomApi.Article.find(selector, localToken).then(angular.bind(this, function (result) {
								  //todo: continue fixing up below to fit new find
									console.log("getUserTestResults:");
									if (typeof listMyTestContentResult !== 'undefined') {
										globals.myContentListArray = lodash.sortBy(listMyTestContentResult, 'document.createdDate').reverse();
										//globals.myContentListPassCount = lodash.filter(listMyTestContentResult, {'testResult': {'isPass': true}}).length + lodash.filter(listMyTestContentResult, {'testResult': {'isPartialPass': true}}).length;
										//globals.myContentListFailCount = listMyTestContentResult.length - globals.myContentListPassCount;

										return true; //return canActivate state once results are available
									}
								}));
							}
							return result;
						}));
          }
        }

      }));
    } else {
      recruitUnitUtil.Util.redirectUserToPath(recruitUnitUtil.Constants.PATH_HOME);
    }
  }
}

<commit_msg>starting fix for developer landing page to display data correctly<commit_after>import template from './userLanding.html';
import formReadDialogTemplate from '../formRead/formReadDialog.html';
import comparisonFormTemplate from './requireComparisonFormDialog.html';
import enableContactMeTemplate from './enableContactMeDialog.html';

class UserLandingController {
  constructor($location, $mdDialog, $mdPanel, loomApi, lodash, moment, recruitUnitUtil, jwtHelper, globals, recruitUnitConfig) {
    "ngInject";
    console.log("in UserLandingController");
    this.moment = moment;
    this.$mdDialog = $mdDialog;
    this.recruitUnitUtil = recruitUnitUtil;
    this.loomApi = loomApi;

    this.username = globals.username;
    this.userguid = globals.userguid;
    this.roles = globals.roles;
    this.id = globals.id;
    this.myContentListArray = globals.myContentListArray;
		this.jobItemDocsArray = globals.jobItemDocsArray;
    this.myContentListPassCount = globals.myContentListPassCount;
    this.myContentListFailCount = globals.myContentListFailCount;
    this.isDeveloper = globals.isDeveloper;

    this._mdPanel = $mdPanel;
    this.openFrom = 'button';
    this.closeTo = 'button';

    var token = jwtHelper.decodeToken(recruitUnitUtil.Util.getLocalUser().token);
    //console.log(recruitUnitConfig);
    if (typeof token.userGuid != 'undefined') {
      if (recruitUnitConfig.APP_ENV != 'prod') {
				var serverUrl = recruitUnitConfig.APP_PROTOCOL + recruitUnitConfig.APP_HOST + ":" + recruitUnitConfig.APP_PORT;
				this.unitTestFormUrl = serverUrl + recruitUnitConfig.PATH_USER + token.userGuid + "/form";
			} else {
				var serverUrl = recruitUnitConfig.APP_PROTOCOL + recruitUnitConfig.APP_HOST;
				this.unitTestFormUrl = serverUrl + recruitUnitConfig.PATH_USER + token.userGuid + "/form";
      }
    }

    //check if the user has a comparison test form and is a developer. Show alert dialog if not
    //todo: might need to move this to the canActivate?
    if (this.recruitUnitUtil.Util.getLocalUser().token !== null) {
      var decodedToken = jwtHelper.decodeToken(this.recruitUnitUtil.Util.getLocalUser().token);
      if (decodedToken.isComparisonFormEnabled) {
        console.log("User has a comparison form enabled");
      } else if (decodedToken.roles.indexOf(this.recruitUnitUtil.Constants.DEVELOPER_ROLE) != -1) {
        this.showPanel();
      }
    }
  }

  $routerOnActivate(next, previous){
    this.useremail = next.params.email;
    console.log("route param email:" + this.useremail);
  }

  showFormDetailDialog($event, item){
    console.log("in showFormDetailDialog");
    console.log("item:");
    console.log(item);
    var id, isPass, isPartialPass = "";
    if (item.model == "RecruitUnitJobDescription"){
      id = item._id;
      isPass = "";
      isPartialPass = "";
		} else {
			id = item.id;
			isPass = item.isPass;
			isPartialPass = item.isPartialPass;
		}

    this.$mdDialog.show({
      controller: 'formReadController',
      controllerAs: 'formRead',
      locals: {
        'jobDetailFormId': id,
        'isItemPass': isPartialPass || isPass ? true : false,
        'payFrequencyOptions': [
          {id: "Permanent", value: "annual salary"},
          {id: "Contract", value: "daily rate"}
        ]
      },
      bindToController: true,
      template: formReadDialogTemplate,
      parent: angular.element(document.body),
      targetEvent: $event,
      clickOutsideToClose: true,
      fullscreen: false
    });
  }

  deleteItem(docId, index){
    console.log("delete id:" + docId + ",index:" + index);
    //todo: ensure the update can only change the users own document
    var controllerId = "/services/recruitunit/articles/recruitUnitContentService.controller.js";
    var jobItemModel = "/models/RecruitUnit.Job.All.js";
    var localToken = this.recruitUnitUtil.Util.getLocalUser().token;
    this.loomApi.Article.updateArticle(docId, controllerId, jobItemModel, {"published": false}, localToken).then(angular.bind(this, function (result) {
      console.log("Delete result:");
      console.log(result);
      if (result.success) {
        this.myContentListArray.splice(index, 1);
      }
    }));
  }

  formatUnixDateToNow(unixTime){
    return this.moment.unix(unixTime).from();
  }

  viewItem(id){
    //console.log("view id:" + id);
    $location.path("/user/" + this.useremail + "/form/" + id);
  }

  searchUser(searchJson){
    var comparisonRulesDocId = "";
    var localToken = this.recruitUnitUtil.Util.getLocalUser().token;

    this.loomApi.Article.getUserTestResults(searchJson, localToken).then(angular.bind(this, function (listMyTestContentResult) {
      console.log("getUserTestResults:");
      console.log(listMyTestContentResult);
      if (typeof listMyTestContentResult !== 'undefined') {
        this.myContentListArray = lodash.sortBy(listMyTestContentResult, 'document.createdDate').reverse();
        this.myContentListPassCount = lodash.filter(listMyTestContentResult, {'testResult': {'isPass': true}}).length + lodash.filter(listMyTestContentResult, {'testResult': {'isPartialPass': true}}).length;
        this.myContentListFailCount = listMyTestContentResult.length - this.myContentListPassCount;

        return true; //return canActivate state once results are available
      }
    }));
  }

  navigateToUserRules(useremail){
    console.log("navigateToUserRules [" + useremail + "]");
    console.log("redirect to path [" + this.recruitUnitUtil.Constants.PATH_USER + useremail + this.recruitUnitUtil.Constants.PATH_COMPARISONRULESFORM + "]");
    this.recruitUnitUtil.Util.redirectUserToPath(this.recruitUnitUtil.Constants.PATH_USER + useremail + this.recruitUnitUtil.Constants.PATH_COMPARISONRULESFORM);
  }

  getDeveloperEmailAddress(docId, isDeveloper, displayDevEmail){
    if (!isDeveloper && displayDevEmail) {
      var localToken = this.recruitUnitUtil.Util.getLocalUser().token;

      return this.loomApi.User.getDevEmailFromDocId(docId, localToken).then(angular.bind(this, function (result) {
        return typeof result.email !== "undefined" ? result.email : result.message;
      }));
    }
  }

  showPanel(){
    console.log("in showPanel");
    var panelPosition = this._mdPanel.newPanelPosition()
      .absolute()
      .center();
    var panelAnimation = this._mdPanel.newPanelAnimation();
    panelAnimation.openFrom({top: 0, left: 0});
    panelAnimation.closeTo({top: document.documentElement.clientHeight, left: 0});
    panelAnimation.withAnimation(this._mdPanel.animation.SCALE);

    var config = {
      attachTo: angular.element(document.body),
      controller: 'genericDialogController',
      controllerAs: 'requireComparisonFormDialog',
      locals: {
        'useremail': this.recruitUnitUtil.Util.getLocalUser().email,
        'navigateToUserRules': this.navigateToUserRules
      },
      position: panelPosition,
      animation: panelAnimation,
      template: comparisonFormTemplate,
      hasBackdrop: true,
      panelClass: 'generic-dialog',
      zIndex: 150,
      clickOutsideToClose: true,
      escapeToClose: true,
      focusOnOpen: true
    }

    this._mdPanel.open(config);
  }

  toggleContactMeDialog($event, id, displayDevEmail, repeatScope){
    console.log("in toggleContactMeDialog");

    var panelPosition = this._mdPanel.newPanelPosition()
      .absolute()
      .center();
    var panelAnimation = this._mdPanel.newPanelAnimation();
    panelAnimation.openFrom({top: 0, left: 0});
    panelAnimation.closeTo({top: document.documentElement.clientHeight, left: 0});
    panelAnimation.withAnimation(this._mdPanel.animation.SCALE);

    var config = {
      attachTo: angular.element(document.body),
      controller: 'genericDialogController',
      controllerAs: 'contactMeDialog',
      locals: {
        'docId': id,
        'isDisplayDevEmail': displayDevEmail,
        'isDeveloper': this.isDeveloper,
        'developerEmailAddress': this.getDeveloperEmailAddress(id, this.isDeveloper, displayDevEmail),
        itemScope: repeatScope
      },
      bindToController: true,
      position: panelPosition,
      animation: panelAnimation,
      template: enableContactMeTemplate,
      hasBackdrop: true,
      panelClass: 'generic-dialog',
      zIndex: 150,
      clickOutsideToClose: true,
      escapeToClose: true,
      focusOnOpen: true
    }

    this._mdPanel.open(config);
  }

}

export default {
  controller: UserLandingController,
  controllerAs: 'userLanding',
  template: template,
  $canActivate: function($nextInstruction, recruitUnitUtil, jwtHelper, loomApi, globals, lodash, recruitUnitConfig){
    "ngInject";
    console.log("in UserLandingController canActivate");
    //console.log(recruitUnitConfig);

    if (recruitUnitUtil.Util.isLocalUserAvailable()) {
      var token = jwtHelper.decodeToken(recruitUnitUtil.Util.getLocalUser().token);
      var tokenUsername = token.username;
      var tokenRoles = token.roles;
      var requestedUsername = $nextInstruction.params.email;

      var serverUrl = recruitUnitUtil.Constants.APP_PROTOCOL + recruitUnitUtil.Constants.APP_HOST + ":" + recruitUnitUtil.Constants.APP_PORT;

      return recruitUnitUtil.Util.isUserAuthenticated(tokenUsername, recruitUnitUtil.Util.getLocalUser().token).then(angular.bind(this, function (result) {
        if (result == false) {
          recruitUnitUtil.Util.redirectUserToPath(recruitUnitUtil.Constants.PATH_HOME);// todo: get path from constant;
          recruitUnitUtil.Util.deleteUserAuth();
        } else if (tokenUsername != requestedUsername) {
          recruitUnitUtil.Util.redirectUserToPath(recruitUnitUtil.Constants.PATH_USER + tokenUsername);
        } else if (result.success) {
          //set user details returned from the jwt
          globals.roles = result.data.roles;
          globals.id = result.data.id;
          globals.username = result.data.displayName;
          globals.userGuid = result.data.userGuid;
          globals.userFormUrl = serverUrl + recruitUnitUtil.Constants.PATH_USER + globals.userGuid + "/form";

          if (tokenRoles.indexOf("recruiter") != -1){
            globals.isDeveloper = false;
            // var searchJson = {
            //   "authorEmail": tokenUsername
            // };
            var localToken = recruitUnitUtil.Util.getLocalUser().token;

            var selector = {
							"selector": {
								"model": "RecruitUnitJobDescription",
								"authorEmail": tokenUsername
							}
						};
            //ToDo: these 2 api calls can be consolidated into a single call
						return loomApi.Article.find(selector, localToken).then(angular.bind(this, function (result) {
							  console.log("find results:");
							  console.log(result.docs);
                if (typeof result.docs !== 'undefined' && result.docs.length > 0) {
                      globals.jobItemDocsArray = lodash.sortBy(result.docs, 'createdDate').reverse();

                      //parse recruiter JobDescription results and find matching developer JobItems
                      return result.docs.length; //return canActivate state once results are available
                } else {
                  return true;
                }
            })).then(angular.bind(this, function (result) {
              if (result > 0) {
								return loomApi.Article.getUserTestResults(null, localToken).then(angular.bind(this, function (listMyTestContentResult) {
									console.log("getUserTestResults:");
									if (typeof listMyTestContentResult !== 'undefined') {
										globals.myContentListArray = lodash.sortBy(listMyTestContentResult, 'document.createdDate').reverse();
										//globals.myContentListPassCount = lodash.filter(listMyTestContentResult, {'testResult': {'isPass': true}}).length + lodash.filter(listMyTestContentResult, {'testResult': {'isPartialPass': true}}).length;
										//globals.myContentListFailCount = listMyTestContentResult.length - globals.myContentListPassCount;

										return true; //return canActivate state once results are available
									}
								}));
							}
              return result;
            }));

						// No longer require user test results as we'll be returning list from search results.
            // return loomApi.Article.getUserTestResults(searchJson, localToken).then(angular.bind(this, function (listMyTestContentResult) {
            //   console.log("getUserTestResults:");
            //   console.log(listMyTestContentResult);
            //   if (typeof listMyTestContentResult !== 'undefined') {
            //     globals.myContentListArray = lodash.sortBy(listMyTestContentResult, 'document.createdDate').reverse();
            //     globals.myContentListPassCount = lodash.filter(listMyTestContentResult, {'testResult': {'isPass': true}}).length + lodash.filter(listMyTestContentResult, {'testResult': {'isPartialPass': true}}).length;
            //     globals.myContentListFailCount = listMyTestContentResult.length - globals.myContentListPassCount;
						//
            //     return true; //return canActivate state once results are available
            //   }
            // }));
            return true;
          } else if (tokenRoles.indexOf("developer") != -1){
            globals.isDeveloper = true;
            var searchJson = {
              "submitTo": globals.userGuid
            };
						var selector = {
							"selector": {
								"model": "RecruitUnitComparisonTest",
								"authorEmail": tokenUsername
							}
						};
            var localToken = recruitUnitUtil.Util.getLocalUser().token;
            return loomApi.Article.getUserComparisonTestResults(searchJson, localToken).then(angular.bind(this, function (listMyTestContentResult) {
              console.log("getUserTestResults:");
              console.log(listMyTestContentResult);
              if (typeof listMyTestContentResult !== 'undefined') {
								globals.jobItemDocsArray = lodash.sortBy(listMyTestContentResult, 'document.createdDate').reverse();
                //globals.myContentListPassCount = lodash.filter(listMyTestContentResult, {'testResult': {'isPass': true}}).length + lodash.filter(listMyTestContentResult, {'testResult': {'isPartialPass': true}}).length;
                //globals.myContentListFailCount = listMyTestContentResult.length - globals.myContentListPassCount;

                return listMyTestContentResult.length;
              }
            })).then(angular.bind(this, function (result) {
							if (result > 0) {
								return loomApi.Article.find(selector, localToken).then(angular.bind(this, function (listMyTestContentResult) {
								  //todo: continue fixing up below to fit new find
									console.log("getUserTestResults:");
									if (typeof listMyTestContentResult !== 'undefined') {
										globals.myContentListArray = lodash.sortBy(listMyTestContentResult, 'document.createdDate').reverse();
										//globals.myContentListPassCount = lodash.filter(listMyTestContentResult, {'testResult': {'isPass': true}}).length + lodash.filter(listMyTestContentResult, {'testResult': {'isPartialPass': true}}).length;
										//globals.myContentListFailCount = listMyTestContentResult.length - globals.myContentListPassCount;

										return true; //return canActivate state once results are available
									}
								}));
							}
							return result;
						}));
          }
        }

      }));
    } else {
      recruitUnitUtil.Util.redirectUserToPath(recruitUnitUtil.Constants.PATH_HOME);
    }
  }
}

<|endoftext|>


<commit_before>Imcms.define(
    "imcms-modal-window-builder",
    ["imcms-bem-builder", "imcms-components-builder", "jquery", "imcms-i18n-texts"],
    function (BEM, components, $, texts) {
        var $modal, $shadow;

        texts = texts.modal;

        function createModalWindow(question, callback) {
            function closeModal() {
                $modal.add($shadow).detach();
            }

            function buildHead() {
                return new BEM({
                    block: "imcms-head",
                    elements: {
                        "title": components.texts.titleText("<div>", texts.title)
                    }
                }).buildBlockStructure("<div>");
            }

            function buildBody(question) {
                return new BEM({
                    block: "imcms-modal-body",
                    elements: {
                        "text": components.texts.infoText("<div>", question)
                    }
                }).buildBlockStructure("<div>");
            }

            function buildFooter(callback) {
                var $yesButton = components.buttons.positiveButton({
                    text: texts.yes,
                    click: function () {
                        callback(true);
                        closeModal();
                    }
                });

                var $noButton = components.buttons.negativeButton({
                    text: texts.no,
                    click: function () {
                        callback(false);
                        closeModal();
                    }
                });

                return new BEM({
                    block: "imcms-modal-footer",
                    elements: {
                        "button": [$yesButton, $noButton]
                    }
                }).buildBlockStructure("<div>");
            }

            return new BEM({
                block: "imcms-modal-window",
                elements: {
                    "modal-head": buildHead(),
                    "modal-body": buildBody(question),
                    "modal-footer": buildFooter(callback)
                }
            }).buildBlockStructure("<div>");
        }

        function createLayout() {
            return $("<div>", {"class": "imcms-modal-layout imcms-modal-layout--front"});
        }

        return {
            buildModalWindow: function (question, callback) {
                $modal = createModalWindow(question, callback);
                $shadow = createLayout();

                $("body").append($shadow, $modal);
            }
        };
    }
);
<commit_msg>IMCMS-294 - ENTER (RETURN) as SAVE: - Modal windows builder refactored.<commit_after>Imcms.define(
    "imcms-modal-window-builder",
    ["imcms-bem-builder", "imcms-components-builder", "jquery", "imcms-i18n-texts"],
    function (BEM, components, $, texts) {

        texts = texts.modal;

        function buildYesButton(callback) {
            return components.buttons.positiveButton({
                text: texts.yes,
                click: callback
            });
        }

        function buildNoButton(callback) {
            return components.buttons.negativeButton({
                text: texts.no,
                click: callback
            });
        }

        function buildFooter(onConfirmed, onDeclined) {
            var $yesButton = buildYesButton(onConfirmed);
            var $noButton = buildNoButton(onDeclined);

            return new BEM({
                block: "imcms-modal-footer",
                elements: {
                    "button": [$yesButton, $noButton]
                }
            }).buildBlockStructure("<div>");
        }

        function createLayout() {
            return $("<div>", {"class": "imcms-modal-layout imcms-modal-layout--front"});
        }

        function buildHead() {
            return new BEM({
                block: "imcms-head",
                elements: {
                    "title": components.texts.titleText("<div>", texts.title)
                }
            }).buildBlockStructure("<div>");
        }

        function buildBody(question) {
            return new BEM({
                block: "imcms-modal-body",
                elements: {
                    "text": components.texts.infoText("<div>", question)
                }
            }).buildBlockStructure("<div>");
        }

        function createModalWindow(question, onConfirmed, onDeclined) {
            return new BEM({
                block: "imcms-modal-window",
                elements: {
                    "modal-head": buildHead(),
                    "modal-body": buildBody(question),
                    "modal-footer": buildFooter(onConfirmed, onDeclined)
                }
            }).buildBlockStructure("<div>");
        }

        var ModalWindow = function (question, callback) {
            this.onConfirmed = this.buildOnDecide(true, callback);
            this.onDeclined = this.buildOnDecide(false, callback);
            this.$modal = createModalWindow(question, this.onConfirmed, this.onDeclined);
        };

        ModalWindow.prototype = {

            buildOnDecide: function (isConfirm, callback) {
                var context = this;

                return function () {
                    callback(isConfirm);
                    context.closeModal();
                }
            },

            addShadow: function () {
                this.$shadow = createLayout();
                return this;
            },

            closeModal: function () {
                this.$modal.add(this.$shadow).detach();
            },

            appendTo: function ($appendToMe) {
                $appendToMe.append(this.$shadow, this.$modal);
            }
        };

        return {
            buildModalWindow: function (question, callback) {
                new ModalWindow(question, callback)
                    .addShadow()
                    .appendTo($("body"));
            }
        };
    }
);
<|endoftext|>


<commit_before>'use strict';

var Page = require('astrolabe').Page,
	baseUrl = protractor.baseUrl || "http://jamaicanpsalms.scriptureforge.local";

var SfLoginPage = require('./pages/loginPage');
var loginPage = new SfLoginPage();
var constants = require('../testConstants');

var siteAdminPage = Page.create({
	url: { value: baseUrl + "/app/siteadmin" },
	addBtn:         { get: function() { return this.findElement(this.by.buttonText('Add New')); }},
	usernameInput:  { get: function() { return this.findElement(this.by.model('record.username')); }},
	nameInput:      { get: function() { return this.findElement(this.by.model('record.name')); }},
	emailInput:     { get: function() { return this.findElement(this.by.model('record.email')); }},
	// roleInput:      { get: function() { return this.findElement(this.by.model('record.role')); }}, // Not needed right now as "User" is default role
	activeCheckbox: { get: function() { return this.findElement(this.by.model('record.active')); }},
	passwordInput:  { get: function() { return this.findElement(this.by.model('record.password')); }},

	clearForm: { value: function() {
		this.usernameInput.clear();
		this.nameInput.clear();
		this.emailInput.clear();
		this.passwordInput.clear();
		//this.activeCheckbox.clear();
	}},
});

describe('Test setup', function() {
	it('verifies that the test_runner_admin account is valid (if this fails, EVERYTHING ELSE will fail!)', function() {

		loginPage.loginAsAdmin();
		// Verify that I'm logged in as an admin by making sure I have a link to app/siteadmin in my user menu
		expect(browser.driver.isElementPresent(by.xpath('.//a[@href="/app/siteadmin"]'))).toBeTruthy();
	});

	it('creates the test project, project manager, and project member accounts used in the rest of the E2E tests', function() {
		siteAdminPage.go();

		// Add project manager account
		siteAdminPage.addBtn.click();
		siteAdminPage.usernameInput.sendKeys(loginPage.managerUsername);
		siteAdminPage.nameInput    .click(); // Make the onBlur() events fire on username input field
		siteAdminPage.nameInput    .sendKeys('Test Manager');
		siteAdminPage.emailInput   .sendKeys(loginPage.managerUsername + '@example.com');
		// siteAdminPage.roleInput .doSomething(); // Not needed right now as "User" is default role
		siteAdminPage.activeCheckbox.isSelected().then(function(checked) {
			// Slightly complicated way to say "activeCheckbox = true", but that's how we need to do it in an E2E testing environment.
			if (!checked) {
				siteAdminPage.activeCheckbox.click();
			};
		});
		siteAdminPage.passwordInput.sendKeys(loginPage.managerPassword);
		siteAdminPage.passwordInput.sendKeys(protractor.Key.ENTER);

		// Add regular user account
		siteAdminPage.clearForm(); // Otherwise we could end up trying to add the user "test_runner_manager_usertest_runner_normal_user"
		siteAdminPage.addBtn.click();
		siteAdminPage.usernameInput.sendKeys(loginPage.memberUsername);
		siteAdminPage.nameInput    .click(); // Make the onBlur() events fire on username input field
		siteAdminPage.nameInput    .sendKeys('Test User');
		siteAdminPage.emailInput   .sendKeys(loginPage.memberUsername + '@example.com');
		siteAdminPage.activeCheckbox.isSelected().then(function(checked) {
			// Slightly complicated way to say "activeCheckbox = true", but that's how we need to do it in an E2E testing environment.
			if (!checked) {
				siteAdminPage.activeCheckbox.click();
			};
		});
		siteAdminPage.passwordInput.sendKeys(loginPage.memberPassword);
		siteAdminPage.passwordInput.sendKeys(protractor.Key.ENTER);
	});

	it('deletes and re-creates the test project', function() {
		var ProjectsPage = require('./pages/projectsPage');
		var projectsPage = new ProjectsPage();
		projectsPage.get();
		projectsPage.deleteProject(projectsPage.testProjectName);
		// You could call deleteProject() several times without reloading the page, and it would work:
		//projectsPage.deleteProject("FooBar");
		//projectsPage.deleteProject("Quux");
		projectsPage.addProject(projectsPage.testProjectName);
	});
});
<commit_msg>Adjust tests to use new constants module<commit_after>'use strict';

var Page = require('astrolabe').Page,
	baseUrl = protractor.baseUrl || "http://jamaicanpsalms.scriptureforge.local";

var SfLoginPage = require('./pages/loginPage');
var loginPage = new SfLoginPage();
var constants = require('../testConstants');

var siteAdminPage = Page.create({
	url: { value: baseUrl + "/app/siteadmin" },
	addBtn:         { get: function() { return this.findElement(this.by.buttonText('Add New')); }},
	usernameInput:  { get: function() { return this.findElement(this.by.model('record.username')); }},
	nameInput:      { get: function() { return this.findElement(this.by.model('record.name')); }},
	emailInput:     { get: function() { return this.findElement(this.by.model('record.email')); }},
	// roleInput:      { get: function() { return this.findElement(this.by.model('record.role')); }}, // Not needed right now as "User" is default role
	activeCheckbox: { get: function() { return this.findElement(this.by.model('record.active')); }},
	passwordInput:  { get: function() { return this.findElement(this.by.model('record.password')); }},

	clearForm: { value: function() {
		this.usernameInput.clear();
		this.nameInput.clear();
		this.emailInput.clear();
		this.passwordInput.clear();
		//this.activeCheckbox.clear();
	}},
});

describe('Test setup', function() {
	it('verifies that the test_runner_admin account is valid (if this fails, EVERYTHING ELSE will fail!)', function() {

		loginPage.loginAsAdmin();
		// Verify that I'm logged in as an admin by making sure I have a link to app/siteadmin in my user menu
		expect(browser.driver.isElementPresent(by.xpath('.//a[@href="/app/siteadmin"]'))).toBeTruthy();
	});

	it('creates the test project, project manager, and project member accounts used in the rest of the E2E tests', function() {
		siteAdminPage.go();

		// Add project manager account
		siteAdminPage.addBtn.click();
		siteAdminPage.usernameInput.sendKeys(constants.managerUsername);
		siteAdminPage.nameInput    .click(); // Make the onBlur() events fire on username input field
		siteAdminPage.nameInput    .sendKeys(constants.managerName);
		siteAdminPage.emailInput   .sendKeys(constants.managerEmail);
		// siteAdminPage.roleInput .doSomething(); // Not needed right now as "User" is default role
		siteAdminPage.activeCheckbox.isSelected().then(function(checked) {
			// Slightly complicated way to say "activeCheckbox = true", but that's how we need to do it in an E2E testing environment.
			if (!checked) {
				siteAdminPage.activeCheckbox.click();
			};
		});
		siteAdminPage.passwordInput.sendKeys(constants.managerPassword);
		siteAdminPage.passwordInput.sendKeys(protractor.Key.ENTER);

		// Add regular user account
		siteAdminPage.clearForm(); // Otherwise we could end up trying to add the user "test_runner_manager_usertest_runner_normal_user"
		siteAdminPage.addBtn.click();
		siteAdminPage.usernameInput.sendKeys(constants.memberUsername);
		siteAdminPage.nameInput    .click(); // Make the onBlur() events fire on username input field
		siteAdminPage.nameInput    .sendKeys(constants.memberName);
		siteAdminPage.emailInput   .sendKeys(constants.memberEmail);
		siteAdminPage.activeCheckbox.isSelected().then(function(checked) {
			// Slightly complicated way to say "activeCheckbox = true", but that's how we need to do it in an E2E testing environment.
			if (!checked) {
				siteAdminPage.activeCheckbox.click();
			};
		});
		siteAdminPage.passwordInput.sendKeys(constants.memberPassword);
		siteAdminPage.passwordInput.sendKeys(protractor.Key.ENTER);
	});

	it('deletes and re-creates the test project', function() {
		var ProjectsPage = require('./pages/projectsPage');
		var projectsPage = new ProjectsPage();
		projectsPage.get();
		projectsPage.deleteProject(projectsPage.testProjectName);
		// You could call deleteProject() several times without reloading the page, and it would work:
		//projectsPage.deleteProject("FooBar");
		//projectsPage.deleteProject("Quux");
		projectsPage.addProject(projectsPage.testProjectName);
	});
});
<|endoftext|>