Commit 944ead14 authored by Evren Kutar's avatar Evren Kutar

merge

parents fbd02c97 2ade4514
...@@ -107,3 +107,6 @@ coverage/ ...@@ -107,3 +107,6 @@ coverage/
sync sync
*.rdb *.rdb
api-docs/
api-docs-source/
\ No newline at end of file
...@@ -100,6 +100,17 @@ module.exports = function (grunt) { ...@@ -100,6 +100,17 @@ module.exports = function (grunt) {
{expand: true, cwd: 'app/bower_components/jquery/dist/', src: 'jquery.min.js', dest: 'dist/bower_components/', flatten: true, filter: 'isFile'}, {expand: true, cwd: 'app/bower_components/jquery/dist/', src: 'jquery.min.js', dest: 'dist/bower_components/', flatten: true, filter: 'isFile'},
{expand: true, cwd: 'app/bower_components/angular/', src: 'angular.js', dest: 'dist/bower_components/', flatten: true, filter: 'isFile'} {expand: true, cwd: 'app/bower_components/angular/', src: 'angular.js', dest: 'dist/bower_components/', flatten: true, filter: 'isFile'}
] ]
},
for_api_docs: {
files: [
{expand: true, cwd: "app/", src: "app.js", dest: "api-docs-source/"},
{expand: true, cwd: "app/zetalib/", src: "interceptors.js", dest: "api-docs-source/"},
{expand: true, cwd: "app/zetalib/", src: "form_service.js", dest: "api-docs-source/"},
{expand: true, cwd: "app/shared/", src: "directives.js", dest: "api-docs-source/"},
{expand: true, cwd: "app/components/auth/", src: "auth_controller.js", dest: "api-docs-source/"},
{expand: true, cwd: "app/components/auth/", src: "auth_service.js", dest: "api-docs-source/"},
{expand: true, cwd: "app/components/crud/", src: "crud_controller.js", dest: "api-docs-source/"}
]
} }
}, },
concat: { concat: {
...@@ -216,6 +227,14 @@ module.exports = function (grunt) { ...@@ -216,6 +227,14 @@ module.exports = function (grunt) {
"app/bower_components/intro.js/themes/introjs-nassim.css" "app/bower_components/intro.js/themes/introjs-nassim.css"
], ],
dest: 'dist/<%= grunt.branchname %>/css/app.css' dest: 'dist/<%= grunt.branchname %>/css/app.css'
},
docs: {
src: ['docs/templates/index_head', 'docs/html/partials/api/**/*.html', 'docs/templates/index_tail'],
dest: 'docs/html/partials/api/index.html'
},
docs_list: {
src: ['docs/html/partials/api/**/index.html'],
dest: 'docs/html/partials/api/list.html'
} }
}, },
watch: { watch: {
...@@ -323,6 +342,39 @@ module.exports = function (grunt) { ...@@ -323,6 +342,39 @@ module.exports = function (grunt) {
} }
} }
} }
},
jsdoc: {
dist: {
src: [
"app/app.js",
"app/zetalib/interceptors.js",
"app/zetalib/form_service.js",
"app/shared/directives.js",
"app/components/auth/auth_controller.js",
"app/components/auth/auth_service.js",
"app/components/crud/crud_controller.js"
],
options: {
destination: 'docs/html',
configure: 'node_modules/angular-jsdoc/common/conf.json',
template: 'node_modules/angular-jsdoc/angular-template',
//tutorial: 'tutorials',
readme: './docs/DOCS.md'
}
}
},
mrdoc: {
custom: {
src: 'api-docs-source',
target: 'api-docs',
options: {
title: 'Ulakbus UI',
readme: './docs/DOCS.md'
//theme: 'cayman'
}
}
} }
}); });
...@@ -339,9 +391,12 @@ module.exports = function (grunt) { ...@@ -339,9 +391,12 @@ module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-angular-gettext'); grunt.loadNpmTasks('grunt-angular-gettext');
grunt.loadNpmTasks('grunt-preprocess'); grunt.loadNpmTasks('grunt-preprocess');
grunt.loadNpmTasks('grunt-env'); grunt.loadNpmTasks('grunt-env');
grunt.loadNpmTasks('grunt-jsdoc');
grunt.loadNpmTasks('grunt-mrdoc');
grunt.registerTask('dev', ['env:dev', 'preprocess:dev', 'html2js:dev', 'default']); grunt.registerTask('dev', ['env:dev', 'preprocess:dev', 'html2js:dev', 'default']);
grunt.registerTask('test', ['bower', 'karma:continuous']); grunt.registerTask('test', ['bower', 'karma:continuous']);
grunt.registerTask('api-docs', ['copy:for_api_docs', 'mrdoc']);
grunt.registerTask('i18n', ['nggettext_extract', 'nggettext_compile']); grunt.registerTask('i18n', ['nggettext_extract', 'nggettext_compile']);
grunt.registerTask('local_prod', ['bower', 'env:prod', 'preprocess:prod', 'nggettext_compile', 'concat:js', 'concat:css', 'concat:components', 'copy:local_prod', 'html2js:prod', 'uglify:dist', 'connect:prod_server', 'watch:local_prod']); grunt.registerTask('local_prod', ['bower', 'env:prod', 'preprocess:prod', 'nggettext_compile', 'concat:js', 'concat:css', 'concat:components', 'copy:local_prod', 'html2js:prod', 'uglify:dist', 'connect:prod_server', 'watch:local_prod']);
grunt.registerTask('default', ['bower', 'env:prod', 'preprocess:prod', 'nggettext_compile', 'concat:js', 'concat:css', 'concat:components', 'copy:prod', 'html2js:prod', 'uglify:dist']); grunt.registerTask('default', ['bower', 'env:prod', 'preprocess:prod', 'nggettext_compile', 'concat:js', 'concat:css', 'concat:components', 'copy:prod', 'html2js:prod', 'uglify:dist']);
...@@ -362,11 +417,4 @@ module.exports = function (grunt) { ...@@ -362,11 +417,4 @@ module.exports = function (grunt) {
'uglify:branch' 'uglify:branch'
]); ]);
}); });
grunt.registerTask('dgeni', 'Generate docs via dgeni.', function() {
var Dgeni = require('dgeni');
var done = this.async();
var dgeni = new Dgeni([require('./docs/docs_conf')]);
dgeni.generate().then(done);
});
}; };
\ No newline at end of file
0.6.10 0.7
\ No newline at end of file \ No newline at end of file
...@@ -91,6 +91,13 @@ a:hover { ...@@ -91,6 +91,13 @@ a:hover {
letter-spacing: 0.5px; letter-spacing: 0.5px;
} }
img.header-profile {
width:27px;
height:27px;
border-radius:100%;
margin-right:6px;
}
/** DETAIL PAGE **/ /** DETAIL PAGE **/
.detail-page { .detail-page {
...@@ -360,11 +367,15 @@ select { ...@@ -360,11 +367,15 @@ select {
.manager-view-inner { .manager-view-inner {
height:calc(100% - 41px); height:calc(100% - 41px);
-webkit-height:calc(100% - 41px); -webkit-height:calc(100% - 41px);
width:100%;
display: -webkit-flex; display: -webkit-flex;
display: flex; display: flex;
-webkit-flex-direction: column; -webkit-flex-direction: column;
flex-direction: column; flex-direction: column;
-webkit-transition: all .2s;
-moz-transition: all .2s;
-ms-transition: all .2s;
-o-transition: all .2s;
transition: all .2s;
} }
.manager-view-header { .manager-view-header {
...@@ -1152,15 +1163,19 @@ table.dataTable thead .sorting:after { ...@@ -1152,15 +1163,19 @@ table.dataTable thead .sorting:after {
} }
.right-sidebar { .right-sidebar {
width: 300px; width: 0px;
background-color: #FFFFFF; background-color: #FFFFFF;
border-left: 1px solid #ccc; border-left: 1px solid #ccc;
/*height: calc(100% - 140px);*/
height: calc(100% - 40px); height: calc(100% - 40px);
position: absolute; position: absolute;
top: 0px; top: 0px;
right: 0px; right: 0px;
overflow-y: auto; overflow-y: auto;
-webkit-transition: all .2s;
-moz-transition: all .2s;
-ms-transition: all .2s;
-o-transition: all .2s;
transition: all .2s;
} }
.right-sidebar-box { .right-sidebar-box {
...@@ -1335,6 +1350,63 @@ table.dataTable thead .sorting:after { ...@@ -1335,6 +1350,63 @@ table.dataTable thead .sorting:after {
/* END OF DASHBOARD */ /* END OF DASHBOARD */
/* SELECTED PERSON FIELD */
.selected-person-field .right-sidebar-header {
height:43px;
width:100%;
}
.selected-person-field .right-sidebar-header .bar-title {
margin-left: 10px;
height: 43px;
line-height: 43px;
font-family: 'robotomedium';
font-size: 15px;
}
.selected-person-field .right-sidebar-header .unselect-person {
height: 43px;
width: 43px;
font-size: 24px;
line-height: 43px;
float: right;
text-align: center;
cursor:pointer;
-webkit-transition: all .2s;
-moz-transition: all .2s;
-ms-transition: all .2s;
-o-transition: all .2s;
transition: all .2s;
}
.selected-person-field .right-sidebar-header .unselect-person:hover > i{
color:#333;
}
.selected-person-field .right-sidebar-header .unselect-person i {
color:#999;
}
.selected-person-field img.selected-person-img {
width:150px;
height:150px;
border-radius:100%;
margin-top:5px;
margin-left:75px;
margin-right:75px;
}
.selected-person-field .selected-person-info .selected-person-name {
width:100%;
padding:15px 20px;
text-align:center;
font-family:'robotomedium';
font-size:18px;
}
/* END OF SELECTED PERSON FIELD */
/* PERSONNEL INFO */ /* PERSONNEL INFO */
......
...@@ -8,14 +8,26 @@ ...@@ -8,14 +8,26 @@
'use strict'; 'use strict';
var app = angular.module( /**
* @ngdoc module
* @name ulakbus
* @module ulakbus
* @description Ulakbus module is the main module of ulakbus-ui.
* All application-wide configurations and definings of constants handled in this module.
*
* There are two scripts on `app/` root; `main.js` and `app.js`. And `main.html`, `index.html`.
* `main.*` files are contains both production and development requirements or configurations/necessities for relative environment.
* Tagged with `NODE_ENV='PRODUCTION'` in commented line and configured in Gruntfile.js with package `preprocess` and `env`, related grunt command generates index.* for given file.
*
*/
angular.module(
'ulakbus', [ 'ulakbus', [
'ui.bootstrap', 'ui.bootstrap',
'angular-loading-bar', 'angular-loading-bar',
'ngRoute', 'ngRoute',
'ngSanitize', 'ngSanitize',
'ngCookies', 'ngCookies',
'formService', 'ulakbus.formService',
'ulakbus.dashboard', 'ulakbus.dashboard',
'ulakbus.auth', 'ulakbus.auth',
'ulakbus.error_pages', 'ulakbus.error_pages',
...@@ -26,12 +38,17 @@ var app = angular.module( ...@@ -26,12 +38,17 @@ var app = angular.module(
//'schemaForm', //'schemaForm',
'gettext', 'gettext',
'ulakbus.uitemplates' 'ulakbus.uitemplates'
]). ])
/** /**
* RESTURL is the url of rest api to talk * @memberof ulakbus
* Based on the environment it changes from dev to prod * @ngdoc constant
* @name RESTURL
* @description RESTURL is the url of rest api to talk.
* Based on the environment it changes from dev to prod.
*
* For development needs backendurl can be switched from both dev/settings page and querystring `?backendurl=http://example.com`
*/ */
constant("RESTURL", (function () { .constant("RESTURL", (function () {
// todo: below backendurl definition is for development purpose and will be deleted // todo: below backendurl definition is for development purpose and will be deleted
var backendurl = location.href.indexOf('nightly') > -1 ? "//nightly.api.ulakbus.net/" : "//api.ulakbus.net/"; var backendurl = location.href.indexOf('nightly') > -1 ? "//nightly.api.ulakbus.net/" : "//api.ulakbus.net/";
if (document.cookie.indexOf("backendurl") > -1) { if (document.cookie.indexOf("backendurl") > -1) {
...@@ -51,31 +68,7 @@ constant("RESTURL", (function () { ...@@ -51,31 +68,7 @@ constant("RESTURL", (function () {
} }
return {url: backendurl}; return {url: backendurl};
})()). })())
/**
* USER_ROLES and AUTH_EVENTS are constant for auth functions
*/
constant("USER_ROLES", {
all: "*",
admin: "admin",
student: "student",
staff: "staff",
dean: "dean"
}).
constant('AUTH_EVENTS', {
loginSuccess: 'auth-login-success',
loginFailed: 'auth-login-failed',
logoutSuccess: 'auth-logout-success',
sessionTimeout: 'auth-session-timeout',
notAuthenticated: 'auth-not-authenticated',
notAuthorized: 'auth-not-authorized'
})
.config(function ($logProvider) { .config(function ($logProvider) {
$logProvider.debugEnabled(true); $logProvider.debugEnabled(true);
}); });
\ No newline at end of file
// test the code with strict di mode to see if it works when minified
//angular.bootstrap(document, ['ulakbus'], {
// strictDi: true
//});
'use strict'; 'use strict';
app.config(['$routeProvider', function ($routeProvider, $route) { angular.module('ulakbus')
.config(['$routeProvider', function ($routeProvider, $route) {
$routeProvider $routeProvider
.when('/login', { .when('/login', {
templateUrl: 'components/auth/login.html', templateUrl: 'components/auth/login.html',
...@@ -47,7 +48,7 @@ app.config(['$routeProvider', function ($routeProvider, $route) { ...@@ -47,7 +48,7 @@ app.config(['$routeProvider', function ($routeProvider, $route) {
}) })
.otherwise({redirectTo: '/dashboard'}); .otherwise({redirectTo: '/dashboard'});
}]) }])
.run(function ($rootScope) { .run(function ($rootScope) {
$rootScope.loggedInUser = true; $rootScope.loggedInUser = true;
......
...@@ -8,16 +8,32 @@ ...@@ -8,16 +8,32 @@
'use strict'; 'use strict';
var auth = angular.module('ulakbus.auth', ['ngRoute', 'schemaForm', 'ngCookies']); /**
auth.controller('LoginCtrl', function ($scope, $q, $timeout, $routeParams, $rootScope, $log, Generator, LoginService) { * @ngdoc module
* @name ulakbus.auth
* @module ulakbus.auth
* @description ulakbus.auth module handles authorization process of ulakbus-ui.
*
* @requires ngRoute
* @requires ngCookies
*/
angular.module('ulakbus.auth', ['ngRoute', 'ngCookies'])
/**
* @memberof ulakbus.auth
* @ngdoc controller
* @name LoginCtrl
* @description LoginCtrl responsible to handle login process.<br>
* Using 'ulakbus.formService.get_form' function generates the login form and post it to the API with input datas.
*/
.controller('LoginCtrl', function ($scope, $q, $timeout, $routeParams, $rootScope, $log, Generator, AuthService) {
$scope.url = 'login'; $scope.url = 'login';
$scope.form_params = {}; $scope.form_params = {};
$scope.form_params['clear_wf'] = 1; $scope.form_params['clear_wf'] = 1;
Generator.get_form($scope).then(function(data){ Generator.get_form($scope).then(function (data) {
$scope.form = [ $scope.form = [
{ key: "username", type: "string", title: "Kullanıcı Adı"}, {key: "username", type: "string", title: "Kullanıcı Adı"},
{ key: "password", type: "password", title: "Şifre"}, {key: "password", type: "password", title: "Şifre"},
{ type: 'submit', title: 'Giriş Yap' } {type: 'submit', title: 'Giriş Yap'}
]; ];
}); });
$scope.loggingIn = false; $scope.loggingIn = false;
...@@ -26,12 +42,15 @@ auth.controller('LoginCtrl', function ($scope, $q, $timeout, $routeParams, $root ...@@ -26,12 +42,15 @@ auth.controller('LoginCtrl', function ($scope, $q, $timeout, $routeParams, $root
if (form.$valid) { if (form.$valid) {
$scope.loggingIn = true; $scope.loggingIn = true;
$rootScope.loginAttempt = 1; $rootScope.loginAttempt = 1;
LoginService.login($scope.url, $scope.model) Generator.button_switch(false);
.error(function(data){ AuthService.login($scope.url, $scope.model)
.error(function (data) {
$scope.message = data.title; $scope.message = data.title;
$scope.loggingIn = false;
}) })
.then(function () { .then(function () {
$scope.loggingIn = false; $scope.loggingIn = false;
Generator.button_switch(false);
}) })
} }
else { else {
...@@ -40,4 +59,4 @@ auth.controller('LoginCtrl', function ($scope, $q, $timeout, $routeParams, $root ...@@ -40,4 +59,4 @@ auth.controller('LoginCtrl', function ($scope, $q, $timeout, $routeParams, $root
}; };
$log.debug('login attempt: ', $rootScope.loginAttempt); $log.debug('login attempt: ', $rootScope.loginAttempt);
}); });
\ No newline at end of file \ No newline at end of file
...@@ -8,12 +8,28 @@ ...@@ -8,12 +8,28 @@
"use strict"; "use strict";
// TODO: login url change with correct one angular.module('ulakbus.auth')
/**
auth.factory('LoginService', function ($http, $rootScope, $location, $log, RESTURL) { * @memberof ulakbus.auth
var loginService = {}; * @ngdoc service
* @name AuthService
* @description provides generic functions for authorization process.
*/
.factory('AuthService', function ($http, $rootScope, $location, $log, Generator, RESTURL) {
var authService = {};
loginService.login = function (url, credentials) { /**
* @memberof ulakbus.auth
* @ngdoc function
* @function login
* @description login function post credentials to API and handles login.
* If login req returns success then interceptor will redirects to related path.
*
* @param url
* @param credentials
* @returns {*}
*/
authService.login = function (url, credentials) {
credentials['cmd'] = "do"; credentials['cmd'] = "do";
return $http return $http
.post(RESTURL.url + url, credentials) .post(RESTURL.url + url, credentials)
...@@ -24,11 +40,20 @@ auth.factory('LoginService', function ($http, $rootScope, $location, $log, RESTU ...@@ -24,11 +40,20 @@ auth.factory('LoginService', function ($http, $rootScope, $location, $log, RESTU
}) })
.error(function (data, status, headers, config) { .error(function (data, status, headers, config) {
// Handle login errors here // Handle login errors here
data.title = "İşlem başarısız oldu. Lütfen girdiğiniz bilgileri kontrol ediniz."
return data; return data;
}); });
}; };
loginService.logout = function () { /**
* @memberof ulakbus.auth
* @ngdoc controller
* @function logout
* @description logout function posts logout request to API and redirects to login path
*
* @returns {*}
*/
authService.logout = function () {
$log.debug("logout"); $log.debug("logout");
return $http.post(RESTURL.url + 'logout', {}).success(function (data) { return $http.post(RESTURL.url + 'logout', {}).success(function (data) {
$rootScope.loggedInUser = false; $rootScope.loggedInUser = false;
...@@ -37,10 +62,5 @@ auth.factory('LoginService', function ($http, $rootScope, $location, $log, RESTU ...@@ -37,10 +62,5 @@ auth.factory('LoginService', function ($http, $rootScope, $location, $log, RESTU
}); });
}; };
loginService.isValidEmail = function (email) { return authService;
var re = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i; });
return re.test(email); \ No newline at end of file
};
return loginService;
});
\ No newline at end of file
...@@ -10,16 +10,9 @@ ...@@ -10,16 +10,9 @@
describe('ulakbus.auth module', function () { describe('ulakbus.auth module', function () {
// load dependencies of modules e.g REST_URL
beforeEach(module('ulakbus')); beforeEach(module('ulakbus'));
beforeEach(module('ulakbus.auth')); beforeEach(module('ulakbus.auth'));
describe('login controller and service', function () {
it('should have a login controller', inject(function () {
expect('ulakbus.auth.LoginCtrl').toBeDefined();
}));
var $controller; var $controller;
var $rootScope; var $rootScope;
...@@ -28,10 +21,21 @@ describe('ulakbus.auth module', function () { ...@@ -28,10 +21,21 @@ describe('ulakbus.auth module', function () {
})); }));
beforeEach(inject(function ($injector) { beforeEach(inject(function ($injector) {
$httpBackend = $injector.get('$httpBackend');
$rootScope = $injector.get('$rootScope'); $rootScope = $injector.get('$rootScope');
})); }));
beforeEach(inject(function ($injector) {
$httpBackend = $injector.get('$httpBackend');
var authRequestHandler = $httpBackend.when('GET', /\.[0-9a-z]+$/i)
.respond({userId: 'userX'}, {'A-Token': 'xxx'});
}));
describe('login controller and service', function () {
it('should have a login controller', inject(function () {
expect('ulakbus.auth.LoginCtrl').toBeDefined();
}));
it('should get login form', inject( it('should get login form', inject(
function ($rootScope, $httpBackend, RESTURL) { function ($rootScope, $httpBackend, RESTURL) {
$httpBackend.expectPOST(RESTURL.url + 'login', {cmd: ''}) $httpBackend.expectPOST(RESTURL.url + 'login', {cmd: ''})
...@@ -43,65 +47,22 @@ describe('ulakbus.auth module', function () { ...@@ -43,65 +47,22 @@ describe('ulakbus.auth module', function () {
var controller = $controller('LoginCtrl', {$scope: $scope}); var controller = $controller('LoginCtrl', {$scope: $scope});
expect($scope.onSubmit).toBeDefined(); expect($scope.onSubmit).toBeDefined();
//expect($scope.loginForm).toBeDefined();
//
//$scope.onSubmit($scope.loginForm);
}) })
); );
it('should validate email', inject(['LoginService', it('ensures user can log in', function (AuthService, $httpBackend, RESTURL) {
function (LoginService) {
expect(LoginService.isValidEmail).not.toBe(null);
// test cases - testing for success
var validEmails = [
'test@test.com',
'test@test.co.uk',
'test734ltylytkliytkryety9ef@jb-fe.com'
];
// test cases - testing for failure
var invalidEmails = [
'test@testcom',
'test@ test.co.uk',
'ghgf@fe.com.co.',
'tes@t@test.com',
''
];
// you can loop through arrays of test cases like this
for (var i in validEmails) {
var valid = LoginService.isValidEmail(validEmails[i]);
expect(valid).toBeTruthy();
}
for (var i in invalidEmails) {
var valid = LoginService.isValidEmail(invalidEmails[i]);
expect(valid).toBeFalsy();
}
}])
);
it('should submit form', inject(function ($httpBackend, RESTURL) {
}));
it('ensures user can log in', function (LoginService, $httpBackend, RESTURL) {
// todo: after backend api ready implement this // todo: after backend api ready implement this
}); });
it('should get login success', it('should get login success',
inject(function (LoginService, $httpBackend, $location, RESTURL) { inject(function (AuthService, $httpBackend, $location, RESTURL) {
// use httpBackend to imitate login api // use httpBackend to imitate login api
$httpBackend.expectPOST(RESTURL.url + 'login', { $httpBackend.expectPOST(RESTURL.url + 'login', {
email: 'test@test.com', email: 'test@test.com',
password: 'password', password: 'password',
cmd: 'do' cmd: 'do'
}) })
// todo: with real api change response data from list to obj
.respond(200, [{ .respond(200, [{
'id': 1, 'user': { 'id': 1, 'user': {
'id': 12 'id': 12
...@@ -111,11 +72,9 @@ describe('ulakbus.auth module', function () { ...@@ -111,11 +72,9 @@ describe('ulakbus.auth module', function () {
}]); }]);
var cred = {email: 'test@test.com', password: 'password'}; var cred = {email: 'test@test.com', password: 'password'};
LoginService.login('login', cred) AuthService.login('login', cred)
.then(function (data) { .then(function (data) {
expect(data).not.toBe(null); expect(data).not.toBe(null);
// after login path need to be change dashboard
//expect($location.path()).toBe('');
}); });
$httpBackend.flush(); $httpBackend.flush();
...@@ -123,7 +82,7 @@ describe('ulakbus.auth module', function () { ...@@ -123,7 +82,7 @@ describe('ulakbus.auth module', function () {
); );
it('should logout', it('should logout',
inject(function (LoginService, $httpBackend, $location, RESTURL) { inject(function (AuthService, $httpBackend, $location, RESTURL) {
// use httpBackend to imitate login api // use httpBackend to imitate login api
...@@ -132,7 +91,7 @@ describe('ulakbus.auth module', function () { ...@@ -132,7 +91,7 @@ describe('ulakbus.auth module', function () {
is_login: false is_login: false
}); });
LoginService.logout().success(function (data) { AuthService.logout().success(function (data) {
expect(data.is_login).toBe(false); expect(data.is_login).toBe(false);
}); });
......
...@@ -7,8 +7,20 @@ ...@@ -7,8 +7,20 @@
*/ */
'use strict'; 'use strict';
/**
angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService']) * @ngdoc module
* @name ulakbus.crud
* @module ulakbus.crud
* @description
* ulakbus.crud module is the main module for ui. It interacts with backend and manipulate data to screen
* generically.
*
* @requires ui.bootstrap
* @requires schemaForm
* @requires ulakbus.formService
* @type {ng.$compileProvider|*}
*/
angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'ulakbus.formService'])
.config(function (sfErrorMessageProvider) { .config(function (sfErrorMessageProvider) {
sfErrorMessageProvider.setDefaultMessage(302, 'Bu alan zorunludur.'); sfErrorMessageProvider.setDefaultMessage(302, 'Bu alan zorunludur.');
sfErrorMessageProvider.setDefaultMessage(200, 'En az {{schema.minLength}} değer giriniz.'); sfErrorMessageProvider.setDefaultMessage(200, 'En az {{schema.minLength}} değer giriniz.');
...@@ -16,22 +28,24 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService']) ...@@ -16,22 +28,24 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService'])
}) })
/** /**
* @memberof ulakbus.crud
* @ngdoc service
* @name CrudUtility * @name CrudUtility
* @description * @description Crud Utility is a service to provide generic functions for Crud controllers to format data and
* Crud Utility is a service to provide functionality for Crud controllers * scope object.
* @returns {object} * @returns {service}
*/ */
.service('CrudUtility', function ($log, $rootScope) { .service('CrudUtility', function ($log, $rootScope) {
return { return {
/** /**
* @memberof ulakbus.crud
* @ngdoc function
* @name generateParam * @name generateParam
* @description * @description generateParam is a function to generate required params to post backend api.
* generateParam is a function to generate required params to post backend api. * @param {object} scope
* * @param {object} routeParams
* @param scope * @param {string} cmd
* @param routeParams * @returns {object} scope
* @param cmd
* @returns {*}
*/ */
generateParam: function (scope, routeParams, cmd) { generateParam: function (scope, routeParams, cmd) {
scope.url = routeParams.wf; scope.url = routeParams.wf;
...@@ -66,12 +80,13 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService']) ...@@ -66,12 +80,13 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService'])
return scope; return scope;
}, },
/** /**
* @memberof ulakbus.crud
* @ngdoc function
* @name listPageItems * @name listPageItems
* @description * @description listPageItems is a function to prepare objects to list in the list page.
* listPageItems is a function to prepare objects to list in list page.
* *
* @param scope * @param {object} scope
* @param pageData * @param {object} pageData
*/ */
listPageItems: function (scope, pageData) { listPageItems: function (scope, pageData) {
angular.forEach(pageData, function (value, key) { angular.forEach(pageData, function (value, key) {
...@@ -104,9 +119,10 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService']) ...@@ -104,9 +119,10 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService'])
}) })
/** /**
* @memberof ulakbus.crud
* @ngdoc controller
* @name CRUDCtrl * @name CRUDCtrl
* @description * @description CRUDCtrl controller is base controller for crud module to redirect to related controller
* CRUDCtrl controller is base controller for crud module to redirect to related controller
* This controller play an empty role for api calls. * This controller play an empty role for api calls.
* With response data, location path change to related controller * With response data, location path change to related controller
* *
...@@ -119,17 +135,19 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService']) ...@@ -119,17 +135,19 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService'])
}) })
/** /**
* @memberof ulakbus.crud
* @ngdoc controller
* @name CRUDListFormCtrl * @name CRUDListFormCtrl
* @description * @description CRUDListFormCtrl is the main controller for crud module
* CRUDListFormCtrl is the main controller for crud module
* Based on the client_cmd parameter it generates its scope items. * Based on the client_cmd parameter it generates its scope items.
* client_cmd can be in ['show', 'list', 'form', 'reload', 'refresh'] * client_cmd can be in ['show', 'list', 'form', 'reload', 'refresh']
* There are 3 directives to manipulate controllers scope objects in crud.html * There are 3 directives to manipulate controllers scope objects in crud.html
* * <br>
* The controller works in 2 ways, with and without pageData. * The controller works in 2 ways, with and without pageData.
* pageData is generated by formService.Generator and it contains data to manipulate page.
* If pageData has set, using Generator's getPageData() function, sets its scope items. After getting pageData * If pageData has set, using Generator's getPageData() function, sets its scope items. After getting pageData
* pageData must be set to `{pageData: false}` for clear scope of next job. * pageData must be set to `{pageData: false}` for clear scope of next job.
* * <br>
* If pageData has not set using Generator's get_wf() function gets scope items from api call. * If pageData has not set using Generator's get_wf() function gets scope items from api call.
* *
* @returns {object} * @returns {object}
...@@ -238,6 +256,10 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService']) ...@@ -238,6 +256,10 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService'])
CrudUtility.generateParam($scope, $routeParams, $routeParams.cmd); CrudUtility.generateParam($scope, $routeParams, $routeParams.cmd);
Generator.get_wf($scope); Generator.get_wf($scope);
} }
if ($scope.object) {
$scope.createListObjects();
}
}; };
$scope.reloadCmd = function () { $scope.reloadCmd = function () {
$scope.reload({}); $scope.reload({});
...@@ -260,6 +282,13 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService']) ...@@ -260,6 +282,13 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService'])
}) })
/**
* @memberof ulakbus.crud
* @ngdoc directive
* @name crudListDirective
* @description directive for listing objects.
* provides template for `scope.objects` object.
*/
.directive('crudListDirective', function () { .directive('crudListDirective', function () {
return { return {
templateUrl: 'components/crud/templates/list.html', templateUrl: 'components/crud/templates/list.html',
...@@ -267,7 +296,13 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService']) ...@@ -267,7 +296,13 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService'])
replace: true replace: true
}; };
}) })
/**
* @memberof ulakbus.crud
* @ngdoc directive
* @name crudFormDirective
* @description directive for form generation.
* provides template for `scope.forms` object.
*/
.directive('crudFormDirective', function () { .directive('crudFormDirective', function () {
return { return {
templateUrl: 'components/crud/templates/form.html', templateUrl: 'components/crud/templates/form.html',
...@@ -275,7 +310,13 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService']) ...@@ -275,7 +310,13 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService'])
replace: true replace: true
}; };
}) })
/**
* @memberof ulakbus.crud
* @ngdoc directive
* @name crudShowDirective
* @description directive for single object or detail of an object.
* provides template for `scope.object` object.
*/
.directive('crudShowDirective', function () { .directive('crudShowDirective', function () {
return { return {
templateUrl: 'components/crud/templates/show.html', templateUrl: 'components/crud/templates/show.html',
...@@ -283,7 +324,13 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService']) ...@@ -283,7 +324,13 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService'])
replace: true replace: true
}; };
}) })
/**
* @memberof ulakbus.crud
* @ngdoc directive
* @name formLocator
* @description directive for finding form element. we use this directive because when form dynamically generated using
* schemaform it belongs to a scope which is hard to reach. This makes it easy to locate form object.
*/
.directive('formLocator', function () { .directive('formLocator', function () {
return { return {
link: function (scope) { link: function (scope) {
...@@ -292,6 +339,13 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService']) ...@@ -292,6 +339,13 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService'])
} }
}) })
/**
* @memberof ulakbus.crud
* @ngdoc directive
* @name crudFilters
* @description directive for filtering functionality. There are three types of filters; `check`, `select`, and `date`.
* @todo filter items returns unselected in response object
*/
.directive('crudFilters', function(Generator) { .directive('crudFilters', function(Generator) {
return { return {
templateUrl: 'components/crud/templates/filter.html', templateUrl: 'components/crud/templates/filter.html',
......
...@@ -10,7 +10,7 @@ describe('crud controller module', function () { ...@@ -10,7 +10,7 @@ describe('crud controller module', function () {
beforeEach(module('ulakbus')); beforeEach(module('ulakbus'));
beforeEach(module('ulakbus.crud')); beforeEach(module('ulakbus.crud'));
beforeEach(module('formService')); beforeEach(module('ulakbus.formService'));
beforeEach(inject(function ($injector) { beforeEach(inject(function ($injector) {
$httpBackend = $injector.get('$httpBackend'); $httpBackend = $injector.get('$httpBackend');
......
<div ng-app="ulakbus.dashboard" class="dashboard"> <div ng-app="ulakbus.dashboard" class="dashboard">
<div class="starter-template" style="width: calc(100% - 300px);"> <div class="starter-template">
<div class="dashboard-main-search clearfix"> <div class="dashboard-main-search clearfix">
...@@ -125,107 +125,24 @@ ...@@ -125,107 +125,24 @@
</div> </div>
<!-- end of dashboard-main-anouncement --> <!-- end of dashboard-main-anouncement -->
<div class="right-sidebar"> <!--<div class="right-sidebar selected-person-field">-->
<div class="right-sidebar-box" data-step="4" <!--<div class="right-sidebar-header">-->
data-intro="mesajlar, yapılan görevlerin son durumları, duyurular ve son yapılan işlemleri buradan takip edebilirsiniz."> <!--<span class="bar-title">Kişi seçildi</span>-->
<div class="right-sidebar-messages"> <!--<span class="unselect-person"><i class="fa fa-times"></i></span>-->
<div class="right-sidebar-title clearfix">
<h3>Mesajlar</h3>
<span><a role="button">Tüm Mesajlar</a></span>
</div>
<!-- end of right-sidebar-title -->
<p ng-show="notifications[2].length === 0" class="text-center">Görüntülenecek içerik yok.</p>
<div class="right-sidebar-message-block" ng-repeat="notify in notifications[2] | limitTo:5">
<a class="clearfix" ng-click="markAsRead(notify)">
<img src="../../../img/sample-profile-pic.jpg">
<div class="right-sidebar-message-content">
<div>{{notify.title}}</div>
<div>{{notify.body}}</div>
<div>16:05</div>
</div>
<!-- end of right-sidebar-message-content -->
</a>
</div>
<!-- end of right-sidebar-message-block -->
</div>
<!-- end of right-sidebar-messages -->
</div>
<!-- end of right-sidebar-box -->
<div class="right-sidebar-box">
<div class="right-sidebar-tasks">
<div class="right-sidebar-title clearfix">
<h3>Görevler</h3>
<span><a role="button">Tüm Görevler</a></span>
</div>
<p ng-show="notifications[1].length === 0" class="text-center">Görüntülenecek içerik yok.</p>
<div class="right-sidebar-task-block">
<!--<div class="task-type">Onay Bekleyen Görevler</div>-->
<a ng-click="markAsRead(notify)" ng-repeat="notify in notifications[1] | limitTo:5">
<div class="task-title">{{notify.title}}</div>
</a>
</div>
<!-- end of right-sidebar-task-block -->
</div>
<!-- end of right-sidebar-tasks -->
</div>
<!-- end of right-sidebar-box -->
<!--<div class="right-sidebar-box">-->
<!--<div class="right-sidebar-announcements">-->
<!--<div class="right-sidebar-title clearfix">-->
<!--<h3>Duyurular</h3>-->
<!--<span><a role="button">Tüm Duyurular</a></span>-->
<!--</div>--> <!--</div>-->
<!--&lt;!&ndash; end of right-sidebar-title &ndash;&gt;--> <!--&lt;!&ndash; end of right-sidebaer-header &ndash;&gt;-->
<!---->
<!--<div class="right-sidebar-announcement-block">--> <!--<div class="selected-person-info">-->
<!--<a ng-click="markAsRead(notify)"--> <!--<img src="../../img/sample-profile-pic.jpg" class="selected-person-img">-->
<!--ng-repeat="notify in notifications[3] | limitTo:5">{{notify--> <!--<div class="selected-person-name">Erkan Öğümsöğütlü</div>-->
<!--.body}}</a>-->
<!--</div>--> <!--</div>-->
<!--&lt;!&ndash; end of right-sidebar-status-block &ndash;&gt;--> <!--&lt;!&ndash; end of selected-person-info &ndash;&gt;-->
<!--</div>--> <!--</div>-->
<!--&lt;!&ndash; end of right-sidebar-status &ndash;&gt;--> <!-- end of right-sidebar -->
<!--</div>-->
<!-- end of right-sidebar-box -->
<div class="right-sidebar-box">
<div class="right-sidebar-last-actions">
<div class="right-sidebar-title clearfix">
<h3>Son İşlemler</h3>
<span><a role="button">Tüm İşlemler</a></span>
</div>
<p class="text-center">Görüntülenecek içerik yok.</p>
<div class="right-sidebar-task-block">
<a>
<div class="task-title"></div>
</a>
</div>
</div>
<!-- end of right-sidebar-status -->
</div>
<!-- end of right-sidebar-box -->
</div>
<!-- end of right-sidebar -->
</div> </div>
</div> </div>
\ No newline at end of file
...@@ -8,6 +8,14 @@ ...@@ -8,6 +8,14 @@
'use strict'; 'use strict';
/**
* @ngdoc module
* @name ulakbus.dashboard
* @module ulakbus.dashboard
* @description ulakbus.dashboard module is holding dashboard's controller, directives and other components.
*
* @type {ng.$compileProvider|*}
*/
angular.module('ulakbus.dashboard', []) angular.module('ulakbus.dashboard', [])
.config(function ($uibTooltipProvider) { .config(function ($uibTooltipProvider) {
$uibTooltipProvider.setTriggers({'click': 'mouseleave'}); $uibTooltipProvider.setTriggers({'click': 'mouseleave'});
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
'use strict'; 'use strict';
app.config(['$routeProvider', function ($routeProvider) { angular.module('ulakbus').config(['$routeProvider', function ($routeProvider) {
$routeProvider $routeProvider
.when('/error/500', { .when('/error/500', {
templateUrl: 'components/error_pages/500.html', templateUrl: 'components/error_pages/500.html',
......
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
<div class="main" ng-view> <div class="main" ng-view>
</div> </div>
<right-sidebar></right-sidebar>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -71,7 +71,7 @@ ...@@ -71,7 +71,7 @@
<div class="main" ng-view> <div class="main" ng-view>
</div> </div>
<right-sidebar></right-sidebar>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -8,14 +8,26 @@ ...@@ -8,14 +8,26 @@
'use strict'; 'use strict';
var app = angular.module( /**
* @ngdoc module
* @name ulakbus
* @module ulakbus
* @description Ulakbus module is the main module of ulakbus-ui.
* All application-wide configurations and definings of constants handled in this module.
*
* There are two scripts on `app/` root; `main.js` and `app.js`. And `main.html`, `index.html`.
* `main.*` files are contains both production and development requirements or configurations/necessities for relative environment.
* Tagged with `NODE_ENV='PRODUCTION'` in commented line and configured in Gruntfile.js with package `preprocess` and `env`, related grunt command generates index.* for given file.
*
*/
angular.module(
'ulakbus', [ 'ulakbus', [
'ui.bootstrap', 'ui.bootstrap',
'angular-loading-bar', 'angular-loading-bar',
'ngRoute', 'ngRoute',
'ngSanitize', 'ngSanitize',
'ngCookies', 'ngCookies',
'formService', 'ulakbus.formService',
'ulakbus.dashboard', 'ulakbus.dashboard',
'ulakbus.auth', 'ulakbus.auth',
'ulakbus.error_pages', 'ulakbus.error_pages',
...@@ -31,12 +43,17 @@ var app = angular.module( ...@@ -31,12 +43,17 @@ var app = angular.module(
// @if NODE_ENV='DEVELOPMENT' // @if NODE_ENV='DEVELOPMENT'
'ulakbus.uitemplates' 'ulakbus.uitemplates'
// @endif // @endif
]). ])
/** /**
* RESTURL is the url of rest api to talk * @memberof ulakbus
* Based on the environment it changes from dev to prod * @ngdoc constant
* @name RESTURL
* @description RESTURL is the url of rest api to talk.
* Based on the environment it changes from dev to prod.
*
* For development needs backendurl can be switched from both dev/settings page and querystring `?backendurl=http://example.com`
*/ */
constant("RESTURL", (function () { .constant("RESTURL", (function () {
// todo: below backendurl definition is for development purpose and will be deleted // todo: below backendurl definition is for development purpose and will be deleted
var backendurl = location.href.indexOf('nightly') > -1 ? "//nightly.api.ulakbus.net/" : "//api.ulakbus.net/"; var backendurl = location.href.indexOf('nightly') > -1 ? "//nightly.api.ulakbus.net/" : "//api.ulakbus.net/";
if (document.cookie.indexOf("backendurl") > -1) { if (document.cookie.indexOf("backendurl") > -1) {
...@@ -56,25 +73,7 @@ constant("RESTURL", (function () { ...@@ -56,25 +73,7 @@ constant("RESTURL", (function () {
} }
return {url: backendurl}; return {url: backendurl};
})()). })())
/**
* USER_ROLES and AUTH_EVENTS are constant for auth functions
*/
constant("USER_ROLES", {
all: "*",
admin: "admin",
student: "student",
staff: "staff",
dean: "dean"
}).
constant('AUTH_EVENTS', {
loginSuccess: 'auth-login-success',
loginFailed: 'auth-login-failed',
logoutSuccess: 'auth-logout-success',
sessionTimeout: 'auth-session-timeout',
notAuthenticated: 'auth-not-authenticated',
notAuthorized: 'auth-not-authorized'
})
.config(function ($logProvider) { .config(function ($logProvider) {
// @if NODE_ENV='PRODUCTION' // @if NODE_ENV='PRODUCTION'
$logProvider.debugEnabled(false); $logProvider.debugEnabled(false);
...@@ -83,9 +82,3 @@ constant("USER_ROLES", { ...@@ -83,9 +82,3 @@ constant("USER_ROLES", {
$logProvider.debugEnabled(true); $logProvider.debugEnabled(true);
// @endif // @endif
}); });
\ No newline at end of file
// test the code with strict di mode to see if it works when minified
//angular.bootstrap(document, ['ulakbus'], {
// strictDi: true
//});
This diff is collapsed.
...@@ -82,11 +82,10 @@ ...@@ -82,11 +82,10 @@
<!-- /.dropdown-alerts --> <!-- /.dropdown-alerts -->
</li> </li>
<!-- /.dropdown --> <!-- /.dropdown -->
<li class="dropdown"> <li class="dropdown" style="border-left:1px solid #891723;">
<a class="dropdown-toggle" data-toggle="dropdown"> <a class="dropdown-toggle" data-toggle="dropdown" style="padding-top: 7px; padding-bottom: 6px;">
<i class="fa fa-user fa-fw" tooltip-placement="bottom" <img src="../../../img/sample-profile-pic.jpg" class="header-profile">&nbsp;{{$root.current_user.name}}&nbsp;{{$root.current_user.surname}}&nbsp;
uib-tooltip="Profil"></i>&nbsp;{{$root.current_user.name}}&nbsp;{{$root.current_user.surname}}&nbsp;<i <i class="fa fa-caret-down" style="margin-left:3px;"></i>
class="fa fa-caret-down"></i>
</a> </a>
<ul class="dropdown-menu dropdown-user"> <ul class="dropdown-menu dropdown-user">
<li><a role="button"><i class="fa fa-user fa-fw"></i> Profil</a></li> <li><a role="button"><i class="fa fa-user fa-fw"></i> Profil</a></li>
......
<div class="manager-view-header" style="{{style}}"> <div class="manager-view-header">
<div class="clearfix"> <div class="clearfix">
<header-breadcrumb></header-breadcrumb> <header-breadcrumb></header-breadcrumb>
<loaderdiv><div></div></loaderdiv> <loaderdiv><div></div></loaderdiv>
......
<div class="right-sidebar selected-person-field">
<div class="right-sidebar-header">
<button type="button" class="close" ng-click="deselectUser()"
aria-label="Close">
<span class="unselect-person"><i class="fa fa-times"></i></span>
</button>
</div>
<div class="selected-person-info">
<img class="selected-person-img"
ng-src="{{selectedUser ? '/img/sample-profile-pic.jpg' : '/img/empty-profile-pic.jpg'}}">
<div class="selected-person-name">
<p class="identity-name">{{selectedUser.name || 'Kişi seçilmedi.'}}</p>
<p class="identity-surname">{{selectedUser.surname}}</p>
<p>{{selectedUser ? 'TCNo: ' + selectedUser.tcno : ''}}</p>
</div>
</div>
<div class="">
<ul class="nav in" id="side-user-menu" data-step="2"
data-intro="seçilen personele veya öğrenciye göre ilgili menüler yer almaktadır. yapılacak işlemi buradan seçebilirsiniz.">
<li ng-repeat="(key, item) in selectedMenuItems" ng-class="{active: collapseVar == $index+100}">{{dropDown}}
<a href="" ng-click="check($index+100)">
<i class="fa fa-fw"
ng-class="{
'Admin': 'fa fa-fw fa-terminal',
'Genel': 'fa fa-fw fa-graduation-cap',
'Alt Kategori': 'fa fa-fw fa-tags',
'Kadro Islemleri': 'fa fa-fw fa-users',
'Seçime Uygun Görevler':'fa fa-fw fa-user'
}[item[0].kategori]"></i>
<span class="menu-text">{{ key }}</span>
<span class="fa arrow"></span>
</a>
<ul class="nav nav-second-level">
<li ng-repeat="(k, v) in item">
<a ng-href="#/{{v.wf}}/{{v.model}}?{{v.param}}={{selectedUser.key}}"
ng-click="breadcrumb([key, v.text], $event)">{{v.text}}</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
\ No newline at end of file
<div class="navbar-default sidebar" role="navigation" ng-mouseenter="openSidebar()" ng-mouseleave="closeSidebar()"> <div class="navbar-default sidebar" role="navigation" ng-mouseenter="openSidebar()" ng-mouseleave="closeSidebar()">
<div class="sidebar-container"> <div class="sidebar-container">
<!-- sidebar-person-info -->
<div class="sidebar-person-info" ng-show="$root.current_user.can_search">
<!--<button class="btn btn-primary close-sidebar-person-info">Profili Kapat</button>-->
<div class="identity">
<button type="button" class="close" ng-class="{hidden: $root.collapsed || !selectedUser}"
ng-click="deselectUser()"
aria-label="Close"><span
aria-hidden="true">&times;</span></button>
<div class="identity-header clearfix">
<img ng-src="{{selectedUser ? '/img/sample-profile-pic.jpg' : '/img/empty-profile-pic.jpg'}}">
<div class="pull-left" ng-class="{hidden: $root.collapsed}">
<p class="identity-name">{{selectedUser.name || 'Kişi seçilmedi.'}}</p>
<p class="identity-surname">{{selectedUser.surname}}</p>
<p>{{selectedUser ? 'TCNo: ' + selectedUser.tcno : ''}}</p>
</div>
</div>
<!-- end of identity-header -->
<!--<div class="identity-info" ng-class="{hidden: $root.collapsed}">-->
<!--<div class="clearfix">-->
<!--<span class="fa fa-envelope"></span>-->
<!--<div>erkanogum@gmail.com</div>-->
<!--</div>-->
<!--<div class="clearfix">-->
<!--<span class="fa fa-home"></span>-->
<!--<div>İşçi Blokları Mah. 1524. sokak B Blok 6. Kat A Kanat 27 numara</div>-->
<!--</div>-->
<!--</div>-->
</div>
<!-- end of identity -->
<div class="">
<ul class="nav in" id="side-user-menu" ng-class="{hidden: !selectedMenuItems}" data-step="2"
data-intro="seçilen personele veya öğrenciye göre ilgili menüler yer almaktadır. yapılacak işlemi buradan seçebilirsiniz.">
<li ng-repeat="(key, item) in selectedMenuItems" ng-class="{active: collapseVar == $index+100}">{{dropDown}}
<a href="" ng-click="check($index+100)">
<i class="fa fa-fw"
ng-class="{
'Admin': 'fa fa-fw fa-terminal',
'Genel': 'fa fa-fw fa-graduation-cap',
'Alt Kategori': 'fa fa-fw fa-tags',
'Kadro Islemleri': 'fa fa-fw fa-users',
'Seçime Uygun Görevler':'fa fa-fw fa-user'
}[item[0].kategori]"></i>
<span class="menu-text" ng-class="{hidden: $root.collapsed}">{{ key }}</span>
<span class="fa arrow" ng-class="{hidden: $root.collapsed}"></span>
</a>
<ul class="nav nav-second-level" ng-class="{hidden: $root.collapsed}">
<li ng-repeat="(k, v) in item">
<!--<a ng-if="v.model" ng-href="#{{v.url}}" ng- -->
<!--ng-click="breadcrumb([key, v.text], $event)">{{v.text}}</a>-->
<a ng-href="#/{{v.wf}}/{{v.model}}?{{v.param}}={{selectedUser.key}}"
ng-click="breadcrumb([key, v.text], $event)">{{v.text}}</a>
</li>
</ul>
<!-- /.nav-second-level -->
</li>
</ul>
</div>
<!-- end of person-actions -->
</div>
<!-- end of sidebar-person-info -->
<div class="sidebar-nav navbar-collapse"> <div class="sidebar-nav navbar-collapse">
<ul class="nav in" id="side-menu" ng-class="{hidden: $root.loggedInUser != true}" data-step="1" <ul class="nav in" id="side-menu" ng-class="{hidden: $root.loggedInUser != true}" data-step="1"
data-intro="Genel menüler yer almaktadır. yapılacak işlemi buradan seçebilirsiniz."> data-intro="Genel menüler yer almaktadır. yapılacak işlemi buradan seçebilirsiniz.">
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
<span ng-if="value.verbose_name">{{ value.verbose_name }}</span> <span ng-if="value.verbose_name">{{ value.verbose_name }}</span>
<span ng-if="!value.verbose_name">{{key}}</span> <span ng-if="!value.verbose_name">{{key}}</span>
</th> </th>
<th>İşlem</th> <th ng-if="meta.allow_actions!==false">İşlem</th>
</tr> </tr>
</thead> </thead>
<tbody ng-class="{hidden: node.lengthModels < 1}"> <tbody ng-class="{hidden: node.lengthModels < 1}">
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
ng-model="node.model[outerIndex][k]" ng-model="node.model[outerIndex][k]"
ng-change="nodeModelChange(this)"> ng-change="nodeModelChange(this)">
</td> </td>
<td> <td ng-if="meta.allow_actions!==false">
<button modal-for-nodes="{{node.schema.model_name}},{{node.schema.formType}},edit,{{$index}}">Düzenle <button modal-for-nodes="{{node.schema.model_name}},{{node.schema.formType}},edit,{{$index}}">Düzenle
</button> </button>
<br> <br>
......
This diff is collapsed.
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
describe('form service module', function () { describe('form service module', function () {
beforeEach(module('ulakbus')); beforeEach(module('ulakbus'));
beforeEach(module('formService')); beforeEach(module('ulakbus.formService'));
var location; var location;
beforeEach(inject(function ($location, $injector) { beforeEach(inject(function ($location, $injector) {
...@@ -84,6 +84,13 @@ describe('form service module', function () { ...@@ -84,6 +84,13 @@ describe('form service module', function () {
}] }]
); );
it('should return scope if no scope.forms', inject['Generator',
function () {
var returnScope = Generator.generate({"test": "scope"}, {"data": "no forms"});
expect(returnScope).toEqual({"test": "scope"});
}]
);
it('should prepare form items', inject( it('should prepare form items', inject(
function (Generator, $httpBackend, RESTURL) { function (Generator, $httpBackend, RESTURL) {
expect(Generator.prepareFormItems).not.toBe(null); expect(Generator.prepareFormItems).not.toBe(null);
...@@ -107,14 +114,14 @@ describe('form service module', function () { ...@@ -107,14 +114,14 @@ describe('form service module', function () {
var scope = { var scope = {
wf: 'test', wf: 'test',
form: ['email', 'id', 'name', 'save', 'select', 'date', 'date2', 'text_general', 'model', 'node', 'listnode'], form: ['email', 'id', 'name', 'save', {"type": "select", "key": "select"}, 'date', 'date2', 'text_general', 'model', 'node', 'listnode'],
schema: { schema: {
properties: { properties: {
email: {title: 'email', type: 'email'}, email: {title: 'email', type: 'email'},
id: {title: 'id', type: 'int'}, id: {title: 'id', type: 'int'},
name: {title: 'name', type: 'string'}, name: {title: 'name', type: 'string'},
save: {title: 'save', type: 'submit'}, save: {title: 'save', type: 'submit'},
select: {title: 'select', type: 'select', key: 'select'}, select: {title: 'select', type: 'select'},
date: {title: 'date', type: 'date'}, date: {title: 'date', type: 'date'},
date2: {title: 'date', type: 'date'}, date2: {title: 'date', type: 'date'},
text_general: {title: 'text_general', type: 'text_general'}, text_general: {title: 'text_general', type: 'text_general'},
...@@ -173,15 +180,23 @@ describe('form service module', function () { ...@@ -173,15 +180,23 @@ describe('form service module', function () {
}, required: [], type: 'object', title: 'servicetest' }, required: [], type: 'object', title: 'servicetest'
}, },
grouping: [ grouping: [
{
"groups": [
{ {
"group_title": "title-1", "group_title": "title-1",
"items": ["email", "id"], "items": ["email", "id"],
}
],
"layout": "4", "layout": "4",
"collapse": false "collapse": false
}, },
{
"groups": [
{ {
"group_title": "title-2", "group_title": "title-2",
"items": ["name", "save"], "items": ["name", "save"],
}
],
"layout": "2", "layout": "2",
"collapse": false "collapse": false
} }
...@@ -483,8 +498,8 @@ describe('form service module', function () { ...@@ -483,8 +498,8 @@ describe('form service module', function () {
// test cases - testing for success // test cases - testing for success
var same_json = [ var same_json = [
{email: 'test@test.com', id: 2, name: 'travolta', foo: {'a':1}, foo2: [1,2,3]}, {email: 'test@test.com', id: 2, name: 'travolta', foo2: [1,2,3], foo: {'a':1}},
{email: 'test@test.com', id: 2, name: 'travolta', foo: {'a':1}, foo2: [1,2,3]} {email: 'test@test.com', id: 2, name: 'travolta', foo2: [1,2,3], foo: {'a':1}}
]; ];
// test cases - testing for failure // test cases - testing for failure
...@@ -511,21 +526,21 @@ describe('form service module', function () { ...@@ -511,21 +526,21 @@ describe('form service module', function () {
var diff = {email: 'test1@test.com', name: 'john'}; var diff = {email: 'test1@test.com', name: 'john'};
var diff2 = {email: 'test1@test.com', id: 2, name: 'john'}; var diff2 = {email: 'test1@test.com', id: 2, name: 'john'};
var noequal = {email: 'test1@test.com', id: 2, name: 'john'}; var noequal = {name: 'travolta'};
var nodiff = {}; var nodiff = {};
var same = Generator.get_diff(same_json[0], same_json[1]); var same = Generator.get_diff(same_json[0], same_json[1]);
expect(same).toEqual(nodiff); expect(same).toEqual(nodiff);
for (var json_obj in different_jsons) { for (var json_obj in different_jsons) {
var different = Generator.get_diff(different_jsons[json_obj][1], different_jsons[json_obj][0]); var different = Generator.get_diff(different_jsons[json_obj][0], different_jsons[json_obj][1]);
expect(different).toEqual(diff); expect(different).toEqual(diff);
} }
var different2 = Generator.get_diff(different_json[1], different_json[0]); var different2 = Generator.get_diff(different_json[0], different_json[1]);
expect(different2).toEqual(diff2); expect(different2).toEqual(diff2);
var not_equal = Generator.get_diff(notEqual[1], notEqual[0]); var not_equal = Generator.get_diff(notEqual[0], notEqual[1]);
expect(not_equal).toEqual(noequal); expect(not_equal).toEqual(noequal);
}) })
); );
......
...@@ -6,10 +6,20 @@ ...@@ -6,10 +6,20 @@
* (GPLv3). See LICENSE.txt for details. * (GPLv3). See LICENSE.txt for details.
*/ */
app.config(['$httpProvider', function ($httpProvider) { angular.module('ulakbus')
.config(['$httpProvider', function ($httpProvider) {
/** /**
* the interceptor for all requests to check response * @memberof ulakbus.formService
* 4xx - 5xx errors will be handled here * @ngdoc interceptor
* @name http_interceptor
* @description The http interceptor for all requests and responses to check and config payload and response
* objects.
* - To prevent OPTIONS preflight request change header Content-Type to `text/plain`.
* - 4xx - 5xx errors are handled in response objects.
* - `_debug_queries` is helper object for development purposes to see how long the queries lasts.
* They are shown in /debug/list' page.
* - API returns `is_login` key to check if current user is authenticated. Interceptor checks and if not logged
* in redirects to login page.
*/ */
$httpProvider.interceptors.push(function ($q, $rootScope, $location, $timeout, $log) { $httpProvider.interceptors.push(function ($q, $rootScope, $location, $timeout, $log) {
return { return {
...@@ -71,7 +81,7 @@ app.config(['$httpProvider', function ($httpProvider) { ...@@ -71,7 +81,7 @@ app.config(['$httpProvider', function ($httpProvider) {
'<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span' + '<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span' +
' aria-hidden="true">&times;</span></button>' + ' aria-hidden="true">&times;</span></button>' +
'<h4 class="modal-title" id="exampleModalLabel">' + '<h4 class="modal-title" id="exampleModalLabel">' +
rejection.status+ rejection.data.title + rejection.status + rejection.data.title +
'</h4>' + '</h4>' +
'</div>' + '</div>' +
'<div class="modal-body">' + '<div class="modal-body">' +
...@@ -80,7 +90,7 @@ app.config(['$httpProvider', function ($httpProvider) { ...@@ -80,7 +90,7 @@ app.config(['$httpProvider', function ($httpProvider) {
rejection.data.description + rejection.data.description +
'</strong>' + '</strong>' +
codefield + codefield +
'</div>'+ '</div>' +
'</div>' + '</div>' +
'<div class="modal-footer">' + '<div class="modal-footer">' +
'<button type="button" class="btn btn-default" data-dismiss="modal">Kapat</button>' + '<button type="button" class="btn btn-default" data-dismiss="modal">Kapat</button>' +
...@@ -89,7 +99,7 @@ app.config(['$httpProvider', function ($httpProvider) { ...@@ -89,7 +99,7 @@ app.config(['$httpProvider', function ($httpProvider) {
'</div>' + '</div>' +
'</div>').modal(); '</div>').modal();
try { try {
$('pre:not(.hljs)').each(function(i, block) { $('pre:not(.hljs)').each(function (i, block) {
hljs.highlightBlock(block); hljs.highlightBlock(block);
}); });
} }
...@@ -100,9 +110,15 @@ app.config(['$httpProvider', function ($httpProvider) { ...@@ -100,9 +110,15 @@ app.config(['$httpProvider', function ($httpProvider) {
if (rejection.status === -1) { if (rejection.status === -1) {
rejection.status = 'Sunucu hatası' rejection.status = 'Sunucu hatası'
rejection.data = {title: "", description : 'Sunucu bağlantısında bir hata oluştu.' + rejection.data = {
'Lütfen yetkili personelle iletişime geçiniz.'}; title: "", description: 'Sunucu bağlantısında bir hata oluştu.' +
$rootScope.$broadcast('alertBox', {title: rejection.status, msg: rejection.data.description, type: 'error'}); 'Lütfen yetkili personelle iletişime geçiniz.'
};
$rootScope.$broadcast('alertBox', {
title: rejection.status,
msg: rejection.data.description,
type: 'error'
});
} }
if (rejection.status === 400) { if (rejection.status === 400) {
...@@ -135,4 +151,4 @@ app.config(['$httpProvider', function ($httpProvider) { ...@@ -135,4 +151,4 @@ app.config(['$httpProvider', function ($httpProvider) {
} }
}; };
}); });
}]); }]);
\ No newline at end of file \ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -56,7 +56,7 @@ ...@@ -56,7 +56,7 @@
<div class="main" ng-view> <div class="main" ng-view>
</div> </div>
<right-sidebar></right-sidebar>
</div> </div>
</div> </div>
</div> </div>
......
This diff is collapsed.
#UI API Docs
UI Application consists of those elements:
- `app.js`: Main module of the app.
- `crud_controller.js`: The module of controllers for CRUD works.
- `auth_controller.js`: The module of controllers for authorization.
- `auth_service.js`: The module of service for authorization.
- `form_service.js`: The service that handles dynamically form generation, prepare input types, validation, redirection of related crud page and form submiting.
- `directives.js`: Carries app-wide directives.
- `interceptors.js`: Module for configure request and response objects of http functions.
\ No newline at end of file
// Canonical path provides a consistent path (i.e. always forward slashes) across different OSes
var path = require('canonical-path');
var Package = require('dgeni').Package;
// Create and export a new Dgeni package called dgeni-example. This package depends upon
// the jsdoc and nunjucks packages defined in the dgeni-packages npm module.
module.exports = new Package('docs_conf', [
require('dgeni-packages/jsdoc'),
require('dgeni-packages/nunjucks')
])
// Configure our dgeni-example package. We can ask the Dgeni dependency injector
// to provide us with access to services and processors that we wish to configure
.config(function(log, readFilesProcessor, templateFinder, writeFilesProcessor) {
// Set logging level
log.level = 'info';
// Specify the base path used when resolving relative paths to source and output files
readFilesProcessor.basePath = path.resolve(__dirname, '..');
console.log(readFilesProcessor.basePath);
// Specify collections of source files that should contain the documentation to extract
readFilesProcessor.sourceFiles = [
{
// Process all js files in `app` and its subfolders ...
include: 'app/components/**/*.js',
// ... except for this one!
exclude: 'app/**/*_test.js',
// When calculating the relative path to these files use this as the base path.
// So `src/foo/bar.js` will have relative path of `foo/bar.js`
basePath: 'app'
}
];
// Add a folder to search for our own templates to use when rendering docs
templateFinder.templateFolders.unshift(path.resolve(__dirname, 'templates'));
// Specify how to match docs to templates.
// In this case we just use the same static template for all docs
templateFinder.templatePatterns.unshift('docs-template.html');
// Specify where the writeFilesProcessor will write our generated doc files
writeFilesProcessor.outputFolder = 'documentation';
});
\ No newline at end of file
<h1>{{ doc.codeName }} ({{ doc.outputPath }})</h1>
<p>{{ doc.description }}</p>
{% if doc.params %}
<h2>Params</h2>
<ul>
{% for param in doc.params %}
<li>
<strong>{{ param.name }}</strong> { {{ param.typeList }} } - {{ param.description }}
</li>
{% endfor %}
</ul>
{% endif %}
{% if doc.returns %}
<h2>Returns</h2>
<p>
{ {{ doc.returns.typeList }} } - {{ doc.returns.description }}
</p>
{% endif %}
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -73,7 +73,8 @@ module.exports = function (config) { ...@@ -73,7 +73,8 @@ module.exports = function (config) {
reporters: ['progress', 'coverage'], reporters: ['progress', 'coverage'],
preprocessors: { preprocessors: {
//'app/app.js': ['coverage'], 'app/app.js': ['coverage'],
'app/app_routes.js': ['coverage'],
'app/components/auth/*.js': ['coverage'], 'app/components/auth/*.js': ['coverage'],
'app/components/crud/*.js': ['coverage'], 'app/components/crud/*.js': ['coverage'],
'app/components/dashboard/*.js': ['coverage'], 'app/components/dashboard/*.js': ['coverage'],
...@@ -90,6 +91,7 @@ module.exports = function (config) { ...@@ -90,6 +91,7 @@ module.exports = function (config) {
lines: 60, lines: 60,
excludes: [ excludes: [
'app/components/uitemplates/*.js', 'app/components/uitemplates/*.js',
//'app/zetalib/interceptors.js'
] ]
} }
}, },
......
...@@ -34,7 +34,10 @@ ...@@ -34,7 +34,10 @@
"grunt-karma": "~0.8.0", "grunt-karma": "~0.8.0",
"grunt-angular-gettext": "~2.1.0", "grunt-angular-gettext": "~2.1.0",
"git-branch": "*", "git-branch": "*",
"phantomjs": "~1.9.18" "phantomjs": "~1.9.18",
"dgeni": "*",
"dgeni-packages": "*",
"canonical-path": "*"
}, },
"scripts": { "scripts": {
"postinstall": "bower install", "postinstall": "bower install",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment