/**
* @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.
* @type {ng.$compileProvider|*}
*/
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 () {
$http.post(RESTURL.url + 'logout', {}).then(function () {
$rootScope.loggedInUser = false;
$location.path("/login");
});
});
}
};
})
/**
* @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
$scope.notifications = {1: [], 2: [], 3: [], 4: []};
angular.forEach(notifications, function (value, key) {
$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) {
$scope.groupNotifications(data.notifications);
$rootScope.$broadcast("notifications", $scope.notifications);
});
};
$scope.getNotifications();
// check notifications every 5 seconds
$interval(function () {
if ($cookies.get("notificate") == "on") {
$scope.getNotifications();
}
}, 5000);
/**
* 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) {
$scope.groupNotifications(data.notifications);
$rootScope.$broadcast("notifications", $scope.notifications);
});
};
// if markasread triggered outside the directive
$scope.$on("markasread", function (event, data) {
$scope.markAsRead(data);
});
}
};
})
/**
* @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 {
templateUrl: 'shared/templates/directives/search.html',
restrict: 'E',
replace: true,
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) {
$scope.$broadcast('schemaFormValidate');
if (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) {
// update objects item of page scope
$rootScope.$broadcast('updateObjects', data.objects);
});
}
};
}
};
})
/**
* @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 {
templateUrl: 'shared/templates/directives/sort.html',
restrict: 'E',
replace: true,
link: function ($scope) {
// titleMap will be list
$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) {
$scope.$broadcast('schemaFormValidate');
if (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);
}
}
}
};
})
/**
* @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',
restrict: 'E',
replace: true,
scope: {},
controller: function ($scope, $rootScope) {
$rootScope.collapsed = false;
$rootScope.sidebarPinned = $cookies.get('sidebarPinned') || 0;
$scope.collapseToggle = function () {
if ($window.innerWidth > '768') {
if ($rootScope.collapsed === false) {
jQuery(".sidebar").css("width", "62px");
jQuery(".manager-view").css("width", "calc(100% - 62px)");
$rootScope.collapsed = true;
$rootScope.sidebarPinned = 0;
$cookies.put('sidebarPinned', 0);
} else {
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 = false;
$rootScope.sidebarPinned = 1;
$cookies.put('sidebarPinned', 1);
}
}
};
$timeout(function () {
if ($cookies.get('sidebarPinned') === "0") {
$scope.collapseToggle();
}
});
}
};
})
/**
* @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',
replace: true,
link: function ($scope) {
$scope.style = 'width:calc(100% - 300px);';
$scope.$on('$routeChangeStart', function () {
$scope.style = $location.path() === '/dashboard' ? 'width:calc(100% - 300px);' : 'width:%100 !important;';
});
}
};
})
/**
* @memberof ulakbus
* @ngdoc directive
* @name breadcrumb
* @description Produces breadcrumb with related links
*/
.directive('headerBreadcrumb', function ($location) {
return {
templateUrl: 'shared/templates/directives/header-breadcrumb.html',
restrict: 'E',
replace: false,
link: function ($scope) {
$scope.goBack = function () {
$location.state();
}
}
};
})
/**
* @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',
restrict: 'E',
replace: true,
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) {
var postToApi = {model: 'Personel', cmd: 'show', id: data[1]};
//postToApi[data[0]]=data[1];
$http.get(RESTURL.url + 'ara/personel/' + data[1]).success(
function (data) {
}
);
})
}
};
})
/**
* @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',
restrict: 'E',
replace: true,
scope: {},
controller: function ($scope, $rootScope, $cookies, $route, $http, RESTURL, $log, $location, $window, $timeout) {
$scope.prepareMenu = function (menuItems) {
var newMenuItems = {};
angular.forEach(menuItems, function (value, key) {
angular.forEach(value, function (v, k) {
newMenuItems[k] = v;
});
});
return newMenuItems;
};
var sidebarmenu = $('#side-menu');
var sidebarUserMenu = $('#side-user-menu');
sidebarmenu.metisMenu();
$http.get(RESTURL.url + 'menu/')
.success(function (data) {
$scope.allMenuItems = angular.copy(data);
// regroup menu items based on their category
function reGroupMenuItems(items, baseCategory) {
var newItems = {};
angular.forEach(items, function (value, key) {
newItems[value.kategori] = newItems[value.kategori] || [];
value['baseCategory'] = baseCategory;
newItems[value.kategori].push(value);
});
return newItems;
}
angular.forEach($scope.allMenuItems, function (value, key) {
if (key !== 'current_user' && key !== 'settings') {
$scope.allMenuItems[key] = reGroupMenuItems(value, key);
}
});
// quick menus to dashboard via rootscope
$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);
// broadcast for authorized menu items, consume in dashboard to show search inputs and/or
// related items
$rootScope.$broadcast("authz", data);
$rootScope.searchInputs = data;
$rootScope.current_user = data.current_user;
if (data.ogrenci || data.personel) {
$rootScope.current_user.can_search = true;
}
$rootScope.settings = data.settings;
$scope.menuItems = $scope.prepareMenu({other: $scope.allMenuItems.other});
// if selecteduser on cookie then add related part to the menu
//if ($cookies.get("selectedUserType")) {
// $scope.menuItems[$cookies.get("selectedUserType")] = $scope.allMenuItems[$cookies.get("selectedUserType")];
//}
$timeout(function () {
sidebarmenu.metisMenu();
sidebarUserMenu.metisMenu();
});
});
// changing menu items by listening for broadcast
$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();
});
});
$scope.$on('selectedUser', function ($event, data) {
$scope.selectedUser = data;
});
$scope.deselectUser = function () {
delete $scope.selectedUser;
delete $scope.selectedMenuItems;
};
$scope.openSidebar = function () {
if ($window.innerWidth > '768') {
if ($rootScope.sidebarPinned === 0) {
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 = false;
}
}
};
$scope.closeSidebar = function () {
if ($window.innerWidth > '768') {
if ($rootScope.sidebarPinned === 0) {
jQuery(".sidebar").css("width", "62px");
jQuery(".manager-view").css("width", "calc(100% - 62px)");
$rootScope.collapsed = true;
}
}
};
$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;
}
};
// breadcrumb function changes breadcrumb items and itemlist must be list
$scope.breadcrumb = function (itemlist, $event) {
$rootScope.breadcrumblinks = itemlist;
};
$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',
restrict: 'E',
replace: true,
scope: {
'model': '=',
'comments': '@',
'number': '@',
'name': '@',
'colour': '@',
'details': '@',
'type': '@',
'goto': '@'
}
};
})
/**
* @memberof ulakbus
* @ngdoc directive
* @name notifications
* @description Holds notifications template with related rootscope items.
*/
.directive('notifications', function () {
return {
templateUrl: 'shared/templates/directives/notifications.html',
restrict: 'E',
replace: true
};
})
/**
* @memberof ulakbus
* @ngdoc directive
* @name msgbox
* @description Holds msgbox template with related rootscope items.
*/
.directive('msgbox', function () {
return {
templateUrl: 'shared/templates/directives/msgbox.html',
restrict: 'E',
replace: false
};
})
/**
* @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',
restrict: 'E',
replace: true,
link: function ($scope) {
$scope.$on('alertBox', function ($event, data) {
$timeout(function () {
delete $scope.alerts;
}, 5000);
$scope.alerts = [data];
});
}
};
})
/**
* @memberof ulakbus
* @ngdoc directive
* @name sidebarSearch
* @description unused for now
*/
.directive('sidebarSearch', function () {
return {
templateUrl: 'shared/templates/directives/sidebar-search.html',
restrict: 'E',
replace: true,
scope: {},
controller: function ($scope) {
$scope.selectedMenu = 'home';
}
};
})
/**
* @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: {
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]);
});
}
}
});