├── 00-html-puro └── index.html ├── 01-Mira-mama-sin-JavaScript └── index.html ├── 02-Control-en-JavaScript ├── app.js ├── cajaCtrl.js └── index.html ├── 03-dos-controladores ├── app.js ├── cajaCtrl.js ├── index.html └── menuCtrl.js ├── 04-tres-vistas-y-un-controlador-spa1 ├── app.js ├── cajaCtrl.js ├── index.html ├── lista.html ├── menuCtrl.js ├── nuevo.html └── total.html ├── 05-tres-vistas-un-controladory-una-factoria-spa2 ├── app.js ├── cajaCtrl.js ├── index.html ├── lista.html ├── menuCtrl.js ├── movimientosFactory.js ├── nuevo.html └── total.html ├── 06-ui-una-ruta-mejor ├── app.js ├── cajaCtrl.js ├── index.html ├── lista.html ├── menuCtrl.js ├── movimientosFactory.js ├── not-found.html ├── nuevo.html └── total.html ├── 07-hola-mundo-nodejs ├── 1-mi-script.js ├── 2-javascript-normal-2.js ├── 3-patrones.js ├── 4-el-proceso.js └── hola-mundo.md ├── 08-nodejs-y-la-consola ├── 1-consola-argumentos.js ├── 2-trabajo-consola-asincrona.js ├── 3-consola-con-callbacks.js └── consola.md ├── 09-nodejs-y-la-web ├── 1-http.js ├── 2-web.js ├── 3-static.js ├── 4-control-caja │ ├── client │ │ ├── app.js │ │ ├── cajaCtrl.js │ │ ├── index.html │ │ ├── lista.html │ │ ├── menuCtrl.js │ │ ├── movimientosFactory.js │ │ ├── not-found.html │ │ ├── nuevo.html │ │ └── total.html │ └── server.js ├── static │ ├── blog.html │ ├── estilo.css │ └── simple.html └── web.md ├── 10-nodejs-promesas-y-modulos ├── 1-modulos-propios │ ├── 1-app.js │ ├── cuenta.js │ └── mates.js ├── 2-operaciones-lentas │ ├── 2-1-callback.js │ ├── 2-2-promesas.js │ └── package.json └── pro.md ├── 11-express ├── 1-hola-express.js ├── 2-middleware.js ├── express.md ├── package.json └── static │ └── simple.html ├── 12-rutas-con-express ├── 1-rutas.js ├── 2-parametros │ ├── mates.js │ └── parametros.js ├── package.json └── rutas.md ├── 13-api-restfull-con-express ├── 1-rest-crud.js ├── API-REST.md └── package.json ├── 14-rest-in-peace ├── client │ ├── app.js │ ├── cajaCtrl.js │ ├── index.html │ ├── lista.html │ ├── menuCtrl.js │ ├── movimientosFactory.js │ ├── not-found.html │ ├── nuevo.html │ └── total.html ├── package.json └── server.js ├── 15-rest-assured ├── client │ ├── app.js │ ├── appSecurity.js │ ├── cajaCtrl.js │ ├── index.html │ ├── lista.html │ ├── maestrosFactory.js │ ├── menuCtrl.js │ ├── movimientosFactory.js │ ├── not-found.html │ ├── nuevo.html │ ├── registro.html │ ├── registroCtrl.js │ └── total.html ├── package.json └── server.js ├── 16-rest-sources ├── client │ ├── app.js │ ├── appSecurity.js │ ├── cajaCtrl.js │ ├── index.html │ ├── lista.html │ ├── maestrosFactory.js │ ├── menuCtrl.js │ ├── movimientosFactory.js │ ├── not-found.html │ ├── nuevo.html │ ├── registro.html │ ├── registroCtrl.js │ └── total.html ├── package.json └── server.js ├── 17-rest-advance ├── client │ ├── app.js │ ├── appHttpLog.js │ ├── appSecurity.js │ ├── cajaCtrl.js │ ├── index.html │ ├── lista.html │ ├── maestrosFactory.js │ ├── menuCtrl.js │ ├── movimiento.html │ ├── movimientoCtrl.js │ ├── movimientosFactory.js │ ├── not-found.html │ ├── nuevo.html │ ├── registro.html │ ├── registroCtrl.js │ └── total.html ├── package.json └── server.js ├── 18-angular-con-filtro ├── client │ ├── app.js │ ├── appHttpLog.js │ ├── appSecurity.js │ ├── cajaCtrl.js │ ├── filtros.js │ ├── index.html │ ├── lista.html │ ├── maestrosFactory.js │ ├── menuCtrl.js │ ├── movimiento.html │ ├── movimientoCtrl.js │ ├── movimientosFactory.js │ ├── not-found.html │ ├── nuevo.html │ ├── registro.html │ ├── registroCtrl.js │ └── total.html ├── cors.md ├── package.json └── server.js ├── 19-directivas ├── client │ ├── app.js │ ├── appHttpLog.js │ ├── appSecurity.js │ ├── cajaCtrl.js │ ├── directivas.js │ ├── filtros.js │ ├── index.html │ ├── lista.html │ ├── maestrosFactory.js │ ├── menuCtrl.js │ ├── movimiento.html │ ├── movimientoCtrl.js │ ├── movimientosFactory.js │ ├── not-found.html │ ├── nuevo.html │ ├── registro.html │ ├── registroCtrl.js │ ├── total.html │ ├── tpl-cabecera.html │ ├── tpl-fila-movimiento.html │ ├── tpl-valoracion.html │ └── valoracion.js ├── directivas.md ├── package.json ├── recursos.md └── server.js ├── 20-e2e ├── Protractor.pdf ├── conf.js ├── index │ ├── conf.js │ └── spec.js ├── ingreso │ ├── conf.js │ └── spec.js └── registro │ ├── conf.js │ └── spec.js ├── 21-organizacion ├── client │ ├── app.js │ ├── appHttpLog.js │ ├── appSecurity.js │ ├── cajaCtrl.js │ ├── directivas.js │ ├── filtros.js │ ├── index.html │ ├── lista.html │ ├── maestrosFactory.js │ ├── menuCtrl.js │ ├── movimiento.html │ ├── movimientoCtrl.js │ ├── movimientosFactory.js │ ├── not-found.html │ ├── nuevo.html │ ├── registro.html │ ├── registroCtrl.js │ ├── total.html │ ├── tpl-cabecera.html │ ├── tpl-fila-movimiento.html │ ├── tpl-valoracion.html │ └── valoracion.js ├── package.json ├── recursos.md └── server.js ├── 21b-organizacion ├── client │ ├── _comun │ │ ├── app.js │ │ ├── appHttpLog.js │ │ ├── appSecurity.js │ │ ├── menuCtrl.js │ │ └── not-found.html │ ├── controlcaja │ │ ├── cajaCtrl.js │ │ ├── lista.html │ │ ├── nuevo.html │ │ └── total.html │ ├── data │ │ ├── maestrosFactory.js │ │ └── movimientosFactory.js │ ├── directivas │ │ ├── directivas.js │ │ ├── tpl-cabecera.html │ │ ├── tpl-fila-movimiento.html │ │ └── valoracion │ │ │ ├── tpl-valoracion.html │ │ │ └── valoracion.js │ ├── filtros │ │ └── filtros.js │ ├── index.html │ ├── movimiento │ │ ├── movimiento.html │ │ └── movimientoCtrl.js │ └── registro │ │ ├── registro.html │ │ └── registroCtrl.js ├── package.json ├── server.js └── server │ ├── config.js │ ├── maestros.js │ ├── movimientos.js │ └── seguridad.js ├── 22-mongo-console ├── 1-crear.js ├── 2-buscar.js ├── 3-modificar.js ├── 4-insertar.js └── mongodb.md ├── 23-mongodb-client ├── client │ ├── _comun │ │ ├── app.js │ │ ├── appHttpLog.js │ │ ├── appSecurity.js │ │ ├── menuCtrl.js │ │ └── not-found.html │ ├── controlcaja │ │ ├── cajaCtrl.js │ │ ├── lista.html │ │ ├── nuevo.html │ │ └── total.html │ ├── data │ │ ├── maestrosFactory.js │ │ └── movimientosFactory.js │ ├── directivas │ │ ├── directivas.js │ │ ├── tpl-cabecera.html │ │ ├── tpl-fila-movimiento.html │ │ └── valoracion │ │ │ ├── tpl-valoracion.html │ │ │ └── valoracion.js │ ├── filtros │ │ └── filtros.js │ ├── index.html │ ├── movimiento │ │ ├── movimiento.html │ │ └── movimientoCtrl.js │ └── registro │ │ ├── registro.html │ │ └── registroCtrl.js ├── package.json ├── server.js └── server │ ├── config.js │ ├── data │ ├── mongodb.js │ ├── movimientosData.js │ └── usuariosData.js │ ├── maestros.js │ ├── movimientos.js │ └── seguridad.js ├── 23b-mongodb-client ├── client │ ├── _comun │ │ ├── app.js │ │ ├── appHttpLog.js │ │ ├── appSecurity.js │ │ ├── menuCtrl.js │ │ └── not-found.html │ ├── controlcaja │ │ ├── cajaCtrl.js │ │ ├── lista.html │ │ ├── nuevo.html │ │ └── total.html │ ├── data │ │ ├── maestrosFactory.js │ │ └── movimientosFactory.js │ ├── directivas │ │ ├── directivas.js │ │ ├── tpl-cabecera.html │ │ ├── tpl-fila-movimiento.html │ │ └── valoracion │ │ │ ├── tpl-valoracion.html │ │ │ └── valoracion.js │ ├── filtros │ │ └── filtros.js │ ├── index.html │ ├── movimiento │ │ ├── movimiento.html │ │ └── movimientoCtrl.js │ └── registro │ │ ├── registro.html │ │ └── registroCtrl.js ├── package.json ├── server.js └── server │ ├── config.js │ ├── data │ ├── mongodb.js │ ├── movimientosData.js │ └── usuariosData.js │ ├── maestros.js │ ├── movimientos.js │ └── seguridad.js ├── 24-pretty-url ├── client │ ├── index.html │ └── static │ │ ├── _comun │ │ ├── app.js │ │ ├── appHttpLog.js │ │ ├── appSecurity.js │ │ ├── menuCtrl.js │ │ └── not-found.html │ │ ├── controlcaja │ │ ├── cajaCtrl.js │ │ ├── lista.html │ │ ├── nuevo.html │ │ └── total.html │ │ ├── data │ │ ├── maestrosFactory.js │ │ └── movimientosFactory.js │ │ ├── directivas │ │ ├── directivas.js │ │ ├── tpl-cabecera.html │ │ ├── tpl-fila-movimiento.html │ │ └── valoracion │ │ │ ├── tpl-valoracion.html │ │ │ └── valoracion.js │ │ ├── filtros │ │ └── filtros.js │ │ ├── movimiento │ │ ├── movimiento.html │ │ └── movimientoCtrl.js │ │ └── registro │ │ ├── registro.html │ │ └── registroCtrl.js ├── package.json ├── server.js └── server │ ├── config.js │ ├── data │ ├── mongodb.js │ ├── movimientosData.js │ └── usuariosData.js │ ├── maestros.js │ ├── movimientos.js │ └── seguridad.js ├── 25-socket-io ├── client │ ├── index.html │ └── static │ │ ├── _comun │ │ ├── app.js │ │ ├── appHttpLog.js │ │ ├── appSecurity.js │ │ ├── menuCtrl.js │ │ ├── not-found.html │ │ └── socketFactory.js │ │ ├── controlcaja │ │ ├── cajaCtrl.js │ │ ├── lista.html │ │ ├── nuevo.html │ │ └── total.html │ │ ├── dashboard │ │ ├── dashboard.html │ │ └── dashboardCtrl.js │ │ ├── data │ │ ├── maestrosFactory.js │ │ └── movimientosFactory.js │ │ ├── directivas │ │ ├── directivas.js │ │ ├── tpl-cabecera.html │ │ ├── tpl-fila-movimiento.html │ │ └── valoracion │ │ │ ├── tpl-valoracion.html │ │ │ └── valoracion.js │ │ ├── filtros │ │ └── filtros.js │ │ ├── movimiento │ │ ├── movimiento.html │ │ └── movimientoCtrl.js │ │ └── registro │ │ ├── registro.html │ │ └── registroCtrl.js ├── package.json ├── server.js └── server │ ├── config.js │ ├── data │ ├── mongodb.js │ ├── movimientosData.js │ └── usuariosData.js │ ├── maestros.js │ ├── movimientos.js │ ├── seguridad.js │ └── socket.js ├── 26-pro └── pro.md ├── LICENSE ├── README.md └── preguntas_fin_de_curso.md /02-Control-en-JavaScript/app.js: -------------------------------------------------------------------------------- 1 | // Declaración de un nuevo módulo sin dependencias, llamado 'controlCajaApp' 2 | angular.module('controlCajaApp', []); -------------------------------------------------------------------------------- /03-dos-controladores/app.js: -------------------------------------------------------------------------------- 1 | angular.module('controlCajaApp', []); -------------------------------------------------------------------------------- /03-dos-controladores/cajaCtrl.js: -------------------------------------------------------------------------------- 1 | // Este controlador permanece igual 2 | // Sus variables no interfieren ni son visible para el otro 3 | (function () { 4 | var cajaCtrl = function () { 5 | var vm = this; 6 | 7 | vm.titulo = "Controla tu Cash Flow"; 8 | 9 | vm.total = { 10 | ingresos: 0, 11 | gastos: 0 12 | }; 13 | 14 | vm.maestros = { 15 | categoriasIngresos: ['Nómina', 'Ventas', 'Intereses Depósitos'], 16 | categoriasGastos: ['Hipotéca', 'Compras', 'Impuestos'] 17 | }; 18 | 19 | vm.nuevoMovimiento = { 20 | esIngreso: 1, 21 | esGasto: 0, 22 | importe: 0, 23 | fecha: new Date() 24 | }; 25 | 26 | vm.movimientos = []; 27 | 28 | vm.guardarMovimiento = function () { 29 | if(vm.nuevoMovimiento.esIngreso){ 30 | vm.total.ingresos += vm.nuevoMovimiento.importe; 31 | }else{ 32 | vm.total.gastos += vm.nuevoMovimiento.importe; 33 | } 34 | var auxCopyMov = angular.copy(vm.nuevoMovimiento); 35 | auxCopyMov.tipo = vm.tipo(auxCopyMov); 36 | vm.movimientos.push(auxCopyMov); 37 | vm.nuevoMovimiento.importe = 0; 38 | } 39 | vm.balance = function () { 40 | return vm.total.ingresos - vm.total.gastos 41 | } 42 | vm.tipo = function (movimiento) { 43 | return movimiento.esIngreso && 'Ingreso' || 'Gasto' 44 | } 45 | } 46 | angular.module('controlCajaApp') 47 | .controller('CajaCtrl', cajaCtrl); 48 | }()); 49 | -------------------------------------------------------------------------------- /03-dos-controladores/menuCtrl.js: -------------------------------------------------------------------------------- 1 | // Dispondremos de tantos controladores como queramos 2 | // Cada uno en su fichero 3 | (function () { 4 | // Los controladores pueden tener dependencias de otras funciones 5 | // En este caso depende de $location, un servicio propio de angular que permite trabajar con urls 6 | function menuCtrl ($location) { 7 | // creamos una función anónima que recibe una ruta y la compara con la ruta actual 8 | this.isActive = function (ruta) { 9 | // Con esto deteminamos si una ruta es o no la actual 10 | return ruta === $location.path(); 11 | } 12 | } 13 | // Se enlaza el controlador al módulo principal de la aplicación 14 | angular.module('controlCajaApp').controller('MenuCtrl',menuCtrl); 15 | }()); -------------------------------------------------------------------------------- /04-tres-vistas-y-un-controlador-spa1/app.js: -------------------------------------------------------------------------------- 1 | // Vemos como usar una dependencia de otro módulo 2 | // En este caso el módulo es 'ngRoute' 3 | // Que viene en el fichero angular-route.min.js 4 | angular.module('controlCajaApp', ['ngRoute']); 5 | 6 | // Además de controladores, un módulo puede tener funciones de configuración 7 | // Estas se ejecutarán al arrancar la aplicación 8 | function configurarRutas($routeProvider) { 9 | // Declaramos una dependencia en el parámetro $routeProvider 10 | // Este servicio nos provee de métodos para realizar un enrutado en el cliente 11 | // Con esto se crean las SPA 12 | $routeProvider 13 | .when('/', { 14 | // Para cada ruta se declara la vista y el controlador asociados 15 | controller: 'CajaCtrl', 16 | controllerAs: 'caja', 17 | templateUrl: 'total.html' 18 | }) 19 | .when('/nuevo', { 20 | controller: 'CajaCtrl', 21 | controllerAs: 'caja', 22 | templateUrl: 'nuevo.html' 23 | }) 24 | .when('/lista', { 25 | controller: 'CajaCtrl', 26 | controllerAs: 'caja', 27 | templateUrl: 'lista.html' 28 | }) 29 | .otherwise({ 30 | // en caso de peticiones no contempladas podemos redirigir 31 | redirectTo: '/' 32 | }); 33 | } 34 | 35 | // Se registra la función como un configurador del módulo 36 | angular.module('controlCajaApp').config(configurarRutas); -------------------------------------------------------------------------------- /04-tres-vistas-y-un-controlador-spa1/cajaCtrl.js: -------------------------------------------------------------------------------- 1 | // El controlador permanece común a las tres vistas 2 | // En principio esto facilita la programación 3 | (function () { 4 | var cajaCtrl = function () { 5 | var vm = this; 6 | 7 | vm.titulo = "Controla tu Cash Flow"; 8 | 9 | vm.total = { 10 | ingresos: 0, 11 | gastos: 0 12 | }; 13 | 14 | vm.maestros = { 15 | categoriasIngresos: ['Nómina', 'Ventas', 'Intereses Depósitos'], 16 | categoriasGastos: ['Hipotéca', 'Compras', 'Impuestos'] 17 | }; 18 | 19 | vm.nuevoMovimiento = { 20 | esIngreso: 1, 21 | esGasto: 0, 22 | importe: 0, 23 | fecha: new Date() 24 | }; 25 | 26 | vm.movimientos = []; 27 | 28 | vm.guardarMovimiento = function () { 29 | if(vm.nuevoMovimiento.esIngreso){ 30 | vm.total.ingresos += vm.nuevoMovimiento.importe; 31 | }else{ 32 | vm.total.gastos += vm.nuevoMovimiento.importe; 33 | } 34 | var auxCopyMov = angular.copy(vm.nuevoMovimiento); 35 | auxCopyMov.tipo = vm.tipo(auxCopyMov); 36 | vm.movimientos.push(auxCopyMov); 37 | vm.nuevoMovimiento.importe = 0; 38 | } 39 | vm.balance = function () { 40 | return vm.total.ingresos - vm.total.gastos 41 | } 42 | vm.tipo = function (movimiento) { 43 | return movimiento.esIngreso && 'Ingreso' || 'Gasto' 44 | } 45 | } 46 | 47 | angular.module('controlCajaApp').controller('CajaCtrl', cajaCtrl); 48 | }()); 49 | -------------------------------------------------------------------------------- /04-tres-vistas-y-un-controlador-spa1/lista.html: -------------------------------------------------------------------------------- 1 |
2 |

Estos son tus movimientos recientes.

3 |
4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
Fecha 10 | TipoCategoríaImporte 14 |
{{movimiento.fecha | date}}{{movimiento.tipo}}{{movimiento.categoria}}{{movimiento.importe | number:2}} €
26 |
-------------------------------------------------------------------------------- /04-tres-vistas-y-un-controlador-spa1/menuCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var menuCtrl = function ($location) { 3 | this.isActive = function (ruta) { 4 | return ruta === $location.path(); 5 | } 6 | } 7 | angular.module('controlCajaApp').controller('MenuCtrl',menuCtrl); 8 | }()); -------------------------------------------------------------------------------- /05-tres-vistas-un-controladory-una-factoria-spa2/app.js: -------------------------------------------------------------------------------- 1 | angular.module('controlCajaApp', ['ngRoute']); 2 | 3 | angular.module('controlCajaApp').config(function ($routeProvider) { 4 | $routeProvider 5 | .when('/', { 6 | controller: 'CajaCtrl', 7 | controllerAs: 'caja', 8 | templateUrl: 'total.html' 9 | }) 10 | .when('/nuevo', { 11 | controller: 'CajaCtrl', 12 | controllerAs: 'caja', 13 | templateUrl: 'nuevo.html' 14 | }) 15 | .when('/lista', { 16 | controller: 'CajaCtrl', 17 | controllerAs: 'caja', 18 | templateUrl: 'lista.html' 19 | }) 20 | .otherwise({ 21 | redirectTo: '/' 22 | }); 23 | }); -------------------------------------------------------------------------------- /05-tres-vistas-un-controladory-una-factoria-spa2/lista.html: -------------------------------------------------------------------------------- 1 |
2 |

Estos son tus movimientos recientes.

3 |
4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
Fecha 10 | TipoCategoríaImporte 14 |
{{movimiento.fecha | date}}{{movimiento.tipo}}{{movimiento.categoria}}{{movimiento.importe | number:2}} €
26 |
-------------------------------------------------------------------------------- /05-tres-vistas-un-controladory-una-factoria-spa2/menuCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var menuCtrl = function ($location) { 3 | this.isActive = function (ruta) { 4 | return ruta === $location.path(); 5 | } 6 | } 7 | angular.module('controlCajaApp').controller('MenuCtrl',menuCtrl); 8 | }()); -------------------------------------------------------------------------------- /06-ui-una-ruta-mejor/app.js: -------------------------------------------------------------------------------- 1 | // tenemos que cambiar la dependencia hacia el nuevo módulo 2 | angular.module('controlCajaApp', ['ui.router']); 3 | 4 | // las rutas ahora se maneja con el concepto de estado 5 | angular.module('controlCajaApp').config(function ($stateProvider,$locationProvider) { 6 | // Las rutas pasan a ser opcionales, 7 | // en la práctica sólo se usan si viene de aplicaciones externas y por cuestiones de SEO 8 | $stateProvider 9 | .state('total', { 10 | url: '/', 11 | controller: 'CajaCtrl as caja', 12 | templateUrl: 'total.html' 13 | }) 14 | .state('nuevo', { 15 | url: '/nuevo', 16 | controller: 'CajaCtrl as caja', 17 | templateUrl: 'nuevo.html' 18 | }) 19 | .state('lista', { 20 | url: '/lista', 21 | controller: 'CajaCtrl as caja', 22 | templateUrl: 'lista.html' 23 | }).state('not-found', { 24 | url: '*path', 25 | templateUrl: 'not-found.html' 26 | }); 27 | // realmente no existe un estado 'not found', 28 | // pero puede llegar rutas no controladas 29 | }); -------------------------------------------------------------------------------- /06-ui-una-ruta-mejor/cajaCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | var cajaCtrl = function (movimientosFactory) { 4 | var vm = this; 5 | 6 | vm.titulo = "Controla tu Cash Flow"; 7 | vm.maestros = { 8 | categoriasIngresos: ['Nómina', 'Ventas', 'Intereses Depósitos'], 9 | categoriasGastos: ['Hipotéca', 'Compras', 'Impuestos'] 10 | }; 11 | vm.nuevoMovimiento = { 12 | esIngreso: 1, 13 | esGasto: 0, 14 | importe: 0, 15 | fecha: new Date() 16 | }; 17 | 18 | vm.movimientos = movimientosFactory.getMovimientos(); 19 | vm.total = movimientosFactory.getTotal(); 20 | 21 | vm.guardarMovimiento = function () { 22 | if(vm.nuevoMovimiento.esIngreso){ 23 | vm.total.ingresos += vm.nuevoMovimiento.importe; 24 | }else{ 25 | vm.total.gastos += vm.nuevoMovimiento.importe; 26 | } 27 | var auxCopyMov = angular.copy(vm.nuevoMovimiento); 28 | auxCopyMov.tipo = vm.tipo(auxCopyMov); 29 | vm.movimientos.push(auxCopyMov); 30 | vm.nuevoMovimiento.importe = 0; 31 | } 32 | vm.balance = function () { 33 | return vm.total.ingresos - vm.total.gastos 34 | } 35 | vm.tipo = function (movimiento) { 36 | return movimiento.esIngreso && 'Ingreso' || 'Gasto' 37 | } 38 | } 39 | angular.module('controlCajaApp').controller('CajaCtrl', cajaCtrl); 40 | }()); -------------------------------------------------------------------------------- /06-ui-una-ruta-mejor/lista.html: -------------------------------------------------------------------------------- 1 |
2 |

Estos son tus movimientos recientes.

3 |
4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
Fecha 10 | TipoCategoríaImporte 14 |
{{movimiento.fecha | date}}{{movimiento.tipo}}{{movimiento.categoria}}{{movimiento.importe | number:2}} €
26 |
-------------------------------------------------------------------------------- /06-ui-una-ruta-mejor/menuCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | // Ahora el sercvicio se llama $state 3 | var menuCtrl = function ($state) { 4 | this.isActive = function (estado) { 5 | // Tiene funciones más amigables para consultar 6 | return $state.is(estado); 7 | } 8 | } 9 | angular.module('controlCajaApp').controller('MenuCtrl',menuCtrl); 10 | }()); -------------------------------------------------------------------------------- /06-ui-una-ruta-mejor/movimientosFactory.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var movimientosFactory =   function ()  { 3 | var movimientos = []; 4 | var total = { 5 | ingresos: 0, 6 | gastos: 0 7 | }; 8 | 9 | 10 | var factory  =   {}; 11 | factory.getMovimientos =   function ()  { 12 | return movimientos; 13 | }; 14 | factory.getTotal =   function ()  { 15 | return total; 16 | }; 17 | factory.postMovimiento =   function (movimiento)  { 18 | movimientos.push(movimiento); 19 | total.ingresos += movimiento.esIngreso * movimiento.importe; 20 | total.gastos += movimiento.esGasto * movimiento.importe; 21 | }; 22 | return factory; 23 | }; 24 | 25 | angular.module('controlCajaApp').factory('movimientosFactory', movimientosFactory); 26 | }()); 27 | 28 | -------------------------------------------------------------------------------- /06-ui-una-ruta-mejor/not-found.html: -------------------------------------------------------------------------------- 1 |
2 |

No se ha encontrado lo que buscabas

3 |
-------------------------------------------------------------------------------- /07-hola-mundo-nodejs/1-mi-script.js: -------------------------------------------------------------------------------- 1 | // Lo que ya sabes de JavaScript 2 | console.log("Hola Mundo"); 3 | -------------------------------------------------------------------------------- /07-hola-mundo-nodejs/2-javascript-normal-2.js: -------------------------------------------------------------------------------- 1 | // Se ejecutan las instucciones del fichero secuencialmente... o no. 2 | // variables 3 | var nombre = 'Alberto'; 4 | var edad = 43; 5 | // funciones 6 | function imprimir(texto){ 7 | console.log(texto); 8 | } 9 | // expresiones 10 | imprimir(nombre + " tiene " + edad + " años"); 11 | -------------------------------------------------------------------------------- /07-hola-mundo-nodejs/3-patrones.js: -------------------------------------------------------------------------------- 1 | 2 | // Código encerrado en una función anónima autoinvocada 3 | (function () { 4 | "use strict"; // restricciñon para mejorar la calidad del código 5 | var nombre = 'Alberto'; 6 | edad = 43; 7 | //var edad = 43; 8 | 9 | function imprimir() { 10 | console.log(nombre + " tiene " + edad + " años"); 11 | } 12 | 13 | imprimir(); 14 | }());// Invocación inmediata de funciones 15 | -------------------------------------------------------------------------------- /07-hola-mundo-nodejs/4-el-proceso.js: -------------------------------------------------------------------------------- 1 | // En NodeJS todo se ejecuta en único thread 2 | // Puedes llamarlo 'EL PROCESO' 3 | (function () { 4 | "use strict"; 5 | process.title = "mi super aplicación"; 6 | imprimir(); 7 | 8 | // Puedes conocer cosas acerca del proceso en curso 9 | function imprimir() { 10 | console.log('----------------------------------------'); 11 | console.log(' DATOS DE NODE.JS PROCESS'); 12 | console.log('----------------------------------------'); 13 | console.log('Directorio .......... ' + process.cwd()); 14 | console.log('Exec path ........... ' + process.execPath); 15 | //console.log('identificador uid ... ' + process.getuid()); 16 | console.log('identificador pid ... ' + process.pid); 17 | console.log('Título .............. ' + process.title); 18 | console.log('Versión de Node .... ' + process.version); 19 | console.log('Plataforma........... ' + process.platform); 20 | } 21 | 22 | }()); 23 | -------------------------------------------------------------------------------- /07-hola-mundo-nodejs/hola-mundo.md: -------------------------------------------------------------------------------- 1 | # 7. Hola Mundo 2 | 3 | ## Scripts en Java-Script 4 | 5 | ### node 1-mi-script.js 6 | * puro JavaScript 7 | ### node 2-javacript-normal.js 8 | * variables 9 | * funciones 10 | * expresiones 11 | ### node 3-patrones.js 12 | * Closures con IIF 13 | * Sintáxis extricta 14 | ### node 4-el-proceso.js 15 | * Directorios 16 | * Identificadores 17 | * Entorno 18 | -------------------------------------------------------------------------------- /08-nodejs-y-la-consola/1-consola-argumentos.js: -------------------------------------------------------------------------------- 1 | // puedes recuperar argumentos desde la línea de comandos 2 | (function() { 3 | "use strict"; 4 | 5 | // array de argumentos process.argv[] 6 | var nodePath = process.argv[0]; // path donde está node.exe 7 | var scriptPath = process.argv[1]; // path donde está este script 8 | // Los Argumentos de usuario, se recuperan a partir de la 3ª posición 9 | var nombre = process.argv[2]; 10 | var edad = process.argv[3]; 11 | 12 | imprimir(); 13 | 14 | function imprimir() { 15 | console.log("Ejecutando " + scriptPath + " con " + nodePath); 16 | console.log(nombre + " tiene " + edad + " años"); 17 | } 18 | 19 | 20 | }()); 21 | -------------------------------------------------------------------------------- /08-nodejs-y-la-consola/2-trabajo-consola-asincrona.js: -------------------------------------------------------------------------------- 1 | // La forma más sencilla de interacción es mediante la consola 2 | 3 | // Versión básica de interacción con la consola 4 | (function () { 5 | "use strict"; 6 | // Se abre un buffer para repuerar la entrada del usuario 7 | var stdin = process.openStdin(); 8 | 9 | var nombre = 'Anónimo'; 10 | var edad = 43; 11 | 12 | console.log("¿Cómo te llamas ?"); 13 | 14 | // el buffer emite eventos 15 | // a los eventos se responde con callbacks 16 | // así funiona el mundo asíncrono 17 | stdin.addListener("data", alRecibirDatos); 18 | 19 | // función callback que se ejecutara en respuesta al evento 20 | function alRecibirDatos(data){ 21 | nombre = data.toString().substring(0, data.length - 1); 22 | imprimir(); 23 | } 24 | 25 | function imprimir() { 26 | console.log(nombre + " tiene " + edad + " años"); 27 | } 28 | 29 | }()); 30 | -------------------------------------------------------------------------------- /08-nodejs-y-la-consola/3-consola-con-callbacks.js: -------------------------------------------------------------------------------- 1 | //Versión más elaborada con callbacks 2 | (function () { 3 | "use strict"; 4 | // ahora vmos a escribir también en otro buffer 5 | var stdin = process.stdin, 6 | stdout = process.stdout; // buffer de salida hacia la conola 7 | 8 | var persona = { 9 | nombre: 'Anónimo', 10 | edad: 0 11 | }; 12 | 13 | process.stdin.setEncoding('utf8'); 14 | 15 | preguntar("¿Cómo te llamas ?", guardarNombre); 16 | 17 | function guardarNombre(nombre) { 18 | persona.nombre = nombre; 19 | // Volver a preguntar 20 | preguntar("Hola " + persona.nombre + " ¿Cuántos años tienes?", guardarEdad); 21 | } 22 | 23 | function guardarEdad(edad) { 24 | persona.edad = edad; 25 | if (persona.edad >= 18) { 26 | process.stdout.write("Adelante " + persona.nombre + " de " + persona.edad + " años \n"); 27 | } 28 | else{ 29 | process.stdout.write("Lo siento " + persona.nombre + " de " + persona.edad + " años \n"); 30 | } 31 | process.exit(); 32 | } 33 | 34 | function preguntar(pregunta, procesoPosterior) { 35 | stdin.resume(); 36 | stdout.write(pregunta + ": "); 37 | // cuando tengamo datos 38 | stdin.once('data', function (respuesta) { 39 | // ejecutar el callback que nos han pasado 40 | // con los datos obtenidos 41 | procesoPosterior(respuesta.toString().trim()); 42 | }); 43 | } 44 | 45 | }()); 46 | -------------------------------------------------------------------------------- /08-nodejs-y-la-consola/consola.md: -------------------------------------------------------------------------------- 1 | # 2. Consola 2 | 3 | ## Argumentos 4 | - process.argv[0] node 5 | - process.argv[1] script 6 | + process.argv[2..n] argumentos 7 | ## Interacción 8 | La respuesta del usuario es asíncrona 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /09-nodejs-y-la-web/1-http.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | "use strict"; 3 | // Ciertas funionaes de node están empaquetadas en módulos 4 | // Mediante la instrucción requiere, se reclaman los módulos por nombre o ruta, 5 | // Las funiones de escucha y respuesta http están en el módulo... http 6 | var http = require('http'); 7 | 8 | // escuchar en un puerto 9 | http.createServer(server).listen(3000); 10 | 11 | // Esta es la función que recoge las peticiones 12 | // Es un callback que se lanza en cada evento de petición recibida 13 | function server(req, res) { 14 | // y envía las respuestas 15 | res.writeHead({ 16 | 'Content-Type': 'text/plain' 17 | }); 18 | res.end('Hola, esto lo envía NodeJS desde un navegador ;-)'); 19 | } 20 | 21 | }()); 22 | -------------------------------------------------------------------------------- /09-nodejs-y-la-web/2-web.js: -------------------------------------------------------------------------------- 1 | // ya que tenemos un servidor http 2 | // lo usaremos para servir html 3 | (function () { 4 | "use strict"; 5 | var http = require('http'); 6 | 7 | http.createServer(server).listen(3000); 8 | 9 | function server(req, res) { 10 | // Repondemos enviando html... 11 | res.writeHead(200, { 12 | "Content-Type": "text/html" 13 | }); 14 | res.write(""); 15 | res.write(""); 16 | res.write("Hola Mundo"); 17 | res.write(""); 18 | res.write(""); 19 | res.write("

Hola

enviado por NodeJS al navegador

;-)"); 20 | res.write(""); 21 | res.write(""); 22 | // esto es un web server !!! 23 | res.end(); 24 | } 25 | 26 | }()); 27 | -------------------------------------------------------------------------------- /09-nodejs-y-la-web/4-control-caja/client/app.js: -------------------------------------------------------------------------------- 1 | // tenemos que cambiar la dependencia hacia el nuevo módulo 2 | angular.module('controlCajaApp', ['ui.router']); 3 | 4 | // las rutas ahora se maneja con el concepto de estado 5 | angular.module('controlCajaApp').config(function ($stateProvider,$locationProvider) { 6 | $stateProvider 7 | .state('total', { 8 | url: '/', 9 | controller: 'CajaCtrl as caja', 10 | templateUrl: 'total.html' 11 | }) 12 | .state('nuevo', { 13 | url: '/nuevo', 14 | controller: 'CajaCtrl as caja', 15 | templateUrl: 'nuevo.html' 16 | }) 17 | .state('lista', { 18 | url: '/lista', 19 | controller: 'CajaCtrl as caja', 20 | templateUrl: 'lista.html' 21 | }).state('not-found', { 22 | url: '*path', 23 | controller: 'CajaCtrl as caja', 24 | templateUrl: 'total.html' 25 | }); 26 | }); -------------------------------------------------------------------------------- /09-nodejs-y-la-web/4-control-caja/client/cajaCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | // El controlador ahora tiene una dependencia de la factoría 3 | var cajaCtrl = function (movimientosFactory) { 4 | var vm = this; 5 | 6 | vm.titulo = "Controla tu Cash Flow"; 7 | vm.maestros = { 8 | categoriasIngresos: ['Nómina', 'Ventas', 'Intereses Depósitos'], 9 | categoriasGastos: ['Hipotéca', 'Compras', 'Impuestos'] 10 | }; 11 | vm.nuevoMovimiento = { 12 | esIngreso: 1, 13 | esGasto: 0, 14 | importe: 0, 15 | fecha: new Date() 16 | }; 17 | // La parte de datos que debe compartir la delega sobre la factoría 18 | vm.movimientos = movimientosFactory.getMovimientos(); 19 | vm.total = movimientosFactory.getTotal(); 20 | 21 | vm.guardarMovimiento = function () { 22 | if(vm.nuevoMovimiento.esIngreso){ 23 | vm.total.ingresos += vm.nuevoMovimiento.importe; 24 | }else{ 25 | vm.total.gastos += vm.nuevoMovimiento.importe; 26 | } 27 | var auxCopyMov = angular.copy(vm.nuevoMovimiento); 28 | auxCopyMov.tipo = vm.tipo(auxCopyMov); 29 | vm.movimientos.push(auxCopyMov); 30 | vm.nuevoMovimiento.importe = 0; 31 | } 32 | vm.balance = function () { 33 | return vm.total.ingresos - vm.total.gastos 34 | } 35 | vm.tipo = function (movimiento) { 36 | return movimiento.esIngreso && 'Ingreso' || 'Gasto' 37 | } 38 | } 39 | angular.module('controlCajaApp').controller('CajaCtrl', cajaCtrl); 40 | }()); -------------------------------------------------------------------------------- /09-nodejs-y-la-web/4-control-caja/client/lista.html: -------------------------------------------------------------------------------- 1 |

2 |

Estos son tus movimientos recientes.

3 |
4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
Fecha 10 | TipoCategoríaImporte 14 |
{{movimiento.fecha | date}}{{movimiento.tipo}}{{movimiento.categoria}}{{movimiento.importe | number:2}} €
26 |
-------------------------------------------------------------------------------- /09-nodejs-y-la-web/4-control-caja/client/menuCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var menuCtrl = function ($state) { 3 | this.isActive = function (estado) { 4 | return $state.is(estado); 5 | } 6 | } 7 | angular.module('controlCajaApp').controller('MenuCtrl',menuCtrl); 8 | }()); -------------------------------------------------------------------------------- /09-nodejs-y-la-web/4-control-caja/client/movimientosFactory.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | // Las factorías, y los servicios, son funciones estándar 3 | // Una gran diferencia con los controladores es que son singleton 4 | // Eso los convierte en un buen lugar para compartir datos 5 | var movimientosFactory =   function ()  { 6 | // el array de movimientos y el total lo mantiene la factoría 7 | // de esta forma sobrevive a las recargas de controladores 8 | var movimientos = []; 9 | var total = { 10 | ingresos: 0, 11 | gastos: 0 12 | }; 13 | 14 | 15 | var factory  =   {}; 16 | factory.getMovimientos =   function ()  { 17 | return movimientos; 18 | }; 19 | factory.getTotal =   function ()  { 20 | return total; 21 | }; 22 | factory.postMovimiento =   function (movimiento)  { 23 | movimientos.push(movimiento); 24 | total.ingresos += movimiento.esIngreso * movimiento.importe; 25 | total.gastos += movimiento.esGasto * movimiento.importe; 26 | }; 27 | // las factorias siempre devuelven objetos 28 | // Estos objetos pueden contener funciones de lógica reutilizables 29 | return factory; 30 | }; 31 | 32 | angular.module('controlCajaApp').factory('movimientosFactory', movimientosFactory); 33 | }()); 34 | 35 | -------------------------------------------------------------------------------- /09-nodejs-y-la-web/4-control-caja/client/not-found.html: -------------------------------------------------------------------------------- 1 |
2 |

No se ha encontrado lo que buscabas

3 |
-------------------------------------------------------------------------------- /09-nodejs-y-la-web/static/blog.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

El Blog de NodeJS

8 |

En construcción...

9 | 10 | -------------------------------------------------------------------------------- /09-nodejs-y-la-web/static/estilo.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: #eeeeee; 3 | font-family: “Trebuchet MS”, Verdana, Arial, serif; 4 | } -------------------------------------------------------------------------------- /09-nodejs-y-la-web/static/simple.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Hola, soy muy simple :-( 6 | 7 | -------------------------------------------------------------------------------- /09-nodejs-y-la-web/web.md: -------------------------------------------------------------------------------- 1 | # 9. Web 2 | 3 | ## http 4 | * escuchar en un puerto y responder 5 | ## web 6 | * si respondemos enviando html... tenemos un web server 7 | ## static server 8 | * podemos sacar el html a ficheros 9 | - localhost:3000 10 | - localhost:3000/blog 11 | - localhost:3000/static/blog 12 | ## control caja 13 | - servidor web y apliacacion cliente 14 | - atención rutas locales con # 15 | -------------------------------------------------------------------------------- /10-nodejs-promesas-y-modulos/1-modulos-propios/1-app.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | // requerimos módulos externos... propios 3 | var Cuenta = require('./cuenta.js'); 4 | // Un patrón común es el de simular clases 5 | var ratilla = new Cuenta("Ratilla"); 6 | var billetero = new Cuenta("Billetero"); 7 | 8 | billetero.ingresar("10"); 9 | ratilla.ingresar(12.8); 10 | ratilla.retirar(2.4); 11 | billetero.retirar("1"); 12 | 13 | console.log(ratilla.propietario + " tiene " + ratilla.saldo + " euros"); 14 | console.log(billetero.propietario + " tiene " + billetero.saldo + " euros"); 15 | 16 | })(); 17 | -------------------------------------------------------------------------------- /10-nodejs-promesas-y-modulos/1-modulos-propios/cuenta.js: -------------------------------------------------------------------------------- 1 | // En este caso 'simulamos' una Clase instanciable 2 | var CuentaExportable = (function(){ 3 | // un módulo puede a su vez requerir de otros 4 | var Mates = require('./mates.js'); 5 | 6 | // La cuenta tendrá una función que acturá de constructor 7 | var Cuenta = function (propietario) { 8 | this.propietario = propietario; 9 | this.saldo = 0; 10 | console.log("creada cuenta para " + this.propietario + " con " + this.saldo + "€") 11 | }; 12 | 13 | // una vez creada una variable, se le pueden agregar métodos y propiedades 14 | Cuenta.prototype = { 15 | ingresar: function(dinero){ 16 | this.saldo = Mates.sumar(this.saldo,dinero); 17 | console.log("ingresar: " + dinero + " a " + this.propietario + " tiene " + this.saldo + "€"); 18 | }, 19 | retirar: function(dinero){ 20 | this.saldo = Mates.restar(this.saldo,dinero); 21 | console.log("retirar: " + dinero + " a " + this.propietario + " tiene " + this.saldo + "€"); 22 | } 23 | } 24 | 25 | return Cuenta; 26 | })(); 27 | 28 | // se exporta la variable CuentaExportable, 29 | // dicha variable apunta a una función que retorna un objeto 30 | 31 | module.exports = CuentaExportable; 32 | -------------------------------------------------------------------------------- /10-nodejs-promesas-y-modulos/1-modulos-propios/mates.js: -------------------------------------------------------------------------------- 1 | // Otro caso muy común es disponer de una 2 | // Biblioteca de funciones de ayuda 3 | var Matematicas = (function(){ 4 | return { 5 | sumar: function(a,b){ 6 | return obtenerNumero(a) + obtenerNumero(b); 7 | }, 8 | restar: function(a,b){ 9 | return obtenerNumero(a) - obtenerNumero(b); 10 | } 11 | } 12 | 13 | function obtenerNumero(texto){ 14 | return texto*1; 15 | } 16 | 17 | })(); 18 | 19 | // exportamos una variable 20 | // que apunta a una función 21 | // que devuelve un objeto 22 | module.exports = Matematicas; 23 | -------------------------------------------------------------------------------- /10-nodejs-promesas-y-modulos/2-operaciones-lentas/2-1-callback.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | // El módulo http puede usarse para responder y para emitir llamadas 3 | var http = require('http'); 4 | var llamada = { 5 | host: 'agorabinaria.com' 6 | }; 7 | 8 | console.log("Trabajo lento iniciado... "); 9 | trabajoLento(); 10 | console.log("Trabajo lentoMejorado iniciado... "); 11 | trabajoLentoMejorado(); 12 | console.log("Trabajo rápido iniciado... "); 13 | trabajoRápido(); 14 | 15 | 16 | // Usando callbacks anónimos 17 | function trabajoLento() { 18 | http.get(llamada, function (res) { 19 | console.log("Trabajo lento terminado: " + res.statusCode); 20 | }).on('error', function (e) { 21 | console.eror("Trabajo lento terminado: " + e.message); 22 | }); 23 | } 24 | 25 | function trabajoRápido() { 26 | console.log("Trabajo rápido terminado :-) "); 27 | } 28 | 29 | // Usando nombres y funciones 30 | function trabajoLentoMejorado() { 31 | 32 | function alRecibirDatos(res) { 33 | console.log("Trabajo lentoMejorado terminado: " + res.statusCode); 34 | } 35 | 36 | function alRecibirError(e) { 37 | console.error("Trabajo lentoMejorado terminado: " + e.message); 38 | } 39 | // El código queda más legible si usamos funiones con nombre 40 | http.get(llamada, alRecibirDatos) 41 | .on('error', alRecibirError); 42 | } 43 | 44 | })(); -------------------------------------------------------------------------------- /10-nodejs-promesas-y-modulos/2-operaciones-lentas/2-2-promesas.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var http = require('http'); 3 | // q es un paquete de NodeJS muy utilizado para facilitar la programación asíncrona 4 | var Q = require('q'); 5 | var llamada = { 6 | host: 'agorabinaria.com' 7 | }; 8 | 9 | // llamar a una función que devuelve una promesa 10 | trabajoLento() 11 | .then(function (res) { 12 | console.log("Trabajo lento terminado: " + res.statusCode); 13 | }) 14 | .fail(function (e) { 15 | console.log("Trabajo lento con error: " + e.message); 16 | }); 17 | 18 | // Esta función promete hacer cosas... 19 | function trabajoLento() { 20 | var deferred = Q.defer(); 21 | http.get(llamada, function (res) { 22 | // ... cuando hace lo prometido informa de ello 23 | deferred.resolve(res); 24 | }).on('error', function (e) { 25 | // ... y cuando falla también 26 | deferred.reject(e); 27 | }); 28 | // la respuesta es inmediata... porque realmente aún no ha pasado nada :-) 29 | return deferred.promise; 30 | } 31 | 32 | })(); -------------------------------------------------------------------------------- /10-nodejs-promesas-y-modulos/2-operaciones-lentas/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "modulos", 3 | "version": "1.0.0", 4 | "description": "módulos externos con npm", 5 | "author": "alberto basalo", 6 | "license": "ISC", 7 | "dependencies": { 8 | "q": "^1.2.0" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /10-nodejs-promesas-y-modulos/pro.md: -------------------------------------------------------------------------------- 1 | # 4. Pro 2 | 3 | ## Herramientas 4 | - **nodemon**: sudo npm install -g nodemon 5 | 6 | ### Módulos externos 7 | - npm init 8 | - npm install q -save 9 | 10 | ## 1 Módulos 11 | - Clases para representar modelos 12 | - Bibliotecas de funciones 13 | 14 | ## 2 Operaciones lentas 15 | - por ejemplo llamadas externas http 16 | 17 | ### 2-1 Callbacks 18 | - Te pueden llevar al infierno 19 | - Al menos organízate y dales nombre 20 | 21 | ### 2-2 Promesas 22 | - El doctor Q al rescate 23 | 24 | -------------------------------------------------------------------------------- /11-express/1-hola-express.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | "use strict"; 3 | // Se requier la presencia del módulo de express 4 | // previamente instalado usando 5 | // npm install express -save 6 | var express = require('express'); 7 | 8 | // Es frecuente llamar app a la instancia de express 9 | var app = express(); 10 | 11 | // Respondemos a las peticiones mediante un mecanismo de suscripción y callbacks 12 | app.get('/', alRecibirPeticion); 13 | 14 | // función que se ejecutará cuando nos llamen 15 | function alRecibirPeticion(peticion, respuesta){ 16 | respuesta.send('Hola Express!'); 17 | } 18 | 19 | // Configuramos la aplicación para escuchar en el puerto 3000 20 | app.listen(3000); 21 | }()); -------------------------------------------------------------------------------- /11-express/2-middleware.js: -------------------------------------------------------------------------------- 1 | // Una petición recibida por una apliación express 2 | // atraviesa una serie de capas llamdas middleware 3 | 4 | (function () { 5 | "use strict"; 6 | var express = require('express'); 7 | 8 | var app = express(); 9 | 10 | var options = { 11 | extensions: ['htm', 'html'], 12 | maxAge: '1d', 13 | setHeaders: function (res, path, stat) { 14 | res.set('x-timestamp', Date.now()) 15 | } 16 | }; 17 | // Un uso muy frecuente es reservar ujna serie de rutas para derivarlas al disco 18 | // Tendremos así un directorio para contenido estático 19 | app.use(express.static(__dirname + '/static', options)); 20 | 21 | // Otro uso común es la monitorización de la aplicación 22 | // Interceptor de llamadas 23 | app.use(function (peticion, respuesta, siguiente) { 24 | console.log("recibida petición: " + peticion.url); 25 | // Es muy importante continuar el flujo hacia la sigueinte función 26 | siguiente(); 27 | // En caso de no hacerlo, se colgaría la llamada 28 | }); 29 | 30 | // También es habitual usarlas para sanear la entrada y securizar la aplicación 31 | 32 | // Tras atravesar las capas de middleware la llamda llegará al código de negocio 33 | // Respuesta con una funión in-line a una petición concreta 34 | app.get('/', function (peticion, respuesta) { 35 | respuesta.send('Hola Express!'); 36 | }); 37 | 38 | app.listen(3000); 39 | }()); -------------------------------------------------------------------------------- /11-express/express.md: -------------------------------------------------------------------------------- 1 | # 5. Express 2 | 3 | ## Instalación 4 | * npm init 5 | * npm install express -save 6 | 7 | ## Hola Mundo 8 | un servidor web en 4 lineas 9 | ## Middleware 10 | app.use() 11 | ### Log de llamadas 12 | atención al 3º argumento, que llama a la siguiente función en la pila 13 | ### Directorio estático 14 | configuración básica 15 | **atención al orden del middleware** 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /11-express/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "holaexpress", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "1-hola-express.js", 6 | "author": "", 7 | "license": "ISC", 8 | "dependencies": { 9 | "express": "^4.12.0" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /11-express/static/simple.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Hola, soy muy simple :-( 6 | 7 | -------------------------------------------------------------------------------- /12-rutas-con-express/1-rutas.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | "use strict"; 3 | var express = require('express'); 4 | 5 | var app = express(); 6 | 7 | // esta función sigue siendo para todos 8 | 9 | app.use(function (peticion, respuesta, siguiente) { 10 | console.log("recibida petición: " + peticion.url); 11 | siguiente(); 12 | }); 13 | // la ruta base 14 | app.get('/', alRecibirPeticion); 15 | 16 | // función que se ejecutará cuando nos llamen 17 | function alRecibirPeticion(peticion, respuesta){ 18 | respuesta.send('Hola Express!'); 19 | } 20 | 21 | // Cada ruta tiene su propia función (en este caso anónima inline) 22 | app.get('/about', function (peticion, respuesta) { 23 | respuesta.send('Página creada por gente que sabe Express!'); 24 | }); 25 | 26 | app.listen(3000); 27 | }()); -------------------------------------------------------------------------------- /12-rutas-con-express/2-parametros/mates.js: -------------------------------------------------------------------------------- 1 | var Mates = (function(){ 2 | return { 3 | sumar: function(a,b){ 4 | return obtenerNumero(a) + obtenerNumero(b); 5 | }, 6 | restar: function(a,b){ 7 | return obtenerNumero(a) - obtenerNumero(b); 8 | } 9 | } 10 | 11 | function obtenerNumero(texto){ 12 | return texto*1; 13 | } 14 | 15 | })(); 16 | 17 | module.exports = Mates; -------------------------------------------------------------------------------- /12-rutas-con-express/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rutasconexpress", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "1-rutas.js", 6 | "author": "", 7 | "license": "ISC", 8 | "dependencies": { 9 | "body-parser": "^1.12.2", 10 | "express": "^4.12.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /12-rutas-con-express/rutas.md: -------------------------------------------------------------------------------- 1 | # 6. Rutas 2 | 3 | ## Enrutación básica 4 | - especificar cada función para cada ruta disponible 5 | ## Parámetros 6 | - /:parametro/ 7 | ## Variantes con patrones de cadenas y expresiones regulares 8 | - se usan tando en las rutas como sobre todo en los parámetros 9 | 10 | 11 | -------------------------------------------------------------------------------- /13-api-restfull-con-express/API-REST.md: -------------------------------------------------------------------------------- 1 | # 7 API-REST 2 | 3 | ## Sintaxis: verbos y sustantivos 4 | - CRUD : -> http verbs 5 | ## Recursos y rutas 6 | - express router 7 | - recuros anidados 8 | ## Documentación 9 | 10 | ## Organización 11 | 12 | - Tener un módulo dónde se definen las rutas y se enlazan a las funciones de respuestas 13 | - Llevar las funciones de respuesta a sus propios módulos 14 | - llevar la configuración a su propio módulo 15 | - mantener el app.js tan limpio como sea posible 16 | -------------------------------------------------------------------------------- /13-api-restfull-con-express/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rest-crud", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "1-rest-crud.js", 6 | "author": "@albertobasalo", 7 | "license": "ISC", 8 | "dependencies": { 9 | "body-parser": "^1.12.2", 10 | "express": "^4.12.0" 11 | } 12 | } -------------------------------------------------------------------------------- /14-rest-in-peace/client/app.js: -------------------------------------------------------------------------------- 1 | angular.module('controlCajaApp', ['ui.router']); 2 | 3 | angular.module('controlCajaApp').config(function ($stateProvider,$locationProvider) { 4 | $stateProvider 5 | .state('total', { 6 | url: '/', 7 | controller: 'CajaCtrl as caja', 8 | templateUrl: 'total.html' 9 | }) 10 | .state('nuevo', { 11 | url: '/nuevo', 12 | controller: 'CajaCtrl as caja', 13 | templateUrl: 'nuevo.html' 14 | }) 15 | .state('lista', { 16 | url: '/lista', 17 | controller: 'CajaCtrl as caja', 18 | templateUrl: 'lista.html' 19 | }).state('not-found', { 20 | url: '*path', 21 | controller: 'CajaCtrl as caja', 22 | templateUrl: 'total.html' 23 | }); 24 | }); -------------------------------------------------------------------------------- /14-rest-in-peace/client/lista.html: -------------------------------------------------------------------------------- 1 |
2 |

Estos son tus movimientos recientes.

3 |
4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
Fecha 10 | TipoCategoríaImporte 14 |
{{movimiento.fecha | date}}{{movimiento.tipo}}{{movimiento.categoria}}{{movimiento.importe | number:2}} €
26 |
-------------------------------------------------------------------------------- /14-rest-in-peace/client/menuCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var menuCtrl = function ($state) { 3 | this.isActive = function (estado) { 4 | return $state.is(estado); 5 | } 6 | } 7 | angular.module('controlCajaApp').controller('MenuCtrl',menuCtrl); 8 | }()); -------------------------------------------------------------------------------- /14-rest-in-peace/client/movimientosFactory.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | // La factoria ya no almacenrá sus propios datos 3 | // Mediante el servicio $http hará las llamadas al servidor 4 | // Es un servicio core y no hay que referenciar ningún módulo extra 5 | var movimientosFactory =   function ($http)  { 6 | var urlBase = "http://localhost:3000/api/"; 7 | 8 | 9 | var factory  =   {}; 10 | 11 | // se produce un cambio en la nomenclatura 12 | // al usar el gerundio indicamos un proceso no terminado 13 | // el controlador que lo consuma debe manejar la promesa 14 | factory.gettingMovimientos =   function ()  { 15 | // Estamos devolviendo promesas, no objetos 16 | return $http.get(urlBase + 'priv/movimientos'); 17 | }; 18 | // 19 | factory.gettingTotal =   function ()  { 20 | return $http.get(urlBase + 'priv/total'); 21 | }; 22 | 23 | factory.postingMovimiento =   function (movimiento)  { 24 | return $http.post(urlBase + 'priv/movimientos', movimiento); 25 | }; 26 | 27 | 28 | return factory; 29 | }; 30 | 31 | angular.module('controlCajaApp').factory('movimientosFactory', movimientosFactory); 32 | }()); -------------------------------------------------------------------------------- /14-rest-in-peace/client/not-found.html: -------------------------------------------------------------------------------- 1 |
2 |

No se ha encontrado lo que buscabas

3 |
-------------------------------------------------------------------------------- /14-rest-in-peace/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rest", 3 | "version": "0.0.0", 4 | "description": "rest nodejs angularjs", 5 | "main": "server.js", 6 | "dependencies": { 7 | "body-parser": "~1.0.2", 8 | "express": "~4.1.2" 9 | }, 10 | "author": "@albertobasalo", 11 | "license": "BSD-2-Clause" 12 | } 13 | -------------------------------------------------------------------------------- /15-rest-assured/client/app.js: -------------------------------------------------------------------------------- 1 | // Apuntamos la nueva dependencia a ngCookies 2 | angular.module('controlCajaApp', ['ui.router','ngCookies']); 3 | 4 | angular.module('controlCajaApp').config(function ($stateProvider,$locationProvider) { 5 | $stateProvider 6 | .state('total', { 7 | url: '/', 8 | controller: 'CajaCtrl as caja', 9 | templateUrl: 'total.html' 10 | }) 11 | .state('nuevo', { 12 | url: '/nuevo', 13 | controller: 'CajaCtrl as caja', 14 | templateUrl: 'nuevo.html' 15 | }) 16 | .state('lista', { 17 | url: '/lista', 18 | controller: 'CajaCtrl as caja', 19 | templateUrl: 'lista.html' 20 | }) 21 | .state('registro', { 22 | url: '/registro', 23 | controller: 'RegistroCtrl as registro', 24 | templateUrl: 'registro.html' 25 | }) 26 | .state('not-found', { 27 | url: '*path', 28 | controller: 'CajaCtrl as caja', 29 | templateUrl: 'total.html' 30 | }); 31 | }); -------------------------------------------------------------------------------- /15-rest-assured/client/lista.html: -------------------------------------------------------------------------------- 1 |
2 |

Estos son tus movimientos recientes.

3 |
4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
Fecha 10 | TipoCategoríaImporte 14 |
{{movimiento.fecha | date}}{{movimiento.tipo}}{{movimiento.categoria}}{{movimiento.importe | number:2}} €
26 |
-------------------------------------------------------------------------------- /15-rest-assured/client/maestrosFactory.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | // La factoría que me comunica con maestros es similar 3 | // Es bueno crear una factoría para cada recuros rest 4 | var maestrosFactory =   function ($http)  { 5 | // en este caso la ruta es pública, pero a este nivel no influye 6 | var urlBase = "http://localhost:3000/api/"; 7 | 8 | var factory  =   {}; 9 | 10 | factory.gettingMaestros =   function ()  { 11 | return $http.get(urlBase+'pub/maestros'); 12 | }; 13 | 14 | return factory; 15 | 16 | }; 17 | 18 | angular.module('controlCajaApp').factory('maestrosFactory', maestrosFactory); 19 | }()); -------------------------------------------------------------------------------- /15-rest-assured/client/menuCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var menuCtrl = function ($state) { 3 | this.isActive = function (estado) { 4 | return $state.is(estado); 5 | } 6 | } 7 | angular.module('controlCajaApp').controller('MenuCtrl',menuCtrl); 8 | }()); -------------------------------------------------------------------------------- /15-rest-assured/client/movimientosFactory.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | // La factoria ya no almacenrá sus propios datos 3 | // Mediante el servicio $http hará las llamadas al servidor 4 | // Es un servicio core y no hay que referenciar ningún módulo extra 5 | var movimientosFactory =   function ($http)  { 6 | 7 | var urlBase = "http://localhost:3000/api/"; 8 | 9 | 10 | var factory  =   {}; 11 | 12 | 13 | // se produce un cambio en la nomenclatura 14 | // al usar el gerundio indicamos un proceso no terminado 15 | // el controlador que lo consuma debe manejar la promesa 16 | factory.gettingMovimientos =   function ()  { 17 | // Estamos devolviendo promesas, no objetos 18 | return $http.get(urlBase + 'priv/movimientos'); 19 | }; 20 | 21 | factory.gettingTotal =   function ()  { 22 | return $http.get(urlBase + 'priv/total'); 23 | }; 24 | factory.postingMovimiento =   function (movimiento)  { 25 | return $http.post(urlBase + 'priv/movimientos', movimiento); 26 | }; 27 | 28 | 29 | //La poca lógica de negocio se irá al lado del servidor 30 | // factory.postMovimiento =   function (movimiento)  { 31 | // movimientos.push(movimiento); 32 | // total.ingresos += movimiento.esIngreso * movimiento.importe; 33 | // total.gastos += movimiento.esGasto * movimiento.importe; 34 | // }; 35 | 36 | return factory; 37 | }; 38 | 39 | angular.module('controlCajaApp').factory('movimientosFactory', movimientosFactory); 40 | }()); -------------------------------------------------------------------------------- /15-rest-assured/client/not-found.html: -------------------------------------------------------------------------------- 1 |
2 |

No se ha encontrado lo que buscabas

3 |
-------------------------------------------------------------------------------- /15-rest-assured/client/registroCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | // El rootScope mantiene un ViewModel al que se puede 'bindear' cualquier vista 3 | // Es cómodo usarlo para compartir datos de infraestructura 4 | // No conviene abusar, para reducir la posibilidad de conflictos y polución de la memoria 5 | // El servicio $cookieStore, viene en el módulo ngCookies 6 | var registroCtrl = function ( $state, $http, $cookieStore) { 7 | var urlBase = "http://localhost:3000/api/"; 8 | var vm = this; 9 | vm.usuario = {}; 10 | vm.registrar = function () { 11 | $http.post(urlBase + 'usuarios/', vm.usuario) 12 | .success(function (data) { 13 | //$rootScope.nombre = vm.usuario.email; 14 | //$rootScope.mensaje = 'recién creado'; 15 | $cookieStore.put("sessionId", data); 16 | $state.go("total"); 17 | }); 18 | } 19 | vm.entrar = function () { 20 | $http.post(urlBase + 'sesiones/', vm.usuario) 21 | .success(function (data) { 22 | //$rootScope.nombre = vm.usuario.email; 23 | //$rootScope.mensaje = 'recién entrado'; 24 | $cookieStore.put("sessionId", data); 25 | $state.go("total"); 26 | }); 27 | } 28 | 29 | } 30 | angular.module('controlCajaApp').controller('RegistroCtrl', registroCtrl); 31 | }()); -------------------------------------------------------------------------------- /15-rest-assured/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ControlCashFlow", 3 | "version": "0.0.0", 4 | "description": "Controla tu flujo de caja", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Alberto Basalo", 10 | "license": "BSD-2-Clause", 11 | "dependencies": { 12 | "express": "~4.1.1", 13 | "body-parser": "~1.0.2" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /16-rest-sources/client/app.js: -------------------------------------------------------------------------------- 1 | // Apuntamos la nueva dependencia a ngResource 2 | angular.module('controlCajaApp', ['ui.router','ngCookies', 'ngResource']); 3 | 4 | angular.module('controlCajaApp').config(function ($stateProvider,$locationProvider) { 5 | $stateProvider 6 | .state('total', { 7 | url: '/', 8 | controller: 'CajaCtrl as caja', 9 | templateUrl: 'total.html' 10 | }) 11 | .state('nuevo', { 12 | url: '/nuevo', 13 | controller: 'CajaCtrl as caja', 14 | templateUrl: 'nuevo.html' 15 | }) 16 | .state('lista', { 17 | url: '/lista', 18 | controller: 'CajaCtrl as caja', 19 | templateUrl: 'lista.html' 20 | }) 21 | .state('registro', { 22 | url: '/registro', 23 | controller: 'RegistroCtrl as registro', 24 | templateUrl: 'registro.html' 25 | }) 26 | .state('not-found', { 27 | url: '*path', 28 | controller: 'CajaCtrl as caja', 29 | templateUrl: 'total.html' 30 | }); 31 | }); -------------------------------------------------------------------------------- /16-rest-sources/client/appSecurity.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | // Como ngResources usa a $http, no hay que cambiar nada a nivel de interceptores 3 | function configuradorInterceptores($httpProvider) { 4 | $httpProvider.interceptors.push(funcionInterceptoraSeguridad); 5 | } 6 | 7 | function funcionInterceptoraSeguridad($q, $injector, $cookieStore, $rootScope) { 8 | 9 | var interceptor = {}; 10 | interceptor.request = function (request) { 11 | request.headers["sessionId"] = $cookieStore.get("sessionId"); 12 | return request || $q.when(request); 13 | }; 14 | interceptor.responseError = function (response) { 15 | var state = $injector.get('$state'); 16 | if (response.status === 401) { 17 | $rootScope.mensaje = "No hay derecho!!!"; 18 | state.go('registro'); 19 | } else if (response.status === 419) { 20 | $rootScope.mensaje = "Estoy caduco!!!"; 21 | $cookieStore.remove("sessionId") 22 | state.go('registro'); 23 | }; 24 | return $q.reject(response); 25 | } 26 | return interceptor; 27 | } 28 | 29 | angular.module('controlCajaApp').config(configuradorInterceptores); 30 | }()); -------------------------------------------------------------------------------- /16-rest-sources/client/lista.html: -------------------------------------------------------------------------------- 1 |
2 |

Estos son tus movimientos recientes.

3 |
4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
Fecha 10 | TipoCategoríaImporte 14 |
{{movimiento.fecha | date}}{{movimiento.tipo}}{{movimiento.categoria}}{{movimiento.importe | number:2}} €
26 |
-------------------------------------------------------------------------------- /16-rest-sources/client/maestrosFactory.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var maestrosFactory =   function ($resource)  { 3 | // El uso de recursos simplifica mucho la sintaxis 4 | return $resource("/api/pub/maestros/"); 5 | }; 6 | 7 | angular.module('controlCajaApp').factory('maestrosFactory', maestrosFactory); 8 | }()); -------------------------------------------------------------------------------- /16-rest-sources/client/menuCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var menuCtrl = function ($state) { 3 | this.isActive = function (estado) { 4 | return $state.is(estado); 5 | } 6 | } 7 | angular.module('controlCajaApp').controller('MenuCtrl',menuCtrl); 8 | }()); -------------------------------------------------------------------------------- /16-rest-sources/client/movimientosFactory.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | var movimientosFactory =   function ($resource)  { 4 | // Las factorias terminan siendo una agrupación de recursos 5 | // En situaciones complejas pueden usarse para configurar promesas, cachés... 6 | var factory  =   {}; 7 | // Estamos devolviendo recursos, que internamente son promesas 8 | factory.movimientos =   $resource("/api/priv/movimientos/"); 9 | factory.total =  $resource("/api/priv/total/"); 10 | return factory; 11 | 12 | // Realmente los métodos crud desaparecen 13 | 14 | 15 | // una alternativa es devolver las promesas y ocultar las llamadas 16 | // pero genera más código del necesario 17 | //factory.total.gettingTotal =  $resource("/api/priv/total/").get().$promise; 18 | 19 | }; 20 | 21 | angular.module('controlCajaApp').factory('movimientosFactory', movimientosFactory); 22 | }()); -------------------------------------------------------------------------------- /16-rest-sources/client/not-found.html: -------------------------------------------------------------------------------- 1 |
2 |

No se ha encontrado lo que buscabas

3 |
-------------------------------------------------------------------------------- /16-rest-sources/client/registroCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var registroCtrl = function ($rootScope, $state, $http, $cookieStore) { 3 | var urlBase = "http://localhost:3000/api/"; 4 | var vm = this; 5 | vm.usuario = {}; 6 | vm.entrar = function () { 7 | $http.post(urlBase + 'sesiones/', vm.usuario) 8 | .success(function (data) { 9 | $rootScope.nombre = vm.usuario.email; 10 | $rootScope.mensaje = 'recién entrado'; 11 | $cookieStore.put("sessionId", data); 12 | $state.go("total"); 13 | }); 14 | } 15 | vm.registrar = function () { 16 | $http.post(urlBase + 'usuarios/', vm.usuario) 17 | .success(function (data) { 18 | $rootScope.nombre = vm.usuario.email; 19 | $rootScope.mensaje = 'recién creado'; 20 | $cookieStore.put("sessionId", data); 21 | $state.go("total"); 22 | }); 23 | } 24 | } 25 | angular.module('controlCajaApp').controller('RegistroCtrl', registroCtrl); 26 | }()); -------------------------------------------------------------------------------- /16-rest-sources/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ControlCashFlow", 3 | "version": "0.0.0", 4 | "description": "Controla tu flujo de caja", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Alberto Basalo", 10 | "license": "BSD-2-Clause", 11 | "dependencies": { 12 | "express": "~4.1.1", 13 | "body-parser": "~1.0.2" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /17-rest-advance/client/app.js: -------------------------------------------------------------------------------- 1 | angular.module('controlCajaApp', ['ui.router','ngCookies', 'ngResource']); 2 | 3 | // ui-router permite trabajr con parámetros 4 | // Los parámetros conforman urls pero se tratan como 'parametros' de un estado 5 | angular.module('controlCajaApp').config(function ($stateProvider,$locationProvider) { 6 | $stateProvider 7 | .state('total', { 8 | url: '/', 9 | controller: 'CajaCtrl as caja', 10 | templateUrl: 'total.html' 11 | }) 12 | .state('nuevo', { 13 | url: '/nuevo', 14 | controller: 'CajaCtrl as caja', 15 | templateUrl: 'nuevo.html' 16 | }) 17 | .state('lista', { 18 | url: '/lista', 19 | controller: 'CajaCtrl as caja', 20 | templateUrl: 'lista.html' 21 | }) 22 | .state('movimiento', { 23 | url: '/movimiento/:id', // declaracion de parametros en rutas 24 | controller: 'MovimientoCtrl as vm', 25 | templateUrl: 'movimiento.html' 26 | }) 27 | .state('registro', { 28 | url: '/registro', 29 | controller: 'RegistroCtrl as registro', 30 | templateUrl: 'registro.html' 31 | }) 32 | .state('not-found', { 33 | url: '*path', 34 | controller: 'CajaCtrl as caja', 35 | templateUrl: 'total.html' 36 | }); 37 | }); -------------------------------------------------------------------------------- /17-rest-advance/client/appHttpLog.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | function configuradorInterceptores($httpProvider) { 4 | $httpProvider.interceptors.push(funcionInterceptoraLog); 5 | } 6 | 7 | // Esta función se especializa en escribir en la consola 8 | // información sobre llamadas http 9 | function funcionInterceptoraLog($log) { 10 | 11 | var interceptor = {}; 12 | 13 | interceptor.request = function (request) { 14 | $log.info('request:' + request.url); 15 | return request ; 16 | }; 17 | 18 | interceptor.responseError = function (response) { 19 | $log.error("excepción: " + response.status + " de :" + response.config.url); 20 | } 21 | 22 | return interceptor; 23 | } 24 | 25 | // Podemos tener varios interceptores con funionalidades específicas 26 | angular.module('controlCajaApp').config(configuradorInterceptores); 27 | }()); -------------------------------------------------------------------------------- /17-rest-advance/client/appSecurity.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | function configuradorInterceptores($httpProvider) { 3 | $httpProvider.interceptors.push(funcionInterceptoraSeguridad); 4 | } 5 | 6 | function funcionInterceptoraSeguridad($q, $injector, $cookieStore, $rootScope) { 7 | 8 | var interceptor = {}; 9 | interceptor.request = function (request) { 10 | request.headers["sessionId"] = $cookieStore.get("sessionId"); 11 | return request || $q.when(request); 12 | }; 13 | interceptor.responseError = function (response) { 14 | var state = $injector.get('$state'); 15 | if (response.status === 401) { 16 | $rootScope.mensaje = "No hay derecho!!!"; 17 | state.go('registro'); 18 | } else if (response.status === 419) { 19 | $rootScope.mensaje = "Estoy caduco!!!"; 20 | $cookieStore.remove("sessionId") 21 | state.go('registro'); 22 | }; 23 | return $q.reject(response); 24 | } 25 | return interceptor; 26 | } 27 | 28 | angular.module('controlCajaApp').config(configuradorInterceptores); 29 | }()); -------------------------------------------------------------------------------- /17-rest-advance/client/cajaCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var cajaCtrl = function (maestrosFactory, movimientosFactory) { 3 | var vm = this; 4 | 5 | vm.titulo = "Controla tu Cash Flow"; 6 | 7 | vm.maestros = maestrosFactory.get(); 8 | 9 | vm.nuevoMovimiento = new movimientosFactory.movimientos(); 10 | vm.nuevoMovimiento.esIngreso =1; 11 | vm.nuevoMovimiento.fecha = new Date(); 12 | 13 | vm.movimientos = movimientosFactory.movimientos.query(); 14 | 15 | vm.total = movimientosFactory.total.get(); 16 | 17 | vm.guardarMovimiento = function () { 18 | vm.nuevoMovimiento.tipo = vm.tipo(vm.nuevoMovimiento); 19 | vm.nuevoMovimiento.$save() 20 | .then(function(postedData){ 21 | vm.movimientos = movimientosFactory.movimientos.query(); 22 | vm.total = movimientosFactory.total.get(); 23 | vm.nuevoMovimiento.importe = 0; 24 | }); 25 | } 26 | vm.balance = function () { 27 | return vm.total.ingresos - vm.total.gastos 28 | } 29 | vm.tipo = function (movimiento) { 30 | return movimiento.esIngreso && 'Ingreso' || 'Gasto' 31 | } 32 | } 33 | angular.module('controlCajaApp').controller('CajaCtrl', cajaCtrl); 34 | }()); -------------------------------------------------------------------------------- /17-rest-advance/client/maestrosFactory.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var maestrosFactory =   function ($resource)  { 3 | // Los resursos son totalmente configurables 4 | // Una de sus utilidades de 'fábrica' de una caché simple pero potente 5 | return $resource("/api/pub/maestros/",{},{get: {cache: true}}); 6 | }; 7 | 8 | angular.module('controlCajaApp').factory('maestrosFactory', maestrosFactory); 9 | }()); -------------------------------------------------------------------------------- /17-rest-advance/client/menuCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var menuCtrl = function ($state) { 3 | this.isActive = function (estado) { 4 | return $state.is(estado); 5 | } 6 | } 7 | angular.module('controlCajaApp').controller('MenuCtrl',menuCtrl); 8 | }()); -------------------------------------------------------------------------------- /17-rest-advance/client/movimientoCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | // $stateParams es el servicio de ui-router para acceder a los parámetros de la ruta 3 | var movimientoCtrl = function ($stateParams, movimientosFactory) { 4 | var vm = this; 5 | // El acceso es por nombre de parámetro 6 | var movId = $stateParams.id; 7 | // Se llama al recurso expuesto por la factoría de recursos 8 | // enviándole el objeto que sirve de consulta al método get 9 | vm.movimiento = movimientosFactory.movimientos.get({id:movId}); 10 | } 11 | angular.module('controlCajaApp').controller('MovimientoCtrl', movimientoCtrl); 12 | }()); -------------------------------------------------------------------------------- /17-rest-advance/client/movimientosFactory.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | var movimientosFactory =   function ($resource)  { 4 | 5 | var factory  =   {}; 6 | 7 | // $resource("/api/priv/movimientos/"); 8 | // El uso de parametros en los recursos debe especificarse 9 | // Indicando el nombre local y el remoto 10 | // En la url va el nombre remoto 11 | // En el objeto se repute ese nombre como clave y se dice que propiedad será la que lo lleve 12 | // La propiedad empieza por @ 13 | factory.movimientos =  $resource("/api/priv/movimientos/:id", { 14 | id: "@id" 15 | }) 16 | 17 | 18 | 19 | factory.total = $resource("/api/priv/total/"); 20 | 21 | return factory; 22 | }; 23 | 24 | angular.module('controlCajaApp').factory('movimientosFactory', movimientosFactory); 25 | }()); -------------------------------------------------------------------------------- /17-rest-advance/client/not-found.html: -------------------------------------------------------------------------------- 1 |
2 |

No se ha encontrado lo que buscabas

3 |
-------------------------------------------------------------------------------- /17-rest-advance/client/registroCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var registroCtrl = function ($rootScope, $state, $http, $cookieStore) { 3 | var urlBase = "http://localhost:3000/api/"; 4 | var vm = this; 5 | vm.usuario = {}; 6 | vm.entrar = function () { 7 | $http.post(urlBase + 'sesiones/', vm.usuario) 8 | .success(function (data) { 9 | $rootScope.nombre = vm.usuario.email; 10 | $rootScope.mensaje = 'recién entrado'; 11 | $cookieStore.put("sessionId", data); 12 | $state.go("total"); 13 | }); 14 | } 15 | vm.registrar = function () { 16 | $http.post(urlBase + 'usuarios/', vm.usuario) 17 | .success(function (data) { 18 | $rootScope.nombre = vm.usuario.email; 19 | $rootScope.mensaje = 'recién creado'; 20 | $cookieStore.put("sessionId", data); 21 | $state.go("total"); 22 | }); 23 | } 24 | } 25 | angular.module('controlCajaApp').controller('RegistroCtrl', registroCtrl); 26 | }()); -------------------------------------------------------------------------------- /17-rest-advance/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ControlCashFlow", 3 | "version": "0.0.0", 4 | "description": "Controla tu flujo de caja", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Alberto Basalo", 10 | "license": "BSD-2-Clause", 11 | "dependencies": { 12 | "express": "~4.12.1", 13 | "body-parser": "~1.0.2" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /18-angular-con-filtro/client/app.js: -------------------------------------------------------------------------------- 1 | // Incluimos referencia a un módulo propio, con un prefijo propio 2 | angular.module('controlCajaApp', ['ui.router','ngCookies', 'ngResource', 'abFiltros']); 3 | 4 | angular.module('controlCajaApp').config(function ($stateProvider) { 5 | $stateProvider 6 | .state('total', { 7 | url: '/', 8 | controller: 'CajaCtrl as caja', 9 | templateUrl: 'total.html' 10 | }) 11 | .state('nuevo', { 12 | url: '/nuevo', 13 | controller: 'CajaCtrl as caja', 14 | templateUrl: 'nuevo.html' 15 | }) 16 | .state('lista', { 17 | url: '/lista', 18 | controller: 'CajaCtrl as caja', 19 | templateUrl: 'lista.html' 20 | }) 21 | .state('movimiento', { 22 | url: '/movimiento/:id', 23 | controller: 'MovimientoCtrl as vm', 24 | templateUrl: 'movimiento.html' 25 | }) 26 | .state('registro', { 27 | url: '/registro', 28 | controller: 'RegistroCtrl as registro', 29 | templateUrl: 'registro.html' 30 | }) 31 | .state('not-found', { 32 | url: '*path', 33 | controller: 'CajaCtrl as caja', 34 | templateUrl: 'total.html' 35 | }); 36 | }); -------------------------------------------------------------------------------- /18-angular-con-filtro/client/appHttpLog.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | function configuradorInterceptores($httpProvider) { 4 | $httpProvider.interceptors.push(funcionInterceptoraLog); 5 | } 6 | 7 | // Esta función se especializa en escribir en la consola 8 | // información sobre llamadas http 9 | function funcionInterceptoraLog($log) { 10 | 11 | var interceptor = {}; 12 | interceptor.request = function (request) { 13 | $log.info('request:' + request.url); 14 | return request ; 15 | }; 16 | interceptor.responseError = function (response) { 17 | $log.error("excepción: " + response.status + " de :" + response.config.url); 18 | } 19 | return interceptor; 20 | } 21 | 22 | angular.module('controlCajaApp').config(configuradorInterceptores); 23 | }()); -------------------------------------------------------------------------------- /18-angular-con-filtro/client/appSecurity.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | function configuradorInterceptores($httpProvider) { 3 | $httpProvider.interceptors.push(funcionInterceptoraSeguridad); 4 | } 5 | 6 | function funcionInterceptoraSeguridad($q, $injector, $cookieStore, $rootScope) { 7 | 8 | var interceptor = {}; 9 | interceptor.request = function (request) { 10 | request.headers["sessionId"] = $cookieStore.get("sessionId"); 11 | return request || $q.when(request); 12 | }; 13 | interceptor.responseError = function (response) { 14 | var state = $injector.get('$state'); 15 | if (response.status === 401) { 16 | $rootScope.mensaje = "No hay derecho!!!"; 17 | state.go('registro'); 18 | } else if (response.status === 419) { 19 | $rootScope.mensaje = "Estoy caduco!!!"; 20 | $cookieStore.remove("sessionId") 21 | state.go('registro'); 22 | }; 23 | return $q.reject(response); 24 | } 25 | return interceptor; 26 | } 27 | 28 | angular.module('controlCajaApp').config(configuradorInterceptores); 29 | }()); -------------------------------------------------------------------------------- /18-angular-con-filtro/client/cajaCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var cajaCtrl = function (maestrosFactory, movimientosFactory) { 3 | var vm = this; 4 | 5 | vm.titulo = "Controla tu Cash Flow"; 6 | 7 | vm.maestros = maestrosFactory.get(); 8 | 9 | vm.nuevoMovimiento = new movimientosFactory.movimientos(); 10 | vm.nuevoMovimiento.esIngreso =1; 11 | vm.nuevoMovimiento.fecha = new Date(); 12 | 13 | vm.movimientos = movimientosFactory.movimientos.query(); 14 | 15 | vm.total = movimientosFactory.total.get(); 16 | 17 | vm.guardarMovimiento = function () { 18 | vm.nuevoMovimiento.tipo = vm.tipo(vm.nuevoMovimiento); 19 | vm.nuevoMovimiento.$save() 20 | .then(function(postedData){ 21 | vm.movimientos = movimientosFactory.movimientos.query(); 22 | vm.total = movimientosFactory.total.get(); 23 | vm.nuevoMovimiento.importe = 0; 24 | }); 25 | } 26 | vm.balance = function () { 27 | return vm.total.ingresos - vm.total.gastos 28 | } 29 | vm.tipo = function (movimiento) { 30 | return movimiento.esIngreso && 'Ingreso' || 'Gasto' 31 | } 32 | } 33 | angular.module('controlCajaApp').controller('CajaCtrl', cajaCtrl); 34 | }()); -------------------------------------------------------------------------------- /18-angular-con-filtro/client/lista.html: -------------------------------------------------------------------------------- 1 |
2 |

Estos son tus movimientos recientes.

3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 15 | 16 | 17 | 19 | 20 | 21 | 22 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
IdFecha 14 | TipoCategoríaImporte 18 |
{{movimiento.id }} {{movimiento.fecha | date}}{{movimiento.tipo}}{{movimiento.categoria}}{{movimiento.importe | number:2}} €
32 |
-------------------------------------------------------------------------------- /18-angular-con-filtro/client/maestrosFactory.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var maestrosFactory =   function ($resource)  { 3 | // Los resursos son totalmente configurables 4 | // Una de sus utilidades de 'fábrica' de una caché simple pero potente 5 | return $resource("/api/pub/maestros/",{},{get: {cache: true}}); 6 | }; 7 | 8 | angular.module('controlCajaApp').factory('maestrosFactory', maestrosFactory); 9 | }()); -------------------------------------------------------------------------------- /18-angular-con-filtro/client/menuCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var menuCtrl = function ($state) { 3 | this.isActive = function (estado) { 4 | return $state.is(estado); 5 | } 6 | } 7 | angular.module('controlCajaApp').controller('MenuCtrl',menuCtrl); 8 | }()); -------------------------------------------------------------------------------- /18-angular-con-filtro/client/movimientoCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | // $stateParams es el servicio de ui-router para acceder a los parámetros de la ruta 3 | var movimientoCtrl = function ($stateParams, movimientosFactory) { 4 | var vm = this; 5 | // El acceso es por nombre de parámetro 6 | var movId = $stateParams.id; 7 | vm.movimiento = movimientosFactory.movimientos.get({id:movId}); 8 | } 9 | angular.module('controlCajaApp').controller('MovimientoCtrl', movimientoCtrl); 10 | }()); -------------------------------------------------------------------------------- /18-angular-con-filtro/client/movimientosFactory.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | var movimientosFactory =   function ($resource)  { 4 | 5 | var factory  =   {}; 6 | 7 | // $resource("/api/priv/movimientos/"); 8 | // El uso de parametros en los recursos debe especificarse 9 | // Indicando el nombre local y el remoto 10 | // En la url va el nombre remoto 11 | // En el objeto se repute ese nombre como clave y se dice que propiedad será la que lo lleve 12 | // La propiedad empieza por @ 13 | factory.movimientos =  $resource("/api/priv/movimientos/:id", { 14 | id: "@id" 15 | }) 16 | 17 | 18 | 19 | factory.total = $resource("/api/priv/total/"); 20 | 21 | return factory; 22 | }; 23 | 24 | angular.module('controlCajaApp').factory('movimientosFactory', movimientosFactory); 25 | }()); -------------------------------------------------------------------------------- /18-angular-con-filtro/client/not-found.html: -------------------------------------------------------------------------------- 1 |
2 |

No se ha encontrado lo que buscabas

3 |
-------------------------------------------------------------------------------- /18-angular-con-filtro/client/registroCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var registroCtrl = function ($rootScope, $state, $http, $cookieStore) { 3 | var urlBase = "http://localhost:3000/api/"; 4 | var vm = this; 5 | vm.usuario = {}; 6 | vm.entrar = function () { 7 | $http.post(urlBase + 'sesiones/', vm.usuario) 8 | .success(function (data) { 9 | $rootScope.nombre = vm.usuario.email; 10 | $rootScope.mensaje = 'recién entrado'; 11 | $cookieStore.put("sessionId", data); 12 | $state.go("total"); 13 | }); 14 | } 15 | vm.registrar = function () { 16 | $http.post(urlBase + 'usuarios/', vm.usuario) 17 | .success(function (data) { 18 | $rootScope.nombre = vm.usuario.email; 19 | $rootScope.mensaje = 'recién creado'; 20 | $cookieStore.put("sessionId", data); 21 | $state.go("total"); 22 | }); 23 | } 24 | } 25 | angular.module('controlCajaApp').controller('RegistroCtrl', registroCtrl); 26 | }()); -------------------------------------------------------------------------------- /18-angular-con-filtro/cors.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EscuelaIt/Curso-angularjs-FS-2015/913a55f705c5bbc3191ae30e54ac09a9aa94941e/18-angular-con-filtro/cors.md -------------------------------------------------------------------------------- /18-angular-con-filtro/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ControlCashFlow", 3 | "version": "0.0.0", 4 | "description": "Controla tu flujo de caja", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Alberto Basalo", 10 | "license": "BSD-2-Clause", 11 | "dependencies": { 12 | "express": "~4.12.1", 13 | "body-parser": "~1.0.2" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /19-directivas/client/app.js: -------------------------------------------------------------------------------- 1 | // Incluimos referencia al módulo de directivas 2 | angular.module('controlCajaApp', ['ui.router','ngCookies', 'ngResource', 'abFiltros','abDirectivas']); 3 | 4 | angular.module('controlCajaApp').config(function ($stateProvider,$locationProvider) { 5 | $stateProvider 6 | .state('total', { 7 | url: '/', 8 | controller: 'CajaCtrl as caja', 9 | templateUrl: 'total.html' 10 | }) 11 | .state('nuevo', { 12 | url: '/nuevo', 13 | controller: 'CajaCtrl as caja', 14 | templateUrl: 'nuevo.html' 15 | }) 16 | .state('lista', { 17 | url: '/lista', 18 | controller: 'CajaCtrl as caja', 19 | templateUrl: 'lista.html' 20 | }) 21 | .state('movimiento', { 22 | url: '/movimiento/:id', // declaracion de parametros en rutas 23 | controller: 'MovimientoCtrl as vm', 24 | templateUrl: 'movimiento.html' 25 | }) 26 | .state('registro', { 27 | url: '/registro', 28 | controller: 'RegistroCtrl as registro', 29 | templateUrl: 'registro.html' 30 | }) 31 | .state('not-found', { 32 | url: '*path', 33 | controller: 'CajaCtrl as caja', 34 | templateUrl: 'total.html' 35 | }); 36 | }); -------------------------------------------------------------------------------- /19-directivas/client/appHttpLog.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | function configuradorInterceptores($httpProvider) { 4 | $httpProvider.interceptors.push(funcionInterceptoraLog); 5 | } 6 | 7 | // Esta función se especializa en escribir en la consola 8 | // información sobre llamadas http 9 | function funcionInterceptoraLog($log) { 10 | 11 | var interceptor = {}; 12 | interceptor.request = function (request) { 13 | $log.info('request:' + request.url); 14 | return request ; 15 | }; 16 | interceptor.responseError = function (response) { 17 | $log.error("excepción: " + response.status + " de :" + response.config.url); 18 | } 19 | return interceptor; 20 | } 21 | 22 | angular.module('controlCajaApp').config(configuradorInterceptores); 23 | }()); -------------------------------------------------------------------------------- /19-directivas/client/appSecurity.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | function configuradorInterceptores($httpProvider) { 3 | $httpProvider.interceptors.push(funcionInterceptoraSeguridad); 4 | } 5 | 6 | function funcionInterceptoraSeguridad($q, $injector, $cookieStore, $rootScope) { 7 | 8 | var interceptor = {}; 9 | interceptor.request = function (request) { 10 | request.headers["sessionId"] = $cookieStore.get("sessionId"); 11 | return request || $q.when(request); 12 | }; 13 | interceptor.responseError = function (response) { 14 | var state = $injector.get('$state'); 15 | if (response.status === 401) { 16 | $rootScope.mensaje = "No hay derecho!!!"; 17 | state.go('registro'); 18 | } else if (response.status === 419) { 19 | $rootScope.mensaje = "Estoy caduco!!!"; 20 | $cookieStore.remove("sessionId") 21 | state.go('registro'); 22 | }; 23 | return $q.reject(response); 24 | } 25 | return interceptor; 26 | } 27 | 28 | angular.module('controlCajaApp').config(configuradorInterceptores); 29 | }()); -------------------------------------------------------------------------------- /19-directivas/client/cajaCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var cajaCtrl = function (maestrosFactory, movimientosFactory) { 3 | var vm = this; 4 | 5 | vm.titulo = "Controla tu Cash Flow"; 6 | 7 | vm.maestros = maestrosFactory.get(); 8 | 9 | vm.nuevoMovimiento = new movimientosFactory.movimientos(); 10 | vm.nuevoMovimiento.esIngreso =1; 11 | vm.nuevoMovimiento.fecha = new Date(); 12 | 13 | vm.movimientos = movimientosFactory.movimientos.query(); 14 | 15 | vm.total = movimientosFactory.total.get(); 16 | 17 | vm.guardarMovimiento = function () { 18 | vm.nuevoMovimiento.tipo = vm.tipo(vm.nuevoMovimiento); 19 | vm.nuevoMovimiento.$save() 20 | .then(function(postedData){ 21 | vm.movimientos = movimientosFactory.movimientos.query(); 22 | vm.total = movimientosFactory.total.get(); 23 | vm.nuevoMovimiento.importe = 0; 24 | }); 25 | } 26 | vm.balance = function () { 27 | return vm.total.ingresos - vm.total.gastos 28 | } 29 | vm.tipo = function (movimiento) { 30 | return movimiento.esIngreso && 'Ingreso' || 'Gasto' 31 | } 32 | } 33 | angular.module('controlCajaApp').controller('CajaCtrl', cajaCtrl); 34 | }()); -------------------------------------------------------------------------------- /19-directivas/client/lista.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | Estos son tus movimientos recientes. 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 15 | 16 | 17 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 28 | 29 |
IdFecha 14 | TipoCategoríaImporte 18 |
30 |
-------------------------------------------------------------------------------- /19-directivas/client/maestrosFactory.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var maestrosFactory =   function ($resource)  { 3 | // Los resursos son totalmente configurables 4 | // Una de sus utilidades de 'fábrica' de una caché simple pero potente 5 | return $resource("/api/pub/maestros/",{},{get: {cache: true}}); 6 | }; 7 | 8 | angular.module('controlCajaApp').factory('maestrosFactory', maestrosFactory); 9 | }()); -------------------------------------------------------------------------------- /19-directivas/client/menuCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var menuCtrl = function ($state) { 3 | this.isActive = function (estado) { 4 | return $state.is(estado); 5 | } 6 | } 7 | angular.module('controlCajaApp').controller('MenuCtrl',menuCtrl); 8 | }()); -------------------------------------------------------------------------------- /19-directivas/client/movimientoCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | // $stateParams es el servicio de ui-router para acceder a los parámetros de la ruta 3 | var movimientoCtrl = function ($stateParams, movimientosFactory) { 4 | var vm = this; 5 | // El acceso es por nombre de parámetro 6 | var movId = $stateParams.id; 7 | vm.movimiento = movimientosFactory.movimientos.get({id:movId}); 8 | } 9 | angular.module('controlCajaApp').controller('MovimientoCtrl', movimientoCtrl); 10 | }()); -------------------------------------------------------------------------------- /19-directivas/client/movimientosFactory.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | var movimientosFactory =   function ($resource)  { 4 | 5 | var factory  =   {}; 6 | 7 | // $resource("/api/priv/movimientos/"); 8 | // El uso de parametros en los recursos debe especificarse 9 | // Indicando el nombre local y el remoto 10 | // En la url va el nombre remoto 11 | // En el objeto se repute ese nombre como clave y se dice que propiedad será la que lo lleve 12 | // La propiedad empieza por @ 13 | factory.movimientos =  $resource("/api/priv/movimientos/:id", { 14 | id: "@id" 15 | }) 16 | 17 | 18 | 19 | factory.total = $resource("/api/priv/total/"); 20 | 21 | return factory; 22 | }; 23 | 24 | angular.module('controlCajaApp').factory('movimientosFactory', movimientosFactory); 25 | }()); -------------------------------------------------------------------------------- /19-directivas/client/not-found.html: -------------------------------------------------------------------------------- 1 |
2 |

No se ha encontrado lo que buscabas

3 |
-------------------------------------------------------------------------------- /19-directivas/client/registroCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var registroCtrl = function ($rootScope, $state, $http, $cookieStore) { 3 | var urlBase = "http://localhost:3000/api/"; 4 | var vm = this; 5 | vm.usuario = {}; 6 | vm.entrar = function () { 7 | $http.post(urlBase + 'sesiones/', vm.usuario) 8 | .success(function (data) { 9 | $rootScope.nombre = vm.usuario.email; 10 | $rootScope.mensaje = 'recién entrado'; 11 | $cookieStore.put("sessionId", data); 12 | $state.go("total"); 13 | }); 14 | } 15 | vm.registrar = function () { 16 | $http.post(urlBase + 'usuarios/', vm.usuario) 17 | .success(function (data) { 18 | $rootScope.nombre = vm.usuario.email; 19 | $rootScope.mensaje = 'recién creado'; 20 | $cookieStore.put("sessionId", data); 21 | $state.go("total"); 22 | }); 23 | } 24 | } 25 | angular.module('controlCajaApp').controller('RegistroCtrl', registroCtrl); 26 | }()); -------------------------------------------------------------------------------- /19-directivas/client/total.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 7 | 8 | Comprueba de dónde viene y a dónde va tu dinero. 9 |
10 |
11 |
12 |

13 | 14 | {{ caja.total.ingresos | number:2 }} € 15 | 16 |

17 |

Total ingresos

18 | Acumulado 19 |
20 |
21 |

22 | 23 | {{ caja.total.gastos | number:2 }} € 24 | 25 |

26 |

Total gastos

27 | Acumulado 28 |
29 |
30 |

31 | 32 | {{ caja.balance() | number:2 }} € 33 | 34 |

35 |

Balance

36 | Ingresos-Gastos 37 |
38 |
39 |
40 |
-------------------------------------------------------------------------------- /19-directivas/client/tpl-cabecera.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Cash Flow

4 |
5 |
6 |
7 | -------------------------------------------------------------------------------- /19-directivas/client/tpl-fila-movimiento.html: -------------------------------------------------------------------------------- 1 | 2 | {{movimientoplantilla.id }} 3 | {{movimientoplantilla.fecha | date}} 4 | {{movimientoplantilla.tipo}} 5 | {{movimientoplantilla.categoria}} 6 | 7 | {{movimientoplantilla.importe | number:2}} € 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /19-directivas/client/tpl-valoracion.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | 9 | * 10 | 11 | 12 | -------------------------------------------------------------------------------- /19-directivas/client/valoracion.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var valoracion = function () { 3 | return { 4 | restrict: 'AE', 5 | templateUrl: '/tpl-valoracion.html', 6 | scope: { 7 | valor: '=', 8 | max: '@', 9 | soloLectura: '@' 10 | }, 11 | link: function (scope, elem, attrs) { 12 | function actualizar() { 13 | if(!scope.valor)scope.valor=1; 14 | scope.estrellas = []; 15 | for (var i = 0; i < scope.max; i++) { 16 | var estrella = { 17 | marcada: (i < scope.valor) 18 | }; 19 | scope.estrellas.push(estrella); 20 | } 21 | }; 22 | 23 | scope.marcar = function (indice) { 24 | if (scope.soloLectura && scope.soloLectura === 'true') { 25 | return; 26 | } 27 | scope.valor = indice + 1; 28 | actualizar(); 29 | }; 30 | actualizar(); 31 | } 32 | } 33 | } 34 | 35 | angular.module('abDirectivas') 36 | .directive('abValoracion', valoracion); 37 | 38 | }()); -------------------------------------------------------------------------------- /19-directivas/directivas.md: -------------------------------------------------------------------------------- 1 | Directivas 2 | ========== 3 | 4 | - Se usan de forma **declarativa** en el HTML 5 | - Su función es extender y enriquecer el HTML encapsulando el **acceso al DOM** 6 | - Se definen como **objetos JS** con propiedades específicas 7 | 8 | Propiedades 9 | ----------- 10 | 11 | ### Restrict 12 | Sirve para determinar dónde se puede aplicar la directiva 13 | 14 | Valores posibles: 15 | 16 | - **A** – Attribute `
` 17 | - **E** – Element ` ` 18 | - **C** – Class `
` 19 | - **M** – Comment ` ` 20 | 21 | ### Replace 22 | Indica si el elemento al que se aplica debe ser sustituído por el resultado de la ejecución 23 | 24 | ### Transclude 25 | Indica si el elemento al que se aplicaca incluirá el resultado de la ejecución de la directiva en su interior 26 | 27 | ### Template y template URL 28 | Cadena de texto o enlace a fichero que contine el HTML que va a devolver la directiva 29 | 30 | ### Scope 31 | Intercambio de datos con el elemento que declara la directiva. 32 | Valores posibles: 33 | 34 | - **@** Interpolating, para enlazar un texto dentro de la directiva. ` scope: { soloLectura: '@' } ` 35 | - **=** Data bind, un objeto para doble-enlace que la directiva pueda cambiar ` scope: { valor: '=alias' } ` 36 | - **&** Expression `scope: { onEvaluado: '&' } ` 37 | 38 | 39 | ### Link 40 | Una función que enlazará la directiva con el scope 41 | 42 | ### Compile 43 | Una función que podrá manipular el DOM creando una función link 44 | 45 | ### Controller 46 | Una función que actuará como contrlador para esta directiva 47 | -------------------------------------------------------------------------------- /19-directivas/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ControlCashFlow", 3 | "version": "0.0.0", 4 | "description": "Controla tu flujo de caja", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Alberto Basalo", 10 | "license": "BSD-2-Clause", 11 | "dependencies": { 12 | "express": "~4.12.1", 13 | "body-parser": "~1.0.2" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /19-directivas/recursos.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EscuelaIt/Curso-angularjs-FS-2015/913a55f705c5bbc3191ae30e54ac09a9aa94941e/19-directivas/recursos.md -------------------------------------------------------------------------------- /20-e2e/Protractor.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EscuelaIt/Curso-angularjs-FS-2015/913a55f705c5bbc3191ae30e54ac09a9aa94941e/20-e2e/Protractor.pdf -------------------------------------------------------------------------------- /20-e2e/conf.js: -------------------------------------------------------------------------------- 1 | var HtmlReporter = require('protractor-html-screenshot-reporter'); 2 | 3 | // configuración de reporter para generar screenshots e informes 4 | var reporter = new HtmlReporter({ 5 | baseDirectory: './screenshots', 6 | // takeScreenShotsOnlyForFailedSpecs: true, 7 | docName: 'protractor-report.html' 8 | }); 9 | 10 | // configuración básica del protractor 11 | exports.config = { 12 | // ruta del web driver 13 | seleniumAddress: 'http://localhost:4444/wd/hub', 14 | 15 | 16 | // Array de pruebas secuenciales 17 | specs: ['./index/spec.js','./registro/spec.js','./ingreso/spec.js'], 18 | 19 | 20 | 21 | // Agregar el reporte html 22 | onPrepare: function () { 23 | jasmine.getEnv().addReporter(reporter); 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /20-e2e/index/conf.js: -------------------------------------------------------------------------------- 1 | exports.config = { 2 | seleniumAddress: 'http://localhost:4444/wd/hub', 3 | specs: ['spec.js'] 4 | } -------------------------------------------------------------------------------- /20-e2e/index/spec.js: -------------------------------------------------------------------------------- 1 | // host que vamos a probar 2 | var host = 'http://localhost:3000/#/'; 3 | // Cada describe es un grupo de pruebas 4 | describe('index elements', function () { 5 | 6 | // cada it es una prueba 7 | it('should have a title', function () { 8 | // se pide y espera por una página 9 | browser.get(host); 10 | // condición que se prueba 11 | var theTitle = browser.getTitle(); 12 | expect(theTitle).toEqual('Control de Caja'); 13 | }); 14 | 15 | it('should have navbar', function () { 16 | browser.get(host); 17 | // se usa un api propio para acceder al DOM 18 | var navbar = element(by.name('navbar')); 19 | // comprobaciones de existencia 20 | expect(navbar.isPresent()).toBe(true); 21 | }); 22 | 23 | it('should have three menu items', function() { 24 | browser.get(host); 25 | var listItems = element.all(by.tagName ('li')); 26 | // comprobaciones de número 27 | expect(listItems.count()).toBe(3); 28 | }); 29 | }); -------------------------------------------------------------------------------- /20-e2e/ingreso/conf.js: -------------------------------------------------------------------------------- 1 | exports.config = { 2 | seleniumAddress: 'http://localhost:4444/wd/hub', 3 | specs: ['spec.js'] 4 | } -------------------------------------------------------------------------------- /20-e2e/ingreso/spec.js: -------------------------------------------------------------------------------- 1 | var host = 'http://localhost:3000/#/'; 2 | describe('ingreso |', function () { 3 | it('should save an ingreso', function () { 4 | browser.get(host); 5 | var menuNuevo = element(by.name('menu-nuevo')); 6 | // Navegación a otra página 7 | menuNuevo.click() 8 | .then(function () { 9 | // función asíncrona 10 | var importe = element(by.name('importe')); 11 | importe.clear(); 12 | importe.sendKeys('2000'); 13 | element(by.name('guardar')).click(); 14 | // comprobar en totales 15 | var menutotal = element(by.name('menu-total')); 16 | menutotal.click() 17 | .then(function () { 18 | var ingresos = element(by.name('ingresos')); 19 | // comprobamos el texto, incluído el formato... 20 | expect(ingresos.getText()).toEqual('2,000.00 €'); 21 | }); 22 | }); 23 | }); 24 | }); -------------------------------------------------------------------------------- /20-e2e/registro/conf.js: -------------------------------------------------------------------------------- 1 | exports.config = { 2 | seleniumAddress: 'http://localhost:4444/wd/hub', 3 | specs: ['spec.js'] 4 | } -------------------------------------------------------------------------------- /20-e2e/registro/spec.js: -------------------------------------------------------------------------------- 1 | var host = 'http://localhost:3000/#/'; 2 | describe('registro |', function () { 3 | it('should perform a registro', function () { 4 | browser.get(host); 5 | var email = element(by.name('email')); 6 | email.clear(); 7 | email.sendKeys('albertobasalo@agorabinaria.com'); 8 | var password = element(by.name('password')); 9 | password.clear(); 10 | password.sendKeys('1234'); 11 | var registrar = element(by.name('registrar')); 12 | registrar.click() 13 | .then(function () { 14 | var ingresos = element(by.name('ingresos')); 15 | // comprobamos el texto, incluído el formato... 16 | expect(ingresos.getText()).toEqual('0.00 €'); 17 | }); 18 | }); 19 | 20 | 21 | it('should not allow to re-registro', function () { 22 | browser.get(host+"#/registro"); 23 | var email = element(by.name('email')); 24 | email.clear(); 25 | email.sendKeys('albertobasalo@agorabinaria.com'); 26 | var password = element(by.name('password')); 27 | password.clear(); 28 | password.sendKeys('1234'); 29 | var registrar = element(by.name('registrar')); 30 | registrar.click() 31 | .then(function () { 32 | var email = element(by.name('email')); 33 | expect(email.isPresent()).toBe(true); 34 | }); 35 | }); 36 | }); -------------------------------------------------------------------------------- /21-organizacion/client/app.js: -------------------------------------------------------------------------------- 1 | angular.module('controlCajaApp', ['ui.router','ngCookies', 'ngResource', 'abFiltros','abDirectivas']); 2 | 3 | angular.module('controlCajaApp').config(function ($stateProvider,$locationProvider) { 4 | $stateProvider 5 | .state('total', { 6 | url: '/', 7 | controller: 'CajaCtrl as caja', 8 | templateUrl: 'total.html' 9 | }) 10 | .state('nuevo', { 11 | url: '/nuevo', 12 | controller: 'CajaCtrl as caja', 13 | templateUrl: 'nuevo.html' 14 | }) 15 | .state('lista', { 16 | url: '/lista', 17 | controller: 'CajaCtrl as caja', 18 | templateUrl: 'lista.html' 19 | }) 20 | .state('movimiento', { 21 | url: '/movimiento/:id', 22 | controller: 'MovimientoCtrl as vm', 23 | templateUrl: 'movimiento.html' 24 | }) 25 | .state('registro', { 26 | url: '/registro', 27 | controller: 'RegistroCtrl as registro', 28 | templateUrl: 'registro.html' 29 | }) 30 | .state('not-found', { 31 | url: '*path', 32 | controller: 'CajaCtrl as caja', 33 | templateUrl: 'total.html' 34 | }); 35 | }); -------------------------------------------------------------------------------- /21-organizacion/client/appHttpLog.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | function configuradorInterceptores($httpProvider) { 4 | $httpProvider.interceptors.push(funcionInterceptoraLog); 5 | } 6 | 7 | function funcionInterceptoraLog($log) { 8 | 9 | var interceptor = {}; 10 | interceptor.request = function (request) { 11 | $log.info('request:' + request.url); 12 | return request ; 13 | }; 14 | interceptor.responseError = function (response) { 15 | $log.error("excepción: " + response.status + " de :" + response.config.url); 16 | } 17 | return interceptor; 18 | } 19 | 20 | angular.module('controlCajaApp').config(configuradorInterceptores); 21 | }()); -------------------------------------------------------------------------------- /21-organizacion/client/appSecurity.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | function configuradorInterceptores($httpProvider) { 3 | $httpProvider.interceptors.push(funcionInterceptoraSeguridad); 4 | } 5 | 6 | function funcionInterceptoraSeguridad($q, $injector, $cookieStore, $rootScope) { 7 | 8 | var interceptor = {}; 9 | interceptor.request = function (request) { 10 | request.headers["sessionId"] = $cookieStore.get("sessionId"); 11 | return request || $q.when(request); 12 | }; 13 | interceptor.responseError = function (response) { 14 | var state = $injector.get('$state'); 15 | if (response.status === 401) { 16 | $rootScope.mensaje = "No hay derecho!!!"; 17 | state.go('registro'); 18 | } else if (response.status === 419) { 19 | $rootScope.mensaje = "Estoy caduco!!!"; 20 | $cookieStore.remove("sessionId") 21 | state.go('registro'); 22 | }; 23 | return $q.reject(response); 24 | } 25 | return interceptor; 26 | } 27 | 28 | angular.module('controlCajaApp').config(configuradorInterceptores); 29 | }()); -------------------------------------------------------------------------------- /21-organizacion/client/cajaCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var cajaCtrl = function (maestrosFactory, movimientosFactory) { 3 | var vm = this; 4 | 5 | vm.titulo = "Controla tu Cash Flow"; 6 | 7 | vm.maestros = maestrosFactory.get(); 8 | 9 | vm.nuevoMovimiento = new movimientosFactory.movimientos(); 10 | vm.nuevoMovimiento.esIngreso = 1; 11 | vm.nuevoMovimiento.fecha = new Date(); 12 | 13 | vm.movimientos = movimientosFactory.movimientos.query(); 14 | 15 | vm.total = movimientosFactory.total.get(); 16 | 17 | vm.guardarMovimiento = function () { 18 | vm.nuevoMovimiento.tipo = vm.tipo(vm.nuevoMovimiento); 19 | vm.nuevoMovimiento.$save() 20 | .then(function (postedData) { 21 | vm.movimientos = movimientosFactory.movimientos.query(); 22 | vm.total = movimientosFactory.total.get(); 23 | vm.nuevoMovimiento.importe = 0; 24 | }); 25 | } 26 | vm.balance = function () { 27 | return vm.total.ingresos - vm.total.gastos 28 | } 29 | vm.tipo = function (movimiento) { 30 | return movimiento.esIngreso && 'Ingreso' || 'Gasto' 31 | } 32 | } 33 | angular.module('controlCajaApp').controller('CajaCtrl', cajaCtrl); 34 | }()); -------------------------------------------------------------------------------- /21-organizacion/client/lista.html: -------------------------------------------------------------------------------- 1 |
2 | Estos son tus movimientos recientes. 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | 16 | 18 | 19 | 20 | 21 | 22 | 26 | 27 |
IdFecha 13 | TipoCategoríaImporte 17 | Valoración
28 |
-------------------------------------------------------------------------------- /21-organizacion/client/maestrosFactory.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var maestrosFactory =   function ($resource)  { 3 | return $resource("/api/pub/maestros/",{},{get: {cache: true}}); 4 | }; 5 | 6 | angular.module('controlCajaApp').factory('maestrosFactory', maestrosFactory); 7 | }()); -------------------------------------------------------------------------------- /21-organizacion/client/menuCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var menuCtrl = function ($state) { 3 | this.isActive = function (estado) { 4 | return $state.is(estado); 5 | } 6 | } 7 | angular.module('controlCajaApp').controller('MenuCtrl',menuCtrl); 8 | }()); -------------------------------------------------------------------------------- /21-organizacion/client/movimientoCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var movimientoCtrl = function ($stateParams, movimientosFactory) { 3 | var vm = this; 4 | var movId = $stateParams.id; 5 | vm.movimiento = movimientosFactory.movimientos.get({id:movId}); 6 | } 7 | angular.module('controlCajaApp').controller('MovimientoCtrl', movimientoCtrl); 8 | }()); -------------------------------------------------------------------------------- /21-organizacion/client/movimientosFactory.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | var movimientosFactory =   function ($resource)  { 4 | 5 | var factory  =   {}; 6 | factory.movimientos =  $resource("/api/priv/movimientos/:id", { 7 | id: "@id" 8 | }) 9 | factory.total = $resource("/api/priv/total/"); 10 | 11 | return factory; 12 | }; 13 | 14 | angular.module('controlCajaApp').factory('movimientosFactory', movimientosFactory); 15 | }()); -------------------------------------------------------------------------------- /21-organizacion/client/not-found.html: -------------------------------------------------------------------------------- 1 |
2 |

No se ha encontrado lo que buscabas

3 |
-------------------------------------------------------------------------------- /21-organizacion/client/registroCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var registroCtrl = function ($rootScope, $state, $http, $cookieStore) { 3 | var urlBase = "http://localhost:3000/api/"; 4 | var vm = this; 5 | vm.usuario = {}; 6 | vm.entrar = function () { 7 | $http.post(urlBase + 'sesiones/', vm.usuario) 8 | .success(function (data) { 9 | $rootScope.nombre = vm.usuario.email; 10 | $rootScope.mensaje = 'recién entrado'; 11 | $cookieStore.put("sessionId", data); 12 | $state.go("total"); 13 | }); 14 | } 15 | vm.registrar = function () { 16 | $http.post(urlBase + 'usuarios/', vm.usuario) 17 | .success(function (data) { 18 | $rootScope.nombre = vm.usuario.email; 19 | $rootScope.mensaje = 'recién creado'; 20 | $cookieStore.put("sessionId", data); 21 | $state.go("total"); 22 | }); 23 | } 24 | } 25 | angular.module('controlCajaApp').controller('RegistroCtrl', registroCtrl); 26 | }()); -------------------------------------------------------------------------------- /21-organizacion/client/total.html: -------------------------------------------------------------------------------- 1 |
2 | Comprueba de dónde viene y a dónde va tu dinero. 3 |
4 |
5 |
6 |

7 | 8 | {{ caja.total.ingresos | number:2 }} € 9 | 10 |

11 |

Total ingresos

12 | Acumulado 13 |
14 |
15 |

16 | 17 | {{ caja.total.gastos | number:2 }} € 18 | 19 |

20 |

Total gastos

21 | Acumulado 22 |
23 |
24 |

25 | 26 | {{ caja.balance() | number:2 }} € 27 | 28 |

29 |

Balance

30 | Ingresos-Gastos 31 |
32 |
33 |
34 |
-------------------------------------------------------------------------------- /21-organizacion/client/tpl-cabecera.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Cash Flow

4 |
5 |
6 |
7 | -------------------------------------------------------------------------------- /21-organizacion/client/tpl-fila-movimiento.html: -------------------------------------------------------------------------------- 1 | 2 | {{movimientoplantilla.id }} 3 | {{movimientoplantilla.fecha | date}} 4 | {{movimientoplantilla.tipo}} 5 | {{movimientoplantilla.categoria}} 6 | 7 | {{movimientoplantilla.importe | number:2}} € 8 | 9 | 10 | -------------------------------------------------------------------------------- /21-organizacion/client/tpl-valoracion.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | 9 | * 10 | 11 | 12 | -------------------------------------------------------------------------------- /21-organizacion/client/valoracion.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var valoracion = function () { 3 | return { 4 | restrict: 'AE', 5 | templateUrl: '/tpl-valoracion.html', 6 | scope: { 7 | valor: '=', 8 | max: '@', 9 | soloLectura: '@' 10 | }, 11 | link: function (scope, elem, attrs) { 12 | function actualizar() { 13 | if(!scope.valor)scope.valor=1; 14 | scope.estrellas = []; 15 | for (var i = 0; i < scope.max; i++) { 16 | var estrella = { 17 | marcada: (i < scope.valor) 18 | }; 19 | scope.estrellas.push(estrella); 20 | } 21 | }; 22 | 23 | scope.marcar = function (indice) { 24 | if (scope.soloLectura && scope.soloLectura === 'true') { 25 | return; 26 | } 27 | scope.valor = indice + 1; 28 | actualizar(); 29 | }; 30 | actualizar(); 31 | } 32 | } 33 | } 34 | 35 | angular.module('abDirectivas') 36 | .directive('abValoracion', valoracion); 37 | 38 | }()); -------------------------------------------------------------------------------- /21-organizacion/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ControlCashFlow", 3 | "version": "0.0.0", 4 | "description": "Controla tu flujo de caja", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Alberto Basalo", 10 | "license": "BSD-2-Clause", 11 | "dependencies": { 12 | "express": "~4.12.1", 13 | "body-parser": "~1.0.2" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /21-organizacion/recursos.md: -------------------------------------------------------------------------------- 1 | https://angular-ui.github.io/ 2 | http://ngmodules.org/c 3 | http://angular-js.in/ 4 | http://www.directiv.es/ 5 | 6 | http://www.tamas.io/node-jsexpress-cors-implementation/ 7 | http://stackoverflow.com/questions/23823010/how-to-enable-cors-in-angularjs -------------------------------------------------------------------------------- /21b-organizacion/client/_comun/app.js: -------------------------------------------------------------------------------- 1 | angular.module('controlCajaApp', ['ui.router','ngCookies', 'ngResource', 'abFiltros','abDirectivas']); 2 | 3 | angular.module('controlCajaApp').config(function ($stateProvider,$locationProvider) { 4 | $stateProvider 5 | .state('total', { 6 | url: '/', 7 | controller: 'CajaCtrl as caja', 8 | templateUrl: 'controlcaja/total.html' 9 | }) 10 | .state('nuevo', { 11 | url: '/nuevo', 12 | controller: 'CajaCtrl as caja', 13 | templateUrl: 'controlcaja/nuevo.html' 14 | }) 15 | .state('lista', { 16 | url: '/lista', 17 | controller: 'CajaCtrl as caja', 18 | templateUrl: 'controlcaja/lista.html' 19 | }) 20 | .state('movimiento', { 21 | url: '/movimiento/:id', 22 | controller: 'MovimientoCtrl as vm', 23 | templateUrl: 'movimiento/movimiento.html' 24 | }) 25 | .state('registro', { 26 | url: '/registro', 27 | controller: 'RegistroCtrl as registro', 28 | templateUrl: 'registro/registro.html' 29 | }) 30 | .state('not-found', { 31 | url: '*path', 32 | templateUrl: '_comun/not-found.html' 33 | }); 34 | }); -------------------------------------------------------------------------------- /21b-organizacion/client/_comun/appHttpLog.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | function configuradorInterceptores($httpProvider) { 4 | $httpProvider.interceptors.push(funcionInterceptoraLog); 5 | } 6 | 7 | function funcionInterceptoraLog($log) { 8 | 9 | var interceptor = {}; 10 | interceptor.request = function (request) { 11 | $log.info('request:' + request.url); 12 | return request ; 13 | }; 14 | interceptor.responseError = function (response) { 15 | $log.error("excepción: " + response.status + " de :" + response.config.url); 16 | } 17 | return interceptor; 18 | } 19 | 20 | angular.module('controlCajaApp').config(configuradorInterceptores); 21 | }()); -------------------------------------------------------------------------------- /21b-organizacion/client/_comun/appSecurity.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | function configuradorInterceptores($httpProvider) { 3 | $httpProvider.interceptors.push(funcionInterceptoraSeguridad); 4 | } 5 | 6 | function funcionInterceptoraSeguridad($q, $injector, $cookieStore, $rootScope) { 7 | 8 | var interceptor = {}; 9 | interceptor.request = function (request) { 10 | request.headers["sessionId"] = $cookieStore.get("sessionId"); 11 | return request || $q.when(request); 12 | }; 13 | interceptor.responseError = function (response) { 14 | var state = $injector.get('$state'); 15 | if (response.status === 401) { 16 | $rootScope.mensaje = "No hay derecho!!!"; 17 | state.go('registro'); 18 | } else if (response.status === 419) { 19 | $rootScope.mensaje = "Estoy caduco!!!"; 20 | $cookieStore.remove("sessionId") 21 | state.go('registro'); 22 | }; 23 | return $q.reject(response); 24 | } 25 | return interceptor; 26 | } 27 | 28 | angular.module('controlCajaApp').config(configuradorInterceptores); 29 | }()); -------------------------------------------------------------------------------- /21b-organizacion/client/_comun/menuCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var menuCtrl = function ($state) { 3 | this.isActive = function (estado) { 4 | return $state.is(estado); 5 | } 6 | } 7 | angular.module('controlCajaApp').controller('MenuCtrl',menuCtrl); 8 | }()); -------------------------------------------------------------------------------- /21b-organizacion/client/_comun/not-found.html: -------------------------------------------------------------------------------- 1 |
2 |

No se ha encontrado lo que buscabas

3 |
-------------------------------------------------------------------------------- /21b-organizacion/client/controlcaja/cajaCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var cajaCtrl = function (maestrosFactory, movimientosFactory) { 3 | var vm = this; 4 | 5 | vm.titulo = "Controla tu Cash Flow"; 6 | 7 | vm.maestros = maestrosFactory.get(); 8 | 9 | vm.nuevoMovimiento = new movimientosFactory.movimientos(); 10 | vm.nuevoMovimiento.esIngreso = 1; 11 | vm.nuevoMovimiento.fecha = new Date(); 12 | 13 | vm.movimientos = movimientosFactory.movimientos.query(); 14 | 15 | vm.total = movimientosFactory.total.get(); 16 | 17 | vm.guardarMovimiento = function () { 18 | vm.nuevoMovimiento.tipo = vm.tipo(vm.nuevoMovimiento); 19 | vm.nuevoMovimiento.$save() 20 | .then(function (postedData) { 21 | vm.movimientos = movimientosFactory.movimientos.query(); 22 | vm.total = movimientosFactory.total.get(); 23 | vm.nuevoMovimiento.importe = 0; 24 | }); 25 | } 26 | vm.balance = function () { 27 | return vm.total.ingresos - vm.total.gastos 28 | } 29 | vm.tipo = function (movimiento) { 30 | return movimiento.esIngreso && 'Ingreso' || 'Gasto' 31 | } 32 | } 33 | angular.module('controlCajaApp').controller('CajaCtrl', cajaCtrl); 34 | }()); -------------------------------------------------------------------------------- /21b-organizacion/client/controlcaja/lista.html: -------------------------------------------------------------------------------- 1 |
2 | Estos son tus movimientos recientes. 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | 16 | 18 | 19 | 20 | 21 | 22 | 26 | 27 |
IdFecha 13 | TipoCategoríaImporte 17 | Valoración
28 |
-------------------------------------------------------------------------------- /21b-organizacion/client/controlcaja/total.html: -------------------------------------------------------------------------------- 1 |
2 | Comprueba de dónde viene y a dónde va tu dinero. 3 |
4 |
5 |
6 |

7 | 8 | {{ caja.total.ingresos | number:2 }} € 9 | 10 |

11 |

Total ingresos

12 | Acumulado 13 |
14 |
15 |

16 | 17 | {{ caja.total.gastos | number:2 }} € 18 | 19 |

20 |

Total gastos

21 | Acumulado 22 |
23 |
24 |

25 | 26 | {{ caja.balance() | number:2 }} € 27 | 28 |

29 |

Balance

30 | Ingresos-Gastos 31 |
32 |
33 |
34 |
-------------------------------------------------------------------------------- /21b-organizacion/client/data/maestrosFactory.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var maestrosFactory =   function ($resource)  { 3 | return $resource("/api/pub/maestros/",{},{get: {cache: true}}); 4 | }; 5 | 6 | angular.module('controlCajaApp').factory('maestrosFactory', maestrosFactory); 7 | }()); -------------------------------------------------------------------------------- /21b-organizacion/client/data/movimientosFactory.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | var movimientosFactory =   function ($resource)  { 4 | 5 | var factory  =   {}; 6 | factory.movimientos =  $resource("/api/priv/movimientos/:id", { 7 | id: "@id" 8 | }) 9 | factory.total = $resource("/api/priv/total/"); 10 | 11 | return factory; 12 | }; 13 | 14 | angular.module('controlCajaApp').factory('movimientosFactory', movimientosFactory); 15 | }()); -------------------------------------------------------------------------------- /21b-organizacion/client/directivas/tpl-cabecera.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Cash Flow

4 |
5 |
6 |
7 | -------------------------------------------------------------------------------- /21b-organizacion/client/directivas/tpl-fila-movimiento.html: -------------------------------------------------------------------------------- 1 | 2 | {{movimientoplantilla.id }} 3 | {{movimientoplantilla.fecha | date}} 4 | {{movimientoplantilla.tipo}} 5 | {{movimientoplantilla.categoria}} 6 | 7 | {{movimientoplantilla.importe | number:2}} € 8 | 9 | 10 | -------------------------------------------------------------------------------- /21b-organizacion/client/directivas/valoracion/tpl-valoracion.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | 9 | * 10 | 11 | 12 | -------------------------------------------------------------------------------- /21b-organizacion/client/directivas/valoracion/valoracion.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var valoracion = function () { 3 | return { 4 | restrict: 'AE', 5 | templateUrl: '/directivas/valoracion/tpl-valoracion.html', 6 | scope: { 7 | valor: '=', 8 | max: '@', 9 | soloLectura: '@' 10 | }, 11 | link: function (scope, elem, attrs) { 12 | function actualizar() { 13 | if(!scope.valor)scope.valor=1; 14 | scope.estrellas = []; 15 | for (var i = 0; i < scope.max; i++) { 16 | var estrella = { 17 | marcada: (i < scope.valor) 18 | }; 19 | scope.estrellas.push(estrella); 20 | } 21 | }; 22 | 23 | scope.marcar = function (indice) { 24 | if (scope.soloLectura && scope.soloLectura === 'true') { 25 | return; 26 | } 27 | scope.valor = indice + 1; 28 | actualizar(); 29 | }; 30 | actualizar(); 31 | } 32 | } 33 | } 34 | 35 | angular.module('abDirectivas') 36 | .directive('abValoracion', valoracion); 37 | 38 | }()); -------------------------------------------------------------------------------- /21b-organizacion/client/movimiento/movimientoCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var movimientoCtrl = function ($stateParams, movimientosFactory) { 3 | var vm = this; 4 | var movId = $stateParams.id; 5 | vm.movimiento = movimientosFactory.movimientos.get({id:movId}); 6 | } 7 | angular.module('controlCajaApp').controller('MovimientoCtrl', movimientoCtrl); 8 | }()); -------------------------------------------------------------------------------- /21b-organizacion/client/registro/registroCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var registroCtrl = function ($rootScope, $state, $http, $cookieStore) { 3 | var urlBase = "http://localhost:3000/api/"; 4 | var vm = this; 5 | vm.usuario = {}; 6 | vm.entrar = function () { 7 | $http.post(urlBase + 'sesiones/', vm.usuario) 8 | .success(function (data) { 9 | $rootScope.nombre = vm.usuario.email; 10 | $rootScope.mensaje = 'recién entrado'; 11 | $cookieStore.put("sessionId", data); 12 | $state.go("total"); 13 | }); 14 | } 15 | vm.registrar = function () { 16 | $http.post(urlBase + 'usuarios/', vm.usuario) 17 | .success(function (data) { 18 | $rootScope.nombre = vm.usuario.email; 19 | $rootScope.mensaje = 'recién creado'; 20 | $cookieStore.put("sessionId", data); 21 | $state.go("total"); 22 | }); 23 | } 24 | } 25 | angular.module('controlCajaApp').controller('RegistroCtrl', registroCtrl); 26 | }()); -------------------------------------------------------------------------------- /21b-organizacion/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ControlCashFlow", 3 | "version": "0.0.0", 4 | "description": "Controla tu flujo de caja", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Alberto Basalo", 10 | "license": "BSD-2-Clause", 11 | "dependencies": { 12 | "express": "~4.12.1", 13 | "body-parser": "~1.0.2" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /21b-organizacion/server.js: -------------------------------------------------------------------------------- 1 | var app = require('./server/config.js').configApp(); 2 | require('./server/seguridad.js').seguridad(app); 3 | console.log('ready'); 4 | 5 | require('./server/maestros.js').routeMaestros(app); 6 | require('./server/movimientos.js').routeMovimientos(app); 7 | console.log('steady'); 8 | 9 | app.listen(3000); 10 | console.log('go'); -------------------------------------------------------------------------------- /21b-organizacion/server/config.js: -------------------------------------------------------------------------------- 1 | module.exports.configApp = function () { 2 | 3 | var express = require('express'); 4 | var bodyParser = require('body-parser'); 5 | 6 | var app = express(); 7 | 8 | app.use(bodyParser()); 9 | app.use(express.static(__dirname + './../client')); 10 | 11 | app.use(function (peticion, respuesta, siguiente) { 12 | console.log("recibida petición: " + peticion.url); 13 | if (peticion.body && Object.keys(peticion.body).length > 0) { 14 | console.log("body: " + JSON.stringify(peticion.body)); 15 | } 16 | siguiente(); 17 | }); 18 | 19 | return app; 20 | 21 | } -------------------------------------------------------------------------------- /21b-organizacion/server/maestros.js: -------------------------------------------------------------------------------- 1 | module.exports.routeMaestros = function (app) { 2 | app.get('/api/pub/maestros', function (req, res, next) { 3 | var maestros = { 4 | categoriasIngresos: ['Nómina', 'Ventas', 'Intereses Depósitos'], 5 | categoriasGastos: ['Hipotéca', 'Compras', 'Impuestos'] 6 | }; 7 | res.json(maestros); 8 | }); 9 | } -------------------------------------------------------------------------------- /22-mongo-console/1-crear.js: -------------------------------------------------------------------------------- 1 | use control_caja 2 | 3 | db.movimientos.drop() 4 | db.createCollection('movimientos') 5 | 6 | //var movimiento = { 7 | // user: 'albertobasalo@agorabinaria.com', 8 | // tipo: 'Ingreso', 9 | // categoria: 'Nómina', 10 | // importe: 1200, 11 | // fecha: new Date(2015, 03, 06, 12, 00, 00, 000) 12 | //}; 13 | //db.movimientos.insert(movimiento); 14 | 15 | var nomina_alberto = { 16 | user: 'albertobasalo@agorabinaria.com', 17 | tipo: 'Ingreso', 18 | categoria: 'Nómina', 19 | importe: 1200, 20 | fecha: new Date(2015, 03, 01, 12,00, 00, 000) 21 | }; 22 | db.movimientos.insert(nomina_alberto); 23 | var hipoteca_alberto = { 24 | user: 'albertobasalo@agorabinaria.com', 25 | tipo: 'Gasto', 26 | categoria: 'Hipoteca', 27 | importe: 400, 28 | fecha: new Date(2015, 03, 06, 12, 0, 00, 000) 29 | }; 30 | db.movimientos.insert(hipoteca_alberto); 31 | var nomina_reinaldo = { 32 | user: 'reinaldo.aguilera@gmail.com', 33 | tipo: 'Ingreso', 34 | categoria: 'Nómina', 35 | importe: 1100, 36 | fecha: new Date(2015, 03, 02, 12, 0, 00, 000) 37 | }; 38 | db.movimientos.insert(nomina_reinaldo); 39 | var hipoteca_reinaldo = { 40 | user: 'reinaldo.aguilera@gmail.com', 41 | tipo: 'Gasto', 42 | categoria: 'Hipoteca', 43 | importe: 450, 44 | fecha: new Date(2015, 03, 04, 12, 0, 00, 000) 45 | }; 46 | db.movimientos.insert(hipoteca_reinaldo); 47 | 48 | db.movimientos.find(); -------------------------------------------------------------------------------- /22-mongo-console/2-buscar.js: -------------------------------------------------------------------------------- 1 | use control_caja 2 | 3 | // busquedas 4 | var movimientos_alberto = db.movimientos.find({ 5 | user: 'albertobasalo@agorabinaria.com' 6 | }); 7 | 8 | var nomina_alberto = db.movimientos.find({ 9 | user: 'albertobasalo@agorabinaria.com', 10 | categoria: 'Nómina' 11 | }); 12 | 13 | var grandes_movimientos = db.movimientos.find({ 14 | importe: { 15 | $gt: 1000 16 | } 17 | }); 18 | 19 | var alberto_or_grandes_movimientos = db.movimientos.find({ 20 | $or: [{ 21 | importe: { 22 | $gt: 1000 23 | } 24 | }, { 25 | user: 'albertobasalo@agorabinaria.com' 26 | } 27 | ] 28 | }); 29 | 30 | var movimientos_parecidos = db.movimientos.find({ 31 | user: /agorabinaria/ 32 | }); 33 | 34 | var movimientos_parecidos = db.movimientos.find({ 35 | user: /al/i 36 | }); 37 | 38 | var movimientos_parecidos = db.movimientos.find({ 39 | user: /^al/ 40 | }); 41 | 42 | 43 | var movimientos_ordenados = db.movimientos.find().sort({importe:1}); 44 | 45 | // proyecciones 46 | var movimientos_importes = db.movimientos.find({},{importe:1}) 47 | var movimientos_importes_sin_clave = db.movimientos.find({},{importe:1, _id:0}) 48 | 49 | // limites y paginación 50 | db.movimientos.find().limit(2).skip(1) 51 | // cuenta 52 | db.movimientos.count() 53 | // distintos 54 | db.movimientos.distinct( "categoria" ) -------------------------------------------------------------------------------- /22-mongo-console/4-insertar.js: -------------------------------------------------------------------------------- 1 | use control_caja 2 | 3 | function azar(desde, hasta) { 4 | return Math.floor((Math.random() * hasta) + desde) 5 | } 6 | 7 | function tipo() { 8 | if (azar(0, 10) > 4) { 9 | return 'Ingreso'; 10 | } else { 11 | return 'Gasto'; 12 | } 13 | } 14 | 15 | function user() { 16 | if (azar(0, 10) > 4) { 17 | return 'albertobasalo@agorabinaria.com'; 18 | } else { 19 | return 'reinaldo.aguilera@gmail.com'; 20 | } 21 | } 22 | 23 | for (i = 0; i < 100; i++) { 24 | var movimiento = { 25 | user: user(); 26 | tipo: tipo(), 27 | importe: azar(100, 2500), 28 | fecha: new Date(2015, azar(0, 11), azar(1, 30), 12, 0, 0) 29 | }; 30 | db.movimientos.insert(movimiento); 31 | } 32 | 33 | db.movimientos.find(); -------------------------------------------------------------------------------- /22-mongo-console/mongodb.md: -------------------------------------------------------------------------------- 1 | #Schemma-less 2 | 3 | #Comparación 4 | 5 | ## Inconvenientes 6 | - No Joins 7 | - No Transactions 8 | - No Integrity 9 | - Sintaxis novedosa y a veces difícil 10 | 11 | ## Ventajas 12 | - Velocidad 13 | - Flexibilidad 14 | - Escalabilidad 15 | 16 | #Conceptos 17 | 18 | ## Física 19 | Server 20 | 21 | Réplica 22 | 23 | Shard 24 | 25 | Database 26 | 27 | 28 | 29 | ## Lógica 30 | Database 31 | 32 | Collection (Table) 33 | 34 | Document (Row) 35 | 36 | Property (Fiel) 37 | 38 | Schemma(-less) 39 | 40 | 41 | #Comandos 42 | mongod --dbpath 43 | mongo 44 | 45 | #GUI 46 | robomongo 47 | 48 | 49 | -------------------------------------------------------------------------------- /23-mongodb-client/client/_comun/app.js: -------------------------------------------------------------------------------- 1 | angular.module('controlCajaApp', ['ui.router','ngCookies', 'ngResource', 'abFiltros','abDirectivas']); 2 | 3 | angular.module('controlCajaApp').config(function ($stateProvider,$locationProvider) { 4 | $stateProvider 5 | .state('total', { 6 | url: '/', 7 | controller: 'CajaCtrl as caja', 8 | templateUrl: 'controlcaja/total.html' 9 | }) 10 | .state('nuevo', { 11 | url: '/nuevo', 12 | controller: 'CajaCtrl as caja', 13 | templateUrl: 'controlcaja/nuevo.html' 14 | }) 15 | .state('lista', { 16 | url: '/lista', 17 | controller: 'CajaCtrl as caja', 18 | templateUrl: 'controlcaja/lista.html' 19 | }) 20 | .state('movimiento', { 21 | url: '/movimiento/:_id', 22 | controller: 'MovimientoCtrl as vm', 23 | templateUrl: 'movimiento/movimiento.html' 24 | }) 25 | .state('registro', { 26 | url: '/registro', 27 | controller: 'RegistroCtrl as registro', 28 | templateUrl: 'registro/registro.html' 29 | }) 30 | .state('not-found', { 31 | url: '*path', 32 | templateUrl: '_comun/not-found.html' 33 | }); 34 | }); -------------------------------------------------------------------------------- /23-mongodb-client/client/_comun/appHttpLog.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | function configuradorInterceptores($httpProvider) { 4 | $httpProvider.interceptors.push(funcionInterceptoraLog); 5 | } 6 | 7 | function funcionInterceptoraLog($log) { 8 | 9 | var interceptor = {}; 10 | interceptor.request = function (request) { 11 | $log.info('request:' + request.url); 12 | return request ; 13 | }; 14 | interceptor.responseError = function (response) { 15 | $log.error("excepción: " + response.status + " de :" + response.config.url); 16 | } 17 | return interceptor; 18 | } 19 | 20 | angular.module('controlCajaApp').config(configuradorInterceptores); 21 | }()); -------------------------------------------------------------------------------- /23-mongodb-client/client/_comun/appSecurity.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | function configuradorInterceptores($httpProvider) { 3 | $httpProvider.interceptors.push(funcionInterceptoraSeguridad); 4 | } 5 | 6 | function funcionInterceptoraSeguridad($q, $injector, $cookieStore, $rootScope) { 7 | 8 | var interceptor = {}; 9 | interceptor.request = function (request) { 10 | request.headers["sessionId"] = $cookieStore.get("sessionId"); 11 | return request || $q.when(request); 12 | }; 13 | interceptor.responseError = function (response) { 14 | var state = $injector.get('$state'); 15 | if (response.status === 401) { 16 | $rootScope.mensaje = "No hay derecho!!!"; 17 | state.go('registro'); 18 | } else if (response.status === 419) { 19 | $rootScope.mensaje = "Estoy caduco!!!"; 20 | $cookieStore.remove("sessionId") 21 | state.go('registro'); 22 | }; 23 | return $q.reject(response); 24 | } 25 | return interceptor; 26 | } 27 | 28 | angular.module('controlCajaApp').config(configuradorInterceptores); 29 | }()); -------------------------------------------------------------------------------- /23-mongodb-client/client/_comun/menuCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var menuCtrl = function ($state) { 3 | this.isActive = function (estado) { 4 | return $state.is(estado); 5 | } 6 | } 7 | angular.module('controlCajaApp').controller('MenuCtrl',menuCtrl); 8 | }()); -------------------------------------------------------------------------------- /23-mongodb-client/client/_comun/not-found.html: -------------------------------------------------------------------------------- 1 |
2 |

No se ha encontrado lo que buscabas

3 |
-------------------------------------------------------------------------------- /23-mongodb-client/client/controlcaja/cajaCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var cajaCtrl = function (maestrosFactory, movimientosFactory) { 3 | var vm = this; 4 | 5 | vm.titulo = "Controla tu Cash Flow"; 6 | 7 | vm.maestros = maestrosFactory.get(); 8 | 9 | vm.nuevoMovimiento = new movimientosFactory.movimientos(); 10 | vm.nuevoMovimiento.esIngreso = 1; 11 | vm.nuevoMovimiento.fecha = new Date(); 12 | 13 | vm.movimientos = movimientosFactory.movimientos.query(); 14 | 15 | vm.total = movimientosFactory.total.get(); 16 | 17 | vm.guardarMovimiento = function () { 18 | vm.nuevoMovimiento.tipo = vm.tipo(vm.nuevoMovimiento); 19 | vm.nuevoMovimiento.$save() 20 | .then(function (postedData) { 21 | vm.movimientos = movimientosFactory.movimientos.query(); 22 | vm.total = movimientosFactory.total.get(); 23 | vm.nuevoMovimiento.importe = 0; 24 | }); 25 | } 26 | vm.balance = function () { 27 | return vm.total.ingresos - vm.total.gastos 28 | } 29 | vm.tipo = function (movimiento) { 30 | return movimiento.esIngreso && 'Ingreso' || 'Gasto' 31 | } 32 | } 33 | angular.module('controlCajaApp').controller('CajaCtrl', cajaCtrl); 34 | }()); -------------------------------------------------------------------------------- /23-mongodb-client/client/controlcaja/lista.html: -------------------------------------------------------------------------------- 1 |
2 | Estos son tus movimientos recientes. 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | 16 | 18 | 19 | 20 | 21 | 22 | 26 | 27 |
IdFecha 13 | TipoCategoríaImporte 17 | Valoración
28 |
-------------------------------------------------------------------------------- /23-mongodb-client/client/controlcaja/total.html: -------------------------------------------------------------------------------- 1 |
2 | Comprueba de dónde viene y a dónde va tu dinero. 3 |
4 |
5 |
6 |

7 | 8 | {{ caja.total.ingresos | number:2 }} € 9 | 10 |

11 |

Total ingresos

12 | Acumulado 13 |
14 |
15 |

16 | 17 | {{ caja.total.gastos | number:2 }} € 18 | 19 |

20 |

Total gastos

21 | Acumulado 22 |
23 |
24 |

25 | 26 | {{ caja.balance() | number:2 }} € 27 | 28 |

29 |

Balance

30 | Ingresos-Gastos 31 |
32 |
33 |
34 |
-------------------------------------------------------------------------------- /23-mongodb-client/client/data/maestrosFactory.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var maestrosFactory =   function ($resource)  { 3 | return $resource("/api/pub/maestros/",{},{get: {cache: true}}); 4 | }; 5 | 6 | angular.module('controlCajaApp').factory('maestrosFactory', maestrosFactory); 7 | }()); -------------------------------------------------------------------------------- /23-mongodb-client/client/data/movimientosFactory.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | var movimientosFactory =   function ($resource)  { 4 | 5 | var factory  =   {}; 6 | factory.movimientos =  $resource("/api/priv/movimientos/:id", { 7 | id: "@id" 8 | }) 9 | factory.total = $resource("/api/priv/total/"); 10 | 11 | return factory; 12 | }; 13 | 14 | angular.module('controlCajaApp').factory('movimientosFactory', movimientosFactory); 15 | }()); -------------------------------------------------------------------------------- /23-mongodb-client/client/directivas/tpl-cabecera.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Cash Flow

4 |
5 |
6 |
7 | -------------------------------------------------------------------------------- /23-mongodb-client/client/directivas/tpl-fila-movimiento.html: -------------------------------------------------------------------------------- 1 | 2 | {{movimientoplantilla._id }} 3 | {{movimientoplantilla.fecha | date}} 4 | {{movimientoplantilla.tipo}} 5 | {{movimientoplantilla.categoria}} 6 | 7 | {{movimientoplantilla.importe | number:2}} € 8 | 9 | 10 | -------------------------------------------------------------------------------- /23-mongodb-client/client/directivas/valoracion/tpl-valoracion.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | 9 | * 10 | 11 | 12 | -------------------------------------------------------------------------------- /23-mongodb-client/client/directivas/valoracion/valoracion.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var valoracion = function () { 3 | return { 4 | restrict: 'AE', 5 | templateUrl: '/directivas/valoracion/tpl-valoracion.html', 6 | scope: { 7 | valor: '=', 8 | max: '@', 9 | soloLectura: '@' 10 | }, 11 | link: function (scope, elem, attrs) { 12 | function actualizar() { 13 | if(!scope.valor)scope.valor=1; 14 | scope.estrellas = []; 15 | for (var i = 0; i < scope.max; i++) { 16 | var estrella = { 17 | marcada: (i < scope.valor) 18 | }; 19 | scope.estrellas.push(estrella); 20 | } 21 | }; 22 | 23 | scope.marcar = function (indice) { 24 | if (scope.soloLectura && scope.soloLectura === 'true') { 25 | return; 26 | } 27 | scope.valor = indice + 1; 28 | actualizar(); 29 | }; 30 | actualizar(); 31 | } 32 | } 33 | } 34 | 35 | angular.module('abDirectivas') 36 | .directive('abValoracion', valoracion); 37 | 38 | }()); -------------------------------------------------------------------------------- /23-mongodb-client/client/movimiento/movimientoCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var movimientoCtrl = function ($stateParams, movimientosFactory) { 3 | var vm = this; 4 | vm.movimiento = movimientosFactory.movimientos.get({id:$stateParams._id}); 5 | } 6 | angular.module('controlCajaApp').controller('MovimientoCtrl', movimientoCtrl); 7 | }()); -------------------------------------------------------------------------------- /23-mongodb-client/client/registro/registroCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var registroCtrl = function ($rootScope, $state, $http, $cookieStore) { 3 | var urlBase = "http://localhost:3000/api/"; 4 | var vm = this; 5 | vm.usuario = {}; 6 | vm.entrar = function () { 7 | $http.post(urlBase + 'sesiones/', vm.usuario) 8 | .success(function (data) { 9 | $rootScope.nombre = vm.usuario.email; 10 | $rootScope.mensaje = 'recién entrado'; 11 | $cookieStore.put("sessionId", data); 12 | $state.go("total"); 13 | }); 14 | } 15 | vm.registrar = function () { 16 | $http.post(urlBase + 'usuarios/', vm.usuario) 17 | .success(function (data) { 18 | $rootScope.nombre = vm.usuario.email; 19 | $rootScope.mensaje = 'recién creado'; 20 | $cookieStore.put("sessionId", data); 21 | $state.go("total"); 22 | }); 23 | } 24 | } 25 | angular.module('controlCajaApp').controller('RegistroCtrl', registroCtrl); 26 | }()); -------------------------------------------------------------------------------- /23-mongodb-client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ControlCashFlow", 3 | "version": "0.0.0", 4 | "description": "Controla tu flujo de caja", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Alberto Basalo", 10 | "license": "BSD-2-Clause", 11 | "dependencies": { 12 | "body-parser": "~1.0.2", 13 | "express": "~4.12.1", 14 | "mongodb": "^2.0.27", 15 | "q": "^1.2.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /23-mongodb-client/server.js: -------------------------------------------------------------------------------- 1 | var app = require('./server/config.js').configApp(); 2 | require('./server/seguridad.js').seguridad(app); 3 | console.log('ready'); 4 | 5 | require('./server/maestros.js').routeMaestros(app); 6 | require('./server/movimientos.js').routeMovimientos(app); 7 | console.log('steady'); 8 | 9 | app.listen(3000); 10 | console.log('go'); -------------------------------------------------------------------------------- /23-mongodb-client/server/config.js: -------------------------------------------------------------------------------- 1 | module.exports.configApp = function () { 2 | 3 | var express = require('express'); 4 | var bodyParser = require('body-parser'); 5 | 6 | var app = express(); 7 | 8 | app.use(bodyParser()); 9 | app.use(express.static(__dirname + './../client')); 10 | 11 | app.use(function (peticion, respuesta, siguiente) { 12 | console.log("recibida petición: " + peticion.url); 13 | if (peticion.body && Object.keys(peticion.body).length > 0) { 14 | console.log("body: " + JSON.stringify(peticion.body)); 15 | } 16 | siguiente(); 17 | }); 18 | 19 | return app; 20 | 21 | } -------------------------------------------------------------------------------- /23-mongodb-client/server/data/mongodb.js: -------------------------------------------------------------------------------- 1 | var Q = require('q'); 2 | var mongodb = require('mongodb'); 3 | var MongoClient = mongodb.MongoClient; 4 | var mongoUrl = "mongodb://localhost:27017/control_caja"; 5 | 6 | exports.connecting = function (mongoCol) { 7 | var deferred = Q.defer(); 8 | MongoClient.connect(mongoUrl, function (err, db) { 9 | if (!err) { 10 | deferred.resolve(db.collection(mongoCol)); 11 | } else { 12 | rejectOnError(deferred, err); 13 | } 14 | }); 15 | return deferred.promise; 16 | } 17 | 18 | exports.ObjectId = mongodb.ObjectID; 19 | 20 | exports.rejectOnError = rejectOnError; 21 | 22 | function rejectOnError(deferred, err) { 23 | console.error(err); 24 | deferred.reject(err); 25 | } -------------------------------------------------------------------------------- /23-mongodb-client/server/maestros.js: -------------------------------------------------------------------------------- 1 | module.exports.routeMaestros = function (app) { 2 | app.get('/api/pub/maestros', function (req, res, next) { 3 | var maestros = { 4 | categoriasIngresos: ['Nómina', 'Ventas', 'Intereses Depósitos'], 5 | categoriasGastos: ['Hipotéca', 'Compras', 'Impuestos'] 6 | }; 7 | res.json(maestros); 8 | }); 9 | } -------------------------------------------------------------------------------- /23-mongodb-client/server/movimientos.js: -------------------------------------------------------------------------------- 1 | var movimientosData = require('./data/movimientosData.js'); 2 | var usuariosData = require('./data/usuariosData.js'); 3 | 4 | module.exports.routeMovimientos = function (app) { 5 | 6 | app.route('/api/priv/movimientos') 7 | .get(function (req, res, next) { 8 | movimientosData.gettingByUsuario(req.usuario) 9 | .then(function (data) { 10 | res.json(data); 11 | }) 12 | .fail(function (err) { 13 | res.status(500).send(err); 14 | }); 15 | }) 16 | .post(function (req, res, next) { 17 | var movimiento = req.body; 18 | movimiento.usuario = req.usuario; 19 | movimientosData.posting(movimiento) 20 | .then(function (data) { 21 | usuariosData.updatingTotal(movimiento) 22 | .then(function (data) { 23 | res.json(data); 24 | }) 25 | .fail(function (err) { 26 | res.status(500).send(err); 27 | }); 28 | }) 29 | .fail(function (err) { 30 | res.status(500).send(err); 31 | }); 32 | }); 33 | 34 | app.get('/api/priv/movimientos/:id', function (req, res, next) { 35 | movimientosData.gettingByIdUsuario(req.params.id, req.usuario) 36 | .then(function (data) { 37 | res.json(data); 38 | }) 39 | .fail(function (err) { 40 | res.status(500).send(err); 41 | }); 42 | }); 43 | 44 | app.get('/api/priv/total', function (req, res, next) { 45 | usuariosData.gettingByEmail(req.usuario) 46 | .then(function (data) { 47 | res.json(data.total); 48 | }) 49 | .fail(function (err) { 50 | res.status(500).send(err); 51 | }); 52 | }); 53 | } -------------------------------------------------------------------------------- /23b-mongodb-client/client/_comun/app.js: -------------------------------------------------------------------------------- 1 | angular.module('controlCajaApp', ['ui.router','ngCookies', 'ngResource', 'abFiltros','abDirectivas']); 2 | 3 | angular.module('controlCajaApp').config(function ($stateProvider,$locationProvider) { 4 | $stateProvider 5 | .state('total', { 6 | url: '/', 7 | controller: 'CajaCtrl as caja', 8 | templateUrl: 'controlcaja/total.html' 9 | }) 10 | .state('nuevo', { 11 | url: '/nuevo', 12 | controller: 'CajaCtrl as caja', 13 | templateUrl: 'controlcaja/nuevo.html' 14 | }) 15 | .state('lista', { 16 | url: '/lista', 17 | controller: 'CajaCtrl as caja', 18 | templateUrl: 'controlcaja/lista.html' 19 | }) 20 | .state('movimiento', { 21 | url: '/movimiento/:_id', 22 | controller: 'MovimientoCtrl as vm', 23 | templateUrl: 'movimiento/movimiento.html' 24 | }) 25 | .state('registro', { 26 | url: '/registro', 27 | controller: 'RegistroCtrl as registro', 28 | templateUrl: 'registro/registro.html' 29 | }) 30 | .state('not-found', { 31 | url: '*path', 32 | templateUrl: '_comun/not-found.html' 33 | }); 34 | }); -------------------------------------------------------------------------------- /23b-mongodb-client/client/_comun/appHttpLog.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | function configuradorInterceptores($httpProvider) { 4 | $httpProvider.interceptors.push(funcionInterceptoraLog); 5 | } 6 | 7 | function funcionInterceptoraLog($log) { 8 | 9 | var interceptor = {}; 10 | interceptor.request = function (request) { 11 | $log.info('request:' + request.url); 12 | return request ; 13 | }; 14 | interceptor.responseError = function (response) { 15 | $log.error("excepción: " + response.status + " de :" + response.config.url); 16 | } 17 | return interceptor; 18 | } 19 | 20 | angular.module('controlCajaApp').config(configuradorInterceptores); 21 | }()); -------------------------------------------------------------------------------- /23b-mongodb-client/client/_comun/appSecurity.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | function configuradorInterceptores($httpProvider) { 3 | $httpProvider.interceptors.push(funcionInterceptoraSeguridad); 4 | } 5 | 6 | function funcionInterceptoraSeguridad($q, $injector, $cookieStore, $rootScope) { 7 | 8 | var interceptor = {}; 9 | interceptor.request = function (request) { 10 | request.headers["sessionId"] = $cookieStore.get("sessionId"); 11 | return request || $q.when(request); 12 | }; 13 | interceptor.responseError = function (response) { 14 | var state = $injector.get('$state'); 15 | if (response.status === 401) { 16 | $rootScope.mensaje = "No hay derecho!!!"; 17 | state.go('registro'); 18 | } else if (response.status === 419) { 19 | $rootScope.mensaje = "Estoy caduco!!!"; 20 | $cookieStore.remove("sessionId") 21 | state.go('registro'); 22 | }; 23 | return $q.reject(response); 24 | } 25 | return interceptor; 26 | } 27 | 28 | angular.module('controlCajaApp').config(configuradorInterceptores); 29 | }()); -------------------------------------------------------------------------------- /23b-mongodb-client/client/_comun/menuCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var menuCtrl = function ($state) { 3 | this.isActive = function (estado) { 4 | return $state.is(estado); 5 | } 6 | } 7 | angular.module('controlCajaApp').controller('MenuCtrl',menuCtrl); 8 | }()); -------------------------------------------------------------------------------- /23b-mongodb-client/client/_comun/not-found.html: -------------------------------------------------------------------------------- 1 |
2 |

No se ha encontrado lo que buscabas

3 |
-------------------------------------------------------------------------------- /23b-mongodb-client/client/controlcaja/cajaCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var cajaCtrl = function (maestrosFactory, movimientosFactory) { 3 | var vm = this; 4 | 5 | vm.titulo = "Controla tu Cash Flow"; 6 | 7 | vm.maestros = maestrosFactory.get(); 8 | 9 | vm.nuevoMovimiento = new movimientosFactory.movimientos(); 10 | vm.nuevoMovimiento.esIngreso = 1; 11 | vm.nuevoMovimiento.fecha = new Date(); 12 | 13 | vm.movimientos = movimientosFactory.movimientos.query(); 14 | 15 | vm.total = movimientosFactory.total.get(); 16 | 17 | vm.guardarMovimiento = function () { 18 | vm.nuevoMovimiento.tipo = vm.tipo(vm.nuevoMovimiento); 19 | vm.nuevoMovimiento.$save() 20 | .then(function (postedData) { 21 | vm.movimientos = movimientosFactory.movimientos.query(); 22 | vm.total = movimientosFactory.total.get(); 23 | vm.nuevoMovimiento.importe = 0; 24 | }); 25 | } 26 | vm.balance = function () { 27 | return vm.total.ingresos - vm.total.gastos 28 | } 29 | vm.tipo = function (movimiento) { 30 | return movimiento.esIngreso && 'Ingreso' || 'Gasto' 31 | } 32 | } 33 | angular.module('controlCajaApp').controller('CajaCtrl', cajaCtrl); 34 | }()); -------------------------------------------------------------------------------- /23b-mongodb-client/client/controlcaja/lista.html: -------------------------------------------------------------------------------- 1 |
2 | Estos son tus movimientos recientes. 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | 16 | 18 | 19 | 20 | 21 | 22 | 26 | 27 |
IdFecha 13 | TipoCategoríaImporte 17 | Valoración
28 |
-------------------------------------------------------------------------------- /23b-mongodb-client/client/controlcaja/total.html: -------------------------------------------------------------------------------- 1 |
2 | Comprueba de dónde viene y a dónde va tu dinero. 3 |
4 |
5 |
6 |

7 | 8 | {{ caja.total.ingresos | number:2 }} € 9 | 10 |

11 |

Total ingresos

12 | Acumulado 13 |
14 |
15 |

16 | 17 | {{ caja.total.gastos | number:2 }} € 18 | 19 |

20 |

Total gastos

21 | Acumulado 22 |
23 |
24 |

25 | 26 | {{ caja.balance() | number:2 }} € 27 | 28 |

29 |

Balance

30 | Ingresos-Gastos 31 |
32 |
33 |
34 |
-------------------------------------------------------------------------------- /23b-mongodb-client/client/data/maestrosFactory.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var maestrosFactory =   function ($resource)  { 3 | return $resource("/api/pub/maestros/",{},{get: {cache: true}}); 4 | }; 5 | 6 | angular.module('controlCajaApp').factory('maestrosFactory', maestrosFactory); 7 | }()); -------------------------------------------------------------------------------- /23b-mongodb-client/client/data/movimientosFactory.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | var movimientosFactory =   function ($resource)  { 4 | 5 | var factory  =   {}; 6 | factory.movimientos =  $resource("/api/priv/movimientos/:id", { 7 | id: "@id" 8 | }) 9 | factory.total = $resource("/api/priv/total/"); 10 | 11 | return factory; 12 | }; 13 | 14 | angular.module('controlCajaApp').factory('movimientosFactory', movimientosFactory); 15 | }()); -------------------------------------------------------------------------------- /23b-mongodb-client/client/directivas/tpl-cabecera.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Cash Flow

4 |
5 |
6 |
7 | -------------------------------------------------------------------------------- /23b-mongodb-client/client/directivas/tpl-fila-movimiento.html: -------------------------------------------------------------------------------- 1 | 2 | {{movimientoplantilla._id }} 3 | {{movimientoplantilla.fecha | date}} 4 | {{movimientoplantilla.tipo}} 5 | {{movimientoplantilla.categoria}} 6 | 7 | {{movimientoplantilla.importe | number:2}} € 8 | 9 | 10 | -------------------------------------------------------------------------------- /23b-mongodb-client/client/directivas/valoracion/tpl-valoracion.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | 9 | * 10 | 11 | 12 | -------------------------------------------------------------------------------- /23b-mongodb-client/client/directivas/valoracion/valoracion.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var valoracion = function () { 3 | return { 4 | restrict: 'AE', 5 | templateUrl: '/directivas/valoracion/tpl-valoracion.html', 6 | scope: { 7 | valor: '=', 8 | max: '@', 9 | soloLectura: '@' 10 | }, 11 | link: function (scope, elem, attrs) { 12 | function actualizar() { 13 | if(!scope.valor)scope.valor=1; 14 | scope.estrellas = []; 15 | for (var i = 0; i < scope.max; i++) { 16 | var estrella = { 17 | marcada: (i < scope.valor) 18 | }; 19 | scope.estrellas.push(estrella); 20 | } 21 | }; 22 | 23 | scope.marcar = function (indice) { 24 | if (scope.soloLectura && scope.soloLectura === 'true') { 25 | return; 26 | } 27 | scope.valor = indice + 1; 28 | actualizar(); 29 | }; 30 | actualizar(); 31 | } 32 | } 33 | } 34 | 35 | angular.module('abDirectivas') 36 | .directive('abValoracion', valoracion); 37 | 38 | }()); -------------------------------------------------------------------------------- /23b-mongodb-client/client/movimiento/movimientoCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var movimientoCtrl = function ($stateParams, movimientosFactory) { 3 | var vm = this; 4 | vm.movimiento = movimientosFactory.movimientos.get({id:$stateParams._id}); 5 | } 6 | angular.module('controlCajaApp').controller('MovimientoCtrl', movimientoCtrl); 7 | }()); -------------------------------------------------------------------------------- /23b-mongodb-client/client/registro/registroCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var registroCtrl = function ($rootScope, $state, $http, $cookieStore) { 3 | var urlBase = "http://localhost:3000/api/"; 4 | var vm = this; 5 | vm.usuario = {}; 6 | vm.entrar = function () { 7 | $http.post(urlBase + 'sesiones/', vm.usuario) 8 | .success(function (data) { 9 | $rootScope.nombre = vm.usuario.email; 10 | $rootScope.mensaje = 'recién entrado'; 11 | $cookieStore.put("sessionId", data); 12 | $state.go("total"); 13 | }); 14 | } 15 | vm.registrar = function () { 16 | $http.post(urlBase + 'usuarios/', vm.usuario) 17 | .success(function (data) { 18 | $rootScope.nombre = vm.usuario.email; 19 | $rootScope.mensaje = 'recién creado'; 20 | $cookieStore.put("sessionId", data); 21 | $state.go("total"); 22 | }); 23 | } 24 | } 25 | angular.module('controlCajaApp').controller('RegistroCtrl', registroCtrl); 26 | }()); -------------------------------------------------------------------------------- /23b-mongodb-client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ControlCashFlow", 3 | "version": "0.0.0", 4 | "description": "Controla tu flujo de caja", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Alberto Basalo", 10 | "license": "BSD-2-Clause", 11 | "dependencies": { 12 | "body-parser": "~1.0.2", 13 | "express": "~4.12.1", 14 | "mongodb": "^2.0.26", 15 | "q": "^1.2.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /23b-mongodb-client/server.js: -------------------------------------------------------------------------------- 1 | var app = require('./server/config.js').configApp(); 2 | require('./server/seguridad.js').seguridad(app); 3 | console.log('ready'); 4 | 5 | require('./server/maestros.js').routeMaestros(app); 6 | require('./server/movimientos.js').routeMovimientos(app); 7 | console.log('steady'); 8 | 9 | app.listen(3000); 10 | console.log('go'); -------------------------------------------------------------------------------- /23b-mongodb-client/server/config.js: -------------------------------------------------------------------------------- 1 | module.exports.configApp = function () { 2 | 3 | var express = require('express'); 4 | var bodyParser = require('body-parser'); 5 | 6 | var app = express(); 7 | 8 | app.use(bodyParser()); 9 | app.use(express.static(__dirname + './../client')); 10 | 11 | app.use(function (peticion, respuesta, siguiente) { 12 | console.log("recibida petición: " + peticion.url); 13 | if (peticion.body && Object.keys(peticion.body).length > 0) { 14 | console.log("body: " + JSON.stringify(peticion.body)); 15 | } 16 | siguiente(); 17 | }); 18 | 19 | return app; 20 | 21 | } -------------------------------------------------------------------------------- /23b-mongodb-client/server/data/movimientosData.js: -------------------------------------------------------------------------------- 1 | var mongodb = require('./mongodb.js') 2 | var mongoCol = "movimientos" 3 | 4 | exports.findingByUsuario = function (usuario) { 5 | return mongodb.finding(mongoCol, { 6 | usuario: usuario 7 | }); 8 | } 9 | 10 | exports.inserting = function (movimiento) { 11 | return mongodb.inserting(mongoCol, movimiento); 12 | } 13 | 14 | exports.findingByIdUsuario = function (_id, usuario) { 15 | return mongodb.finding(mongoCol, { 16 | _id: new mongodb.ObjectId(_id), 17 | usuario: usuario 18 | }); 19 | } -------------------------------------------------------------------------------- /23b-mongodb-client/server/data/usuariosData.js: -------------------------------------------------------------------------------- 1 | var mongodb = require('./mongodb.js') 2 | var mongoCol = "usuarios" 3 | 4 | exports.findingByEmail = function (email) { 5 | return mongodb.finding(mongoCol, { 6 | email: email 7 | }); 8 | } 9 | 10 | exports.findingByEmailPassword = function (email, password) { 11 | return mongodb.finding(mongoCol, { 12 | email: email, 13 | password: password 14 | }); 15 | } 16 | 17 | exports.inserting = function (usuario) { 18 | return mongodb.inserting(mongoCol, usuario); 19 | } 20 | 21 | exports.updating = function (usuario) { 22 | return mongodb.updating(mongoCol, { 23 | email: usuario.email 24 | }, 25 | usuario); 26 | } -------------------------------------------------------------------------------- /23b-mongodb-client/server/maestros.js: -------------------------------------------------------------------------------- 1 | module.exports.routeMaestros = function (app) { 2 | app.get('/api/pub/maestros', function (req, res, next) { 3 | var maestros = { 4 | categoriasIngresos: ['Nómina', 'Ventas', 'Intereses Depósitos'], 5 | categoriasGastos: ['Hipotéca', 'Compras', 'Impuestos'] 6 | }; 7 | res.json(maestros); 8 | }); 9 | } -------------------------------------------------------------------------------- /24-pretty-url/client/static/_comun/app.js: -------------------------------------------------------------------------------- 1 | angular.module('controlCajaApp', ['ui.router', 'ngCookies', 'ngResource', 'abFiltros', 'abDirectivas']); 2 | 3 | angular.module('controlCajaApp').config(function ($stateProvider, $urlRouterProvider, $locationProvider) { 4 | // configuración para url amigables 5 | $locationProvider.html5Mode(true); 6 | // En caso de rutas no validas, vamos a la página raiz 7 | $urlRouterProvider.otherwise('/'); 8 | $stateProvider 9 | .state('total', { 10 | url: '/', 11 | controller: 'CajaCtrl as caja', 12 | templateUrl: 'static/controlcaja/total.html' 13 | }) 14 | .state('nuevo', { 15 | url: '/nuevo', 16 | 17 | controller: 'CajaCtrl as caja', 18 | templateUrl: 'static/controlcaja/nuevo.html' 19 | }) 20 | .state('lista', { 21 | url: '/lista', 22 | controller: 'CajaCtrl as caja', 23 | templateUrl: 'static/controlcaja/lista.html' 24 | }) 25 | .state('movimiento', { 26 | url: '/movimiento/:_id', 27 | controller: 'MovimientoCtrl as vm', 28 | templateUrl: 'static/movimiento/movimiento.html' 29 | }) 30 | .state('registro', { 31 | url: '/registro', 32 | controller: 'RegistroCtrl as registro', 33 | templateUrl: 'static/registro/registro.html' 34 | }); 35 | }); -------------------------------------------------------------------------------- /24-pretty-url/client/static/_comun/appHttpLog.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | function configuradorInterceptores($httpProvider) { 4 | $httpProvider.interceptors.push(funcionInterceptoraLog); 5 | } 6 | 7 | function funcionInterceptoraLog($log) { 8 | 9 | var interceptor = {}; 10 | interceptor.request = function (request) { 11 | $log.info('request:' + request.url); 12 | return request ; 13 | }; 14 | interceptor.responseError = function (response) { 15 | $log.error("excepción: " + response.status + " de :" + response.config.url); 16 | } 17 | return interceptor; 18 | } 19 | 20 | angular.module('controlCajaApp').config(configuradorInterceptores); 21 | }()); -------------------------------------------------------------------------------- /24-pretty-url/client/static/_comun/appSecurity.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | function configuradorInterceptores($httpProvider) { 3 | $httpProvider.interceptors.push(funcionInterceptoraSeguridad); 4 | } 5 | 6 | function funcionInterceptoraSeguridad($q, $injector, $cookieStore, $rootScope) { 7 | 8 | var interceptor = {}; 9 | interceptor.request = function (request) { 10 | request.headers["sessionId"] = $cookieStore.get("sessionId"); 11 | return request || $q.when(request); 12 | }; 13 | interceptor.responseError = function (response) { 14 | var state = $injector.get('$state'); 15 | if (response.status === 401) { 16 | $rootScope.mensaje = "No hay derecho!!!"; 17 | state.go('registro'); 18 | } else if (response.status === 419) { 19 | $rootScope.mensaje = "Estoy caduco!!!"; 20 | $cookieStore.remove("sessionId") 21 | state.go('registro'); 22 | }; 23 | return $q.reject(response); 24 | } 25 | return interceptor; 26 | } 27 | 28 | angular.module('controlCajaApp').config(configuradorInterceptores); 29 | }()); -------------------------------------------------------------------------------- /24-pretty-url/client/static/_comun/menuCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var menuCtrl = function ($state) { 3 | this.isActive = function (estado) { 4 | return $state.is(estado); 5 | } 6 | } 7 | angular.module('controlCajaApp').controller('MenuCtrl',menuCtrl); 8 | }()); -------------------------------------------------------------------------------- /24-pretty-url/client/static/_comun/not-found.html: -------------------------------------------------------------------------------- 1 |
2 |

No se ha encontrado lo que buscabas

3 |
-------------------------------------------------------------------------------- /24-pretty-url/client/static/controlcaja/cajaCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var cajaCtrl = function (maestrosFactory, movimientosFactory) { 3 | var vm = this; 4 | 5 | 6 | vm.titulo = "Controla tu Cash Flow"; 7 | 8 | vm.maestros = maestrosFactory.get(); 9 | 10 | vm.nuevoMovimiento = new movimientosFactory.movimientos(); 11 | vm.nuevoMovimiento.esIngreso = 1; 12 | vm.nuevoMovimiento.fecha = new Date(); 13 | 14 | vm.movimientos = movimientosFactory.movimientos.query(); 15 | 16 | vm.total = movimientosFactory.total.get(); 17 | 18 | vm.guardarMovimiento = function () { 19 | vm.nuevoMovimiento.tipo = vm.tipo(vm.nuevoMovimiento); 20 | vm.nuevoMovimiento.$save() 21 | .then(function (postedData) { 22 | vm.movimientos = movimientosFactory.movimientos.query(); 23 | vm.total = movimientosFactory.total.get(); 24 | vm.nuevoMovimiento.importe = 0; 25 | }); 26 | } 27 | vm.balance = function () { 28 | return vm.total.ingresos - vm.total.gastos 29 | } 30 | vm.tipo = function (movimiento) { 31 | return movimiento.esIngreso && 'Ingreso' || 'Gasto' 32 | } 33 | } 34 | angular.module('controlCajaApp').controller('CajaCtrl', cajaCtrl); 35 | }()); -------------------------------------------------------------------------------- /24-pretty-url/client/static/controlcaja/lista.html: -------------------------------------------------------------------------------- 1 |
2 | Estos son tus movimientos recientes. 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | 16 | 18 | 19 | 20 | 21 | 22 | 26 | 27 |
IdFecha 13 | TipoCategoríaImporte 17 | Valoración
28 |
-------------------------------------------------------------------------------- /24-pretty-url/client/static/controlcaja/total.html: -------------------------------------------------------------------------------- 1 |
2 | Comprueba de dónde viene y a dónde va tu dinero. 3 |
4 |
5 |
6 |

7 | 8 | {{ caja.total.ingresos | number:2 }} € 9 | 10 |

11 |

Total ingresos

12 | Acumulado 13 |
14 |
15 |

16 | 17 | {{ caja.total.gastos | number:2 }} € 18 | 19 |

20 |

Total gastos

21 | Acumulado 22 |
23 |
24 |

25 | 26 | {{ caja.balance() | number:2 }} € 27 | 28 |

29 |

Balance

30 | Ingresos-Gastos 31 |
32 |
33 |
34 |
-------------------------------------------------------------------------------- /24-pretty-url/client/static/data/maestrosFactory.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var maestrosFactory =   function ($resource)  { 3 | return $resource("/api/pub/maestros/",{},{get: {cache: true}}); 4 | }; 5 | 6 | angular.module('controlCajaApp').factory('maestrosFactory', maestrosFactory); 7 | }()); -------------------------------------------------------------------------------- /24-pretty-url/client/static/data/movimientosFactory.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | var movimientosFactory =   function ($resource)  { 4 | 5 | var factory  =   {}; 6 | factory.movimientos =  $resource("/api/priv/movimientos/:id", { 7 | id: "@id" 8 | }) 9 | factory.total = $resource("/api/priv/total/"); 10 | 11 | return factory; 12 | }; 13 | 14 | angular.module('controlCajaApp').factory('movimientosFactory', movimientosFactory); 15 | }()); -------------------------------------------------------------------------------- /24-pretty-url/client/static/directivas/tpl-cabecera.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Cash Flow

4 |
5 |
6 |
7 | -------------------------------------------------------------------------------- /24-pretty-url/client/static/directivas/tpl-fila-movimiento.html: -------------------------------------------------------------------------------- 1 | 2 | {{movimientoplantilla._id }} 3 | {{movimientoplantilla.fecha | date}} 4 | {{movimientoplantilla.tipo}} 5 | {{movimientoplantilla.categoria}} 6 | 7 | {{movimientoplantilla.importe | number:2}} € 8 | 9 | 10 | -------------------------------------------------------------------------------- /24-pretty-url/client/static/directivas/valoracion/tpl-valoracion.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | 9 | * 10 | 11 | 12 | -------------------------------------------------------------------------------- /24-pretty-url/client/static/directivas/valoracion/valoracion.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var valoracion = function () { 3 | return { 4 | restrict: 'AE', 5 | templateUrl: '/static/directivas/valoracion/tpl-valoracion.html', 6 | scope: { 7 | valor: '=', 8 | max: '@', 9 | soloLectura: '@' 10 | }, 11 | link: function (scope, elem, attrs) { 12 | function actualizar() { 13 | if(!scope.valor)scope.valor=1; 14 | scope.estrellas = []; 15 | for (var i = 0; i < scope.max; i++) { 16 | var estrella = { 17 | marcada: (i < scope.valor) 18 | }; 19 | scope.estrellas.push(estrella); 20 | } 21 | }; 22 | 23 | scope.marcar = function (indice) { 24 | if (scope.soloLectura && scope.soloLectura === 'true') { 25 | return; 26 | } 27 | scope.valor = indice + 1; 28 | actualizar(); 29 | }; 30 | actualizar(); 31 | } 32 | } 33 | } 34 | 35 | angular.module('abDirectivas') 36 | .directive('abValoracion', valoracion); 37 | 38 | }()); -------------------------------------------------------------------------------- /24-pretty-url/client/static/movimiento/movimientoCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var movimientoCtrl = function ($stateParams, movimientosFactory) { 3 | var vm = this; 4 | vm.movimiento = movimientosFactory.movimientos.get({id:$stateParams._id}); 5 | } 6 | angular.module('controlCajaApp').controller('MovimientoCtrl', movimientoCtrl); 7 | }()); -------------------------------------------------------------------------------- /24-pretty-url/client/static/registro/registroCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var registroCtrl = function ($rootScope, $state, $http, $cookieStore) { 3 | var urlBase = "http://localhost:3000/api/"; 4 | var vm = this; 5 | vm.usuario = {}; 6 | vm.entrar = function () { 7 | $http.post(urlBase + 'sesiones/', vm.usuario) 8 | .success(function (data) { 9 | afterLogIn(data); 10 | }); 11 | } 12 | vm.registrar = function () { 13 | $http.post(urlBase + 'usuarios/', vm.usuario) 14 | .success(function (data) { 15 | afterLogIn(data); 16 | }); 17 | } 18 | 19 | function afterLogIn(data) { 20 | $rootScope.nombre = vm.usuario.email; 21 | $cookieStore.put("sessionId", data); 22 | $state.go("total"); 23 | } 24 | } 25 | angular.module('controlCajaApp').controller('RegistroCtrl', registroCtrl); 26 | }()); -------------------------------------------------------------------------------- /24-pretty-url/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ControlCashFlow", 3 | "version": "0.0.0", 4 | "description": "Controla tu flujo de caja", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Alberto Basalo", 10 | "license": "BSD-2-Clause", 11 | "dependencies": { 12 | "body-parser": "~1.0.2", 13 | "express": "~4.12.1", 14 | "mongodb": "^2.0.26", 15 | "q": "^1.2.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /24-pretty-url/server.js: -------------------------------------------------------------------------------- 1 | var app = require('./server/config.js').configApp(); 2 | require('./server/seguridad.js').seguridad(app); 3 | console.log('ready'); 4 | 5 | require('./server/maestros.js').routeMaestros(app); 6 | require('./server/movimientos.js').routeMovimientos(app); 7 | console.log('steady'); 8 | 9 | 10 | 11 | app.listen(3000); 12 | console.log('go'); -------------------------------------------------------------------------------- /24-pretty-url/server/config.js: -------------------------------------------------------------------------------- 1 | module.exports.configApp = function () { 2 | var path = require('path'); 3 | var express = require('express'); 4 | var bodyParser = require('body-parser'); 5 | 6 | var app = express(); 7 | 8 | 9 | app.use(function (peticion, respuesta, siguiente) { 10 | console.log("recibida petición: " + peticion.url); 11 | if (peticion.body && Object.keys(peticion.body).length > 0) { 12 | console.log("body: " + JSON.stringify(peticion.body)); 13 | } 14 | siguiente(); 15 | }); 16 | app.use(bodyParser()); 17 | 18 | // rewrites para que permita usar rutas sin # 19 | app.get('/*', function (req, res, next) { 20 | if ((req.url.indexOf("static/") >= 0) || (req.url.indexOf("api/") >= 0)) { 21 | next(); 22 | } else { 23 | res.sendFile('./index.html', { 24 | root: path.join(__dirname, '../client') 25 | }); 26 | } 27 | }); 28 | app.use(express.static(__dirname + './../client')); 29 | 30 | 31 | return app; 32 | 33 | } -------------------------------------------------------------------------------- /24-pretty-url/server/data/movimientosData.js: -------------------------------------------------------------------------------- 1 | var mongodb = require('./mongodb.js') 2 | var mongoCol = "movimientos" 3 | 4 | exports.findingByUsuario = function (usuario) { 5 | return mongodb.finding(mongoCol, { 6 | usuario: usuario 7 | }); 8 | } 9 | 10 | exports.inserting = function (movimiento) { 11 | return mongodb.inserting(mongoCol, movimiento); 12 | } 13 | 14 | exports.findingByIdUsuario = function (_id, usuario) { 15 | return mongodb.finding(mongoCol, { 16 | _id: new mongodb.ObjectId(_id), 17 | usuario: usuario 18 | }); 19 | } -------------------------------------------------------------------------------- /24-pretty-url/server/data/usuariosData.js: -------------------------------------------------------------------------------- 1 | var mongodb = require('./mongodb.js') 2 | var mongoCol = "usuarios" 3 | 4 | exports.findingByEmail = function (email) { 5 | return mongodb.finding(mongoCol, { 6 | email: email 7 | }); 8 | } 9 | 10 | exports.findingByEmailPassword = function (email, password) { 11 | return mongodb.finding(mongoCol, { 12 | email: email, 13 | password: password 14 | }); 15 | } 16 | 17 | exports.inserting = function (usuario) { 18 | return mongodb.inserting(mongoCol, usuario); 19 | } 20 | 21 | exports.updating = function (usuario) { 22 | return mongodb.updating(mongoCol, { 23 | email: usuario.email 24 | }, 25 | usuario); 26 | } 27 | 28 | -------------------------------------------------------------------------------- /24-pretty-url/server/maestros.js: -------------------------------------------------------------------------------- 1 | module.exports.routeMaestros = function (app) { 2 | app.get('/api/pub/maestros', function (req, res, next) { 3 | var maestros = { 4 | categoriasIngresos: ['Nómina', 'Ventas', 'Intereses Depósitos'], 5 | categoriasGastos: ['Hipotéca', 'Compras', 'Impuestos'] 6 | }; 7 | res.json(maestros); 8 | }); 9 | } -------------------------------------------------------------------------------- /25-socket-io/client/static/_comun/app.js: -------------------------------------------------------------------------------- 1 | angular.module('controlCajaApp', ['ui.router', 'ngCookies', 'ngResource', 'abFiltros', 'abDirectivas']); 2 | 3 | angular.module('controlCajaApp').config(function ($stateProvider, $urlRouterProvider, $locationProvider) { 4 | $locationProvider.html5Mode(true); 5 | 6 | $urlRouterProvider.otherwise('/'); 7 | $stateProvider 8 | .state('total', { 9 | url: '/', 10 | controller: 'CajaCtrl as caja', 11 | templateUrl: 'static/controlcaja/total.html' 12 | }) 13 | .state('nuevo', { 14 | url: '/nuevo', 15 | 16 | controller: 'CajaCtrl as caja', 17 | templateUrl: 'static/controlcaja/nuevo.html' 18 | }) 19 | .state('lista', { 20 | url: '/lista', 21 | controller: 'CajaCtrl as caja', 22 | templateUrl: 'static/controlcaja/lista.html' 23 | }) 24 | .state('movimiento', { 25 | url: '/movimiento/:_id', 26 | controller: 'MovimientoCtrl as vm', 27 | templateUrl: 'static/movimiento/movimiento.html' 28 | }) 29 | .state('registro', { 30 | url: '/registro', 31 | controller: 'RegistroCtrl as registro', 32 | templateUrl: 'static/registro/registro.html' 33 | }).state('dashboard', { // Nuevo estado para el dashboard 34 | url: '/dashboard', 35 | controller: 'DashboardCtrl as vm', 36 | templateUrl: 'static/dashboard/dashboard.html' 37 | }); 38 | 39 | }); -------------------------------------------------------------------------------- /25-socket-io/client/static/_comun/appHttpLog.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | function configuradorInterceptores($httpProvider) { 4 | $httpProvider.interceptors.push(funcionInterceptoraLog); 5 | } 6 | 7 | function funcionInterceptoraLog($log) { 8 | 9 | var interceptor = {}; 10 | interceptor.request = function (request) { 11 | $log.info('request:' + request.url); 12 | return request ; 13 | }; 14 | interceptor.responseError = function (response) { 15 | $log.error("excepción: " + response.status + " de :" + response.config.url); 16 | } 17 | return interceptor; 18 | } 19 | 20 | angular.module('controlCajaApp').config(configuradorInterceptores); 21 | }()); -------------------------------------------------------------------------------- /25-socket-io/client/static/_comun/appSecurity.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | function configuradorInterceptores($httpProvider) { 3 | $httpProvider.interceptors.push(funcionInterceptoraSeguridad); 4 | } 5 | 6 | function funcionInterceptoraSeguridad($q, $injector, $cookieStore, $rootScope) { 7 | 8 | var interceptor = {}; 9 | interceptor.request = function (request) { 10 | request.headers["sessionId"] = $cookieStore.get("sessionId"); 11 | return request || $q.when(request); 12 | }; 13 | interceptor.responseError = function (response) { 14 | var state = $injector.get('$state'); 15 | if (response.status === 401) { 16 | $rootScope.mensaje = "No hay derecho!!!"; 17 | state.go('registro'); 18 | } else if (response.status === 419) { 19 | $rootScope.mensaje = "Estoy caduco!!!"; 20 | $cookieStore.remove("sessionId") 21 | state.go('registro'); 22 | }; 23 | return $q.reject(response); 24 | } 25 | return interceptor; 26 | } 27 | 28 | angular.module('controlCajaApp').config(configuradorInterceptores); 29 | }()); -------------------------------------------------------------------------------- /25-socket-io/client/static/_comun/menuCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var menuCtrl = function ($state) { 3 | this.isActive = function (estado) { 4 | return $state.is(estado); 5 | } 6 | } 7 | angular.module('controlCajaApp').controller('MenuCtrl',menuCtrl); 8 | }()); -------------------------------------------------------------------------------- /25-socket-io/client/static/_comun/not-found.html: -------------------------------------------------------------------------------- 1 |
2 |

No se ha encontrado lo que buscabas

3 |
-------------------------------------------------------------------------------- /25-socket-io/client/static/_comun/socketFactory.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | angular.module('controlCajaApp').factory('socketFactory', function () { 3 | var socket; 4 | return { 5 | connect: function(){ 6 | socket= io.connect(); 7 | console.log("IO: connected" ); 8 | }, 9 | on: function (eventName, callback) { 10 | socket.on(eventName, function () { 11 | var args = arguments; 12 | console.log("IN: " + eventName + " : " + JSON.stringify(args)); 13 | }); 14 | }, 15 | emit: function (eventName, data) { 16 | console.log("OUT: " + eventName + " : " + JSON.stringify(data)); 17 | socket.emit(eventName, data); 18 | } 19 | } 20 | }); 21 | }()); -------------------------------------------------------------------------------- /25-socket-io/client/static/controlcaja/cajaCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var cajaCtrl = function (maestrosFactory, movimientosFactory) { 3 | var vm = this; 4 | 5 | 6 | vm.titulo = "Controla tu Cash Flow"; 7 | 8 | vm.maestros = maestrosFactory.get(); 9 | 10 | vm.nuevoMovimiento = new movimientosFactory.movimientos(); 11 | vm.nuevoMovimiento.esIngreso = 1; 12 | vm.nuevoMovimiento.fecha = new Date(); 13 | 14 | vm.movimientos = movimientosFactory.movimientos.query(); 15 | 16 | vm.total = movimientosFactory.total.get(); 17 | 18 | vm.guardarMovimiento = function () { 19 | vm.nuevoMovimiento.tipo = vm.tipo(vm.nuevoMovimiento); 20 | vm.nuevoMovimiento.$save() 21 | .then(function (postedData) { 22 | vm.movimientos = movimientosFactory.movimientos.query(); 23 | vm.total = movimientosFactory.total.get(); 24 | vm.nuevoMovimiento.importe = 0; 25 | }); 26 | } 27 | vm.balance = function () { 28 | return vm.total.ingresos - vm.total.gastos 29 | } 30 | vm.tipo = function (movimiento) { 31 | return movimiento.esIngreso && 'Ingreso' || 'Gasto' 32 | } 33 | } 34 | angular.module('controlCajaApp').controller('CajaCtrl', cajaCtrl); 35 | }()); -------------------------------------------------------------------------------- /25-socket-io/client/static/controlcaja/lista.html: -------------------------------------------------------------------------------- 1 |
2 | Estos son tus movimientos recientes. 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | 16 | 18 | 19 | 20 | 21 | 22 | 26 | 27 |
IdFecha 13 | TipoCategoríaImporte 17 | Valoración
28 |
-------------------------------------------------------------------------------- /25-socket-io/client/static/controlcaja/total.html: -------------------------------------------------------------------------------- 1 |
2 | Comprueba de dónde viene y a dónde va tu dinero. 3 |
4 |
5 |
6 |

7 | 8 | {{ caja.total.ingresos | number:2 }} € 9 | 10 |

11 |

Total ingresos

12 | Acumulado 13 |
14 |
15 |

16 | 17 | {{ caja.total.gastos | number:2 }} € 18 | 19 |

20 |

Total gastos

21 | Acumulado 22 |
23 |
24 |

25 | 26 | {{ caja.balance() | number:2 }} € 27 | 28 |

29 |

Balance

30 | Ingresos-Gastos 31 |
32 |
33 |
34 |
-------------------------------------------------------------------------------- /25-socket-io/client/static/dashboard/dashboard.html: -------------------------------------------------------------------------------- 1 |
2 | Comprueba de dónde viene y a dónde va tu dinero. 3 |
4 |
5 |
6 |

7 | 8 | {{ vm.total.usuarios | number:0 }} 9 | 10 |

11 |

Usuarios

12 |
13 |
14 |

15 | 16 | {{ vm.total.ingresos | number:2 }} € 17 | 18 |

19 |

Total ingresos

20 |
21 |
22 |

23 | 24 | {{ vm.total.gastos | number:2 }} € 25 | 26 |

27 |

Total gastos

28 |
29 |
30 |
31 |
-------------------------------------------------------------------------------- /25-socket-io/client/static/dashboard/dashboardCtrl.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | "use strict"; 3 | 4 | angular 5 | .module("controlCajaApp") 6 | .controller("DashboardCtrl", function (socketFactory) { 7 | var vm = this; 8 | socketFactory.connect(); 9 | socketFactory.on('total_updated', function (msgIn) { 10 | vm.total = msgIn[0]; 11 | }); 12 | }); 13 | 14 | }()); -------------------------------------------------------------------------------- /25-socket-io/client/static/data/maestrosFactory.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var maestrosFactory =   function ($resource)  { 3 | return $resource("/api/pub/maestros/",{},{get: {cache: true}}); 4 | }; 5 | 6 | angular.module('controlCajaApp').factory('maestrosFactory', maestrosFactory); 7 | }()); -------------------------------------------------------------------------------- /25-socket-io/client/static/data/movimientosFactory.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | var movimientosFactory =   function ($resource)  { 4 | 5 | var factory  =   {}; 6 | factory.movimientos =  $resource("/api/priv/movimientos/:id", { 7 | id: "@id" 8 | }) 9 | factory.total = $resource("/api/priv/total/"); 10 | 11 | return factory; 12 | }; 13 | 14 | angular.module('controlCajaApp').factory('movimientosFactory', movimientosFactory); 15 | }()); -------------------------------------------------------------------------------- /25-socket-io/client/static/directivas/tpl-cabecera.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Cash Flow

4 |
5 |
6 |
7 | -------------------------------------------------------------------------------- /25-socket-io/client/static/directivas/tpl-fila-movimiento.html: -------------------------------------------------------------------------------- 1 | 2 | {{movimientoplantilla._id }} 3 | {{movimientoplantilla.fecha | date}} 4 | {{movimientoplantilla.tipo}} 5 | {{movimientoplantilla.categoria}} 6 | 7 | {{movimientoplantilla.importe | number:2}} € 8 | 9 | 10 | -------------------------------------------------------------------------------- /25-socket-io/client/static/directivas/valoracion/tpl-valoracion.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | 9 | * 10 | 11 | 12 | -------------------------------------------------------------------------------- /25-socket-io/client/static/directivas/valoracion/valoracion.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var valoracion = function () { 3 | return { 4 | restrict: 'AE', 5 | templateUrl: '/static/directivas/valoracion/tpl-valoracion.html', 6 | scope: { 7 | valor: '=', 8 | max: '@', 9 | soloLectura: '@' 10 | }, 11 | link: function (scope, elem, attrs) { 12 | function actualizar() { 13 | if(!scope.valor)scope.valor=1; 14 | scope.estrellas = []; 15 | for (var i = 0; i < scope.max; i++) { 16 | var estrella = { 17 | marcada: (i < scope.valor) 18 | }; 19 | scope.estrellas.push(estrella); 20 | } 21 | }; 22 | 23 | scope.marcar = function (indice) { 24 | if (scope.soloLectura && scope.soloLectura === 'true') { 25 | return; 26 | } 27 | scope.valor = indice + 1; 28 | actualizar(); 29 | }; 30 | actualizar(); 31 | } 32 | } 33 | } 34 | 35 | angular.module('abDirectivas') 36 | .directive('abValoracion', valoracion); 37 | 38 | }()); -------------------------------------------------------------------------------- /25-socket-io/client/static/movimiento/movimientoCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var movimientoCtrl = function ($stateParams, movimientosFactory) { 3 | var vm = this; 4 | vm.movimiento = movimientosFactory.movimientos.get({id:$stateParams._id}); 5 | } 6 | angular.module('controlCajaApp').controller('MovimientoCtrl', movimientoCtrl); 7 | }()); -------------------------------------------------------------------------------- /25-socket-io/client/static/registro/registroCtrl.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var registroCtrl = function ($rootScope, $state, $http, $cookieStore, socketFactory) { 3 | var urlBase = "http://localhost:3000/api/"; 4 | var vm = this; 5 | vm.usuario = {}; 6 | vm.entrar = function () { 7 | $http.post(urlBase + 'sesiones/', vm.usuario) 8 | .success(function (data) { 9 | afterLogIn(data); 10 | }); 11 | } 12 | vm.registrar = function () { 13 | $http.post(urlBase + 'usuarios/', vm.usuario) 14 | .success(function (data) { 15 | afterLogIn(data); 16 | }); 17 | } 18 | 19 | function afterLogIn(data) { 20 | $rootScope.nombre = vm.usuario.email; 21 | $cookieStore.put("sessionId", data); 22 | socketFactory.connect(); 23 | socketFactory.on('wellcome', function (msgIn) { 24 | console.log("Me he conectado: " + JSON.stringify(msgIn)); 25 | socketFactory.emit("ackClient", "thanks"); 26 | }); 27 | socketFactory.on('ackServer', function (msgIn) { 28 | console.log("Han recibido mi mensaje: " + JSON.stringify(msgIn)); 29 | }); 30 | $state.go("total"); 31 | } 32 | } 33 | angular.module('controlCajaApp').controller('RegistroCtrl', registroCtrl); 34 | }()); -------------------------------------------------------------------------------- /25-socket-io/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ControlCashFlow", 3 | "version": "0.0.0", 4 | "description": "Controla tu flujo de caja", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Alberto Basalo", 10 | "license": "BSD-2-Clause", 11 | "dependencies": { 12 | "body-parser": "~1.0.2", 13 | "express": "~4.12.1", 14 | "mongodb": "^2.0.26", 15 | "q": "^1.2.0", 16 | "socket.io": "^1.3.5" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /25-socket-io/server.js: -------------------------------------------------------------------------------- 1 | var app = require('./server/config.js').configApp(); 2 | var socket = require('./server/socket.js').initIO(app); 3 | require('./server/seguridad.js').seguridad(app); 4 | console.log('ready'); 5 | 6 | require('./server/maestros.js').routeMaestros(app); 7 | require('./server/movimientos.js').routeMovimientos(app, socket.emitter); 8 | console.log('steady'); 9 | 10 | 11 | // El encargado de escuchar es el servicio http, en lugar de express 12 | // Esto se hace para soportar las llamadas desde socket.io 13 | socket.server.listen(3000); 14 | console.log('go'); -------------------------------------------------------------------------------- /25-socket-io/server/config.js: -------------------------------------------------------------------------------- 1 | module.exports.configApp = function () { 2 | var path = require('path'); 3 | var express = require('express'); 4 | var bodyParser = require('body-parser'); 5 | 6 | var app = express(); 7 | 8 | 9 | app.use(function (peticion, respuesta, siguiente) { 10 | console.log("recibida petición: " + peticion.url); 11 | if (peticion.body && Object.keys(peticion.body).length > 0) { 12 | console.log("body: " + JSON.stringify(peticion.body)); 13 | } 14 | siguiente(); 15 | }); 16 | app.use(bodyParser()); 17 | 18 | app.get('/*', function (req, res, next) { 19 | if ((req.url.indexOf("static/") >= 0) || (req.url.indexOf("api/") >= 0)) { 20 | next(); 21 | } else { 22 | res.sendFile('./index.html', { 23 | root: path.join(__dirname, '../client') 24 | }); 25 | } 26 | }); 27 | app.use(express.static(__dirname + './../client')); 28 | 29 | 30 | return app; 31 | 32 | } -------------------------------------------------------------------------------- /25-socket-io/server/data/movimientosData.js: -------------------------------------------------------------------------------- 1 | var mongodb = require('./mongodb.js') 2 | var mongoCol = "movimientos" 3 | 4 | exports.findingByUsuario = function (usuario) { 5 | return mongodb.finding(mongoCol, { 6 | usuario: usuario 7 | }); 8 | } 9 | 10 | exports.inserting = function (movimiento) { 11 | return mongodb.inserting(mongoCol, movimiento); 12 | } 13 | 14 | exports.findingByIdUsuario = function (_id, usuario) { 15 | return mongodb.finding(mongoCol, { 16 | _id: new mongodb.ObjectId(_id), 17 | usuario: usuario 18 | }); 19 | } -------------------------------------------------------------------------------- /25-socket-io/server/data/usuariosData.js: -------------------------------------------------------------------------------- 1 | var mongodb = require('./mongodb.js') 2 | var mongoCol = "usuarios" 3 | 4 | exports.findingByEmail = function (email) { 5 | return mongodb.finding(mongoCol, { 6 | email: email 7 | }); 8 | } 9 | 10 | exports.findingByEmailPassword = function (email, password) { 11 | return mongodb.finding(mongoCol, { 12 | email: email, 13 | password: password 14 | }); 15 | } 16 | 17 | exports.inserting = function (usuario) { 18 | return mongodb.inserting(mongoCol, usuario); 19 | } 20 | 21 | exports.updating = function (usuario) { 22 | return mongodb.updating(mongoCol, { 23 | email: usuario.email 24 | }, 25 | usuario); 26 | } 27 | 28 | exports.findingTotal = function () { 29 | 30 | return mongodb.aggregating(mongoCol, [{ 31 | $group: { 32 | _id: null, 33 | usuarios: { 34 | $sum: 1 35 | }, 36 | ingresos: { 37 | $sum: "$total.ingresos" 38 | }, 39 | gastos: { 40 | $sum: "$total.gastos" 41 | } 42 | } 43 | }]); 44 | } 45 | 46 | -------------------------------------------------------------------------------- /25-socket-io/server/maestros.js: -------------------------------------------------------------------------------- 1 | module.exports.routeMaestros = function (app) { 2 | app.get('/api/pub/maestros', function (req, res, next) { 3 | var maestros = { 4 | categoriasIngresos: ['Nómina', 'Ventas', 'Intereses Depósitos'], 5 | categoriasGastos: ['Hipotéca', 'Compras', 'Impuestos'] 6 | }; 7 | res.json(maestros); 8 | }); 9 | } -------------------------------------------------------------------------------- /25-socket-io/server/socket.js: -------------------------------------------------------------------------------- 1 | var io; 2 | module.exports.initIO = function (app) { 3 | 4 | var server = require('http').Server(app); 5 | io = require('socket.io')(server); 6 | 7 | function conectar(socket) { 8 | console.log("IN: conectado!!!" + socket.client.conn.remoteAddress); 9 | var saludo = { 10 | serverPid: process.pid, 11 | date: new Date() 12 | }; 13 | socket.emit('wellcome', saludo); 14 | socket.on('ackClient', function (data) { 15 | console.log("IN: mensaje: " + data); 16 | socket.emit('ackServer', data); 17 | }); 18 | } 19 | io.on("connect", conectar); 20 | 21 | 22 | // Devolvemos el servidor http que hay bajo express y un puntero a una función para emitir mensajes 23 | return { 24 | server: server, 25 | emitter: emitirCanalMensaje 26 | }; 27 | } 28 | 29 | 30 | function emitirCanalMensaje(canal, mensaje) { 31 | console.log("OUT: " + canal + ' : ' +JSON.stringify(mensaje)); 32 | io.sockets.emit(canal, mensaje); 33 | } -------------------------------------------------------------------------------- /26-pro/pro.md: -------------------------------------------------------------------------------- 1 | # AngularJS fullStack JavaScript 2 | 3 | ##Recursos extra para incorporar a una aplicación profesional 4 | 5 | ### Flujo de trabajo [gulp](http://gulpjs.com/) 6 | ### Concatenar y minificar [useref](https://www.npmjs.com/package/gulp-useref) 7 | ### Traducción [gettext](https://angular-gettext.rocketeer.be/) 8 | ### SEO [prerender.io](https://prerender.io/) 9 | ### Validación de esquema documento [mongoose](http://mongoosejs.com/) 10 | ### Carga dinámica [ocLazyLoad](https://github.com/ocombe/ocLazyLoad) 11 | ### Analíticas [angulartics](https://github.com/luisfarzati/angulartics) 12 | ### Animaciones [ngFx](https://github.com/Hendrixer/ngFx) 13 | ### Formularios complejos o dinámicos [formly](http://formly-js.github.io/angular-formly/#/) 14 | ### User Interface [angular-ui](https://angular-ui.github.io/) 15 | ### Gráficos [angular-chartist ](https://github.com/paradox41/angular-chartist.js) 16 | ### Tests [Karma](http://karma-runner.github.io) 17 | ### SiteMap [gulp-sitemap](https://www.npmjs.com/package/gulp-sitemap) 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Curso-angularjs-FS 2 | ======================= 3 | 4 | 5 | 6 | 7 | --------------------------------------------------------------------------------