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

merge

parents fbd02c97 2ade4514
......@@ -106,4 +106,7 @@ target/
coverage/
sync
*.rdb
\ No newline at end of file
*.rdb
api-docs/
api-docs-source/
\ No newline at end of file
......@@ -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/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: {
......@@ -216,6 +227,14 @@ module.exports = function (grunt) {
"app/bower_components/intro.js/themes/introjs-nassim.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: {
......@@ -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) {
grunt.loadNpmTasks('grunt-angular-gettext');
grunt.loadNpmTasks('grunt-preprocess');
grunt.loadNpmTasks('grunt-env');
grunt.loadNpmTasks('grunt-jsdoc');
grunt.loadNpmTasks('grunt-mrdoc');
grunt.registerTask('dev', ['env:dev', 'preprocess:dev', 'html2js:dev', 'default']);
grunt.registerTask('test', ['bower', 'karma:continuous']);
grunt.registerTask('api-docs', ['copy:for_api_docs', 'mrdoc']);
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('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) {
'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
\ No newline at end of file
0.7
\ No newline at end of file
......@@ -91,6 +91,13 @@ a:hover {
letter-spacing: 0.5px;
}
img.header-profile {
width:27px;
height:27px;
border-radius:100%;
margin-right:6px;
}
/** DETAIL PAGE **/
.detail-page {
......@@ -360,11 +367,15 @@ select {
.manager-view-inner {
height:calc(100% - 41px);
-webkit-height:calc(100% - 41px);
width:100%;
display: -webkit-flex;
display: flex;
-webkit-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 {
......@@ -1152,15 +1163,19 @@ table.dataTable thead .sorting:after {
}
.right-sidebar {
width: 300px;
width: 0px;
background-color: #FFFFFF;
border-left: 1px solid #ccc;
/*height: calc(100% - 140px);*/
height: calc(100% - 40px);
position: absolute;
top: 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 {
......@@ -1335,6 +1350,63 @@ table.dataTable thead .sorting:after {
/* 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 */
......
......@@ -8,14 +8,26 @@
'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', [
'ui.bootstrap',
'angular-loading-bar',
'ngRoute',
'ngSanitize',
'ngCookies',
'formService',
'ulakbus.formService',
'ulakbus.dashboard',
'ulakbus.auth',
'ulakbus.error_pages',
......@@ -26,56 +38,37 @@ var app = angular.module(
//'schemaForm',
'gettext',
'ulakbus.uitemplates'
]).
/**
* RESTURL is the url of rest api to talk
* Based on the environment it changes from dev to prod
*/
constant("RESTURL", (function () {
// 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/";
if (document.cookie.indexOf("backendurl") > -1) {
var cookiearray = document.cookie.split(';');
angular.forEach(cookiearray, function (item) {
if (item.indexOf("backendurl") > -1) {
backendurl = item.split('=')[1];
}
});
}
])
/**
* @memberof ulakbus
* @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 () {
// 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/";
if (document.cookie.indexOf("backendurl") > -1) {
var cookiearray = document.cookie.split(';');
angular.forEach(cookiearray, function (item) {
if (item.indexOf("backendurl") > -1) {
backendurl = item.split('=')[1];
}
});
}
if (location.href.indexOf("backendurl") > -1) {
var urlfromqstr = location.href.split('?')[1].split('=')[1];
backendurl = decodeURIComponent(urlfromqstr.replace(/\+/g, " "));
document.cookie = "backendurl=" + backendurl;
window.location.href = window.location.href.split('?')[0];
}
if (location.href.indexOf("backendurl") > -1) {
var urlfromqstr = location.href.split('?')[1].split('=')[1];
backendurl = decodeURIComponent(urlfromqstr.replace(/\+/g, " "));
document.cookie = "backendurl=" + backendurl;
window.location.href = window.location.href.split('?')[0];
}
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'
})
return {url: backendurl};
})())
.config(function ($logProvider) {
$logProvider.debugEnabled(true);
});
// test the code with strict di mode to see if it works when minified
//angular.bootstrap(document, ['ulakbus'], {
// strictDi: true
//});
});
\ No newline at end of file
'use strict';
app.config(['$routeProvider', function ($routeProvider, $route) {
$routeProvider
.when('/login', {
templateUrl: 'components/auth/login.html',
controller: 'LoginCtrl'
})
.when('/dashboard', {
templateUrl: 'components/dashboard/dashboard.html',
controller: 'DashCtrl'
})
.when('/dev/settings', {
templateUrl: 'components/devSettings/devSettings.html',
controller: 'DevSettingsCtrl'
})
.when('/debug/list', {
templateUrl: 'components/debug/debug.html',
controller: 'DebugCtrl'
})
angular.module('ulakbus')
.config(['$routeProvider', function ($routeProvider, $route) {
$routeProvider
.when('/login', {
templateUrl: 'components/auth/login.html',
controller: 'LoginCtrl'
})
.when('/dashboard', {
templateUrl: 'components/dashboard/dashboard.html',
controller: 'DashCtrl'
})
.when('/dev/settings', {
templateUrl: 'components/devSettings/devSettings.html',
controller: 'DevSettingsCtrl'
})
.when('/debug/list', {
templateUrl: 'components/debug/debug.html',
controller: 'DebugCtrl'
})
// use crud without selected user
// important: regex urls must be defined later than static ones
.when('/:wf/', {
templateUrl: 'components/crud/templates/crud.html',
controller: 'CRUDCtrl'
})
.when('/:wf/do/:cmd', {
templateUrl: 'components/crud/templates/crud.html',
controller: 'CRUDListFormCtrl'
})
.when('/:wf/do/:cmd/:key', {
templateUrl: 'components/crud/templates/crud.html',
controller: 'CRUDListFormCtrl'
})
.when('/:wf/:model', {
templateUrl: 'components/crud/templates/crud.html',
controller: 'CRUDCtrl'
})
.when('/:wf/:model/do/:cmd', {
templateUrl: 'components/crud/templates/crud.html',
controller: 'CRUDListFormCtrl'
})
.when('/:wf/:model/do/:cmd/:key', {
templateUrl: 'components/crud/templates/crud.html',
controller: 'CRUDListFormCtrl'
})
// use crud without selected user
// important: regex urls must be defined later than static ones
.when('/:wf/', {
templateUrl: 'components/crud/templates/crud.html',
controller: 'CRUDCtrl'
})
.when('/:wf/do/:cmd', {
templateUrl: 'components/crud/templates/crud.html',
controller: 'CRUDListFormCtrl'
})
.when('/:wf/do/:cmd/:key', {
templateUrl: 'components/crud/templates/crud.html',
controller: 'CRUDListFormCtrl'
})
.when('/:wf/:model', {
templateUrl: 'components/crud/templates/crud.html',
controller: 'CRUDCtrl'
})
.when('/:wf/:model/do/:cmd', {
templateUrl: 'components/crud/templates/crud.html',
controller: 'CRUDListFormCtrl'
})
.when('/:wf/:model/do/:cmd/:key', {
templateUrl: 'components/crud/templates/crud.html',
controller: 'CRUDListFormCtrl'
})
.otherwise({redirectTo: '/dashboard'});
}])
.otherwise({redirectTo: '/dashboard'});
}])
.run(function ($rootScope) {
$rootScope.loggedInUser = true;
......
......@@ -8,36 +8,55 @@
'use strict';
var auth = angular.module('ulakbus.auth', ['ngRoute', 'schemaForm', 'ngCookies']);
auth.controller('LoginCtrl', function ($scope, $q, $timeout, $routeParams, $rootScope, $log, Generator, LoginService) {
$scope.url = 'login';
$scope.form_params = {};
$scope.form_params['clear_wf'] = 1;
Generator.get_form($scope).then(function(data){
$scope.form = [
{ key: "username", type: "string", title: "Kullanıcı Adı"},
{ key: "password", type: "password", title: "Şifre"},
{ type: 'submit', title: 'Giriş Yap' }
];
});
$scope.loggingIn = false;
$scope.onSubmit = function (form) {
$scope.$broadcast('schemaFormValidate');
if (form.$valid) {
$scope.loggingIn = true;
$rootScope.loginAttempt = 1;
LoginService.login($scope.url, $scope.model)
.error(function(data){
$scope.message = data.title;
})
.then(function () {
$scope.loggingIn = false;
})
}
else {
$log.debug("not valid");
}
};
$log.debug('login attempt: ', $rootScope.loginAttempt);
/**
* @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.form_params = {};
$scope.form_params['clear_wf'] = 1;
Generator.get_form($scope).then(function (data) {
$scope.form = [
{key: "username", type: "string", title: "Kullanıcı Adı"},
{key: "password", type: "password", title: "Şifre"},
{type: 'submit', title: 'Giriş Yap'}
];
});
$scope.loggingIn = false;
$scope.onSubmit = function (form) {
$scope.$broadcast('schemaFormValidate');
if (form.$valid) {
$scope.loggingIn = true;
$rootScope.loginAttempt = 1;
Generator.button_switch(false);
AuthService.login($scope.url, $scope.model)
.error(function (data) {
$scope.message = data.title;
$scope.loggingIn = false;
})
.then(function () {
$scope.loggingIn = false;
Generator.button_switch(false);
})
}
else {
$log.debug("not valid");
}
};
$log.debug('login attempt: ', $rootScope.loginAttempt);
});
\ No newline at end of file
});
\ No newline at end of file
......@@ -8,39 +8,59 @@
"use strict";
// TODO: login url change with correct one
angular.module('ulakbus.auth')
/**
* @memberof ulakbus.auth
* @ngdoc service
* @name AuthService
* @description provides generic functions for authorization process.
*/
.factory('AuthService', function ($http, $rootScope, $location, $log, Generator, RESTURL) {
var authService = {};
auth.factory('LoginService', function ($http, $rootScope, $location, $log, RESTURL) {
var loginService = {};
/**
* @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";
return $http
.post(RESTURL.url + url, credentials)
.success(function (data, status, headers, config) {
//$window.sessionStorage.token = data.token;
loginService.login = function (url, credentials) {
credentials['cmd'] = "do";
return $http
.post(RESTURL.url + url, credentials)
.success(function (data, status, headers, config) {
//$window.sessionStorage.token = data.token;
$rootScope.loggedInUser = true;
})
.error(function (data, status, headers, config) {
// Handle login errors here
data.title = "İşlem başarısız oldu. Lütfen girdiğiniz bilgileri kontrol ediniz."
return data;
});
};
$rootScope.loggedInUser = true;
})
.error(function (data, status, headers, config) {
// Handle login errors here
return data;
/**
* @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");
return $http.post(RESTURL.url + 'logout', {}).success(function (data) {
$rootScope.loggedInUser = false;
$log.debug("loggedout");
$location.path("/login");
});
};
};
loginService.logout = function () {
$log.debug("logout");
return $http.post(RESTURL.url + 'logout', {}).success(function (data) {
$rootScope.loggedInUser = false;
$log.debug("loggedout");
$location.path("/login");
});
};
loginService.isValidEmail = function (email) {
var re = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
return re.test(email);
};
return loginService;
});
\ No newline at end of file
return authService;
});
\ No newline at end of file
......@@ -10,26 +10,30 @@
describe('ulakbus.auth module', function () {
// load dependencies of modules e.g REST_URL
beforeEach(module('ulakbus'));
beforeEach(module('ulakbus.auth'));
describe('login controller and service', function () {
var $controller;
var $rootScope;
it('should have a login controller', inject(function () {
expect('ulakbus.auth.LoginCtrl').toBeDefined();
}));
beforeEach(inject(function (_$controller_) {
$controller = _$controller_;
}));
var $controller;
var $rootScope;
beforeEach(inject(function ($injector) {
$rootScope = $injector.get('$rootScope');
}));
beforeEach(inject(function (_$controller_) {
$controller = _$controller_;
}));
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 () {
beforeEach(inject(function ($injector) {
$httpBackend = $injector.get('$httpBackend');
$rootScope = $injector.get('$rootScope');
it('should have a login controller', inject(function () {
expect('ulakbus.auth.LoginCtrl').toBeDefined();
}));
it('should get login form', inject(
......@@ -43,65 +47,22 @@ describe('ulakbus.auth module', function () {
var controller = $controller('LoginCtrl', {$scope: $scope});
expect($scope.onSubmit).toBeDefined();
//expect($scope.loginForm).toBeDefined();
//
//$scope.onSubmit($scope.loginForm);
})
);
it('should validate email', inject(['LoginService',
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) {
it('ensures user can log in', function (AuthService, $httpBackend, RESTURL) {
// todo: after backend api ready implement this
});
it('should get login success',
inject(function (LoginService, $httpBackend, $location, RESTURL) {
inject(function (AuthService, $httpBackend, $location, RESTURL) {
// use httpBackend to imitate login api
$httpBackend.expectPOST(RESTURL.url + 'login', {
email: 'test@test.com',
password: 'password',
cmd: 'do'
})
// todo: with real api change response data from list to obj
.respond(200, [{
'id': 1, 'user': {
'id': 12
......@@ -111,11 +72,9 @@ describe('ulakbus.auth module', function () {
}]);
var cred = {email: 'test@test.com', password: 'password'};
LoginService.login('login', cred)
AuthService.login('login', cred)
.then(function (data) {
expect(data).not.toBe(null);
// after login path need to be change dashboard
//expect($location.path()).toBe('');
});
$httpBackend.flush();
......@@ -123,7 +82,7 @@ describe('ulakbus.auth module', function () {
);
it('should logout',
inject(function (LoginService, $httpBackend, $location, RESTURL) {
inject(function (AuthService, $httpBackend, $location, RESTURL) {
// use httpBackend to imitate login api
......@@ -132,7 +91,7 @@ describe('ulakbus.auth module', function () {
is_login: false
});
LoginService.logout().success(function (data) {
AuthService.logout().success(function (data) {
expect(data.is_login).toBe(false);
});
......
......@@ -7,8 +7,20 @@
*/
'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) {
sfErrorMessageProvider.setDefaultMessage(302, 'Bu alan zorunludur.');
sfErrorMessageProvider.setDefaultMessage(200, 'En az {{schema.minLength}} değer giriniz.');
......@@ -16,22 +28,24 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService'])
})
/**
* @memberof ulakbus.crud
* @ngdoc service
* @name CrudUtility
* @description
* Crud Utility is a service to provide functionality for Crud controllers
* @returns {object}
* @description Crud Utility is a service to provide generic functions for Crud controllers to format data and
* scope object.
* @returns {service}
*/
.service('CrudUtility', function ($log, $rootScope) {
return {
/**
* @memberof ulakbus.crud
* @ngdoc function
* @name generateParam
* @description
* generateParam is a function to generate required params to post backend api.
*
* @param scope
* @param routeParams
* @param cmd
* @returns {*}
* @description generateParam is a function to generate required params to post backend api.
* @param {object} scope
* @param {object} routeParams
* @param {string} cmd
* @returns {object} scope
*/
generateParam: function (scope, routeParams, cmd) {
scope.url = routeParams.wf;
......@@ -66,12 +80,13 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService'])
return scope;
},
/**
* @memberof ulakbus.crud
* @ngdoc function
* @name listPageItems
* @description
* listPageItems is a function to prepare objects to list in list page.
* @description listPageItems is a function to prepare objects to list in the list page.
*
* @param scope
* @param pageData
* @param {object} scope
* @param {object} pageData
*/
listPageItems: function (scope, pageData) {
angular.forEach(pageData, function (value, key) {
......@@ -104,9 +119,10 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService'])
})
/**
* @memberof ulakbus.crud
* @ngdoc controller
* @name CRUDCtrl
* @description
* CRUDCtrl controller is base controller for crud module to redirect to related controller
* @description CRUDCtrl controller is base controller for crud module to redirect to related controller
* This controller play an empty role for api calls.
* With response data, location path change to related controller
*
......@@ -119,17 +135,19 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService'])
})
/**
* @memberof ulakbus.crud
* @ngdoc controller
* @name CRUDListFormCtrl
* @description
* CRUDListFormCtrl is the main controller for crud module
* @description CRUDListFormCtrl is the main controller for crud module
* Based on the client_cmd parameter it generates its scope items.
* client_cmd can be in ['show', 'list', 'form', 'reload', 'refresh']
* There are 3 directives to manipulate controllers scope objects in crud.html
*
* <br>
* 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
* 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.
*
* @returns {object}
......@@ -238,6 +256,10 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService'])
CrudUtility.generateParam($scope, $routeParams, $routeParams.cmd);
Generator.get_wf($scope);
}
if ($scope.object) {
$scope.createListObjects();
}
};
$scope.reloadCmd = function () {
$scope.reload({});
......@@ -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 () {
return {
templateUrl: 'components/crud/templates/list.html',
......@@ -267,7 +296,13 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService'])
replace: true
};
})
/**
* @memberof ulakbus.crud
* @ngdoc directive
* @name crudFormDirective
* @description directive for form generation.
* provides template for `scope.forms` object.
*/
.directive('crudFormDirective', function () {
return {
templateUrl: 'components/crud/templates/form.html',
......@@ -275,7 +310,13 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService'])
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 () {
return {
templateUrl: 'components/crud/templates/show.html',
......@@ -283,7 +324,13 @@ angular.module('ulakbus.crud', ['ui.bootstrap', 'schemaForm', 'formService'])
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 () {
return {
link: function (scope) {
......@@ -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) {
return {
templateUrl: 'components/crud/templates/filter.html',
......
......@@ -10,7 +10,7 @@ describe('crud controller module', function () {
beforeEach(module('ulakbus'));
beforeEach(module('ulakbus.crud'));
beforeEach(module('formService'));
beforeEach(module('ulakbus.formService'));
beforeEach(inject(function ($injector) {
$httpBackend = $injector.get('$httpBackend');
......
<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">
......@@ -125,107 +125,24 @@
</div>
<!-- end of dashboard-main-anouncement -->
<div class="right-sidebar">
<!--<div class="right-sidebar selected-person-field">-->
<div class="right-sidebar-box" data-step="4"
data-intro="mesajlar, yapılan görevlerin son durumları, duyurular ve son yapılan işlemleri buradan takip edebilirsiniz.">
<div class="right-sidebar-messages">
<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>-->
<!--&lt;!&ndash; end of right-sidebar-title &ndash;&gt;-->
<!--<div class="right-sidebar-announcement-block">-->
<!--<a ng-click="markAsRead(notify)"-->
<!--ng-repeat="notify in notifications[3] | limitTo:5">{{notify-->
<!--.body}}</a>-->
<!--</div>-->
<!--&lt;!&ndash; end of right-sidebar-status-block &ndash;&gt;-->
<!--</div>-->
<!--&lt;!&ndash; end of right-sidebar-status &ndash;&gt;-->
<!--<div class="right-sidebar-header">-->
<!--<span class="bar-title">Kişi seçildi</span>-->
<!--<span class="unselect-person"><i class="fa fa-times"></i></span>-->
<!--</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>
<!--&lt;!&ndash; end of right-sidebaer-header &ndash;&gt;-->
<!---->
<!--<div class="selected-person-info">-->
<!--<img src="../../img/sample-profile-pic.jpg" class="selected-person-img">-->
<!--<div class="selected-person-name">Erkan Öğümsöğütlü</div>-->
<!--</div>-->
<!--&lt;!&ndash; end of selected-person-info &ndash;&gt;-->
<div class="right-sidebar-task-block">
<a>
<div class="task-title"></div>
</a>
</div>
<!--</div>-->
<!-- end of right-sidebar -->
</div>
<!-- end of right-sidebar-status -->
</div>
<!-- end of right-sidebar-box -->
</div>
<!-- end of right-sidebar -->
</div>
</div>
\ No newline at end of file
......@@ -8,6 +8,14 @@
'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', [])
.config(function ($uibTooltipProvider) {
$uibTooltipProvider.setTriggers({'click': 'mouseleave'});
......
......@@ -8,7 +8,7 @@
'use strict';
app.config(['$routeProvider', function ($routeProvider) {
angular.module('ulakbus').config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/error/500', {
templateUrl: 'components/error_pages/500.html',
......
......@@ -64,7 +64,7 @@
<div class="main" ng-view>
</div>
<right-sidebar></right-sidebar>
</div>
</div>
</div>
......
......@@ -71,7 +71,7 @@
<div class="main" ng-view>
</div>
<right-sidebar></right-sidebar>
</div>
</div>
</div>
......
......@@ -8,14 +8,26 @@
'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', [
'ui.bootstrap',
'angular-loading-bar',
'ngRoute',
'ngSanitize',
'ngCookies',
'formService',
'ulakbus.formService',
'ulakbus.dashboard',
'ulakbus.auth',
'ulakbus.error_pages',
......@@ -31,50 +43,37 @@ var app = angular.module(
// @if NODE_ENV='DEVELOPMENT'
'ulakbus.uitemplates'
// @endif
]).
/**
* RESTURL is the url of rest api to talk
* Based on the environment it changes from dev to prod
*/
constant("RESTURL", (function () {
// 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/";
if (document.cookie.indexOf("backendurl") > -1) {
var cookiearray = document.cookie.split(';');
angular.forEach(cookiearray, function (item) {
if (item.indexOf("backendurl") > -1) {
backendurl = item.split('=')[1];
}
});
}
])
/**
* @memberof ulakbus
* @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 () {
// 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/";
if (document.cookie.indexOf("backendurl") > -1) {
var cookiearray = document.cookie.split(';');
angular.forEach(cookiearray, function (item) {
if (item.indexOf("backendurl") > -1) {
backendurl = item.split('=')[1];
}
});
}
if (location.href.indexOf("backendurl") > -1) {
var urlfromqstr = location.href.split('?')[1].split('=')[1];
backendurl = decodeURIComponent(urlfromqstr.replace(/\+/g, " "));
document.cookie = "backendurl=" + backendurl;
window.location.href = window.location.href.split('?')[0];
}
if (location.href.indexOf("backendurl") > -1) {
var urlfromqstr = location.href.split('?')[1].split('=')[1];
backendurl = decodeURIComponent(urlfromqstr.replace(/\+/g, " "));
document.cookie = "backendurl=" + backendurl;
window.location.href = window.location.href.split('?')[0];
}
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'
})
return {url: backendurl};
})())
.config(function ($logProvider) {
// @if NODE_ENV='PRODUCTION'
$logProvider.debugEnabled(false);
......@@ -82,10 +81,4 @@ constant("USER_ROLES", {
// @if NODE_ENV='DEVELOPMENT'
$logProvider.debugEnabled(true);
// @endif
});
// test the code with strict di mode to see if it works when minified
//angular.bootstrap(document, ['ulakbus'], {
// strictDi: true
//});
});
\ No newline at end of file
......@@ -4,13 +4,18 @@
*
* This file is licensed under the GNU General Public License v3
* (GPLv3). See LICENSE.txt for details.
* @type {ng.$compileProvider|*}
*/
/**
* logout directive
*/
app.directive('logout', function ($http, $location, RESTURL) {
angular.module('ulakbus')
/**
* @memberof ulakbus
* @ngdoc directive
* @name logout
* @description logout directive provides a button with click event. When triggered it post to
* '/logout' path of the API.
*/
.directive('logout', function ($http, $location, RESTURL) {
return {
link: function ($scope, $element, $rootScope) {
$element.on('click', function () {
......@@ -22,17 +27,26 @@ app.directive('logout', function ($http, $location, RESTURL) {
}
};
})
/**
* headerNotification directive for header
* @memberof ulakbus
* @ngdoc directive
* @name headerNotification
* @description This directive is responsible to get and show notification.
* It calls API's /notify path with given interval and broadcasts `notifications` application-wide.
* There are 4 types of notifications:
* 1: tasks, 2: messages, 3: announcements, 4: recents
* - Notifications can be disabled in /dev/settings page
*/
.directive('headerNotification', function ($http, $rootScope, $cookies, $interval, RESTURL) {
return {
templateUrl: 'shared/templates/directives/header-notification.html',
restrict: 'E',
replace: true,
link: function ($scope) {
/**
* Group notifications
* @param notifications
*/
$scope.groupNotifications = function (notifications) {
// notification categories:
// 1: tasks, 2: messages, 3: announcements, 4: recents
......@@ -42,6 +56,10 @@ app.directive('logout', function ($http, $location, RESTURL) {
$scope.notifications[value.type].push(value);
});
};
/**
* Get notifications from API's /notify path and group it then broadcast "notifications" object.
* {ignoreLoadingBar: true} is telling loading bar not work on this particular request.
*/
$scope.getNotifications = function () {
// ignore loading bar here
$http.get(RESTURL.url + "notify", {ignoreLoadingBar: true}).success(function (data) {
......@@ -59,8 +77,11 @@ app.directive('logout', function ($http, $location, RESTURL) {
}
}, 5000);
// when clicked mark as read notification
// it can be list of notifications
/**
* When clicked mark the notification as read.
* @param items
* @todo: do it in detail page of notification
*/
$scope.markAsRead = function (items) {
$http.post(RESTURL.url + "notify", {ignoreLoadingBar: true, read: [items]})
.success(function (data) {
......@@ -76,9 +97,12 @@ app.directive('logout', function ($http, $location, RESTURL) {
}
};
})
/**
*
* @memberof ulakbus
* @ngdoc directive
* @name searchDirective
* @description This directive provides reusable search form application-wide.
* When search form submitted and response returns, it broadcasts the result with key `updateObjects`.
*/
.directive('searchDirective', function (Generator, $log, $rootScope) {
return {
......@@ -130,9 +154,12 @@ app.directive('logout', function ($http, $location, RESTURL) {
}
};
})
/**
*
* @memberof ulakbus
* @ngdoc directive
* @name sortDirective
* @description Sort directive is responsible to post sorting params to API and process the response to the screen.
* @todo test and implement when backend ready
*/
.directive('sortDirective', function (Generator, $log) {
return {
......@@ -180,13 +207,12 @@ app.directive('logout', function ($http, $location, RESTURL) {
}
};
})
/**
* collapseMenu directive
* toggle collapses sidebar menu when clicked menu button
* @memberof ulakbus
* @ngdoc directive
* @name collapseMenu
* @description Toggle collapses sidebar menu when clicked menu button
*/
.directive('collapseMenu', function ($timeout, $window, $cookies) {
return {
templateUrl: 'shared/templates/directives/menuCollapse.html',
......@@ -224,16 +250,16 @@ app.directive('logout', function ($http, $location, RESTURL) {
}
};
})
/**
* headerSubmenu directive
* @memberof ulakbus
* @ngdoc directive
* @name headerSubmenu
* @description Contains breadcrumb elements and loading animation
*/
.directive('headerSubMenu', function ($location) {
return {
templateUrl: 'shared/templates/directives/header-sub-menu.html',
restrict: 'E',
//controller: "CRUDAddEditCtrl",
replace: true,
link: function ($scope) {
$scope.style = 'width:calc(100% - 300px);';
......@@ -243,12 +269,12 @@ app.directive('logout', function ($http, $location, RESTURL) {
}
};
})
/**
* breadcrumb directive
* produces breadcrumb with related links
* @memberof ulakbus
* @ngdoc directive
* @name breadcrumb
* @description Produces breadcrumb with related links
*/
.directive('headerBreadcrumb', function ($location) {
return {
templateUrl: 'shared/templates/directives/header-breadcrumb.html',
......@@ -261,12 +287,13 @@ app.directive('logout', function ($http, $location, RESTURL) {
}
};
})
/**
* selected user directive
* todo: unused
* @memberof ulakbus
* @ngdoc directive
* @name selectedUser
* @description Selected user on which the current job done is hold in this directive.
* @deprecated
*/
.directive('selectedUser', function ($http, RESTURL) {
return {
templateUrl: 'shared/templates/directives/selected-user.html',
......@@ -295,14 +322,13 @@ app.directive('logout', function ($http, $location, RESTURL) {
}
};
})
/**
* sidebar directive
* changes breadcrumb when an item selected
* consists of menu items of related user or transaction
* controller communicates with dashboard controller to shape menu items and authz
* @memberof ulakbus
* @ngdoc directive
* @name sidebar
* @description Changes breadcrumb when an item selected consists of menu items of related user or transaction
* controller communicates with dashboard controller to shape menu items and authz.
*/
.directive('sidebar', ['$location', function () {
return {
templateUrl: 'shared/templates/directives/sidebar.html',
......@@ -321,7 +347,7 @@ app.directive('logout', function ($http, $location, RESTURL) {
};
var sidebarmenu = $('#side-menu');
var sidebarUserMenu = $('#side-user-menu');
//var sidebarUserMenu = $('#side-user-menu');
sidebarmenu.metisMenu();
$http.get(RESTURL.url + 'menu/')
.success(function (data) {
......@@ -372,7 +398,7 @@ app.directive('logout', function ($http, $location, RESTURL) {
$timeout(function () {
sidebarmenu.metisMenu();
sidebarUserMenu.metisMenu();
//sidebarUserMenu.metisMenu();
});
});
......@@ -381,12 +407,11 @@ app.directive('logout', function ($http, $location, RESTURL) {
$scope.$on("menuitems", function (event, data) {
var menu = {};
menu[data] = $scope.allMenuItems[data];
//menu['other'] = $scope.allMenuItems.other;
$scope.selectedMenuItems = $scope.prepareMenu(menu);
$timeout(function () {
//sidebarmenu.metisMenu();
sidebarUserMenu.metisMenu();
});
$rootScope.$broadcast("usermenuitems", $scope.prepareMenu(menu));
//$timeout(function () {
// sidebarmenu.metisMenu();
// sidebarUserMenu.metisMenu();
//});
});
$scope.$on('selectedUser', function ($event, data) {
......@@ -459,7 +484,81 @@ app.directive('logout', function ($http, $location, RESTURL) {
}
};
}])
/**
* @memberof ulakbus
* @ngdoc directive
* @name rightSidebar
* @description placeholder
*/
.directive('rightSidebar', ['$location', function () {
return {
templateUrl: 'shared/templates/directives/right-sidebar.html',
restrict: 'E',
replace: true,
scope: {},
controller: function ($scope, $rootScope, $cookies, $route, $http, RESTURL, $log, $location, $window, $timeout) {
var sidebarUserMenu = $('#side-user-menu');
sidebarUserMenu.metisMenu();
$scope.$on("usermenuitems", function (event, data) {
$scope.selectedMenuItems = data;
$timeout(function () {
sidebarUserMenu.metisMenu();
});
jQuery(".right-sidebar").css("width", "300px");
jQuery(".manager-view-inner").css("width", "calc(100% - 300px)");
});
$scope.$on('selectedUser', function ($event, data) {
$scope.selectedUser = data;
});
$scope.deselectUser = function () {
jQuery(".right-sidebar").css("width", "0px");
jQuery(".manager-view-inner").css("width", "");
delete $scope.selectedUser;
delete $scope.selectedMenuItems;
};
$rootScope.$watch(function ($rootScope) {
return $rootScope.section;
},
function (newindex, oldindex) {
if (newindex > -1) {
$scope.menuItems = [$scope.allMenuItems[newindex]];
$scope.collapseVar = 0;
}
});
$scope.selectedMenu = $location.path();
$scope.collapseVar = 0;
$scope.multiCollapseVar = 0;
$scope.check = function (x) {
if (x === $scope.collapseVar) {
$scope.collapseVar = 0;
} else {
$scope.collapseVar = x;
}
};
$scope.multiCheck = function (y) {
if (y === $scope.multiCollapseVar) {
$scope.multiCollapseVar = 0;
} else {
$scope.multiCollapseVar = y;
}
};
}
}
}])
/**
* @memberof ulakbus
* @ngdoc directive
* @name stats
* @description Statistical data directive.
* @todo unused for now
*/
.directive('stats', function () {
return {
templateUrl: 'shared/templates/directives/stats.html',
......@@ -478,11 +577,12 @@ app.directive('logout', function ($http, $location, RESTURL) {
};
})
/**
* header menu notifications directive
* @memberof ulakbus
* @ngdoc directive
* @name notifications
* @description Holds notifications template with related rootscope items.
*/
.directive('notifications', function () {
return {
templateUrl: 'shared/templates/directives/notifications.html',
......@@ -490,11 +590,12 @@ app.directive('logout', function ($http, $location, RESTURL) {
replace: true
};
})
/**
* msgbox directive
* @memberof ulakbus
* @ngdoc directive
* @name msgbox
* @description Holds msgbox template with related rootscope items.
*/
.directive('msgbox', function () {
return {
templateUrl: 'shared/templates/directives/msgbox.html',
......@@ -502,12 +603,12 @@ app.directive('logout', function ($http, $location, RESTURL) {
replace: false
};
})
/**
* alert directive
* @memberof ulakbus
* @ngdoc directive
* @name alertBox
* @description Triggers when `alertBox` broadcasted with alert data..
*/
.directive('alertBox', function ($timeout) {
return {
templateUrl: 'shared/templates/directives/alert.html',
......@@ -523,11 +624,12 @@ app.directive('logout', function ($http, $location, RESTURL) {
}
};
})
/**
* search directive in sidebar
* @memberof ulakbus
* @ngdoc directive
* @name sidebarSearch
* @description unused for now
*/
.directive('sidebarSearch', function () {
return {
templateUrl: 'shared/templates/directives/sidebar-search.html',
......@@ -539,7 +641,13 @@ app.directive('logout', function ($http, $location, RESTURL) {
}
};
})
/**
* @memberof ulakbus
* @ngdoc directive
* @name fileread
* @description Fileread directive is responsible for reading uploaded file and replace it to related model item.
* @todo implement preview only for images
*/
.directive("fileread", function ($timeout) {
return {
scope: {
......@@ -564,20 +672,4 @@ app.directive('logout', function ($http, $location, RESTURL) {
});
}
}
});
//app.directive('timeline', function () {
// return {
// templateUrl: 'shared/templates/directives/timeline.html',
// restrict: 'E',
// replace: true,
// };
//});
//
//app.directive('chat', function () {
// return {
// templateUrl: 'shared/templates/directives/chat.html',
// restrict: 'E',
// replace: true,
// };
//});
\ No newline at end of file
});
\ No newline at end of file
......@@ -82,11 +82,10 @@
<!-- /.dropdown-alerts -->
</li>
<!-- /.dropdown -->
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-user fa-fw" tooltip-placement="bottom"
uib-tooltip="Profil"></i>&nbsp;{{$root.current_user.name}}&nbsp;{{$root.current_user.surname}}&nbsp;<i
class="fa fa-caret-down"></i>
<li class="dropdown" style="border-left:1px solid #891723;">
<a class="dropdown-toggle" data-toggle="dropdown" style="padding-top: 7px; padding-bottom: 6px;">
<img src="../../../img/sample-profile-pic.jpg" class="header-profile">&nbsp;{{$root.current_user.name}}&nbsp;{{$root.current_user.surname}}&nbsp;
<i class="fa fa-caret-down" style="margin-left:3px;"></i>
</a>
<ul class="dropdown-menu dropdown-user">
<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">
<header-breadcrumb></header-breadcrumb>
<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="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">
<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.">
......
......@@ -22,7 +22,7 @@
<span ng-if="value.verbose_name">{{ value.verbose_name }}</span>
<span ng-if="!value.verbose_name">{{key}}</span>
</th>
<th>İşlem</th>
<th ng-if="meta.allow_actions!==false">İşlem</th>
</tr>
</thead>
<tbody ng-class="{hidden: node.lengthModels < 1}">
......@@ -55,7 +55,7 @@
ng-model="node.model[outerIndex][k]"
ng-change="nodeModelChange(this)">
</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>
<br>
......
/**
* @license Ulakbus-UI
* Copyright (C) 2015 ZetaOps Inc.
*
* This file is licensed under the GNU General Public License v3
* (GPLv3). See LICENSE.txt for details.
*/
/**
* @name formService
* @ngdoc module
* @name ulakbus.formService
* @module ulakbus.formService
* @description
*
* The `formService` module provides generic services for auto generated forms.
*
* @requires ui.bootstrap
* @type {ng.$compileProvider|*}
*/
angular.module('formService', ['ui.bootstrap'])
angular.module('ulakbus.formService', ['ui.bootstrap'])
/**
* Moment.js used for date type conversions.
* there must be no global object, so we change it into a service here.
*/
.service('Moment', function(){
return window.moment;
})
/**
* @memberof ulakbus.formService
* @ngdoc factory
* @name Generator
* @description
* form service's Generator factory service handles all generic form operations
* @description form service's Generator factory service handles all generic form operations
*/
.factory('Generator', function ($http, $q, $timeout, $sce, $location, $route, $compile, $log, RESTURL, $rootScope, Moment) {
var generator = {};
/**
* @memberof ulakbus.formService
* @ngdoc function
* @name makeUrl
* @description
* this function generates url combining backend url and the related object properties for http requests
* @description this function generates url combining backend url and the related object properties for http requests
* @param scope
* @returns {string}
* @param scope
*/
generator.makeUrl = function (scope) {
var getparams = scope.form_params.param ? "?" + scope.form_params.param + "=" + scope.form_params.id : "";
return RESTURL.url + scope.url + getparams;
};
/**
* @memberof ulakbus.formService
* @ngdoc function
* @name generate
* @param scope
* @param data
* @description
* # generate function is inclusive for form generation
* @description - generate function is inclusive for form generation
* defines given scope's client_cmd, model, schema, form, token, object_id objects
*
* @returns {string}
* @returns {*} scope
* @param scope
* @param data
*/
generator.generate = function (scope, data) {
......@@ -77,14 +87,14 @@ angular.module('formService', ['ui.bootstrap'])
return scope;
};
/**
* @memberof ulakbus.formService
* @ngdoc function
* @name group
* @param scope
* @description
* group function to group form layout by form meta data for layout
*
* grouping will use an object like below when parsing its items:
*
* grouping = [
* @description group function to group form layout by form meta data for layout
* grouping will use an object like example below when parsing its items.
* @example
* `grouping = [
* {
* "groups": [
* {
......@@ -104,9 +114,10 @@ angular.module('formService', ['ui.bootstrap'])
* ],
* "layout": "2",
* "collapse": False
* }]
* }]`
*
* @returns {object}
* @returns {*}
* @param scope
*/
generator.group = function (scope) {
......@@ -179,14 +190,22 @@ angular.module('formService', ['ui.bootstrap'])
return scope;
};
/**
* @memberof ulakbus.formService
* @ngdoc function
* @name prepareFormItems
* @param scope {Object} given scope on which form items prepared
* @description
* prepareFormItems looks up fields of schema objects and changes their types to proper type for schemaform
* for listnode, node and model types it uses templates to generate modal
* prepareforms checks input types and convert if necessary
* It looks up fields of schema objects and changes their types to proper type for schemaform.
* To prepare items for schemaform loop items of scope.schema.properties by checking index value's `type` key.
*
* @param scope
* @returns {*}
* If `type` is in `['file', 'select', 'submit', 'date', 'int', 'text_general', 'model', 'ListNode', 'Node']`
* then the item must be converted into the data format which schemaform works with.
*
*
* For listnode, node and model types it uses templates to generate modal. The modal is aa instance of
* ui.bootstraps modal directive.
*
* @returns scope {Object}
*/
generator.prepareFormItems = function (scope) {
......@@ -220,7 +239,7 @@ angular.module('formService', ['ui.bootstrap'])
$scope.$broadcast('schemaForm.error.' + k, 'tv4-302', true);
},
imageSrc: scope.model[k] ? $rootScope.settings.static_url + scope.model[k] : '',
avatar: k === 'avatar' ? true : false
avatar: k === 'avatar'
};
v.type = 'string';
}
......@@ -276,6 +295,12 @@ angular.module('formService', ['ui.bootstrap'])
if (scope[workOnForm].$valid) {
generator.submit(scope, redirectTo);
scope.$broadcast('disposeModal');
} else {
// focus to first input with validation error
$timeout(function () {
var firsterror = angular.element(document.querySelectorAll('input.ng-invalid'))[0]
firsterror.focus();
});
}
}
}
......@@ -565,7 +590,7 @@ angular.module('formService', ['ui.bootstrap'])
url: scope.url,
wf: scope.wf,
nodeModelChange: function (item) {
debugger;
//debugger;
}
});
......@@ -641,8 +666,11 @@ angular.module('formService', ['ui.bootstrap'])
return generator.group(scope);
};
/**
* dateformatter handles all date fields and returns humanized and jquery datepicker format dates
* @param formObject
* @memberof ulakbus.formService
* @ngdoc function
* @name dateformatter
* @description dateformatter handles all date fields and returns humanized and jquery datepicker format dates
* @param {Object} formObject
* @returns {*}
*/
generator.dateformatter = function (formObject) {
......@@ -655,10 +683,21 @@ angular.module('formService', ['ui.bootstrap'])
return newdatearray;
}
};
/**
* @memberof ulakbus.formService
* @ngdoc function
* @name doItemAction
* @description `mode` could be in ['normal', 'modal', 'new'] . the default mode is 'normal' and it loads data
* on same
* tab without modal. 'modal' will use modal to manipulate data and do all actions in that modal. 'new'
* will be open new page with response data
* @param {Object} $scope
* @param {string} key
* @param {Object} todo
* @param {string} mode
* @returns {*}
*/
generator.doItemAction = function ($scope, key, todo, mode) {
// mode could be in ['normal', 'modal', 'new'] . the default mode is 'normal' and it loads data on same
// tab without modal. 'modal' will use modal to manipulate data and do all actions in that modal. 'new'
// will be open new page with response data
var _do = {
normal: function () {
$log.debug('normal mode starts');
......@@ -690,36 +729,70 @@ angular.module('formService', ['ui.bootstrap'])
};
return _do[mode]();
};
/**
* @memberof ulakbus.formService
* @ngdoc function
* @name button_switch
* @description Changes html disabled and enabled attributes of all buttons on current page.
* @param {boolean} position
*/
generator.button_switch = function (position) {
var buttons = angular.element(document.querySelectorAll('button'));
var positions = {true: "enabled", false: "disabled"};
angular.forEach(buttons, function (button, key) {
button[positions[position]] = true;
});
$log.debug('buttons >> ', positions[position])
}
/**
* @memberof ulakbus.formService
* @ngdoc function
* @name get_form
* @description Communicates with api with given scope object.
* @param {Object} scope
* @returns {*}
*/
generator.get_form = function (scope) {
generator.button_switch(false);
return $http
.post(generator.makeUrl(scope), scope.form_params)
.then(function (res) {
generator.button_switch(true);
return generator.generate(scope, res.data);
});
};
/**
* gets list of related wf/model
* @memberof ulakbus.formService
* @ngdoc function
* @name get_list
* @description gets list of related wf/model
* @param scope
* @returns {*}
*/
generator.get_list = function (scope) {
generator.button_switch(false);
return $http
.post(generator.makeUrl(scope), scope.form_params)
.then(function (res) {
generator.button_switch(true);
return res;
});
};
/**
* get_wf is the main function for client_cmd based api calls
* @memberof ulakbus.formService
* @ngdoc function
* @name get_wf
* @description get_wf is the main function for client_cmd based api calls
* based on response content it redirects to related path/controller with pathDecider function
* @param scope
* @returns {*}
*/
generator.get_wf = function (scope) {
generator.button_switch(false);
return $http
.post(generator.makeUrl(scope), scope.form_params)
.then(function (res) {
generator.button_switch(true);
if (res.data.client_cmd) {
return generator.pathDecider(res.data.client_cmd, scope, res.data);
}
......@@ -732,45 +805,47 @@ angular.module('formService', ['ui.bootstrap'])
}
});
};
/**
* @memberof ulakbus.formService
* @ngdoc function
* @name isValidEmail
* @description checks if given value is a valid email address.
* @param email
* @returns {boolean}
*/
generator.isValidEmail = function (email) {
var re = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
return re.test(email);
};
/**
* @memberof ulakbus.formService
* @ngdoc function
* @name isValidTCNo
* @description checks if given value is a valid identity number for Turkey.
* @param tcno
* @returns {boolean}
*/
generator.isValidTCNo = function (tcno) {
var re = /^([1-9]{1}[0-9]{9}[0,2,4,6,8]{1})$/i;
return re.test(tcno);
};
/**
* @memberof ulakbus.formService
* @ngdoc function
* @name isValidDate
* @description checks if given value can be parsed as Date object
* @param dateValue
* @returns {boolean}
*/
generator.isValidDate = function (dateValue) {
return !isNaN(Date.parse(dateValue));
};
//generator.asyncValidators = {
// emailNotValid: function (value) {
// var deferred = $q.defer();
// $timeout(function () {
// if (generator.isValidEmail(value)) {
// deferred.resolve();
// } else {
// deferred.reject();
// }
// }, 500);
// return deferred.promise;
// },
// tcNoNotValid: function (value) {
// var deferred = $q.defer();
// $timeout(function () {
// if (generator.isValidTCNo(value)) {
// deferred.resolve();
// } else {
// deferred.reject();
// }
// }, 500);
// return deferred.promise;
// }
//};
/**
* pageData object is moving object from response to controller
* @memberof ulakbus.formService
* @ngdoc property
* @name pageData
* @description pageData object is moving object from response to controller
* with this object controller will not need to call the api for response object to work on to
* @type {{}}
*/
......@@ -784,10 +859,13 @@ angular.module('formService', ['ui.bootstrap'])
/**
* pathDecider is used to redirect related path by looking up the data in response
* @param client_cmd
* @param $scope
* @param data
* @memberof ulakbus.formService
* @ngdoc function
* @name pathDecider
* @description pathDecider is used to redirect related path by looking up the data in response
* @param {string} client_cmd
* @param {Object} $scope
* @param {Object} data
*/
generator.pathDecider = function (client_cmd, $scope, data) {
if (client_cmd[0] === 'reload' || client_cmd[0] === 'reset') {
......@@ -795,13 +873,15 @@ angular.module('formService', ['ui.bootstrap'])
return;
}
/**
* @memberof ulakbus.formService
* @ngdoc function
* @name redirectTo
* @description
* redirectTo function redirects to related controller and path with given data
* @description redirectTo function redirects to related controller and path with given data
* before redirect setPageData must be called and pageData need to be defined
* otherwise redirected path will call api for its data
* @param scope
* @param page
* @param {Object} scope
* @param {string} page
* @return {*}
*/
function redirectTo(scope, page) {
var pathUrl = '/' + scope.form_params.wf;
......@@ -822,8 +902,13 @@ angular.module('formService', ['ui.bootstrap'])
}
}
// client_cmd can be in ['list', 'form', 'show', 'reload', 'reset']
/**
* @memberof ulakbus.formService
* @ngdoc function
* @name dispatchClientCmd
* @description Sets params for scope to the related page and redirect to the page in client_cmd param.
* client_cmd can be in ['list', 'form', 'show', 'reload', 'reset']
*/
function dispatchClientCmd() {
data[$scope.form_params.param] = $scope.form_params.id;
data['model'] = $scope.form_params.model;
......@@ -840,22 +925,46 @@ angular.module('formService', ['ui.bootstrap'])
dispatchClientCmd();
};
generator.get_diff = function (obj1, obj2) {
/**
* @memberof ulakbus.formService
* @ngdoc function
* @name get_diff
* @description returns diff of the second param to first param
* @param {Object} obj1
* @param {Object} obj2
* @returns {Object} diff object of two given objects
*/
generator.get_diff = function (oldObj, newObj) {
var result = {};
angular.forEach(obj1, function (value, key) {
if (obj2[key] != obj1[key]) {
result[key] = angular.copy(obj1[key])
}
if (obj2[key].constructor === Array && obj1[key].constructor === Array) {
result[key] = arguments.callee(obj1[key], obj2[key]);
}
if (obj2[key].constructor === Object && obj1[key].constructor === Object) {
result[key] = arguments.callee(obj1[key], obj2[key]);
angular.forEach(newObj, function (value, key) {
if (oldObj[key]) {
if ((oldObj[key].constructor === newObj[key].constructor) && (newObj[key].constructor === Object || newObj[key].constructor === Array)) {
angular.forEach(value, function (v, k) {
if (oldObj[key][k] != value[k]) {
result[key][k] = angular.copy(value[k]);
}
});
} else {
if (oldObj[key] != newObj[key]) {
result[key] = angular.copy(newObj[key]);
}
}
} else {
result[key] = angular.copy(newObj[key]);
}
});
return result;
};
/**
* @memberof ulakbus.formService
* @ngdoc function
* @name get_diff_array
* @description extracts items of second array from the first array
* @param {Array} array1
* @param {Array} array2
* @param {Number} way
* @returns {Array} diff of arrays
*/
generator.get_diff_array = function (array1, array2, way) {
var result = [];
angular.forEach(array1, function (value, key) {
......@@ -871,8 +980,15 @@ angular.module('formService', ['ui.bootstrap'])
});
return result;
};
// get item unicode name from titleMap using this method
/**
* @memberof ulakbus.formService
* @ngdoc function
* @name item_from_array
* @description gets item unicode name from titleMap
* @param {Object} item
* @param {Array} array
* @returns {*}
*/
generator.item_from_array = function (item, array) {
var result = item;
angular.forEach(array, function (value, key) {
......@@ -884,13 +1000,47 @@ angular.module('formService', ['ui.bootstrap'])
};
/**
* submit function is general function for submiting forms
* @param $scope
* @memberof ulakbus.formService
* @ngdoc function
* @name submit
* @description Submit function is generic function for submiting forms.
* - redirectTo param is used for redirect if return value will be evaluated in a new page.
* - In case of unformatted date object in any key recursively, it must be converted by convertDate function.
* - ListNode and Node objects get seperated from model in
* {@link prepareFormItems module:ulakbus.formService.function:prepareFormItems} They must be concat to model
* key of scope first.
* - Backend API waits form as model value. So `data.form` key must be set to `$scope.model`
* - Other parameters we pass to backend API are shown in the example below
* ```
* var data = {
"form": $scope.model,
"token": $scope.token,
"model": $scope.form_params.model,
"cmd": $scope.form_params.cmd,
"flow": $scope.form_params.flow,
"object_id": $scope.object_id,
"filter": $scope.filter,
"query": $scope.form_params.query
};
* ```
*
* Special response object process
* -------------------------------
*
* - If response object is a downloadable pdf file, checking from headers `headers('content-type') ===
* "application/pdf"` download using Blob object.
*
* @param {Object} $scope
* @param {Object} redirectTo
* @returns {*}
* @todo diff for all submits to recognize form change. if no change returns to view with no submit
*/
generator.submit = function ($scope, redirectTo) {
// todo: diff for all submits to recognize form change. if no change returns to view with no submit
/**
* In case of unformatted date object in any key recursively, it must be converted.
* @param model
*/
var convertDate = function (model) {
angular.forEach(model, function (value, key) {
if (value && value.constructor === Date) {
......@@ -948,14 +1098,16 @@ angular.module('formService', ['ui.bootstrap'])
})
/**
* @memberof ulakbus.formService
* @ngdoc controller
* @name ModalCtrl
* @description
* controller for listnode, node and linkedmodel modal and save data of it
* @param items
* @requires $scope, $uibModalInstance, $route
* @returns returns value for modal
* @description controller for listnode, node and linkedmodel modal and save data of it
* @param {Object} items
* @param {Object} $scope
* @param {Object} $uibModalInstance
* @param {Object} $route
* @returns {Object} returns value for modal
*/
.controller('ModalCtrl', function ($scope, $uibModalInstance, Generator, items) {
angular.forEach(items, function (value, key) {
$scope[key] = items[key];
......@@ -998,11 +1150,13 @@ angular.module('formService', ['ui.bootstrap'])
})
/**
* @memberof ulakbus.formService
* @ngdoc directive
* @name modalForNodes
* @description
* add modal directive for nodes
* @param $uibModal
* @returns openmodal directive
* @description add modal directive for nodes
* @param {Module} $uibModal
* @param {Service} Generator
* @returns {Object} openmodal directive
*/
.directive('modalForNodes', function ($uibModal, Generator) {
......@@ -1117,13 +1271,16 @@ angular.module('formService', ['ui.bootstrap'])
/**
* @memberof ulakbus.formService
* @ngdoc directive
* @name addModalForLinkedModel
* @description
* add modal directive for linked models
* @param $uibModal, Generator
* @returns openmodal directive
* @description add modal directive for linked models
* @param {Module} $uibModal
* @param {Object} $rootScope
* @param {Module} $route
* @param {Service} Generator
* @returns {Object} openmodal directive
*/
.directive('addModalForLinkedModel', function ($uibModal, $rootScope, $route, Generator) {
return {
link: function (scope, element, attributes) {
......@@ -1193,47 +1350,17 @@ angular.module('formService', ['ui.bootstrap'])
};
})
/**
* @memberof ulakbus.formService
* @ngdoc directive
* @name modalFormLocator
* @description This directive helps to locate form object in modal.
* @returns {Object} form object
*/
.directive('modalFormLocator', function () {
return {
link: function (scope) {
scope.$emit('modalFormLocator');
}
}
})
/**
* @name editModalForLinkedModel
* @description
* edit modal directive for linked models
* @param $uibModal, Generator
* @returns openmodal directive
*/
// todo: useless modal check if any use cases?? and delete if useless
.directive('editModalForLinkedModel', function ($uibModal, Generator) {
return {
link: function (scope, element) {
element.on('click', function () {
var modalInstance = $uibModal.open({
animation: false,
templateUrl: 'shared/templates/linkedModelModalContent.html',
controller: 'ModalCtrl',
size: 'lg',
resolve: {
items: function () {
return Generator.get_form({
url: 'crud',
form_params: {'model': scope.form.title, "cmd": "form"}
});
}
}
});
modalInstance.result.then(function (childmodel, key) {
Generator.submit(childmodel);
});
});
}
};
});
\ No newline at end of file
......@@ -10,7 +10,7 @@
describe('form service module', function () {
beforeEach(module('ulakbus'));
beforeEach(module('formService'));
beforeEach(module('ulakbus.formService'));
var location;
beforeEach(inject(function ($location, $injector) {
......@@ -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(
function (Generator, $httpBackend, RESTURL) {
expect(Generator.prepareFormItems).not.toBe(null);
......@@ -107,14 +114,14 @@ describe('form service module', function () {
var scope = {
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: {
properties: {
email: {title: 'email', type: 'email'},
id: {title: 'id', type: 'int'},
name: {title: 'name', type: 'string'},
save: {title: 'save', type: 'submit'},
select: {title: 'select', type: 'select', key: 'select'},
select: {title: 'select', type: 'select'},
date: {title: 'date', type: 'date'},
date2: {title: 'date', type: 'date'},
text_general: {title: 'text_general', type: 'text_general'},
......@@ -174,14 +181,22 @@ describe('form service module', function () {
},
grouping: [
{
"group_title": "title-1",
"items": ["email", "id"],
"groups": [
{
"group_title": "title-1",
"items": ["email", "id"],
}
],
"layout": "4",
"collapse": false
},
{
"group_title": "title-2",
"items": ["name", "save"],
"groups": [
{
"group_title": "title-2",
"items": ["name", "save"],
}
],
"layout": "2",
"collapse": false
}
......@@ -483,8 +498,8 @@ describe('form service module', function () {
// test cases - testing for success
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', 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', foo2: [1,2,3], foo: {'a':1}}
];
// test cases - testing for failure
......@@ -511,21 +526,21 @@ describe('form service module', function () {
var diff = {email: 'test1@test.com', 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 same = Generator.get_diff(same_json[0], same_json[1]);
expect(same).toEqual(nodiff);
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);
}
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);
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);
})
);
......
......@@ -6,133 +6,149 @@
* (GPLv3). See LICENSE.txt for details.
*/
app.config(['$httpProvider', function ($httpProvider) {
/**
* the interceptor for all requests to check response
* 4xx - 5xx errors will be handled here
*/
$httpProvider.interceptors.push(function ($q, $rootScope, $location, $timeout, $log) {
return {
'request': function (config) {
if (config.method === "POST") {
// to prevent OPTIONS preflight request
config.headers["Content-Type"] = "text/plain";
}
return config;
},
'response': function (response) {
//Will only be called for HTTP up to 300
if (response.data._debug_queries) {
if (response.data._debug_queries.length > 0) {
$rootScope.debug_queries = $rootScope.debug_queries || [];
$rootScope.debug_queries.push({
"url": response.config.url,
"queries": response.data._debug_queries
});
angular.module('ulakbus')
.config(['$httpProvider', function ($httpProvider) {
/**
* @memberof ulakbus.formService
* @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) {
return {
'request': function (config) {
if (config.method === "POST") {
// to prevent OPTIONS preflight request
config.headers["Content-Type"] = "text/plain";
}
}
if (response.data.is_login === false) {
$rootScope.loggedInUser = response.data.is_login;
$location.path("/login");
}
if (response.data.is_login === true) {
$rootScope.loggedInUser = true;
$rootScope.loginAttempt = 1; // this needs for popup errors
if ($location.path() === "/login") {
$location.path("/dashboard");
}
}
return config;
},
'response': function (response) {
//Will only be called for HTTP up to 300
// if (response.data.client_cmd) {
//$location.path(response.data.screen);
// }
return response;
},
'responseError': function (rejection) {
if (response.data._debug_queries) {
if (response.data._debug_queries.length > 0) {
$rootScope.debug_queries = $rootScope.debug_queries || [];
$rootScope.debug_queries.push({
"url": response.config.url,
"queries": response.data._debug_queries
});
}
}
var errorModal = function () {
if ($rootScope.loginAttempt === 0) {
$log.debug('not logged in, no alert message triggered');
return;
if (response.data.is_login === false) {
$rootScope.loggedInUser = response.data.is_login;
$location.path("/login");
}
var codefield = "";
if (rejection.data.error) {
codefield = '<p><pre>' +
rejection.data.error +
'</pre></p>';
if (response.data.is_login === true) {
$rootScope.loggedInUser = true;
$rootScope.loginAttempt = 1; // this needs for popup errors
if ($location.path() === "/login") {
$location.path("/dashboard");
}
}
$('<div class="modal">' +
'<div class="modal-dialog" style="width:100%;" role="document">' +
'<div class="modal-content">' +
'<div class="modal-header">' +
'<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span' +
' aria-hidden="true">&times;</span></button>' +
'<h4 class="modal-title" id="exampleModalLabel">' +
rejection.status+ rejection.data.title +
'</h4>' +
'</div>' +
'<div class="modal-body">' +
'<div class="alert alert-danger">' +
'<strong>' +
rejection.data.description +
'</strong>' +
codefield +
'</div>'+
'</div>' +
'<div class="modal-footer">' +
'<button type="button" class="btn btn-default" data-dismiss="modal">Kapat</button>' +
'</div>' +
'</div>' +
'</div>' +
'</div>').modal();
try {
$('pre:not(.hljs)').each(function(i, block) {
hljs.highlightBlock(block);
// if (response.data.client_cmd) {
//$location.path(response.data.screen);
// }
return response;
},
'responseError': function (rejection) {
var errorModal = function () {
if ($rootScope.loginAttempt === 0) {
$log.debug('not logged in, no alert message triggered');
return;
}
var codefield = "";
if (rejection.data.error) {
codefield = '<p><pre>' +
rejection.data.error +
'</pre></p>';
}
$('<div class="modal">' +
'<div class="modal-dialog" style="width:100%;" role="document">' +
'<div class="modal-content">' +
'<div class="modal-header">' +
'<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span' +
' aria-hidden="true">&times;</span></button>' +
'<h4 class="modal-title" id="exampleModalLabel">' +
rejection.status + rejection.data.title +
'</h4>' +
'</div>' +
'<div class="modal-body">' +
'<div class="alert alert-danger">' +
'<strong>' +
rejection.data.description +
'</strong>' +
codefield +
'</div>' +
'</div>' +
'<div class="modal-footer">' +
'<button type="button" class="btn btn-default" data-dismiss="modal">Kapat</button>' +
'</div>' +
'</div>' +
'</div>' +
'</div>').modal();
try {
$('pre:not(.hljs)').each(function (i, block) {
hljs.highlightBlock(block);
});
}
catch (e) {
$log.debug('Exception: ', e.message);
}
};
if (rejection.status === -1) {
rejection.status = 'Sunucu hatası'
rejection.data = {
title: "", description: 'Sunucu bağlantısında bir hata oluştu.' +
'Lütfen yetkili personelle iletişime geçiniz.'
};
$rootScope.$broadcast('alertBox', {
title: rejection.status,
msg: rejection.data.description,
type: 'error'
});
}
catch (e) {
$log.debug('Exception: ', e.message);
}
};
if (rejection.status === -1) {
rejection.status = 'Sunucu hatası'
rejection.data = {title: "", description : 'Sunucu bağlantısında bir hata oluştu.' +
'Lütfen yetkili personelle iletişime geçiniz.'};
$rootScope.$broadcast('alertBox', {title: rejection.status, msg: rejection.data.description, type: 'error'});
}
if (rejection.status === 400) {
$location.reload();
}
if (rejection.status === 401) {
$location.path('/login');
if ($location.path() === "/login") {
$log.debug("show errors on login form");
if (rejection.status === 400) {
$location.reload();
}
}
if (rejection.status === 403) {
if (rejection.data.is_login === true) {
$rootScope.loggedInUser = true;
if (rejection.status === 401) {
$location.path('/login');
if ($location.path() === "/login") {
$location.path("/dashboard");
$log.debug("show errors on login form");
}
}
//errorModal();
}
$rootScope.$broadcast('show_notifications', rejection.data);
if (rejection.status === 403) {
if (rejection.data.is_login === true) {
$rootScope.loggedInUser = true;
if ($location.path() === "/login") {
$location.path("/dashboard");
}
}
//errorModal();
}
$rootScope.$broadcast('show_notifications', rejection.data);
if (rejection.status === 404) {
errorModal();
}
if (rejection.status === 500) {
errorModal();
if (rejection.status === 404) {
errorModal();
}
if (rejection.status === 500) {
errorModal();
}
return $q.reject(rejection);
}
return $q.reject(rejection);
}
};
});
}]);
\ No newline at end of file
};
});
}]);
\ No newline at end of file
/*! ulakbus-ui 2015-12-28 */
"use strict";var app=angular.module("ulakbus",["ui.bootstrap","angular-loading-bar","ngRoute","ngSanitize","ngCookies","formService","ulakbus.dashboard","ulakbus.auth","ulakbus.error_pages","ulakbus.crud","ulakbus.debug","ulakbus.devSettings","ulakbus.version","gettext","templates-prod"]).constant("RESTURL",function(){var backendurl=location.href.indexOf("nightly")>-1?"//nightly.api.ulakbus.net/":"//api.ulakbus.net/";if(document.cookie.indexOf("backendurl")>-1){var cookiearray=document.cookie.split(";");angular.forEach(cookiearray,function(item){item.indexOf("backendurl")>-1&&(backendurl=item.split("=")[1])})}if(location.href.indexOf("backendurl")>-1){var urlfromqstr=location.href.split("?")[1].split("=")[1];backendurl=decodeURIComponent(urlfromqstr.replace(/\+/g," ")),document.cookie="backendurl="+backendurl,window.location.href=window.location.href.split("?")[0]}return{url:backendurl}}()).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){$logProvider.debugEnabled(!1)});app.config(["$routeProvider",function($routeProvider,$route){$routeProvider.when("/login",{templateUrl:"components/auth/login.html",controller:"LoginCtrl"}).when("/dashboard",{templateUrl:"components/dashboard/dashboard.html",controller:"DashCtrl"}).when("/dev/settings",{templateUrl:"components/devSettings/devSettings.html",controller:"DevSettingsCtrl"}).when("/debug/list",{templateUrl:"components/debug/debug.html",controller:"DebugCtrl"}).when("/:wf/",{templateUrl:"components/crud/templates/crud.html",controller:"CRUDCtrl"}).when("/:wf/do/:cmd",{templateUrl:"components/crud/templates/crud.html",controller:"CRUDListFormCtrl"}).when("/:wf/do/:cmd/:key",{templateUrl:"components/crud/templates/crud.html",controller:"CRUDListFormCtrl"}).when("/:wf/:model",{templateUrl:"components/crud/templates/crud.html",controller:"CRUDCtrl"}).when("/:wf/:model/do/:cmd",{templateUrl:"components/crud/templates/crud.html",controller:"CRUDListFormCtrl"}).when("/:wf/:model/do/:cmd/:key",{templateUrl:"components/crud/templates/crud.html",controller:"CRUDListFormCtrl"}).otherwise({redirectTo:"/dashboard"})}]).run(function($rootScope){$rootScope.loggedInUser=!0,$rootScope.loginAttempt=0,$rootScope.$on("$routeChangeStart",function(event,next,current){})}).config(["$httpProvider",function($httpProvider){$httpProvider.defaults.withCredentials=!0}]).run(function(gettextCatalog){gettextCatalog.setCurrentLanguage("tr"),gettextCatalog.debug=!0}).config(["cfpLoadingBarProvider",function(cfpLoadingBarProvider){cfpLoadingBarProvider.includeBar=!1,cfpLoadingBarProvider.parentSelector="loaderdiv",cfpLoadingBarProvider.spinnerTemplate='<div class="loader">Loading...</div>'}]),app.config(["$httpProvider",function($httpProvider){$httpProvider.interceptors.push(function($q,$rootScope,$location,$timeout,$log){return{request:function(config){return"POST"===config.method&&(config.headers["Content-Type"]="text/plain"),config},response:function(response){return response.data._debug_queries&&response.data._debug_queries.length>0&&($rootScope.debug_queries=$rootScope.debug_queries||[],$rootScope.debug_queries.push({url:response.config.url,queries:response.data._debug_queries})),response.data.is_login===!1&&($rootScope.loggedInUser=response.data.is_login,$location.path("/login")),response.data.is_login===!0&&($rootScope.loggedInUser=!0,$rootScope.loginAttempt=1,"/login"===$location.path()&&$location.path("/dashboard")),response},responseError:function(rejection){var errorModal=function(){if(0===$rootScope.loginAttempt)return void $log.debug("not logged in, no alert message triggered");var codefield="";rejection.data.error&&(codefield="<p><pre>"+rejection.data.error+"</pre></p>"),$('<div class="modal"><div class="modal-dialog" style="width:100%;" role="document"><div class="modal-content"><div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button><h4 class="modal-title" id="exampleModalLabel">'+rejection.status+rejection.data.title+'</h4></div><div class="modal-body"><div class="alert alert-danger"><strong>'+rejection.data.description+"</strong>"+codefield+'</div></div><div class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">Kapat</button></div></div></div></div>').modal();try{$("pre:not(.hljs)").each(function(i,block){hljs.highlightBlock(block)})}catch(e){$log.debug("Exception: ",e.message)}};return-1===rejection.status&&(rejection.status="Sunucu hatası",rejection.data={title:"",description:"Sunucu bağlantısında bir hata oluştu.Lütfen yetkili personelle iletişime geçiniz."},$rootScope.$broadcast("alertBox",{title:rejection.status,msg:rejection.data.description,type:"error"})),400===rejection.status&&$location.reload(),401===rejection.status&&($location.path("/login"),"/login"===$location.path()&&$log.debug("show errors on login form")),403===rejection.status&&rejection.data.is_login===!0&&($rootScope.loggedInUser=!0,"/login"===$location.path()&&$location.path("/dashboard")),$rootScope.$broadcast("show_notifications",rejection.data),404===rejection.status&&errorModal(),500===rejection.status&&errorModal(),$q.reject(rejection)}}})}]),angular.module("formService",["ui.bootstrap"]).service("Moment",function(){return window.moment}).factory("Generator",function($http,$q,$timeout,$sce,$location,$route,$compile,$log,RESTURL,$rootScope,Moment){var generator={};return generator.makeUrl=function(scope){var getparams=scope.form_params.param?"?"+scope.form_params.param+"="+scope.form_params.id:"";return RESTURL.url+scope.url+getparams},generator.generate=function(scope,data){return data.forms?(angular.forEach(data.forms,function(value,key){scope[key]=data.forms[key]}),scope.client_cmd=data.client_cmd,scope.token=data.token,scope.initialModel=angular.copy(scope.model),generator.prepareFormItems(scope),scope.object_id=scope.form_params.object_id,$log.debug("scope at after generate",scope),scope):scope},generator.group=function(scope){if(!scope.grouping)return scope;var newForm=[],extractFormItem=function(itemList){var extractedList=[];return angular.forEach(itemList,function(value,key){var item=getFormItem(value);item&&extractedList.push(item)}),$log.debug("extractedList: ",extractedList),extractedList},getFormItem=function(item){var formItem;return scope.form.indexOf(item)>-1?(formItem=scope.form[scope.form.indexOf(item)],scope.form.splice(scope.form.indexOf(item),1),formItem):(angular.forEach(scope.form,function(value,key){return value.key===item?(formItem=value,void scope.form.splice(key,1)):void 0}),formItem)},makeGroup=function(itemsToGroup){var subItems=[];return angular.forEach(itemsToGroup,function(value,key){subItems.push({type:"fieldset",items:extractFormItem(value.items),title:value.group_title})}),subItems};return angular.forEach(scope.grouping,function(value,key){newForm.push({type:"fieldset",items:makeGroup(value.groups),htmlClass:"col-md-"+value.layout,title:value.group_title})}),$log.debug("grouped form: ",newForm),$log.debug("rest of form: ",scope.form),$log.debug("form united: ",newForm.concat(scope.form)),scope.form=newForm.concat(scope.form),scope},generator.prepareFormItems=function(scope){return angular.forEach(scope.form,function(value,key){"select"===value.type&&(scope.schema.properties[value.key].type="select",scope.schema.properties[value.key].titleMap=value.titleMap,scope.form[key]=value.key)}),angular.forEach(scope.schema.properties,function(v,k){if("form_params"in scope&&k==scope.form_params.param)return scope.model[k]=scope.form_params.id,void scope.form.splice(scope.form.indexOf(k),1);if("file"===v.type&&(scope.form[scope.form.indexOf(k)]={type:"template",title:v.title,templateUrl:"shared/templates/filefield.html",name:k,key:k,fileInsert:function(){$scope.$broadcast("schemaForm.error."+k,"tv4-302",!0)},imageSrc:scope.model[k]?$rootScope.settings.static_url+scope.model[k]:"",avatar:"avatar"===k?!0:!1},v.type="string"),"select"===v.type&&(scope.form[scope.form.indexOf(k)]={type:"template",title:v.title,templateUrl:"shared/templates/select.html",name:k,key:k,titleMap:v.titleMap}),"submit"===v.type||"button"===v.type){var buttonPositions=scope.modalElements?scope.modalElements.buttonPositions:{bottom:"move-to-bottom",top:"move-to-top",none:""},workOnForm=scope.modalElements?scope.modalElements.workOnForm:"formgenerated",workOnDiv=scope.modalElements?scope.modalElements.workOnDiv:"",buttonClass=buttonPositions[v.position]||buttonPositions.bottom,redirectTo=scope.modalElements?!1:!0;scope.form[scope.form.indexOf(k)]={type:v.type,title:v.title,style:"btn-danger hide "+buttonClass,onClick:function(){delete scope.form_params.cmd,delete scope.form_params.flow,v.cmd&&(scope.form_params.cmd=v.cmd),v.flow&&(scope.form_params.flow=v.flow),v.wf&&(delete scope.form_params.cmd,scope.form_params.wf=v.wf),scope.model[k]=1,scope.modalElements?scope.submitModalForm():v.validation===!1?generator.submit(scope,redirectTo):(scope.$broadcast("schemaFormValidate"),scope[workOnForm].$valid&&(generator.submit(scope,redirectTo),scope.$broadcast("disposeModal")))}},$timeout(function(){var selectorBottom=".buttons-on-bottom"+workOnDiv,buttonsToBottom=angular.element(document.querySelector("."+buttonClass));angular.element(document.querySelector(selectorBottom)).append(buttonsToBottom),buttonsToBottom.removeClass("hide")},500)}if("date"===v.type&&($log.debug("date:",scope.model[k]),scope.model[k]=generator.dateformatter(scope.model[k]),scope.form[scope.form.indexOf(k)]={key:k,name:k,title:v.title,type:"template",templateUrl:"shared/templates/datefield.html",validationMessage:{dateNotValid:"Girdiğiniz tarih geçerli değildir. <i>orn: '01.01.2015'<i/>",302:"Bu alan zorunludur."},$asyncValidators:{dateNotValid:function(value){var deferred=$q.defer();return $timeout(function(){if(scope.model[k]=angular.copy(generator.dateformatter(value)),scope.schema.required.indexOf(k)>-1&&deferred.resolve(),value.constructor===Date)deferred.resolve();else{var dateValue=d=value.split(".");isNaN(Date.parse(value))||3!==dateValue.length?deferred.reject():deferred.resolve()}}),deferred.promise}},status:{opened:!1},open:function($event){this.status.opened=!0},format:"dd.MM.yyyy",onSelect:function(){scope.model[k]=angular.copy(generator.dateformatter(scope.model[k]))}}),("int"===v.type||"float"===v.type)&&(v.type="number",scope.model[k]=parseInt(scope.model[k])),"text_general"===v.type&&(v.type="string",v["x-schema-form"]={type:"textarea"}),"model"===v.type){var formitem=scope.form[scope.form.indexOf(k)],modelScope={url:v.wf,wf:v.wf,form_params:{model:v.model_name,cmd:v.list_cmd}};scope.generateTitleMap=function(modelScope){return generator.get_list(modelScope).then(function(res){return formitem.titleMap=[],angular.forEach(res.data.objects,function(item){-1!==item?formitem.titleMap.push({value:item.key,name:item.value}):formitem.focusToInput=!0}),formitem.titleMap})},scope.model[k]&&generator.get_list({url:"crud",form_params:{model:v.model_name,object_id:scope.model[k],cmd:"object_name"}}).then(function(data){try{scope.$watch(document.querySelector("input[name="+v.model_name+"]"),function(){document.querySelector("input[name="+k+"]").value=data.data.object_name})}catch(e){document.querySelector("input[name="+k+"]").value=data.data.object_name,$log.debug("exception",e)}}),formitem={type:"template",templateUrl:"shared/templates/foreignKey.html",formName:k,title:v.title,wf:v.wf,add_cmd:v.add_cmd,name:k,key:k,model_name:v.model_name,selected_item:{},titleMap:[],onSelect:function(item,inputname){scope.model[k]=item.value,$timeout(function(){document.querySelector("input[name="+inputname+"]").value=item.name})},onDropdownSelect:function(item,inputname){scope.model[k]=item.value,$timeout(function(){document.querySelector("input[name="+inputname+"]").value=item.name})},getTitleMap:function(viewValue){return modelScope.form_params.query=viewValue,scope.generateTitleMap(modelScope)},getDropdownTitleMap:function(){delete modelScope.form_params.query,formitem.gettingTitleMap=!0,scope.generateTitleMap(modelScope).then(function(data){formitem.titleMap=data,formitem.gettingTitleMap=!1})}},scope.form[scope.form.indexOf(k)]=formitem}if(("ListNode"===v.type||"Node"===v.type)&&"filter_interface"===v.widget){var formitem=scope.form[scope.form.indexOf(k)],modelScope={url:v.wf||scope.wf,wf:v.wf||scope.wf,form_params:{model:v.model_name||v.schema[0].model_name,cmd:v.list_cmd||"select_list",query:""}};scope.generateTitleMap=function(modelScope){generator.get_list(modelScope).then(function(res){formitem.titleMap=[],angular.forEach(res.data.objects,function(item){"-1"!==item&&formitem.titleMap.push({value:item.key,name:item.value})}),formitem.filteredItems=generator.get_diff_array(angular.copy(formitem.titleMap),angular.copy(formitem.selectedFilteredItems),1)})};var modelItems=[],modelKeys=[];angular.forEach(scope.model[k],function(value,mkey){modelItems.push({value:value[v.schema[0].name].key,name:value[v.schema[0].name].unicode});var modelKey={};modelKey[v.schema[0].name]=value[v.schema[0].name].key,modelKeys.push(modelKey)}),scope.model[k]=angular.copy(modelKeys),formitem={type:"template",templateUrl:"shared/templates/multiselect.html",title:v.title,formName:k,wf:v.wf,add_cmd:v.add_cmd,name:v.model_name,model_name:v.model_name,filterValue:"",selected_item:{},filteredItems:[],selectedFilteredItems:modelItems,titleMap:scope.generateTitleMap(modelScope),appendFiltered:function(filterValue){filterValue.length>2&&(formitem.filteredItems=[],angular.forEach(formitem.titleMap,function(value,key){value.name.indexOf(filterValue)>-1&&formitem.filteredItems.push(formitem.titleMap[key])})),2>=filterValue&&(formitem.filteredItems=formitem.titleMap),formitem.filteredItems=generator.get_diff_array(formitem.filteredItems,formitem.selectedFilteredItems)},select:function(selectedItemsModel){selectedItemsModel&&(formitem.selectedFilteredItems=formitem.selectedFilteredItems.concat(selectedItemsModel),formitem.appendFiltered(formitem.filterValue),scope.model[k]=(scope.model[k]||[]).concat(formitem.dataToModel(selectedItemsModel)))},deselect:function(selectedFilteredItemsModel){selectedFilteredItemsModel&&(formitem.selectedFilteredItems=generator.get_diff_array(angular.copy(formitem.selectedFilteredItems),angular.copy(selectedFilteredItemsModel)),formitem.appendFiltered(formitem.filterValue),formitem.filteredItems=formitem.filteredItems.concat(selectedFilteredItemsModel),scope.model[k]=generator.get_diff_array(scope.model[k]||[],formitem.dataToModel(selectedFilteredItemsModel)))},dataToModel:function(data){var dataValues=[];return angular.forEach(data,function(value,key){var dataKey={};dataKey[v.schema[0].name]=value.value,dataValues.push(dataKey)}),dataValues}},scope.form[scope.form.indexOf(k)]=formitem}"ListNode"!==v.type&&"Node"!==v.type||"filter_interface"===v.widget||(scope[v.type]=scope[v.type]||{},scope[v.type][k]=angular.copy({title:v.title,form:[],schema:{properties:{},required:[],title:v.title,type:"object",formType:v.type,model_name:k,inline_edit:scope.inline_edit},url:scope.url,wf:scope.wf,nodeModelChange:function(item){}}),angular.forEach(v.schema,function(item){scope[v.type][k].schema.properties[item.name]=angular.copy(item),item.required===!0&&"idx"!==item.name&&scope[v.type][k].schema.required.push(angular.copy(item.name)),"idx"!==item.name&&scope[v.type][k].form.push(item.name);try{"date"===item.type&&(scope.model[k][item.name]=generator.dateformatter(scope.model[k][item.name]))}catch(e){$log.debug("Error: ",e.message)}}),$timeout(function(){"ListNode"===v.type&&(scope[v.type][k].items=angular.copy(scope.model[k]||[]),angular.forEach(scope[v.type][k].items,function(value,key){value.constructor===Object&&angular.forEach(value,function(x,y){try{"date"===scope[v.type][k].schema.properties[y].type&&(scope[v.type][k].items[key][y]=generator.dateformatter(x),scope[v.type][k].model[key][y]=generator.dateformatter(x)),"select"===scope[v.type][k].schema.properties[y].type&&(scope[v.type][k].items[key][y]=generator.item_from_array(x.toString(),scope[v.type][k].schema.properties[y].titleMap))}catch(e){$log.debug("Field is not date")}})}))}),scope.model[k]&&angular.forEach(scope.model[k],function(value,key){angular.forEach(value,function(y,x){y.constructor===Object&&(scope.model[k][key][x]=y.key)})}),scope.model[k]=scope.model[k]||[],scope[v.type][k].model=scope.model[k],scope[v.type][k].lengthModels=scope.model[k]?1:0)}),$log.debug("scope at after prepareformitems",scope),generator.group(scope)},generator.dateformatter=function(formObject){var ndate=new Date(formObject);if(isNaN(ndate))return"";var newdatearray=Moment(ndate).format("DD.MM.YYYY");return $log.debug("date formatted: ",newdatearray),newdatearray},generator.doItemAction=function($scope,key,todo,mode){var _do={normal:function(){return $log.debug("normal mode starts"),$scope.form_params.cmd=todo.cmd,todo.wf&&($scope.url=todo.wf,$scope.form_params.wf=todo.wf,delete $scope.token,delete $scope.form_params.model,delete $scope.form_params.cmd),todo.object_key?$scope.form_params[todo.object_key]=key:$scope.form_params.object_id=key,$scope.form_params.param=$scope.param,$scope.form_params.id=$scope.param_id,$scope.form_params.token=$scope.token,generator.get_wf($scope)},modal:function(){$log.debug("modal mode is not not ready")},"new":function(){$log.debug("new mode is not not ready")}};return _do[mode]()},generator.get_form=function(scope){return $http.post(generator.makeUrl(scope),scope.form_params).then(function(res){return generator.generate(scope,res.data)})},generator.get_list=function(scope){return $http.post(generator.makeUrl(scope),scope.form_params).then(function(res){return res})},generator.get_wf=function(scope){return $http.post(generator.makeUrl(scope),scope.form_params).then(function(res){if(res.data.client_cmd)return generator.pathDecider(res.data.client_cmd,scope,res.data);if(res.data.msgbox){scope.msgbox=res.data.msgbox;var newElement=$compile("<msgbox></msgbox>")(scope);angular.element(document.querySelector(".main.ng-scope")).children().remove(),angular.element(document.querySelector(".main.ng-scope")).append(newElement)}})},generator.isValidEmail=function(email){var re=/^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;return re.test(email)},generator.isValidTCNo=function(tcno){var re=/^([1-9]{1}[0-9]{9}[0,2,4,6,8]{1})$/i;return re.test(tcno)},generator.isValidDate=function(dateValue){return!isNaN(Date.parse(dateValue))},generator.pageData={},generator.getPageData=function(){return generator.pageData},generator.setPageData=function(value){generator.pageData=value},generator.pathDecider=function(client_cmd,$scope,data){function redirectTo(scope,page){var pathUrl="/"+scope.form_params.wf;return pathUrl+=scope.form_params.model?"/"+scope.form_params.model+"/do/"+page:"/do/"+page,$location.path()===pathUrl?$route.reload():void $location.path(pathUrl)}function dispatchClientCmd(){data[$scope.form_params.param]=$scope.form_params.id,data.model=$scope.form_params.model,data.wf=$scope.form_params.wf,data.param=$scope.form_params.param,data.param_id=$scope.form_params.id,data.pageData=!0,data.second_client_cmd=client_cmd[1],generator.setPageData(data),redirectTo($scope,client_cmd[0])}return"reload"===client_cmd[0]||"reset"===client_cmd[0]?void $rootScope.$broadcast("reload_cmd",$scope.reload_cmd):void dispatchClientCmd()},generator.get_diff=function(obj1,obj2){var result={};return angular.forEach(obj1,function(value,key){obj2[key]!=obj1[key]&&(result[key]=angular.copy(obj1[key])),obj2[key].constructor===Array&&obj1[key].constructor===Array&&(result[key]=arguments.callee(obj1[key],obj2[key])),obj2[key].constructor===Object&&obj1[key].constructor===Object&&(result[key]=arguments.callee(obj1[key],obj2[key]))}),result},generator.get_diff_array=function(array1,array2,way){var result=[];return angular.forEach(array1,function(value,key){1===way?angular.toJson(array2).indexOf(value.value)<0&&result.push(value):angular.toJson(array2).indexOf(angular.toJson(value))<0&&result.push(value)}),result},generator.item_from_array=function(item,array){var result=item;return angular.forEach(array,function(value,key){value.value===item&&(result=value.name)}),result},generator.submit=function($scope,redirectTo){angular.forEach($scope.ListNode,function(value,key){$scope.model[key]=value.model}),angular.forEach($scope.Node,function(value,key){$scope.model[key]=value.model});var data={form:$scope.model,token:$scope.token,model:$scope.form_params.model,cmd:$scope.form_params.cmd,flow:$scope.form_params.flow,object_id:$scope.object_id,filter:$scope.filter,query:$scope.form_params.query};return $http.post(generator.makeUrl($scope),data).success(function(data,status,headers){if("application/pdf"===headers("content-type")){var a=document.createElement("a");document.body.appendChild(a),a.style="display: none";var file=new Blob([data],{type:"application/pdf"}),fileURL=URL.createObjectURL(file),fileName=$scope.schema.title;a.href=fileURL,a.download=fileName,a.click()}if(redirectTo===!0&&(data.client_cmd&&generator.pathDecider(data.client_cmd,$scope,data),data.msgbox)){$scope.msgbox=data.msgbox;var newElement=$compile("<msgbox></msgbox>")($scope);angular.element(document.querySelector(".main.ng-scope")).children().remove(),angular.element(document.querySelector(".main.ng-scope")).append(newElement)}})},generator}).controller("ModalCtrl",function($scope,$uibModalInstance,Generator,items){angular.forEach(items,function(value,key){$scope[key]=items[key]}),$scope.$on("disposeModal",function(){$scope.cancel()}),$scope.$on("modalFormLocator",function(event){$scope.linkedModelForm=event.targetScope.linkedModelForm}),$scope.$on("submitModalForm",function(){$scope.onSubmit($scope.linkedModelForm)}),$scope.$on("validateModalDate",function(event,field){$scope.$broadcast("schemaForm.error."+field,"tv4-302",!0)}),$scope.onSubmit=function(form){$scope.$broadcast("schemaFormValidate"),form.$valid&&$uibModalInstance.close($scope)},$scope.onNodeSubmit=function(){$scope.$broadcast("schemaFormValidate"),$scope.modalForm.$valid&&$uibModalInstance.close($scope)},$scope.cancel=function(){$uibModalInstance.dismiss("cancel")}}).directive("modalForNodes",function($uibModal,Generator){return{link:function(scope,element,attributes){element.on("click",function(){var modalInstance=$uibModal.open({animation:!0,backdrop:"static",keyboard:!1,templateUrl:"shared/templates/listnodeModalContent.html",controller:"ModalCtrl",size:"lg",resolve:{items:function(){var attribs=attributes.modalForNodes.split(","),node=angular.copy(scope.$parent[attribs[1]][attribs[0]]);"add"===attribs[2]&&(node.model={}),attribs[3]&&(node.model=node.model[attribs[3]]),node.edit=attribs[3],scope.node.schema.wf=scope.node.url,angular.forEach(scope.node.schema.properties,function(value,key){scope.node.schema.properties[key].wf=scope.node.url,scope.node.schema.properties[key].list_cmd="select_list"});var newscope={wf:scope.node.wf,url:scope.node.url,form_params:{model:scope.node.schema.model_name},edit:attribs[3]};return Generator.generate(newscope,{forms:scope.node}),newscope.model=newscope.model[node.edit]||newscope.model[0]||{},newscope}}});modalInstance.result.then(function(childmodel,key){var listNodeItem=scope.$parent[childmodel.schema.formType][childmodel.schema.model_name];if("Node"===childmodel.schema.formType&&(listNodeItem.model=angular.copy(childmodel.model),listNodeItem.lengthModels+=1),"ListNode"===childmodel.schema.formType){var reformattedModel={};angular.forEach(childmodel.model,function(value,key){key.indexOf("_id")>-1?angular.forEach(childmodel.form,function(v,k){function indexInTitleMap(element,index,array){return element.value===value?element:void 0}v.formName===key&&(reformattedModel[key]={key:value,unicode:v.titleMap.find(indexInTitleMap).name})}):reformattedModel[key]={key:key,unicode:Generator.item_from_array(value,childmodel.schema.properties[key].titleMap)}}),childmodel.edit?(listNodeItem.model[childmodel.edit]=childmodel.model,Object.keys(reformattedModel).length>0?listNodeItem.items[childmodel.edit]=reformattedModel:listNodeItem.items[childmodel.edit]=angular.copy(childmodel.model)):(listNodeItem.model.push(angular.copy(childmodel.model)),Object.keys(reformattedModel).length>0?listNodeItem.items.push(reformattedModel):listNodeItem.items.push(angular.copy(childmodel.model))),listNodeItem.lengthModels+=1}})})}}}).directive("addModalForLinkedModel",function($uibModal,$rootScope,$route,Generator){return{link:function(scope,element,attributes){element.on("click",function(){var modalInstance=$uibModal.open({animation:!0,backdrop:"static",keyboard:!1,templateUrl:"shared/templates/linkedModelModalContent.html",controller:"ModalCtrl",size:"lg",resolve:{items:function(){var formName=attributes.addModalForLinkedModel;return Generator.get_form({url:scope.form.wf,wf:scope.form.wf,form_params:{model:scope.form.model_name,cmd:scope.form.add_cmd},modalElements:{buttonPositions:{bottom:"move-to-bottom-modal",top:"move-to-top-modal",none:""},workOnForm:"linkedModelForm",workOnDiv:"-modal"+formName},submitModalForm:function(){$rootScope.$broadcast("submitModalForm")},validateModalDate:function(field){$rootScope.$broadcast("validateModalDate",field)},formName:formName})}}});modalInstance.result.then(function(childscope,key){var formName=childscope.formName;Generator.submit(childscope,!1).success(function(data){scope.model[formName]=data.forms.model.object_key,scope.form.titleMap.push({value:data.forms.model.object_key,name:data.forms.model.unicode}),scope.form.selected_item={value:data.forms.model.object_key,name:data.forms.model.unicode},scope.$watch(document.querySelector("input[name="+scope.form.model_name+"]"),function(){angular.element(document.querySelector("input[name="+scope.form.model_name+"]")).val(scope.form.selected_item.name)})})})})}}}).directive("modalFormLocator",function(){return{link:function(scope){scope.$emit("modalFormLocator")}}}).directive("editModalForLinkedModel",function($uibModal,Generator){return{link:function(scope,element){element.on("click",function(){var modalInstance=$uibModal.open({animation:!1,templateUrl:"shared/templates/linkedModelModalContent.html",controller:"ModalCtrl",size:"lg",resolve:{items:function(){return Generator.get_form({url:"crud",form_params:{model:scope.form.title,cmd:"form"}})}}});modalInstance.result.then(function(childmodel,key){Generator.submit(childmodel)})})}}}),app.directive("logout",function($http,$location,RESTURL){return{link:function($scope,$element,$rootScope){$element.on("click",function(){$http.post(RESTURL.url+"logout",{}).then(function(){$rootScope.loggedInUser=!1,$location.path("/login")})})}}}).directive("headerNotification",function($http,$rootScope,$cookies,$interval,RESTURL){return{templateUrl:"shared/templates/directives/header-notification.html",restrict:"E",replace:!0,link:function($scope){$scope.groupNotifications=function(notifications){$scope.notifications={1:[],2:[],3:[],4:[]},angular.forEach(notifications,function(value,key){$scope.notifications[value.type].push(value)})},$scope.getNotifications=function(){$http.get(RESTURL.url+"notify",{ignoreLoadingBar:!0}).success(function(data){$scope.groupNotifications(data.notifications),$rootScope.$broadcast("notifications",$scope.notifications)})},$scope.getNotifications(),$interval(function(){"on"==$cookies.get("notificate")&&$scope.getNotifications()},5e3),$scope.markAsRead=function(items){$http.post(RESTURL.url+"notify",{ignoreLoadingBar:!0,read:[items]}).success(function(data){$scope.groupNotifications(data.notifications),$rootScope.$broadcast("notifications",$scope.notifications)})},$scope.$on("markasread",function(event,data){$scope.markAsRead(data)})}}}).directive("searchDirective",function(Generator,$log,$rootScope){return{templateUrl:"shared/templates/directives/search.html",restrict:"E",replace:!0,link:function($scope){$scope.searchForm=[{key:"searchbox",htmlClass:"pull-left"},{type:"submit",title:"Ara",style:"btn-info",htmlClass:"pull-left"}],$scope.searchSchema={type:"object",properties:{searchbox:{type:"string",minLength:2,title:"Ara","x-schema-form":{placeholder:"Arama kriteri giriniz..."}}},required:[]},$scope.searchModel={searchbox:""},$scope.searchSubmit=function(form){if($scope.$broadcast("schemaFormValidate"),form.$valid){var searchparams={url:$scope.wf,token:$scope.$parent.token,object_id:$scope.$parent.object_id,form_params:{model:$scope.$parent.form_params.model,cmd:$scope.$parent.reload_cmd,flow:$scope.$parent.form_params.flow,query:$scope.searchModel.searchbox}};Generator.submit(searchparams).success(function(data){$rootScope.$broadcast("updateObjects",data.objects)})}}}}}).directive("sortDirective",function(Generator,$log){return{templateUrl:"shared/templates/directives/sort.html",restrict:"E",replace:!0,link:function($scope){$scope.titleMap=[{value:"artan",name:"Artan"},{value:"azalan",name:"Azalan"}],$scope.sortForm=[{key:"sortbox",htmlClass:"pull-left",type:"select",titleMap:$scope.titleMap},{type:"submit",title:"Sırala",htmlClass:"pull-left"}],$scope.sortSchema={type:"object",properties:{sortbox:{type:"select",title:"Sırala"}},required:["sortbox"]},$scope.sortModel={sortbox:""},$scope.sortSubmit=function(form){if($scope.$broadcast("schemaFormValidate"),form.$valid){var sortparams={url:$scope.wf,token:$scope.$parent.token,object_id:$scope.$parent.object_id,form_params:{model:$scope.$parent.form_params.model,cmd:$scope.$parent.reload_cmd,flow:$scope.$parent.form_params.flow,param:"sort",id:$scope.sortModel.sortbox}};Generator.submit(sortparams)}}}}}).directive("collapseMenu",function($timeout,$window,$cookies){return{templateUrl:"shared/templates/directives/menuCollapse.html",restrict:"E",replace:!0,scope:{},controller:function($scope,$rootScope){$rootScope.collapsed=!1,$rootScope.sidebarPinned=$cookies.get("sidebarPinned")||0,$scope.collapseToggle=function(){$window.innerWidth>"768"&&($rootScope.collapsed===!1?(jQuery(".sidebar").css("width","62px"),jQuery(".manager-view").css("width","calc(100% - 62px)"),$rootScope.collapsed=!0,$rootScope.sidebarPinned=0,$cookies.put("sidebarPinned",0)):(jQuery("span.menu-text, span.arrow, .sidebar footer").fadeIn(400),jQuery(".sidebar").css("width","250px"),jQuery(".manager-view").css("width","calc(100% - 250px)"),$rootScope.collapsed=!1,$rootScope.sidebarPinned=1,$cookies.put("sidebarPinned",1)))},$timeout(function(){"0"===$cookies.get("sidebarPinned")&&$scope.collapseToggle()})}}}).directive("headerSubMenu",function($location){return{templateUrl:"shared/templates/directives/header-sub-menu.html",restrict:"E",replace:!0,link:function($scope){$scope.style="width:calc(100% - 300px);",$scope.$on("$routeChangeStart",function(){$scope.style="/dashboard"===$location.path()?"width:calc(100% - 300px);":"width:%100 !important;"})}}}).directive("headerBreadcrumb",function($location){return{templateUrl:"shared/templates/directives/header-breadcrumb.html",restrict:"E",replace:!1,link:function($scope){$scope.goBack=function(){$location.state()}}}}).directive("selectedUser",function($http,RESTURL){return{templateUrl:"shared/templates/directives/selected-user.html",restrict:"E",replace:!0,link:function($scope,$rootScope){$scope.$on("selectedUser",function($event,data){$scope.selectedUser=data,$scope.dynamicPopover={content:"",name:data.name,tcno:data.tcno,key:data.key,templateUrl:"shared/templates/directives/selectedUserPopover.html",title:"İşlem Yapılan Kişi"}}),$scope.$on("selectedUserTrigger",function($event,data){({model:"Personel",cmd:"show",id:data[1]});$http.get(RESTURL.url+"ara/personel/"+data[1]).success(function(data){})})}}}).directive("sidebar",["$location",function(){return{templateUrl:"shared/templates/directives/sidebar.html",
restrict:"E",replace:!0,scope:{},controller:function($scope,$rootScope,$cookies,$route,$http,RESTURL,$log,$location,$window,$timeout){$scope.prepareMenu=function(menuItems){var newMenuItems={};return angular.forEach(menuItems,function(value,key){angular.forEach(value,function(v,k){newMenuItems[k]=v})}),newMenuItems};var sidebarmenu=$("#side-menu"),sidebarUserMenu=$("#side-user-menu");sidebarmenu.metisMenu(),$http.get(RESTURL.url+"menu/").success(function(data){function reGroupMenuItems(items,baseCategory){var newItems={};return angular.forEach(items,function(value,key){newItems[value.kategori]=newItems[value.kategori]||[],value.baseCategory=baseCategory,newItems[value.kategori].push(value)}),newItems}$scope.allMenuItems=angular.copy(data),angular.forEach($scope.allMenuItems,function(value,key){"current_user"!==key&&"settings"!==key&&($scope.allMenuItems[key]=reGroupMenuItems(value,key))}),$rootScope.quick_menu=reGroupMenuItems(data.quick_menu,"quick_menus"),$rootScope.quick_menu=data.quick_menu,delete data.quick_menu,$log.debug("quick menu",$rootScope.quick_menu),$rootScope.$broadcast("authz",data),$rootScope.searchInputs=data,$rootScope.current_user=data.current_user,(data.ogrenci||data.personel)&&($rootScope.current_user.can_search=!0),$rootScope.settings=data.settings,$scope.menuItems=$scope.prepareMenu({other:$scope.allMenuItems.other}),$timeout(function(){sidebarmenu.metisMenu(),sidebarUserMenu.metisMenu()})}),$scope.$on("menuitems",function(event,data){var menu={};menu[data]=$scope.allMenuItems[data],$scope.selectedMenuItems=$scope.prepareMenu(menu),$timeout(function(){sidebarUserMenu.metisMenu()})}),$scope.$on("selectedUser",function($event,data){$scope.selectedUser=data}),$scope.deselectUser=function(){delete $scope.selectedUser,delete $scope.selectedMenuItems},$scope.openSidebar=function(){$window.innerWidth>"768"&&0===$rootScope.sidebarPinned&&(jQuery("span.menu-text, span.arrow, .sidebar footer, #side-menu").fadeIn(400),jQuery(".sidebar").css("width","250px"),jQuery(".manager-view").css("width","calc(100% - 250px)"),$rootScope.collapsed=!1)},$scope.closeSidebar=function(){$window.innerWidth>"768"&&0===$rootScope.sidebarPinned&&(jQuery(".sidebar").css("width","62px"),jQuery(".manager-view").css("width","calc(100% - 62px)"),$rootScope.collapsed=!0)},$rootScope.$watch(function($rootScope){return $rootScope.section},function(newindex,oldindex){newindex>-1&&($scope.menuItems=[$scope.allMenuItems[newindex]],$scope.collapseVar=0)}),$scope.selectedMenu=$location.path(),$scope.collapseVar=0,$scope.multiCollapseVar=0,$scope.check=function(x){x===$scope.collapseVar?$scope.collapseVar=0:$scope.collapseVar=x},$scope.breadcrumb=function(itemlist,$event){$rootScope.breadcrumblinks=itemlist},$scope.multiCheck=function(y){y===$scope.multiCollapseVar?$scope.multiCollapseVar=0:$scope.multiCollapseVar=y}}}}]).directive("stats",function(){return{templateUrl:"shared/templates/directives/stats.html",restrict:"E",replace:!0,scope:{model:"=",comments:"@",number:"@",name:"@",colour:"@",details:"@",type:"@","goto":"@"}}}).directive("notifications",function(){return{templateUrl:"shared/templates/directives/notifications.html",restrict:"E",replace:!0}}).directive("msgbox",function(){return{templateUrl:"shared/templates/directives/msgbox.html",restrict:"E",replace:!1}}).directive("alertBox",function($timeout){return{templateUrl:"shared/templates/directives/alert.html",restrict:"E",replace:!0,link:function($scope){$scope.$on("alertBox",function($event,data){$timeout(function(){delete $scope.alerts},5e3),$scope.alerts=[data]})}}}).directive("sidebarSearch",function(){return{templateUrl:"shared/templates/directives/sidebar-search.html",restrict:"E",replace:!0,scope:{},controller:function($scope){$scope.selectedMenu="home"}}}).directive("fileread",function($timeout){return{scope:{fileread:"="},link:function(scope,element,attributes){element.bind("change",function(changeEvent){var reader=new FileReader;reader.onload=function(loadEvent){scope.$apply(function(){scope.fileread=loadEvent.target.result}),$timeout(function(){scope.$parent.model[changeEvent.target.name]={file_name:changeEvent.target.files[0].name,file_content:scope.$parent.model[changeEvent.target.name]},document.querySelector("#image-preview").src=URL.createObjectURL(changeEvent.target.files[0])})},reader.readAsDataURL(changeEvent.target.files[0])})}}});var auth=angular.module("ulakbus.auth",["ngRoute","schemaForm","ngCookies"]);auth.controller("LoginCtrl",function($scope,$q,$timeout,$routeParams,$rootScope,$log,Generator,LoginService){$scope.url="login",$scope.form_params={},$scope.form_params.clear_wf=1,Generator.get_form($scope).then(function(data){$scope.form=[{key:"username",type:"string",title:"Kullanıcı Adı"},{key:"password",type:"password",title:"Şifre"},{type:"submit",title:"Giriş Yap"}]}),$scope.loggingIn=!1,$scope.onSubmit=function(form){$scope.$broadcast("schemaFormValidate"),form.$valid?($scope.loggingIn=!0,$rootScope.loginAttempt=1,LoginService.login($scope.url,$scope.model).error(function(data){$scope.message=data.title}).then(function(){$scope.loggingIn=!1})):$log.debug("not valid")},$log.debug("login attempt: ",$rootScope.loginAttempt)}),auth.factory("LoginService",function($http,$rootScope,$location,$log,RESTURL){var loginService={};return loginService.login=function(url,credentials){return credentials.cmd="do",$http.post(RESTURL.url+url,credentials).success(function(data,status,headers,config){$rootScope.loggedInUser=!0}).error(function(data,status,headers,config){return data})},loginService.logout=function(){return $log.debug("logout"),$http.post(RESTURL.url+"logout",{}).success(function(data){$rootScope.loggedInUser=!1,$log.debug("loggedout"),$location.path("/login")})},loginService.isValidEmail=function(email){var re=/^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;return re.test(email)},loginService}),angular.module("ulakbus.dashboard",[]).config(function($uibTooltipProvider){$uibTooltipProvider.setTriggers({click:"mouseleave"})}).controller("DashCtrl",function($scope,$rootScope,$timeout,$http,$cookies,RESTURL,Generator){$scope.section=function(section_index){$rootScope.section=section_index},$scope.$on("authz",function(event,data){$rootScope.searchInputs=data}),$scope.keyword={student:"",staff:""},$scope.students=[],$scope.staffs=[],$scope.search=function(where){$timeout(function(){"personel"===where&&$scope.keyword.staff.length>2&&$scope.getItems(where,$scope.keyword.staff).success(function(data){$scope.staffs=data.results}),"ogrenci"===where&&$scope.keyword.student.length>2&&$scope.getItems(where,$scope.keyword.student).success(function(data){$scope.students=data.results})},500)},$scope.getItems=function(where,what){return $scope.showResults=!0,$http.get(RESTURL.url+"ara/"+where+"/"+what)},$scope.userPopover={templateUrl:"components/dashboard/user-info.html"},$scope.get_info=function(type,key){Generator.get_list({url:"crud",form_params:{model:type,object_id:key,cmd:"show"}}).then(function(data){$scope.userPopover.name=data.data.object.unicode,$scope.userPopover.tcno=data.data.object.tckn})},$scope.select=function(who,type){$rootScope.$broadcast("selectedUser",{name:who[0],tcno:who[1],key:who[2]}),$rootScope.$broadcast("menuitems",type),$scope.showResults=!1},$scope.$on("notifications",function(event,data){$scope.notifications=data}),$scope.$on("selectedUser",function($event,data){$scope.selectedUser=data}),$scope.deselectUser=function(){delete $scope.selectedUser,delete $scope.selectedMenuItems},$scope.markAsRead=function(items){$rootScope.$broadcast("markasread",items)}}).directive("sidebarNotifications",function(){return{templateUrl:"shared/templates/directives/sidebar-notification.html",restrict:"E",replace:!0,link:function($scope){}}}),angular.module("ulakbus.crud",["ui.bootstrap","schemaForm","formService"]).config(function(sfErrorMessageProvider){sfErrorMessageProvider.setDefaultMessage(302,"Bu alan zorunludur."),sfErrorMessageProvider.setDefaultMessage(200,"En az {{schema.minLength}} değer giriniz."),sfErrorMessageProvider.setDefaultMessage(201,"En fazla {{schema.minLength}} değer giriniz.")}).service("CrudUtility",function($log,$rootScope){return{generateParam:function(scope,routeParams,cmd){return scope.url=routeParams.wf,angular.forEach(routeParams,function(value,key){key.indexOf("_id")>-1&&"param_id"!==key&&(scope.param=key,scope.param_id=value)}),scope.form_params={model:routeParams.model,param:scope.param||routeParams.param,id:scope.param_id||routeParams.param_id,wf:routeParams.wf,object_id:routeParams.key,filters:{}},scope.param_id&&(scope.form_params.filters[scope.param]={values:[scope.param_id],type:"check"}),scope.model=scope.form_params.model,scope.wf=scope.form_params.wf,scope.param=scope.form_params.param,scope.param_id=scope.form_params.id,scope},listPageItems:function(scope,pageData){angular.forEach(pageData,function(value,key){scope[key]=value}),angular.forEach(scope.objects,function(value,key){if(key>0){var linkIndexes={};angular.forEach(value.actions,function(v,k){"link"===v.show_as&&(linkIndexes=v)}),angular.forEach(value.fields,function(v,k){value.actions.length>0&&linkIndexes.fields?scope.objects[key].fields[k]={type:linkIndexes.fields.indexOf(k)>-1?"link":"str",content:v,cmd:linkIndexes.cmd,mode:linkIndexes.mode}:scope.objects[key].fields[k]={type:"str",content:v}})}}),$log.debug(scope.objects)}}}).controller("CRUDCtrl",function($scope,$routeParams,Generator,CrudUtility){CrudUtility.generateParam($scope,$routeParams),Generator.get_wf($scope)}).controller("CRUDListFormCtrl",function($scope,$rootScope,$location,$http,$log,$uibModal,$timeout,Generator,$routeParams,CrudUtility){$scope.reload=function(reloadData){$scope.form_params.cmd=$scope.reload_cmd,$scope.form_params=angular.extend($scope.form_params,reloadData),$log.debug("reload data",$scope),Generator.get_wf($scope)},$scope.$on("reload_cmd",function(event,data){$scope.reload_cmd=data,$scope.reload({})}),$scope.$on("updateObjects",function($event,data){$scope.objects=data,CrudUtility.listPageItems($scope,{objects:$scope.objects})}),$scope.$on("formLocator",function(event){$scope.formgenerated=event.targetScope.formgenerated}),$scope.remove=function(item,type,index){$scope[type][item.title].model.splice(index,1),$scope[type][item.title].items.splice(index,1)},$scope.onSubmit=function(form){$scope.$broadcast("schemaFormValidate"),form.$valid&&Generator.submit($scope)},$scope.do_action=function(key,todo){Generator.doItemAction($scope,key,todo,todo.mode||"normal")},$scope.getNumber=function(num){return new Array(num)},$scope.createListObjects=function(){$scope.object.constructor===Array?$log.debug("new type show object"):$scope.object.type?$scope.object=[$scope.object]:$scope.object=[{type:"table",fields:angular.copy($scope.object)}]},$scope.showCmd=function(){CrudUtility.generateParam($scope,$routeParams,$routeParams.cmd);var pageData=Generator.getPageData();pageData.pageData===!0?($scope.object=pageData.object,Generator.setPageData({pageData:!1})):Generator.get_wf($scope).then(function(res){$scope.object=res.data.object,$scope.model=$routeParams.model}),$scope.createListObjects()},$scope.listFormCmd=function(){var setpageobjects=function(data){CrudUtility.listPageItems($scope,data),Generator.generate($scope,data),Generator.setPageData({pageData:!1})},pageData=Generator.getPageData();pageData.pageData===!0&&($log.debug("pagedata",pageData.pageData),CrudUtility.generateParam($scope,pageData,$routeParams.cmd),setpageobjects(pageData,pageData),$scope.second_client_cmd&&$scope.createListObjects()),(void 0===pageData.pageData||pageData.pageData===!1)&&(CrudUtility.generateParam($scope,$routeParams,$routeParams.cmd),Generator.get_wf($scope))},$scope.reloadCmd=function(){$scope.reload({})},$scope.resetCmd=function(){delete $scope.token,$scope.cmd="reset",Generator.get_wf($scope)};var executeCmd={show:$scope.showCmd,list:$scope.listFormCmd,form:$scope.listFormCmd,reload:$scope.reloadCmd,reset:$scope.resetCmd};return executeCmd[$routeParams.cmd]()}).directive("crudListDirective",function(){return{templateUrl:"components/crud/templates/list.html",restrict:"E",replace:!0}}).directive("crudFormDirective",function(){return{templateUrl:"components/crud/templates/form.html",restrict:"E",replace:!0}}).directive("crudShowDirective",function(){return{templateUrl:"components/crud/templates/show.html",restrict:"E",replace:!0}}).directive("formLocator",function(){return{link:function(scope){scope.$emit("formLocator")}}}).directive("crudFilters",function(Generator){return{templateUrl:"components/crud/templates/filter.html",restrict:"E",replace:!0,link:function($scope){$scope.form_params.filters=$scope.form_params.filters||{},$scope.filterList={},$scope.filterCollapsed={},$scope.$watch("list_filters",function(){angular.forEach($scope.list_filters,function(value,key){$scope.filterList[value.field]={values:value.values||[],type:value.type},$scope.filterCollapsed[value.field]=Object.keys($scope.filterCollapsed).length>0?!0:!1})}),$scope.collapseFilter=function(field){$scope.filterCollapsed[field]=!$scope.filterCollapsed[field]},$scope.status={startOpened:!1,endOpened:!1},$scope.dateFilterOpen=function($event,which){this.status[which]=!0},$scope.format="dd.MM.yyyy",$scope.filterSubmit=function(){angular.forEach($scope.filterList,function(value,key){if(value.model)if("date"===value.type){var dateValues=[null,null];angular.forEach(value.model,function(v,k){dateValues[k]=Generator.dateformatter(v)}),$scope.form_params.filters[key]={values:dateValues,type:value.type}}else $scope.form_params.filters[key]={values:Object.keys(value.model),type:value.type||"check"}}),Generator.get_wf($scope)}}}}),angular.module("ulakbus.debug",["ngRoute"]).controller("DebugCtrl",function($scope,$rootScope,$location){$scope.debug_queries=$rootScope.debug_queries}),angular.module("ulakbus.devSettings",["ngRoute"]).controller("DevSettingsCtrl",function($scope,$cookies,$rootScope,RESTURL){$scope.backendurl=$cookies.get("backendurl"),$scope.notificate=$cookies.get("notificate")||"on",$scope.changeSettings=function(what,set){document.cookie=what+"="+set,$scope[what]=set,$rootScope.$broadcast(what,set)},$scope.switchOnOff=function(pinn){return"on"==pinn?"off":"on"},$scope.setbackendurl=function(){$scope.changeSettings("backendurl",$scope.backendurl),RESTURL.url=$scope.backendurl},$scope.setnotification=function(){$scope.changeSettings("notificate",$scope.switchOnOff($scope.notificate))}}),app.config(["$routeProvider",function($routeProvider){$routeProvider.when("/error/500",{templateUrl:"components/error_pages/500.html",controller:"500Ctrl"}).when("/error/404",{templateUrl:"components/error_pages/404.html",controller:"404Ctrl"})}]),angular.module("ulakbus.error_pages",["ngRoute"]).controller("500Ctrl",function($scope,$rootScope,$location){}).controller("404Ctrl",function($scope,$rootScope,$location){}),angular.module("ulakbus.version",["ulakbus.version.interpolate-filter","ulakbus.version.version-directive"]).value("version","0.6.10"),angular.module("ulakbus.version.interpolate-filter",[]).filter("interpolate",["version",function(version){return function(text){return String(text).replace(/\%VERSION\%/gm,version)}}]),angular.module("ulakbus.version.version-directive",[]).directive("appVersion",["version",function(version){return function(scope,elm,attrs){elm.text(version)}}]);
\ No newline at end of file
/*! ulakbus-ui 2016-02-11 */
"use strict";angular.module("ulakbus",["ui.bootstrap","angular-loading-bar","ngRoute","ngSanitize","ngCookies","ulakbus.formService","ulakbus.dashboard","ulakbus.auth","ulakbus.error_pages","ulakbus.crud","ulakbus.debug","ulakbus.devSettings","ulakbus.version","gettext","templates-prod"]).constant("RESTURL",function(){var backendurl=location.href.indexOf("nightly")>-1?"//nightly.api.ulakbus.net/":"//api.ulakbus.net/";if(document.cookie.indexOf("backendurl")>-1){var cookiearray=document.cookie.split(";");angular.forEach(cookiearray,function(item){item.indexOf("backendurl")>-1&&(backendurl=item.split("=")[1])})}if(location.href.indexOf("backendurl")>-1){var urlfromqstr=location.href.split("?")[1].split("=")[1];backendurl=decodeURIComponent(urlfromqstr.replace(/\+/g," ")),document.cookie="backendurl="+backendurl,window.location.href=window.location.href.split("?")[0]}return{url:backendurl}}()).config(function($logProvider){$logProvider.debugEnabled(!1)}),angular.module("ulakbus").config(["$routeProvider",function($routeProvider,$route){$routeProvider.when("/login",{templateUrl:"components/auth/login.html",controller:"LoginCtrl"}).when("/dashboard",{templateUrl:"components/dashboard/dashboard.html",controller:"DashCtrl"}).when("/dev/settings",{templateUrl:"components/devSettings/devSettings.html",controller:"DevSettingsCtrl"}).when("/debug/list",{templateUrl:"components/debug/debug.html",controller:"DebugCtrl"}).when("/:wf/",{templateUrl:"components/crud/templates/crud.html",controller:"CRUDCtrl"}).when("/:wf/do/:cmd",{templateUrl:"components/crud/templates/crud.html",controller:"CRUDListFormCtrl"}).when("/:wf/do/:cmd/:key",{templateUrl:"components/crud/templates/crud.html",controller:"CRUDListFormCtrl"}).when("/:wf/:model",{templateUrl:"components/crud/templates/crud.html",controller:"CRUDCtrl"}).when("/:wf/:model/do/:cmd",{templateUrl:"components/crud/templates/crud.html",controller:"CRUDListFormCtrl"}).when("/:wf/:model/do/:cmd/:key",{templateUrl:"components/crud/templates/crud.html",controller:"CRUDListFormCtrl"}).otherwise({redirectTo:"/dashboard"})}]).run(function($rootScope){$rootScope.loggedInUser=!0,$rootScope.loginAttempt=0,$rootScope.$on("$routeChangeStart",function(event,next,current){})}).config(["$httpProvider",function($httpProvider){$httpProvider.defaults.withCredentials=!0}]).run(function(gettextCatalog){gettextCatalog.setCurrentLanguage("tr"),gettextCatalog.debug=!0}).config(["cfpLoadingBarProvider",function(cfpLoadingBarProvider){cfpLoadingBarProvider.includeBar=!1,cfpLoadingBarProvider.parentSelector="loaderdiv",cfpLoadingBarProvider.spinnerTemplate='<div class="loader">Loading...</div>'}]),angular.module("ulakbus").config(["$httpProvider",function($httpProvider){$httpProvider.interceptors.push(function($q,$rootScope,$location,$timeout,$log){return{request:function(config){return"POST"===config.method&&(config.headers["Content-Type"]="text/plain"),config},response:function(response){return response.data._debug_queries&&response.data._debug_queries.length>0&&($rootScope.debug_queries=$rootScope.debug_queries||[],$rootScope.debug_queries.push({url:response.config.url,queries:response.data._debug_queries})),response.data.is_login===!1&&($rootScope.loggedInUser=response.data.is_login,$location.path("/login")),response.data.is_login===!0&&($rootScope.loggedInUser=!0,$rootScope.loginAttempt=1,"/login"===$location.path()&&$location.path("/dashboard")),response},responseError:function(rejection){var errorModal=function(){if(0===$rootScope.loginAttempt)return void $log.debug("not logged in, no alert message triggered");var codefield="";rejection.data.error&&(codefield="<p><pre>"+rejection.data.error+"</pre></p>"),$('<div class="modal"><div class="modal-dialog" style="width:100%;" role="document"><div class="modal-content"><div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button><h4 class="modal-title" id="exampleModalLabel">'+rejection.status+rejection.data.title+'</h4></div><div class="modal-body"><div class="alert alert-danger"><strong>'+rejection.data.description+"</strong>"+codefield+'</div></div><div class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">Kapat</button></div></div></div></div>').modal();try{$("pre:not(.hljs)").each(function(i,block){hljs.highlightBlock(block)})}catch(e){$log.debug("Exception: ",e.message)}};return-1===rejection.status&&(rejection.status="Sunucu hatası",rejection.data={title:"",description:"Sunucu bağlantısında bir hata oluştu.Lütfen yetkili personelle iletişime geçiniz."},$rootScope.$broadcast("alertBox",{title:rejection.status,msg:rejection.data.description,type:"error"})),400===rejection.status&&$location.reload(),401===rejection.status&&($location.path("/login"),"/login"===$location.path()&&$log.debug("show errors on login form")),403===rejection.status&&rejection.data.is_login===!0&&($rootScope.loggedInUser=!0,"/login"===$location.path()&&$location.path("/dashboard")),$rootScope.$broadcast("show_notifications",rejection.data),404===rejection.status&&errorModal(),500===rejection.status&&errorModal(),$q.reject(rejection)}}})}]),angular.module("ulakbus.formService",["ui.bootstrap"]).service("Moment",function(){return window.moment}).factory("Generator",function($http,$q,$timeout,$sce,$location,$route,$compile,$log,RESTURL,$rootScope,Moment){var generator={};return generator.makeUrl=function(scope){var getparams=scope.form_params.param?"?"+scope.form_params.param+"="+scope.form_params.id:"";return RESTURL.url+scope.url+getparams},generator.generate=function(scope,data){return data.forms?(angular.forEach(data.forms,function(value,key){scope[key]=data.forms[key]}),scope.client_cmd=data.client_cmd,scope.token=data.token,scope.initialModel=angular.copy(scope.model),generator.prepareFormItems(scope),scope.object_id=scope.form_params.object_id,$log.debug("scope at after generate",scope),scope):scope},generator.group=function(scope){if(!scope.grouping)return scope;var newForm=[],extractFormItem=function(itemList){var extractedList=[];return angular.forEach(itemList,function(value,key){var item=getFormItem(value);item&&extractedList.push(item)}),$log.debug("extractedList: ",extractedList),extractedList},getFormItem=function(item){var formItem;return scope.form.indexOf(item)>-1?(formItem=scope.form[scope.form.indexOf(item)],scope.form.splice(scope.form.indexOf(item),1),formItem):(angular.forEach(scope.form,function(value,key){return value.key===item?(formItem=value,void scope.form.splice(key,1)):void 0}),formItem)},makeGroup=function(itemsToGroup){var subItems=[];return angular.forEach(itemsToGroup,function(value,key){subItems.push({type:"fieldset",items:extractFormItem(value.items),title:value.group_title})}),subItems};return angular.forEach(scope.grouping,function(value,key){newForm.push({type:"fieldset",items:makeGroup(value.groups),htmlClass:"col-md-"+value.layout,title:value.group_title})}),$log.debug("grouped form: ",newForm),$log.debug("rest of form: ",scope.form),$log.debug("form united: ",newForm.concat(scope.form)),scope.form=newForm.concat(scope.form),scope},generator.prepareFormItems=function(scope){return angular.forEach(scope.form,function(value,key){"select"===value.type&&(scope.schema.properties[value.key].type="select",scope.schema.properties[value.key].titleMap=value.titleMap,scope.form[key]=value.key)}),angular.forEach(scope.schema.properties,function(v,k){if("form_params"in scope&&k==scope.form_params.param)return scope.model[k]=scope.form_params.id,void scope.form.splice(scope.form.indexOf(k),1);if("file"===v.type&&(scope.form[scope.form.indexOf(k)]={type:"template",title:v.title,templateUrl:"shared/templates/filefield.html",name:k,key:k,fileInsert:function(){$scope.$broadcast("schemaForm.error."+k,"tv4-302",!0)},imageSrc:scope.model[k]?$rootScope.settings.static_url+scope.model[k]:"",avatar:"avatar"===k},v.type="string"),"select"===v.type&&(scope.form[scope.form.indexOf(k)]={type:"template",title:v.title,templateUrl:"shared/templates/select.html",name:k,key:k,titleMap:v.titleMap}),"submit"===v.type||"button"===v.type){var buttonPositions=scope.modalElements?scope.modalElements.buttonPositions:{bottom:"move-to-bottom",top:"move-to-top",none:""},workOnForm=scope.modalElements?scope.modalElements.workOnForm:"formgenerated",workOnDiv=scope.modalElements?scope.modalElements.workOnDiv:"",buttonClass=buttonPositions[v.position]||buttonPositions.bottom,redirectTo=scope.modalElements?!1:!0;scope.form[scope.form.indexOf(k)]={type:v.type,title:v.title,style:"btn-danger hide "+buttonClass,onClick:function(){delete scope.form_params.cmd,delete scope.form_params.flow,v.cmd&&(scope.form_params.cmd=v.cmd),v.flow&&(scope.form_params.flow=v.flow),v.wf&&(delete scope.form_params.cmd,scope.form_params.wf=v.wf),scope.model[k]=1,scope.modalElements?scope.submitModalForm():v.validation===!1?generator.submit(scope,redirectTo):(scope.$broadcast("schemaFormValidate"),scope[workOnForm].$valid?(generator.submit(scope,redirectTo),scope.$broadcast("disposeModal")):$timeout(function(){var firsterror=angular.element(document.querySelectorAll("input.ng-invalid"))[0];firsterror.focus()}))}},$timeout(function(){var selectorBottom=".buttons-on-bottom"+workOnDiv,buttonsToBottom=angular.element(document.querySelector("."+buttonClass));angular.element(document.querySelector(selectorBottom)).append(buttonsToBottom),buttonsToBottom.removeClass("hide")},500)}if("date"===v.type&&($log.debug("date:",scope.model[k]),scope.model[k]=generator.dateformatter(scope.model[k]),scope.form[scope.form.indexOf(k)]={key:k,name:k,title:v.title,type:"template",templateUrl:"shared/templates/datefield.html",validationMessage:{dateNotValid:"Girdiğiniz tarih geçerli değildir. <i>orn: '01.01.2015'<i/>",302:"Bu alan zorunludur."},$asyncValidators:{dateNotValid:function(value){var deferred=$q.defer();return $timeout(function(){if(scope.model[k]=angular.copy(generator.dateformatter(value)),scope.schema.required.indexOf(k)>-1&&deferred.resolve(),value.constructor===Date)deferred.resolve();else{var dateValue=d=value.split(".");isNaN(Date.parse(value))||3!==dateValue.length?deferred.reject():deferred.resolve()}}),deferred.promise}},status:{opened:!1},open:function($event){this.status.opened=!0},format:"dd.MM.yyyy",onSelect:function(){scope.model[k]=angular.copy(generator.dateformatter(scope.model[k]))}}),("int"===v.type||"float"===v.type)&&(v.type="number",scope.model[k]=parseInt(scope.model[k])),"text_general"===v.type&&(v.type="string",v["x-schema-form"]={type:"textarea"}),"model"===v.type){var formitem=scope.form[scope.form.indexOf(k)],modelScope={url:v.wf,wf:v.wf,form_params:{model:v.model_name,cmd:v.list_cmd}};scope.generateTitleMap=function(modelScope){return generator.get_list(modelScope).then(function(res){return formitem.titleMap=[],angular.forEach(res.data.objects,function(item){-1!==item?formitem.titleMap.push({value:item.key,name:item.value}):formitem.focusToInput=!0}),formitem.titleMap})},scope.model[k]&&generator.get_list({url:"crud",form_params:{model:v.model_name,object_id:scope.model[k],cmd:"object_name"}}).then(function(data){try{scope.$watch(document.querySelector("input[name="+v.model_name+"]"),function(){document.querySelector("input[name="+k+"]").value=data.data.object_name})}catch(e){document.querySelector("input[name="+k+"]").value=data.data.object_name,$log.debug("exception",e)}}),formitem={type:"template",templateUrl:"shared/templates/foreignKey.html",formName:k,title:v.title,wf:v.wf,add_cmd:v.add_cmd,name:k,key:k,model_name:v.model_name,selected_item:{},titleMap:[],onSelect:function(item,inputname){scope.model[k]=item.value,$timeout(function(){document.querySelector("input[name="+inputname+"]").value=item.name})},onDropdownSelect:function(item,inputname){scope.model[k]=item.value,$timeout(function(){document.querySelector("input[name="+inputname+"]").value=item.name})},getTitleMap:function(viewValue){return modelScope.form_params.query=viewValue,scope.generateTitleMap(modelScope)},getDropdownTitleMap:function(){delete modelScope.form_params.query,formitem.gettingTitleMap=!0,scope.generateTitleMap(modelScope).then(function(data){formitem.titleMap=data,formitem.gettingTitleMap=!1})}},scope.form[scope.form.indexOf(k)]=formitem}if(("ListNode"===v.type||"Node"===v.type)&&"filter_interface"===v.widget){var formitem=scope.form[scope.form.indexOf(k)],modelScope={url:v.wf||scope.wf,wf:v.wf||scope.wf,form_params:{model:v.model_name||v.schema[0].model_name,cmd:v.list_cmd||"select_list",query:""}};scope.generateTitleMap=function(modelScope){generator.get_list(modelScope).then(function(res){formitem.titleMap=[],angular.forEach(res.data.objects,function(item){"-1"!==item&&formitem.titleMap.push({value:item.key,name:item.value})}),formitem.filteredItems=generator.get_diff_array(angular.copy(formitem.titleMap),angular.copy(formitem.selectedFilteredItems),1)})};var modelItems=[],modelKeys=[];angular.forEach(scope.model[k],function(value,mkey){modelItems.push({value:value[v.schema[0].name].key,name:value[v.schema[0].name].unicode});var modelKey={};modelKey[v.schema[0].name]=value[v.schema[0].name].key,modelKeys.push(modelKey)}),scope.model[k]=angular.copy(modelKeys),formitem={type:"template",templateUrl:"shared/templates/multiselect.html",title:v.title,formName:k,wf:v.wf,add_cmd:v.add_cmd,name:v.model_name,model_name:v.model_name,filterValue:"",selected_item:{},filteredItems:[],selectedFilteredItems:modelItems,titleMap:scope.generateTitleMap(modelScope),appendFiltered:function(filterValue){filterValue.length>2&&(formitem.filteredItems=[],angular.forEach(formitem.titleMap,function(value,key){value.name.indexOf(filterValue)>-1&&formitem.filteredItems.push(formitem.titleMap[key])})),2>=filterValue&&(formitem.filteredItems=formitem.titleMap),formitem.filteredItems=generator.get_diff_array(formitem.filteredItems,formitem.selectedFilteredItems)},select:function(selectedItemsModel){selectedItemsModel&&(formitem.selectedFilteredItems=formitem.selectedFilteredItems.concat(selectedItemsModel),formitem.appendFiltered(formitem.filterValue),scope.model[k]=(scope.model[k]||[]).concat(formitem.dataToModel(selectedItemsModel)))},deselect:function(selectedFilteredItemsModel){selectedFilteredItemsModel&&(formitem.selectedFilteredItems=generator.get_diff_array(angular.copy(formitem.selectedFilteredItems),angular.copy(selectedFilteredItemsModel)),formitem.appendFiltered(formitem.filterValue),formitem.filteredItems=formitem.filteredItems.concat(selectedFilteredItemsModel),scope.model[k]=generator.get_diff_array(scope.model[k]||[],formitem.dataToModel(selectedFilteredItemsModel)))},dataToModel:function(data){var dataValues=[];return angular.forEach(data,function(value,key){var dataKey={};dataKey[v.schema[0].name]=value.value,dataValues.push(dataKey)}),dataValues}},scope.form[scope.form.indexOf(k)]=formitem}"ListNode"!==v.type&&"Node"!==v.type||"filter_interface"===v.widget||(scope[v.type]=scope[v.type]||{},scope[v.type][k]=angular.copy({title:v.title,form:[],schema:{properties:{},required:[],title:v.title,type:"object",formType:v.type,model_name:k,inline_edit:scope.inline_edit},url:scope.url,wf:scope.wf,nodeModelChange:function(item){}}),angular.forEach(v.schema,function(item){scope[v.type][k].schema.properties[item.name]=angular.copy(item),item.required===!0&&"idx"!==item.name&&scope[v.type][k].schema.required.push(angular.copy(item.name)),"idx"!==item.name&&scope[v.type][k].form.push(item.name);try{"date"===item.type&&(scope.model[k][item.name]=generator.dateformatter(scope.model[k][item.name]))}catch(e){$log.debug("Error: ",e.message)}}),$timeout(function(){"ListNode"===v.type&&(scope[v.type][k].items=angular.copy(scope.model[k]||[]),angular.forEach(scope[v.type][k].items,function(value,key){value.constructor===Object&&angular.forEach(value,function(x,y){try{"date"===scope[v.type][k].schema.properties[y].type&&(scope[v.type][k].items[key][y]=generator.dateformatter(x),scope[v.type][k].model[key][y]=generator.dateformatter(x)),"select"===scope[v.type][k].schema.properties[y].type&&(scope[v.type][k].items[key][y]=generator.item_from_array(x.toString(),scope[v.type][k].schema.properties[y].titleMap))}catch(e){$log.debug("Field is not date")}})}))}),scope.model[k]&&angular.forEach(scope.model[k],function(value,key){angular.forEach(value,function(y,x){y.constructor===Object&&(scope.model[k][key][x]=y.key)})}),scope.model[k]=scope.model[k]||[],scope[v.type][k].model=scope.model[k],scope[v.type][k].lengthModels=scope.model[k]?1:0)}),$log.debug("scope at after prepareformitems",scope),generator.group(scope)},generator.dateformatter=function(formObject){var ndate=new Date(formObject);if(isNaN(ndate))return"";var newdatearray=Moment(ndate).format("DD.MM.YYYY");return $log.debug("date formatted: ",newdatearray),newdatearray},generator.doItemAction=function($scope,key,todo,mode){var _do={normal:function(){return $log.debug("normal mode starts"),$scope.form_params.cmd=todo.cmd,todo.wf&&($scope.url=todo.wf,$scope.form_params.wf=todo.wf,delete $scope.token,delete $scope.form_params.model,delete $scope.form_params.cmd),todo.object_key?$scope.form_params[todo.object_key]=key:$scope.form_params.object_id=key,$scope.form_params.param=$scope.param,$scope.form_params.id=$scope.param_id,$scope.form_params.token=$scope.token,generator.get_wf($scope)},modal:function(){$log.debug("modal mode is not not ready")},"new":function(){$log.debug("new mode is not not ready")}};return _do[mode]()},generator.button_switch=function(position){var buttons=angular.element(document.querySelectorAll("button")),positions={"true":"enabled","false":"disabled"};angular.forEach(buttons,function(button,key){button[positions[position]]=!0}),$log.debug("buttons >> ",positions[position])},generator.get_form=function(scope){return generator.button_switch(!1),$http.post(generator.makeUrl(scope),scope.form_params).then(function(res){return generator.button_switch(!0),generator.generate(scope,res.data)})},generator.get_list=function(scope){return generator.button_switch(!1),$http.post(generator.makeUrl(scope),scope.form_params).then(function(res){return generator.button_switch(!0),res})},generator.get_wf=function(scope){return generator.button_switch(!1),$http.post(generator.makeUrl(scope),scope.form_params).then(function(res){if(generator.button_switch(!0),res.data.client_cmd)return generator.pathDecider(res.data.client_cmd,scope,res.data);if(res.data.msgbox){scope.msgbox=res.data.msgbox;var newElement=$compile("<msgbox></msgbox>")(scope);angular.element(document.querySelector(".main.ng-scope")).children().remove(),angular.element(document.querySelector(".main.ng-scope")).append(newElement)}})},generator.isValidEmail=function(email){var re=/^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;return re.test(email)},generator.isValidTCNo=function(tcno){var re=/^([1-9]{1}[0-9]{9}[0,2,4,6,8]{1})$/i;return re.test(tcno)},generator.isValidDate=function(dateValue){return!isNaN(Date.parse(dateValue))},generator.pageData={},generator.getPageData=function(){return generator.pageData},generator.setPageData=function(value){generator.pageData=value},generator.pathDecider=function(client_cmd,$scope,data){function redirectTo(scope,page){var pathUrl="/"+scope.form_params.wf;return pathUrl+=scope.form_params.model?"/"+scope.form_params.model+"/do/"+page:"/do/"+page,$location.path()===pathUrl?$route.reload():void $location.path(pathUrl)}function dispatchClientCmd(){data[$scope.form_params.param]=$scope.form_params.id,data.model=$scope.form_params.model,data.wf=$scope.form_params.wf,data.param=$scope.form_params.param,data.param_id=$scope.form_params.id,data.pageData=!0,data.second_client_cmd=client_cmd[1],generator.setPageData(data),redirectTo($scope,client_cmd[0])}return"reload"===client_cmd[0]||"reset"===client_cmd[0]?void $rootScope.$broadcast("reload_cmd",$scope.reload_cmd):void dispatchClientCmd()},generator.get_diff=function(oldObj,newObj){var result={};return angular.forEach(newObj,function(value,key){oldObj[key]?oldObj[key].constructor!==newObj[key].constructor||newObj[key].constructor!==Object&&newObj[key].constructor!==Array?oldObj[key]!=newObj[key]&&(result[key]=angular.copy(newObj[key])):angular.forEach(value,function(v,k){oldObj[key][k]!=value[k]&&(result[key][k]=angular.copy(value[k]))}):result[key]=angular.copy(newObj[key])}),result},generator.get_diff_array=function(array1,array2,way){var result=[];return angular.forEach(array1,function(value,key){1===way?angular.toJson(array2).indexOf(value.value)<0&&result.push(value):angular.toJson(array2).indexOf(angular.toJson(value))<0&&result.push(value)}),result},generator.item_from_array=function(item,array){var result=item;return angular.forEach(array,function(value,key){value.value===item&&(result=value.name)}),result},generator.submit=function($scope,redirectTo){angular.forEach($scope.ListNode,function(value,key){$scope.model[key]=value.model}),angular.forEach($scope.Node,function(value,key){$scope.model[key]=value.model});var data={form:$scope.model,token:$scope.token,model:$scope.form_params.model,cmd:$scope.form_params.cmd,flow:$scope.form_params.flow,object_id:$scope.object_id,filter:$scope.filter,query:$scope.form_params.query};return $http.post(generator.makeUrl($scope),data).success(function(data,status,headers){if("application/pdf"===headers("content-type")){var a=document.createElement("a");document.body.appendChild(a),a.style="display: none";var file=new Blob([data],{type:"application/pdf"}),fileURL=URL.createObjectURL(file),fileName=$scope.schema.title;a.href=fileURL,a.download=fileName,a.click()}if(redirectTo===!0&&(data.client_cmd&&generator.pathDecider(data.client_cmd,$scope,data),data.msgbox)){$scope.msgbox=data.msgbox;var newElement=$compile("<msgbox></msgbox>")($scope);angular.element(document.querySelector(".main.ng-scope")).children().remove(),angular.element(document.querySelector(".main.ng-scope")).append(newElement)}})},generator}).controller("ModalCtrl",function($scope,$uibModalInstance,Generator,items){angular.forEach(items,function(value,key){$scope[key]=items[key]}),$scope.$on("disposeModal",function(){$scope.cancel()}),$scope.$on("modalFormLocator",function(event){$scope.linkedModelForm=event.targetScope.linkedModelForm}),$scope.$on("submitModalForm",function(){$scope.onSubmit($scope.linkedModelForm)}),$scope.$on("validateModalDate",function(event,field){$scope.$broadcast("schemaForm.error."+field,"tv4-302",!0)}),$scope.onSubmit=function(form){$scope.$broadcast("schemaFormValidate"),form.$valid&&$uibModalInstance.close($scope)},$scope.onNodeSubmit=function(){$scope.$broadcast("schemaFormValidate"),$scope.modalForm.$valid&&$uibModalInstance.close($scope)},$scope.cancel=function(){$uibModalInstance.dismiss("cancel")}}).directive("modalForNodes",function($uibModal,Generator){return{link:function(scope,element,attributes){element.on("click",function(){var modalInstance=$uibModal.open({animation:!0,backdrop:"static",keyboard:!1,templateUrl:"shared/templates/listnodeModalContent.html",controller:"ModalCtrl",size:"lg",resolve:{items:function(){var attribs=attributes.modalForNodes.split(","),node=angular.copy(scope.$parent[attribs[1]][attribs[0]]);"add"===attribs[2]&&(node.model={}),attribs[3]&&(node.model=node.model[attribs[3]]),node.edit=attribs[3],scope.node.schema.wf=scope.node.url,angular.forEach(scope.node.schema.properties,function(value,key){scope.node.schema.properties[key].wf=scope.node.url,scope.node.schema.properties[key].list_cmd="select_list"});var newscope={wf:scope.node.wf,url:scope.node.url,form_params:{model:scope.node.schema.model_name},edit:attribs[3]};return Generator.generate(newscope,{forms:scope.node}),newscope.model=newscope.model[node.edit]||newscope.model[0]||{},newscope}}});modalInstance.result.then(function(childmodel,key){var listNodeItem=scope.$parent[childmodel.schema.formType][childmodel.schema.model_name];if("Node"===childmodel.schema.formType&&(listNodeItem.model=angular.copy(childmodel.model),listNodeItem.lengthModels+=1),"ListNode"===childmodel.schema.formType){var reformattedModel={};angular.forEach(childmodel.model,function(value,key){key.indexOf("_id")>-1?angular.forEach(childmodel.form,function(v,k){function indexInTitleMap(element,index,array){return element.value===value?element:void 0}v.formName===key&&(reformattedModel[key]={key:value,unicode:v.titleMap.find(indexInTitleMap).name})}):reformattedModel[key]={key:key,unicode:Generator.item_from_array(value,childmodel.schema.properties[key].titleMap)}}),childmodel.edit?(listNodeItem.model[childmodel.edit]=childmodel.model,Object.keys(reformattedModel).length>0?listNodeItem.items[childmodel.edit]=reformattedModel:listNodeItem.items[childmodel.edit]=angular.copy(childmodel.model)):(listNodeItem.model.push(angular.copy(childmodel.model)),Object.keys(reformattedModel).length>0?listNodeItem.items.push(reformattedModel):listNodeItem.items.push(angular.copy(childmodel.model))),listNodeItem.lengthModels+=1}})})}}}).directive("addModalForLinkedModel",function($uibModal,$rootScope,$route,Generator){return{link:function(scope,element,attributes){element.on("click",function(){var modalInstance=$uibModal.open({animation:!0,backdrop:"static",keyboard:!1,templateUrl:"shared/templates/linkedModelModalContent.html",controller:"ModalCtrl",size:"lg",resolve:{items:function(){var formName=attributes.addModalForLinkedModel;return Generator.get_form({url:scope.form.wf,wf:scope.form.wf,form_params:{model:scope.form.model_name,cmd:scope.form.add_cmd},modalElements:{buttonPositions:{bottom:"move-to-bottom-modal",top:"move-to-top-modal",none:""},workOnForm:"linkedModelForm",workOnDiv:"-modal"+formName},submitModalForm:function(){$rootScope.$broadcast("submitModalForm")},validateModalDate:function(field){$rootScope.$broadcast("validateModalDate",field)},formName:formName})}}});modalInstance.result.then(function(childscope,key){var formName=childscope.formName;Generator.submit(childscope,!1).success(function(data){scope.model[formName]=data.forms.model.object_key,scope.form.titleMap.push({value:data.forms.model.object_key,name:data.forms.model.unicode}),scope.form.selected_item={value:data.forms.model.object_key,name:data.forms.model.unicode},scope.$watch(document.querySelector("input[name="+scope.form.model_name+"]"),function(){angular.element(document.querySelector("input[name="+scope.form.model_name+"]")).val(scope.form.selected_item.name)})})})})}}}).directive("modalFormLocator",function(){return{link:function(scope){scope.$emit("modalFormLocator")}}}),angular.module("ulakbus").directive("logout",function($http,$location,RESTURL){return{link:function($scope,$element,$rootScope){$element.on("click",function(){$http.post(RESTURL.url+"logout",{}).then(function(){$rootScope.loggedInUser=!1,$location.path("/login")})})}}}).directive("headerNotification",function($http,$rootScope,$cookies,$interval,RESTURL){return{templateUrl:"shared/templates/directives/header-notification.html",restrict:"E",replace:!0,link:function($scope){$scope.groupNotifications=function(notifications){$scope.notifications={1:[],2:[],3:[],4:[]},angular.forEach(notifications,function(value,key){$scope.notifications[value.type].push(value)})},$scope.getNotifications=function(){$http.get(RESTURL.url+"notify",{ignoreLoadingBar:!0}).success(function(data){$scope.groupNotifications(data.notifications),$rootScope.$broadcast("notifications",$scope.notifications)})},$scope.getNotifications(),$interval(function(){"on"==$cookies.get("notificate")&&$scope.getNotifications()},5e3),$scope.markAsRead=function(items){$http.post(RESTURL.url+"notify",{ignoreLoadingBar:!0,read:[items]}).success(function(data){$scope.groupNotifications(data.notifications),$rootScope.$broadcast("notifications",$scope.notifications)})},$scope.$on("markasread",function(event,data){$scope.markAsRead(data)})}}}).directive("searchDirective",function(Generator,$log,$rootScope){return{templateUrl:"shared/templates/directives/search.html",restrict:"E",replace:!0,link:function($scope){$scope.searchForm=[{key:"searchbox",htmlClass:"pull-left"},{type:"submit",title:"Ara",style:"btn-info",htmlClass:"pull-left"}],$scope.searchSchema={type:"object",properties:{searchbox:{type:"string",minLength:2,title:"Ara","x-schema-form":{placeholder:"Arama kriteri giriniz..."}}},required:[]},$scope.searchModel={searchbox:""},$scope.searchSubmit=function(form){if($scope.$broadcast("schemaFormValidate"),form.$valid){var searchparams={url:$scope.wf,token:$scope.$parent.token,object_id:$scope.$parent.object_id,form_params:{model:$scope.$parent.form_params.model,cmd:$scope.$parent.reload_cmd,flow:$scope.$parent.form_params.flow,query:$scope.searchModel.searchbox}};Generator.submit(searchparams).success(function(data){$rootScope.$broadcast("updateObjects",data.objects)})}}}}}).directive("sortDirective",function(Generator,$log){return{templateUrl:"shared/templates/directives/sort.html",restrict:"E",replace:!0,link:function($scope){$scope.titleMap=[{value:"artan",name:"Artan"},{value:"azalan",name:"Azalan"}],$scope.sortForm=[{key:"sortbox",htmlClass:"pull-left",type:"select",titleMap:$scope.titleMap},{type:"submit",title:"Sırala",htmlClass:"pull-left"}],$scope.sortSchema={type:"object",properties:{sortbox:{type:"select",title:"Sırala"}},required:["sortbox"]},$scope.sortModel={sortbox:""},$scope.sortSubmit=function(form){if($scope.$broadcast("schemaFormValidate"),form.$valid){var sortparams={url:$scope.wf,token:$scope.$parent.token,object_id:$scope.$parent.object_id,form_params:{model:$scope.$parent.form_params.model,cmd:$scope.$parent.reload_cmd,flow:$scope.$parent.form_params.flow,param:"sort",id:$scope.sortModel.sortbox}};Generator.submit(sortparams)}}}}}).directive("collapseMenu",function($timeout,$window,$cookies){return{templateUrl:"shared/templates/directives/menuCollapse.html",restrict:"E",replace:!0,scope:{},controller:function($scope,$rootScope){$rootScope.collapsed=!1,$rootScope.sidebarPinned=$cookies.get("sidebarPinned")||0,$scope.collapseToggle=function(){$window.innerWidth>"768"&&($rootScope.collapsed===!1?(jQuery(".sidebar").css("width","62px"),jQuery(".manager-view").css("width","calc(100% - 62px)"),$rootScope.collapsed=!0,$rootScope.sidebarPinned=0,$cookies.put("sidebarPinned",0)):(jQuery("span.menu-text, span.arrow, .sidebar footer").fadeIn(400),jQuery(".sidebar").css("width","250px"),jQuery(".manager-view").css("width","calc(100% - 250px)"),$rootScope.collapsed=!1,$rootScope.sidebarPinned=1,$cookies.put("sidebarPinned",1)))},$timeout(function(){"0"===$cookies.get("sidebarPinned")&&$scope.collapseToggle()})}}}).directive("headerSubMenu",function($location){return{templateUrl:"shared/templates/directives/header-sub-menu.html",restrict:"E",replace:!0,link:function($scope){$scope.style="width:calc(100% - 300px);",$scope.$on("$routeChangeStart",function(){$scope.style="/dashboard"===$location.path()?"width:calc(100% - 300px);":"width:%100 !important;"})}}}).directive("headerBreadcrumb",function($location){return{templateUrl:"shared/templates/directives/header-breadcrumb.html",restrict:"E",replace:!1,link:function($scope){$scope.goBack=function(){$location.state()}}}}).directive("selectedUser",function($http,RESTURL){return{templateUrl:"shared/templates/directives/selected-user.html",restrict:"E",replace:!0,link:function($scope,$rootScope){$scope.$on("selectedUser",function($event,data){$scope.selectedUser=data,$scope.dynamicPopover={content:"",name:data.name,tcno:data.tcno,key:data.key,templateUrl:"shared/templates/directives/selectedUserPopover.html",title:"İşlem Yapılan Kişi"}}),$scope.$on("selectedUserTrigger",function($event,data){({model:"Personel",cmd:"show",id:data[1]});$http.get(RESTURL.url+"ara/personel/"+data[1]).success(function(data){})})}}}).directive("sidebar",["$location",function(){return{templateUrl:"shared/templates/directives/sidebar.html",restrict:"E",replace:!0,scope:{},controller:function($scope,$rootScope,$cookies,$route,$http,RESTURL,$log,$location,$window,$timeout){
$scope.prepareMenu=function(menuItems){var newMenuItems={};return angular.forEach(menuItems,function(value,key){angular.forEach(value,function(v,k){newMenuItems[k]=v})}),newMenuItems};var sidebarmenu=$("#side-menu");sidebarmenu.metisMenu(),$http.get(RESTURL.url+"menu/").success(function(data){function reGroupMenuItems(items,baseCategory){var newItems={};return angular.forEach(items,function(value,key){newItems[value.kategori]=newItems[value.kategori]||[],value.baseCategory=baseCategory,newItems[value.kategori].push(value)}),newItems}$scope.allMenuItems=angular.copy(data),angular.forEach($scope.allMenuItems,function(value,key){"current_user"!==key&&"settings"!==key&&($scope.allMenuItems[key]=reGroupMenuItems(value,key))}),$rootScope.quick_menu=reGroupMenuItems(data.quick_menu,"quick_menus"),$rootScope.quick_menu=data.quick_menu,delete data.quick_menu,$log.debug("quick menu",$rootScope.quick_menu),$rootScope.$broadcast("authz",data),$rootScope.searchInputs=data,$rootScope.current_user=data.current_user,(data.ogrenci||data.personel)&&($rootScope.current_user.can_search=!0),$rootScope.settings=data.settings,$scope.menuItems=$scope.prepareMenu({other:$scope.allMenuItems.other}),$timeout(function(){sidebarmenu.metisMenu()})}),$scope.$on("menuitems",function(event,data){var menu={};menu[data]=$scope.allMenuItems[data],$rootScope.$broadcast("usermenuitems",$scope.prepareMenu(menu))}),$scope.$on("selectedUser",function($event,data){$scope.selectedUser=data}),$scope.deselectUser=function(){delete $scope.selectedUser,delete $scope.selectedMenuItems},$scope.openSidebar=function(){$window.innerWidth>"768"&&0===$rootScope.sidebarPinned&&(jQuery("span.menu-text, span.arrow, .sidebar footer, #side-menu").fadeIn(400),jQuery(".sidebar").css("width","250px"),jQuery(".manager-view").css("width","calc(100% - 250px)"),$rootScope.collapsed=!1)},$scope.closeSidebar=function(){$window.innerWidth>"768"&&0===$rootScope.sidebarPinned&&(jQuery(".sidebar").css("width","62px"),jQuery(".manager-view").css("width","calc(100% - 62px)"),$rootScope.collapsed=!0)},$rootScope.$watch(function($rootScope){return $rootScope.section},function(newindex,oldindex){newindex>-1&&($scope.menuItems=[$scope.allMenuItems[newindex]],$scope.collapseVar=0)}),$scope.selectedMenu=$location.path(),$scope.collapseVar=0,$scope.multiCollapseVar=0,$scope.check=function(x){x===$scope.collapseVar?$scope.collapseVar=0:$scope.collapseVar=x},$scope.breadcrumb=function(itemlist,$event){$rootScope.breadcrumblinks=itemlist},$scope.multiCheck=function(y){y===$scope.multiCollapseVar?$scope.multiCollapseVar=0:$scope.multiCollapseVar=y}}}}]).directive("rightSidebar",["$location",function(){return{templateUrl:"shared/templates/directives/right-sidebar.html",restrict:"E",replace:!0,scope:{},controller:function($scope,$rootScope,$cookies,$route,$http,RESTURL,$log,$location,$window,$timeout){var sidebarUserMenu=$("#side-user-menu");sidebarUserMenu.metisMenu(),$scope.$on("usermenuitems",function(event,data){$scope.selectedMenuItems=data,$timeout(function(){sidebarUserMenu.metisMenu()}),jQuery(".right-sidebar").css("width","300px"),jQuery(".manager-view-inner").css("width","calc(100% - 300px)")}),$scope.$on("selectedUser",function($event,data){$scope.selectedUser=data}),$scope.deselectUser=function(){jQuery(".right-sidebar").css("width","0px"),jQuery(".manager-view-inner").css("width",""),delete $scope.selectedUser,delete $scope.selectedMenuItems},$rootScope.$watch(function($rootScope){return $rootScope.section},function(newindex,oldindex){newindex>-1&&($scope.menuItems=[$scope.allMenuItems[newindex]],$scope.collapseVar=0)}),$scope.selectedMenu=$location.path(),$scope.collapseVar=0,$scope.multiCollapseVar=0,$scope.check=function(x){x===$scope.collapseVar?$scope.collapseVar=0:$scope.collapseVar=x},$scope.multiCheck=function(y){y===$scope.multiCollapseVar?$scope.multiCollapseVar=0:$scope.multiCollapseVar=y}}}}]).directive("stats",function(){return{templateUrl:"shared/templates/directives/stats.html",restrict:"E",replace:!0,scope:{model:"=",comments:"@",number:"@",name:"@",colour:"@",details:"@",type:"@","goto":"@"}}}).directive("notifications",function(){return{templateUrl:"shared/templates/directives/notifications.html",restrict:"E",replace:!0}}).directive("msgbox",function(){return{templateUrl:"shared/templates/directives/msgbox.html",restrict:"E",replace:!1}}).directive("alertBox",function($timeout){return{templateUrl:"shared/templates/directives/alert.html",restrict:"E",replace:!0,link:function($scope){$scope.$on("alertBox",function($event,data){$timeout(function(){delete $scope.alerts},5e3),$scope.alerts=[data]})}}}).directive("sidebarSearch",function(){return{templateUrl:"shared/templates/directives/sidebar-search.html",restrict:"E",replace:!0,scope:{},controller:function($scope){$scope.selectedMenu="home"}}}).directive("fileread",function($timeout){return{scope:{fileread:"="},link:function(scope,element,attributes){element.bind("change",function(changeEvent){var reader=new FileReader;reader.onload=function(loadEvent){scope.$apply(function(){scope.fileread=loadEvent.target.result}),$timeout(function(){scope.$parent.model[changeEvent.target.name]={file_name:changeEvent.target.files[0].name,file_content:scope.$parent.model[changeEvent.target.name]},document.querySelector("#image-preview").src=URL.createObjectURL(changeEvent.target.files[0])})},reader.readAsDataURL(changeEvent.target.files[0])})}}}),angular.module("ulakbus.auth",["ngRoute","ngCookies"]).controller("LoginCtrl",function($scope,$q,$timeout,$routeParams,$rootScope,$log,Generator,AuthService){$scope.url="login",$scope.form_params={},$scope.form_params.clear_wf=1,Generator.get_form($scope).then(function(data){$scope.form=[{key:"username",type:"string",title:"Kullanıcı Adı"},{key:"password",type:"password",title:"Şifre"},{type:"submit",title:"Giriş Yap"}]}),$scope.loggingIn=!1,$scope.onSubmit=function(form){$scope.$broadcast("schemaFormValidate"),form.$valid?($scope.loggingIn=!0,$rootScope.loginAttempt=1,Generator.button_switch(!1),AuthService.login($scope.url,$scope.model).error(function(data){$scope.message=data.title,$scope.loggingIn=!1}).then(function(){$scope.loggingIn=!1,Generator.button_switch(!1)})):$log.debug("not valid")},$log.debug("login attempt: ",$rootScope.loginAttempt)}),angular.module("ulakbus.auth").factory("AuthService",function($http,$rootScope,$location,$log,Generator,RESTURL){var authService={};return authService.login=function(url,credentials){return credentials.cmd="do",$http.post(RESTURL.url+url,credentials).success(function(data,status,headers,config){$rootScope.loggedInUser=!0}).error(function(data,status,headers,config){return data.title="İşlem başarısız oldu. Lütfen girdiğiniz bilgileri kontrol ediniz.",data})},authService.logout=function(){return $log.debug("logout"),$http.post(RESTURL.url+"logout",{}).success(function(data){$rootScope.loggedInUser=!1,$log.debug("loggedout"),$location.path("/login")})},authService}),angular.module("ulakbus.dashboard",[]).config(function($uibTooltipProvider){$uibTooltipProvider.setTriggers({click:"mouseleave"})}).controller("DashCtrl",function($scope,$rootScope,$timeout,$http,$cookies,RESTURL,Generator){$scope.section=function(section_index){$rootScope.section=section_index},$scope.$on("authz",function(event,data){$rootScope.searchInputs=data}),$scope.keyword={student:"",staff:""},$scope.students=[],$scope.staffs=[],$scope.search=function(where){$timeout(function(){"personel"===where&&$scope.keyword.staff.length>2&&$scope.getItems(where,$scope.keyword.staff).success(function(data){$scope.staffs=data.results}),"ogrenci"===where&&$scope.keyword.student.length>2&&$scope.getItems(where,$scope.keyword.student).success(function(data){$scope.students=data.results})},500)},$scope.getItems=function(where,what){return $scope.showResults=!0,$http.get(RESTURL.url+"ara/"+where+"/"+what)},$scope.userPopover={templateUrl:"components/dashboard/user-info.html"},$scope.get_info=function(type,key){Generator.get_list({url:"crud",form_params:{model:type,object_id:key,cmd:"show"}}).then(function(data){$scope.userPopover.name=data.data.object.unicode,$scope.userPopover.tcno=data.data.object.tckn})},$scope.select=function(who,type){$rootScope.$broadcast("selectedUser",{name:who[0],tcno:who[1],key:who[2]}),$rootScope.$broadcast("menuitems",type),$scope.showResults=!1},$scope.$on("notifications",function(event,data){$scope.notifications=data}),$scope.$on("selectedUser",function($event,data){$scope.selectedUser=data}),$scope.deselectUser=function(){delete $scope.selectedUser,delete $scope.selectedMenuItems},$scope.markAsRead=function(items){$rootScope.$broadcast("markasread",items)}}).directive("sidebarNotifications",function(){return{templateUrl:"shared/templates/directives/sidebar-notification.html",restrict:"E",replace:!0,link:function($scope){}}}),angular.module("ulakbus.crud",["ui.bootstrap","schemaForm","ulakbus.formService"]).config(function(sfErrorMessageProvider){sfErrorMessageProvider.setDefaultMessage(302,"Bu alan zorunludur."),sfErrorMessageProvider.setDefaultMessage(200,"En az {{schema.minLength}} değer giriniz."),sfErrorMessageProvider.setDefaultMessage(201,"En fazla {{schema.minLength}} değer giriniz.")}).service("CrudUtility",function($log,$rootScope){return{generateParam:function(scope,routeParams,cmd){return scope.url=routeParams.wf,angular.forEach(routeParams,function(value,key){key.indexOf("_id")>-1&&"param_id"!==key&&(scope.param=key,scope.param_id=value)}),scope.form_params={model:routeParams.model,param:scope.param||routeParams.param,id:scope.param_id||routeParams.param_id,wf:routeParams.wf,object_id:routeParams.key,filters:{}},scope.param_id&&(scope.form_params.filters[scope.param]={values:[scope.param_id],type:"check"}),scope.model=scope.form_params.model,scope.wf=scope.form_params.wf,scope.param=scope.form_params.param,scope.param_id=scope.form_params.id,scope},listPageItems:function(scope,pageData){angular.forEach(pageData,function(value,key){scope[key]=value}),angular.forEach(scope.objects,function(value,key){if(key>0){var linkIndexes={};angular.forEach(value.actions,function(v,k){"link"===v.show_as&&(linkIndexes=v)}),angular.forEach(value.fields,function(v,k){value.actions.length>0&&linkIndexes.fields?scope.objects[key].fields[k]={type:linkIndexes.fields.indexOf(k)>-1?"link":"str",content:v,cmd:linkIndexes.cmd,mode:linkIndexes.mode}:scope.objects[key].fields[k]={type:"str",content:v}})}}),$log.debug(scope.objects)}}}).controller("CRUDCtrl",function($scope,$routeParams,Generator,CrudUtility){CrudUtility.generateParam($scope,$routeParams),Generator.get_wf($scope)}).controller("CRUDListFormCtrl",function($scope,$rootScope,$location,$http,$log,$uibModal,$timeout,Generator,$routeParams,CrudUtility){$scope.reload=function(reloadData){$scope.form_params.cmd=$scope.reload_cmd,$scope.form_params=angular.extend($scope.form_params,reloadData),$log.debug("reload data",$scope),Generator.get_wf($scope)},$scope.$on("reload_cmd",function(event,data){$scope.reload_cmd=data,$scope.reload({})}),$scope.$on("updateObjects",function($event,data){$scope.objects=data,CrudUtility.listPageItems($scope,{objects:$scope.objects})}),$scope.$on("formLocator",function(event){$scope.formgenerated=event.targetScope.formgenerated}),$scope.remove=function(item,type,index){$scope[type][item.title].model.splice(index,1),$scope[type][item.title].items.splice(index,1)},$scope.onSubmit=function(form){$scope.$broadcast("schemaFormValidate"),form.$valid&&Generator.submit($scope)},$scope.do_action=function(key,todo){Generator.doItemAction($scope,key,todo,todo.mode||"normal")},$scope.getNumber=function(num){return new Array(num)},$scope.createListObjects=function(){$scope.object.constructor===Array?$log.debug("new type show object"):$scope.object.type?$scope.object=[$scope.object]:$scope.object=[{type:"table",fields:angular.copy($scope.object)}]},$scope.showCmd=function(){CrudUtility.generateParam($scope,$routeParams,$routeParams.cmd);var pageData=Generator.getPageData();pageData.pageData===!0?($scope.object=pageData.object,Generator.setPageData({pageData:!1})):Generator.get_wf($scope).then(function(res){$scope.object=res.data.object,$scope.model=$routeParams.model}),$scope.createListObjects()},$scope.listFormCmd=function(){var setpageobjects=function(data){CrudUtility.listPageItems($scope,data),Generator.generate($scope,data),Generator.setPageData({pageData:!1})},pageData=Generator.getPageData();pageData.pageData===!0&&($log.debug("pagedata",pageData.pageData),CrudUtility.generateParam($scope,pageData,$routeParams.cmd),setpageobjects(pageData,pageData),$scope.second_client_cmd&&$scope.createListObjects()),(void 0===pageData.pageData||pageData.pageData===!1)&&(CrudUtility.generateParam($scope,$routeParams,$routeParams.cmd),Generator.get_wf($scope)),$scope.object&&$scope.createListObjects()},$scope.reloadCmd=function(){$scope.reload({})},$scope.resetCmd=function(){delete $scope.token,$scope.cmd="reset",Generator.get_wf($scope)};var executeCmd={show:$scope.showCmd,list:$scope.listFormCmd,form:$scope.listFormCmd,reload:$scope.reloadCmd,reset:$scope.resetCmd};return executeCmd[$routeParams.cmd]()}).directive("crudListDirective",function(){return{templateUrl:"components/crud/templates/list.html",restrict:"E",replace:!0}}).directive("crudFormDirective",function(){return{templateUrl:"components/crud/templates/form.html",restrict:"E",replace:!0}}).directive("crudShowDirective",function(){return{templateUrl:"components/crud/templates/show.html",restrict:"E",replace:!0}}).directive("formLocator",function(){return{link:function(scope){scope.$emit("formLocator")}}}).directive("crudFilters",function(Generator){return{templateUrl:"components/crud/templates/filter.html",restrict:"E",replace:!0,link:function($scope){$scope.form_params.filters=$scope.form_params.filters||{},$scope.filterList={},$scope.filterCollapsed={},$scope.$watch("list_filters",function(){angular.forEach($scope.list_filters,function(value,key){$scope.filterList[value.field]={values:value.values||[],type:value.type},$scope.filterCollapsed[value.field]=Object.keys($scope.filterCollapsed).length>0?!0:!1})}),$scope.collapseFilter=function(field){$scope.filterCollapsed[field]=!$scope.filterCollapsed[field]},$scope.status={startOpened:!1,endOpened:!1},$scope.dateFilterOpen=function($event,which){this.status[which]=!0},$scope.format="dd.MM.yyyy",$scope.filterSubmit=function(){angular.forEach($scope.filterList,function(value,key){if(value.model)if("date"===value.type){var dateValues=[null,null];angular.forEach(value.model,function(v,k){dateValues[k]=Generator.dateformatter(v)}),$scope.form_params.filters[key]={values:dateValues,type:value.type}}else $scope.form_params.filters[key]={values:Object.keys(value.model),type:value.type||"check"}}),Generator.get_wf($scope)}}}}),angular.module("ulakbus.debug",["ngRoute"]).controller("DebugCtrl",function($scope,$rootScope,$location){$scope.debug_queries=$rootScope.debug_queries}),angular.module("ulakbus.devSettings",["ngRoute"]).controller("DevSettingsCtrl",function($scope,$cookies,$rootScope,RESTURL){$scope.backendurl=$cookies.get("backendurl"),$scope.notificate=$cookies.get("notificate")||"on",$scope.changeSettings=function(what,set){document.cookie=what+"="+set,$scope[what]=set,$rootScope.$broadcast(what,set)},$scope.switchOnOff=function(pinn){return"on"==pinn?"off":"on"},$scope.setbackendurl=function(){$scope.changeSettings("backendurl",$scope.backendurl),RESTURL.url=$scope.backendurl},$scope.setnotification=function(){$scope.changeSettings("notificate",$scope.switchOnOff($scope.notificate))}}),angular.module("ulakbus").config(["$routeProvider",function($routeProvider){$routeProvider.when("/error/500",{templateUrl:"components/error_pages/500.html",controller:"500Ctrl"}).when("/error/404",{templateUrl:"components/error_pages/404.html",controller:"404Ctrl"})}]),angular.module("ulakbus.error_pages",["ngRoute"]).controller("500Ctrl",function($scope,$rootScope,$location){}).controller("404Ctrl",function($scope,$rootScope,$location){}),angular.module("ulakbus.version",["ulakbus.version.interpolate-filter","ulakbus.version.version-directive"]).value("version","0.6.10"),angular.module("ulakbus.version.interpolate-filter",[]).filter("interpolate",["version",function(version){return function(text){return String(text).replace(/\%VERSION\%/gm,version)}}]),angular.module("ulakbus.version.version-directive",[]).directive("appVersion",["version",function(version){return function(scope,elm,attrs){elm.text(version)}}]);
\ No newline at end of file
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.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -56,7 +56,7 @@
<div class="main" ng-view>
</div>
<right-sidebar></right-sidebar>
</div>
</div>
</div>
......
angular.module('templates-prod', ['components/auth/login.html', 'components/crud/templates/crud.html', 'components/crud/templates/filter.html', 'components/crud/templates/form.html', 'components/crud/templates/list.html', 'components/crud/templates/show.html', 'components/dashboard/dashboard.html', 'components/dashboard/user-info.html', 'components/debug/debug.html', 'components/devSettings/devSettings.html', 'components/error_pages/404.html', 'components/error_pages/500.html', 'components/uitemplates/404.html', 'components/uitemplates/500.html', 'shared/templates/add.html', 'shared/templates/datefield.html', 'shared/templates/directives/alert.html', 'shared/templates/directives/chat.html', 'shared/templates/directives/guide-help.html', 'shared/templates/directives/header-breadcrumb.html', 'shared/templates/directives/header-notification.html', 'shared/templates/directives/header-sub-menu.html', 'shared/templates/directives/menuCollapse.html', 'shared/templates/directives/msgbox.html', 'shared/templates/directives/notifications.html', 'shared/templates/directives/search.html', 'shared/templates/directives/selected-user.html', 'shared/templates/directives/selectedUserPopover.html', 'shared/templates/directives/sidebar-notification.html', 'shared/templates/directives/sidebar-search.html', 'shared/templates/directives/sidebar.html', 'shared/templates/directives/sort.html', 'shared/templates/directives/stats.html', 'shared/templates/directives/timeline.html', 'shared/templates/fieldset.html', 'shared/templates/filefield.html', 'shared/templates/foreignKey.html', 'shared/templates/linkedModelModalContent.html', 'shared/templates/listnodeModalContent.html', 'shared/templates/modalContent.html', 'shared/templates/multiselect.html', 'shared/templates/nodeTable.html', 'shared/templates/select.html']);
angular.module('templates-prod', ['components/auth/login.html', 'components/crud/templates/crud.html', 'components/crud/templates/filter.html', 'components/crud/templates/form.html', 'components/crud/templates/list.html', 'components/crud/templates/show.html', 'components/dashboard/dashboard.html', 'components/dashboard/user-info.html', 'components/debug/debug.html', 'components/devSettings/devSettings.html', 'components/error_pages/404.html', 'components/error_pages/500.html', 'components/uitemplates/404.html', 'components/uitemplates/500.html', 'shared/templates/add.html', 'shared/templates/datefield.html', 'shared/templates/directives/alert.html', 'shared/templates/directives/chat.html', 'shared/templates/directives/guide-help.html', 'shared/templates/directives/header-breadcrumb.html', 'shared/templates/directives/header-notification.html', 'shared/templates/directives/header-sub-menu.html', 'shared/templates/directives/menuCollapse.html', 'shared/templates/directives/msgbox.html', 'shared/templates/directives/notifications.html', 'shared/templates/directives/right-sidebar.html', 'shared/templates/directives/search.html', 'shared/templates/directives/selected-user.html', 'shared/templates/directives/selectedUserPopover.html', 'shared/templates/directives/sidebar-notification.html', 'shared/templates/directives/sidebar-search.html', 'shared/templates/directives/sidebar.html', 'shared/templates/directives/sort.html', 'shared/templates/directives/stats.html', 'shared/templates/directives/timeline.html', 'shared/templates/fieldset.html', 'shared/templates/filefield.html', 'shared/templates/foreignKey.html', 'shared/templates/linkedModelModalContent.html', 'shared/templates/listnodeModalContent.html', 'shared/templates/modalContent.html', 'shared/templates/multiselect.html', 'shared/templates/nodeTable.html', 'shared/templates/select.html']);
angular.module("components/auth/login.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("components/auth/login.html",
......@@ -270,7 +270,7 @@ angular.module("components/crud/templates/show.html", []).run(["$templateCache",
angular.module("components/dashboard/dashboard.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("components/dashboard/dashboard.html",
"<div ng-app=\"ulakbus.dashboard\" class=\"dashboard\">\n" +
" <div class=\"starter-template\" style=\"width: calc(100% - 300px);\">\n" +
" <div class=\"starter-template\">\n" +
"\n" +
" <div class=\"dashboard-main-search clearfix\">\n" +
"\n" +
......@@ -396,107 +396,24 @@ angular.module("components/dashboard/dashboard.html", []).run(["$templateCache",
" </div>\n" +
" <!-- end of dashboard-main-anouncement -->\n" +
"\n" +
" <div class=\"right-sidebar\">\n" +
"\n" +
" <div class=\"right-sidebar-box\" data-step=\"4\"\n" +
" data-intro=\"mesajlar, yapılan görevlerin son durumları, duyurular ve son yapılan işlemleri buradan takip edebilirsiniz.\">\n" +
" <div class=\"right-sidebar-messages\">\n" +
"\n" +
" <div class=\"right-sidebar-title clearfix\">\n" +
" <h3>Mesajlar</h3>\n" +
" <span><a role=\"button\">Tüm Mesajlar</a></span>\n" +
" </div>\n" +
" <!-- end of right-sidebar-title -->\n" +
" <p ng-show=\"notifications[2].length === 0\" class=\"text-center\">Görüntülenecek içerik yok.</p>\n" +
"\n" +
" <div class=\"right-sidebar-message-block\" ng-repeat=\"notify in notifications[2] | limitTo:5\">\n" +
" <a class=\"clearfix\" ng-click=\"markAsRead(notify)\">\n" +
" <img src=\"../../../img/sample-profile-pic.jpg\">\n" +
" <div class=\"right-sidebar-message-content\">\n" +
" <div>{{notify.title}}</div>\n" +
" <div>{{notify.body}}</div>\n" +
" <div>16:05</div>\n" +
" </div>\n" +
" <!-- end of right-sidebar-message-content -->\n" +
" </a>\n" +
" </div>\n" +
" <!-- end of right-sidebar-message-block -->\n" +
"\n" +
" </div>\n" +
" <!-- end of right-sidebar-messages -->\n" +
" </div>\n" +
" <!-- end of right-sidebar-box -->\n" +
"\n" +
"\n" +
" <div class=\"right-sidebar-box\">\n" +
" <div class=\"right-sidebar-tasks\">\n" +
"\n" +
" <div class=\"right-sidebar-title clearfix\">\n" +
" <h3>Görevler</h3>\n" +
" <span><a role=\"button\">Tüm Görevler</a></span>\n" +
" </div>\n" +
"\n" +
" <p ng-show=\"notifications[1].length === 0\" class=\"text-center\">Görüntülenecek içerik yok.</p>\n" +
"\n" +
" <div class=\"right-sidebar-task-block\">\n" +
" <!--<div class=\"task-type\">Onay Bekleyen Görevler</div>-->\n" +
" <a ng-click=\"markAsRead(notify)\" ng-repeat=\"notify in notifications[1] | limitTo:5\">\n" +
" <div class=\"task-title\">{{notify.title}}</div>\n" +
" </a>\n" +
" </div>\n" +
" <!-- end of right-sidebar-task-block -->\n" +
"\n" +
" </div>\n" +
" <!-- end of right-sidebar-tasks -->\n" +
" </div>\n" +
" <!-- end of right-sidebar-box -->\n" +
"\n" +
"\n" +
" <!--<div class=\"right-sidebar-box\">-->\n" +
" <!--<div class=\"right-sidebar-announcements\">-->\n" +
" <!--<div class=\"right-sidebar selected-person-field\">-->\n" +
"\n" +
" <!--<div class=\"right-sidebar-title clearfix\">-->\n" +
" <!--<h3>Duyurular</h3>-->\n" +
" <!--<span><a role=\"button\">Tüm Duyurular</a></span>-->\n" +
" <!--</div>-->\n" +
" <!--&lt;!&ndash; end of right-sidebar-title &ndash;&gt;-->\n" +
"\n" +
" <!--<div class=\"right-sidebar-announcement-block\">-->\n" +
" <!--<a ng-click=\"markAsRead(notify)\"-->\n" +
" <!--ng-repeat=\"notify in notifications[3] | limitTo:5\">{{notify-->\n" +
" <!--.body}}</a>-->\n" +
" <!--</div>-->\n" +
" <!--&lt;!&ndash; end of right-sidebar-status-block &ndash;&gt;-->\n" +
"\n" +
" <!--</div>-->\n" +
" <!--&lt;!&ndash; end of right-sidebar-status &ndash;&gt;-->\n" +
" <!--<div class=\"right-sidebar-header\">-->\n" +
" <!--<span class=\"bar-title\">Kişi seçildi</span>-->\n" +
" <!--<span class=\"unselect-person\"><i class=\"fa fa-times\"></i></span>-->\n" +
" <!--</div>-->\n" +
" <!-- end of right-sidebar-box -->\n" +
"\n" +
"\n" +
" <div class=\"right-sidebar-box\">\n" +
" <div class=\"right-sidebar-last-actions\">\n" +
" <!--&lt;!&ndash; end of right-sidebaer-header &ndash;&gt;-->\n" +
" <!---->\n" +
" <!--<div class=\"selected-person-info\">-->\n" +
" <!--<img src=\"../../img/sample-profile-pic.jpg\" class=\"selected-person-img\">-->\n" +
" <!--<div class=\"selected-person-name\">Erkan Öğümsöğütlü</div>-->\n" +
" <!--</div>-->\n" +
" <!--&lt;!&ndash; end of selected-person-info &ndash;&gt;-->\n" +
"\n" +
" <div class=\"right-sidebar-title clearfix\">\n" +
" <h3>Son İşlemler</h3>\n" +
" <span><a role=\"button\">Tüm İşlemler</a></span>\n" +
" </div>\n" +
" <!--</div>-->\n" +
" <!-- end of right-sidebar -->\n" +
"\n" +
" <p class=\"text-center\">Görüntülenecek içerik yok.</p>\n" +
"\n" +
" <div class=\"right-sidebar-task-block\">\n" +
" <a>\n" +
" <div class=\"task-title\"></div>\n" +
" </a>\n" +
" </div>\n" +
"\n" +
" </div>\n" +
" <!-- end of right-sidebar-status -->\n" +
" </div>\n" +
" <!-- end of right-sidebar-box -->\n" +
"\n" +
" </div>\n" +
" <!-- end of right-sidebar -->\n" +
"\n" +
" </div>\n" +
"</div>");
......@@ -1007,11 +924,10 @@ angular.module("shared/templates/directives/header-notification.html", []).run([
" <!-- /.dropdown-alerts -->\n" +
" </li>\n" +
" <!-- /.dropdown -->\n" +
" <li class=\"dropdown\">\n" +
" <a class=\"dropdown-toggle\" data-toggle=\"dropdown\">\n" +
" <i class=\"fa fa-user fa-fw\" tooltip-placement=\"bottom\"\n" +
" uib-tooltip=\"Profil\"></i>&nbsp;{{$root.current_user.name}}&nbsp;{{$root.current_user.surname}}&nbsp;<i\n" +
" class=\"fa fa-caret-down\"></i>\n" +
" <li class=\"dropdown\" style=\"border-left:1px solid #891723;\">\n" +
" <a class=\"dropdown-toggle\" data-toggle=\"dropdown\" style=\"padding-top: 7px; padding-bottom: 6px;\">\n" +
" <img src=\"../../../img/sample-profile-pic.jpg\" class=\"header-profile\">&nbsp;{{$root.current_user.name}}&nbsp;{{$root.current_user.surname}}&nbsp;\n" +
" <i class=\"fa fa-caret-down\" style=\"margin-left:3px;\"></i>\n" +
" </a>\n" +
" <ul class=\"dropdown-menu dropdown-user\">\n" +
" <li><a role=\"button\"><i class=\"fa fa-user fa-fw\"></i> Profil</a></li>\n" +
......@@ -1031,7 +947,7 @@ angular.module("shared/templates/directives/header-notification.html", []).run([
angular.module("shared/templates/directives/header-sub-menu.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("shared/templates/directives/header-sub-menu.html",
"<div class=\"manager-view-header\" style=\"{{style}}\">\n" +
"<div class=\"manager-view-header\">\n" +
" <div class=\"clearfix\">\n" +
" <header-breadcrumb></header-breadcrumb>\n" +
" <loaderdiv><div></div></loaderdiv>\n" +
......@@ -1124,6 +1040,57 @@ angular.module("shared/templates/directives/notifications.html", []).run(["$temp
"</div>");
}]);
angular.module("shared/templates/directives/right-sidebar.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("shared/templates/directives/right-sidebar.html",
"<div class=\"right-sidebar selected-person-field\">\n" +
" <div class=\"right-sidebar-header\">\n" +
" <button type=\"button\" class=\"close\" ng-click=\"deselectUser()\"\n" +
" aria-label=\"Close\">\n" +
" <span class=\"unselect-person\"><i class=\"fa fa-times\"></i></span>\n" +
" </button>\n" +
" </div>\n" +
"\n" +
" <div class=\"selected-person-info\">\n" +
" <img class=\"selected-person-img\"\n" +
" ng-src=\"{{selectedUser ? '/img/sample-profile-pic.jpg' : '/img/empty-profile-pic.jpg'}}\">\n" +
" <div class=\"selected-person-name\">\n" +
" <p class=\"identity-name\">{{selectedUser.name || 'Kişi seçilmedi.'}}</p>\n" +
" <p class=\"identity-surname\">{{selectedUser.surname}}</p>\n" +
" <p>{{selectedUser ? 'TCNo: ' + selectedUser.tcno : ''}}</p>\n" +
" </div>\n" +
"\n" +
" </div>\n" +
"\n" +
" <div class=\"\">\n" +
" <ul class=\"nav in\" id=\"side-user-menu\" data-step=\"2\"\n" +
" data-intro=\"seçilen personele veya öğrenciye göre ilgili menüler yer almaktadır. yapılacak işlemi buradan seçebilirsiniz.\">\n" +
"\n" +
"\n" +
" <li ng-repeat=\"(key, item) in selectedMenuItems\" ng-class=\"{active: collapseVar == $index+100}\">{{dropDown}}\n" +
" <a href=\"\" ng-click=\"check($index+100)\">\n" +
" <i class=\"fa fa-fw\"\n" +
" ng-class=\"{\n" +
" 'Admin': 'fa fa-fw fa-terminal',\n" +
" 'Genel': 'fa fa-fw fa-graduation-cap',\n" +
" 'Alt Kategori': 'fa fa-fw fa-tags',\n" +
" 'Kadro Islemleri': 'fa fa-fw fa-users',\n" +
" 'Seçime Uygun Görevler':'fa fa-fw fa-user'\n" +
" }[item[0].kategori]\"></i>\n" +
" <span class=\"menu-text\">{{ key }}</span>\n" +
" <span class=\"fa arrow\"></span>\n" +
" </a>\n" +
" <ul class=\"nav nav-second-level\">\n" +
" <li ng-repeat=\"(k, v) in item\">\n" +
" <a ng-href=\"#/{{v.wf}}/{{v.model}}?{{v.param}}={{selectedUser.key}}\"\n" +
" ng-click=\"breadcrumb([key, v.text], $event)\">{{v.text}}</a>\n" +
" </li>\n" +
" </ul>\n" +
" </li>\n" +
" </ul>\n" +
" </div>\n" +
"</div>");
}]);
angular.module("shared/templates/directives/search.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("shared/templates/directives/search.html",
"<form class=\"form-inline pull-right\" id=\"search\" name=\"search\" sf-schema=\"searchSchema\" sf-form=\"searchForm\"\n" +
......@@ -1294,71 +1261,6 @@ angular.module("shared/templates/directives/sidebar.html", []).run(["$templateCa
"<div class=\"navbar-default sidebar\" role=\"navigation\" ng-mouseenter=\"openSidebar()\" ng-mouseleave=\"closeSidebar()\">\n" +
"\n" +
" <div class=\"sidebar-container\">\n" +
" <!-- sidebar-person-info -->\n" +
" <div class=\"sidebar-person-info\" ng-show=\"$root.current_user.can_search\">\n" +
" <!--<button class=\"btn btn-primary close-sidebar-person-info\">Profili Kapat</button>-->\n" +
" <div class=\"identity\">\n" +
" <button type=\"button\" class=\"close\" ng-class=\"{hidden: $root.collapsed || !selectedUser}\"\n" +
" ng-click=\"deselectUser()\"\n" +
" aria-label=\"Close\"><span\n" +
" aria-hidden=\"true\">&times;</span></button>\n" +
" <div class=\"identity-header clearfix\">\n" +
" <img ng-src=\"{{selectedUser ? '/img/sample-profile-pic.jpg' : '/img/empty-profile-pic.jpg'}}\">\n" +
" <div class=\"pull-left\" ng-class=\"{hidden: $root.collapsed}\">\n" +
" <p class=\"identity-name\">{{selectedUser.name || 'Kişi seçilmedi.'}}</p>\n" +
" <p class=\"identity-surname\">{{selectedUser.surname}}</p>\n" +
" <p>{{selectedUser ? 'TCNo: ' + selectedUser.tcno : ''}}</p>\n" +
" </div>\n" +
" </div>\n" +
" <!-- end of identity-header -->\n" +
" <!--<div class=\"identity-info\" ng-class=\"{hidden: $root.collapsed}\">-->\n" +
"\n" +
" <!--<div class=\"clearfix\">-->\n" +
" <!--<span class=\"fa fa-envelope\"></span>-->\n" +
" <!--<div>erkanogum@gmail.com</div>-->\n" +
" <!--</div>-->\n" +
" <!--<div class=\"clearfix\">-->\n" +
" <!--<span class=\"fa fa-home\"></span>-->\n" +
" <!--<div>İşçi Blokları Mah. 1524. sokak B Blok 6. Kat A Kanat 27 numara</div>-->\n" +
" <!--</div>-->\n" +
" <!--</div>-->\n" +
"\n" +
" </div>\n" +
" <!-- end of identity -->\n" +
" <div class=\"\">\n" +
" <ul class=\"nav in\" id=\"side-user-menu\" ng-class=\"{hidden: !selectedMenuItems}\" data-step=\"2\"\n" +
" data-intro=\"seçilen personele veya öğrenciye göre ilgili menüler yer almaktadır. yapılacak işlemi buradan seçebilirsiniz.\">\n" +
"\n" +
"\n" +
" <li ng-repeat=\"(key, item) in selectedMenuItems\" ng-class=\"{active: collapseVar == $index+100}\">{{dropDown}}\n" +
" <a href=\"\" ng-click=\"check($index+100)\">\n" +
" <i class=\"fa fa-fw\"\n" +
" ng-class=\"{\n" +
" 'Admin': 'fa fa-fw fa-terminal',\n" +
" 'Genel': 'fa fa-fw fa-graduation-cap',\n" +
" 'Alt Kategori': 'fa fa-fw fa-tags',\n" +
" 'Kadro Islemleri': 'fa fa-fw fa-users',\n" +
" 'Seçime Uygun Görevler':'fa fa-fw fa-user'\n" +
" }[item[0].kategori]\"></i>\n" +
" <span class=\"menu-text\" ng-class=\"{hidden: $root.collapsed}\">{{ key }}</span>\n" +
" <span class=\"fa arrow\" ng-class=\"{hidden: $root.collapsed}\"></span>\n" +
" </a>\n" +
" <ul class=\"nav nav-second-level\" ng-class=\"{hidden: $root.collapsed}\">\n" +
" <li ng-repeat=\"(k, v) in item\">\n" +
" <!--<a ng-if=\"v.model\" ng-href=\"#{{v.url}}\" ng- -->\n" +
" <!--ng-click=\"breadcrumb([key, v.text], $event)\">{{v.text}}</a>-->\n" +
" <a ng-href=\"#/{{v.wf}}/{{v.model}}?{{v.param}}={{selectedUser.key}}\"\n" +
" ng-click=\"breadcrumb([key, v.text], $event)\">{{v.text}}</a>\n" +
" </li>\n" +
" </ul>\n" +
" <!-- /.nav-second-level -->\n" +
" </li>\n" +
" </ul>\n" +
" </div>\n" +
" <!-- end of person-actions -->\n" +
" </div>\n" +
" <!-- end of sidebar-person-info -->\n" +
"\n" +
" <div class=\"sidebar-nav navbar-collapse\">\n" +
" <ul class=\"nav in\" id=\"side-menu\" ng-class=\"{hidden: $root.loggedInUser != true}\" data-step=\"1\"\n" +
" data-intro=\"Genel menüler yer almaktadır. yapılacak işlemi buradan seçebilirsiniz.\">\n" +
......@@ -1805,7 +1707,7 @@ angular.module("shared/templates/nodeTable.html", []).run(["$templateCache", fun
" <span ng-if=\"value.verbose_name\">{{ value.verbose_name }}</span>\n" +
" <span ng-if=\"!value.verbose_name\">{{key}}</span>\n" +
" </th>\n" +
" <th>İşlem</th>\n" +
" <th ng-if=\"meta.allow_actions!==false\">İşlem</th>\n" +
" </tr>\n" +
" </thead>\n" +
" <tbody ng-class=\"{hidden: node.lengthModels < 1}\">\n" +
......@@ -1838,7 +1740,7 @@ angular.module("shared/templates/nodeTable.html", []).run(["$templateCache", fun
" ng-model=\"node.model[outerIndex][k]\"\n" +
" ng-change=\"nodeModelChange(this)\">\n" +
" </td>\n" +
" <td>\n" +
" <td ng-if=\"meta.allow_actions!==false\">\n" +
" <button modal-for-nodes=\"{{node.schema.model_name}},{{node.schema.formType}},edit,{{$index}}\">Düzenle\n" +
" </button>\n" +
" <br>\n" +
......
#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 %}
/* Space out content a bit */
body {
font-family:'robotoregular';
background-color: #f5f5f5;
overflow:hidden;
}
::-webkit-scrollbar {
width: 5px;
height: 5px;
}
::-webkit-scrollbar-track {
background-color:#ccc;
}
::-webkit-scrollbar-thumb {
background-color:#999;
}
.badge {
border-radius: 100%;
width: 22px;
height: 22px;
padding: 0;
position: absolute;
z-index: 1;
line-height: 19px;
top: 4px;
left: 2px;
background-color: rgba(220, 112, 0, 1);
border: 2px solid #a61229;
font-family: 'robotomedium';
font-weight: normal;
}
.form-control {
box-shadow:none;
border-radius:0;
border-color:#ececec;
}
.btn {
border:none;
}
.btn:focus,
.btn:active:focus,
.btn.active:focus,
.btn.focus,
.btn:active.focus,
.btn.active.focus {
outline: none;
}
a {
color:#a61229;
-webkit-transition: all .1s;
-moz-transition: all .1s;
-ms-transition: all .1s;
-o-transition: all .1s;
transition: all .1s;
}
a:hover {
color:#941A1A;
}
.breadcrumb {
background-color:transparent;
padding:0;
font-size:18px;
float:left;
margin-bottom: 0;
}
/** BRAND **/
.brand-bg {
background-color:#A61229;
}
button.brand-bg {
background-color:#A61229;
color:#fff;
}
button.brand-bg:hover {
background-color:#941A1A;
color:#fff;
}
.brand {
height:98px;
border-bottom:1px solid #ccc;
}
.logo {
}
.logo img {
width: 80%;
margin-left: 8%;
margin-top: 22px;
margin-bottom: 22px;
}
/** END OF BRAND **/
/** LOADER **/
.loader {
font-size: 2px;
position: relative;
text-indent: -9999em;
border-top: 1.1em solid rgba(166, 12, 41, 0.2);
border-right: 1.1em solid rgba(166, 12, 41, 0.2);
border-bottom: 1.1em solid rgba(166, 12, 41, 0.2);
border-left: 1.1em solid #A61229;
-webkit-transform: translateZ(0);
-ms-transform: translateZ(0);
transform: translateZ(0);
-webkit-animation: load8 1.1s infinite linear;
animation: load8 1.1s infinite linear;
float: left;
margin-left: 10px;
margin-top: 3px;
}
.loader,
.loader:after {
border-radius: 50%;
width: 10em;
height: 10em;
}
@-webkit-keyframes load8 {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes load8 {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
/** END OF LOADER **/
/* Everything but the jumbotron gets side spacing for mobile first views */
.header,
.marketing,
.footer {
padding-left: 15px;
padding-right: 15px;
}
/* Custom page header */
.header {
border-bottom: 1px solid #e5e5e5;
}
/* Make the masthead heading the same height as the navigation */
.header h3 {
margin-top: 0;
margin-bottom: 0;
line-height: 40px;
padding-bottom: 19px;
}
/* Custom page footer */
.footer {
padding-top: 19px;
color: #777;
border-top: 1px solid #e5e5e5;
}
nav.navbar {
background-color: #A61229;
border-color: #941A1A;
min-height:30px;
}
a.navbar-brand img {
height:45px;
margin-top:-6px;
}
.navbar-default .navbar-toggle .icon-bar {
background-color:#fff;
}
.navbar-default .navbar-toggle:hover {
background-color:#9a1026;
}
.navbar-default .navbar-toggle:focus {
background-color:#A61229;
}
.container-narrow > hr {
margin: 30px 0;
}
/* Main marketing message and sign up button */
.jumbotron {
text-align: center;
border-bottom: 1px solid #e5e5e5;
}
.jumbotron .btn {
font-size: 21px;
padding: 14px 24px;
}
/* Supporting marketing content */
.marketing {
margin: 40px 0;
}
.marketing p + h4 {
margin-top: 28px;
}
ul.header-menu {
float:left;
padding-left:23px;
}
ul.header-menu li {
list-style:none;
float:left;
margin-right:15px;
margin-top:10px;
}
ul.header-menu li a{
color:#fff;
text-decoration:none;
opacity:0.9;
}
ul.header-menu li a:hover{
opacity:1;
}
.nav>li>a {
color: #696969;
border-left:3px solid transparent;
-webkit-transition: all .2s;
-moz-transition: all .2s;
-ms-transition: all .2s;
-o-transition: all .2s;
transition: all .2s;
}
.sidebar .nav>li ul {
border-left: 3px solid #A61229;
}
.sidebar .nav>li ul>li a {
font-family:'robotoregular';
background-color:#fdfdfd;
}
.nav>li>a:visited {
}
.nav>li.active>a {
text-decoration: none;
background-color: #fdfdfd;
color: #565656;
border-color:#A61229;
}
.nav>li.active>a:hover,
.sidebar .nav>li ul>li a:hover,
.nav>li>a:hover {
background-color:#f9f9f9;
}
/*!
* Start Bootstrap - SB Admin 2 Bootstrap Admin Theme (http://startbootstrap.com)
* Code licensed under the Apache License v2.0.
* For details, see http://www.apache.org/licenses/LICENSE-2.0.
*/
select {
padding: 5px 10px;
border-color: #dcdcdc;
outline: none;
}
#wrapper {
width: 100%;
}
.manager-view {
height:100%;
width: calc(100% - 250px);
-webkit-width: calc(100% - 250px);
position: absolute;
right: 0;
background-color:#f5f5f5;
-webkit-transition: all .2s;
-moz-transition: all .2s;
-ms-transition: all .2s;
-o-transition: all .2s;
transition: all .2s;
}
.manager-view-inner {
height:calc(100% - 41px);
-webkit-height:calc(100% - 41px);
width:100%;
display: -webkit-flex;
display: flex;
-webkit-flex-direction: column;
flex-direction: column;
}
.manager-view-header {
/*width:100%;*/
/*width: calc(100% - 300px);*/
padding:10px;
background-color:#fff;
border-bottom:1px solid #ccc;
-webkit-flex-shrink: 0;
flex-shrink: 0;
position:relative;
z-index:1;
height: 43px;
}
.manager-view-content {
padding:35px 40px;
overflow:auto;
-webkit-flex-grow: 1;
flex-grow: 1;
}
.navbar-top-links {
margin-right: 0;
}
.navbar-top-links li {
display: inline-block;
}
.navbar-top-links li:last-child {
margin-right: 15px;
}
.navbar-top-links li a {
color:#fff;
cursor:pointer;
}
.navbar-top-links li>a:hover,
.navbar-top-links .open>a,
.navbar-top-links .open>a:hover,
.navbar-top-links .open>a:active,
.navbar-top-links .open>a:focus {
background-color:#9A1026;
}
.navbar-top-links .dropdown-menu li.divider {
margin:0;
}
.navbar-top-links .dropdown-menu li a:hover {
background-color:#fcfcfc;
}
.navbar-top-links .open>a,
.navbar-top-links .open>a:hover {
border-color:#9A1026;
}
.navbar-top-links .dropdown-menu li {
display: block;
}
.navbar-top-links .dropdown-menu li:last-child {
margin-right: 0;
}
.navbar-top-links .dropdown-menu li a {
padding: 10px 20px;
min-height: 0;
color:#444;
}
.navbar-top-links .dropdown-menu li a div {
white-space: normal;
}
.navbar-top-links .dropdown-messages,
.navbar-top-links .dropdown-tasks,
.navbar-top-links .dropdown-alerts {
width: 310px;
min-width: 0;
}
.navbar-top-links .dropdown-messages {
margin-left: 5px;
}
.navbar-top-links .dropdown-tasks {
margin-left: -59px;
}
.navbar-top-links .dropdown-alerts {
margin-left: -123px;
}
.navbar-top-links .dropdown-user {
right: 0;
left: auto;
}
.sidebar {
background-color:#fff;
border-right: 1px solid #ccc;
-webkit-transition: all .2s;
-moz-transition: all .2s;
-ms-transition: all .2s;
-o-transition: all .2s;
transition: all .2s;
}
.sidebar .fa {
font-size:18px;
margin-right:10px;
}
.sidebar span.menu-text {
display:inline-block;
}
.sidebar .sidebar-nav.navbar-collapse {
padding-right: 0;
padding-left: 0;
}
.sidebar .sidebar-search {
padding: 15px;
}
.sidebar ul li {
font-family: 'robotomedium';
letter-spacing: 0.2px;
border-bottom: 1px solid #DCDCDC;
}
.sidebar ul li a {
height:40px;
overflow:hidden;
}
.sidebar ul li a.active {
background-color: #eee;
}
.sidebar .arrow {
float: right;
}
.sidebar .fa.arrow:before {
content: "\f104";
}
.sidebar .active>a>.fa.arrow:before {
content: "\f107";
}
.sidebar .nav-second-level li,
.sidebar .nav-third-level li {
border-bottom: 0!important;
}
.sidebar .nav-second-level li a {
padding-left: 37px;
}
.sidebar .nav-third-level li a {
padding-left: 52px;
font-size: 12px;
}
.sidebar-person-info {
overflow-x: visible;
overflow-y: auto;
position: absolute;
width: 100%;
max-height: calc(85% - 139px);
background: #fff;
/*display:none;*/ /** angular template will hndle this */
}
.sidebar-person-info .identity {
color:#555;
padding:15px;
padding-bottom: 0px;
}
.sidebar-person-info .identity-header {
border-bottom: 1px solid #ECECEC;
}
.sidebar-person-info .identity-info {
margin-top:10px;
color: #6D6D6D;
border-bottom: 1px solid #ECECEC;
}
.sidebar-person-info .identity-info div {
margin-bottom:4px;
}
.sidebar-person-info .identity-info div div {
float:left;
width:80%;
}
.sidebar-person-info .identity-info span {
float:left;
width:27px;
margin-top: 3px;
}
.sidebar-person-info .identity img {
width:50px;
height:50px;
border-radius:100%;
margin:10px auto;
float:left;
margin-right:10px;
}
.sidebar-person-info .identity p.identity-name {
font-family:'robotomedium';
font-size:16px;
margin-bottom: 0;
margin-top:13px;
}
.sidebar-person-info .identity p.identity-surname {
font-family:'robotomedium';
font-size:16px;
margin-bottom: 0;
text-transform:uppercase;
}
.sidebar-person-info .identity p.identity-email {
float:left;
}
.sidebar-person-info .identity ul {
margin:0;
padding:0;
}
.sidebar-person-info .identity ul li {
list-style:none;
border:none;
}
.sidebar-person-info .person-actions {
}
.sidebar-person-info .person-actions ul {
margin:0;
padding:0;
}
.sidebar-person-info .person-actions ul li {
list-style:none;
border:none;
}
.sidebar-person-info .person-actions ul li a {
text-decoration:none;
color:#555;
display:block;
padding:10px 15px;
font-family: 'robotobold';
}
.sidebar-person-info .person-actions ul li a:hover {
background-color:#f5f5f5;
}
.sidebar-person-info .person-actions ul li a span {
margin-right:13px;
}
.sidebar-person-info .close-sidebar-person-info {
width: 45%;
margin-left: auto;
margin-right: auto;
margin-top: 11px;
border-radius: 5px;
padding: 8px 10px;
text-align: center;
cursor: pointer;
-webkit-transition: all .2s;
-moz-transition: all .2s;
-ms-transition: all .2s;
-o-transition: all .2s;
transition: all .2s;
background-color: #B93939;
color: #fff;
display:block;
}
.sidebar-person-info .close-sidebar-person-info:hover {
background-color:#9A1026;
}
.sidebar-person-info .close-sidebar-person-info span {
font-size: 12px;
color: #555;
margin-right: 6px;
position: relative;
top: -1px;
}
.btn-outline {
color: inherit;
background-color: transparent;
transition: all .5s;
}
.btn-primary.btn-outline {
color: #428bca;
}
.btn-success.btn-outline {
color: #5cb85c;
}
.btn-info.btn-outline {
color: #5bc0de;
}
.btn-warning.btn-outline {
color: #f0ad4e;
}
.btn-danger.btn-outline {
color: #d9534f;
}
.btn-primary.btn-outline:hover,
.btn-success.btn-outline:hover,
.btn-info.btn-outline:hover,
.btn-warning.btn-outline:hover,
.btn-danger.btn-outline:hover {
color: #fff;
}
.chat {
margin: 0;
padding: 0;
list-style: none;
}
.chat li {
margin-bottom: 10px;
padding-bottom: 5px;
border-bottom: 1px dotted #999;
}
.chat li.left .chat-body {
margin-left: 60px;
}
.chat li.right .chat-body {
margin-right: 60px;
}
.chat li .chat-body p {
margin: 0;
}
.panel .slidedown .glyphicon,
.chat .glyphicon {
margin-right: 5px;
}
.chat-panel .panel-body {
height: 350px;
overflow-y: scroll;
}
.login-panel {
margin-top: 25%;
}
.flot-chart {
display: block;
height: 400px;
}
.flot-chart-content {
width: 100%;
height: 100%;
}
.dataTables_wrapper {
position: relative;
clear: both;
}
table.dataTable thead .sorting,
table.dataTable thead .sorting_asc,
table.dataTable thead .sorting_desc,
table.dataTable thead .sorting_asc_disabled,
table.dataTable thead .sorting_desc_disabled {
background: 0 0;
}
table.dataTable thead .sorting_asc:after {
content: "\f0de";
float: right;
font-family: fontawesome;
}
table.dataTable thead .sorting_desc:after {
content: "\f0dd";
float: right;
font-family: fontawesome;
}
table.dataTable thead .sorting:after {
content: "\f0dc";
float: right;
font-family: fontawesome;
color: rgba(50,50,50,.5);
}
.btn-circle {
width: 30px;
height: 30px;
padding: 6px 0;
border-radius: 15px;
text-align: center;
font-size: 12px;
line-height: 1.428571429;
}
.btn-circle.btn-lg {
width: 50px;
height: 50px;
padding: 10px 16px;
border-radius: 25px;
font-size: 18px;
line-height: 1.33;
}
.btn-circle.btn-xl {
width: 70px;
height: 70px;
padding: 10px 16px;
border-radius: 35px;
font-size: 24px;
line-height: 1.33;
}
.show-grid [class^=col-] {
padding-top: 10px;
padding-bottom: 10px;
border: 1px solid #ddd;
background-color: #eee!important;
}
.show-grid {
margin: 15px 0;
}
.huge {
font-size: 40px;
}
.panel-green {
border-color: #5cb85c;
}
.panel-green .panel-heading {
border-color: #5cb85c;
color: #fff;
background-color: #5cb85c;
}
.panel-green a {
color: #5cb85c;
}
.panel-green a:hover {
color: #3d8b3d;
}
.panel-red {
border-color: #d9534f;
}
.panel-red .panel-heading {
border-color: #d9534f;
color: #fff;
background-color: #d9534f;
}
.panel-red a {
color: #d9534f;
}
.panel-red a:hover {
color: #b52b27;
}
.panel-yellow {
border-color: #f0ad4e;
}
.panel-yellow .panel-heading {
border-color: #f0ad4e;
color: #fff;
background-color: #f0ad4e;
}
.panel-yellow a {
color: #f0ad4e;
}
.panel-yellow a:hover {
color: #df8a13;
}
.timeline {
position: relative;
padding: 20px 0 20px;
list-style: none;
}
.timeline:before {
content: " ";
position: absolute;
top: 0;
bottom: 0;
left: 50%;
width: 3px;
margin-left: -1.5px;
background-color: #eeeeee;
}
.timeline > li {
position: relative;
margin-bottom: 20px;
}
.timeline > li:before,
.timeline > li:after {
content: " ";
display: table;
}
.timeline > li:after {
clear: both;
}
.timeline > li:before,
.timeline > li:after {
content: " ";
display: table;
}
.timeline > li:after {
clear: both;
}
.timeline > li > .timeline-panel {
float: left;
position: relative;
width: 46%;
padding: 20px;
border: 1px solid #d4d4d4;
border-radius: 2px;
-webkit-box-shadow: 0 1px 6px rgba(0, 0, 0, 0.175);
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.175);
}
.timeline > li > .timeline-panel:before {
content: " ";
display: inline-block;
position: absolute;
top: 26px;
right: -15px;
border-top: 15px solid transparent;
border-right: 0 solid #ccc;
border-bottom: 15px solid transparent;
border-left: 15px solid #ccc;
}
.timeline > li > .timeline-panel:after {
content: " ";
display: inline-block;
position: absolute;
top: 27px;
right: -14px;
border-top: 14px solid transparent;
border-right: 0 solid #fff;
border-bottom: 14px solid transparent;
border-left: 14px solid #fff;
}
.timeline > li > .timeline-badge {
z-index: 100;
position: absolute;
top: 16px;
left: 50%;
width: 50px;
height: 50px;
margin-left: -25px;
border-radius: 50% 50% 50% 50%;
text-align: center;
font-size: 1.4em;
line-height: 50px;
color: #fff;
background-color: #999999;
}
.timeline > li.timeline-inverted > .timeline-panel {
float: right;
}
.timeline > li.timeline-inverted > .timeline-panel:before {
right: auto;
left: -15px;
border-right-width: 15px;
border-left-width: 0;
}
.timeline > li.timeline-inverted > .timeline-panel:after {
right: auto;
left: -14px;
border-right-width: 14px;
border-left-width: 0;
}
.timeline-badge.primary {
background-color: #2e6da4 !important;
}
.timeline-badge.success {
background-color: #3f903f !important;
}
.timeline-badge.warning {
background-color: #f0ad4e !important;
}
.timeline-badge.danger {
background-color: #d9534f !important;
}
.timeline-badge.info {
background-color: #5bc0de !important;
}
.timeline-title {
margin-top: 0;
color: inherit;
}
.timeline-body > p,
.timeline-body > ul {
margin-bottom: 0;
}
.timeline-body > p + p {
margin-top: 5px;
}
/* DASHBOARD */
.dashboard .row {
margin-bottom:30px;
}
.dashboard .major-buttons {
margin-bottom:20px;
}
.dashboard .major-buttons i {
margin-right:10px;
}
.dashboard .major-buttons a button {
width:100%;
height:100px;
font-size: 19px;
font-family: 'robotolight';
}
.dashboard .major-buttons a button:focus {
color:#fff;
}
.dashboard-main-search {
width: calc(100% - 300px);
}
.dashboard-main-search .dashboard-student-search h3,
.dashboard-main-search .dashboard-personnel-search h3 {
font-family: 'robotoblack';
color: #5A5A5A;
letter-spacing: 1px;
}
.dashboard-main-search input {
width: 70%;
border-radius: 3px;
border: 1px solid #e0e0e0;
padding: 7px;
outline: none;
border-right: none;
border-bottom-right-radius: 0;
border-top-right-radius: 0;
}
.dashboard-main-search .fa {
padding: 10px 15px;
border: 1px solid #e0e0e0;
border-bottom-right-radius: 3px;
border-top-right-radius: 3px;
background-color: #FBF9F9;
cursor:pointer;
color:#5A5A5A;
}
.dashboard-student-search {
float: left;
width: 50%;
border-right: 1px solid #e8e8e8;
}
.dashboard-personnel-search {
float: left;
width: 50%;
}
.dashboard-search-results {
width: 80%;
margin-left: auto;
margin-right: auto;
margin-top: 25px;
}
.dashboard-search-results ul {
max-height: 600px;
overflow-y: auto;
padding:0;
webkit-box-shadow: 0 0 4px rgba(0,0,0,0.15);
-moz-box-shadow: 0 0 4px rgba(0,0,0,0.15);
box-shadow: 0 0 4px rgba(0,0,0,0.15);
background-color: #fff;
border-radius: 3px;
}
.dashboard-search-results ul li {
list-style:none;
border-bottom: 1px solid #F3F3F3;
}
.dashboard-search-results ul li:last-child {
border:none;
}
.dashboard-search-results ul li a {
color:#666;
padding: 10px 25px;
display:block;
text-decoration:none;
}
.dashboard-search-results ul li a:hover {
background-color:#f5f5f5;
}
.dashboard-search-results ul li:first-child a:hover {
border-top-left-radius:3px;
border-top-right-radius:3px;
}
.dashboard-search-results ul li:last-child a:hover {
border-bottom-left-radius:3px;
border-bottom-right-radius:3px;
}
.right-sidebar {
width: 300px;
background-color: #FFFFFF;
border-left: 1px solid #ccc;
/*height: calc(100% - 140px);*/
height: calc(100% - 40px);
position: absolute;
top: 0px;
right: 0px;
overflow-y: auto;
}
.right-sidebar-box {
border-bottom: 1px solid #D0D0D0;
}
.right-sidebar-title {
border-bottom: 1px solid #D0D0D0;
padding: 10px;
background-color: #F3F3F3;
}
.right-sidebar-title h3 {
float: left;
margin: 0;
font-size: 16px;
color: #666;
font-weight: bold;
font-family: 'robotobold';
text-transform: uppercase;
line-height:normal;
}
.right-sidebar-title span a {
float: right;
color: #A61229;
text-decoration:none;
}
.right-sidebar-message-block {
border-bottom: 1px solid #F3F3F3;
}
.right-sidebar-message-block:last-child {
border-bottom:none;
}
.right-sidebar-message-block a {
padding: 10px 15px;
display: block;
color: #555;
}
.right-sidebar-message-block a:hover{
background-color:#f5f5f5;
}
.right-sidebar-message-block a img {
width: 30px;
height: 30px;
border-radius: 100%;
float: left;
}
.right-sidebar-message-content {
float: left;
margin-left: 15px;
position:relative;
width: calc(100% - 50px);
}
.right-sidebar-message-content div:nth-child(1) {
width: 180px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
font-family: 'robotomedium';
font-size: 15px;
margin-top: -5px;
}
.right-sidebar-message-content div:nth-child(2) {
width: 180px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
margin-top: -5px;
}
.right-sidebar-message-content div:nth-child(3) {
color: #8C8C8C;
position: absolute;
right: 0;
top: 5px;
}
.right-sidebar-task-block a {
padding: 10px 25px;
display: block;
color: #555;
text-decoration:none;
}
.right-sidebar-task-block a:hover {
background-color:#f5f5f5;
}
.right-sidebar-task-block .task-type {
padding: 5px 10px;
font-size: 15px;
font-family: 'robotomedium';
color: #666;
}
.right-sidebar-task-block .progress {
margin-top: 5px;
margin-bottom: 0;
}
.right-sidebar-task-block .progress .progress-bar {
background-color: #A61229;
}
.right-sidebar-announcement-block a,
.right-sidebar-last-action-block a {
width: 100%;
display: block;
padding: 7px 15px;
color:#555;
text-decoration:none;
border-bottom: 1px solid #f3f3f3;
}
.right-sidebar-announcement-block a:hover,
.right-sidebar-last-action-block a:hover {
background-color:#f5f5f5;
}
/* END OF DASHBOARD */
/* PERSONNEL INFO */
.generic-profile-picture img {
width:220px;
height:220px;
}
.personnel-info-container {
width:1000px;
height:530px;
margin-left:auto;
margin-right:auto;
margin-bottom:50px;
background-color:#fff;
-webkit-box-shadow: 0 0 3px rgba(0,0,0,0.1);
-moz-box-shadow: 0 0 3px rgba(0,0,0,0.1);
box-shadow: 0 0 3px rgba(0,0,0,0.1);
position:relative;
}
.personnel-info-left {
width:250px;
height:100%;
background-color:#fcfcfc;
padding:15px;
position:absolute;
left:0;
overflow-y: auto;
overflow-x: hidden;
border-right: 1px solid #F7F7F7;
}
.personnel-info-left ul {
padding:0;
margin-top:20px;
}
.personnel-info-left ul li {
list-style:none;
margin-bottom:15px;
position:relative;
padding-left:30px;
color:#555;
}
.personnel-info-left ul li:nth-child(1) {
padding:0;
font-family:'robotobold';
font-size:18px;
color:#333;
}
.personnel-info-left ul li:nth-child(2) {
padding:0;
font-family:'robotomedium';
font-size:17px;
color:#666;
}
.personnel-info-left ul li i.fa {
width:18px;
margin-right:15px;
font-size:18px;
position:absolute;
left:0;
text-align:center;
}
.personnel-info-right {
width:750px;
height:100%;
background-color:#fff;
padding:40px;
padding-top:15px;
position:absolute;
right:0;
overflow-y:auto;
}
.personnel-info-right h2 {
margin-top:0;
margin-bottom:20px;
font-family:'robotolight';
font-size:23px;
}
.info-block {
margin-bottom:70px;
}
.info-block:last-child {
margin-bottom:0px;
}
.info-block-body dt {
text-align:left;
font-family:'robotomedium';
font-weight:normal;
}
.info-block-body dl {
margin-bottom:10px;
color:#444;
}
.personnel-info-edit .personnel-info-left ul li {
padding-left:0;
}
/* END OF PERSONNEL INFO */
/* SIDEBAR COLLAPSE */
.sidebar-collapse-button {
width: 62px;
height: 41px;
float: left;
padding: 8px 16px;
cursor:pointer;
}
.sidebar-collapse-button:hover {
background-color:#9A1026;
}
.sidebar-collapse-button div {
width: 30px;
height: 2px;
background-color: #fff;
margin-top:5px;
border-radius:5px;
}
/* END OF SIDEBAR COLLAPSE */
/* Responsive: Portrait tablets and up */
@media screen and (min-width: 768px) {
/* Remove the padding we set earlier */
.header,
.marketing,
.footer {
padding-left: 0;
padding-right: 0;
}
/* Space out the masthead */
.header {
margin-bottom: 30px;
}
/* Remove the bottom border on the jumbotron for visual effect */
.jumbotron {
border-bottom: 0;
}
.sidebar {
z-index: 1;
position: absolute;
width: 250px;
height: 100%;
-webkit-box-shadow: 0 0 25px rgba(0,0,0,0.1);
-moz-box-shadow: 0 0 25px rgba(0,0,0,0.1);
box-shadow: 0 0 25px rgba(0,0,0,0.1);
}
.navbar-top-links .dropdown-messages,
.navbar-top-links .dropdown-tasks,
.navbar-top-links .dropdown-alerts {
margin-left: auto;
}
.container {
max-width: 730px;
}
.manager-view {
height:100%;
}
.sidebar .sidebar-nav.navbar-collapse {
overflow-x: visible;
overflow-y: auto;
position: absolute;
width: 100%;
max-height: calc(85% - 139px);
}
footer {
position: absolute;
bottom: 35px;
padding: 15px;
width:100%;
text-align:center;
}
footer span {
font-family:'robotobold';
color:#777;
}
}
@media (max-width: 767px) {
.manager-view {
width:100%;
}
ul.timeline:before {
left: 40px;
}
ul.timeline > li > .timeline-panel {
width: calc(100% - 90px);
width: -moz-calc(100% - 90px);
width: -webkit-calc(100% - 90px);
}
ul.timeline > li > .timeline-badge {
top: 16px;
left: 15px;
margin-left: 0;
}
ul.timeline > li > .timeline-panel {
float: right;
}
ul.timeline > li > .timeline-panel:before {
right: auto;
left: -15px;
border-right-width: 15px;
border-left-width: 0;
}
ul.timeline > li > .timeline-panel:after {
right: auto;
left: -14px;
border-right-width: 14px;
border-left-width: 0;
}
.sidebar {
width:100% !important;
}
.brand,
footer {
display:none;
}
.logo img {
width:200px;
margin-left:0;
}
.manager-view-content {
overflow:inherit;
}
body {
overflow:auto;
}
.sidebar-collapse-button {
display:none;
}
.right-sidebar {
display: none;
}
}
@media (max-width: 1350px) {
.personnel-info-container {
width:700px;
}
.personnel-info-right {
width:450px;
}
}
@media (max-width: 1000px) {
.personnel-info-container {
width:500px;
height:auto;
}
.personnel-info-left {
width:100%;
position:relative;
height:auto;
border:none;
}
.personnel-info-right {
width:100%;
position:relative;
height:auto;
}
.generic-profile-picture,
.personnel-info-left ul li:nth-child(1),
.personnel-info-left ul li:nth-child(2) {
text-align:center;
}
.generic-profile-picture img {
border-radius:100%;
}
}
@media (max-width: 560px) {
.personnel-info-container {
width: 350px;
}
}
@media (max-width: 991px) {
.dashboard .major-buttons a button {
margin-bottom:20px;
}
}
.tablescroll{
width: 100%;
overflow-x:scroll;
overflow-y:visible;
padding-bottom:1px;
}
.tablescrollfixleft {
position:absolute;
left:0;
top:auto;
}
.tablescrollfixleft {
position:absolute;
right:0;
top:auto;
}
/* loading bar */
.loadingbarfullsize{
z-index:10001;
position:fixed;
width:100%;
height:100%;
top: 0;
left: 0;
background: url('/img/loading_spinner.gif') rgba(0, 0, 3, 0.2) no-repeat center center;
background-size: 100px 100px;
}
/* page transitions */
.slide {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
.slide.ng-enter,
.slide.ng-leave {
-webkit-transition: all 1s ease;
transition: all 1s ease;
}
.slide.ng-enter {
left: 100%;
}
.slide.ng-enter-active {
left: 0;
}
.slide.ng-leave {
left: 0;
}
.slide.ng-leave-active {
left: -100%;
}
/* end page transitions */
.movetobottom {
margin-right: 10px !important;
}
\ No newline at end of file
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) {
reporters: ['progress', 'coverage'],
preprocessors: {
//'app/app.js': ['coverage'],
'app/app.js': ['coverage'],
'app/app_routes.js': ['coverage'],
'app/components/auth/*.js': ['coverage'],
'app/components/crud/*.js': ['coverage'],
'app/components/dashboard/*.js': ['coverage'],
......@@ -90,6 +91,7 @@ module.exports = function (config) {
lines: 60,
excludes: [
'app/components/uitemplates/*.js',
//'app/zetalib/interceptors.js'
]
}
},
......
......@@ -34,7 +34,10 @@
"grunt-karma": "~0.8.0",
"grunt-angular-gettext": "~2.1.0",
"git-branch": "*",
"phantomjs": "~1.9.18"
"phantomjs": "~1.9.18",
"dgeni": "*",
"dgeni-packages": "*",
"canonical-path": "*"
},
"scripts": {
"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