Source: angular-app/suxessApp.js

'use strict';

/**
 * Suxess app module
 *
 * You can use $rootScope.userIsLogged and $rootScope.user to check whether user
 * is validated or not.
 *
 * @type {*|module}
 */

var suxessApp = angular.module('suxessApp', [

    'ngRoute',
    'ngCookies',
    'ng-token-auth',
    'suxessControllers',
    'suxessDirectives',
    'suxessServices',
    'ui.router',
    'restangular',
    'ui.bootstrap',
    'ngMessages',
    'validation.match',
    'ncy-angular-breadcrumb',
    'xeditable',
    'monospaced.elastic',
    'ui.bootstrap.contextMenu',
    'chart.js',
    'angular-clipboard'

]);

suxessApp.config([

    '$routeProvider',
    '$authProvider',
    '$locationProvider',
    '$stateProvider',
    '$urlRouterProvider',
    'RestangularProvider',
    '$breadcrumbProvider',

    function(

        $routeProvider,
        $authProvider,
        $locationProvider,
        $stateProvider,
        $urlRouterProvider,
        RestangularProvider,
        $breadcrumbProvider

    ) {

        // Sets api requests url
        RestangularProvider.setBaseUrl('/api/');

        //
        // RULES
        //

        // Adds rule to simulate HTML5 on development
        $urlRouterProvider.rule(function($injector, $location) {

            var url = $location.url().replace('?goto=', '');
            $location.url(url);

        });

        //
        // ROUTES
        //

        // Default state
        $urlRouterProvider.otherwise('');

        //breadcrumb global configuration
        $breadcrumbProvider.setOptions({

            templateUrl: 'angular-app/templates/views/breadcrumb.html'

        });

        //Routes
        $stateProvider
            .state('no-menu', {

                abstract: true,
                templateUrl: 'angular-app/templates/views/no-menu-template.html'

            })
            .state('nav-only', {

                abstract: true,
                parent: 'no-menu',
                templateUrl: 'angular-app/templates/views/navigation-only-template.html'

            })
            .state('nav-side', {

                abstract: true,
                parent: 'no-menu',
                templateUrl: 'angular-app/templates/views/navigation-sidebar-template.html',
                controller: 'NavSideBarController'

            })
            .state('home', {
                parent: 'no-menu',
                url: '/',
                templateUrl: 'angular-app/templates/home.html',
                controller: 'HomeController'
            })
            .state('project', {
                parent: 'nav-only',
                resolve: {
                    projectsObj: function(projectService) {
                        return projectService.getAll();
                    }
                },
                url: '/projects',
                templateUrl: 'angular-app/templates/views/project/project.html',
                controller: 'ProjectController',
                ncyBreadcrumb: {
                    label: 'Home'
                }
            })
            .state('project-detail', {
                parent: 'nav-side',
                resolve: {
                    project: function(projectService, $stateParams) {
                        return projectService.get($stateParams.projectId);
                    },
                    prototypes: function(prototypeService, $stateParams) {
                        return prototypeService.getAll($stateParams.projectId);
                    },
                    files: function(projectService, $stateParams) {
                        return projectService.getAllFiles($stateParams.projectId);
                    }
                },
                url: '/project/:projectId',
                templateUrl: 'angular-app/templates/views/project/project-detail.html',
                controller: 'ProjectDetailController',
                ncyBreadcrumb: {
                    parent: 'project',
                    label: '{{project.name}}'
                }
            })
            .state('mockup-editor', {
                url: '/project/:projectId/prototype/:prototypeId/editor/',
                templateUrl: 'angular-app/templates/views/mockup-editor/mockup-editor.html',
                controller: 'MockupEditorController',
                resolve: {
                    mockups: function(projectService, $stateParams) {

                        return projectService.getPrototypeMockups(
                                $stateParams.projectId,
                                $stateParams.prototypeId
                            );

                    },
                    project: function(projectService, $stateParams) {
                        return projectService.get($stateParams.projectId);
                    },

                    prototype: function(prototypeService, $stateParams) {
                        return prototypeService.get($stateParams.prototypeId);

                    }
                }
            })
            .state('prototype', {
                parent: 'nav-side',
                url: '/project/:projectId/prototypes',
                templateUrl: 'angular-app/templates/views/project/prototype/prototype.html',
                controller: 'PrototypeController',
                resolve: {
                    project: function(projectService, $stateParams) {
                        return projectService.get($stateParams.projectId);
                    },
                    prototypes: function(prototypeService, $stateParams) {
                        return prototypeService.getAll($stateParams.projectId);
                    }
                },
                ncyBreadcrumb: {
                    parent: 'project-detail',
                    label: 'Prototypes'
                }
            })
            .state('test', {
                parent: 'nav-side',
                url: '/project/:projectId/tests',
                templateUrl: 'angular-app/templates/views/project/test/tests.html',
                controller: 'TestController',
                resolve: {
                    project: function(projectService, $stateParams) {
                        return projectService.get($stateParams.projectId);
                    }
                },
                ncyBreadcrumb: {
                    parent: 'project-detail',
                    label: 'Tests'
                }
            })
            .state('test-digest', {
              parent: 'no-menu',
              url: '/test/:digest',
              templateUrl: 'angular-app/templates/views/project/test/test-display.html',
              controller: 'TestPlayController',
              resolve: {
                  test: function(testService, $stateParams) {
                      return testService.getByDigest(
                          $stateParams.digest
                      );
                  },
              }
            })
            .state('task', {
                parent: 'nav-side',
                url: '/project/:projectId/test/:testId/tasks',
                templateUrl: 'angular-app/templates/views/project/test/task/tasks.html',
                controller: 'TaskController',
                resolve: {
                    tasks: function(taskService, $stateParams) {

                        return taskService.getAll(
                            $stateParams.projectId,
                            $stateParams.testId
                        );

                    },
                    project: function(projectService, $stateParams) {
                        return projectService.get($stateParams.projectId);
                    },
                    test: function(testService, $stateParams) {
                        return testService.one($stateParams.projectId,$stateParams.testId);
                    }
                },
                ncyBreadcrumb: {
                    parent: 'test',
                    label: '{{test.name}}'
                }
            })
            .state('test-preview', {
                url: '/preview/:testId/:taskId/:mockupId',
                templateUrl: 'angular-app/templates/views/project/test/test-display.html',
                controller: 'TestDisplayController',
                resolve: {
                    test: function(Restangular, $stateParams) {
                        return Restangular.one('tests', $stateParams.testId).get({show_all: true});
                    },
                    task: function($stateParams, test) {
                        return test.tasks.filter(function (t) {
                            return (parseInt(t.id) === parseInt($stateParams.taskId));
                        })[0];
                    },
                    tasks: function($stateParams, test) {
                        console.log(test);
                        return test.tasks;
                    },
                    elements: function(task, $stateParams){
                        var mockElems;
                        if($stateParams.mockupId === ''){
                            mockElems = task.prototype.mockups[0].elements;
                        }
                        else{
                            mockElems = task.prototype.mockups.filter(function (t) {
                                return (parseInt(t.id) === parseInt($stateParams.mockupId));
                            })[0].elements;
                        }
                        return mockElems;

                    }
                },
                params: {
                    log: { value: false },
                    descriptionState: {value : 'task-preview-description'}
                }
            })
            .state('test-run', {
                url: '/run/:testId/:taskId/:mockupId',
                templateUrl: 'angular-app/templates/views/project/test/test-display.html',
                controller: 'TestDisplayController',
                resolve: {
                    test: function(Restangular, $stateParams) {
                        return Restangular.one('tests', $stateParams.testId).get({show_all: true});
                    },
                    task: function($stateParams, test) {
                        return test.tasks.filter(function (t) {
                            return (parseInt(t.id) === parseInt($stateParams.taskId));
                        })[0];
                    },
                    tasks: function($stateParams, test) {
                        console.log(test);
                        return test.tasks;
                    },
                    taskRunId: function(Restangular, $cookies, $stateParams, $q){
                        var taskRunId = $cookies.get('taskId-' + $stateParams.taskId);
                        if(taskRunId !== undefined){
                            return taskRunId;
                        }
                        else {
                            var deferred = $q.defer();
                            Restangular.one('tasks', $stateParams.taskId).all('task_runs').post({
                                    started_at: Date.now()
                                })
                                .then(function(taskRun) {
                                    $cookies.put('taskId-' + $stateParams.taskId, taskRun.id);
                                    deferred.resolve(taskRun.id);
                            });
                            return deferred;
                        }
                    },
                    testRunId: function(Restangular, $cookies, $q, test){
                        var testRunId = $cookies.get('testId-' + test.id);
                        if(testRunId !== undefined){
                            return testRunId;
                        }
                        else {
                            var userAgent = new SUXESS.UserAgentLogger();
                            var data = {
                                'os': userAgent._os[0],
                                'os_version': userAgent._os[1],
                                'browser': userAgent._browser,
                                'mobile': userAgent._mobile,
                                'screen_width': userAgent._screenSize[0],
                                'screen_height': userAgent._screenSize[1]

                            };
                            var deferred = $q.defer();
                            Restangular.one('tests', test.id).all('test_runs').post(data)
                                .then(function(testRun){
                                    $cookies.put('testId-' + test.id, testRun.id);
                                    deferred.resolve(testRun.id);
                            });
                            return deferred;
                        }
                    },
                    elements: function(task, $stateParams){
                        var mockElems;
                        if($stateParams.mockupId === ''){
                            mockElems = task.prototype.mockups[0].elements;
                        }
                        else{
                            mockElems = task.prototype.mockups.filter(function (t) {
                                return (parseInt(t.id) === parseInt($stateParams.mockupId));
                            })[0].elements;
                        }
                        return mockElems;

                    }
                },
                params: {
                    log: { value: true },
                    descriptionState: {value : 'task-run-description'}
                }
            })
            .state('test-hash', {
                url: '/test/:testId/:taskId/:mockupId',
                templateUrl: 'angular-app/templates/views/project/test/test-display.html',
                controller: 'TestDisplayController',
                resolve: {
                    test: function(testService, $stateParams) {
                        return testService.getByDigest($stateParams.testId);
                    },
                    task: function($stateParams, test) {
                        return test.tasks.filter(function (t) {
                            return (parseInt(t.id) === parseInt($stateParams.taskId));
                        })[0];
                    },
                    tasks: function($stateParams, test) {
                        console.log(test);
                        return test.tasks;
                    },
                    taskRunId: function(Restangular, $cookies, $stateParams, $q){
                        var taskRunId = $cookies.get('taskId-' + $stateParams.taskId);
                        if(taskRunId !== undefined){
                            return taskRunId;
                        }
                        else {
                            var deferred = $q.defer();
                            Restangular.one('tasks', $stateParams.taskId).all('task_runs').post({
                                    started_at: Date.now()
                                })
                                .then(function(taskRun){
                                    $cookies.put('taskId-' + $stateParams.taskId, taskRun.id);
                                    deferred.resolve(taskRun.id);
                            });
                            return deferred;
                        }
                    },
                    testRunId: function(Restangular, $cookies, $q, test){
                        var testRunId = $cookies.get('testId-' + test.id);
                        if(testRunId !== undefined){
                            return testRunId;
                        }
                        else {
                            var userAgent = new SUXESS.UserAgentLogger();
                            var data = {
                                'os': userAgent._os[0],
                                'os_version': userAgent._os[1],
                                'browser': userAgent._browser,
                                'mobile': userAgent._mobile,
                                'screen_width': userAgent._screenSize[0],
                                'screen_height': userAgent._screenSize[1]

                            };
                            var deferred = $q.defer();
                            Restangular.one('tests', test.id).all('test_runs').post(data)
                                .then(function(testRun){
                                    $cookies.put('testId-' + test.id, testRun.id);
                                    deferred.resolve(testRun.id);
                            });
                            return deferred;
                        }
                    },
                    elements: function(task, $stateParams){
                        var mockElems;
                        if($stateParams.mockupId === ''){
                            mockElems = task.prototype.mockups[0].elements;
                        }
                        else{
                            mockElems = task.prototype.mockups.filter(function (t) {
                                return (parseInt(t.id) === parseInt($stateParams.mockupId));
                            })[0].elements;
                        }
                        return mockElems;

                    }
                },
                params: {
                    log: { value: true },
                    descriptionState: {value : 'task-hash-description'}
                }
            })
            .state('task-preview-description', {
                url: '/description-preview/:testId/:taskId/',
                templateUrl: 'angular-app/templates/views/project/test/task/task-desc.html',
                controller: 'TaskDescController',
                resolve: {
                    task: function(Restangular, $stateParams) {
                        return Restangular.one('tasks', $stateParams.taskId).get();
                    }
                },
                params: {
                    prototypeState: { value: 'test-preview' }
                }
            })
            .state('task-run-description', {
                url: '/description-run/:testId/:taskId/',
                templateUrl: 'angular-app/templates/views/project/test/task/task-desc.html',
                controller: 'TaskDescController',
                resolve: {
                    task: function(Restangular, $stateParams) {
                        return Restangular.one('tasks', $stateParams.taskId).get();
                    }
                },
                params: {
                    prototypeState: { value: 'test-run' }
                }
            })
            .state('task-hash-description', {
                url: '/description-hash/:testId/:taskId/',
                templateUrl: 'angular-app/templates/views/project/test/task/task-desc.html',
                controller: 'TaskDescController',
                resolve: {
                    task: function(testService, $stateParams, Restangular) {
                        return testService.getByDigest($stateParams.testId).then(function(test){
                            return test.tasks.filter(function (t) {
                                return (parseInt(t.id) === parseInt($stateParams.taskId));
                            })[0];
                        });
                    }
                },
                params: {
                    prototypeState: { value: 'test-hash' }
                }
            })
            .state('prototype-preview', {
                url: '/prototype-preview/:projectId/:prototypeId/:mockupId',
                templateUrl: 'angular-app/templates/views/mockup-editor/prototype-preview.html',
                controller: 'PrototypePreviewController',
                resolve: {
                    prototype: function (prototypeService, $stateParams) {
                        return prototypeService.get($stateParams.prototypeId);
                    },
                    elements: function(projectService, $stateParams){
                        return projectService.getPrototypeMockups(
                            $stateParams.projectId, $stateParams.prototypeId
                        ).then(function (mockups) {
                            if($stateParams.mockupId === ''){
                                return mockups[0].all('elements').getList();
                            }
                            else{
                                return mockups.filter(function (t) {
                                    return (parseInt(t.id) === parseInt($stateParams.mockupId));
                                })[0].all('elements').getList();
                            }
                        });
                    }
                }
            })
            .state('test-end', {
                url: '/test-end',
                templateUrl: 'angular-app/templates/views/project/test/test-end.html',
                controller: 'TestEndController'
            })
            .state('results', {
                parent: 'nav-side',
                url: '/project/:projectId/test/:testId/results',
                templateUrl: 'angular-app/templates/views/project/result.html',
                controller: 'ResultController',
                resolve: {
                    project: function(projectService, $stateParams) {
                        return projectService.get($stateParams.projectId);
                    },
                    results: function(resultService, $stateParams){
                        return resultService.getByTestId($stateParams.testId);
                    },
                    test: function(Restangular, $stateParams) {
                        return Restangular.one('tests', $stateParams.testId).get({show_all: true});
                    }
                },
                ncyBreadcrumb: {
                    parent: 'task',
                    label: 'Results'
                }
            });

        // HTML 5
        //if (window.history && window.history.pushState) {
        //
        //    $locationProvider.html5Mode({
        //        enabled: true,
        //        requireBase: false
        //    });
        //
        //}

        //
        // AUTHENTICATION
        //

        //TODO FIX THIS SHIT, REDIRECT WHEN NOT AUTHORIZED
        $authProvider.configure({
            apiUrl:                  '/api',
            tokenValidationPath:     '/auth/validate_token',
            signOutUrl:              '/auth/sign_out',
            emailRegistrationPath:   '/auth',
            accountUpdatePath:       '/auth',
            accountDeletePath:       '/auth',
            confirmationSuccessUrl:  window.location.href,
            passwordResetPath:       '/auth/password',
            passwordUpdatePath:      '/auth/password',
            passwordResetSuccessUrl: window.location.href,
            emailSignInPath:         '/auth/sign_in',
            storage:                 'cookies',
            forceValidateToken:      false,
            validateOnPageLoad:      true,
            omniauthWindowType:      'sameWindow',

            parseExpiry: function(headers) {

                // convert from UTC ruby (seconds) to UTC js (milliseconds)
                return (parseInt( headers.expiry ) * 1000) || null;

            },
            handleLoginResponse: function(response) {

                return response.data;

            },
            handleAccountUpdateResponse: function(response) {

                return response.data;

            },
            handleTokenValidationResponse: function(response) {

                return response.data;

            }
        });

    }

]);

suxessApp.run(['$rootScope', '$state',

    function($rootScope, $state) {

        // Event manager setup
        SUXESS.eventManager.setRootScope($rootScope);

        // USER ON ROOT SCOPE
        $rootScope.userIsLogged = false;
        $rootScope.user = {};

        $rootScope.$on('auth:login-success', function(ev, user) {

            $rootScope.userIsLogged = true;
            $rootScope.user = user;
            console.log('User logged in successfully');

        });

        $rootScope.$on('auth:logout-success', function(ev, user) {

            $rootScope.userIsLogged = false;
            $rootScope.user = {};
            console.log('User logged out successfully');

        });

        $rootScope.$on('auth:validation-success', function(ev, user) {

            $rootScope.userIsLogged = true;
            $rootScope.user = user;
            console.log('User validated successfully');

        });

        $rootScope.$on('$stateChangeSuccess', function() {
            document.body.scrollTop = document.documentElement.scrollTop = 0;
        });

        //// SECURITY STATE CHECK
        //
        //var deafultState = 'home';
        //var secureCheck = new SUXESS.SecureStateCheck(
        //    [ 'project']
        //);
        //
        //// on state change check for access
        //// TODO Throw invalid access event for flash messages
        //
        //$rootScope.$on( '$stateChangeStart',
        //
        //    function(event, toState, toParams, fromState, fromParams) {
        //
        //        if (!secureCheck.hasAccess(toState, $rootScope.user)) {
        //
        //            $state.transitionTo(deafultState);
        //            event.preventDefault();
        //
        //        }
        //
        //    }
        //);

        $rootScope.$on('$stateChangeError',

            function (event, toState, toParams, fromState, fromParams, error) {

                console.log(error);
                SUXESS.showMessage.error('Error occurred during page resolve.','Error');

            }

        );

    }

]);

// XEDITABLE
suxessApp.run(function( editableOptions, editableThemes ) {
    editableOptions.theme = 'bs3'; // bootstrap3 theme. Can be also 'bs2', 'default'
});