UNPKG

zettapi_client

Version:

Client side CRUD operations in angular to use with zettapi_server rest api to get started quickly in any CMS project

1,773 lines (1,528 loc) 214 kB
var app = angular.module('zapi', [ 'ngSanitize', 'ngAnimate', 'ui.bootstrap', 'blockUI', 'inform', 'chart.js', 'btford.socket-io', 'ngCsv', 'ngTable', 'selector', 'angularUtils.directives.dirPagination', 'angularMoment', 'ngIdle', 'pascalprecht.translate' ]).config(function (TitleProvider) { TitleProvider.enabled(false); }).provider('zapi', function (apiEntityMap) { var map = {}; var idle = false; return { getRoutes: function (param) { if (typeof map[param.entity] === 'undefined') return 'client/entity/entity.notfound.html'; if (typeof map[param.entity][param.action] === 'undefined') return 'client/entity/entity.notfound.html'; switch (param.action) { case 'edit': return 'client/entity/entity.edit.html'; case 'view': if (typeof param.id === 'undefined') return 'client/entity/entity.notfound.html'; return 'client/entity/entity.view.html'; case 'list': if (typeof param.id !== 'undefined') return 'client/entity/entity.notfound.html'; return 'client/entity/entity.list.html'; default: return 'client/entity/entity.notfound.html'; } }, setMap: function (entityMap) { map = apiEntityMap; for (var key in entityMap) { map[key] = entityMap[key]; } }, setIdle: function (state) { idle = state; }, $get: function () { return { entityMap: map, idle: idle }; } }; }); app.controller('entityCtrl', function ($entity, zapi, ErrorSvc, $page, mySocket, $window, $routeParams, $controller, $location, $scope, $uibModal, blockUI, inform, $route, NgTableParams, $translate) { //set scope variables $scope.table = { params: null }; $scope.console = null; $scope.entities = zapi.entityMap; $scope.entityName = $routeParams.entity; $scope.lookup = {}; $scope.items = []; $scope.item = {}; $scope.newFile = {}; //set scope functions $scope.add = function (item, beforeAdd, callback) { $translate('api.entity.sendData').then(function(text){ blockUI.start(text); }); var next = typeof beforeAdd === 'function' ? beforeAdd : skip; next(function (err) { if (err) return inform.add(err, { ttl: 2000, type: 'danger' }); $entity.add($routeParams.entity, item).then(function (response) { $translate([$scope.entity.title,'api.entity.newRecordSuccess','api.entity.editRecordSuccess']).then(function (translations) { if (item._id) inform.add(translations[$scope.entity.title] + translations['api.entity.newRecordSuccess'], { ttl: 2000, type: 'info' }); else inform.add(translations[$scope.entity.title] + translations['api.entity.editRecordSuccess'], { ttl: 2000, type: 'info' }); }); if (typeof callback === 'function') callback(); }).catch(function (response) { inform.add(response.data, { ttl: 2000, type: 'danger' }); if (typeof callback === 'function') callback(response.data); }).finally(function () { blockUI.stop(); }); }); }; $scope.remove = function (item) { $translate('api.entity.checkRemove').then(function(text){ blockUI.start(text); }); $entity.remove($routeParams.entity, item).then(function (response) { $translate([$scope.entity.title,'api.entity.deleteRecordSuccess']).then(function (translations) { inform.add(translations[$scope.entity.title] + translations['api.entity.deleteRecordSuccess'], { ttl: 2000, type: 'info' }); }); }).catch(function (response) { inform.add(response.error ? response.error : response.data, { ttl: 2000, type: 'danger' }); }).finally(function () { blockUI.stop(); }); }; $scope.openEdit = function (item) { if (!$scope.entity.modal) { var url = $location.path(); url = url.substring(0, url.lastIndexOf('/')) + '/edit'; if (item) { return $location.path(url + '/' + item._id); } else { return $location.path(url); } } setEdit(item); var modalInstance = $uibModal.open({ animation: true, templateUrl: 'client/entity/entity.modal.html', controller: 'entityModalCtrl', size: 'lg', backdrop: 'static', scope: $scope }); modalInstance.result.then(function (newItem) { //item added }, function () { $translate('api.entity.cancelRecord').then(function (text) { inform.add(text, { ttl: 2000, type: 'info' }); }); $scope.item = {}; }); }; $scope.validate = function () { if (typeof $scope.getError === 'function') { var response = $scope.getError($scope.item, $scope.items); if (response.disabled) { $scope.console = response.tooltip; return true; } } $scope.console = null; return false; }; $scope.unflattenArray = $entity.unflattenArray; $scope.flattenArray = $entity.flattenArray; $scope.applySearch = function (search) { var criteria = angular.copy(search.text); if (search.inverted) { criteria = "!" + criteria; } $scope.table.params.filter({ $: criteria }); }; //set private methods function get(entity, id, callback) { $translate('api.entity.getData').then(function(text){ blockUI.start(text); }); getLookups($scope.lookup, function (err, lookups) { if (err) { $translate('api.entity.errorData').then(function (text) { inform.add(text, { ttl: 2000, type: 'danger' }); }); blockUI.stop(); return callback(err); } $scope.lookup = lookups; //if user is creating a new record if (!$routeParams.id && $routeParams.action === 'edit') { blockUI.stop(); return callback(); } $entity.get(entity, id).then(function (response) { if (id) { $scope.item = response.data; } else { $scope.items = response.data; $scope.table.params = new NgTableParams({}, { dataset: $scope.items }); } }).catch(function (response) { $translate('api.entity.errorData').then(function (text) { inform.add(text, { ttl: 2000, type: 'danger' }); }); }).finally(function () { blockUI.stop(); callback(); }); }); } function getLookups(lookup, callback) { if (lookup) { if (lookup.length) return callback(null, lookup); } $entity.getLookups($routeParams.entity, function (err, data) { if (err) return callback(err); callback(null, data); }); } function setEdit(item) { if (item) { $scope.item = angular.copy(item); } else { $scope.item = typeof $scope.blank === 'function' ? $scope.blank() : {}; } } function loadFinished() { //inject child controller try { $controller($routeParams.entity + 'Ctrl', { $scope: $scope }); } catch (err) { console.log(err); } var websocket; if (typeof zapi.entityMap[$routeParams.entity].websocket === 'undefined') { websocket = $routeParams.entity; } else { websocket = eval(zapi.entityMap[$routeParams.entity].websocket) + "." + $routeParams.entity; } mySocket.on(websocket + '.remove', onThisEntityRemove); mySocket.on(websocket + '.new', onThisEntityAdd); mySocket.on(websocket + '.edit', onThisEntityEdit); } function onThisEntityAdd(data) { switch ($routeParams.action) { case 'list': $scope.items.unshift(data); $scope.table.params.reload(); break; } //todo update lookup } function onThisEntityEdit(data) { switch ($routeParams.action) { case 'list': for (var i = 0; i < $scope.items.length; i++) { if ($scope.items[i]._id === data._id) { $scope.items[i] = data; $scope.table.params.reload(); break; } } break; case 'view': case 'edit': if ($scope.item._id === data._id) { $scope.item = data; $scope.table.params.reload(); } break; } //todo update lookup } function onThisEntityRemove(data) { switch ($routeParams.action) { case 'list': for (var i = 0; i < $scope.items.length; i++) { if ($scope.items[i]._id === data) { $scope.items.splice(i, 1); $scope.table.params.reload(); break; } } break; case 'view': case 'edit': if ($scope.item._id === data._id) { $location.path('/' + $routeParams.entity + '/list'); } break; } //todo update lookup } //initialization function initialize(callback) { $translate('api.entity.whereyougo').then(function (text) { $page.setTitle(text); }); $scope.entity = zapi.entityMap[$routeParams.entity]; if (!$scope.entity) { return; } switch ($routeParams.action) { case 'edit': if (!$routeParams.id) { $translate([$scope.entity.title, 'api.entity.newRecord']).then(function (translations) { $page.setTitle(translations[$scope.entity.title] + "-" + translations['api.entity.newRecord']); }); get($routeParams.entity, null, callback); } else { $translate([$scope.entity.title, 'api.entity.editRecord']).then(function (translations) { $page.setTitle(translations[$scope.entity.title] + "-" + translations['api.entity.editRecord']); }); get($routeParams.entity, $routeParams.id, callback); } break; case 'view': if (!$routeParams.id) { return; } $translate([$scope.entity.title, 'api.entity.viewRecord']).then(function (translations) { $page.setTitle(translations[$scope.entity.title] + "-" + translations['api.entity.viewRecord']); }); get($routeParams.entity, $routeParams.id, callback); break; case 'list': if ($routeParams.id) { return; } $translate($scope.entity.title).then(function (title) { $page.setTitle(title); }); get($routeParams.entity, null, callback); break; default: return; } } function skip(callback) { callback(); } initialize(loadFinished); }); app.controller('entityModalCtrl', function ($uibModalInstance, $scope) { $scope.ok = function () { $scope.add($scope.item, $scope.onBeforeSave, function (err) { if (!err) $scope.$close($scope.item); }); }; $scope.cancel = function () { $scope.$dismiss('cancel'); }; }); app.controller('activityCtrl', function($scope) { }); app.controller('alertCtrl', function() { }); app.controller('countryCtrl', function ($scope) { }); app.controller('errorCtrl', function($scope, $modal) { $scope.openModal = $modal._open; }); app.controller('holidayCtrl', function (ErrorSvc, $scope, $holiday) { $scope.getError = function (holiday, holidays) { $scope.nextOccurrence = null; if (!holiday) { return ErrorSvc.validationArgs(true); } if (!holiday.name) { return ErrorSvc.validationArgs(true, "Introduza um nome do feriado"); } if (holiday.name.trim() === "") { return ErrorSvc.validationArgs(true, "Introduza um nome do feriado"); } for (var i = 0; i < holidays.length; i++) { if (holidays[i].name == holiday.name && holiday._id != holidays[i]._id) { return ErrorSvc.validationArgs(true, "Feriado já existente"); } } if (!holiday.date && !holiday.formula) { return ErrorSvc.validationArgs(true, "Impossivel calcular próxima ocorrência para este feriado"); } if (holiday.date) { var pattern = /^(?:(?:[12][0-9]|0[1-9])\/(02)|(?:30|[12][0-9]|0[1-9])\/(?:(?:0[469]|11))|(?:3[01]|[12][0-9]|0[1-9])\/(?:(?:0[13578]|1[02])))$/; if (!pattern.test(holiday.date)) { return ErrorSvc.validationArgs(true, "A data deve ser no formato dd/mm"); } } else if (holiday.formula) { try { var currentYear = new Date().getFullYear(); eval('my_function = ' + holiday.formula); var d = my_function(currentYear); if (Object.prototype.toString.call(d) === "[object Date]") { //it is a date if (isNaN(d.getTime())) { return ErrorSvc.validationArgs(true, "Data inválida"); } } else { return ErrorSvc.validationArgs(true, "Data inválida"); } } catch (err) { return ErrorSvc.validationArgs(true, "A formula que introduziu contém um erro: " + err); } } return ErrorSvc.validationArgs(false); }; $scope.items.forEach(function (item) { item.next = $holiday.calculateNextOccurrence(item); }); }); app.controller('maintenanceCtrl', function () { }); app.controller('messageCtrl', function ($scope, $modal) { $scope.openModal = $modal._open; }); app.controller('roleCtrl', function (ErrorSvc, $scope, $role) { $scope.permissions = {}; $role.getPermissions().then(function (response) { $scope.permissions = response.data; }); $scope.togglePermissions = function (value) { if (!$scope.item.permissions) { $scope.item.permissions = {}; } for (var entity in $scope.permissions) { if (!$scope.item.permissions[entity]) { $scope.item.permissions[entity] = {}; } for (var action in $scope.permissions[entity]) { if (action === 'label') { continue; } $scope.item.permissions[entity][action] = value; } } }; $scope.getError = function (role, roles) { if (!role) { return ErrorSvc.validationArgs(true); } if (!role.name) { return ErrorSvc.validationArgs(true, "Introduza um nome para o perfil de utilizador"); } if (role.name.trim() === "") { return ErrorSvc.validationArgs(true, "Introduza um nome para o perfil de utilizador"); } for (var i = 0; i < roles.length; i++) { if (roles[i].name == role.name && roles[i]._id != role._id) { return ErrorSvc.validationArgs(true, "Perfil de utilizador já existente"); } } return ErrorSvc.validationArgs(false); }; $scope.blank = function () { var permissions = {}; for (var entity in $scope.permissions) { permissions[entity] = {}; for (var action in $scope.permissions[entity]) { if (action === 'label') { continue; } permissions[entity][action] = true; } } return { name: "", approvalLevel: 0, admin: false, permissions: permissions }; }; }); //manage tasks Controller app.controller('taskCtrl', function ($scope, $date, ErrorSvc, $task, mySocket, blockUI) { $scope.taskTypes = []; $scope.getError = function (task, tasks) { if (!task) { return ErrorSvc.validationArgs(true); } if (!task.name) { return ErrorSvc.validationArgs(true, "Indique um nome para a tarefa"); } if (task.name.trim() === "") { return ErrorSvc.validationArgs(true, "Indique um nome para a tarefa"); } if (!task.type) { return ErrorSvc.validationArgs(true, "Escolha um tipo de tarefa"); } if (!task.criteria) { return ErrorSvc.validationArgs(true, "Complete o critério de periodicidade"); } if (!task.criteria.month) { return ErrorSvc.validationArgs(true, "Complete o critério de periodicidade"); } if (!task.criteria.monthday) { return ErrorSvc.validationArgs(true, "Complete o critério de periodicidade"); } if (!task.criteria.weekday) { return ErrorSvc.validationArgs(true, "Complete o critério de periodicidade"); } if (!task.criteria.hour) { return ErrorSvc.validationArgs(true, "Complete o critério de periodicidade"); } if (!task.criteria.minute) { return ErrorSvc.validationArgs(true, "Complete o critério de periodicidade"); } return ErrorSvc.validationArgs(false); }; $scope.formatDatetime = $date.formatDatetime; $scope.calculateTimespan = $date.calculateTimespan; $scope.toggleState = $task.toggleState; $scope.run = function (task) { $task.run(task) .then(function (response) { blockUI.start('A executar...'); }) .catch(function (response) { swal('Ocorreu um erro ao iniciar a tarefa manualmente.', response.data, 'error'); }); }; mySocket.on($scope.login._id, function(data) { swal('Tarefa executada com sucesso.', null, 'success'); blockUI.stop(); }); $task.getTypes(function (types) { $scope.taskTypes = types; }); }); app.controller('userCtrl', function($scope, $http, inform, ErrorSvc) { $scope.getError = function(user, users) { if (!user) { return ErrorSvc.validationArgs(true); } if (!user.username) { return ErrorSvc.validationArgs(true, "Introduza um username"); } if (user.username.trim() === "") { return ErrorSvc.validationArgs(true, "Introduza um username"); } if (!user.email) { return ErrorSvc.validationArgs(true, "Introduza um email"); } if (user.email.trim() === "") { return ErrorSvc.validationArgs(true, "Introduza um email"); } for (var i = 0; i < users.length; i++) { if (users[i].username == user.username && users[i]._id != user._id) { return ErrorSvc.validationArgs(true, "Utilizador já existente"); } } return ErrorSvc.validationArgs(false); }; }); app.controller('stackTraceCtrl', function($scope, $uibModalInstance, data) { $scope.item = data; $scope.cancel = function () { $uibModalInstance.dismiss({ type: $scope.type }); }; $scope.ok = function() { $uibModalInstance.close({ type: $scope.type }); }; }); app.controller('viewMsgCtrl', function($scope, $uibModalInstance, data) { $scope.item = data; $scope.cancel = function () { $uibModalInstance.dismiss({ type: $scope.type }); }; $scope.ok = function() { $uibModalInstance.close({ type: $scope.type }); }; }); app.controller('attachmentsCtrl', function() { }); app.controller('ccCtrl', function() { }); app.controller('emailCtrl', function() { }); app.controller('fromCtrl', function() { }); app.controller('toCtrl', function() { }); app.filter("dateFilter", function(moment) { return function(items, from, to) { if (!from || !to) { return items; } from = moment(from); to = moment(to); var result = []; for (var i = 0; i < items.length; i++) { var date = moment(items[i].data_pagamento); if (date >= from && date <= to) { result.push(items[i]); } } return result; }; }); app.filter('orderObjectBy', function () { return function (items, field, reverse) { var filtered = []; angular.forEach(items, function (item) { filtered.push(item); }); filtered.sort(function (a, b) { return (a[field] > b[field] ? 1 : -1); }); if (reverse) filtered.reverse(); return filtered; }; }); app.directive('zlActivation', function (zapiPath) { return { restrict: 'E', scope: true, replace: false, templateUrl: zapiPath + '/directives/activation/activation.html', controller: function ($scope, $auth, $location, $routeParams) { $scope.user = null; $auth.activateAccount($routeParams.code, function (err, user) { if (err) { return $location.path('/'); } $scope.user = user; }); $scope.changePassword = function (newPassword1, newPassword2) { $auth.changePassword($scope.user, newPassword1, newPassword2, function (err) { if (!err) { return $location.path('/'); } }); }; } }; }); app.directive('zlAddress', function (zapiPath) { return { restrict: 'E', scope: { item: '=', countries: '=' }, replace: false, templateUrl: zapiPath + '/directives/address/address.html', controller: function ($scope, $address, inform) { $scope.getAddressPT = function(zipcode) { $address.getAddressPT(zipcode, function (err, data) { if (err) { $scope.item.address = ""; $scope.item.city = ""; $scope.item.country = ""; $scope.item.district = ""; $scope.item.county = ""; $scope.item.locality = ""; return inform.add("Não foi possível completar o arruamento", { ttl: 2000, type: "warning" }); } $scope.item.address = data.address; $scope.item.city = data.city; $scope.item.country = data.country; $scope.item.district = data.district; $scope.item.county = data.county; $scope.item.locality = data.locality; $address.getCoordinates(zipcode, function (err, coords) { if (!err) { $scope.item.coords = coords; } }); }); }; $scope.validateZipcode = $address.validateZipcode; } }; }); app.directive('apiMenuItem', function (zapiPath) { return { restrict: 'E', scope: false, replace: true, templateUrl: zapiPath + '/directives/apiMenuItem/apiMenuItem.html', }; }); app.directive('console', function(zapiPath) { return { restrict: 'E', scope: true, replace: false, templateUrl: zapiPath + '/directives/console/console.html' }; }); app.directive('zlContainer', function(zapiPath) { return { restrict: 'E', replace: false, templateUrl: zapiPath + '/directives/container/container.html', scope: { entity: '@', item: '=', lookup: '=', label: '@', var: '@', key: '@', isVisible: '&?', isMovable: '@', noInsert: '@', removable: '@', approvalMaxLevel: '@' }, controller: function($scope, $rootScope, $controller, $timeout) { if ($scope.key) { $scope.newContainerItem = {}; } else { $scope.newContainerItem = ""; } $scope.append = function(newContainerItem) { append(newContainerItem, function(err) { if (err) { return swal("Atenção", err, "warning"); } //clear new container item fields if ($scope.key) { $scope.newContainerItem = {}; } else { $scope.newContainerItem = ""; } }); }; $scope.remove = function(containerItem) { var index = $scope.item[$scope.var].indexOf(containerItem); if (index != -1) { $scope.item[$scope.var].splice(index, 1); } }; $scope.validate = function(newContainerItem) { if (!newContainerItem) { return true; } if ($scope.key) { if (Object.keys(newContainerItem).length === 0 && JSON.stringify(newContainerItem) === JSON.stringify({})) { return true; } } if (typeof $scope.getError === 'function') { var response = $scope.getError(newContainerItem, $scope.item[$scope.var]); if (response.disabled) { $scope.console = response.tooltip; return true; } } $scope.console = null; return false; }; $scope.pushBack = function(index) { var _containerItem = $scope.item[$scope.var].splice(index, 1); $scope.item[$scope.var].splice(index - 1, 0, _containerItem[0]); }; $scope.pushForward = function(index) { var _containerItem = $scope.item[$scope.var].splice(index, 1); $scope.item[$scope.var].splice(index + 1, 0, _containerItem[0]); }; //$timeout is only ready after directive has fully loaded //this way when the controller loads, $scope will be fully populated $timeout(function() { //inject child controller $controller($scope.var + 'Ctrl', {$scope: $scope}); }); function append(newContainerItem, callback) { var i, property; if (!$scope.item[$scope.var]) { $scope.item[$scope.var] = []; } //check if containerItem is not empty if ($scope.key) { var key = { property: null, key: null }; if (newContainerItem[$scope.key]) { key.key = newContainerItem[$scope.key]; } else { for (property in newContainerItem) { if (newContainerItem[property][$scope.key]) { key.property = property; key.key = newContainerItem[property][$scope.key]; break; } } } if (key.key) { //check if containerItem already exists in container for (i = 0; i < $scope.item[$scope.var].length; i++) { var obj = key.property ? $scope.item[$scope.var][i][key.property] : $scope.item[$scope.var][i]; if (obj[$scope.key] === key.key) { return callback('Registo duplicado em ' + $scope.label); } } } } else { for (i = 0; i < $scope.item[$scope.var].length; i++) { if ($scope.item[$scope.var][i] === newContainerItem) { return callback('Registo duplicado em ' + $scope.label); } } } //append item to container $scope.item[$scope.var].unshift(newContainerItem); //approvable containers only if ($scope.approvalMaxLevel) { //assign approval if ($scope.approvalMaxLevel) { newContainerItem.approval = { level: $rootScope.login.role.approvalLevel, maxLevel: $scope.approvalMaxLevel }; } } callback(); } } }; }); app.directive("contenteditable", function() { return { require: "ngModel", link: function(scope, element, attrs, ngModel) { function read() { ngModel.$setViewValue(element.html()); } ngModel.$render = function() { element.html(ngModel.$viewValue || ""); }; element.bind("blur keyup change", function() { scope.$apply(read); }); } }; }); app.directive('zlCountry', function(zapiPath) { return { restrict: 'E', scope: { item: '=', 'var': '@', label: '@', lookup: '=' }, replace: false, templateUrl: zapiPath + '/directives/country/country.html' }; }); app.directive('zlFile', function(zapiPath) { return { restrict: 'A', scope: { item: '=', var: '=', docid: '=' }, replace: false, link: function (scope, element, attrs) { if (scope.docid) { if (scope.docid._id) { scope.docid = scope.docid._id; } } }, templateUrl: zapiPath + '/directives/document/file.html' }; }); app.directive('fileModel', function ($parse) { return { restrict: 'A', replace: false, link: function(scope, element, attrs) { var model = $parse(attrs.fileModel); var modelSetter = model.assign; element.bind('change', function() { scope.$apply(function() { modelSetter(scope, element[0].files[0]); }); }); } }; }); app.directive('zlDynamicField', function (zapiPath) { return { restrict: 'E', scope: { field: '=', value: '=' }, replace: false, template: '<div ng-include src="contentUrl" include-replace></div>', controller: function ($scope) { $scope.$watch('field.type', onFieldChange); function onFieldChange(newField) { if (!newField) return; var type = $scope.field.type || 'Unknown'; if ($scope.field.type === 'ObjectId' && typeof $scope.field.ref === 'undefined') { type = "String"; } $scope.contentUrl = zapiPath + "/directives/dynamicField/" + type + ".html"; } } }; }); app.directive('entityEdit', function(zapiPath) { return { restrict: 'E', scope: true, replace: false, link: function(scope, element, attrs) { var scaffoldUrl = scope.entity.custom ? 'client/entity/' : (zapiPath + '/entity/'); scope.contentUrl = scaffoldUrl + scope.entityName + '/' + scope.entityName + '.edit.html'; }, template: '<div ng-include="contentUrl"></div>' }; }); app.directive('entityList', function(zapiPath) { return { restrict: 'E', scope: true, replace: false, link: function(scope, element, attrs) { var scaffoldUrl = scope.entity.custom ? 'client/entity/' : (zapiPath + '/entity/'); scope.contentUrl = scaffoldUrl + scope.entityName + '/' + scope.entityName + '.list.html'; }, template: '<div ng-include src="contentUrl" include-replace></div>' }; }); app.directive('entityView', function(zapiPath) { return { restrict: 'E', scope: true, replace: false, link: function(scope, element, attrs) { var scaffoldUrl = scope.entity.custom ? 'client/entity/' : (zapiPath + 'entity/'); scope.contentUrl = scaffoldUrl + scope.entityName + '/' + scope.entityName + '.view.html'; }, template: '<div ng-include="contentUrl"></div>' }; }); app.directive('zlGraph', function (zapiPath) { return { restrict: 'E', scope: { item: '=', custom: '@?' }, replace: false, templateUrl: zapiPath + '/directives/graph/graph.html', controller: function ($scope, blockUI, $graph) { var chartTypes = [ ['bar', 'doughnut', 'pie', 'horizontalBar'], ['line', 'radar'], ['bubble', 'polar-area'] ]; $scope.getNext = function () { var index = chartTypes[$scope.item.dimension].indexOf($scope.item.type) + 1; return chartTypes[$scope.item.dimension][index === chartTypes[$scope.item.dimension].length ? 0 : index]; }; $scope.toggle = function () { $scope.item.type = $scope.getNext(); }; $scope.chart = {}; var graphBlockUI = blockUI.instances.get('graphBlockUI'); graphBlockUI.start("A criar gráfico..."); if (typeof $scope.custom === 'string') { var parts = $scope.custom.split('|'); $graph.custom(parts[0], parts[1], finished); } else { $graph.get( $scope.item.namespace, $scope.item.collection, $scope.item.query, $scope.item.obj, $scope.item.seriesKey, $scope.item.dataKey, $scope.item.labelsKey, finished ); } function finished(chart) { $scope.chart = chart; graphBlockUI.stop(); } } }; }); app.directive('zlIdle', function () { return { restrict: 'A', scope: true, controller: function ($scope, $location, $auth) { $scope.$on('IdleStart', function () { swal("Atenção", "Devido à sua inactividade irá ser disconectado em 5 segundos", "info"); }); $scope.$on('IdleEnd', function () { console.log('IdleEnd'); }); $scope.$on('IdleTimeout', function () { $auth.logout(); $location.path('/'); }); } }; }); app.directive('zlList', function (zapiPath) { return { restrict: 'E', scope: { dbs: '=', channel: '@' }, replace: false, templateUrl: zapiPath + '/directives/list/list.html', controller: function ($scope, $list, NgTableParams, $httpParamSerializer) { $scope.items = []; $scope.tableParams = null; $scope.list = { name: "", parameters: [], values: {} }; $scope.selectedDbs = []; $list.getMetadata(function (lists) { $scope.lists = lists; }); $scope.reset = function () { $scope.items = []; $scope.tableParams = null; }; $scope.get = function (list) { $list.get(list, $scope.selectedDbs, $scope.channel, function (items) { var initialParams = {}, params = { dataset: items }; if (list.group) { initialParams.group = list.group; } if (typeof list.groupOptions !== 'undefined') { params.groupOptions = list.groupOptions; } $scope.items = items; $scope.tableParams = new NgTableParams(initialParams, params); }); }; $scope.getExcelUrl = function (list) { return '/api/list/values/' + list.name + '?xls=1&' + $httpParamSerializer({ query: list.values, dbs: $scope.selectedDbs }); }; $scope.applySearch = function (search) { var criteria = angular.copy(search.text); if (search.inverted) { criteria = "!" + criteria; } $scope.tableParams.filter({ $: criteria }); }; } }; }); app.directive('zlLogin', function (zapiPath) { return { restrict: 'E', scope: true, replace: false, templateUrl: zapiPath + '/directives/login/login.html', controller: function (blockUI, $auth, $location, $scope, $uibModalStack) { $scope.login = function () { if ($scope.validateLogin()) { return; } $auth.login($scope.username, $scope.password, function (err) { if (err) { reset(); } else { $location.path('/profile'); $uibModalStack.dismissAll(); } }); }; $scope.validateLogin = function () { if (!$scope.username) { return true; } if (!$scope.password) { return true; } return false; }; function reset() { $scope.username = ""; $scope.password = ""; } } }; }); app.directive('zlMaintenance', function () { return { restrict: 'A', scope: true, controller: function (mySocket, $timeout) { mySocket.on('maintenance', function (data) { swal("Manutenção Programada", data, "info"); }); } }; }); app.directive('zlNewsletter', function (zapiPath, blockUI, inform, $entity) { return { restrict: 'E', scope: true, replace: false, templateUrl: zapiPath + '/directives/newsletter/newsletter.html', controller: function ($scope, $newsletter) { $scope.saveEmail = function (item) { $newsletter.subscribe(item, function () { $scope.newsItem = {}; }); }; } }; }); app.directive('asDate', function () { return { require: '^ngModel', restrict: 'A', link: function (scope, element, attrs, ctrl) { ctrl.$formatters.splice(0, ctrl.$formatters.length); ctrl.$parsers.splice(0, ctrl.$parsers.length); ctrl.$formatters.push(function (modelValue) { if (!modelValue) { return; } return new Date(modelValue).toISOString().slice(0,10); }); ctrl.$parsers.push(function (modelValue) { return modelValue; }); } }; }); app.directive('dlKeyCode', dlKeyCode); function dlKeyCode() { return { restrict: 'A', link: function($scope, $element, $attrs) { $element.bind("keypress", function(event) { var keyCode = event.which || event.keyCode; if (keyCode == $attrs.code) { $scope.$apply(function() { $scope.$eval($attrs.dlKeyCode, {$event: event}); }); } }); } }; } app.directive('asFloat', function () { return { require: '^ngModel', restrict: 'A', link: function (scope, element, attrs, ctrl) { ctrl.$formatters.splice(0, ctrl.$formatters.length); ctrl.$parsers.splice(0, ctrl.$parsers.length); ctrl.$formatters.push(function (modelValue) { if (!modelValue) { return; } return parseFloat(modelValue); }); ctrl.$parsers.push(function (modelValue) { return modelValue; }); } }; }); app.directive('asInteger', function () { return { require: '^ngModel', restrict: 'A', link: function (scope, element, attrs, ctrl) { ctrl.$formatters.splice(0, ctrl.$formatters.length); ctrl.$parsers.splice(0, ctrl.$parsers.length); ctrl.$formatters.push(function (modelValue) { if (!modelValue) { return; } return parseInt(modelValue); }); ctrl.$parsers.push(function (modelValue) { return modelValue; }); } }; }); app.directive('lettersOnly', function () { return { require: 'ngModel', link: function (scope, element, attr, ngModelCtrl) { function onlyLetters(text) { if (text) { var transformedInput = text.replace(/[^A-Za-z]/g, ''); if (transformedInput !== text) { ngModelCtrl.$setViewValue(transformedInput); ngModelCtrl.$render(); } return transformedInput; } return undefined; } if (attr.lettersOnly === 'true') { ngModelCtrl.$parsers.push(onlyLetters); } } }; }); app.directive('numbersOnly', function () { return { require: 'ngModel', link: function (scope, element, attr, ngModelCtrl) { function onlyNumbers(text) { if (text) { var transformedInput = text.replace(/[^0-9]/g, ''); if (transformedInput !== text) { ngModelCtrl.$setViewValue(transformedInput); ngModelCtrl.$render(); } return transformedInput; } return undefined; } if (attr.numbersOnly === 'true') { ngModelCtrl.$parsers.push(onlyNumbers); } } }; }); app.directive('zlQueryBuilder', function (zapiPath) { return { restrict: 'E', scope: { field: '=', value: '=' }, replace: false, template: '<div ng-include src="contentUrl" include-replace></div>', controller: function ($scope) { $scope.$watch('field.type', onFieldChange); function onFieldChange(newField) { if (!newField) return; var type = $scope.field.type || 'Unknown'; if ($scope.field.type === 'ObjectId' && typeof $scope.field.ref === 'undefined') { type = "String"; } $scope.contentUrl = zapiPath + "/directives/queryBuilder/" + type + ".html"; } } }; }); app.directive('zlReport', function (zapiPath) { return { restrict: 'E', scope: { field: '=', condition: '=' }, replace: false, templateUrl: zapiPath + '/directives/report/report.html', controller: function ($scope, $report) { $scope.metadata = {}; $scope.item = { type: 'exp', database: '', collection: '', query: [], select: {}, limit: 0, sort: {}, populate: '' }; $scope.map = { "id_animal": "Número SIA", "id_eletronico": "Brinco Electrónico", "sexo": "Sexo", "raca": "Raça", "data_nascimento": "Dt. Nascimento", "mae": "Mãe", "pai": "Pai", "tipo": "Aptidão", "fenotipo": "Fenotipo" }; $report.getMetadata(function (err, metadata) { $scope.metadata = metadata; }); $scope.appendQuery = function (fieldName, field) { $scope.item.query.push({ field: field, fieldName: fieldName }); }; } }; }); app.directive('zlReset', function (zapiPath) { return { restrict: 'E', scope: true, replace: false, templateUrl: zapiPath + '/directives/reset/reset.html', controller: function ($scope, $auth, $location, blockUI) { $scope.reset = function (item) { if ($scope.validateReset(item)) { return; } $auth.resetPassword(item.email, item.username, function (err) { if (!err) { return $location.path("/"); } }); }; $scope.validateReset = function (item) { if (!item) { return true; } if (!item.email) { return true; } if (!item.username) { return true; } return false; }; } }; }); app.directive('zlSignup', function (zapiPath) { return { restrict: 'E', scope: true, replace: false, templateUrl: zapiPath + '/directives/signup/signup.html', controller: function ($scope, blockUI, $entity, $uibModalStack) { $scope.signup = function (item) { if ($scope.validateSignup(item)) { return; } blockUI.start("A reservar conta..."); $entity.add('user', item) .then(function (response) { swal("Está quase!", "Consulte o seu email para ativar a conta de utilizador", "success"); $uibModalStack.dismissAll(); }) .catch(function (response) { swal("Erro", response.data, "error"); }) .finally(function () { blockUI.stop(); }); }; $scope.validateSignup = function (item) { if (!item) { return true; } if (!item.username) { return true; } var validUsername = new RegExp('^[a-zA-Z0-9.\-_$@*!]{3,30}$'); if (!validUsername.test(item.username)) { return true; } if (!item.email) { return true; } return false; }; } }; }); app.service('$address', function($http, blockUI) { this.getAddressPT = function(zipcode, callback) { if (this.validateZipcode(zipcode)) { return callback("Código postal inválido"); } blockUI.start('A procurar arruamento...'); $http.get("./api/address/pt/" + zipcode) .then(function(response) { callback(null, response.data); }) .catch(function(response) { callback(response); }) .finally(function() { blockUI.stop(); }); }; this.validateZipcode = function(zipcode) { if (!zipcode) { return true; } if (typeof zipcode !== 'string') { zipcode = zipcode + ''; } var cps = zipcode.split('-'); if (cps.length < 1 || cps.length > 2) { return true; } if (isNaN(cps[0])) { return true; } if (cps.length > 1) { if (isNaN(cps[1])) { return true; } } return false; }; this.getCoordinates = function(zipcode, callback) { try { var geocoder = new google.maps.Geocoder(); geocoder.geocode({ 'address': zipcode }, function (results, status) { if (status !== google.maps.GeocoderStatus.OK) { callback(status); } callback(null, { lat: results[0].geometry.location.lat(), lng: results[0].geometry.location.lng() }); }); } catch (error) { callback(error); } }; }); app.factory('$auth', function ($http, $crypto, blockUI, $location, anonymousPages, $rootScope, Idle, zapi, $translate) { var service = { currentUser: null, login: function (username, password, callback) { $translate('api.services.auth.loginLoad', function (text) { blockUI.start(text); }, function (translationId) { blockUI.start(translationId); }); return $http.post('/api/session/login/', { username: username, password: $crypto.md5(password) }).then(function (response) { if (zapi.idle) Idle.watch(); service.currentUser = response.data.user; callback(); }).catch(function (response) { $translate(['api.services.auth.loginErrorTitle', 'api.services.auth.loginErrorContent']).then(function (translations) { swal(translations['api.services.auth.loginErrorTitle'], translations['api.services.auth.loginErrorContent'], "error"); //swal(loginErrorTitle, response.data, "danger"); }, function (translationsId) { swal(translationsId.api_service_auth_loginerrortitle, translationsId.api_service_auth_loginerrorcontent, "error"); }); callback(true); }).finally(function () { blockUI.stop(); }); }, logout: function () { $http.get('/api/session/logout').then(function (response) { if (zapi.idle) Idle.unwatch(); service.currentUser = null; $rootScope.login = {}; $location.path('/'); }); }, requestCurrentUser: function (callback) { if (service.isAuthenticated()) return callback(null, service.currentUser); $http.get('/api/session/currentuser').then(function (response) { service.currentUser = response.data.user; callback(null, service.currentUser); }).catch(function (response) { service.currentUser = null; callback(response); }); }, isAuthenticated: function () { return !!service.currentUser; }, activateAccount: function (rawCode, callback) { if (!rawCode) return callback(true); var codes = rawCode.split('&'); if (codes.length !== 2) return callback(true); $translate('api.services.auth.activateAccountLoad', function (text) { blockUI.start(text); }, function (translationId) { blockUI.start(translationId); }); $http.post('/api/user/activate/', { email: codes[0], code: codes[1] }).then(function (response) { callback(null, response.data); }).catch(function (response) { $translate(['api.services.auth.activateAccountErrorTitle', 'api.services.auth.activateAccountErrorContent']).then(function (translations) { swal({ title: translations['api.services.auth.activateAccountErrorTitle'], text: translations['api.services.auth.activateAccountErrorContent'], type: "info", confirmButtonText: "OK" }); }, function (translationsId) { swal({ title: translationsId.api_service_auth_activateaccounterrortitle, text: translationsId.api_service_auth_activateaccounterrorcontent, type: "info", confirmButtonText: "OK" }); }); callback(true); }).finally(function () { blockUI.stop(); }); }, resetPassword: function (email, username, callback) { $translate('api.services.auth.resetPasswordLoad', function (text) { blockUI.start(text); }, function (translationId) { blockUI.start(translationId); }); return $http.post('/api/user/resetpassword/', { email: email, username: username }).then(function (response) { $translate(['api.services.auth.resetPasswordSuccessTitle', 'api.services.auth.resetPasswordSuccessContent']).then(function (translations) { swal(translations['api.services.auth.resetPasswordSuccessTitle'], translations['api.services.auth.resetPasswordSuccessContent'], "success"); }, function (translationsId) { swal(translationsId.api_service_auth_resetpasswordsuccesstitle, translationsId.api_service_auth_resetpasswordsuccesscontent, "success"); }); callback(); }).catch(function (response) { $translate(['api.services.auth.resetPasswordErrorTitle', 'api.services.auth.resetPasswordErrorContent']).then(function (translations) { swal(translations['api.services.auth.resetPasswordErrorTitle'], translations['api.services.auth.resetPasswordErrorContent'], "error"); }, function (translationsId) { swal(translationsId.api_service_auth_resetpassworderrortitle, translationsId.api_service_auth_resetpassworderrorcontent, "error"); }); callback(true); }).finally(function () { blockUI.stop(); }); }, changePassword: function (user, newPassword1, newPassword2, callback) { if (!newPassword1) return; if (newPassword1 !== newPassword2) { $translate(['api.services.auth.changepasswordWrongPasswordTitle', 'api.services.auth.changepasswordWrongPasswordContent']).then(function (translations) { swal(translations['api.services.auth.changepasswordWrongPasswordTitle'], translations['api.services.auth.changepasswordWrongPasswordContent'], "error"); }, function (translationsId) { swal(