From 2ae971a7ad1eaa1ea4f45c8591b911f1c333a51b Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Mon, 10 Jul 2017 15:51:58 +0200 Subject: [PATCH 001/222] Typescript conversion. --- .../{account.config.js => account.config.ts} | 0 .../{account.controller.js => account.controller.ts} | 0 .../{account.factory.js => account.factory.ts} | 0 ...alances.factory.js => accountBalances.factory.ts} | 0 src/accounts/{index.js => index.ts} | 8 ++++---- src/{app.config.js => app.config.ts} | 0 src/{app.js => app.ts} | 12 ++++++------ src/{bootstrap.config.js => bootstrap.config.ts} | 0 src/login/{index.js => index.ts} | 0 src/login/{login.config.js => login.config.ts} | 0 src/login/{login.service.js => login.service.ts} | 0 ...chart.component.js => balance-chart.component.ts} | 0 ...hart.component.js => category-chart.component.ts} | 0 src/operations/{index.js => index.ts} | 9 +++++---- .../{operation.config.js => operation.config.ts} | 0 ...eration.controller.js => operation.controller.ts} | 0 .../{operation.factory.js => operation.factory.ts} | 0 src/scheduler/{index.js => index.ts} | 6 +++--- .../{schedule.config.js => schedule.config.ts} | 0 ...schedule.controller.js => schedule.controller.ts} | 0 .../{schedule.factory.js => schedule.factory.ts} | 0 webpack.config.js | 11 ++++++++++- 22 files changed, 28 insertions(+), 18 deletions(-) rename src/accounts/{account.config.js => account.config.ts} (100%) rename src/accounts/{account.controller.js => account.controller.ts} (100%) rename src/accounts/{account.factory.js => account.factory.ts} (100%) rename src/accounts/{accountBalances.factory.js => accountBalances.factory.ts} (100%) rename src/accounts/{index.js => index.ts} (85%) rename src/{app.config.js => app.config.ts} (100%) rename src/{app.js => app.ts} (77%) rename src/{bootstrap.config.js => bootstrap.config.ts} (100%) rename src/login/{index.js => index.ts} (100%) rename src/login/{login.config.js => login.config.ts} (100%) rename src/login/{login.service.js => login.service.ts} (100%) rename src/operations/{balance-chart.component.js => balance-chart.component.ts} (100%) rename src/operations/{category-chart.component.js => category-chart.component.ts} (100%) rename src/operations/{index.js => index.ts} (86%) rename src/operations/{operation.config.js => operation.config.ts} (100%) rename src/operations/{operation.controller.js => operation.controller.ts} (100%) rename src/operations/{operation.factory.js => operation.factory.ts} (100%) rename src/scheduler/{index.js => index.ts} (87%) rename src/scheduler/{schedule.config.js => schedule.config.ts} (100%) rename src/scheduler/{schedule.controller.js => schedule.controller.ts} (100%) rename src/scheduler/{schedule.factory.js => schedule.factory.ts} (100%) diff --git a/src/accounts/account.config.js b/src/accounts/account.config.ts similarity index 100% rename from src/accounts/account.config.js rename to src/accounts/account.config.ts diff --git a/src/accounts/account.controller.js b/src/accounts/account.controller.ts similarity index 100% rename from src/accounts/account.controller.js rename to src/accounts/account.controller.ts diff --git a/src/accounts/account.factory.js b/src/accounts/account.factory.ts similarity index 100% rename from src/accounts/account.factory.js rename to src/accounts/account.factory.ts diff --git a/src/accounts/accountBalances.factory.js b/src/accounts/accountBalances.factory.ts similarity index 100% rename from src/accounts/accountBalances.factory.js rename to src/accounts/accountBalances.factory.ts diff --git a/src/accounts/index.js b/src/accounts/index.ts similarity index 85% rename from src/accounts/index.js rename to src/accounts/index.ts index 75e3bc0..bab9a69 100644 --- a/src/accounts/index.js +++ b/src/accounts/index.ts @@ -25,10 +25,10 @@ var ngResource = require('angular-resource'), ngUiNotification = require('angular-ui-notification'), ngStrap = require('angular-strap'); -var AccountFactory = require('./account.factory.js'); -var AccountBalancesFactory = require('./accountBalances.factory.js'); -var AccountConfig = require('./account.config.js'); -var AccountController = require('./account.controller.js'); +var AccountFactory = require('./account.factory'); +var AccountBalancesFactory = require('./accountBalances.factory'); +var AccountConfig = require('./account.config'); +var AccountController = require('./account.controller'); module.exports = angular.module('accountant.accounts', [ ngResource, diff --git a/src/app.config.js b/src/app.config.ts similarity index 100% rename from src/app.config.js rename to src/app.config.ts diff --git a/src/app.js b/src/app.ts similarity index 77% rename from src/app.js rename to src/app.ts index b4b2d47..241ff89 100644 --- a/src/app.js +++ b/src/app.ts @@ -22,14 +22,14 @@ var angular = require('angular'); var ngRoute = require('angular-route'); -var accountModule = require('./accounts'), - loginModule = require('./login'), - operationModule = require('./operations'), - schedulerModule = require('./scheduler'); +import accountModule from '@accountant/accounts'; +import loginModule from '@accountant/login'; +import operationModule from '@accountant/operations'; +import schedulerModule from '@accountant/scheduler'; -var routing = require('./app.config'); +var routing = require('./app.config.ts'); -require('bootstrap-webpack!./bootstrap.config.js'); +require('bootstrap-webpack!./bootstrap.config.ts'); angular.module('accountant', [ ngRoute, diff --git a/src/bootstrap.config.js b/src/bootstrap.config.ts similarity index 100% rename from src/bootstrap.config.js rename to src/bootstrap.config.ts diff --git a/src/login/index.js b/src/login/index.ts similarity index 100% rename from src/login/index.js rename to src/login/index.ts diff --git a/src/login/login.config.js b/src/login/login.config.ts similarity index 100% rename from src/login/login.config.js rename to src/login/login.config.ts diff --git a/src/login/login.service.js b/src/login/login.service.ts similarity index 100% rename from src/login/login.service.js rename to src/login/login.service.ts diff --git a/src/operations/balance-chart.component.js b/src/operations/balance-chart.component.ts similarity index 100% rename from src/operations/balance-chart.component.js rename to src/operations/balance-chart.component.ts diff --git a/src/operations/category-chart.component.js b/src/operations/category-chart.component.ts similarity index 100% rename from src/operations/category-chart.component.js rename to src/operations/category-chart.component.ts diff --git a/src/operations/index.js b/src/operations/index.ts similarity index 86% rename from src/operations/index.js rename to src/operations/index.ts index 1b97b02..462930c 100644 --- a/src/operations/index.js +++ b/src/operations/index.ts @@ -27,15 +27,16 @@ var ngResource = require('angular-resource'), ngUiNotification = require('angular-ui-notification'), ngStrap = require('angular-strap'); -var balanceChartModule = require('./balance-chart.component.js'), - categoryChartModule = require('./category-chart.component.js'), - accountModule = require('../accounts'); +var balanceChartModule = require('./balance-chart.component'), + categoryChartModule = require('./category-chart.component'); + +import accountModule from '../accounts/index'; var OperationFactory = require('./operation.factory'); var OperationConfig = require('./operation.config'); var OperationController = require('./operation.controller'); -module.exports = angular.module('accountant.operations', [ +export default angular.module('accountant.operations', [ ngResource, ngMessages, ngUiNotification, diff --git a/src/operations/operation.config.js b/src/operations/operation.config.ts similarity index 100% rename from src/operations/operation.config.js rename to src/operations/operation.config.ts diff --git a/src/operations/operation.controller.js b/src/operations/operation.controller.ts similarity index 100% rename from src/operations/operation.controller.js rename to src/operations/operation.controller.ts diff --git a/src/operations/operation.factory.js b/src/operations/operation.factory.ts similarity index 100% rename from src/operations/operation.factory.js rename to src/operations/operation.factory.ts diff --git a/src/scheduler/index.js b/src/scheduler/index.ts similarity index 87% rename from src/scheduler/index.js rename to src/scheduler/index.ts index e0cc799..721c2ea 100644 --- a/src/scheduler/index.js +++ b/src/scheduler/index.ts @@ -24,9 +24,9 @@ var ngMessages = require('angular-messages'), ngUiNotification = require('angular-ui-notification'), ngStrap = require('angular-strap'); -var ScheduleConfig = require('./schedule.config.js'); -var ScheduleController = require('./schedule.controller.js'); -var ScheduleFactory = require('./schedule.factory.js'); +var ScheduleConfig = require('./schedule.config'); +var ScheduleController = require('./schedule.controller'); +var ScheduleFactory = require('./schedule.factory'); module.exports = angular.module('accountant.scheduler', [ ngMessages, diff --git a/src/scheduler/schedule.config.js b/src/scheduler/schedule.config.ts similarity index 100% rename from src/scheduler/schedule.config.js rename to src/scheduler/schedule.config.ts diff --git a/src/scheduler/schedule.controller.js b/src/scheduler/schedule.controller.ts similarity index 100% rename from src/scheduler/schedule.controller.js rename to src/scheduler/schedule.controller.ts diff --git a/src/scheduler/schedule.factory.js b/src/scheduler/schedule.factory.ts similarity index 100% rename from src/scheduler/schedule.factory.js rename to src/scheduler/schedule.factory.ts diff --git a/webpack.config.js b/webpack.config.js index 6323694..5b2e547 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -5,8 +5,17 @@ const webpack = require('webpack'); module.exports = { context: path.resolve(__dirname, 'src'), - entry: './app.js', + entry: './app.ts', devtool: 'source-map', + resolve: { + extensions: ['.js', '.jsx', '.ts', '.tsx', '.html'], + alias: { + '@accountant/accounts': './accounts/index.ts', + '@accountant/operations': './operations/index.ts', + '@accountant/login': './login/index.ts', + '@accountant/scheduler': './scheduler/index.ts' + } + }, module: { rules: [{ enforce: 'pre', From 3ff001569084e7d7a36c900606dbd9b2dd524ba4 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 11 Jul 2017 08:49:39 +0200 Subject: [PATCH 002/222] Fix module resolution. --- src/operations/index.ts | 2 +- webpack.config.js | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/operations/index.ts b/src/operations/index.ts index 462930c..1b3a6f1 100644 --- a/src/operations/index.ts +++ b/src/operations/index.ts @@ -30,7 +30,7 @@ var ngResource = require('angular-resource'), var balanceChartModule = require('./balance-chart.component'), categoryChartModule = require('./category-chart.component'); -import accountModule from '../accounts/index'; +import accountModule from '@accountant/accounts'; var OperationFactory = require('./operation.factory'); var OperationConfig = require('./operation.config'); diff --git a/webpack.config.js b/webpack.config.js index 5b2e547..9e35efb 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -10,10 +10,14 @@ module.exports = { resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx', '.html'], alias: { - '@accountant/accounts': './accounts/index.ts', - '@accountant/operations': './operations/index.ts', - '@accountant/login': './login/index.ts', - '@accountant/scheduler': './scheduler/index.ts' + '@accountant/accounts': path.resolve( + __dirname, 'src/accounts/index.ts'), + '@accountant/operations': path.resolve( + __dirname, 'src/operations/index.ts'), + '@accountant/login': path.resolve( + __dirname, 'src/login/index.ts'), + '@accountant/scheduler': path.resolve( + __dirname, 'src/scheduler/index.ts') } }, module: { From f3c3ddfebf3381ce99d356bd01cd37d1159a03c1 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 11 Jul 2017 18:51:01 +0200 Subject: [PATCH 003/222] Bootstrap Angular app. --- package.json | 14 +++++++++++++- src/accounts/index.ts | 2 +- src/app.config.ts | 2 +- src/app.module.ts | 27 +++++++++++++++++++++++++++ src/index.ejs | 3 ++- src/login/index.ts | 2 +- src/scheduler/index.ts | 2 +- tsconfig.json | 13 +++++++++++++ webpack.config.js | 14 ++++++++++++-- 9 files changed, 71 insertions(+), 8 deletions(-) create mode 100644 src/app.module.ts create mode 100644 tsconfig.json diff --git a/package.json b/package.json index ce156e2..bac6db0 100644 --- a/package.json +++ b/package.json @@ -29,11 +29,20 @@ "less-loader": "^4.0.4", "ngtemplate-loader": "^2.0.0", "style-loader": "^0.18.2", + "ts-loader": "^2.2.2", + "typescript": "^2.4.1", "url-loader": "^0.5.8", "webpack": "^3.1.0", "webpack-dev-server": "^2.5.1" }, "dependencies": { + "@angular/common": "^4.2.6", + "@angular/compiler": "^4.2.6", + "@angular/core": "^4.2.6", + "@angular/platform-browser": "^4.2.6", + "@angular/platform-browser-dynamic": "^4.2.6", + "@angular/upgrade": "^4.2.6", + "@types/node": "^8.0.10", "angular": "^1.6", "angular-http-auth": "^1.5", "angular-messages": "^1.6", @@ -49,7 +58,10 @@ "font-awesome": "^4.7.0", "jquery": "^3.2", "meanie-angular-storage": "^1.3.1", - "moment": "^2.18" + "moment": "^2.18", + "reflect-metadata": "^0.1.10", + "rxjs": "^5.4.2", + "zone.js": "^0.8.12" }, "scripts": { "build": "webpack --config webpack.config.js", diff --git a/src/accounts/index.ts b/src/accounts/index.ts index bab9a69..b00f3ae 100644 --- a/src/accounts/index.ts +++ b/src/accounts/index.ts @@ -30,7 +30,7 @@ var AccountBalancesFactory = require('./accountBalances.factory'); var AccountConfig = require('./account.config'); var AccountController = require('./account.controller'); -module.exports = angular.module('accountant.accounts', [ +export default angular.module('accountant.accounts', [ ngResource, ngMessages, ngUiNotification, diff --git a/src/app.config.ts b/src/app.config.ts index b3400dd..9ca2867 100644 --- a/src/app.config.ts +++ b/src/app.config.ts @@ -2,7 +2,7 @@ var operationsTmpl = require('./operations/operations.html'); var accountsTmpl = require('./accounts/accounts.html'); var schedulerTmpl = require('./scheduler/scheduler.html'); -module.exports = function($routeProvider) { +export default function AppConfig($routeProvider) { // Defining template and controller in function of route. $routeProvider .when('/account/:accountId/operations', { diff --git a/src/app.module.ts b/src/app.module.ts new file mode 100644 index 0000000..d0202af --- /dev/null +++ b/src/app.module.ts @@ -0,0 +1,27 @@ +// vim: set tw=80 ts=2 sw=2 sts=2: +import 'zone.js'; +import 'reflect-metadata'; + +import './app.ts'; + +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { UpgradeModule } from '@angular/upgrade/static'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +@NgModule({ + imports: [ + BrowserModule, + UpgradeModule + ] +}) + +export class AppModule { + constructor(private upgrade: UpgradeModule) { } + + ngDoBootstrap() { + this.upgrade.bootstrap(document.body, ['accountant'], { strictDi: false }); + } +} + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/src/index.ejs b/src/index.ejs index 888c8b5..71e1d8d 100644 --- a/src/index.ejs +++ b/src/index.ejs @@ -19,13 +19,14 @@ + <% htmlWebpackPlugin.options.title %> - +
-
+
diff --git a/src/operations/balance-chart.component.ts b/src/operations/balance-chart.component.ts index 10cea1c..4c79f5e 100644 --- a/src/operations/balance-chart.component.ts +++ b/src/operations/balance-chart.component.ts @@ -35,12 +35,12 @@ module.exports = angular.module('balanceChartModule', [ account: '<', onUpdate: '&' }, - controller: function($routeParams, Balances, $element) { + controller: function($stateParams, Balances, $element) { var vm = this; vm.loadData = function() { Balances.query({ - id: $routeParams.accountId + id: $stateParams.accountId }, function(results) { var headers = [['date', 'balances', 'expenses', 'revenues']]; diff --git a/src/operations/category-chart.component.ts b/src/operations/category-chart.component.ts index 05e6413..7fc1e64 100644 --- a/src/operations/category-chart.component.ts +++ b/src/operations/category-chart.component.ts @@ -35,12 +35,12 @@ module.exports = angular.module('categoryChartModule', [ minDate: '<', maxDate: '<' }, - controller: function($routeParams, $element, Categories, Incomes) { + controller: function($stateParams, $element, Categories, Incomes) { var vm = this; vm.loadData = function() { Categories.query({ - id: $routeParams.accountId, + id: $stateParams.accountId, begin: vm.minDate ? moment(vm.minDate).format('YYYY-MM-DD') : null, end: vm.maxDate ? moment(vm.maxDate).format('YYYY-MM-DD') : null }, function(results) { diff --git a/src/operations/operation.controller.ts b/src/operations/operation.controller.ts index b8b7546..ea8dd7e 100644 --- a/src/operations/operation.controller.ts +++ b/src/operations/operation.controller.ts @@ -1,7 +1,7 @@ var operationFormTmpl = require('./operation.form.tmpl.html'), operationDeleteTmpl = require('./operation.delete.tmpl.html'); -module.exports = function($routeParams, $modal, Notification, Operation, +module.exports = function($stateParams, $modal, Notification, Operation, AccountService) { var vm = this; @@ -12,7 +12,7 @@ module.exports = function($routeParams, $modal, Notification, Operation, vm.add = function() { var operation = new Operation({ // eslint-disable-next-line camelcase - account_id: $routeParams.accountId + account_id: $stateParams.accountId }); return vm.modify(operation); @@ -27,7 +27,7 @@ module.exports = function($routeParams, $modal, Notification, Operation, return Operation.query({ // eslint-disable-next-line camelcase - account_id: $routeParams.accountId, + account_id: $stateParams.accountId, begin: minDate ? moment(minDate).format('YYYY-MM-DD') : null, end: maxDate ? moment(maxDate).format('YYYY-MM-DD') : null }); @@ -145,7 +145,7 @@ module.exports = function($routeParams, $modal, Notification, Operation, vm.operations = vm.load(minDate, maxDate); }; - AccountService.get($routeParams.accountId).subscribe(account => { + AccountService.get($stateParams.accountId).subscribe(account => { vm.account = account }); }; diff --git a/src/scheduler/schedule.controller.ts b/src/scheduler/schedule.controller.ts index 7a3663f..bb064dc 100644 --- a/src/scheduler/schedule.controller.ts +++ b/src/scheduler/schedule.controller.ts @@ -1,7 +1,7 @@ var scheduleFormTmpl = require('./schedule.form.tmpl.html'), scheduleDeleteTmpl = require('./schedule.delete.tmpl.html'); -module.exports= function($rootScope, $routeParams, Notification, ScheduledOperation, $log, $modal) { +module.exports= function($rootScope, $stateParams, Notification, ScheduledOperation, $log, $modal) { var vm = this; // Operation store. @@ -13,7 +13,7 @@ module.exports= function($rootScope, $routeParams, Notification, ScheduledOperat vm.add = function() { var operation = new ScheduledOperation({ // eslint-disable-next-line camelcase - account_id: $routeParams.accountId + account_id: $stateParams.accountId }); return vm.modify(operation); @@ -25,7 +25,7 @@ module.exports= function($rootScope, $routeParams, Notification, ScheduledOperat vm.load = function() { return ScheduledOperation.query({ // eslint-disable-next-line camelcase - account_id: $routeParams.accountId + account_id: $stateParams.accountId }); }; From 330ed6b92647d569a4abafc8aee0fef7ed6598b1 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 16 Jul 2017 14:23:23 +0200 Subject: [PATCH 029/222] Transform account state to component. --- src/accounts/index.ts | 8 +++++++- src/app.config.ts | 4 +--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/accounts/index.ts b/src/accounts/index.ts index 94a3b05..5d461a5 100644 --- a/src/accounts/index.ts +++ b/src/accounts/index.ts @@ -27,6 +27,8 @@ var ngResource = require('angular-resource'), ngUiNotification = require('angular-ui-notification'), ngStrap = require('angular-strap'); +var accountsTmpl = require('./accounts.html'); + import { AccountBalancesFactory } from './accountBalances.factory'; import { AccountService } from './account.service'; import { AccountComponent } from './account.component'; @@ -42,6 +44,10 @@ export default angular.module('accountant.accounts', [ .factory('AccountService', downgradeInjectable(AccountService)) - .controller('AccountController', AccountComponent) + .component('accountList', { + controller: AccountComponent, + controllerAs: 'accountsCtrl', + templateUrl: accountsTmpl + }) .name; diff --git a/src/app.config.ts b/src/app.config.ts index d99b853..3ce37b9 100644 --- a/src/app.config.ts +++ b/src/app.config.ts @@ -29,9 +29,7 @@ export default function AppConfig($uiRouterProvider) { $stateRegistry.register({ name: 'accounts', url: '/accounts', - templateUrl: accountsTmpl, - controller: 'AccountController', - controllerAs: 'accountsCtrl' + component: 'accountList', }); const $urlService = $uiRouterProvider.urlService; From de945cd16c514248eb9203b6cbb35e71d04a0cef Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 16 Jul 2017 17:03:37 +0200 Subject: [PATCH 030/222] Create service for AccountBalances and use it. --- src/accounts/account.component.ts | 19 ++++++++++++++++--- src/accounts/account.module.ts | 6 ++++-- src/accounts/accountBalances.service.ts | 18 ++++++++++++++++++ src/accounts/index.ts | 4 ++-- 4 files changed, 40 insertions(+), 7 deletions(-) create mode 100644 src/accounts/accountBalances.service.ts diff --git a/src/accounts/account.component.ts b/src/accounts/account.component.ts index c01cef8..841799a 100644 --- a/src/accounts/account.component.ts +++ b/src/accounts/account.component.ts @@ -4,13 +4,22 @@ var accountFormTmpl = require('./account.form.tmpl.html'), accountDeleteTmpl = require('./account.delete.tmpl.html'); import { Account } from './account'; +import { AccountBalances } from './accountBalances'; +import { AccountService } from './account.service'; +import { AccountBalancesService } from './accountBalances.service'; export class AccountComponent { - static $inject = ['AccountService', 'AccountBalances', 'Notification', '$log', '$modal']; + static $inject = ['AccountService', 'AccountBalancesService', 'Notification', '$log', '$modal']; accounts: Account[]; - constructor(private AccountService, private AccountBalances, private Notification, private $log, private $modal) { + constructor( + private AccountService: AccountService, + private AccountBalancesService: AccountBalancesService, + private Notification, + private $log, + private $modal + ) { // Load accounts. this.load(); } @@ -52,7 +61,11 @@ export class AccountComponent { load() { this.AccountService.query().subscribe(accounts => { this.accounts = accounts.map((account: Account) => { - account.balances = this.AccountBalances.get({id: account.id}); + this.AccountBalancesService + .get(account.id) + .subscribe((accountBalances: AccountBalances) => { + account.balances = accountBalances; + }) return account; }) }); diff --git a/src/accounts/account.module.ts b/src/accounts/account.module.ts index a684b94..ee89a7c 100644 --- a/src/accounts/account.module.ts +++ b/src/accounts/account.module.ts @@ -7,6 +7,7 @@ import { NgLoggerModule, Level } from '@nsalaun/ng-logger'; import { RestangularModule } from 'ngx-restangular'; import { AccountService } from './account.service'; +import { AccountBalancesService } from './accountBalances.service'; @NgModule({ imports: [ @@ -15,8 +16,9 @@ import { AccountService } from './account.service'; RestangularModule ], providers: [ - AccountService - ] + AccountService, + AccountBalancesService, + ], }) export class AccountModule {} diff --git a/src/accounts/accountBalances.service.ts b/src/accounts/accountBalances.service.ts new file mode 100644 index 0000000..77b99fa --- /dev/null +++ b/src/accounts/accountBalances.service.ts @@ -0,0 +1,18 @@ +// vim: set tw=80 ts=2 sw=2 sts=2 : +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs/Rx'; + +import { Restangular } from "ngx-restangular"; + +import { AccountBalances } from './accountBalances'; + +@Injectable() +export class AccountBalancesService { + constructor( + private restangular: Restangular + ) {} + + get(id: number): Observable { + return this.restangular.one('account', id).one('balances').get(); + } +} diff --git a/src/accounts/index.ts b/src/accounts/index.ts index 5d461a5..e4a3e6f 100644 --- a/src/accounts/index.ts +++ b/src/accounts/index.ts @@ -29,7 +29,7 @@ var ngResource = require('angular-resource'), var accountsTmpl = require('./accounts.html'); -import { AccountBalancesFactory } from './accountBalances.factory'; +import { AccountBalancesService } from './accountBalances.service'; import { AccountService } from './account.service'; import { AccountComponent } from './account.component'; @@ -40,7 +40,7 @@ export default angular.module('accountant.accounts', [ ngStrap, ]) - .factory('AccountBalances', AccountBalancesFactory) + .factory('AccountBalancesService', downgradeInjectable(AccountBalancesService)) .factory('AccountService', downgradeInjectable(AccountService)) From 3e6b1ecccccdf9290f71a13969adb3e22e21c909 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 16 Jul 2017 22:25:50 +0200 Subject: [PATCH 031/222] Use new Logger in account module. --- src/accounts/account.component.ts | 11 +++++++---- src/accounts/index.ts | 4 ++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/accounts/account.component.ts b/src/accounts/account.component.ts index 841799a..027af1b 100644 --- a/src/accounts/account.component.ts +++ b/src/accounts/account.component.ts @@ -1,5 +1,7 @@ import { Observable } from 'rxjs/Rx'; +import { Logger } from '@nsalaun/ng-logger'; + var accountFormTmpl = require('./account.form.tmpl.html'), accountDeleteTmpl = require('./account.delete.tmpl.html'); @@ -9,7 +11,7 @@ import { AccountService } from './account.service'; import { AccountBalancesService } from './accountBalances.service'; export class AccountComponent { - static $inject = ['AccountService', 'AccountBalancesService', 'Notification', '$log', '$modal']; + static $inject = ['AccountService', 'AccountBalancesService', 'Notification', 'Logger', '$modal']; accounts: Account[]; @@ -17,7 +19,7 @@ export class AccountComponent { private AccountService: AccountService, private AccountBalancesService: AccountBalancesService, private Notification, - private $log, + private Logger: Logger, private $modal ) { // Load accounts. @@ -61,6 +63,7 @@ export class AccountComponent { load() { this.AccountService.query().subscribe(accounts => { this.accounts = accounts.map((account: Account) => { + this.Logger.log(account); this.AccountBalancesService .get(account.id) .subscribe((accountBalances: AccountBalances) => { @@ -95,7 +98,7 @@ export class AccountComponent { this.load(); }, result => { - this.$log.error('Error while saving account', account, result); + this.Logger.error('Error while saving account', account, result); this.Notification.error( 'Error while saving account: ' + result.message @@ -157,7 +160,7 @@ export class AccountComponent { this.$modal({ templateUrl: accountFormTmpl, - controller: function($log, $scope, title, account, $save) { + controller: function($scope, title, account, $save) { $scope.title = title; $scope.account = account; $scope.account.authorized_overdraft *= -1; diff --git a/src/accounts/index.ts b/src/accounts/index.ts index e4a3e6f..42c9069 100644 --- a/src/accounts/index.ts +++ b/src/accounts/index.ts @@ -27,6 +27,8 @@ var ngResource = require('angular-resource'), ngUiNotification = require('angular-ui-notification'), ngStrap = require('angular-strap'); +import { Logger } from '@nsalaun/ng-logger'; + var accountsTmpl = require('./accounts.html'); import { AccountBalancesService } from './accountBalances.service'; @@ -40,6 +42,8 @@ export default angular.module('accountant.accounts', [ ngStrap, ]) + .factory('Logger', downgradeInjectable(Logger)) + .factory('AccountBalancesService', downgradeInjectable(AccountBalancesService)) .factory('AccountService', downgradeInjectable(AccountService)) From 4057705e224de01fac892b57734129ab4fb2b03c Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Thu, 20 Jul 2017 10:32:05 +0200 Subject: [PATCH 032/222] Use ng-bootstrap Modal. --- src/accounts/account.component.ts | 63 ++++--------- src/accounts/account.delete.tmpl.html | 23 ----- src/accounts/account.form.tmpl.html | 72 --------------- src/accounts/account.module.ts | 18 +++- src/accounts/accountDeleteModal.component.ts | 53 +++++++++++ src/accounts/accountEditModal.component.ts | 96 ++++++++++++++++++++ src/accounts/index.ts | 3 + 7 files changed, 188 insertions(+), 140 deletions(-) delete mode 100644 src/accounts/account.delete.tmpl.html delete mode 100644 src/accounts/account.form.tmpl.html create mode 100644 src/accounts/accountDeleteModal.component.ts create mode 100644 src/accounts/accountEditModal.component.ts diff --git a/src/accounts/account.component.ts b/src/accounts/account.component.ts index 027af1b..cdcf98e 100644 --- a/src/accounts/account.component.ts +++ b/src/accounts/account.component.ts @@ -1,17 +1,16 @@ import { Observable } from 'rxjs/Rx'; import { Logger } from '@nsalaun/ng-logger'; - -var accountFormTmpl = require('./account.form.tmpl.html'), - accountDeleteTmpl = require('./account.delete.tmpl.html'); +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { Account } from './account'; import { AccountBalances } from './accountBalances'; import { AccountService } from './account.service'; import { AccountBalancesService } from './accountBalances.service'; - +import { AccountDeleteModalComponent } from './accountDeleteModal.component'; +import { AccountEditModalComponent } from './accountEditModal.component'; export class AccountComponent { - static $inject = ['AccountService', 'AccountBalancesService', 'Notification', 'Logger', '$modal']; + static $inject = ['AccountService', 'AccountBalancesService', 'Notification', 'Logger', 'NgbModal']; accounts: Account[]; @@ -20,7 +19,7 @@ export class AccountComponent { private AccountBalancesService: AccountBalancesService, private Notification, private Logger: Logger, - private $modal + private NgbModal: NgbModal ) { // Load accounts. this.load(); @@ -107,23 +106,14 @@ export class AccountComponent { }; confirmDelete(account) { - var title = "Delete account #" + account.id; + const modal = this.NgbModal.open(AccountDeleteModalComponent, { + windowClass: 'in' + }); - this.$modal({ - templateUrl: accountDeleteTmpl, - controller: function($scope, title, account, $delete) { - $scope.title = title; - $scope.account = account; - $scope.$delete = function() { - $scope.$hide(); - $delete($scope.account); - }; - }, - locals: { - title: title, - account: account, - $delete: (account: Account) => { this.delete(account); } - } + modal.componentInstance.account = account; + + modal.result.then((account: Account) => { + this.delete(account); }); }; @@ -151,30 +141,15 @@ export class AccountComponent { * Open the popup to modify the account, save it on confirm. */ modify(account) { - // FIXME Alexis Lahouze 2017-06-15 i18n - var title = "Account"; + const modal = this.NgbModal.open(AccountEditModalComponent, { + windowClass: 'in' + }); - if (account.id) { - title = title + " #" + account.id; - } + modal.componentInstance.account = account; - this.$modal({ - templateUrl: accountFormTmpl, - controller: function($scope, title, account, $save) { - $scope.title = title; - $scope.account = account; - $scope.account.authorized_overdraft *= -1; - $scope.$save = function() { - $scope.$hide(); - $scope.account.authorized_overdraft *= -1; - $save($scope.account); - }; - }, - locals: { - title: title, - account: account, - $save: (account: Account) => { this.save(account); } - } + modal.result.then((account: Account) => { + this.Logger.log("Modal closed => save account", account); + this.save(account); }); }; }; diff --git a/src/accounts/account.delete.tmpl.html b/src/accounts/account.delete.tmpl.html deleted file mode 100644 index b1f4bb5..0000000 --- a/src/accounts/account.delete.tmpl.html +++ /dev/null @@ -1,23 +0,0 @@ - diff --git a/src/accounts/account.form.tmpl.html b/src/accounts/account.form.tmpl.html deleted file mode 100644 index 9963fd1..0000000 --- a/src/accounts/account.form.tmpl.html +++ /dev/null @@ -1,72 +0,0 @@ - - - diff --git a/src/accounts/account.module.ts b/src/accounts/account.module.ts index ee89a7c..439acfb 100644 --- a/src/accounts/account.module.ts +++ b/src/accounts/account.module.ts @@ -1,24 +1,40 @@ // vim: set tw=80 ts=2 sw=2 sts=2 : import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http'; import { NgLoggerModule, Level } from '@nsalaun/ng-logger'; import { RestangularModule } from 'ngx-restangular'; +import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { AccountService } from './account.service'; import { AccountBalancesService } from './accountBalances.service'; +import { AccountDeleteModalComponent } from './accountDeleteModal.component'; +import { AccountEditModalComponent } from './accountEditModal.component'; @NgModule({ imports: [ HttpModule, + CommonModule, + FormsModule, NgLoggerModule, - RestangularModule + RestangularModule, + NgbModule ], providers: [ AccountService, AccountBalancesService, ], + declarations: [ + AccountDeleteModalComponent, + AccountEditModalComponent + ], + entryComponents: [ + AccountDeleteModalComponent, + AccountEditModalComponent + ] }) export class AccountModule {} diff --git a/src/accounts/accountDeleteModal.component.ts b/src/accounts/accountDeleteModal.component.ts new file mode 100644 index 0000000..0f375fa --- /dev/null +++ b/src/accounts/accountDeleteModal.component.ts @@ -0,0 +1,53 @@ +// vim: set tw=80 ts=2 sw=2 sts=2: +import { Component, Input } from '@angular/core'; + +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; + +import { Account } from './account'; + +@Component({ + selector: 'account-delete-modal', + template: ` + + + + + + ` +}) +export class AccountDeleteModalComponent { + @Input() account: Account + + constructor(public activeModal: NgbActiveModal) {} + + title(): string { + if(this.account.id) { + return "Account #" + this.account.id; + } else { + return "New account"; + } + } + + submit(): void { + this.activeModal.close(this.account); + } + + cancel(): void { + this.activeModal.dismiss("closed"); + } +} diff --git a/src/accounts/accountEditModal.component.ts b/src/accounts/accountEditModal.component.ts new file mode 100644 index 0000000..4de215a --- /dev/null +++ b/src/accounts/accountEditModal.component.ts @@ -0,0 +1,96 @@ +// vim: set tw=80 ts=2 sw=2 sts=2: +import { Component, Input } from '@angular/core'; + +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; + +import { Account } from './account'; + +@Component({ + selector: 'account-edit-modal', + template: ` + + + + + + ` +}) +export class AccountEditModalComponent { + @Input() account: Account + + constructor(public activeModal: NgbActiveModal) {} + + title(): string { + if(this.account.id) { + return "Account #" + this.account.id; + } else { + return "New account"; + } + } + + submit(): void { + this.activeModal.close(this.account); + } + + cancel(): void { + this.activeModal.dismiss("closed"); + } +} diff --git a/src/accounts/index.ts b/src/accounts/index.ts index 42c9069..73545f8 100644 --- a/src/accounts/index.ts +++ b/src/accounts/index.ts @@ -28,6 +28,7 @@ var ngResource = require('angular-resource'), ngStrap = require('angular-strap'); import { Logger } from '@nsalaun/ng-logger'; +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; var accountsTmpl = require('./accounts.html'); @@ -44,6 +45,8 @@ export default angular.module('accountant.accounts', [ .factory('Logger', downgradeInjectable(Logger)) + .factory('NgbModal', downgradeInjectable(NgbModal)) + .factory('AccountBalancesService', downgradeInjectable(AccountBalancesService)) .factory('AccountService', downgradeInjectable(AccountService)) From adfd61fac905cdb1921a50baecdcbc05c59e3eee Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Thu, 20 Jul 2017 22:31:58 +0200 Subject: [PATCH 033/222] Add missing dependencies for NgbModal. --- package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package.json b/package.json index 2bbec67..b04d97d 100644 --- a/package.json +++ b/package.json @@ -36,13 +36,16 @@ "webpack-dev-server": "^2.4.5" }, "dependencies": { + "@angular/animations": "^4.3.0", "@angular/common": "^4.2.6", "@angular/compiler": "^4.2.6", "@angular/core": "^4.2.6", + "@angular/forms": "^4.3.0", "@angular/http": "^4.2.6", "@angular/platform-browser": "^4.2.6", "@angular/platform-browser-dynamic": "^4.2.6", "@angular/upgrade": "^4.2.6", + "@ng-bootstrap/ng-bootstrap": "^1.0.0-alpha.28", "@nsalaun/ng-logger": "^2.0.1", "@types/angular": "^1.6.25", "@types/node": "^8.0.10", From 60aa6310bb9de096f5ddfe578d366277a531b209 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Thu, 20 Jul 2017 22:52:33 +0200 Subject: [PATCH 034/222] Separate account form from modal. --- src/accounts/account.module.ts | 7 ++- src/accounts/accountEditModal.component.ts | 55 ++--------------- src/accounts/accountForm.component.ts | 72 ++++++++++++++++++++++ 3 files changed, 83 insertions(+), 51 deletions(-) create mode 100644 src/accounts/accountForm.component.ts diff --git a/src/accounts/account.module.ts b/src/accounts/account.module.ts index 439acfb..a818c64 100644 --- a/src/accounts/account.module.ts +++ b/src/accounts/account.module.ts @@ -13,6 +13,7 @@ import { AccountService } from './account.service'; import { AccountBalancesService } from './accountBalances.service'; import { AccountDeleteModalComponent } from './accountDeleteModal.component'; import { AccountEditModalComponent } from './accountEditModal.component'; +import { AccountFormComponent } from './accountForm.component'; @NgModule({ imports: [ @@ -29,11 +30,13 @@ import { AccountEditModalComponent } from './accountEditModal.component'; ], declarations: [ AccountDeleteModalComponent, - AccountEditModalComponent + AccountEditModalComponent, + AccountFormComponent ], entryComponents: [ AccountDeleteModalComponent, - AccountEditModalComponent + AccountEditModalComponent, + AccountFormComponent ] }) export class AccountModule {} diff --git a/src/accounts/accountEditModal.component.ts b/src/accounts/accountEditModal.component.ts index 4de215a..e2a2c92 100644 --- a/src/accounts/accountEditModal.component.ts +++ b/src/accounts/accountEditModal.component.ts @@ -1,5 +1,6 @@ // vim: set tw=80 ts=2 sw=2 sts=2: import { Component, Input } from '@angular/core'; +import { NgForm } from '@angular/forms'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; @@ -13,57 +14,11 @@ import { Account } from './account'; From b95f36f09c6bc97ca311f4e603057401537f350c Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Fri, 21 Jul 2017 00:06:07 +0200 Subject: [PATCH 039/222] Change field parent bind. --- src/accounts/accountEditModal.component.ts | 6 +++--- src/accounts/accountForm.component.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/accounts/accountEditModal.component.ts b/src/accounts/accountEditModal.component.ts index e2a2c92..2ccc961 100644 --- a/src/accounts/accountEditModal.component.ts +++ b/src/accounts/accountEditModal.component.ts @@ -14,11 +14,11 @@ import { Account } from './account'; `, }) -export class AccountListComponent { - static $inject = [ - 'AccountService', - 'AccountBalancesService', - 'ToastrService', - 'Logger', - 'NgbModal' - ]; - +export class AccountListComponent implements OnInit { accounts: Account[]; constructor( private AccountService: AccountService, - private AccountBalancesService: AccountBalancesService, private ToastrService: ToastrService, private Logger: Logger, private NgbModal: NgbModal ) { + } + + ngOnInit() { // Load accounts. this.load(); } - /* - * Return the class for an account current value compared to authorized - * overdraft. - */ - rowClass(account) { - // eslint-disable-next-line camelcase - if (!account || !account.authorized_overdraft || !account.current) { - return; - } - - // eslint-disable-next-line camelcase - if (account.current < account.authorized_overdraft) { - return 'danger'; - } else if (account.current < 0) { - return 'warning'; - } - }; - - /* - * Return the class for a value compared to account authorized overdraft. - */ - valueClass(account, value) { - if (!account || !value) { - return; - } - - // eslint-disable-next-line camelcase - if (value < account.authorized_overdraft) { - return 'text-danger'; - } else if (value < 0) { - return 'text-warning'; - } - }; - load() { this.AccountService.query().subscribe(accounts => { - this.accounts = accounts.map((account: Account) => { - this.Logger.log(account); - this.AccountBalancesService - .get(account.id) - .subscribe((accountBalances: AccountBalances) => { - account.balances = accountBalances; - }) - return account; - }) + this.accounts = accounts; }); }; @@ -178,15 +86,7 @@ export class AccountListComponent { * Save account. */ save(account) { - var observable: Observable; - - if(account.id) { - observable = this.AccountService.update(account); - } else { - observable = this.AccountService.create(account); - } - - observable.subscribe(account => { + this.AccountService.create(account).subscribe(account => { this.ToastrService.success('Account #' + account.id + ' saved.'); this.load(); @@ -198,54 +98,4 @@ export class AccountListComponent { ); }); }; - - confirmDelete(account) { - const modal = this.NgbModal.open(AccountDeleteModalComponent, { - windowClass: 'in' - }); - - modal.componentInstance.account = account; - - modal.result.then((account: Account) => { - this.delete(account); - }, (reason) => function(reason) { - }); - }; - - /* - * Delete an account. - */ - delete(account) { - var id = account.id; - - this.AccountService.delete(account).subscribe(account => { - this.ToastrService.success('account #' + id + ' deleted.'); - - this.load(); - - return account; - }, function(result) { - this.ToastrService.error( - 'An error occurred while trying to delete account #' + - id + ':
' + result - ); - }); - }; - - /* - * Open the popup to modify the account, save it on confirm. - */ - modify(account) { - const modal = this.NgbModal.open(AccountEditModalComponent, { - windowClass: 'in' - }); - - modal.componentInstance.account = account; - - modal.result.then((account: Account) => { - this.Logger.log("Modal closed => save account", account); - this.save(account); - }, (reason) => function(reason) { - }); - }; }; diff --git a/src/accounts/accountRow.component.ts b/src/accounts/accountRow.component.ts new file mode 100644 index 0000000..7c42bf8 --- /dev/null +++ b/src/accounts/accountRow.component.ts @@ -0,0 +1,176 @@ +// vim: set tw=80 ts=2 sw=2 sts=2 : +import { CurrencyPipe } from '@angular/common'; +import { Component, Inject, Input, Output, EventEmitter, OnInit } from '@angular/core'; + +import { Logger } from '@nsalaun/ng-logger'; +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { ToastrService } from 'ngx-toastr'; + +import { Account } from './account'; +import { AccountBalances } from './accountBalances'; +import { AccountBalancesService } from './accountBalances.service'; +import { AccountService } from './account.service'; +import { AccountDeleteModalComponent } from './accountDeleteModal.component'; +import { AccountEditModalComponent } from './accountEditModal.component'; + +@Component({ + selector: 'tr[account-row]', + host: { + "[id]": "account.id", + "[class.warning]": "warning", + "[class.danger]": "danger" + }, + template: ` + + {{ account.name }} + + + + + {{ accountBalances?.current | currency:"EUR" }} + + + + + + {{ accountBalances?.pointed | currency:"EUR" }} + + + +{{ account.authorized_overdraft | currency:"EUR" }} + + +
+ + + + + + + + + + +
+ + ` +}) +export class AccountRowComponent implements OnInit { + @Input('account-row') account: Account; + @Output() needsReload: EventEmitter = new EventEmitter(); + + accountBalances: AccountBalances; + + constructor( + private accountService: AccountService, + private accountBalancesService: AccountBalancesService, + private toastrService: ToastrService, + private logger: Logger, + private modal: NgbModal + ) { + this.logger.log("AccountRowComponent constructor"); + } + + ngOnInit() { + this.logger.log(this.account); + this.accountBalancesService + .get(this.account.id) + .subscribe((accountBalances: AccountBalances) => { + this.accountBalances = accountBalances; + }) + } + + get warning() { + return this.account.authorized_overdraft < this.accountBalances.current + && this.accountBalances.current < 0; + }; + + get error() { + return this.accountBalances.current < this.account.authorized_overdraft; + }; + + /* + * Return the class for a value compared to account authorized overdraft. + */ + valueClass(value: number) { + if (!value) { + return; + } + + if (value < this.account.authorized_overdraft) { + return 'text-danger'; + } else if (value < 0) { + return 'text-warning'; + } + }; + + confirmDelete() { + const modal = this.modal.open(AccountDeleteModalComponent, { + windowClass: 'in' + }); + + modal.componentInstance.account = this.account; + + modal.result.then((account: Account) => { + this.delete(account); + }, (reason) => function(reason) { + }); + }; + + /* + * Delete an account. + */ + delete(account: Account) { + var id = account.id; + + this.accountService.delete(account).subscribe(account => { + this.toastrService.success('account #' + id + ' deleted.'); + + this.needsReload.emit(); + }, function(result) { + this.toastrService.error( + 'An error occurred while trying to delete account #' + + id + ':
' + result + ); + }); + }; + + /* + * Open the popup to modify the account, save it on confirm. + */ + modify() { + const modal = this.modal.open(AccountEditModalComponent, { + windowClass: 'in' + }); + + modal.componentInstance.account = this.account; + + modal.result.then((account: Account) => { + this.logger.log("Modal closed => save account", account); + this.save(account); + }, (reason) => function(reason) { + }); + }; + + save(account: Account) { + this.accountService.update(account).subscribe((account: Account) => { + this.toastrService.success('Account #' + account.id + ' saved.'); + + this.needsReload.emit(); + }, result => { + this.logger.error('Error while saving account', account, result); + + this.toastrService.error( + 'Error while saving account: ' + result.message + ); + }); + }; +} From cc5b0b1ee1b7680eb1f1dd6a263d8edfbcc32c27 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Fri, 21 Jul 2017 22:42:16 +0200 Subject: [PATCH 053/222] Fix condition. --- src/accounts/accountRow.component.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/accounts/accountRow.component.ts b/src/accounts/accountRow.component.ts index 7c42bf8..64a7dcc 100644 --- a/src/accounts/accountRow.component.ts +++ b/src/accounts/accountRow.component.ts @@ -89,12 +89,14 @@ export class AccountRowComponent implements OnInit { } get warning() { - return this.account.authorized_overdraft < this.accountBalances.current + return this.account && this.accountBalances + && this.account.authorized_overdraft < this.accountBalances.current && this.accountBalances.current < 0; }; get error() { - return this.accountBalances.current < this.account.authorized_overdraft; + return this.account && this.accountBalances + && this.accountBalances.current < this.account.authorized_overdraft; }; /* From a398752c0c8e3414ebdd1a319ba73742173e2623 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Fri, 21 Jul 2017 23:06:10 +0200 Subject: [PATCH 054/222] Fix export and import. --- src/scheduler/index.ts | 2 +- src/scheduler/schedule.factory.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/scheduler/index.ts b/src/scheduler/index.ts index a2fb9b3..a351aef 100644 --- a/src/scheduler/index.ts +++ b/src/scheduler/index.ts @@ -25,7 +25,7 @@ var ngMessages = require('angular-messages'), ngStrap = require('angular-strap'); var ScheduleController = require('./schedule.controller'); -var ScheduleFactory = require('./schedule.factory'); +import { ScheduleFactory } from './schedule.factory'; export default angular.module('accountant.scheduler', [ ngMessages, diff --git a/src/scheduler/schedule.factory.ts b/src/scheduler/schedule.factory.ts index aa00231..6e0be2b 100644 --- a/src/scheduler/schedule.factory.ts +++ b/src/scheduler/schedule.factory.ts @@ -1,4 +1,4 @@ -module.exports = function($resource) { +export function ScheduleFactory($resource) { return $resource( '/api/scheduled_operation/:id', { id: '@id' From 8626c7870854f632c0f74c78a54c25ba16847b11 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Fri, 21 Jul 2017 23:06:59 +0200 Subject: [PATCH 055/222] Transform controller function to class. --- src/scheduler/index.ts | 2 +- src/scheduler/schedule.controller.ts | 66 ++++++++++++++++------------ 2 files changed, 38 insertions(+), 30 deletions(-) diff --git a/src/scheduler/index.ts b/src/scheduler/index.ts index a351aef..f70731d 100644 --- a/src/scheduler/index.ts +++ b/src/scheduler/index.ts @@ -24,7 +24,7 @@ var ngMessages = require('angular-messages'), ngUiNotification = require('angular-ui-notification'), ngStrap = require('angular-strap'); -var ScheduleController = require('./schedule.controller'); +import { ScheduleController } from './schedule.controller'; import { ScheduleFactory } from './schedule.factory'; export default angular.module('accountant.scheduler', [ diff --git a/src/scheduler/schedule.controller.ts b/src/scheduler/schedule.controller.ts index bb064dc..180b2c0 100644 --- a/src/scheduler/schedule.controller.ts +++ b/src/scheduler/schedule.controller.ts @@ -1,48 +1,59 @@ var scheduleFormTmpl = require('./schedule.form.tmpl.html'), scheduleDeleteTmpl = require('./schedule.delete.tmpl.html'); -module.exports= function($rootScope, $stateParams, Notification, ScheduledOperation, $log, $modal) { - var vm = this; +export class ScheduleController{ + $inject=['$rootScope', '$stateParams', 'Notification', 'ScheduledOperation', '$log', '$modal'] - // Operation store. - vm.operations = []; + operations = []; + + constructor( + private $rootScope, + private $stateParams, + private Notification, + private ScheduledOperation, + private $log, + private $modal + ) { + // Load operations on controller initialization. + this.operations = this.load(); + } /* * Add a new operation at the beginning of th array. */ - vm.add = function() { - var operation = new ScheduledOperation({ + add = function() { + var operation = new this.ScheduledOperation({ // eslint-disable-next-line camelcase - account_id: $stateParams.accountId + account_id: this.$stateParams.accountId }); - return vm.modify(operation); + return this.modify(operation); }; /* * Load operations. */ - vm.load = function() { - return ScheduledOperation.query({ + load = function() { + return this.ScheduledOperation.query({ // eslint-disable-next-line camelcase - account_id: $stateParams.accountId + account_id: this.$stateParams.accountId }); }; /* * Save operation. */ - vm.save = function(operation) { + save = function(operation) { return operation.$save().then(function(operation) { - Notification.success('Scheduled operation #' + operation.id + ' saved.'); + this.Notification.success('Scheduled operation #' + operation.id + ' saved.'); - vm.operations = vm.load(); + this.operations = this.load(); return operation; }, function(result){ - $log.error('Error while saving scheduled operation', operation, result); + this.$log.error('Error while saving scheduled operation', operation, result); - Notification.error( + this.Notification.error( 'Error while saving scheduled operation: ' + result.message ); }); @@ -51,10 +62,10 @@ module.exports= function($rootScope, $stateParams, Notification, ScheduledOperat /* * Delete an operation and return a promise. */ - vm.confirmDelete = function(operation) { + confirmDelete = function(operation) { var title = "Delete operation #" + operation.id; - $modal({ + this.$modal({ templateUrl: scheduleDeleteTmpl, controller: function($scope, title, operation, $delete) { $scope.title = title; @@ -67,7 +78,7 @@ module.exports= function($rootScope, $stateParams, Notification, ScheduledOperat locals: { title: title, operation: operation, - $delete: vm.delete + $delete: this.delete } }); }; @@ -75,17 +86,17 @@ module.exports= function($rootScope, $stateParams, Notification, ScheduledOperat /* * Delete operation. */ - vm.delete = function(operation) { + delete = function(operation) { var id = operation.id; return operation.$delete().then(function() { - Notification.success('Scheduled operation #' + id + ' deleted.'); + this.Notification.success('Scheduled operation #' + id + ' deleted.'); - vm.operations = vm.load(); + this.operations = this.load(); return operation; }, function(result) { - Notification.error( + this.Notification.error( 'An error occurred while trying to delete scheduled operation #' + id + ':
' + result ); @@ -96,7 +107,7 @@ module.exports= function($rootScope, $stateParams, Notification, ScheduledOperat * Open the popup to modify the operation, save it on confirm. * @returns a promise. */ - vm.modify = function(operation) { + modify = function(operation) { // FIXME Alexis Lahouze 2017-06-15 i18n var title = "Operation"; @@ -104,7 +115,7 @@ module.exports= function($rootScope, $stateParams, Notification, ScheduledOperat title = title + " #" + operation.id; } - $modal({ + this.$modal({ templateUrl: scheduleFormTmpl, controller: function($scope, title, operation, $save) { $scope.title = title; @@ -117,11 +128,8 @@ module.exports= function($rootScope, $stateParams, Notification, ScheduledOperat locals: { title: title, operation: operation, - $save: vm.save + $save: this.save } }); }; - - // Load operations on controller initialization. - vm.operations = vm.load(); }; From fc0c08d58e86cff395da70ebfdda96f4ceb411df Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Fri, 21 Jul 2017 23:07:20 +0200 Subject: [PATCH 056/222] Fix currency. --- src/accounts/accountRow.component.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/accounts/accountRow.component.ts b/src/accounts/accountRow.component.ts index 64a7dcc..cd80ccb 100644 --- a/src/accounts/accountRow.component.ts +++ b/src/accounts/accountRow.component.ts @@ -27,17 +27,17 @@ import { AccountEditModalComponent } from './accountEditModal.component'; - {{ accountBalances?.current | currency:"EUR" }} + {{ accountBalances?.current | currency:"EUR":true }} - {{ accountBalances?.pointed | currency:"EUR" }} + {{ accountBalances?.pointed | currency:"EUR":true }} -{{ account.authorized_overdraft | currency:"EUR" }} +{{ account.authorized_overdraft | currency:"EUR":true }}
From f9c2e7f4bc10230fa51f52d554a57335a5372228 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Fri, 21 Jul 2017 23:11:04 +0200 Subject: [PATCH 057/222] Cleanup imports. --- src/scheduler/schedule.controller.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/scheduler/schedule.controller.ts b/src/scheduler/schedule.controller.ts index 180b2c0..5f53ba5 100644 --- a/src/scheduler/schedule.controller.ts +++ b/src/scheduler/schedule.controller.ts @@ -2,16 +2,14 @@ var scheduleFormTmpl = require('./schedule.form.tmpl.html'), scheduleDeleteTmpl = require('./schedule.delete.tmpl.html'); export class ScheduleController{ - $inject=['$rootScope', '$stateParams', 'Notification', 'ScheduledOperation', '$log', '$modal'] + $inject=['$stateParams', 'Notification', 'ScheduledOperation', '$modal'] operations = []; constructor( - private $rootScope, private $stateParams, private Notification, private ScheduledOperation, - private $log, private $modal ) { // Load operations on controller initialization. @@ -51,8 +49,6 @@ export class ScheduleController{ return operation; }, function(result){ - this.$log.error('Error while saving scheduled operation', operation, result); - this.Notification.error( 'Error while saving scheduled operation: ' + result.message ); From adec1f102e97afb1f43e9bfa50e206bf6e89d3d7 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 22 Jul 2017 08:42:17 +0200 Subject: [PATCH 058/222] Rename dependencies. --- src/accounts/accountList.component.ts | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/accounts/accountList.component.ts b/src/accounts/accountList.component.ts index 6543a58..622fed5 100644 --- a/src/accounts/accountList.component.ts +++ b/src/accounts/accountList.component.ts @@ -47,10 +47,10 @@ export class AccountListComponent implements OnInit { accounts: Account[]; constructor( - private AccountService: AccountService, - private ToastrService: ToastrService, - private Logger: Logger, - private NgbModal: NgbModal + private accountService: AccountService, + private toastrService: ToastrService, + private logger: Logger, + private ngbModal: NgbModal ) { } @@ -60,7 +60,8 @@ export class AccountListComponent implements OnInit { } load() { - this.AccountService.query().subscribe(accounts => { + this.logger.log("Load accounts."); + this.accountService.query().subscribe(accounts => { this.accounts = accounts; }); }; @@ -69,14 +70,14 @@ export class AccountListComponent implements OnInit { * Add an empty account. */ add() { - const modal = this.NgbModal.open(AccountEditModalComponent, { + const modal = this.ngbModal.open(AccountEditModalComponent, { windowClass: 'in' }); modal.componentInstance.account = new Account(); modal.result.then((account: Account) => { - this.Logger.log("Modal closed => save account", account); + this.logger.log("Modal closed => save account", account); this.save(account); }, (reason) => function(reason) { }); @@ -86,14 +87,14 @@ export class AccountListComponent implements OnInit { * Save account. */ save(account) { - this.AccountService.create(account).subscribe(account => { - this.ToastrService.success('Account #' + account.id + ' saved.'); + this.accountService.create(account).subscribe(account => { + this.toastrService.success('Account #' + account.id + ' saved.'); this.load(); }, result => { - this.Logger.error('Error while saving account', account, result); + this.logger.error('Error while saving account', account, result); - this.ToastrService.error( + this.toastrService.error( 'Error while saving account: ' + result.message ); }); From aa07ffb12562dc73347fcbb048fb605471d82115 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 22 Jul 2017 08:44:54 +0200 Subject: [PATCH 059/222] Remove unused factory. --- src/accounts/accountBalances.factory.ts | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 src/accounts/accountBalances.factory.ts diff --git a/src/accounts/accountBalances.factory.ts b/src/accounts/accountBalances.factory.ts deleted file mode 100644 index 24e6606..0000000 --- a/src/accounts/accountBalances.factory.ts +++ /dev/null @@ -1,8 +0,0 @@ -// vim: set tw=80 ts=2 sw=2 sts=2 : -export function AccountBalancesFactory($resource) { - return $resource( - '/api/account/:id/balances', { - id: '@id' - } - ); -}; From 68df4e5ce2fce9acd8f25aab2e0274a3c7671538 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 22 Jul 2017 09:16:16 +0200 Subject: [PATCH 060/222] Prepare scheduler module for angular2 upgrade. --- src/scheduler/index.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/scheduler/index.ts b/src/scheduler/index.ts index f70731d..66b30b4 100644 --- a/src/scheduler/index.ts +++ b/src/scheduler/index.ts @@ -20,6 +20,15 @@ var angular = require('angular'); +import { + downgradeInjectable, + downgradeComponent +} from '@angular/upgrade/static'; + +import { Logger } from '@nsalaun/ng-logger'; +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { ToastrService } from 'ngx-toastr'; + var ngMessages = require('angular-messages'), ngUiNotification = require('angular-ui-notification'), ngStrap = require('angular-strap'); @@ -32,6 +41,11 @@ export default angular.module('accountant.scheduler', [ ngUiNotification, ngStrap ]) + .factory('toastrService', downgradeInjectable(ToastrService)) + + .factory('ngbModal', downgradeInjectable(NgbModal)) + + .factory('logger', downgradeInjectable(Logger)) .factory('ScheduledOperation', ScheduleFactory) From 801d2ae380816cfa5512f4bd1b66988c3578b530 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 22 Jul 2017 09:17:50 +0200 Subject: [PATCH 061/222] Migrate to toastr. --- src/scheduler/schedule.controller.ts | 34 +++++++++++++++++----------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src/scheduler/schedule.controller.ts b/src/scheduler/schedule.controller.ts index 5f53ba5..97f67a6 100644 --- a/src/scheduler/schedule.controller.ts +++ b/src/scheduler/schedule.controller.ts @@ -1,3 +1,7 @@ +import { Logger } from '@nsalaun/ng-logger'; +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { ToastrService } from 'ngx-toastr'; + var scheduleFormTmpl = require('./schedule.form.tmpl.html'), scheduleDeleteTmpl = require('./schedule.delete.tmpl.html'); @@ -8,7 +12,7 @@ export class ScheduleController{ constructor( private $stateParams, - private Notification, + private toastrService: ToastrService, private ScheduledOperation, private $modal ) { @@ -42,14 +46,14 @@ export class ScheduleController{ * Save operation. */ save = function(operation) { - return operation.$save().then(function(operation) { - this.Notification.success('Scheduled operation #' + operation.id + ' saved.'); + return operation.$save().then((operation) => { + this.toastrService.success('Scheduled operation #' + operation.id + ' saved.'); this.operations = this.load(); return operation; - }, function(result){ - this.Notification.error( + }, (result) => { + this.toastrService.error( 'Error while saving scheduled operation: ' + result.message ); }); @@ -66,7 +70,7 @@ export class ScheduleController{ controller: function($scope, title, operation, $delete) { $scope.title = title; $scope.operation = operation; - $scope.$delete = function() { + $scope.$delete = () => { $scope.$hide(); $delete($scope.operation); }; @@ -74,7 +78,9 @@ export class ScheduleController{ locals: { title: title, operation: operation, - $delete: this.delete + $delete: (operation) => { + this.delete(operation); + } } }); }; @@ -85,14 +91,14 @@ export class ScheduleController{ delete = function(operation) { var id = operation.id; - return operation.$delete().then(function() { - this.Notification.success('Scheduled operation #' + id + ' deleted.'); + return operation.$delete().then(() => { + this.toastrService.success('Scheduled operation #' + id + ' deleted.'); this.operations = this.load(); return operation; - }, function(result) { - this.Notification.error( + }, (result) => { + this.toastrService.error( 'An error occurred while trying to delete scheduled operation #' + id + ':
' + result ); @@ -116,7 +122,7 @@ export class ScheduleController{ controller: function($scope, title, operation, $save) { $scope.title = title; $scope.operation = operation; - $scope.$save = function() { + $scope.$save = () => { $scope.$hide(); $save($scope.operation); }; @@ -124,7 +130,9 @@ export class ScheduleController{ locals: { title: title, operation: operation, - $save: this.save + $save: (operation) => { + this.save(operation); + } } }); }; From d5e00b8fe3b419f97c64749860a1a801238553cc Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 22 Jul 2017 09:18:22 +0200 Subject: [PATCH 062/222] Remove eslint comments. --- src/scheduler/schedule.controller.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/scheduler/schedule.controller.ts b/src/scheduler/schedule.controller.ts index 97f67a6..3980a03 100644 --- a/src/scheduler/schedule.controller.ts +++ b/src/scheduler/schedule.controller.ts @@ -25,7 +25,6 @@ export class ScheduleController{ */ add = function() { var operation = new this.ScheduledOperation({ - // eslint-disable-next-line camelcase account_id: this.$stateParams.accountId }); @@ -37,7 +36,6 @@ export class ScheduleController{ */ load = function() { return this.ScheduledOperation.query({ - // eslint-disable-next-line camelcase account_id: this.$stateParams.accountId }); }; From d96a66ee3e79633aad2f166abf37e3b6c98d2da8 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 22 Jul 2017 09:46:06 +0200 Subject: [PATCH 063/222] Remove unneeded . --- src/scheduler/schedule.controller.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/scheduler/schedule.controller.ts b/src/scheduler/schedule.controller.ts index 3980a03..357ff74 100644 --- a/src/scheduler/schedule.controller.ts +++ b/src/scheduler/schedule.controller.ts @@ -6,8 +6,6 @@ var scheduleFormTmpl = require('./schedule.form.tmpl.html'), scheduleDeleteTmpl = require('./schedule.delete.tmpl.html'); export class ScheduleController{ - $inject=['$stateParams', 'Notification', 'ScheduledOperation', '$modal'] - operations = []; constructor( From c5f3a5334721a00cde3709022f6afabebab93ed3 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 22 Jul 2017 09:54:52 +0200 Subject: [PATCH 064/222] Add Schedule model. --- src/scheduler/schedule.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/scheduler/schedule.ts diff --git a/src/scheduler/schedule.ts b/src/scheduler/schedule.ts new file mode 100644 index 0000000..300310a --- /dev/null +++ b/src/scheduler/schedule.ts @@ -0,0 +1,13 @@ +// vim: set tw=80 ts=2 sw=2 sts=2: + +export class Schedule { + id: number; + start_date: Date; + stop_date: Date; + day: number; + frequency: number; + label: string; + value: number; + category: string; + account_id: number +} From c25706964489f502dd67dcb14a955183bb931179 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 22 Jul 2017 11:11:39 +0200 Subject: [PATCH 065/222] Add schedule service. --- src/scheduler/schedule.service.ts | 49 +++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/scheduler/schedule.service.ts diff --git a/src/scheduler/schedule.service.ts b/src/scheduler/schedule.service.ts new file mode 100644 index 0000000..fb0d8f1 --- /dev/null +++ b/src/scheduler/schedule.service.ts @@ -0,0 +1,49 @@ +// vim: set tw=80 ts=2 sw=2 sts=2 : + +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs/Rx'; + +import { Restangular } from "ngx-restangular"; + +import { Schedule } from './schedule'; + +@Injectable() +export class ScheduleService { + constructor( + private restangular: Restangular + ) {} + + private all() { + //return this.accountService.one(accountId).all('scheduled_operation'); + return this.restangular.all('scheduled_operation'); + } + + private one(id: number) { + //return this.accountService.one(accountId).one('scheduled_operation', id); + return this.restangular.one('scheduled_operation', id); + } + + query(accountId: number): Observable { + return this.all().getList({ + account_id: accountId + }); + } + + get(accountId: number, id: number): Observable { + return this.one(id).get({ + account_id: accountId + }); + } + + create(schedule: Schedule): Observable { + return this.all().post(schedule); + } + + update(schedule: Schedule): Observable { + return this.one(schedule.id).post(null, schedule); + } + + delete(schedule: Schedule): Observable { + return this.one(schedule.id).delete(); + } +} From 42c0fe6c9b3926e75f0cbc5715b28c7af9a6e68b Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 22 Jul 2017 11:12:30 +0200 Subject: [PATCH 066/222] Add schedule module. --- src/app.module.ts | 2 ++ src/scheduler/schedule.module.ts | 34 ++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 src/scheduler/schedule.module.ts diff --git a/src/app.module.ts b/src/app.module.ts index 5fbb5b1..4083165 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -16,6 +16,7 @@ import { ToastrModule } from 'ngx-toastr'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { AccountModule } from './accounts/account.module'; +import { ScheduleModule } from './scheduler/schedule.module'; import { ApiBaseURL, LogLevel } from './app.config'; @NgModule({ @@ -24,6 +25,7 @@ import { ApiBaseURL, LogLevel } from './app.config'; BrowserAnimationsModule, UpgradeModule, AccountModule, + ScheduleModule, NgLoggerModule.forRoot(LogLevel), RestangularModule.forRoot((RestangularProvider) => { RestangularProvider.setBaseUrl(ApiBaseURL); diff --git a/src/scheduler/schedule.module.ts b/src/scheduler/schedule.module.ts new file mode 100644 index 0000000..a7a24c7 --- /dev/null +++ b/src/scheduler/schedule.module.ts @@ -0,0 +1,34 @@ +// vim: set tw=80 ts=2 sw=2 sts=2 : + +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { HttpModule } from '@angular/http'; + +import { NgLoggerModule, Level } from '@nsalaun/ng-logger'; +import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; +import { ToastrModule } from 'ngx-toastr'; + +import { ScheduleService } from './schedule.service'; +import { ScheduleDeleteModalComponent } from './scheduleDeleteModal.component'; + +@NgModule({ + imports: [ + HttpModule, + CommonModule, + FormsModule, + NgLoggerModule, + ToastrModule, + NgbModule + ], + providers: [ + ScheduleService + ], + declarations: [ + ScheduleDeleteModalComponent + ], + entryComponents: [ + ScheduleDeleteModalComponent + ] +}) +export class ScheduleModule {} From d52d38265333cc2bc93256f41e06ed0b2293b044 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 22 Jul 2017 11:16:04 +0200 Subject: [PATCH 067/222] Replace schedule factory by schedule service. --- src/scheduler/index.ts | 4 +-- src/scheduler/schedule.controller.ts | 48 ++++++++++++++++++---------- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/scheduler/index.ts b/src/scheduler/index.ts index 66b30b4..0937603 100644 --- a/src/scheduler/index.ts +++ b/src/scheduler/index.ts @@ -34,7 +34,7 @@ var ngMessages = require('angular-messages'), ngStrap = require('angular-strap'); import { ScheduleController } from './schedule.controller'; -import { ScheduleFactory } from './schedule.factory'; +import { ScheduleService } from './schedule.service'; export default angular.module('accountant.scheduler', [ ngMessages, @@ -47,7 +47,7 @@ export default angular.module('accountant.scheduler', [ .factory('logger', downgradeInjectable(Logger)) - .factory('ScheduledOperation', ScheduleFactory) + .factory('scheduleService', downgradeInjectable(ScheduleService)) .controller('SchedulerController', ScheduleController) diff --git a/src/scheduler/schedule.controller.ts b/src/scheduler/schedule.controller.ts index 357ff74..37e19a2 100644 --- a/src/scheduler/schedule.controller.ts +++ b/src/scheduler/schedule.controller.ts @@ -1,7 +1,12 @@ +import { Observable } from 'rxjs/Rx'; + import { Logger } from '@nsalaun/ng-logger'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { ToastrService } from 'ngx-toastr'; +import { ScheduleService } from './schedule.service'; +import { Schedule } from './schedule'; + var scheduleFormTmpl = require('./schedule.form.tmpl.html'), scheduleDeleteTmpl = require('./schedule.delete.tmpl.html'); @@ -11,41 +16,50 @@ export class ScheduleController{ constructor( private $stateParams, private toastrService: ToastrService, - private ScheduledOperation, + private scheduleService: ScheduleService, private $modal ) { // Load operations on controller initialization. - this.operations = this.load(); + this.load(); } /* * Add a new operation at the beginning of th array. */ add = function() { - var operation = new this.ScheduledOperation({ - account_id: this.$stateParams.accountId - }); + var schedule = new Schedule(); + schedule.account_id = this.$stateParams.accountId; - return this.modify(operation); + return this.modify(schedule); }; /* * Load operations. */ load = function() { - return this.ScheduledOperation.query({ - account_id: this.$stateParams.accountId - }); + return this.scheduleService.query(this.$stateParams.accountId) + .subscribe((schedules: Schedule[]) => { + this.operations = schedules; + } + ); }; /* * Save operation. */ - save = function(operation) { - return operation.$save().then((operation) => { + save = function(operation: Schedule) { + let subscription: Observable; + + if(operation.id) { + subscription = this.scheduleService.create(operation); + } else { + subscription = this.scheduleService.update(operation); + } + + return subscription.subscribe((operation: Schedule) => { this.toastrService.success('Scheduled operation #' + operation.id + ' saved.'); - this.operations = this.load(); + this.load(); return operation; }, (result) => { @@ -58,7 +72,7 @@ export class ScheduleController{ /* * Delete an operation and return a promise. */ - confirmDelete = function(operation) { + confirmDelete = function(operation: Schedule) { var title = "Delete operation #" + operation.id; this.$modal({ @@ -84,13 +98,13 @@ export class ScheduleController{ /* * Delete operation. */ - delete = function(operation) { + delete = function(operation: Schedule) { var id = operation.id; - return operation.$delete().then(() => { + return this.scheduleService.delete(operation).subscribe(() => { this.toastrService.success('Scheduled operation #' + id + ' deleted.'); - this.operations = this.load(); + this.load(); return operation; }, (result) => { @@ -105,7 +119,7 @@ export class ScheduleController{ * Open the popup to modify the operation, save it on confirm. * @returns a promise. */ - modify = function(operation) { + modify = function(operation: Schedule) { // FIXME Alexis Lahouze 2017-06-15 i18n var title = "Operation"; From e927736b4587318fb169a0c6771ed25ec8117b28 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 22 Jul 2017 11:16:20 +0200 Subject: [PATCH 068/222] Remove unused factory. --- src/scheduler/schedule.factory.ts | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 src/scheduler/schedule.factory.ts diff --git a/src/scheduler/schedule.factory.ts b/src/scheduler/schedule.factory.ts deleted file mode 100644 index 6e0be2b..0000000 --- a/src/scheduler/schedule.factory.ts +++ /dev/null @@ -1,7 +0,0 @@ -export function ScheduleFactory($resource) { - return $resource( - '/api/scheduled_operation/:id', { - id: '@id' - } - ); -}; From 3326dac51ab643e428219f4bb7ca1d09853bd30d Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 22 Jul 2017 14:29:29 +0200 Subject: [PATCH 069/222] Fix creation and update. --- src/scheduler/schedule.controller.ts | 7 +++++-- src/scheduler/schedule.service.ts | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/scheduler/schedule.controller.ts b/src/scheduler/schedule.controller.ts index 37e19a2..ffdafd2 100644 --- a/src/scheduler/schedule.controller.ts +++ b/src/scheduler/schedule.controller.ts @@ -17,6 +17,7 @@ export class ScheduleController{ private $stateParams, private toastrService: ToastrService, private scheduleService: ScheduleService, + private logger: Logger, private $modal ) { // Load operations on controller initialization. @@ -51,9 +52,11 @@ export class ScheduleController{ let subscription: Observable; if(operation.id) { - subscription = this.scheduleService.create(operation); - } else { + this.logger.log("updating schedule", operation); subscription = this.scheduleService.update(operation); + } else { + this.logger.log("creating schedule", operation); + subscription = this.scheduleService.create(operation); } return subscription.subscribe((operation: Schedule) => { diff --git a/src/scheduler/schedule.service.ts b/src/scheduler/schedule.service.ts index fb0d8f1..d29036b 100644 --- a/src/scheduler/schedule.service.ts +++ b/src/scheduler/schedule.service.ts @@ -44,6 +44,6 @@ export class ScheduleService { } delete(schedule: Schedule): Observable { - return this.one(schedule.id).delete(); + return this.one(schedule.id).remove(); } } From c4c10f9ab7929ca47c4b92d1ae712a794898ce5e Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 23 Jul 2017 00:12:44 +0200 Subject: [PATCH 070/222] Use component in scheduler route, inject accountId into. --- src/app.config.ts | 10 ++++++---- src/scheduler/index.ts | 11 ++++++++++- src/scheduler/schedule.controller.ts | 12 ++++++++---- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/app.config.ts b/src/app.config.ts index 7fe96a5..d9d521e 100644 --- a/src/app.config.ts +++ b/src/app.config.ts @@ -2,7 +2,6 @@ import { Level } from '@nsalaun/ng-logger'; var operationsTmpl = require('./operations/operations.html'); -var schedulerTmpl = require('./scheduler/scheduler.html'); export default function AppConfig($uiRouterProvider) { $uiRouterProvider.trace.enable(1); @@ -21,9 +20,12 @@ export default function AppConfig($uiRouterProvider) { $stateRegistry.register({ name: 'scheduler', url: '/account/:accountId/scheduler', - templateUrl: schedulerTmpl, - controller: 'SchedulerController', - controllerAs: 'schedulerCtrl' + component: 'scheduleComponent', + resolve: { + accountId: function($transition$) { + return $transition$.params().accountId; + } + } }); $stateRegistry.register({ diff --git a/src/scheduler/index.ts b/src/scheduler/index.ts index 0937603..d22c23a 100644 --- a/src/scheduler/index.ts +++ b/src/scheduler/index.ts @@ -33,6 +33,8 @@ var ngMessages = require('angular-messages'), ngUiNotification = require('angular-ui-notification'), ngStrap = require('angular-strap'); +var schedulerTmpl = require('./scheduler.html'); + import { ScheduleController } from './schedule.controller'; import { ScheduleService } from './schedule.service'; @@ -49,6 +51,13 @@ export default angular.module('accountant.scheduler', [ .factory('scheduleService', downgradeInjectable(ScheduleService)) - .controller('SchedulerController', ScheduleController) + .component('scheduleComponent', { + bindings: { + accountId: '<' + }, + templateUrl: schedulerTmpl, + controller: ScheduleController, + controllerAs: 'schedulerCtrl' + }) .name; diff --git a/src/scheduler/schedule.controller.ts b/src/scheduler/schedule.controller.ts index ffdafd2..9e83e5a 100644 --- a/src/scheduler/schedule.controller.ts +++ b/src/scheduler/schedule.controller.ts @@ -11,15 +11,17 @@ var scheduleFormTmpl = require('./schedule.form.tmpl.html'), scheduleDeleteTmpl = require('./schedule.delete.tmpl.html'); export class ScheduleController{ + accountId: number; operations = []; constructor( - private $stateParams, private toastrService: ToastrService, private scheduleService: ScheduleService, private logger: Logger, private $modal - ) { + ) {} + + $onInit = function() { // Load operations on controller initialization. this.load(); } @@ -29,7 +31,7 @@ export class ScheduleController{ */ add = function() { var schedule = new Schedule(); - schedule.account_id = this.$stateParams.accountId; + schedule.account_id = this.accountId; return this.modify(schedule); }; @@ -38,9 +40,11 @@ export class ScheduleController{ * Load operations. */ load = function() { - return this.scheduleService.query(this.$stateParams.accountId) + return this.scheduleService.query(this.accountId) .subscribe((schedules: Schedule[]) => { this.operations = schedules; + }, (reason) => { + this.logger.log("Got error", reason); } ); }; From 40bc4bf1e8a3e82cdfcd272c4ed06a7da050320d Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 23 Jul 2017 07:44:03 +0200 Subject: [PATCH 071/222] Rename controller to component. --- src/scheduler/index.ts | 4 ++-- .../{schedule.controller.ts => schedule.component.ts} | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename src/scheduler/{schedule.controller.ts => schedule.component.ts} (99%) diff --git a/src/scheduler/index.ts b/src/scheduler/index.ts index d22c23a..4dc53ed 100644 --- a/src/scheduler/index.ts +++ b/src/scheduler/index.ts @@ -35,7 +35,7 @@ var ngMessages = require('angular-messages'), var schedulerTmpl = require('./scheduler.html'); -import { ScheduleController } from './schedule.controller'; +import { ScheduleComponent } from './schedule.component'; import { ScheduleService } from './schedule.service'; export default angular.module('accountant.scheduler', [ @@ -56,7 +56,7 @@ export default angular.module('accountant.scheduler', [ accountId: '<' }, templateUrl: schedulerTmpl, - controller: ScheduleController, + controller: ScheduleComponent, controllerAs: 'schedulerCtrl' }) diff --git a/src/scheduler/schedule.controller.ts b/src/scheduler/schedule.component.ts similarity index 99% rename from src/scheduler/schedule.controller.ts rename to src/scheduler/schedule.component.ts index 9e83e5a..5a8b3b6 100644 --- a/src/scheduler/schedule.controller.ts +++ b/src/scheduler/schedule.component.ts @@ -10,7 +10,7 @@ import { Schedule } from './schedule'; var scheduleFormTmpl = require('./schedule.form.tmpl.html'), scheduleDeleteTmpl = require('./schedule.delete.tmpl.html'); -export class ScheduleController{ +export class ScheduleComponent { accountId: number; operations = []; From 1f5d4980e5b9694b90babfb87898fd3fbbdc9e9e Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 23 Jul 2017 07:44:31 +0200 Subject: [PATCH 072/222] Cleanup module. --- src/scheduler/index.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/scheduler/index.ts b/src/scheduler/index.ts index 4dc53ed..fb0a8cb 100644 --- a/src/scheduler/index.ts +++ b/src/scheduler/index.ts @@ -29,9 +29,7 @@ import { Logger } from '@nsalaun/ng-logger'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { ToastrService } from 'ngx-toastr'; -var ngMessages = require('angular-messages'), - ngUiNotification = require('angular-ui-notification'), - ngStrap = require('angular-strap'); +var ngStrap = require('angular-strap'); var schedulerTmpl = require('./scheduler.html'); @@ -39,8 +37,6 @@ import { ScheduleComponent } from './schedule.component'; import { ScheduleService } from './schedule.service'; export default angular.module('accountant.scheduler', [ - ngMessages, - ngUiNotification, ngStrap ]) .factory('toastrService', downgradeInjectable(ToastrService)) From 4f090a22df3f045a04125a96df18da0d3e80e7d3 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 23 Jul 2017 07:53:26 +0200 Subject: [PATCH 073/222] Format. --- src/scheduler/schedule.component.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/scheduler/schedule.component.ts b/src/scheduler/schedule.component.ts index 5a8b3b6..f2fc90c 100644 --- a/src/scheduler/schedule.component.ts +++ b/src/scheduler/schedule.component.ts @@ -21,7 +21,7 @@ export class ScheduleComponent { private $modal ) {} - $onInit = function() { + $onInit() { // Load operations on controller initialization. this.load(); } @@ -29,7 +29,7 @@ export class ScheduleComponent { /* * Add a new operation at the beginning of th array. */ - add = function() { + add() { var schedule = new Schedule(); schedule.account_id = this.accountId; @@ -39,7 +39,7 @@ export class ScheduleComponent { /* * Load operations. */ - load = function() { + load() { return this.scheduleService.query(this.accountId) .subscribe((schedules: Schedule[]) => { this.operations = schedules; @@ -52,7 +52,7 @@ export class ScheduleComponent { /* * Save operation. */ - save = function(operation: Schedule) { + save(operation: Schedule) { let subscription: Observable; if(operation.id) { @@ -79,7 +79,7 @@ export class ScheduleComponent { /* * Delete an operation and return a promise. */ - confirmDelete = function(operation: Schedule) { + confirmDelete(operation: Schedule) { var title = "Delete operation #" + operation.id; this.$modal({ @@ -105,7 +105,7 @@ export class ScheduleComponent { /* * Delete operation. */ - delete = function(operation: Schedule) { + delete(operation: Schedule) { var id = operation.id; return this.scheduleService.delete(operation).subscribe(() => { @@ -126,7 +126,7 @@ export class ScheduleComponent { * Open the popup to modify the operation, save it on confirm. * @returns a promise. */ - modify = function(operation: Schedule) { + modify(operation: Schedule) { // FIXME Alexis Lahouze 2017-06-15 i18n var title = "Operation"; From 7b7f72bf1ea32f6aab50e368986aa45518c18301 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 23 Jul 2017 07:58:41 +0200 Subject: [PATCH 074/222] Inject $modal from router. --- src/app.config.ts | 3 +++ src/scheduler/index.ts | 3 ++- src/scheduler/schedule.component.ts | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/app.config.ts b/src/app.config.ts index d9d521e..035c0d7 100644 --- a/src/app.config.ts +++ b/src/app.config.ts @@ -24,6 +24,9 @@ export default function AppConfig($uiRouterProvider) { resolve: { accountId: function($transition$) { return $transition$.params().accountId; + }, + $modal: function($modal) { + return $modal; } } }); diff --git a/src/scheduler/index.ts b/src/scheduler/index.ts index fb0a8cb..e1b6835 100644 --- a/src/scheduler/index.ts +++ b/src/scheduler/index.ts @@ -49,7 +49,8 @@ export default angular.module('accountant.scheduler', [ .component('scheduleComponent', { bindings: { - accountId: '<' + accountId: '<', + $modal: '<' }, templateUrl: schedulerTmpl, controller: ScheduleComponent, diff --git a/src/scheduler/schedule.component.ts b/src/scheduler/schedule.component.ts index f2fc90c..1b467f3 100644 --- a/src/scheduler/schedule.component.ts +++ b/src/scheduler/schedule.component.ts @@ -11,6 +11,7 @@ var scheduleFormTmpl = require('./schedule.form.tmpl.html'), scheduleDeleteTmpl = require('./schedule.delete.tmpl.html'); export class ScheduleComponent { + $modal: any; accountId: number; operations = []; @@ -18,7 +19,6 @@ export class ScheduleComponent { private toastrService: ToastrService, private scheduleService: ScheduleService, private logger: Logger, - private $modal ) {} $onInit() { From a7cee2891cfd06bfd5347237fb856d9e841ff759 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Mon, 24 Jul 2017 18:48:57 +0200 Subject: [PATCH 075/222] Move states in separate files. --- src/accounts/account.states.ts | 7 +++++++ src/app.config.ts | 32 ++++++------------------------ src/operations/operation.states.ts | 11 ++++++++++ src/scheduler/schedule.states.ts | 17 ++++++++++++++++ 4 files changed, 41 insertions(+), 26 deletions(-) create mode 100644 src/accounts/account.states.ts create mode 100644 src/operations/operation.states.ts create mode 100644 src/scheduler/schedule.states.ts diff --git a/src/accounts/account.states.ts b/src/accounts/account.states.ts new file mode 100644 index 0000000..e691de6 --- /dev/null +++ b/src/accounts/account.states.ts @@ -0,0 +1,7 @@ +// vim: set tw=80 ts=2 sw=2 sts=2 : + +export const AccountListState = { + name: 'accounts', + url: '/accounts', + component: 'accountList' +} diff --git a/src/app.config.ts b/src/app.config.ts index 035c0d7..b0d3f3d 100644 --- a/src/app.config.ts +++ b/src/app.config.ts @@ -1,7 +1,9 @@ // vim: set tw=80 ts=2 sw=2 sts=2 : import { Level } from '@nsalaun/ng-logger'; -var operationsTmpl = require('./operations/operations.html'); +import { AccountListState } from './accounts/account.states'; +import { OperationListState } from './operations/operation.states'; +import { ScheduleListState } from './scheduler/schedule.states'; export default function AppConfig($uiRouterProvider) { $uiRouterProvider.trace.enable(1); @@ -9,33 +11,11 @@ export default function AppConfig($uiRouterProvider) { // Defining template and controller in function of route. const $stateRegistry = $uiRouterProvider.stateRegistry; - $stateRegistry.register({ - name: 'operations', - url: '/account/:accountId/operations', - templateUrl: operationsTmpl, - controller: 'OperationController', - controllerAs: 'operationsCtrl' - }); + $stateRegistry.register(OperationListState); - $stateRegistry.register({ - name: 'scheduler', - url: '/account/:accountId/scheduler', - component: 'scheduleComponent', - resolve: { - accountId: function($transition$) { - return $transition$.params().accountId; - }, - $modal: function($modal) { - return $modal; - } - } - }); + $stateRegistry.register(ScheduleListState); - $stateRegistry.register({ - name: 'accounts', - url: '/accounts', - component: 'accountList', - }); + $stateRegistry.register(AccountListState); const $urlService = $uiRouterProvider.urlService; $urlService.rules.otherwise({ diff --git a/src/operations/operation.states.ts b/src/operations/operation.states.ts new file mode 100644 index 0000000..0998ad9 --- /dev/null +++ b/src/operations/operation.states.ts @@ -0,0 +1,11 @@ +// vim: set tw=80 ts=2 sw=2 sts=2 : + +var operationsTmpl = require('./operations.html'); + +export const OperationListState = { + name: 'operations', + url: '/account/:accountId/operations', + templateUrl: operationsTmpl, + controller: 'OperationController', + controllerAs: 'operationsCtrl' +} diff --git a/src/scheduler/schedule.states.ts b/src/scheduler/schedule.states.ts new file mode 100644 index 0000000..a3b0eae --- /dev/null +++ b/src/scheduler/schedule.states.ts @@ -0,0 +1,17 @@ +// vim: set tw=80 ts=2 sw=2 sts=2 : + +import { ScheduleComponent } from './schedule.component'; + +export const ScheduleListState = { + name: 'scheduler', + url: '/account/:accountId/scheduler', + component: 'scheduleComponent', + resolve: { + accountId: function($transition$) { + return $transition$.params().accountId; + }, + $modal: function($modal) { + return $modal; + } + } +} From 6873b32005b4ffe04f599f981fe1c29eabe8959a Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Mon, 24 Jul 2017 19:51:30 +0200 Subject: [PATCH 076/222] Set name for Angular1 app module. --- src/app.module.ts | 4 ++-- src/app.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app.module.ts b/src/app.module.ts index 4083165..0871474 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -2,7 +2,7 @@ import 'zone.js'; import 'reflect-metadata'; -import './app.ts'; +import { AppModule as Ng1AppModule } from './app'; import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; @@ -48,7 +48,7 @@ export class AppModule { constructor(private upgrade: UpgradeModule) { } ngDoBootstrap() { - this.upgrade.bootstrap(document.body, ['accountant'], { strictDi: false }); + this.upgrade.bootstrap(document.body, [Ng1AppModule.name], { strictDi: false }); } } diff --git a/src/app.ts b/src/app.ts index 111395f..f3bdb5e 100644 --- a/src/app.ts +++ b/src/app.ts @@ -31,7 +31,7 @@ import AppConfig from './app.config.ts'; require('bootstrap-webpack!./bootstrap.config.ts'); -angular.module('accountant', [ +export const AppModule = angular.module('accountant', [ uiRouter, accountModule, loginModule, From 8fb5f2ff7a4d1fc795183927939d95706743825e Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Mon, 24 Jul 2017 19:53:24 +0200 Subject: [PATCH 077/222] Separate hybrid application bootstrap. --- src/app.module.ts | 2 -- src/main.ts | 7 +++++++ webpack.config.js | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 src/main.ts diff --git a/src/app.module.ts b/src/app.module.ts index 0871474..dc3f915 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -8,7 +8,6 @@ import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { UpgradeModule } from '@angular/upgrade/static'; -import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { NgLoggerModule } from '@nsalaun/ng-logger'; import { RestangularModule } from 'ngx-restangular'; @@ -52,4 +51,3 @@ export class AppModule { } } -platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..07b1480 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,7 @@ +// vim: set tw=80 ts=2 sw=2 sts=2 : + +import { AppModule } from './app.module'; + +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/webpack.config.js b/webpack.config.js index 2c5fe51..c751891 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -5,7 +5,7 @@ const webpack = require('webpack'); module.exports = { context: path.resolve(__dirname, 'src'), - entry: './app.module.ts', + entry: './main.ts', devtool: 'source-map', resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx', '.html'], From 17a363d69da2b6aeaa29e207f1e02e8e5af7b33d Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Mon, 24 Jul 2017 20:33:30 +0200 Subject: [PATCH 078/222] Move up ng1 specific configuration in ng1 app module. --- src/app.config.ts | 22 ---------------------- src/app.ts | 28 +++++++++++++++++++++++++--- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/app.config.ts b/src/app.config.ts index b0d3f3d..482e7b4 100644 --- a/src/app.config.ts +++ b/src/app.config.ts @@ -1,27 +1,5 @@ // vim: set tw=80 ts=2 sw=2 sts=2 : import { Level } from '@nsalaun/ng-logger'; -import { AccountListState } from './accounts/account.states'; -import { OperationListState } from './operations/operation.states'; -import { ScheduleListState } from './scheduler/schedule.states'; - -export default function AppConfig($uiRouterProvider) { - $uiRouterProvider.trace.enable(1); - - // Defining template and controller in function of route. - const $stateRegistry = $uiRouterProvider.stateRegistry; - - $stateRegistry.register(OperationListState); - - $stateRegistry.register(ScheduleListState); - - $stateRegistry.register(AccountListState); - - const $urlService = $uiRouterProvider.urlService; - $urlService.rules.otherwise({ - state: 'accounts' - }); -}; - export const ApiBaseURL = "http://localhost:8080/api"; export const LogLevel = Level.LOG; diff --git a/src/app.ts b/src/app.ts index f3bdb5e..2e003e7 100644 --- a/src/app.ts +++ b/src/app.ts @@ -22,13 +22,15 @@ var angular = require('angular'); import uiRouter from '@uirouter/angularjs'; +import { AccountListState } from './accounts/account.states'; +import { OperationListState } from './operations/operation.states'; +import { ScheduleListState } from './scheduler/schedule.states'; + import accountModule from '@accountant/accounts'; import loginModule from '@accountant/login'; import operationModule from '@accountant/operations'; import schedulerModule from '@accountant/scheduler'; -import AppConfig from './app.config.ts'; - require('bootstrap-webpack!./bootstrap.config.ts'); export const AppModule = angular.module('accountant', [ @@ -37,4 +39,24 @@ export const AppModule = angular.module('accountant', [ loginModule, operationModule, schedulerModule, -]).config(AppConfig); +]); + +AppModule.config(['$uiRouterProvider', ($uiRouterProvider) => { + $uiRouterProvider.trace.enable(1); + + // Defining template and controller in function of route. + const $stateRegistry = $uiRouterProvider.stateRegistry; + + $stateRegistry.register(OperationListState); + + $stateRegistry.register(ScheduleListState); + + $stateRegistry.register(AccountListState); + + const $urlService = $uiRouterProvider.urlService; + $urlService.rules.otherwise({ + state: 'accounts' + }); +}]); + +AppModule.run(['$trace', $trace => { $trace.enable(1); }]); From ad16b5a39197d94f089742bf646a6fda8ba5e28a Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Mon, 24 Jul 2017 21:22:54 +0200 Subject: [PATCH 079/222] Upgrades. --- package.json | 76 ++++++++++++++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/package.json b/package.json index 2407a06..6075f21 100644 --- a/package.json +++ b/package.json @@ -6,72 +6,72 @@ "devDependencies": { "babel-core": "^6.25.0", "babel-eslint": "^7.2.3", - "babel-loader": "^7.0.0", + "babel-loader": "^7.1.1", "bootstrap-webpack": "^0.0.6", "css-loader": "^0.28.4", - "eslint": "^4.1.1", - "eslint-config-angular": "^0.5", - "eslint-config-webpack": "^1.2.3", - "eslint-loader": "^1.7.1", + "eslint": "^4.3.0", + "eslint-config-angular": "^0.5.0", + "eslint-config-webpack": "^1.2.5", + "eslint-loader": "^1.9.0", "eslint-plugin-angular": "^3.0.0", - "eslint-plugin-html": "^3.0.0", - "eslint-plugin-jquery": "^1.2", - "eslint-plugin-promise": "^3.5", - "eslint-plugin-security": "^1.3", - "eslint-plugin-this": "^0.2", + "eslint-plugin-html": "^3.1.1", + "eslint-plugin-jquery": "^1.2.1", + "eslint-plugin-promise": "^3.5.0", + "eslint-plugin-security": "^1.4.0", + "eslint-plugin-this": "^0.2.2", "extract-text-webpack-plugin": "^3.0.0", "file-loader": "^0.11.2", "html-loader": "^0.4.5", - "html-webpack-plugin": "^2.28.0", + "html-webpack-plugin": "^2.29.0", "htmllint-loader": "^1.3.8", "imports-loader": "^0.7.1", "less": "^2.7.2", - "less-loader": "^4.0.4", - "ngtemplate-loader": "^2.0.0", + "less-loader": "^4.0.5", + "ngtemplate-loader": "^2.0.1", "style-loader": "^0.18.2", - "ts-loader": "^2.2.2", - "typescript": "^2.4.1", - "url-loader": "^0.5.8", - "webpack": "^3.1.0", - "webpack-dev-server": "^2.4.5" + "ts-loader": "^2.3.1", + "typescript": "^2.4.2", + "url-loader": "^0.5.9", + "webpack": "^3.3.0", + "webpack-dev-server": "^2.6.1" }, "dependencies": { - "@angular/animations": "^4.3.0", - "@angular/common": "^4.2.6", - "@angular/compiler": "^4.2.6", - "@angular/core": "^4.2.6", - "@angular/forms": "^4.3.0", - "@angular/http": "^4.2.6", - "@angular/platform-browser": "^4.2.6", - "@angular/platform-browser-dynamic": "^4.2.6", - "@angular/upgrade": "^4.2.6", + "@angular/animations": "^4.3.1", + "@angular/common": "^4.3.1", + "@angular/compiler": "^4.3.1", + "@angular/core": "^4.3.1", + "@angular/forms": "^4.3.1", + "@angular/http": "^4.3.1", + "@angular/platform-browser": "^4.3.1", + "@angular/platform-browser-dynamic": "^4.3.1", + "@angular/upgrade": "^4.3.1", "@ng-bootstrap/ng-bootstrap": "^1.0.0-alpha.28", "@nsalaun/ng-logger": "^2.0.1", - "@types/angular": "^1.6.25", - "@types/node": "^8.0.10", + "@types/angular": "^1.6.27", + "@types/node": "^8.0.16", "@uirouter/angularjs": "^1.0.5", "@uirouter/core": "^5.0.5", - "angular": "^1.6", - "angular-http-auth": "^1.5", - "angular-messages": "^1.6", - "angular-resource": "^1.6", + "angular": "^1.6.5", + "angular-http-auth": "^1.5.0", + "angular-messages": "^1.6.5", + "angular-resource": "^1.6.5", "angular-strap": "^2.3.12", - "angular-ui-notification": "^0.3", + "angular-ui-notification": "^0.3.6", "angular2-notifications": "^0.7.4", "base64util": "^1.0.2", "bootbox": "^4.4.0", "bootstrap": "^3.3.7", "bootstrap-additions": "^0.3.1", - "c3": "^0.4.13", + "c3": "^0.4.15", "font-awesome": "^4.7.0", - "jquery": "^3.2", + "jquery": "^3.2.1", "meanie-angular-storage": "^1.3.1", - "moment": "^2.18", + "moment": "^2.18.1", "ngx-restangular": "^1.0.11", "ngx-toastr": "^5.3.1", "reflect-metadata": "^0.1.10", "rxjs": "^5.4.2", - "zone.js": "^0.8.12" + "zone.js": "^0.8.14" }, "scripts": { "build": "webpack --config webpack.config.js", From fa9402e25ef8408af6c97fdd95cf2340707dbc0b Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 25 Jul 2017 08:53:08 +0200 Subject: [PATCH 080/222] Add accountIdService to be able to correctly retrieve accountId in UiRouter transition. --- src/scheduler/index.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/scheduler/index.ts b/src/scheduler/index.ts index e1b6835..07bc9f9 100644 --- a/src/scheduler/index.ts +++ b/src/scheduler/index.ts @@ -30,6 +30,7 @@ import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { ToastrService } from 'ngx-toastr'; var ngStrap = require('angular-strap'); +import uiRouter from '@uirouter/angularjs'; var schedulerTmpl = require('./scheduler.html'); @@ -37,6 +38,7 @@ import { ScheduleComponent } from './schedule.component'; import { ScheduleService } from './schedule.service'; export default angular.module('accountant.scheduler', [ + uiRouter, ngStrap ]) .factory('toastrService', downgradeInjectable(ToastrService)) @@ -45,6 +47,19 @@ export default angular.module('accountant.scheduler', [ .factory('logger', downgradeInjectable(Logger)) + .factory('accountIdService', function() { + var accountId: null; + + return { + get: () => { + return accountId; + }, + set: (value) => { + accountId = value; + } + } + }) + .factory('scheduleService', downgradeInjectable(ScheduleService)) .component('scheduleComponent', { @@ -57,4 +72,10 @@ export default angular.module('accountant.scheduler', [ controllerAs: 'schedulerCtrl' }) + .run(function($transitions, accountIdService) { + $transitions.onSuccess({}, (transition) => { + accountIdService.set(transition.params().accountId); + }); + }) + .name; From 7ea652e23e640eb71ae7e801b328c7a147ac5043 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 25 Jul 2017 08:55:34 +0200 Subject: [PATCH 081/222] Add Shecdule Row Component. --- src/scheduler/scheduleRow.component.ts | 138 +++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 src/scheduler/scheduleRow.component.ts diff --git a/src/scheduler/scheduleRow.component.ts b/src/scheduler/scheduleRow.component.ts new file mode 100644 index 0000000..beb3607 --- /dev/null +++ b/src/scheduler/scheduleRow.component.ts @@ -0,0 +1,138 @@ +// vim: set tw=80 ts=2 sw=2 sts=2 : +import { CurrencyPipe } from '@angular/common'; +import { Component, Inject, Input, Output, EventEmitter, OnInit } from '@angular/core'; + +import { Logger } from '@nsalaun/ng-logger'; +import { ToastrService } from 'ngx-toastr'; + +import { ScheduleService } from './schedule.service'; +import { Schedule } from './schedule'; + +var scheduleFormTmpl = require('./schedule.form.tmpl.html'), + scheduleDeleteTmpl = require('./schedule.delete.tmpl.html'); + +@Component({ + selector: 'tr[schedule-row]', + host: { + "[id]": "schedule.id", + }, + template: ` +{{ schedule.start_date | date: "yyyy-MM-dd" }} + + +{{ schedule.stop_date | date: "yyyy-MM-dd" }} + +{{ schedule.day }} + +{{ schedule.frequency }} + +{{ schedule.label }} + +{{ schedule.value | currency:"EUR":true }} + +{{ schedule.category }} + + +
+ + + + + +
+ + ` +}) +export class ScheduleRowComponent { + @Input('schedule-row') schedule: Schedule; + @Output() needsReload: EventEmitter = new EventEmitter(); + + constructor( + private scheduleService: ScheduleService, + private logger: Logger, + private toastrService: ToastrService, + @Inject('$modal') private $modal + ) {} + + save(schedule: Schedule) { + return this.scheduleService.create(schedule).subscribe((schedule: Schedule) => { + this.toastrService.success('Schedule #' + schedule.id + ' saved.'); + + this.needsReload.emit(); + }, result => { + this.toastrService.error( + 'Error while saving schedule: ' + result.message + ); + }); + } + + confirmDelete() { + var title = "Delete schedule #" + this.schedule.id; + + this.$modal({ + templateUrl: scheduleDeleteTmpl, + controller: function($scope, title, schedule, $delete) { + $scope.title = title; + $scope.operation = schedule; + $scope.$delete = () => { + $scope.$hide(); + $delete($scope.operation); + }; + }, + locals: { + title: title, + schedule: this.schedule, + $delete: (schedule) => { + this.delete(schedule); + } + } + }); + } + + delete(schedule: Schedule) { + var id = schedule.id; + + return this.scheduleService.delete(schedule).subscribe(() => { + this.toastrService.success('Schedule #' + id + ' deleted.'); + + this.needsReload.emit(); + }, result => { + this.toastrService.error( + 'An error occurred while trying to delete schedule #' + id + ':
' + + result.message + ); + }); + } + + modify() { + // FIXME Alexis Lahouze 2017-06-15 i18n + var title = "Modify schedule #" + this.schedule.id; + + this.$modal({ + templateUrl: scheduleFormTmpl, + controller: function($scope, title, schedule, $save) { + $scope.title = title; + $scope.operation = schedule; + $scope.$save = () => { + $scope.$hide(); + $save($scope.operation); + }; + }, + locals: { + title: title, + schedule: this.schedule, + $save: (operation) => { + this.save(operation); + } + } + }); + } +} From 3c3741c33f35fb000d5fb453d712a5dab5cddacb Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 25 Jul 2017 10:06:41 +0200 Subject: [PATCH 082/222] Use accountIdService to retrieve current Account Id in Schedule Component. --- src/scheduler/schedule.component.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/scheduler/schedule.component.ts b/src/scheduler/schedule.component.ts index 1b467f3..3c427a2 100644 --- a/src/scheduler/schedule.component.ts +++ b/src/scheduler/schedule.component.ts @@ -19,9 +19,12 @@ export class ScheduleComponent { private toastrService: ToastrService, private scheduleService: ScheduleService, private logger: Logger, + private $modal, + private accountIdService ) {} $onInit() { + this.accountId = this.accountIdService.get(); // Load operations on controller initialization. this.load(); } From 434020f7adb358fa4f7267f81e1bfc2e63865264 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 25 Jul 2017 10:15:00 +0200 Subject: [PATCH 083/222] Add Restangular module and ScheduleRowComponent. --- src/scheduler/schedule.module.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/scheduler/schedule.module.ts b/src/scheduler/schedule.module.ts index a7a24c7..27fee9e 100644 --- a/src/scheduler/schedule.module.ts +++ b/src/scheduler/schedule.module.ts @@ -5,12 +5,14 @@ import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http'; +import { RestangularModule } from 'ngx-restangular'; import { NgLoggerModule, Level } from '@nsalaun/ng-logger'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { ToastrModule } from 'ngx-toastr'; import { ScheduleService } from './schedule.service'; import { ScheduleDeleteModalComponent } from './scheduleDeleteModal.component'; +import { ScheduleRowComponent } from './scheduleRow.component'; @NgModule({ imports: [ @@ -18,6 +20,7 @@ import { ScheduleDeleteModalComponent } from './scheduleDeleteModal.component'; CommonModule, FormsModule, NgLoggerModule, + RestangularModule, ToastrModule, NgbModule ], @@ -25,10 +28,12 @@ import { ScheduleDeleteModalComponent } from './scheduleDeleteModal.component'; ScheduleService ], declarations: [ - ScheduleDeleteModalComponent + ScheduleDeleteModalComponent, + ScheduleRowComponent ], entryComponents: [ - ScheduleDeleteModalComponent + ScheduleDeleteModalComponent, + ScheduleRowComponent ] }) export class ScheduleModule {} From 3c148e5297a2b8756f340927a1a00de8517cbd76 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 25 Jul 2017 10:42:29 +0200 Subject: [PATCH 084/222] Remove unused dependency. --- src/accounts/accountRow.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/accounts/accountRow.component.ts b/src/accounts/accountRow.component.ts index cd80ccb..94aa5b4 100644 --- a/src/accounts/accountRow.component.ts +++ b/src/accounts/accountRow.component.ts @@ -1,6 +1,6 @@ // vim: set tw=80 ts=2 sw=2 sts=2 : import { CurrencyPipe } from '@angular/common'; -import { Component, Inject, Input, Output, EventEmitter, OnInit } from '@angular/core'; +import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core'; import { Logger } from '@nsalaun/ng-logger'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; From 2166def0f10bf8033aef995178cd966a52b1d107 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 25 Jul 2017 10:45:13 +0200 Subject: [PATCH 085/222] Inject $modal and accountIdService in Angular Component. --- src/scheduler/schedule.component.ts | 1 - src/scheduler/schedule.module.ts | 19 ++++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/scheduler/schedule.component.ts b/src/scheduler/schedule.component.ts index 3c427a2..a117e8f 100644 --- a/src/scheduler/schedule.component.ts +++ b/src/scheduler/schedule.component.ts @@ -11,7 +11,6 @@ var scheduleFormTmpl = require('./schedule.form.tmpl.html'), scheduleDeleteTmpl = require('./schedule.delete.tmpl.html'); export class ScheduleComponent { - $modal: any; accountId: number; operations = []; diff --git a/src/scheduler/schedule.module.ts b/src/scheduler/schedule.module.ts index 27fee9e..505d983 100644 --- a/src/scheduler/schedule.module.ts +++ b/src/scheduler/schedule.module.ts @@ -14,6 +14,14 @@ import { ScheduleService } from './schedule.service'; import { ScheduleDeleteModalComponent } from './scheduleDeleteModal.component'; import { ScheduleRowComponent } from './scheduleRow.component'; +export function $modalServiceFactory(i: any) { + return i.get('$modal'); +} + +export function accountIdServiceFactory(i: any) { + return i.get('accountIdService'); +} + @NgModule({ imports: [ HttpModule, @@ -25,7 +33,16 @@ import { ScheduleRowComponent } from './scheduleRow.component'; NgbModule ], providers: [ - ScheduleService + ScheduleService, + { + provide: '$modal', + deps: ['$injector'], + useFactory: $modalServiceFactory + }, { + provide: 'accountIdService', + deps: ['$injector'], + useFactory: accountIdServiceFactory + } ], declarations: [ ScheduleDeleteModalComponent, From e8247e30ab68cb9d08f847815c910c184dbe4c7c Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 25 Jul 2017 12:03:42 +0200 Subject: [PATCH 086/222] Upgrade Schedule component to Angular4. --- src/scheduler/index.ts | 12 +- src/scheduler/schedule.component.ts | 187 ++++++++++++---------------- src/scheduler/schedule.module.ts | 3 + 3 files changed, 84 insertions(+), 118 deletions(-) diff --git a/src/scheduler/index.ts b/src/scheduler/index.ts index 07bc9f9..427a500 100644 --- a/src/scheduler/index.ts +++ b/src/scheduler/index.ts @@ -62,15 +62,9 @@ export default angular.module('accountant.scheduler', [ .factory('scheduleService', downgradeInjectable(ScheduleService)) - .component('scheduleComponent', { - bindings: { - accountId: '<', - $modal: '<' - }, - templateUrl: schedulerTmpl, - controller: ScheduleComponent, - controllerAs: 'schedulerCtrl' - }) + .directive('scheduleComponent', downgradeComponent({ + component: ScheduleComponent + })) .run(function($transitions, accountIdService) { $transitions.onSuccess({}, (transition) => { diff --git a/src/scheduler/schedule.component.ts b/src/scheduler/schedule.component.ts index a117e8f..966bee2 100644 --- a/src/scheduler/schedule.component.ts +++ b/src/scheduler/schedule.component.ts @@ -1,3 +1,4 @@ +import { Component, Inject, OnInit } from '@angular/core'; import { Observable } from 'rxjs/Rx'; import { Logger } from '@nsalaun/ng-logger'; @@ -7,22 +8,61 @@ import { ToastrService } from 'ngx-toastr'; import { ScheduleService } from './schedule.service'; import { Schedule } from './schedule'; -var scheduleFormTmpl = require('./schedule.form.tmpl.html'), - scheduleDeleteTmpl = require('./schedule.delete.tmpl.html'); +var scheduleFormTmpl = require('./schedule.form.tmpl.html'); -export class ScheduleComponent { +@Component({ + selector: 'schedule-list', + template: ` +
+ + + + + + + + + + + + + + + + + + + + + + +
Date de débutDate de finJourFréq.Libellé de l'opérationMontantCatégorieActions
+ +
+
+ ` +}) +export class ScheduleComponent implements OnInit { accountId: number; - operations = []; + schedules = []; constructor( private toastrService: ToastrService, private scheduleService: ScheduleService, private logger: Logger, - private $modal, - private accountIdService + @Inject('$modal') private $modal, + @Inject('accountIdService') private accountIdService ) {} $onInit() { + this.ngOnInit(); + } + + ngOnInit() { + this.logger.log("ngOnInit"); this.accountId = this.accountIdService.get(); // Load operations on controller initialization. this.load(); @@ -35,124 +75,53 @@ export class ScheduleComponent { var schedule = new Schedule(); schedule.account_id = this.accountId; - return this.modify(schedule); + var title = "New schedule"; + + this.$modal({ + templateUrl: scheduleFormTmpl, + controller: function($scope, title, schedule, $save) { + $scope.title = title; + $scope.operation = schedule; + $scope.$save = () => { + $scope.$hide(); + $save($scope.operation); + }; + }, + locals: { + title: title, + schedule: schedule, + $save: (schedule) => { + this.save(schedule); + } + } + }); }; - /* - * Load operations. - */ load() { - return this.scheduleService.query(this.accountId) + this.logger.log("Loading schedules for accountId", this.accountId); + if(!this.accountId) { + return; + } + + this.scheduleService.query(this.accountId) .subscribe((schedules: Schedule[]) => { - this.operations = schedules; + this.logger.log("Schedules loaded.", schedules); + this.schedules = schedules; }, (reason) => { this.logger.log("Got error", reason); } ); }; - /* - * Save operation. - */ - save(operation: Schedule) { - let subscription: Observable; - - if(operation.id) { - this.logger.log("updating schedule", operation); - subscription = this.scheduleService.update(operation); - } else { - this.logger.log("creating schedule", operation); - subscription = this.scheduleService.create(operation); - } - - return subscription.subscribe((operation: Schedule) => { - this.toastrService.success('Scheduled operation #' + operation.id + ' saved.'); + save(schedule: Schedule) { + return this.scheduleService.update(schedule).subscribe((schedule: Schedule) => { + this.toastrService.success('Schedule #' + schedule.id + ' saved.'); this.load(); - - return operation; }, (result) => { this.toastrService.error( - 'Error while saving scheduled operation: ' + result.message + 'Error while saving schedule: ' + result.message ); }); }; - - /* - * Delete an operation and return a promise. - */ - confirmDelete(operation: Schedule) { - var title = "Delete operation #" + operation.id; - - this.$modal({ - templateUrl: scheduleDeleteTmpl, - controller: function($scope, title, operation, $delete) { - $scope.title = title; - $scope.operation = operation; - $scope.$delete = () => { - $scope.$hide(); - $delete($scope.operation); - }; - }, - locals: { - title: title, - operation: operation, - $delete: (operation) => { - this.delete(operation); - } - } - }); - }; - - /* - * Delete operation. - */ - delete(operation: Schedule) { - var id = operation.id; - - return this.scheduleService.delete(operation).subscribe(() => { - this.toastrService.success('Scheduled operation #' + id + ' deleted.'); - - this.load(); - - return operation; - }, (result) => { - this.toastrService.error( - 'An error occurred while trying to delete scheduled operation #' + - id + ':
' + result - ); - }); - }; - - /* - * Open the popup to modify the operation, save it on confirm. - * @returns a promise. - */ - modify(operation: Schedule) { - // FIXME Alexis Lahouze 2017-06-15 i18n - var title = "Operation"; - - if (operation.id) { - title = title + " #" + operation.id; - } - - this.$modal({ - templateUrl: scheduleFormTmpl, - controller: function($scope, title, operation, $save) { - $scope.title = title; - $scope.operation = operation; - $scope.$save = () => { - $scope.$hide(); - $save($scope.operation); - }; - }, - locals: { - title: title, - operation: operation, - $save: (operation) => { - this.save(operation); - } - } - }); - }; }; diff --git a/src/scheduler/schedule.module.ts b/src/scheduler/schedule.module.ts index 505d983..42d8da1 100644 --- a/src/scheduler/schedule.module.ts +++ b/src/scheduler/schedule.module.ts @@ -13,6 +13,7 @@ import { ToastrModule } from 'ngx-toastr'; import { ScheduleService } from './schedule.service'; import { ScheduleDeleteModalComponent } from './scheduleDeleteModal.component'; import { ScheduleRowComponent } from './scheduleRow.component'; +import { ScheduleComponent } from './schedule.component'; export function $modalServiceFactory(i: any) { return i.get('$modal'); @@ -46,10 +47,12 @@ export function accountIdServiceFactory(i: any) { ], declarations: [ ScheduleDeleteModalComponent, + ScheduleComponent, ScheduleRowComponent ], entryComponents: [ ScheduleDeleteModalComponent, + ScheduleComponent, ScheduleRowComponent ] }) From fd4da93c20e8dc1628ebb28acc3dc87cddd64afa Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 25 Jul 2017 12:09:51 +0200 Subject: [PATCH 087/222] Add missing loglevel dependency. --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 6075f21..c3741b3 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "imports-loader": "^0.7.1", "less": "^2.7.2", "less-loader": "^4.0.5", + "loglevel": "^1.4.1", "ngtemplate-loader": "^2.0.1", "style-loader": "^0.18.2", "ts-loader": "^2.3.1", From 46f5f72bd42d9078fb6559b7806ad72e50fa4dbb Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 25 Jul 2017 15:45:25 +0200 Subject: [PATCH 088/222] Add Schedule Delete Modal component. --- .../scheduleDeleteModal.component.ts | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/scheduler/scheduleDeleteModal.component.ts diff --git a/src/scheduler/scheduleDeleteModal.component.ts b/src/scheduler/scheduleDeleteModal.component.ts new file mode 100644 index 0000000..7e21276 --- /dev/null +++ b/src/scheduler/scheduleDeleteModal.component.ts @@ -0,0 +1,49 @@ +// vim: set tw=80 ts=2 sw=2 sts=2: +import { Component, Input } from '@angular/core'; + +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; + +import { Schedule } from './schedule'; + +@Component({ + selector: 'schedule-delete-modal', + template: ` + + + + + + ` +}) +export class ScheduleDeleteModalComponent { + @Input() schedule: Schedule + + constructor(public activeModal: NgbActiveModal) {} + + title(): string { + return "Delete schedule #" + this.schedule.id; + } + + submit(): void { + this.activeModal.close(this.schedule); + } + + cancel(): void { + this.activeModal.dismiss("closed"); + } +} From 53a29062ea8765e0e3998a1204c4b2b067d88884 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 25 Jul 2017 15:58:54 +0200 Subject: [PATCH 089/222] Use Schedule Delete Modal Component in scheduleRow Component. --- src/scheduler/schedule.delete.tmpl.html | 25 ------------------ src/scheduler/scheduleRow.component.ts | 34 ++++++++++--------------- 2 files changed, 14 insertions(+), 45 deletions(-) delete mode 100644 src/scheduler/schedule.delete.tmpl.html diff --git a/src/scheduler/schedule.delete.tmpl.html b/src/scheduler/schedule.delete.tmpl.html deleted file mode 100644 index 904ae6d..0000000 --- a/src/scheduler/schedule.delete.tmpl.html +++ /dev/null @@ -1,25 +0,0 @@ - - diff --git a/src/scheduler/scheduleRow.component.ts b/src/scheduler/scheduleRow.component.ts index beb3607..d50c1d5 100644 --- a/src/scheduler/scheduleRow.component.ts +++ b/src/scheduler/scheduleRow.component.ts @@ -3,13 +3,14 @@ import { CurrencyPipe } from '@angular/common'; import { Component, Inject, Input, Output, EventEmitter, OnInit } from '@angular/core'; import { Logger } from '@nsalaun/ng-logger'; +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { ToastrService } from 'ngx-toastr'; +import { ScheduleDeleteModalComponent } from './scheduleDeleteModal.component'; import { ScheduleService } from './schedule.service'; import { Schedule } from './schedule'; -var scheduleFormTmpl = require('./schedule.form.tmpl.html'), - scheduleDeleteTmpl = require('./schedule.delete.tmpl.html'); +var scheduleFormTmpl = require('./schedule.form.tmpl.html'); @Component({ selector: 'tr[schedule-row]', @@ -59,7 +60,8 @@ export class ScheduleRowComponent { private scheduleService: ScheduleService, private logger: Logger, private toastrService: ToastrService, - @Inject('$modal') private $modal + @Inject('$modal') private $modal, + private ngbModal: NgbModal ) {} save(schedule: Schedule) { @@ -77,23 +79,15 @@ export class ScheduleRowComponent { confirmDelete() { var title = "Delete schedule #" + this.schedule.id; - this.$modal({ - templateUrl: scheduleDeleteTmpl, - controller: function($scope, title, schedule, $delete) { - $scope.title = title; - $scope.operation = schedule; - $scope.$delete = () => { - $scope.$hide(); - $delete($scope.operation); - }; - }, - locals: { - title: title, - schedule: this.schedule, - $delete: (schedule) => { - this.delete(schedule); - } - } + const modal = this.ngbModal.open(ScheduleDeleteModalComponent, { + windowClass: 'in' + }); + + modal.componentInstance.schedule = this.schedule; + + modal.result.then((schedule: Schedule) => { + this.delete(schedule); + }, (reason) => function(reason) { }); } From d83a164cc68f5927aa48b89abf3e47fe4623c166 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 25 Jul 2017 16:14:48 +0200 Subject: [PATCH 090/222] Remove dependency. --- src/scheduler/scheduleRow.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scheduler/scheduleRow.component.ts b/src/scheduler/scheduleRow.component.ts index d50c1d5..151d07b 100644 --- a/src/scheduler/scheduleRow.component.ts +++ b/src/scheduler/scheduleRow.component.ts @@ -1,6 +1,6 @@ // vim: set tw=80 ts=2 sw=2 sts=2 : import { CurrencyPipe } from '@angular/common'; -import { Component, Inject, Input, Output, EventEmitter, OnInit } from '@angular/core'; +import { Component, Inject, Input, Output, EventEmitter } from '@angular/core'; import { Logger } from '@nsalaun/ng-logger'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; From 2cf432ed2c60135e594bc7385899720ae1952666 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 25 Jul 2017 16:56:57 +0200 Subject: [PATCH 091/222] Rename component. --- src/scheduler/index.ts | 6 +++--- src/scheduler/schedule.module.ts | 6 +++--- src/scheduler/schedule.states.ts | 4 +--- .../{schedule.component.ts => scheduleList.component.ts} | 2 +- 4 files changed, 8 insertions(+), 10 deletions(-) rename src/scheduler/{schedule.component.ts => scheduleList.component.ts} (98%) diff --git a/src/scheduler/index.ts b/src/scheduler/index.ts index 427a500..98e6867 100644 --- a/src/scheduler/index.ts +++ b/src/scheduler/index.ts @@ -34,7 +34,7 @@ import uiRouter from '@uirouter/angularjs'; var schedulerTmpl = require('./scheduler.html'); -import { ScheduleComponent } from './schedule.component'; +import { ScheduleListComponent } from './scheduleList.component'; import { ScheduleService } from './schedule.service'; export default angular.module('accountant.scheduler', [ @@ -62,8 +62,8 @@ export default angular.module('accountant.scheduler', [ .factory('scheduleService', downgradeInjectable(ScheduleService)) - .directive('scheduleComponent', downgradeComponent({ - component: ScheduleComponent + .directive('scheduleListComponent', downgradeComponent({ + component: ScheduleListComponent })) .run(function($transitions, accountIdService) { diff --git a/src/scheduler/schedule.module.ts b/src/scheduler/schedule.module.ts index 42d8da1..acc847c 100644 --- a/src/scheduler/schedule.module.ts +++ b/src/scheduler/schedule.module.ts @@ -13,7 +13,7 @@ import { ToastrModule } from 'ngx-toastr'; import { ScheduleService } from './schedule.service'; import { ScheduleDeleteModalComponent } from './scheduleDeleteModal.component'; import { ScheduleRowComponent } from './scheduleRow.component'; -import { ScheduleComponent } from './schedule.component'; +import { ScheduleListComponent } from './scheduleList.component'; export function $modalServiceFactory(i: any) { return i.get('$modal'); @@ -47,12 +47,12 @@ export function accountIdServiceFactory(i: any) { ], declarations: [ ScheduleDeleteModalComponent, - ScheduleComponent, + ScheduleListComponent, ScheduleRowComponent ], entryComponents: [ ScheduleDeleteModalComponent, - ScheduleComponent, + ScheduleListComponent, ScheduleRowComponent ] }) diff --git a/src/scheduler/schedule.states.ts b/src/scheduler/schedule.states.ts index a3b0eae..4912166 100644 --- a/src/scheduler/schedule.states.ts +++ b/src/scheduler/schedule.states.ts @@ -1,11 +1,9 @@ // vim: set tw=80 ts=2 sw=2 sts=2 : -import { ScheduleComponent } from './schedule.component'; - export const ScheduleListState = { name: 'scheduler', url: '/account/:accountId/scheduler', - component: 'scheduleComponent', + component: 'scheduleListComponent', resolve: { accountId: function($transition$) { return $transition$.params().accountId; diff --git a/src/scheduler/schedule.component.ts b/src/scheduler/scheduleList.component.ts similarity index 98% rename from src/scheduler/schedule.component.ts rename to src/scheduler/scheduleList.component.ts index 966bee2..74ab286 100644 --- a/src/scheduler/schedule.component.ts +++ b/src/scheduler/scheduleList.component.ts @@ -45,7 +45,7 @@ var scheduleFormTmpl = require('./schedule.form.tmpl.html');
` }) -export class ScheduleComponent implements OnInit { +export class ScheduleListComponent implements OnInit { accountId: number; schedules = []; From 3dd347ee8c2253b9bcd031b6b326a593fb16414c Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 25 Jul 2017 16:59:40 +0200 Subject: [PATCH 092/222] Remove unused template. --- src/scheduler/index.ts | 2 - src/scheduler/scheduler.html | 92 ------------------------------------ 2 files changed, 94 deletions(-) delete mode 100644 src/scheduler/scheduler.html diff --git a/src/scheduler/index.ts b/src/scheduler/index.ts index 98e6867..957c965 100644 --- a/src/scheduler/index.ts +++ b/src/scheduler/index.ts @@ -32,8 +32,6 @@ import { ToastrService } from 'ngx-toastr'; var ngStrap = require('angular-strap'); import uiRouter from '@uirouter/angularjs'; -var schedulerTmpl = require('./scheduler.html'); - import { ScheduleListComponent } from './scheduleList.component'; import { ScheduleService } from './schedule.service'; diff --git a/src/scheduler/scheduler.html b/src/scheduler/scheduler.html deleted file mode 100644 index d68e3e7..0000000 --- a/src/scheduler/scheduler.html +++ /dev/null @@ -1,92 +0,0 @@ - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Date de débutDate de finJourFréq.Libellé de l'opérationMontantCatégorieActions
- -
- {{ operation.start_date | date: "yyyy-MM-dd" }} - - {{ operation.stop_date | date: "yyyy-MM-dd" }} - - {{ operation.day }} - - {{ operation.frequency }} - - {{ operation.label }} - - {{ operation.value | currency : "€" }} - - {{ operation.category }} - -
- - - - - -
-
-
From 3c0d3c1a39de6b1c9c3bd8cb4c5a8b180f976502 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 25 Jul 2017 17:17:22 +0200 Subject: [PATCH 093/222] Add Schedule Form component. --- src/scheduler/schedule.module.ts | 3 + src/scheduler/scheduleForm.component.ts | 86 +++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 src/scheduler/scheduleForm.component.ts diff --git a/src/scheduler/schedule.module.ts b/src/scheduler/schedule.module.ts index acc847c..e8c5c9a 100644 --- a/src/scheduler/schedule.module.ts +++ b/src/scheduler/schedule.module.ts @@ -12,6 +12,7 @@ import { ToastrModule } from 'ngx-toastr'; import { ScheduleService } from './schedule.service'; import { ScheduleDeleteModalComponent } from './scheduleDeleteModal.component'; +import { ScheduleFormComponent } from './scheduleForm.component'; import { ScheduleRowComponent } from './scheduleRow.component'; import { ScheduleListComponent } from './scheduleList.component'; @@ -47,11 +48,13 @@ export function accountIdServiceFactory(i: any) { ], declarations: [ ScheduleDeleteModalComponent, + ScheduleFormComponent, ScheduleListComponent, ScheduleRowComponent ], entryComponents: [ ScheduleDeleteModalComponent, + ScheduleFormComponent, ScheduleListComponent, ScheduleRowComponent ] diff --git a/src/scheduler/scheduleForm.component.ts b/src/scheduler/scheduleForm.component.ts new file mode 100644 index 0000000..8d1ea33 --- /dev/null +++ b/src/scheduler/scheduleForm.component.ts @@ -0,0 +1,86 @@ +// vim: set tw=80 ts=2 sw=2 sts=2 : +import { AfterViewChecked, Component, EventEmitter, Input, Output, ViewChild } from '@angular/core'; +import { NgForm } from '@angular/forms'; + +import { Logger } from '@nsalaun/ng-logger'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; + +import { Schedule } from './schedule'; + +@Component({ + selector: 'schedule-form', + template: ` +
+
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+
+ ` +}) +export class ScheduleFormComponent implements AfterViewChecked { + @Input() schedule: Schedule; + @Output() onValid: EventEmitter = new EventEmitter(); + @ViewChild('form') form: NgForm; + + constructor() {} + + ngAfterViewChecked() { + this.onValid.emit(this.form.form.valid); + } +} From 57aa737465bee3778d0bd45afbe2f90a073f8aba Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 25 Jul 2017 17:18:04 +0200 Subject: [PATCH 094/222] Add Schedule Edit Modal component. --- src/scheduler/schedule.module.ts | 3 ++ src/scheduler/scheduleEditModal.component.ts | 53 ++++++++++++++++++++ src/scheduler/scheduleRow.component.ts | 1 + 3 files changed, 57 insertions(+) create mode 100644 src/scheduler/scheduleEditModal.component.ts diff --git a/src/scheduler/schedule.module.ts b/src/scheduler/schedule.module.ts index e8c5c9a..423eaae 100644 --- a/src/scheduler/schedule.module.ts +++ b/src/scheduler/schedule.module.ts @@ -12,6 +12,7 @@ import { ToastrModule } from 'ngx-toastr'; import { ScheduleService } from './schedule.service'; import { ScheduleDeleteModalComponent } from './scheduleDeleteModal.component'; +import { ScheduleEditModalComponent } from './scheduleEditModal.component'; import { ScheduleFormComponent } from './scheduleForm.component'; import { ScheduleRowComponent } from './scheduleRow.component'; import { ScheduleListComponent } from './scheduleList.component'; @@ -48,12 +49,14 @@ export function accountIdServiceFactory(i: any) { ], declarations: [ ScheduleDeleteModalComponent, + ScheduleEditModalComponent, ScheduleFormComponent, ScheduleListComponent, ScheduleRowComponent ], entryComponents: [ ScheduleDeleteModalComponent, + ScheduleEditModalComponent, ScheduleFormComponent, ScheduleListComponent, ScheduleRowComponent diff --git a/src/scheduler/scheduleEditModal.component.ts b/src/scheduler/scheduleEditModal.component.ts new file mode 100644 index 0000000..98258f8 --- /dev/null +++ b/src/scheduler/scheduleEditModal.component.ts @@ -0,0 +1,53 @@ +// vim: set tw=80 ts=2 sw=2 sts=2: +import { Component, Input } from '@angular/core'; +import { NgForm } from '@angular/forms'; + +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; + +import { Schedule } from './schedule'; + +@Component({ + selector: 'schedule-edit-modal', + template: ` + + + + + + ` +}) +export class ScheduleEditModalComponent { + @Input() schedule: Schedule; + + valid: boolean = false; + + constructor(private activeModal: NgbActiveModal) {} + + title(): string { + if(this.schedule.id) { + return "Schedule #" + this.schedule.id; + } else { + return "New schedule"; + } + } + + submit(): void { + this.activeModal.close(this.schedule); + } + + cancel(): void { + this.activeModal.dismiss("closed"); + } +} diff --git a/src/scheduler/scheduleRow.component.ts b/src/scheduler/scheduleRow.component.ts index 151d07b..9440577 100644 --- a/src/scheduler/scheduleRow.component.ts +++ b/src/scheduler/scheduleRow.component.ts @@ -7,6 +7,7 @@ import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { ToastrService } from 'ngx-toastr'; import { ScheduleDeleteModalComponent } from './scheduleDeleteModal.component'; +import { ScheduleEditModalComponent } from './scheduleEditModal.component'; import { ScheduleService } from './schedule.service'; import { Schedule } from './schedule'; From d1344d57b823e6e597b627184e06537b802176a8 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 25 Jul 2017 17:21:01 +0200 Subject: [PATCH 095/222] Use Schedule Edit Modal component in Schedule Row component. --- src/scheduler/scheduleRow.component.ts | 30 +++++++------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/src/scheduler/scheduleRow.component.ts b/src/scheduler/scheduleRow.component.ts index 9440577..020ade3 100644 --- a/src/scheduler/scheduleRow.component.ts +++ b/src/scheduler/scheduleRow.component.ts @@ -11,8 +11,6 @@ import { ScheduleEditModalComponent } from './scheduleEditModal.component'; import { ScheduleService } from './schedule.service'; import { Schedule } from './schedule'; -var scheduleFormTmpl = require('./schedule.form.tmpl.html'); - @Component({ selector: 'tr[schedule-row]', host: { @@ -61,7 +59,6 @@ export class ScheduleRowComponent { private scheduleService: ScheduleService, private logger: Logger, private toastrService: ToastrService, - @Inject('$modal') private $modal, private ngbModal: NgbModal ) {} @@ -108,26 +105,15 @@ export class ScheduleRowComponent { } modify() { - // FIXME Alexis Lahouze 2017-06-15 i18n - var title = "Modify schedule #" + this.schedule.id; + const modal = this.ngbModal.open(ScheduleEditModalComponent, { + windowClass: 'in' + }); - this.$modal({ - templateUrl: scheduleFormTmpl, - controller: function($scope, title, schedule, $save) { - $scope.title = title; - $scope.operation = schedule; - $scope.$save = () => { - $scope.$hide(); - $save($scope.operation); - }; - }, - locals: { - title: title, - schedule: this.schedule, - $save: (operation) => { - this.save(operation); - } - } + modal.componentInstance.schedule = this.schedule; + + modal.result.then((schedule: Schedule) => { + this.save(schedule); + }, (reason) => function(reason) { }); } } From 2f64fa10183a74eb923efd96c123837e83b8a927 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 25 Jul 2017 17:25:50 +0200 Subject: [PATCH 096/222] Use Schedule Edit Modal component in Schedule List component. --- src/scheduler/scheduleList.component.ts | 29 +++++++++---------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/src/scheduler/scheduleList.component.ts b/src/scheduler/scheduleList.component.ts index 74ab286..db6f1b0 100644 --- a/src/scheduler/scheduleList.component.ts +++ b/src/scheduler/scheduleList.component.ts @@ -5,6 +5,7 @@ import { Logger } from '@nsalaun/ng-logger'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { ToastrService } from 'ngx-toastr'; +import { ScheduleEditModalComponent } from './scheduleEditModal.component'; import { ScheduleService } from './schedule.service'; import { Schedule } from './schedule'; @@ -53,7 +54,7 @@ export class ScheduleListComponent implements OnInit { private toastrService: ToastrService, private scheduleService: ScheduleService, private logger: Logger, - @Inject('$modal') private $modal, + private ngbModal: NgbModal, @Inject('accountIdService') private accountIdService ) {} @@ -75,25 +76,15 @@ export class ScheduleListComponent implements OnInit { var schedule = new Schedule(); schedule.account_id = this.accountId; - var title = "New schedule"; + const modal = this.ngbModal.open(ScheduleEditModalComponent, { + windowClass: 'in' + }); - this.$modal({ - templateUrl: scheduleFormTmpl, - controller: function($scope, title, schedule, $save) { - $scope.title = title; - $scope.operation = schedule; - $scope.$save = () => { - $scope.$hide(); - $save($scope.operation); - }; - }, - locals: { - title: title, - schedule: schedule, - $save: (schedule) => { - this.save(schedule); - } - } + modal.componentInstance.schedule = schedule; + + modal.result.then((schedule: Schedule) => { + this.save(schedule); + }, (reason) => function(reason) { }); }; From fc14efbda1b043324f8e65e9355cff03dd9b64fd Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 25 Jul 2017 17:26:09 +0200 Subject: [PATCH 097/222] Fix inverted create and update calls. --- src/scheduler/scheduleList.component.ts | 2 +- src/scheduler/scheduleRow.component.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/scheduler/scheduleList.component.ts b/src/scheduler/scheduleList.component.ts index db6f1b0..23dc281 100644 --- a/src/scheduler/scheduleList.component.ts +++ b/src/scheduler/scheduleList.component.ts @@ -105,7 +105,7 @@ export class ScheduleListComponent implements OnInit { }; save(schedule: Schedule) { - return this.scheduleService.update(schedule).subscribe((schedule: Schedule) => { + return this.scheduleService.create(schedule).subscribe((schedule: Schedule) => { this.toastrService.success('Schedule #' + schedule.id + ' saved.'); this.load(); diff --git a/src/scheduler/scheduleRow.component.ts b/src/scheduler/scheduleRow.component.ts index 020ade3..9fd4809 100644 --- a/src/scheduler/scheduleRow.component.ts +++ b/src/scheduler/scheduleRow.component.ts @@ -63,7 +63,7 @@ export class ScheduleRowComponent { ) {} save(schedule: Schedule) { - return this.scheduleService.create(schedule).subscribe((schedule: Schedule) => { + return this.scheduleService.update(schedule).subscribe((schedule: Schedule) => { this.toastrService.success('Schedule #' + schedule.id + ' saved.'); this.needsReload.emit(); From cd7aba50e5fda362a95caf0771a69de02192aeb2 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 25 Jul 2017 17:26:26 +0200 Subject: [PATCH 098/222] Cleanup unused title definition. --- src/scheduler/scheduleRow.component.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/scheduler/scheduleRow.component.ts b/src/scheduler/scheduleRow.component.ts index 9fd4809..24f7c39 100644 --- a/src/scheduler/scheduleRow.component.ts +++ b/src/scheduler/scheduleRow.component.ts @@ -75,8 +75,6 @@ export class ScheduleRowComponent { } confirmDelete() { - var title = "Delete schedule #" + this.schedule.id; - const modal = this.ngbModal.open(ScheduleDeleteModalComponent, { windowClass: 'in' }); From b3d274eabf8cd0eb069ee140e2a64d40ed86b591 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 25 Jul 2017 22:08:18 +0200 Subject: [PATCH 099/222] Replace angular-ui-notifications by toastr. --- src/main.less | 1 - src/operations/index.ts | 10 ++++++++-- src/operations/operation.controller.ts | 10 +++++----- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/main.less b/src/main.less index dc244c4..3f83abc 100644 --- a/src/main.less +++ b/src/main.less @@ -1,6 +1,5 @@ @import '~font-awesome/less/font-awesome'; -@import '~angular-ui-notification/src/angular-ui-notification'; @import (inline) '~c3/c3.css'; diff --git a/src/operations/index.ts b/src/operations/index.ts index b4fe981..e096a00 100644 --- a/src/operations/index.ts +++ b/src/operations/index.ts @@ -22,9 +22,14 @@ var moment = require('moment'); var angular = require('angular'); +import { + downgradeInjectable, +} from '@angular/upgrade/static'; + +import { ToastrService } from 'ngx-toastr'; + var ngResource = require('angular-resource'), ngMessages = require('angular-messages'), - ngUiNotification = require('angular-ui-notification'), ngStrap = require('angular-strap'); var balanceChartModule = require('./balance-chart.component'), @@ -38,13 +43,14 @@ var OperationController = require('./operation.controller'); export default angular.module('accountant.operations', [ ngResource, ngMessages, - ngUiNotification, ngStrap, accountModule, balanceChartModule, categoryChartModule ]) + .factory('toastrService', downgradeInjectable(ToastrService)) + .factory('Operation', OperationFactory) .controller('OperationController', OperationController) diff --git a/src/operations/operation.controller.ts b/src/operations/operation.controller.ts index ea8dd7e..e294a08 100644 --- a/src/operations/operation.controller.ts +++ b/src/operations/operation.controller.ts @@ -1,7 +1,7 @@ var operationFormTmpl = require('./operation.form.tmpl.html'), operationDeleteTmpl = require('./operation.delete.tmpl.html'); -module.exports = function($stateParams, $modal, Notification, Operation, +module.exports = function($stateParams, $modal, toastrService, Operation, AccountService) { var vm = this; @@ -58,13 +58,13 @@ module.exports = function($stateParams, $modal, Notification, Operation, operation.confirmed = true; return operation.$save().then(function(operation) { - Notification.success('Operation #' + operation.id + ' saved.'); + toastrService.success('Operation #' + operation.id + ' saved.'); vm.operations = vm.load(); return operation; }, function(result){ - Notification.error( + toastrService.error( 'Error while saving operation: ' + result.message ); }); @@ -98,13 +98,13 @@ module.exports = function($stateParams, $modal, Notification, Operation, var id = operation.id; return operation.$delete().then(function() { - Notification.success('Operation #' + id + ' deleted.'); + toastrService.success('Operation #' + id + ' deleted.'); vm.operations = vm.load(); return operation; }, function(result) { - Notification.error( + toastrService.error( 'An error occurred while trying to delete operation #' + id + ':
' + result ); From 0e037e664f78447787af1d9be5018b2983401c0b Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 25 Jul 2017 22:11:16 +0200 Subject: [PATCH 100/222] Begin migration to bootstrap v4. --- package.json | 6 +----- src/accounts/accountList.component.ts | 10 +++++----- src/app.module.ts | 2 ++ src/app.ts | 2 -- src/index.ejs | 9 ++------- src/main.less | 21 +-------------------- src/operations/operations.html | 12 ++++++------ src/scheduler/scheduleList.component.ts | 16 ++++++++-------- src/scheduler/scheduleRow.component.ts | 2 +- webpack.config.js | 1 - 10 files changed, 26 insertions(+), 55 deletions(-) diff --git a/package.json b/package.json index c3741b3..9b2a2b6 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,6 @@ "babel-core": "^6.25.0", "babel-eslint": "^7.2.3", "babel-loader": "^7.1.1", - "bootstrap-webpack": "^0.0.6", "css-loader": "^0.28.4", "eslint": "^4.3.0", "eslint-config-angular": "^0.5.0", @@ -57,12 +56,9 @@ "angular-messages": "^1.6.5", "angular-resource": "^1.6.5", "angular-strap": "^2.3.12", - "angular-ui-notification": "^0.3.6", - "angular2-notifications": "^0.7.4", "base64util": "^1.0.2", "bootbox": "^4.4.0", - "bootstrap": "^3.3.7", - "bootstrap-additions": "^0.3.1", + "bootstrap": "4.0.0-alpha.6", "c3": "^0.4.15", "font-awesome": "^4.7.0", "jquery": "^3.2.1", diff --git a/src/accounts/accountList.component.ts b/src/accounts/accountList.component.ts index 622fed5..7ffe65c 100644 --- a/src/accounts/accountList.component.ts +++ b/src/accounts/accountList.component.ts @@ -15,14 +15,14 @@ import { AccountEditModalComponent } from './accountEditModal.component'; selector: 'account-list', template: `
- +
- - - - + + + + diff --git a/src/app.module.ts b/src/app.module.ts index dc3f915..ea4f6bc 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -2,6 +2,8 @@ import 'zone.js'; import 'reflect-metadata'; +require('./main.less'); + import { AppModule as Ng1AppModule } from './app'; import { NgModule } from '@angular/core'; diff --git a/src/app.ts b/src/app.ts index 2e003e7..de46970 100644 --- a/src/app.ts +++ b/src/app.ts @@ -31,8 +31,6 @@ import loginModule from '@accountant/login'; import operationModule from '@accountant/operations'; import schedulerModule from '@accountant/scheduler'; -require('bootstrap-webpack!./bootstrap.config.ts'); - export const AppModule = angular.module('accountant', [ uiRouter, accountModule, diff --git a/src/index.ejs b/src/index.ejs index 534a0d5..2292ec3 100644 --- a/src/index.ejs +++ b/src/index.ejs @@ -29,13 +29,8 @@ -
Nom du compteSolde courantSolde pointéDécouvert autoriséActionsSolde courantSolde pointéDécouvert autoriséActions
- + - - - - + + + + @@ -50,7 +50,7 @@ - diff --git a/src/scheduler/scheduleList.component.ts b/src/scheduler/scheduleList.component.ts index 23dc281..244c594 100644 --- a/src/scheduler/scheduleList.component.ts +++ b/src/scheduler/scheduleList.component.ts @@ -15,17 +15,17 @@ var scheduleFormTmpl = require('./schedule.form.tmpl.html'); selector: 'schedule-list', template: `
-
Date d'op.Date d'op. Libellé de l'opérationMontantSoldeCatégorieActionsMontantSoldeCatégorieActions
+
- - - - + + + + - - - + + + diff --git a/src/scheduler/scheduleRow.component.ts b/src/scheduler/scheduleRow.component.ts index 24f7c39..02ce9c3 100644 --- a/src/scheduler/scheduleRow.component.ts +++ b/src/scheduler/scheduleRow.component.ts @@ -17,7 +17,7 @@ import { Schedule } from './schedule'; "[id]": "schedule.id", }, template: ` - + diff --git a/webpack.config.js b/webpack.config.js index c751891..f4861cd 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -44,7 +44,6 @@ module.exports = { enforce: 'pre', test: /\.jsx?$/, //include: path.resolve(__dirname, 'src'), - exclude: /(node_modules|bootstrap)/, loader: 'eslint-loader', options: { useEslintrc: false, From 931ef38f2900492d469739612a67d6dff0025f8c Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 25 Jul 2017 23:29:16 +0200 Subject: [PATCH 101/222] Fix button sizes and styles. --- src/accounts/accountRow.component.ts | 6 +-- src/bootstrap.config.less | 3 -- src/bootstrap.config.ts | 64 -------------------------- src/operations/operations.html | 10 ++-- src/scheduler/scheduleRow.component.ts | 6 +-- 5 files changed, 11 insertions(+), 78 deletions(-) delete mode 100644 src/bootstrap.config.less delete mode 100644 src/bootstrap.config.ts diff --git a/src/accounts/accountRow.component.ts b/src/accounts/accountRow.component.ts index 94aa5b4..4e224d3 100644 --- a/src/accounts/accountRow.component.ts +++ b/src/accounts/accountRow.component.ts @@ -40,7 +40,7 @@ import { AccountEditModalComponent } from './accountEditModal.component'; + + + + + + + + + + + ` +}) +export class OperationRowComponent { + @Input() operation: Operation; + @Output() needsReload: EventEmitter = new EventEmitter(); + + constructor( + private operationService: OperationService, + private toastrService: ToastrService, + @Inject('$modal') private $modal, + ) {} + + togglePointed(operation, rowform) { + operation.pointed = !operation.pointed; + + this.save(operation); + }; + + toggleCanceled(operation) { + operation.canceled = !operation.canceled; + + this.save(operation); + }; + + save(operation) { + return this.operationService.update(operation).subscribe((operation) => { + operation.confirmed = true; + + this.toastrService.success('Operation #' + operation.id + ' saved.'); + + this.needsReload.emit(); + }, (result) => { + this.toastrService.error( + 'Error while saving operation: ' + result.message + ); + }); + } + + confirmDelete(operation) { + var title = "Delete operation #" + operation.id; + + this.$modal({ + templateUrl: operationDeleteTmpl, + controller: function($scope, title, operation, $delete) { + $scope.title = title; + $scope.operation = operation; + $scope.$delete = () => { + $scope.$hide(); + $delete($scope.operation); + }; + }, + locals: { + title: title, + operation: operation, + $delete: (operation: Operation) => { + this.delete(operation); + } + } + }); + }; + + delete(operation) { + var id = operation.id; + + return this.operationService.delete(operation).subscribe(() => { + this.toastrService.success('Operation #' + id + ' deleted.'); + + this.needsReload.emit(); + }, (result) => { + this.toastrService.error( + 'An error occurred while trying to delete operation #' + + id + ':
' + result + ); + }); + }; + + modify(operation) { + // FIXME Alexis Lahouze 2017-06-15 i18n + var title = "Modify operation #" + operation.id; + + this.$modal({ + templateUrl: operationFormTmpl, + controller: function($scope, title, operation, $save) { + $scope.title = title; + $scope.operation = operation; + $scope.$save = () => { + $scope.$hide(); + $save($scope.operation); + }; + }, + locals: { + title: title, + operation: operation, + $save: (operation: Operation) => { + this.save(operation); + } + } + }); + }; +} From b7c2d94c6288c0d37fc317d4b8e078f7237951a5 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 15:12:57 +0200 Subject: [PATCH 150/222] Fix Operation Row component. --- src/operations/operationRow.component.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/operations/operationRow.component.ts b/src/operations/operationRow.component.ts index e97e1f6..9afe471 100644 --- a/src/operations/operationRow.component.ts +++ b/src/operations/operationRow.component.ts @@ -17,7 +17,8 @@ import { OperationService } from './operation.service'; "[id]": "operation.id", "[class.stroke]": "operation.canceled", "[class.italic]": "!operation.confirmed", - "[class.warning]": "operation.balance < 0, danger: operation.balance < operationsCtrl.account.authorized_overdraft" + "[class.warning]": "operation.balance < 0", + "[class.danger]": "operation.balance < account.authorized_overdraft" }, template: `
@@ -37,14 +38,14 @@ import { OperationService } from './operation.service';
@@ -70,7 +71,8 @@ import { OperationService } from './operation.service'; ` }) export class OperationRowComponent { - @Input() operation: Operation; + @Input('operation-row') operation: Operation; + @Input() account: Account; @Output() needsReload: EventEmitter = new EventEmitter(); constructor( From 129c9f9ee30c1ca36b825855d21f1fb98c2bdb8d Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 15:13:36 +0200 Subject: [PATCH 151/222] Upgrade Operation controller. --- src/operations/index.ts | 16 +-- src/operations/operation.controller.ts | 137 +++++++++++-------------- src/operations/operation.module.ts | 3 + src/operations/operation.states.ts | 6 +- 4 files changed, 67 insertions(+), 95 deletions(-) diff --git a/src/operations/index.ts b/src/operations/index.ts index b34c81e..140ca28 100644 --- a/src/operations/index.ts +++ b/src/operations/index.ts @@ -44,18 +44,8 @@ export default angular.module('accountant.operations', [ accountModule, ]) - .factory('toastrService', downgradeInjectable(ToastrService)) - - .factory('operationService', downgradeInjectable(OperationService)) - - .controller('OperationController', OperationController) - - .directive('balanceChart', downgradeComponent({ - component: BalanceChartComponent - }) as angular.IDirectiveFactory) - - .directive('categoryChart', downgradeComponent({ - component: CategoryChartComponent - }) as angular.IDirectiveFactory) + .directive('operationListComponent', downgradeComponent({ + component: OperationController + })) .name; diff --git a/src/operations/operation.controller.ts b/src/operations/operation.controller.ts index 9077cf2..4dc0c5e 100644 --- a/src/operations/operation.controller.ts +++ b/src/operations/operation.controller.ts @@ -11,20 +11,72 @@ import { AccountService } from '../accounts/account.service'; import { Operation } from './operation'; import { OperationService } from './operation.service'; -export class OperationController { +@Component({ + selector: 'operation-list', + template: ` +
+
+
+ +
+
+ +
+
+ +
+
Date de débutDate de finJourFréq.Date de débutDate de finJourFréq. Libellé de l'opérationMontantCatégorieActionsMontantCatégorieActions
{{ schedule.start_date | date: "yyyy-MM-dd" }}{{ schedule.start_date | date: "yyyy-MM-dd" }} {{ schedule.stop_date | date: "yyyy-MM-dd" }}{{ account.authorized_overdraft | currency:"EUR":true }} -
+
- - diff --git a/src/bootstrap.config.less b/src/bootstrap.config.less deleted file mode 100644 index f2d357b..0000000 --- a/src/bootstrap.config.less +++ /dev/null @@ -1,3 +0,0 @@ -@pre-border-color: @pre-bg; // hide the border. - -@import "./main.less"; diff --git a/src/bootstrap.config.ts b/src/bootstrap.config.ts deleted file mode 100644 index bcd24eb..0000000 --- a/src/bootstrap.config.ts +++ /dev/null @@ -1,64 +0,0 @@ -/* jshint node: true */ -'use strict'; - -module.exports = { - scripts: { - 'transition': true, - 'alert': true, - 'button': true, - 'carousel': true, - 'collapse': true, - 'dropdown': true, - 'modal': true, - 'tooltip': true, - 'popover': true, - 'scrollspy': true, - 'tab': true, - 'affix': true - }, - - styles: { - 'mixins': true, - - 'normalize': true, - 'print': true, - - 'scaffolding': true, - 'type': true, - 'code': true, - 'grid': true, - 'tables': true, - 'forms': true, - 'buttons': true, - - 'component-animations': true, - 'glyphicons': true, - 'dropdowns': true, - 'button-groups': true, - 'input-groups': true, - 'navs': true, - 'navbar': true, - 'breadcrumbs': true, - 'pagination': true, - 'pager': true, - 'labels': true, - 'badges': true, - 'jumbotron': true, - 'thumbnails': true, - 'alerts': true, - 'progress-bars': true, - 'media': true, - 'list-group': true, - 'panels': true, - 'wells': true, - 'close': true, - - 'modals': true, - 'tooltip': true, - 'popovers': true, - 'carousel': true, - - 'utilities': true, - 'responsive-utilities': true - } -}; diff --git a/src/operations/operations.html b/src/operations/operations.html index aceab41..4989849 100644 --- a/src/operations/operations.html +++ b/src/operations/operations.html @@ -76,16 +76,16 @@
-
+
- - - -
{{ schedule.category }} -
+
- -
@@ -25,8 +24,7 @@ import { Schedule } from './schedule';
@@ -78,6 +76,8 @@ export class ScheduleFormComponent implements AfterViewChecked { @Output() onValid: EventEmitter = new EventEmitter(); @ViewChild('form') form: NgForm; + dateMask = ['2', '0', /\d/, /\d/, '-', /[0-1]/, /\d/, '-', /[0-3]/, /\d/]; + constructor() {} ngAfterViewChecked() { From 3363cf682ae2215f1170884612355ff67fa12ad2 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Wed, 26 Jul 2017 23:09:55 +0200 Subject: [PATCH 103/222] Fix Schedule field types. --- src/scheduler/schedule.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/scheduler/schedule.ts b/src/scheduler/schedule.ts index 300310a..57a9a47 100644 --- a/src/scheduler/schedule.ts +++ b/src/scheduler/schedule.ts @@ -2,8 +2,8 @@ export class Schedule { id: number; - start_date: Date; - stop_date: Date; + start_date: string; + stop_date: string; day: number; frequency: number; label: string; From b7c44a39dacab3808f028c75928f396307632d82 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Wed, 26 Jul 2017 23:10:21 +0200 Subject: [PATCH 104/222] Style. --- src/scheduler/scheduleForm.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scheduler/scheduleForm.component.ts b/src/scheduler/scheduleForm.component.ts index 179d740..2a4e9d8 100644 --- a/src/scheduler/scheduleForm.component.ts +++ b/src/scheduler/scheduleForm.component.ts @@ -71,7 +71,7 @@ import { Schedule } from './schedule'; ` }) -export class ScheduleFormComponent implements AfterViewChecked { +export class ScheduleFormComponent implements AfterViewChecked { @Input() schedule: Schedule; @Output() onValid: EventEmitter = new EventEmitter(); @ViewChild('form') form: NgForm; From fab48803894e0a0424503bcb8f56ae57c613a608 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Wed, 26 Jul 2017 23:12:03 +0200 Subject: [PATCH 105/222] Add format in date field labels. --- src/scheduler/scheduleForm.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/scheduler/scheduleForm.component.ts b/src/scheduler/scheduleForm.component.ts index 2a4e9d8..f887594 100644 --- a/src/scheduler/scheduleForm.component.ts +++ b/src/scheduler/scheduleForm.component.ts @@ -12,7 +12,7 @@ import { Schedule } from './schedule'; template: `
- +
- +
Date: Thu, 27 Jul 2017 00:32:38 +0200 Subject: [PATCH 106/222] Move accountId retrieving into account module. --- src/accounts/index.ts | 25 ++++++++++++++++++++++++- src/scheduler/index.ts | 26 ++++---------------------- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/accounts/index.ts b/src/accounts/index.ts index 0811f3f..29022cd 100644 --- a/src/accounts/index.ts +++ b/src/accounts/index.ts @@ -25,10 +25,27 @@ import { downgradeComponent } from '@angular/upgrade/static'; +import uiRouter from '@uirouter/angularjs'; + import { AccountService } from './account.service'; import { AccountListComponent } from './accountList.component'; -export default angular.module('accountant.accounts', []) +export default angular.module('accountant.accounts', [ + uiRouter +]) + + .factory('accountIdService', function() { + var accountId: null; + + return { + get: () => { + return accountId; + }, + set: (value) => { + accountId = value; + } + } + }) .factory('AccountService', downgradeInjectable(AccountService)) @@ -36,4 +53,10 @@ export default angular.module('accountant.accounts', []) component: AccountListComponent })) + .run(function($transitions, accountIdService) { + $transitions.onSuccess({}, (transition) => { + accountIdService.set(transition.params().accountId); + }); + }) + .name; diff --git a/src/scheduler/index.ts b/src/scheduler/index.ts index 957c965..53cf72f 100644 --- a/src/scheduler/index.ts +++ b/src/scheduler/index.ts @@ -30,14 +30,15 @@ import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { ToastrService } from 'ngx-toastr'; var ngStrap = require('angular-strap'); -import uiRouter from '@uirouter/angularjs'; + +import accountModule from '@accountant/accounts'; import { ScheduleListComponent } from './scheduleList.component'; import { ScheduleService } from './schedule.service'; export default angular.module('accountant.scheduler', [ - uiRouter, - ngStrap + ngStrap, + accountModule ]) .factory('toastrService', downgradeInjectable(ToastrService)) @@ -45,29 +46,10 @@ export default angular.module('accountant.scheduler', [ .factory('logger', downgradeInjectable(Logger)) - .factory('accountIdService', function() { - var accountId: null; - - return { - get: () => { - return accountId; - }, - set: (value) => { - accountId = value; - } - } - }) - .factory('scheduleService', downgradeInjectable(ScheduleService)) .directive('scheduleListComponent', downgradeComponent({ component: ScheduleListComponent })) - .run(function($transitions, accountIdService) { - $transitions.onSuccess({}, (transition) => { - accountIdService.set(transition.params().accountId); - }); - }) - .name; From 2d50ad8a0b9ebbe2eb122a36923f7040cd2535d4 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Thu, 27 Jul 2017 00:35:11 +0200 Subject: [PATCH 107/222] Remove uneeded dependency. --- package.json | 1 - src/operations/index.ts | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/package.json b/package.json index a3cf95a..bd502b0 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,6 @@ "@uirouter/core": "^5.0.5", "angular": "^1.6.5", "angular-http-auth": "^1.5.0", - "angular-messages": "^1.6.5", "angular-resource": "^1.6.5", "angular-strap": "^2.3.12", "angular2-text-mask": "^8.0.2", diff --git a/src/operations/index.ts b/src/operations/index.ts index e096a00..7274179 100644 --- a/src/operations/index.ts +++ b/src/operations/index.ts @@ -24,12 +24,12 @@ var angular = require('angular'); import { downgradeInjectable, + downgradeComponent } from '@angular/upgrade/static'; import { ToastrService } from 'ngx-toastr'; var ngResource = require('angular-resource'), - ngMessages = require('angular-messages'), ngStrap = require('angular-strap'); var balanceChartModule = require('./balance-chart.component'), @@ -42,7 +42,6 @@ var OperationController = require('./operation.controller'); export default angular.module('accountant.operations', [ ngResource, - ngMessages, ngStrap, accountModule, balanceChartModule, From c0b236ff6c4ffa55bb305907a0edbb2821da5087 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Thu, 27 Jul 2017 00:41:07 +0200 Subject: [PATCH 108/222] Use accountIdService to retrieve current Account Id. --- src/accounts/index.ts | 2 +- src/operations/balance-chart.component.ts | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/accounts/index.ts b/src/accounts/index.ts index 29022cd..d1d67cb 100644 --- a/src/accounts/index.ts +++ b/src/accounts/index.ts @@ -54,7 +54,7 @@ export default angular.module('accountant.accounts', [ })) .run(function($transitions, accountIdService) { - $transitions.onSuccess({}, (transition) => { + $transitions.onEnter({}, (transition) => { accountIdService.set(transition.params().accountId); }); }) diff --git a/src/operations/balance-chart.component.ts b/src/operations/balance-chart.component.ts index 4c79f5e..082480d 100644 --- a/src/operations/balance-chart.component.ts +++ b/src/operations/balance-chart.component.ts @@ -25,8 +25,11 @@ var angular = require('angular'); var ngResource = require('angular-resource'); +import accountModule from '@accountant/accounts'; + module.exports = angular.module('balanceChartModule', [ - ngResource + ngResource, + accountModule ]) .component('balanceChart', { @@ -35,12 +38,12 @@ module.exports = angular.module('balanceChartModule', [ account: '<', onUpdate: '&' }, - controller: function($stateParams, Balances, $element) { + controller: function(accountIdService, Balances, $element) { var vm = this; vm.loadData = function() { Balances.query({ - id: $stateParams.accountId + id: accountIdService.get() }, function(results) { var headers = [['date', 'balances', 'expenses', 'revenues']]; From d8adfd91c5500f349fef58416553ebe81db2ba0c Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Thu, 27 Jul 2017 01:00:33 +0200 Subject: [PATCH 109/222] Add Daily Balance service. --- src/accounts/account.module.ts | 2 ++ src/accounts/dailyBalance.service.ts | 19 +++++++++++++++++++ src/accounts/dailyBalance.ts | 8 ++++++++ src/accounts/index.ts | 3 +++ 4 files changed, 32 insertions(+) create mode 100644 src/accounts/dailyBalance.service.ts create mode 100644 src/accounts/dailyBalance.ts diff --git a/src/accounts/account.module.ts b/src/accounts/account.module.ts index bde0c86..cd1917a 100644 --- a/src/accounts/account.module.ts +++ b/src/accounts/account.module.ts @@ -17,6 +17,7 @@ import { AccountDeleteModalComponent } from './accountDeleteModal.component'; import { AccountEditModalComponent } from './accountEditModal.component'; import { AccountFormComponent } from './accountForm.component'; import { AccountRowComponent } from './accountRow.component'; +import { DailyBalanceService } from './dailyBalance.service'; @NgModule({ imports: [ @@ -31,6 +32,7 @@ import { AccountRowComponent } from './accountRow.component'; providers: [ AccountService, AccountBalancesService, + DailyBalanceService, ], declarations: [ AccountListComponent, diff --git a/src/accounts/dailyBalance.service.ts b/src/accounts/dailyBalance.service.ts new file mode 100644 index 0000000..1751613 --- /dev/null +++ b/src/accounts/dailyBalance.service.ts @@ -0,0 +1,19 @@ +// vim: set tw=80 ts=2 sw=2 sts=2: + +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs/Rx'; + +import { Restangular } from "ngx-restangular"; + +import { DailyBalance } from './dailyBalance'; + +@Injectable() +export class DailyBalanceService { + constructor( + private restangular: Restangular + ) {} + + query(id: number): Observable { + return this.restangular.one('account', id).one('daily_balances').getList(); + } +} diff --git a/src/accounts/dailyBalance.ts b/src/accounts/dailyBalance.ts new file mode 100644 index 0000000..68c3669 --- /dev/null +++ b/src/accounts/dailyBalance.ts @@ -0,0 +1,8 @@ +// vim: set tw=80 ts=2 sw=2 sts=2 : + +export class DailyBalance { + operation_date: string; + balance: number; + expenses: number; + revenues: number; +} diff --git a/src/accounts/index.ts b/src/accounts/index.ts index d1d67cb..553182b 100644 --- a/src/accounts/index.ts +++ b/src/accounts/index.ts @@ -29,6 +29,7 @@ import uiRouter from '@uirouter/angularjs'; import { AccountService } from './account.service'; import { AccountListComponent } from './accountList.component'; +import { DailyBalanceService } from './dailyBalance.service'; export default angular.module('accountant.accounts', [ uiRouter @@ -49,6 +50,8 @@ export default angular.module('accountant.accounts', [ .factory('AccountService', downgradeInjectable(AccountService)) + .factory('DailyBalanceService', downgradeInjectable(DailyBalanceService)) + .directive('accountList', downgradeComponent({ component: AccountListComponent })) From 64c53441cb31d67d8d4c92383d0bb53c3d752648 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Thu, 27 Jul 2017 01:02:02 +0200 Subject: [PATCH 110/222] Use Daily Balance service in Balance Chart component. --- src/operations/balance-chart.component.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/operations/balance-chart.component.ts b/src/operations/balance-chart.component.ts index 082480d..7b5c920 100644 --- a/src/operations/balance-chart.component.ts +++ b/src/operations/balance-chart.component.ts @@ -38,13 +38,13 @@ module.exports = angular.module('balanceChartModule', [ account: '<', onUpdate: '&' }, - controller: function(accountIdService, Balances, $element) { + controller: function(accountIdService, DailyBalanceService, $element) { var vm = this; vm.loadData = function() { - Balances.query({ - id: accountIdService.get() - }, function(results) { + DailyBalanceService.query( + accountIdService.get() + ).subscribe(function(results) { var headers = [['date', 'balances', 'expenses', 'revenues']]; var rows = results.map(function(result) { From c0bc7b82b3f8d0fddb49a2498b78f28eab5415ba Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Thu, 27 Jul 2017 01:07:27 +0200 Subject: [PATCH 111/222] Remove unused Balances factory. --- src/operations/balance-chart.component.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/operations/balance-chart.component.ts b/src/operations/balance-chart.component.ts index 7b5c920..d273aae 100644 --- a/src/operations/balance-chart.component.ts +++ b/src/operations/balance-chart.component.ts @@ -179,12 +179,4 @@ module.exports = angular.module('balanceChartModule', [ } }) - .factory('Balances', function($resource) { - return $resource( - '/api/account/:id/daily_balances', { - id: '@id' - } - ); - }) - .name; From ac0aa056cfd9eb12a2bba69498eb788f5b8dbf3b Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Thu, 27 Jul 2017 13:55:30 +0200 Subject: [PATCH 112/222] Fix DailyBalanceService query return type. --- src/accounts/dailyBalance.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/accounts/dailyBalance.service.ts b/src/accounts/dailyBalance.service.ts index 1751613..8c41dcf 100644 --- a/src/accounts/dailyBalance.service.ts +++ b/src/accounts/dailyBalance.service.ts @@ -13,7 +13,7 @@ export class DailyBalanceService { private restangular: Restangular ) {} - query(id: number): Observable { + query(id: number): Observable { return this.restangular.one('account', id).one('daily_balances').getList(); } } From 863160881f6c7e0570a2b12ee92f07b0fcdc2437 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Thu, 27 Jul 2017 13:57:40 +0200 Subject: [PATCH 113/222] Initialize Operation module. --- src/app.module.ts | 3 +++ src/operations/operation.module.ts | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 src/operations/operation.module.ts diff --git a/src/app.module.ts b/src/app.module.ts index ea4f6bc..b7af799 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -18,6 +18,8 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { AccountModule } from './accounts/account.module'; import { ScheduleModule } from './scheduler/schedule.module'; +import { OperationModule } from './operations/operation.module'; + import { ApiBaseURL, LogLevel } from './app.config'; @NgModule({ @@ -27,6 +29,7 @@ import { ApiBaseURL, LogLevel } from './app.config'; UpgradeModule, AccountModule, ScheduleModule, + OperationModule, NgLoggerModule.forRoot(LogLevel), RestangularModule.forRoot((RestangularProvider) => { RestangularProvider.setBaseUrl(ApiBaseURL); diff --git a/src/operations/operation.module.ts b/src/operations/operation.module.ts new file mode 100644 index 0000000..b30080d --- /dev/null +++ b/src/operations/operation.module.ts @@ -0,0 +1,20 @@ +// vim: set tw=80 ts=2 sw=2 sts=2 : + +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { HttpModule } from '@angular/http'; + +import { NgLoggerModule, Level } from '@nsalaun/ng-logger'; +import { RestangularModule } from 'ngx-restangular'; + +@NgModule({ + imports: [ + HttpModule, + CommonModule, + FormsModule, + NgLoggerModule, + RestangularModule, + ], +}) +export class OperationModule {} From 003b4de822ba0ae3149156128014e8de9b047e49 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Thu, 27 Jul 2017 14:03:39 +0200 Subject: [PATCH 114/222] Upgrade Balance Chart component to Angular2. --- package.json | 1 + src/operations/balance-chart.component.ts | 119 ++++++++++++++-------- src/operations/index.ts | 14 +-- src/operations/operation.controller.ts | 6 +- src/operations/operations.html | 4 +- 5 files changed, 92 insertions(+), 52 deletions(-) diff --git a/package.json b/package.json index bd502b0..0fb07bd 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "@ng-bootstrap/ng-bootstrap": "^1.0.0-alpha.28", "@nsalaun/ng-logger": "^2.0.1", "@types/angular": "^1.6.27", + "@types/c3": "^0.4.44", "@types/node": "^8.0.16", "@uirouter/angularjs": "^1.0.5", "@uirouter/core": "^5.0.5", diff --git a/src/operations/balance-chart.component.ts b/src/operations/balance-chart.component.ts index d273aae..3ef68b6 100644 --- a/src/operations/balance-chart.component.ts +++ b/src/operations/balance-chart.component.ts @@ -18,34 +18,56 @@ /* jshint node: true */ 'use strict'; -var moment = require('moment'), - c3 = require('c3'); +import * as moment from 'moment'; +import * as c3 from 'c3'; -var angular = require('angular'); +import { + Component, ElementRef, + Inject, Input, Output, EventEmitter, + OnInit, OnChanges +} from '@angular/core'; -var ngResource = require('angular-resource'); +import { Logger } from '@nsalaun/ng-logger'; -import accountModule from '@accountant/accounts'; +import { Account } from '../accounts/account'; +import { DailyBalanceService } from '../accounts/dailyBalance.service'; -module.exports = angular.module('balanceChartModule', [ - ngResource, - accountModule -]) +class DateRange { + minDate: Date; + maxDate: Date; +} - .component('balanceChart', { - template: '
', - bindings: { - account: '<', - onUpdate: '&' - }, - controller: function(accountIdService, DailyBalanceService, $element) { - var vm = this; +class xAxis { + balances: Date[]; + expenses: Date[]; + revenues: Date[]; +} - vm.loadData = function() { - DailyBalanceService.query( - accountIdService.get() - ).subscribe(function(results) { - var headers = [['date', 'balances', 'expenses', 'revenues']]; +@Component({ + selector: 'balance-chart', + template: '
' +}) +export class BalanceChartComponent implements OnInit, OnChanges { + @Input() account: Account; + @Output() onUpdate: EventEmitter = new EventEmitter(); + + private chart: c3.ChartAPI; + private balances: number[]; + + constructor( + private elementRef: ElementRef, + private logger: Logger, + private dailyBalanceService: DailyBalanceService, + @Inject('accountIdService') private accountIdService, + ) { + this.logger.log("Constructor BalanceChartComponent") + } + + loadData() { + this.dailyBalanceService.query( + this.accountIdService.get() + ).subscribe((results) => { + var headers: any[][] = [['date', 'balances', 'expenses', 'revenues']]; var rows = results.map(function(result) { return [ @@ -56,24 +78,36 @@ module.exports = angular.module('balanceChartModule', [ ]; }); - vm.chart.unload(); + this.chart.unload(); - vm.chart.load({ + this.chart.load({ rows: headers.concat(rows) }); - var x = vm.chart.x(); + var x: any; + + x = this.chart.x(); + + this.logger.log("x", x); + var balances = x.balances; - vm.onUpdate(balances[0], balances[balances.length - 1]); + this.onUpdate.emit({ + minDate: balances[0], + maxDate: balances[balances.length - 1] + }); }); }; - vm.$onInit = function() { + $onInit() { + this.ngOnInit(); + } + + ngOnInit() { var tomorrow = moment().endOf('day').valueOf(); - vm.chart = c3.generate({ - bindto: $element[0].children[0], + this.chart = c3.generate({ + bindto: this.elementRef.nativeElement.children[0], size: { height: 450, }, @@ -144,23 +178,23 @@ module.exports = angular.module('balanceChartModule', [ subchart: { show: true, onbrush: function(domain) { - vm.onUpdate({minDate: domain[0], maxDate: domain[1]}); + this.onUpdate.emit({minDate: domain[0], maxDate: domain[1]}); } } }); - vm.loadData(); + this.loadData(); }; - vm.setLines = function(account) { - if(vm.chart) { - vm.chart.ygrids([ + setLines(account: Account) { + if(this.chart) { + this.chart.ygrids([ { value: 0, axis: 'y2' }, { value: 0, axis: 'y', class: 'zeroline'}, ]); if(account) { - vm.chart.ygrids.add({ + this.chart.ygrids.add({ value: account.authorized_overdraft, axis: 'y', class: 'overdraft' @@ -169,14 +203,15 @@ module.exports = angular.module('balanceChartModule', [ } }; - vm.$onChanges = function(changes) { + $onChanges(changes) { + this.ngOnChanges(changes); + } + + ngOnChanges(changes) { if('account' in changes) { - vm.setLines(changes.account.currentValue); + this.setLines(changes.account.currentValue); } else { - vm.setLines(vm.account); + this.setLines(this.account); } }; - } - }) - - .name; +} diff --git a/src/operations/index.ts b/src/operations/index.ts index 7274179..bba2ba4 100644 --- a/src/operations/index.ts +++ b/src/operations/index.ts @@ -18,9 +18,7 @@ /* jshint node: true */ 'use strict'; -var moment = require('moment'); - -var angular = require('angular'); +import * as angular from 'angular'; import { downgradeInjectable, @@ -32,11 +30,12 @@ import { ToastrService } from 'ngx-toastr'; var ngResource = require('angular-resource'), ngStrap = require('angular-strap'); -var balanceChartModule = require('./balance-chart.component'), - categoryChartModule = require('./category-chart.component'); +var categoryChartModule = require('./category-chart.component'); import accountModule from '@accountant/accounts'; +import { BalanceChartComponent } from './balance-chart.component'; + var OperationFactory = require('./operation.factory'); var OperationController = require('./operation.controller'); @@ -44,7 +43,6 @@ export default angular.module('accountant.operations', [ ngResource, ngStrap, accountModule, - balanceChartModule, categoryChartModule ]) @@ -54,4 +52,8 @@ export default angular.module('accountant.operations', [ .controller('OperationController', OperationController) + .directive('balanceChart', downgradeComponent({ + component: BalanceChartComponent + }) as angular.IDirectiveFactory) + .name; diff --git a/src/operations/operation.controller.ts b/src/operations/operation.controller.ts index e294a08..d8bf2d3 100644 --- a/src/operations/operation.controller.ts +++ b/src/operations/operation.controller.ts @@ -1,3 +1,5 @@ +import * as moment from 'moment'; + var operationFormTmpl = require('./operation.form.tmpl.html'), operationDeleteTmpl = require('./operation.delete.tmpl.html'); @@ -141,8 +143,8 @@ module.exports = function($stateParams, $modal, toastrService, Operation, }); }; - vm.onUpdate = function(minDate, maxDate) { - vm.operations = vm.load(minDate, maxDate); + vm.onUpdate = function(dateRange) { + vm.operations = vm.load(dateRange.minDate, dateRange.maxDate); }; AccountService.get($stateParams.accountId).subscribe(account => { diff --git a/src/operations/operations.html b/src/operations/operations.html index 4989849..a53afa7 100644 --- a/src/operations/operations.html +++ b/src/operations/operations.html @@ -18,8 +18,8 @@
- +
Date: Thu, 27 Jul 2017 14:08:11 +0200 Subject: [PATCH 115/222] Cleanup, indent. --- src/operations/balance-chart.component.ts | 362 ++++++++++------------ 1 file changed, 172 insertions(+), 190 deletions(-) diff --git a/src/operations/balance-chart.component.ts b/src/operations/balance-chart.component.ts index 3ef68b6..0796503 100644 --- a/src/operations/balance-chart.component.ts +++ b/src/operations/balance-chart.component.ts @@ -1,30 +1,12 @@ -// vim: set tw=80 ts=4 sw=4 sts=4: -/* - This file is part of Accountant. - - Accountant is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Accountant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with Accountant. If not, see . - */ -/* jshint node: true */ -'use strict'; +// vim: set tw=80 ts=2 sw=2 sts=2: import * as moment from 'moment'; import * as c3 from 'c3'; import { - Component, ElementRef, - Inject, Input, Output, EventEmitter, - OnInit, OnChanges + Component, ElementRef, + Inject, Input, Output, EventEmitter, + OnInit, OnChanges } from '@angular/core'; import { Logger } from '@nsalaun/ng-logger'; @@ -33,185 +15,185 @@ import { Account } from '../accounts/account'; import { DailyBalanceService } from '../accounts/dailyBalance.service'; class DateRange { - minDate: Date; - maxDate: Date; + minDate: Date; + maxDate: Date; } class xAxis { - balances: Date[]; - expenses: Date[]; - revenues: Date[]; + balances: Date[]; + expenses: Date[]; + revenues: Date[]; } @Component({ - selector: 'balance-chart', - template: '
' + selector: 'balance-chart', + template: '
' }) export class BalanceChartComponent implements OnInit, OnChanges { - @Input() account: Account; - @Output() onUpdate: EventEmitter = new EventEmitter(); + @Input() account: Account; + @Output() onUpdate: EventEmitter = new EventEmitter(); - private chart: c3.ChartAPI; - private balances: number[]; + private chart: c3.ChartAPI; + private balances: number[]; - constructor( - private elementRef: ElementRef, - private logger: Logger, - private dailyBalanceService: DailyBalanceService, - @Inject('accountIdService') private accountIdService, - ) { - this.logger.log("Constructor BalanceChartComponent") + constructor( + private elementRef: ElementRef, + private logger: Logger, + private dailyBalanceService: DailyBalanceService, + @Inject('accountIdService') private accountIdService, + ) { + this.logger.log("Constructor BalanceChartComponent") + } + + loadData() { + this.dailyBalanceService.query( + this.accountIdService.get() + ).subscribe((results) => { + var headers: any[][] = [['date', 'balances', 'expenses', 'revenues']]; + + var rows = results.map(function(result) { + return [ + result.operation_date, + result.balance, + result.expenses, + result.revenues + ]; + }); + + this.chart.unload(); + + this.chart.load({ + rows: headers.concat(rows) + }); + + var x: any; + + x = this.chart.x(); + + this.logger.log("x", x); + + var balances = x.balances; + + this.onUpdate.emit({ + minDate: balances[0], + maxDate: balances[balances.length - 1] + }); + }); + }; + + $onInit() { + this.ngOnInit(); + } + + ngOnInit() { + var tomorrow = moment().endOf('day').valueOf(); + + this.chart = c3.generate({ + bindto: this.elementRef.nativeElement.children[0], + size: { + height: 450, + }, + data: { + x: 'date', + rows: [], + axes: { + expenses: 'y2', + revenues: 'y2' + }, + type: 'bar', + types: { + balances: 'area' + }, + groups: [ + ['expenses', 'revenues'] + ], + // Disable for the moment because there is an issue when + // using subchart line is not refreshed after subset + // selection. + //regions: { + // balances: [{ + // start: tomorrow, + // style: 'dashed' + // }] + //} + }, + regions: [{ + start: tomorrow, + }], + axis: { + x: { + type: 'timeseries', + tick: { + format: '%Y-%m-%d', + rotate: 50, + } + }, + y: { + label: { + text: 'Amount', + position: 'outer-middle' + } + }, + y2: { + show: true, + label: { + text: 'Amount', + position: 'outer-middle' + } + } + }, + grid: { + x: { + show: true, + }, + y: { + show: true, + } + }, + tooltip: { + format: { + value: function(value, ratio, id, index) { + return value + '€'; + } + } + }, + subchart: { + show: true, + onbrush: function(domain) { + this.onUpdate.emit({minDate: domain[0], maxDate: domain[1]}); + } + } + }); + + this.loadData(); + }; + + setLines(account: Account) { + if(this.chart) { + this.chart.ygrids([ + { value: 0, axis: 'y2' }, + { value: 0, axis: 'y', class: 'zeroline'}, + ]); + + if(account) { + this.chart.ygrids.add({ + value: account.authorized_overdraft, + axis: 'y', + class: 'overdraft' + }); + } } + }; - loadData() { - this.dailyBalanceService.query( - this.accountIdService.get() - ).subscribe((results) => { - var headers: any[][] = [['date', 'balances', 'expenses', 'revenues']]; + $onChanges(changes) { + this.ngOnChanges(changes); + } - var rows = results.map(function(result) { - return [ - result.operation_date, - result.balance, - result.expenses, - result.revenues - ]; - }); - - this.chart.unload(); - - this.chart.load({ - rows: headers.concat(rows) - }); - - var x: any; - - x = this.chart.x(); - - this.logger.log("x", x); - - var balances = x.balances; - - this.onUpdate.emit({ - minDate: balances[0], - maxDate: balances[balances.length - 1] - }); - }); - }; - - $onInit() { - this.ngOnInit(); - } - - ngOnInit() { - var tomorrow = moment().endOf('day').valueOf(); - - this.chart = c3.generate({ - bindto: this.elementRef.nativeElement.children[0], - size: { - height: 450, - }, - data: { - x: 'date', - rows: [], - axes: { - expenses: 'y2', - revenues: 'y2' - }, - type: 'bar', - types: { - balances: 'area' - }, - groups: [ - ['expenses', 'revenues'] - ], - // Disable for the moment because there is an issue when - // using subchart line is not refreshed after subset - // selection. - //regions: { - // balances: [{ - // start: tomorrow, - // style: 'dashed' - // }] - //} - }, - regions: [{ - start: tomorrow, - }], - axis: { - x: { - type: 'timeseries', - tick: { - format: '%Y-%m-%d', - rotate: 50, - } - }, - y: { - label: { - text: 'Amount', - position: 'outer-middle' - } - }, - y2: { - show: true, - label: { - text: 'Amount', - position: 'outer-middle' - } - } - }, - grid: { - x: { - show: true, - }, - y: { - show: true, - } - }, - tooltip: { - format: { - value: function(value, ratio, id, index) { - return value + '€'; - } - } - }, - subchart: { - show: true, - onbrush: function(domain) { - this.onUpdate.emit({minDate: domain[0], maxDate: domain[1]}); - } - } - }); - - this.loadData(); - }; - - setLines(account: Account) { - if(this.chart) { - this.chart.ygrids([ - { value: 0, axis: 'y2' }, - { value: 0, axis: 'y', class: 'zeroline'}, - ]); - - if(account) { - this.chart.ygrids.add({ - value: account.authorized_overdraft, - axis: 'y', - class: 'overdraft' - }); - } - } - }; - - $onChanges(changes) { - this.ngOnChanges(changes); - } - - ngOnChanges(changes) { - if('account' in changes) { - this.setLines(changes.account.currentValue); - } else { - this.setLines(this.account); - } - }; + ngOnChanges(changes) { + if('account' in changes) { + this.setLines(changes.account.currentValue); + } else { + this.setLines(this.account); + } + }; } From 99d0eb6d1caaff8647fccd53e7284d0793cdc8e6 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Thu, 27 Jul 2017 14:09:09 +0200 Subject: [PATCH 116/222] Cleanup. --- src/operations/balance-chart.component.ts | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/operations/balance-chart.component.ts b/src/operations/balance-chart.component.ts index 0796503..8cde252 100644 --- a/src/operations/balance-chart.component.ts +++ b/src/operations/balance-chart.component.ts @@ -9,8 +9,6 @@ import { OnInit, OnChanges } from '@angular/core'; -import { Logger } from '@nsalaun/ng-logger'; - import { Account } from '../accounts/account'; import { DailyBalanceService } from '../accounts/dailyBalance.service'; @@ -19,12 +17,6 @@ class DateRange { maxDate: Date; } -class xAxis { - balances: Date[]; - expenses: Date[]; - revenues: Date[]; -} - @Component({ selector: 'balance-chart', template: '
' @@ -38,11 +30,9 @@ export class BalanceChartComponent implements OnInit, OnChanges { constructor( private elementRef: ElementRef, - private logger: Logger, private dailyBalanceService: DailyBalanceService, @Inject('accountIdService') private accountIdService, ) { - this.logger.log("Constructor BalanceChartComponent") } loadData() { @@ -70,8 +60,6 @@ export class BalanceChartComponent implements OnInit, OnChanges { x = this.chart.x(); - this.logger.log("x", x); - var balances = x.balances; this.onUpdate.emit({ From e24d5defb7bbc807d6f2bb284a57241c492259dd Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Thu, 27 Jul 2017 14:12:54 +0200 Subject: [PATCH 117/222] Add missinf component in operation module. --- ...lance-chart.component.ts => balanceChart.component.ts} | 0 src/operations/operation.module.ts | 8 ++++++++ 2 files changed, 8 insertions(+) rename src/operations/{balance-chart.component.ts => balanceChart.component.ts} (100%) diff --git a/src/operations/balance-chart.component.ts b/src/operations/balanceChart.component.ts similarity index 100% rename from src/operations/balance-chart.component.ts rename to src/operations/balanceChart.component.ts diff --git a/src/operations/operation.module.ts b/src/operations/operation.module.ts index b30080d..76edc19 100644 --- a/src/operations/operation.module.ts +++ b/src/operations/operation.module.ts @@ -8,6 +8,8 @@ import { HttpModule } from '@angular/http'; import { NgLoggerModule, Level } from '@nsalaun/ng-logger'; import { RestangularModule } from 'ngx-restangular'; +import { BalanceChartComponent } from './balanceChart.component'; + @NgModule({ imports: [ HttpModule, @@ -16,5 +18,11 @@ import { RestangularModule } from 'ngx-restangular'; NgLoggerModule, RestangularModule, ], + declarations: [ + BalanceChartComponent, + ], + entryComponents: [ + BalanceChartComponent, + ] }) export class OperationModule {} From 2619238996c6b19fb60937d046efa0841546712e Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Thu, 27 Jul 2017 14:13:13 +0200 Subject: [PATCH 118/222] Add missing component in operation module. --- src/operations/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/operations/index.ts b/src/operations/index.ts index bba2ba4..c6eaa2a 100644 --- a/src/operations/index.ts +++ b/src/operations/index.ts @@ -34,7 +34,7 @@ var categoryChartModule = require('./category-chart.component'); import accountModule from '@accountant/accounts'; -import { BalanceChartComponent } from './balance-chart.component'; +import { BalanceChartComponent } from './balanceChart.component'; var OperationFactory = require('./operation.factory'); var OperationController = require('./operation.controller'); From 27e3307a8e26cc30689b50733d564fe07d3d9914 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Thu, 27 Jul 2017 14:21:35 +0200 Subject: [PATCH 119/222] Fix callback. --- src/operations/balanceChart.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/operations/balanceChart.component.ts b/src/operations/balanceChart.component.ts index 8cde252..ed7d2ee 100644 --- a/src/operations/balanceChart.component.ts +++ b/src/operations/balanceChart.component.ts @@ -147,7 +147,7 @@ export class BalanceChartComponent implements OnInit, OnChanges { }, subchart: { show: true, - onbrush: function(domain) { + onbrush: (domain) => { this.onUpdate.emit({minDate: domain[0], maxDate: domain[1]}); } } From 13ffa1dc9841e9cb997e5c47c0a0fcde0573fde9 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Thu, 27 Jul 2017 14:28:28 +0200 Subject: [PATCH 120/222] Cleanup. --- src/operations/balanceChart.component.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/operations/balanceChart.component.ts b/src/operations/balanceChart.component.ts index ed7d2ee..4c1028f 100644 --- a/src/operations/balanceChart.component.ts +++ b/src/operations/balanceChart.component.ts @@ -69,10 +69,6 @@ export class BalanceChartComponent implements OnInit, OnChanges { }); }; - $onInit() { - this.ngOnInit(); - } - ngOnInit() { var tomorrow = moment().endOf('day').valueOf(); @@ -173,10 +169,6 @@ export class BalanceChartComponent implements OnInit, OnChanges { } }; - $onChanges(changes) { - this.ngOnChanges(changes); - } - ngOnChanges(changes) { if('account' in changes) { this.setLines(changes.account.currentValue); From eb0d898c1988d91d91e9e04d7d199e596f46d80a Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Thu, 27 Jul 2017 14:30:12 +0200 Subject: [PATCH 121/222] Fix imports. --- src/operations/category-chart.component.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/operations/category-chart.component.ts b/src/operations/category-chart.component.ts index 7fc1e64..c9f5fcd 100644 --- a/src/operations/category-chart.component.ts +++ b/src/operations/category-chart.component.ts @@ -18,10 +18,10 @@ /* jshint node: true */ 'use strict'; -var moment = require('moment'), - c3 = require('c3'); +import * as moment from 'moment'; +import * as c3 from 'c3'; -var angular = require('angular'); +import * as angular from 'angular'; var ngResource = require('angular-resource'); From 7281d1f11d061b306f39340b1c659313ec8f83c9 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Thu, 27 Jul 2017 14:31:15 +0200 Subject: [PATCH 122/222] Use accountIdService to retrieve current Account Id. --- src/operations/category-chart.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/operations/category-chart.component.ts b/src/operations/category-chart.component.ts index c9f5fcd..f07bec8 100644 --- a/src/operations/category-chart.component.ts +++ b/src/operations/category-chart.component.ts @@ -35,12 +35,12 @@ module.exports = angular.module('categoryChartModule', [ minDate: '<', maxDate: '<' }, - controller: function($stateParams, $element, Categories, Incomes) { + controller: function(accountIdService, $element, Categories, Incomes) { var vm = this; vm.loadData = function() { Categories.query({ - id: $stateParams.accountId, + id: accountIdService.get(), begin: vm.minDate ? moment(vm.minDate).format('YYYY-MM-DD') : null, end: vm.maxDate ? moment(vm.maxDate).format('YYYY-MM-DD') : null }, function(results) { From fa147e74fc3d6a93e69c33bd1a1e364d947aad08 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 29 Jul 2017 16:28:59 +0200 Subject: [PATCH 123/222] Use account directly to load daily balances. --- src/operations/balanceChart.component.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/operations/balanceChart.component.ts b/src/operations/balanceChart.component.ts index 4c1028f..cff6d46 100644 --- a/src/operations/balanceChart.component.ts +++ b/src/operations/balanceChart.component.ts @@ -35,9 +35,9 @@ export class BalanceChartComponent implements OnInit, OnChanges { ) { } - loadData() { + loadData(account: Account) { this.dailyBalanceService.query( - this.accountIdService.get() + account.id ).subscribe((results) => { var headers: any[][] = [['date', 'balances', 'expenses', 'revenues']]; @@ -148,8 +148,6 @@ export class BalanceChartComponent implements OnInit, OnChanges { } } }); - - this.loadData(); }; setLines(account: Account) { @@ -170,7 +168,8 @@ export class BalanceChartComponent implements OnInit, OnChanges { }; ngOnChanges(changes) { - if('account' in changes) { + if('account' in changes && changes.account.currentValue) { + this.loadData(changes.account.currentValue); this.setLines(changes.account.currentValue); } else { this.setLines(this.account); From 2812891b235c9c082a8f511e0c6a434a4e735090 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 29 Jul 2017 16:32:07 +0200 Subject: [PATCH 124/222] Inject account in category chart component instead of using accountIdService. --- src/operations/category-chart.component.ts | 26 +++++++++++----------- src/operations/operations.html | 3 ++- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/operations/category-chart.component.ts b/src/operations/category-chart.component.ts index f07bec8..a90c637 100644 --- a/src/operations/category-chart.component.ts +++ b/src/operations/category-chart.component.ts @@ -33,17 +33,18 @@ module.exports = angular.module('categoryChartModule', [ template: '
', bindings: { minDate: '<', - maxDate: '<' + maxDate: '<', + account: '<' }, - controller: function(accountIdService, $element, Categories, Incomes) { + controller: function($element, Categories, Incomes) { var vm = this; - vm.loadData = function() { - Categories.query({ - id: accountIdService.get(), - begin: vm.minDate ? moment(vm.minDate).format('YYYY-MM-DD') : null, - end: vm.maxDate ? moment(vm.maxDate).format('YYYY-MM-DD') : null - }, function(results) { + vm.loadData = function(account: Account) { + categoryService.query( + accountIdService.get(), + vm.minDate ? moment(vm.minDate).format('YYYY-MM-DD') : null, + vm.maxDate ? moment(vm.maxDate).format('YYYY-MM-DD') : null + ).subscribe((results) => { var expenses=[], revenues=[], colors={}, @@ -107,14 +108,13 @@ module.exports = angular.module('categoryChartModule', [ show: false } }); - - //vm.loadData(); }; - vm.$onChanges = function() { - vm.loadData(); + vm.$onChanges = function(changes) { + if('account' in changes && changes.account.currentValue) { + vm.loadData(changes.account.currentValue); + } }; - } }) diff --git a/src/operations/operations.html b/src/operations/operations.html index a53afa7..0fca7d7 100644 --- a/src/operations/operations.html +++ b/src/operations/operations.html @@ -24,7 +24,8 @@
+ max-date="operationsCtrl.maxDate" + account="operationsCtrl.account"/>
From a6a7c1cd776285c098bcdb85f49467f07e42dde8 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 29 Jul 2017 16:33:24 +0200 Subject: [PATCH 125/222] Add category service in Angular2. --- src/operations/category.service.ts | 22 ++++++++++++++++++++++ src/operations/category.ts | 7 +++++++ src/operations/index.ts | 3 +++ src/operations/operation.module.ts | 4 ++++ 4 files changed, 36 insertions(+) create mode 100644 src/operations/category.service.ts create mode 100644 src/operations/category.ts diff --git a/src/operations/category.service.ts b/src/operations/category.service.ts new file mode 100644 index 0000000..675ff2d --- /dev/null +++ b/src/operations/category.service.ts @@ -0,0 +1,22 @@ +// vim: set tw=80 ts=2 sw=2 sts=2: + +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs/Rx'; + +import { Restangular } from "ngx-restangular"; + +import { Category } from './category'; + +@Injectable() +export class CategoryService { + constructor( + private restangular: Restangular + ) {} + + query(id: number, minDate: Date = null, maxDate: Date = null): Observable { + return this.restangular.one('account', id).getList('category', { + begin: minDate, + end: maxDate + }); + } +} diff --git a/src/operations/category.ts b/src/operations/category.ts new file mode 100644 index 0000000..fc7f2a6 --- /dev/null +++ b/src/operations/category.ts @@ -0,0 +1,7 @@ +// vim: set tw=80 ts=2 sw=2 sts=2 : + +export class Category { + category: string; + expenses: number; + revenues: number; +} diff --git a/src/operations/index.ts b/src/operations/index.ts index c6eaa2a..ff56ea5 100644 --- a/src/operations/index.ts +++ b/src/operations/index.ts @@ -35,6 +35,7 @@ var categoryChartModule = require('./category-chart.component'); import accountModule from '@accountant/accounts'; import { BalanceChartComponent } from './balanceChart.component'; +import { CategoryService } from './category.service'; var OperationFactory = require('./operation.factory'); var OperationController = require('./operation.controller'); @@ -52,6 +53,8 @@ export default angular.module('accountant.operations', [ .controller('OperationController', OperationController) + .factory('categoryService', downgradeInjectable(CategoryService)) + .directive('balanceChart', downgradeComponent({ component: BalanceChartComponent }) as angular.IDirectiveFactory) diff --git a/src/operations/operation.module.ts b/src/operations/operation.module.ts index 76edc19..a646106 100644 --- a/src/operations/operation.module.ts +++ b/src/operations/operation.module.ts @@ -9,6 +9,7 @@ import { NgLoggerModule, Level } from '@nsalaun/ng-logger'; import { RestangularModule } from 'ngx-restangular'; import { BalanceChartComponent } from './balanceChart.component'; +import { CategoryService } from './category.service' @NgModule({ imports: [ @@ -18,6 +19,9 @@ import { BalanceChartComponent } from './balanceChart.component'; NgLoggerModule, RestangularModule, ], + providers: [ + CategoryService, + ], declarations: [ BalanceChartComponent, ], From efcf07565bbd38f6b1ed31d3073c315c97de5959 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 29 Jul 2017 16:34:24 +0200 Subject: [PATCH 126/222] Use categoryService instead of old Categories factory. --- src/operations/category-chart.component.ts | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/src/operations/category-chart.component.ts b/src/operations/category-chart.component.ts index a90c637..2a76403 100644 --- a/src/operations/category-chart.component.ts +++ b/src/operations/category-chart.component.ts @@ -36,12 +36,12 @@ module.exports = angular.module('categoryChartModule', [ maxDate: '<', account: '<' }, - controller: function($element, Categories, Incomes) { + controller: function($element, categoryService) { var vm = this; vm.loadData = function(account: Account) { categoryService.query( - accountIdService.get(), + account.id, vm.minDate ? moment(vm.minDate).format('YYYY-MM-DD') : null, vm.maxDate ? moment(vm.maxDate).format('YYYY-MM-DD') : null ).subscribe((results) => { @@ -118,20 +118,4 @@ module.exports = angular.module('categoryChartModule', [ } }) - .factory('Categories', function($resource) { - return $resource( - '/api/account/:id/category', { - id: '@id' - } - ); - }) - - .factory('Incomes', function($resource) { - return $resource( - '/api/account/:id/income', { - id: '@id' - } - ); - }) - .name; From 927459b6c5954ec323e64b6a7b4e9b4842144559 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 29 Jul 2017 16:36:16 +0200 Subject: [PATCH 127/222] Remove unused ngResource. --- src/operations/category-chart.component.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/operations/category-chart.component.ts b/src/operations/category-chart.component.ts index 2a76403..a1d633e 100644 --- a/src/operations/category-chart.component.ts +++ b/src/operations/category-chart.component.ts @@ -23,10 +23,7 @@ import * as c3 from 'c3'; import * as angular from 'angular'; -var ngResource = require('angular-resource'); - module.exports = angular.module('categoryChartModule', [ - ngResource ]) .component('categoryChart', { From 89fc42c47ad1f82f4f9a7be6aef4b73e965f3ed2 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 29 Jul 2017 16:57:05 +0200 Subject: [PATCH 128/222] Fix date range in category service. --- src/operations/category.service.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/operations/category.service.ts b/src/operations/category.service.ts index 675ff2d..44f33c5 100644 --- a/src/operations/category.service.ts +++ b/src/operations/category.service.ts @@ -14,9 +14,15 @@ export class CategoryService { ) {} query(id: number, minDate: Date = null, maxDate: Date = null): Observable { - return this.restangular.one('account', id).getList('category', { - begin: minDate, - end: maxDate - }); + var dateRange: any; + if(minDate) { + dateRange.begin = minDate; + } + + if(maxDate) { + dateRange.end = maxDate; + } + + return this.restangular.one('account', id).getList('category', dateRange); } } From 1bd59cbbf8d810701b2d9175398fe29f66293324 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 29 Jul 2017 17:07:43 +0200 Subject: [PATCH 129/222] Fix date format in category service. --- src/operations/category.service.ts | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/operations/category.service.ts b/src/operations/category.service.ts index 44f33c5..411d4b7 100644 --- a/src/operations/category.service.ts +++ b/src/operations/category.service.ts @@ -1,5 +1,7 @@ // vim: set tw=80 ts=2 sw=2 sts=2: +import * as moment from 'moment'; + import { Injectable } from '@angular/core'; import { Observable } from 'rxjs/Rx'; @@ -13,14 +15,23 @@ export class CategoryService { private restangular: Restangular ) {} + formatDate(date: Date|string) { + if(date instanceof Date) { + return moment(date).format('YYYY-MM-DD'); + } + + return date; + } + query(id: number, minDate: Date = null, maxDate: Date = null): Observable { - var dateRange: any; + var dateRange: any = {}; + if(minDate) { - dateRange.begin = minDate; + dateRange.begin = this.formatDate(minDate); } if(maxDate) { - dateRange.end = maxDate; + dateRange.end = this.formatDate(maxDate); } return this.restangular.one('account', id).getList('category', dateRange); From 02f447d63c93af23cf910eb8800e37080c49ab8f Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 29 Jul 2017 17:18:36 +0200 Subject: [PATCH 130/222] Upgrade Category chart component to Angular2. --- src/operations/category-chart.component.ts | 67 ++++++++++++---------- src/operations/index.ts | 11 ++-- src/operations/operation.module.ts | 3 + src/operations/operations.html | 6 +- 4 files changed, 49 insertions(+), 38 deletions(-) diff --git a/src/operations/category-chart.component.ts b/src/operations/category-chart.component.ts index a1d633e..57fb11b 100644 --- a/src/operations/category-chart.component.ts +++ b/src/operations/category-chart.component.ts @@ -21,26 +21,36 @@ import * as moment from 'moment'; import * as c3 from 'c3'; -import * as angular from 'angular'; +import { + Component, ElementRef, + Inject, Input, Output, EventEmitter, + OnInit, OnChanges +} from '@angular/core'; -module.exports = angular.module('categoryChartModule', [ -]) +import { Account } from '../accounts/account'; +import { CategoryService } from './category.service'; - .component('categoryChart', { - template: '
', - bindings: { - minDate: '<', - maxDate: '<', - account: '<' - }, - controller: function($element, categoryService) { - var vm = this; +@Component({ + selector: 'category-chart', + template: '
' +}) +export class CategoryChartComponent implements OnInit, OnChanges { + @Input() minDate: Date; + @Input() maxDate: Date; + @Input() account: Account; - vm.loadData = function(account: Account) { - categoryService.query( + chart: c3.ChartAPI; + + constructor( + private elementRef: ElementRef, + private categoryService: CategoryService, + ) {} + + loadData(account: Account) { + this.categoryService.query( account.id, - vm.minDate ? moment(vm.minDate).format('YYYY-MM-DD') : null, - vm.maxDate ? moment(vm.maxDate).format('YYYY-MM-DD') : null + this.minDate, + this.maxDate ).subscribe((results) => { var expenses=[], revenues=[], @@ -50,7 +60,7 @@ module.exports = angular.module('categoryChartModule', [ var revenuesColor = 'green', expensesColor = 'orange'; - angular.forEach(results, function(result) { + for(let result of results) { if(result.revenues > 0) { var revenuesName = 'revenues-' + result.category; @@ -67,11 +77,11 @@ module.exports = angular.module('categoryChartModule', [ names[expensesName] = result.category; colors[expensesName] = expensesColor; } - }); + }; - vm.chart.unload(); + this.chart.unload(); - vm.chart.load({ + this.chart.load({ columns: revenues.concat(expenses), names: names, colors: colors @@ -79,9 +89,9 @@ module.exports = angular.module('categoryChartModule', [ }); }; - vm.$onInit = function() { - vm.chart = c3.generate({ - bindto: $element[0].children[0], + ngOnInit() { + this.chart = c3.generate({ + bindto: this.elementRef.nativeElement.children[0], data: { columns: [], type: 'donut', @@ -107,12 +117,11 @@ module.exports = angular.module('categoryChartModule', [ }); }; - vm.$onChanges = function(changes) { + ngOnChanges(changes) { if('account' in changes && changes.account.currentValue) { - vm.loadData(changes.account.currentValue); + this.loadData(changes.account.currentValue); + } else if (this.account) { + this.loadData(this.account); } }; - } - }) - - .name; +} diff --git a/src/operations/index.ts b/src/operations/index.ts index ff56ea5..5d16f4b 100644 --- a/src/operations/index.ts +++ b/src/operations/index.ts @@ -30,12 +30,10 @@ import { ToastrService } from 'ngx-toastr'; var ngResource = require('angular-resource'), ngStrap = require('angular-strap'); -var categoryChartModule = require('./category-chart.component'); - import accountModule from '@accountant/accounts'; import { BalanceChartComponent } from './balanceChart.component'; -import { CategoryService } from './category.service'; +import { CategoryChartComponent } from './category-chart.component'; var OperationFactory = require('./operation.factory'); var OperationController = require('./operation.controller'); @@ -44,7 +42,6 @@ export default angular.module('accountant.operations', [ ngResource, ngStrap, accountModule, - categoryChartModule ]) .factory('toastrService', downgradeInjectable(ToastrService)) @@ -53,10 +50,12 @@ export default angular.module('accountant.operations', [ .controller('OperationController', OperationController) - .factory('categoryService', downgradeInjectable(CategoryService)) - .directive('balanceChart', downgradeComponent({ component: BalanceChartComponent }) as angular.IDirectiveFactory) + .directive('categoryChart', downgradeComponent({ + component: CategoryChartComponent + }) as angular.IDirectiveFactory) + .name; diff --git a/src/operations/operation.module.ts b/src/operations/operation.module.ts index a646106..ff2b4b5 100644 --- a/src/operations/operation.module.ts +++ b/src/operations/operation.module.ts @@ -9,6 +9,7 @@ import { NgLoggerModule, Level } from '@nsalaun/ng-logger'; import { RestangularModule } from 'ngx-restangular'; import { BalanceChartComponent } from './balanceChart.component'; +import { CategoryChartComponent } from './category-chart.component'; import { CategoryService } from './category.service' @NgModule({ @@ -24,9 +25,11 @@ import { CategoryService } from './category.service' ], declarations: [ BalanceChartComponent, + CategoryChartComponent, ], entryComponents: [ BalanceChartComponent, + CategoryChartComponent, ] }) export class OperationModule {} diff --git a/src/operations/operations.html b/src/operations/operations.html index 0fca7d7..b5d1ed3 100644 --- a/src/operations/operations.html +++ b/src/operations/operations.html @@ -23,9 +23,9 @@
+ [min-date]="operationsCtrl.minDate" + [max-date]="operationsCtrl.maxDate" + [account]="operationsCtrl.account">
From 20437ba54884fa32952f473a286e4ce72fd9b6c6 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 29 Jul 2017 17:21:45 +0200 Subject: [PATCH 131/222] Indent and cleanup. --- src/operations/category-chart.component.ts | 181 ++++++++++----------- 1 file changed, 82 insertions(+), 99 deletions(-) diff --git a/src/operations/category-chart.component.ts b/src/operations/category-chart.component.ts index 57fb11b..079fa39 100644 --- a/src/operations/category-chart.component.ts +++ b/src/operations/category-chart.component.ts @@ -1,24 +1,5 @@ -// vim: set tw=80 ts=4 sw=4 sts=4: -/* - This file is part of Accountant. +// vim: set tw=80 ts=2 sw=2 sts=2 : - Accountant is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Accountant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with Accountant. If not, see . - */ -/* jshint node: true */ -'use strict'; - -import * as moment from 'moment'; import * as c3 from 'c3'; import { @@ -27,101 +8,103 @@ import { OnInit, OnChanges } from '@angular/core'; +import { Logger } from '@nsalaun/ng-logger'; + import { Account } from '../accounts/account'; import { CategoryService } from './category.service'; @Component({ - selector: 'category-chart', - template: '
' + selector: 'category-chart', + template: '
' }) export class CategoryChartComponent implements OnInit, OnChanges { - @Input() minDate: Date; - @Input() maxDate: Date; - @Input() account: Account; + @Input() minDate: Date; + @Input() maxDate: Date; + @Input() account: Account; - chart: c3.ChartAPI; + chart: c3.ChartAPI; - constructor( - private elementRef: ElementRef, - private categoryService: CategoryService, - ) {} + constructor( + private elementRef: ElementRef, + private categoryService: CategoryService, + private logger: Logger, + ) {} - loadData(account: Account) { - this.categoryService.query( - account.id, - this.minDate, - this.maxDate - ).subscribe((results) => { - var expenses=[], - revenues=[], - colors={}, - names={}; + loadData(account: Account) { + this.categoryService.query( + account.id, + this.minDate, + this.maxDate + ).subscribe((results) => { + var expenses=[], + revenues=[], + colors={}, + names={}; - var revenuesColor = 'green', - expensesColor = 'orange'; + var revenuesColor = 'green', + expensesColor = 'orange'; - for(let result of results) { + for(let result of results) { + if(result.revenues > 0) { + var revenuesName = 'revenues-' + result.category; - if(result.revenues > 0) { - var revenuesName = 'revenues-' + result.category; + revenues.push([revenuesName, result.revenues]); + names[revenuesName] = result.category; + colors[revenuesName] = revenuesColor; + } - revenues.push([revenuesName, result.revenues]); - names[revenuesName] = result.category; - colors[revenuesName] = revenuesColor; - } + if(result.expenses < 0) { + var expensesName = 'expenses-' + result.category; - if(result.expenses < 0) { - var expensesName = 'expenses-' + result.category; + expenses.splice(0, 0, [expensesName, -result.expenses]); + names[expensesName] = result.category; + colors[expensesName] = expensesColor; + } + }; - expenses.splice(0, 0, [expensesName, -result.expenses]); - names[expensesName] = result.category; - colors[expensesName] = expensesColor; - } - }; + this.chart.unload(); - this.chart.unload(); + this.chart.load({ + columns: revenues.concat(expenses), + names: names, + colors: colors + }); + }); + }; - this.chart.load({ - columns: revenues.concat(expenses), - names: names, - colors: colors - }); - }); - }; + ngOnInit() { + this.chart = c3.generate({ + bindto: this.elementRef.nativeElement.children[0], + data: { + columns: [], + type: 'donut', + order: null, + }, + tooltip: { + format: { + value: function(value, ratio, id, index) { + return value + '€'; + } + } + }, + donut: { + label: { + format: function(value) { + return value + '€'; + } + } + }, + legend: { + show: false + } + }); + }; - ngOnInit() { - this.chart = c3.generate({ - bindto: this.elementRef.nativeElement.children[0], - data: { - columns: [], - type: 'donut', - order: null, - }, - tooltip: { - format: { - value: function(value, ratio, id, index) { - return value + '€'; - } - } - }, - donut: { - label: { - format: function(value) { - return value + '€'; - } - } - }, - legend: { - show: false - } - }); - }; - - ngOnChanges(changes) { - if('account' in changes && changes.account.currentValue) { - this.loadData(changes.account.currentValue); - } else if (this.account) { - this.loadData(this.account); - } - }; + ngOnChanges(changes) { + if('account' in changes && changes.account.currentValue) { + this.loadData(changes.account.currentValue); + } else if (this.account) { + this.loadData(this.account); + } + }; } From f58afb37bdadacb3a76e20558979ea64d4fe9946 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 29 Jul 2017 17:22:25 +0200 Subject: [PATCH 132/222] Cleanup unused dependency. --- src/operations/category-chart.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/operations/category-chart.component.ts b/src/operations/category-chart.component.ts index 079fa39..d041a36 100644 --- a/src/operations/category-chart.component.ts +++ b/src/operations/category-chart.component.ts @@ -4,7 +4,7 @@ import * as c3 from 'c3'; import { Component, ElementRef, - Inject, Input, Output, EventEmitter, + Inject, Input, Output, OnInit, OnChanges } from '@angular/core'; From 1d35438444e3f37d9989f7672f0d31f0427bc3bb Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 29 Jul 2017 17:24:25 +0200 Subject: [PATCH 133/222] Rename Category Chart component file. --- .../{category-chart.component.ts => categoryChart.component.ts} | 0 src/operations/index.ts | 2 +- src/operations/operation.module.ts | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename src/operations/{category-chart.component.ts => categoryChart.component.ts} (100%) diff --git a/src/operations/category-chart.component.ts b/src/operations/categoryChart.component.ts similarity index 100% rename from src/operations/category-chart.component.ts rename to src/operations/categoryChart.component.ts diff --git a/src/operations/index.ts b/src/operations/index.ts index 5d16f4b..ea006b6 100644 --- a/src/operations/index.ts +++ b/src/operations/index.ts @@ -33,7 +33,7 @@ var ngResource = require('angular-resource'), import accountModule from '@accountant/accounts'; import { BalanceChartComponent } from './balanceChart.component'; -import { CategoryChartComponent } from './category-chart.component'; +import { CategoryChartComponent } from './categoryChart.component'; var OperationFactory = require('./operation.factory'); var OperationController = require('./operation.controller'); diff --git a/src/operations/operation.module.ts b/src/operations/operation.module.ts index ff2b4b5..c8ad79c 100644 --- a/src/operations/operation.module.ts +++ b/src/operations/operation.module.ts @@ -9,7 +9,7 @@ import { NgLoggerModule, Level } from '@nsalaun/ng-logger'; import { RestangularModule } from 'ngx-restangular'; import { BalanceChartComponent } from './balanceChart.component'; -import { CategoryChartComponent } from './category-chart.component'; +import { CategoryChartComponent } from './categoryChart.component'; import { CategoryService } from './category.service' @NgModule({ From 595fe60fc4608aae946a1ff1d9bb27f7b663bde8 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 29 Jul 2017 17:51:44 +0200 Subject: [PATCH 134/222] Add Operation Service. --- src/operations/operation.module.ts | 4 ++- src/operations/operation.service.ts | 43 +++++++++++++++++++++++++++++ src/operations/operation.ts | 9 ++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 src/operations/operation.service.ts create mode 100644 src/operations/operation.ts diff --git a/src/operations/operation.module.ts b/src/operations/operation.module.ts index c8ad79c..3ed1d67 100644 --- a/src/operations/operation.module.ts +++ b/src/operations/operation.module.ts @@ -10,7 +10,8 @@ import { RestangularModule } from 'ngx-restangular'; import { BalanceChartComponent } from './balanceChart.component'; import { CategoryChartComponent } from './categoryChart.component'; -import { CategoryService } from './category.service' +import { CategoryService } from './category.service'; +import { OperationService } from './operation.service'; @NgModule({ imports: [ @@ -22,6 +23,7 @@ import { CategoryService } from './category.service' ], providers: [ CategoryService, + OperationService, ], declarations: [ BalanceChartComponent, diff --git a/src/operations/operation.service.ts b/src/operations/operation.service.ts new file mode 100644 index 0000000..0a211fb --- /dev/null +++ b/src/operations/operation.service.ts @@ -0,0 +1,43 @@ +// vim: set tw=80 ts=2 sw=2 sts=2 : + +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs/Rx'; + +import { Restangular } from "ngx-restangular"; + +import { Operation } from './operation'; + +@Injectable() +export class OperationService { + constructor( + private restangular: Restangular + ) {} + + private all() { + return this.restangular.all('operation'); + } + + private one(id: number) { + return this.restangular.one('operation', id); + } + + query(): Observable { + return this.all().getList(); + } + + get(id: number): Observable { + return this.one(id).get(); + } + + create(operation: Operation): Observable { + return this.all().post(operation); + } + + update(operation: Operation): Observable { + return this.one(operation.id).post(null, operation); + } + + delete(operation: Operation): Observable { + return this.one(operation.id).delete(); + } +} diff --git a/src/operations/operation.ts b/src/operations/operation.ts new file mode 100644 index 0000000..82afb7d --- /dev/null +++ b/src/operations/operation.ts @@ -0,0 +1,9 @@ +// vim: set tw=80 ts=2 sw=2 sts=2: + +export class Operation { + id: number; + operation_date: string; + label: string; + value: number; + category: string; +} From 4c921bfaaa5c8fee545f7778b6defbde2061b18d Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 29 Jul 2017 17:57:50 +0200 Subject: [PATCH 135/222] Add minDate and maxDate parameters in Operation query. --- src/operations/operation.service.ts | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/operations/operation.service.ts b/src/operations/operation.service.ts index 0a211fb..d83b67b 100644 --- a/src/operations/operation.service.ts +++ b/src/operations/operation.service.ts @@ -1,5 +1,7 @@ // vim: set tw=80 ts=2 sw=2 sts=2 : +import * as moment from 'moment'; + import { Injectable } from '@angular/core'; import { Observable } from 'rxjs/Rx'; @@ -21,8 +23,30 @@ export class OperationService { return this.restangular.one('operation', id); } - query(): Observable { - return this.all().getList(); + formatDate(date: Date|string) { + if(date instanceof Date) { + return moment(date).format('YYYY-MM-DD'); + } + + return date; + } + + query( + accountId: number, + minDate: Date|string = null, + maxDate: Date|string = null + ): Observable { + var dateRange: any = {}; + + if(minDate) { + dateRange.begin = this.formatDate(minDate); + } + + if(maxDate) { + dateRange.end = this.formatDate(maxDate); + } + + return this.all().getList([], dateRange); } get(id: number): Observable { From 8348f5bb8fa02f21f23f71f622a0a753cba8d591 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 29 Jul 2017 22:26:38 +0200 Subject: [PATCH 136/222] Use Operation Service in Operation controller. --- src/operations/index.ts | 4 +- src/operations/operation.controller.ts | 55 ++++++++++++++++---------- src/operations/operation.service.ts | 4 +- 3 files changed, 40 insertions(+), 23 deletions(-) diff --git a/src/operations/index.ts b/src/operations/index.ts index ea006b6..f370cfd 100644 --- a/src/operations/index.ts +++ b/src/operations/index.ts @@ -34,8 +34,8 @@ import accountModule from '@accountant/accounts'; import { BalanceChartComponent } from './balanceChart.component'; import { CategoryChartComponent } from './categoryChart.component'; +import { OperationService } from './operation.service'; -var OperationFactory = require('./operation.factory'); var OperationController = require('./operation.controller'); export default angular.module('accountant.operations', [ @@ -46,7 +46,7 @@ export default angular.module('accountant.operations', [ .factory('toastrService', downgradeInjectable(ToastrService)) - .factory('Operation', OperationFactory) + .factory('operationService', downgradeInjectable(OperationService)) .controller('OperationController', OperationController) diff --git a/src/operations/operation.controller.ts b/src/operations/operation.controller.ts index d8bf2d3..4b4bce1 100644 --- a/src/operations/operation.controller.ts +++ b/src/operations/operation.controller.ts @@ -1,21 +1,27 @@ -import * as moment from 'moment'; - var operationFormTmpl = require('./operation.form.tmpl.html'), operationDeleteTmpl = require('./operation.delete.tmpl.html'); -module.exports = function($stateParams, $modal, toastrService, Operation, - AccountService) { +import { Observable } from 'rxjs/Rx'; +import { ToastrService } from 'ngx-toastr'; + +import { Operation } from './operation'; +import { OperationService } from './operation.service'; + +module.exports = function( + $stateParams, $modal, + toastrService: ToastrService, + operationService: OperationService, + AccountService +){ var vm = this; /* * Add an empty operation. */ vm.add = function() { - var operation = new Operation({ - // eslint-disable-next-line camelcase - account_id: $stateParams.accountId - }); + var operation = new Operation(); + operation.account_id = $stateParams.accountId; return vm.modify(operation); }; @@ -27,11 +33,12 @@ module.exports = function($stateParams, $modal, toastrService, Operation, vm.minDate = minDate; vm.maxDate = maxDate; - return Operation.query({ - // eslint-disable-next-line camelcase - account_id: $stateParams.accountId, - begin: minDate ? moment(minDate).format('YYYY-MM-DD') : null, - end: maxDate ? moment(maxDate).format('YYYY-MM-DD') : null + return operationService.query( + $stateParams.accountId, + minDate, + maxDate + ).subscribe((operations: Operation[]) => { + vm.operations = operations; }); }; @@ -59,13 +66,21 @@ module.exports = function($stateParams, $modal, toastrService, Operation, vm.save = function(operation) { operation.confirmed = true; - return operation.$save().then(function(operation) { + var observable: Observable; + + if(operation.id){ + observable = operationService.update(operation); + } else { + observable = operationService.create(operation); + } + + return observable.subscribe((operation) => { toastrService.success('Operation #' + operation.id + ' saved.'); - vm.operations = vm.load(); + vm.load(); return operation; - }, function(result){ + }, (result) => { toastrService.error( 'Error while saving operation: ' + result.message ); @@ -99,13 +114,13 @@ module.exports = function($stateParams, $modal, toastrService, Operation, vm.delete = function(operation) { var id = operation.id; - return operation.$delete().then(function() { + return operationService.delete(operation).subscribe(() => { toastrService.success('Operation #' + id + ' deleted.'); - vm.operations = vm.load(); + vm.load(); return operation; - }, function(result) { + }, (result) => { toastrService.error( 'An error occurred while trying to delete operation #' + id + ':
' + result @@ -144,7 +159,7 @@ module.exports = function($stateParams, $modal, toastrService, Operation, }; vm.onUpdate = function(dateRange) { - vm.operations = vm.load(dateRange.minDate, dateRange.maxDate); + vm.load(dateRange.minDate, dateRange.maxDate); }; AccountService.get($stateParams.accountId).subscribe(account => { diff --git a/src/operations/operation.service.ts b/src/operations/operation.service.ts index d83b67b..dd6d414 100644 --- a/src/operations/operation.service.ts +++ b/src/operations/operation.service.ts @@ -36,7 +36,9 @@ export class OperationService { minDate: Date|string = null, maxDate: Date|string = null ): Observable { - var dateRange: any = {}; + var dateRange: any = { + account_id: accountId + }; if(minDate) { dateRange.begin = this.formatDate(minDate); From 75dc2afc80c70b4e7bc3d6acdc4b13b9a9811803 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 29 Jul 2017 22:26:57 +0200 Subject: [PATCH 137/222] Fix Operation query parameters. --- src/operations/operation.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/operations/operation.service.ts b/src/operations/operation.service.ts index dd6d414..084c544 100644 --- a/src/operations/operation.service.ts +++ b/src/operations/operation.service.ts @@ -48,7 +48,7 @@ export class OperationService { dateRange.end = this.formatDate(maxDate); } - return this.all().getList([], dateRange); + return this.all().getList(dateRange); } get(id: number): Observable { From 0a5a7e72e3cb383e5f9d0fd98456467fb4e3567f Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 29 Jul 2017 22:27:25 +0200 Subject: [PATCH 138/222] Add account_id in Operation. --- src/operations/operation.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/operations/operation.ts b/src/operations/operation.ts index 82afb7d..e8e2867 100644 --- a/src/operations/operation.ts +++ b/src/operations/operation.ts @@ -6,4 +6,5 @@ export class Operation { label: string; value: number; category: string; + account_id: number; } From bb21dd700ea56e62dd87f74448a9d2f207811cc8 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 29 Jul 2017 22:53:41 +0200 Subject: [PATCH 139/222] Use Account Id service instead of $stateParam. --- src/operations/operation.controller.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/operations/operation.controller.ts b/src/operations/operation.controller.ts index 4b4bce1..818203c 100644 --- a/src/operations/operation.controller.ts +++ b/src/operations/operation.controller.ts @@ -9,7 +9,8 @@ import { Operation } from './operation'; import { OperationService } from './operation.service'; module.exports = function( - $stateParams, $modal, + $modal, + accountIdService, toastrService: ToastrService, operationService: OperationService, AccountService @@ -21,7 +22,7 @@ module.exports = function( */ vm.add = function() { var operation = new Operation(); - operation.account_id = $stateParams.accountId; + operation.account_id = accountIdService.get(); return vm.modify(operation); }; @@ -34,7 +35,7 @@ module.exports = function( vm.maxDate = maxDate; return operationService.query( - $stateParams.accountId, + accountIdService.get(), minDate, maxDate ).subscribe((operations: Operation[]) => { @@ -162,7 +163,7 @@ module.exports = function( vm.load(dateRange.minDate, dateRange.maxDate); }; - AccountService.get($stateParams.accountId).subscribe(account => { + AccountService.get(accountIdService.get()).subscribe(account => { vm.account = account }); }; From f37481537117f3334986e58f97c768c4e47ecf77 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 29 Jul 2017 22:58:34 +0200 Subject: [PATCH 140/222] Add typing. --- src/operations/operation.controller.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/operations/operation.controller.ts b/src/operations/operation.controller.ts index 818203c..a81e8e5 100644 --- a/src/operations/operation.controller.ts +++ b/src/operations/operation.controller.ts @@ -5,6 +5,7 @@ import { Observable } from 'rxjs/Rx'; import { ToastrService } from 'ngx-toastr'; +import { AccountService } from '../accounts/account.service'; import { Operation } from './operation'; import { OperationService } from './operation.service'; @@ -13,7 +14,7 @@ module.exports = function( accountIdService, toastrService: ToastrService, operationService: OperationService, - AccountService + AccountService: AccountService ){ var vm = this; From f48483338013d5f7b69478d51003af7fb551c41b Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 29 Jul 2017 23:04:09 +0200 Subject: [PATCH 141/222] Remove unused injection. --- src/scheduler/schedule.states.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/scheduler/schedule.states.ts b/src/scheduler/schedule.states.ts index 4912166..7361322 100644 --- a/src/scheduler/schedule.states.ts +++ b/src/scheduler/schedule.states.ts @@ -4,12 +4,4 @@ export const ScheduleListState = { name: 'scheduler', url: '/account/:accountId/scheduler', component: 'scheduleListComponent', - resolve: { - accountId: function($transition$) { - return $transition$.params().accountId; - }, - $modal: function($modal) { - return $modal; - } - } } From 45af7791ff2eced1b56bf2734fe3e2fc72e191fc Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 29 Jul 2017 23:05:38 +0200 Subject: [PATCH 142/222] Remove unused injection. --- src/scheduler/schedule.module.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/scheduler/schedule.module.ts b/src/scheduler/schedule.module.ts index 4edf4c3..b7e7649 100644 --- a/src/scheduler/schedule.module.ts +++ b/src/scheduler/schedule.module.ts @@ -18,10 +18,6 @@ import { ScheduleFormComponent } from './scheduleForm.component'; import { ScheduleRowComponent } from './scheduleRow.component'; import { ScheduleListComponent } from './scheduleList.component'; -export function $modalServiceFactory(i: any) { - return i.get('$modal'); -} - export function accountIdServiceFactory(i: any) { return i.get('accountIdService'); } @@ -40,10 +36,6 @@ export function accountIdServiceFactory(i: any) { providers: [ ScheduleService, { - provide: '$modal', - deps: ['$injector'], - useFactory: $modalServiceFactory - }, { provide: 'accountIdService', deps: ['$injector'], useFactory: accountIdServiceFactory From f7ea8a46218fa2f95f367229755aa95226af9e98 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 29 Jul 2017 23:06:10 +0200 Subject: [PATCH 143/222] Prepare needed injection to upgrade Operation Component to Angular2. --- src/operations/operation.module.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/operations/operation.module.ts b/src/operations/operation.module.ts index 3ed1d67..b229b3b 100644 --- a/src/operations/operation.module.ts +++ b/src/operations/operation.module.ts @@ -13,6 +13,14 @@ import { CategoryChartComponent } from './categoryChart.component'; import { CategoryService } from './category.service'; import { OperationService } from './operation.service'; +export function $modalServiceFactory(i: any) { + return i.get('$modal'); +} + +export function accountIdServiceFactory(i: any) { + return i.get('accountIdService'); +} + @NgModule({ imports: [ HttpModule, @@ -24,6 +32,15 @@ import { OperationService } from './operation.service'; providers: [ CategoryService, OperationService, + { + provide: '$modal', + deps: ['$injector'], + useFactory: $modalServiceFactory + }, { + provide: 'accountIdService', + deps: ['$injector'], + useFactory: accountIdServiceFactory + } ], declarations: [ BalanceChartComponent, From 90ecb2bd57efe2cf4090dc0f0507626d0685ad5b Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 29 Jul 2017 23:13:07 +0200 Subject: [PATCH 144/222] Upgrades. --- package.json | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index 0fb07bd..7deab88 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "eslint-plugin-this": "^0.2.2", "extract-text-webpack-plugin": "^3.0.0", "file-loader": "^0.11.2", - "html-loader": "^0.4.5", + "html-loader": "^0.5.0", "html-webpack-plugin": "^2.29.0", "htmllint-loader": "^1.3.8", "imports-loader": "^0.7.1", @@ -29,29 +29,28 @@ "loglevel": "^1.4.1", "ngtemplate-loader": "^2.0.1", "style-loader": "^0.18.2", - "ts-loader": "^2.3.1", + "ts-loader": "^2.3.2", "typescript": "^2.4.2", "url-loader": "^0.5.9", - "webpack": "^3.3.0", + "webpack": "^3.4.1", "webpack-dev-server": "^2.6.1" }, "dependencies": { - "@angular/animations": "^4.3.1", - "@angular/common": "^4.3.1", - "@angular/compiler": "^4.3.1", - "@angular/core": "^4.3.1", - "@angular/forms": "^4.3.1", - "@angular/http": "^4.3.1", - "@angular/platform-browser": "^4.3.1", - "@angular/platform-browser-dynamic": "^4.3.1", - "@angular/upgrade": "^4.3.1", - "@ng-bootstrap/ng-bootstrap": "^1.0.0-alpha.28", + "@angular/animations": "^4.3.2", + "@angular/common": "^4.3.2", + "@angular/compiler": "^4.3.2", + "@angular/core": "^4.3.2", + "@angular/forms": "^4.3.2", + "@angular/http": "^4.3.2", + "@angular/platform-browser": "^4.3.2", + "@angular/platform-browser-dynamic": "^4.3.2", + "@angular/upgrade": "^4.3.2", + "@ng-bootstrap/ng-bootstrap": "^1.0.0-alpha.29", "@nsalaun/ng-logger": "^2.0.1", - "@types/angular": "^1.6.27", + "@types/angular": "^1.6.28", "@types/c3": "^0.4.44", - "@types/node": "^8.0.16", + "@types/node": "^8.0.17", "@uirouter/angularjs": "^1.0.5", - "@uirouter/core": "^5.0.5", "angular": "^1.6.5", "angular-http-auth": "^1.5.0", "angular-resource": "^1.6.5", @@ -69,7 +68,7 @@ "ngx-toastr": "^5.3.1", "reflect-metadata": "^0.1.10", "rxjs": "^5.4.2", - "zone.js": "^0.8.14" + "zone.js": "^0.8.16" }, "scripts": { "build": "webpack --config webpack.config.js", From ecf38725e3ec26d4aad13e5f02e34e3ed60d70b8 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sat, 29 Jul 2017 23:14:00 +0200 Subject: [PATCH 145/222] Readd missing dependency. --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 7deab88..a500369 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "@types/c3": "^0.4.44", "@types/node": "^8.0.17", "@uirouter/angularjs": "^1.0.5", + "@uirouter/core": "^5.0.5", "angular": "^1.6.5", "angular-http-auth": "^1.5.0", "angular-resource": "^1.6.5", From 3eba873eb5f078b1b0b07e021b3bd8dbfad73800 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 09:21:50 +0200 Subject: [PATCH 146/222] Fix callbacks. --- src/operations/index.ts | 2 +- src/operations/operation.controller.ts | 109 ++++++++++++++----------- 2 files changed, 61 insertions(+), 50 deletions(-) diff --git a/src/operations/index.ts b/src/operations/index.ts index f370cfd..b34c81e 100644 --- a/src/operations/index.ts +++ b/src/operations/index.ts @@ -36,7 +36,7 @@ import { BalanceChartComponent } from './balanceChart.component'; import { CategoryChartComponent } from './categoryChart.component'; import { OperationService } from './operation.service'; -var OperationController = require('./operation.controller'); +import { OperationController } from './operation.controller'; export default angular.module('accountant.operations', [ ngResource, diff --git a/src/operations/operation.controller.ts b/src/operations/operation.controller.ts index a81e8e5..9077cf2 100644 --- a/src/operations/operation.controller.ts +++ b/src/operations/operation.controller.ts @@ -1,89 +1,100 @@ -var operationFormTmpl = require('./operation.form.tmpl.html'), - operationDeleteTmpl = require('./operation.delete.tmpl.html'); - +import { Component, Inject, OnInit } from '@angular/core'; import { Observable } from 'rxjs/Rx'; import { ToastrService } from 'ngx-toastr'; +var operationFormTmpl = require('./operation.form.tmpl.html'), + operationDeleteTmpl = require('./operation.delete.tmpl.html'); + +import { Account } from '../accounts/account'; import { AccountService } from '../accounts/account.service'; import { Operation } from './operation'; import { OperationService } from './operation.service'; -module.exports = function( - $modal, - accountIdService, - toastrService: ToastrService, - operationService: OperationService, - AccountService: AccountService -){ - var vm = this; +export class OperationController { + private account: Account; + private minDate: Date; + private maxDate: Date; + private operations: Operation[]; + + constructor( + private $modal, + private accountIdService, + private toastrService: ToastrService, + private operationService: OperationService, + private AccountService: AccountService + ){ + AccountService.get(this.accountIdService.get()).subscribe(account => { + this.account = account + }); + } /* * Add an empty operation. */ - vm.add = function() { + add() { var operation = new Operation(); - operation.account_id = accountIdService.get(); + operation.account_id = this.accountIdService.get(); - return vm.modify(operation); + return this.modify(operation); }; /* * Load operations. */ - vm.load = function(minDate, maxDate) { - vm.minDate = minDate; - vm.maxDate = maxDate; + load(minDate, maxDate) { + this.minDate = minDate; + this.maxDate = maxDate; - return operationService.query( - accountIdService.get(), + return this.operationService.query( + this.accountIdService.get(), minDate, maxDate ).subscribe((operations: Operation[]) => { - vm.operations = operations; + this.operations = operations; }); }; /* * Toggle pointed indicator for an operation. */ - vm.togglePointed = function(operation, rowform) { + togglePointed(operation, rowform) { operation.pointed = !operation.pointed; - vm.save(operation); + this.save(operation); }; /* * Toggle cancel indicator for an operation. */ - vm.toggleCanceled = function(operation) { + toggleCanceled(operation) { operation.canceled = !operation.canceled; - vm.save(operation); + this.save(operation); }; /* * Save an operation and return a promise. */ - vm.save = function(operation) { + save(operation) { operation.confirmed = true; var observable: Observable; if(operation.id){ - observable = operationService.update(operation); + observable = this.operationService.update(operation); } else { - observable = operationService.create(operation); + observable = this.operationService.create(operation); } return observable.subscribe((operation) => { - toastrService.success('Operation #' + operation.id + ' saved.'); + this.toastrService.success('Operation #' + operation.id + ' saved.'); - vm.load(); + this.load(this.minDate, this.maxDate); return operation; }, (result) => { - toastrService.error( + this.toastrService.error( 'Error while saving operation: ' + result.message ); }); @@ -92,15 +103,15 @@ module.exports = function( /* * Delete an operation and return a promise. */ - vm.confirmDelete = function(operation) { + confirmDelete(operation) { var title = "Delete operation #" + operation.id; - $modal({ + this.$modal({ templateUrl: operationDeleteTmpl, controller: function($scope, title, operation, $delete) { $scope.title = title; $scope.operation = operation; - $scope.$delete = function() { + $scope.$delete = () => { $scope.$hide(); $delete($scope.operation); }; @@ -108,22 +119,24 @@ module.exports = function( locals: { title: title, operation: operation, - $delete: vm.delete + $delete: (operation: Operation) => { + this.delete(operation); + } } }); }; - vm.delete = function(operation) { + delete(operation) { var id = operation.id; - return operationService.delete(operation).subscribe(() => { - toastrService.success('Operation #' + id + ' deleted.'); + return this.operationService.delete(operation).subscribe(() => { + this.toastrService.success('Operation #' + id + ' deleted.'); - vm.load(); + this.load(this.minDate, this.maxDate); return operation; }, (result) => { - toastrService.error( + this.toastrService.error( 'An error occurred while trying to delete operation #' + id + ':
' + result ); @@ -134,7 +147,7 @@ module.exports = function( * Open the popup to modify the operation, save it on confirm. * @returns a promise. */ - vm.modify = function(operation) { + modify(operation) { // FIXME Alexis Lahouze 2017-06-15 i18n var title = "Operation"; @@ -142,12 +155,12 @@ module.exports = function( title = title + " #" + operation.id; } - $modal({ + this.$modal({ templateUrl: operationFormTmpl, controller: function($scope, title, operation, $save) { $scope.title = title; $scope.operation = operation; - $scope.$save = function() { + $scope.$save = () => { $scope.$hide(); $save($scope.operation); }; @@ -155,16 +168,14 @@ module.exports = function( locals: { title: title, operation: operation, - $save: vm.save + $save: (operation: Operation) => { + this.save(operation); + } } }); }; - vm.onUpdate = function(dateRange) { - vm.load(dateRange.minDate, dateRange.maxDate); + onUpdate(dateRange) { + this.load(dateRange.minDate, dateRange.maxDate); }; - - AccountService.get(accountIdService.get()).subscribe(account => { - vm.account = account - }); }; From c3d6fa97cfc4fb6b11b7dc845dc32973cc77dbbb Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 13:15:00 +0200 Subject: [PATCH 147/222] Add missing fields in operation. --- src/operations/operation.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/operations/operation.ts b/src/operations/operation.ts index e8e2867..f122da5 100644 --- a/src/operations/operation.ts +++ b/src/operations/operation.ts @@ -6,5 +6,10 @@ export class Operation { label: string; value: number; category: string; + scheduled_operation_id: number; account_id: number; + balance: number; + confirmed: boolean; + pointed: boolean; + cancelled: boolean } From 2fdce22698affb85e7728f7a513210c7110400aa Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 13:15:16 +0200 Subject: [PATCH 148/222] Indent. --- src/operations/operation.ts | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/operations/operation.ts b/src/operations/operation.ts index f122da5..5d176c0 100644 --- a/src/operations/operation.ts +++ b/src/operations/operation.ts @@ -1,15 +1,15 @@ // vim: set tw=80 ts=2 sw=2 sts=2: export class Operation { - id: number; - operation_date: string; - label: string; - value: number; - category: string; - scheduled_operation_id: number; - account_id: number; - balance: number; - confirmed: boolean; - pointed: boolean; - cancelled: boolean + id: number; + operation_date: string; + label: string; + value: number; + category: string; + scheduled_operation_id: number; + account_id: number; + balance: number; + confirmed: boolean; + pointed: boolean; + cancelled: boolean } From 558988a57ae196607f58340f9ba3e33469bff0cd Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 13:15:49 +0200 Subject: [PATCH 149/222] Add Operation Row component. --- src/operations/operation.module.ts | 3 + src/operations/operationRow.component.ts | 169 +++++++++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 src/operations/operationRow.component.ts diff --git a/src/operations/operation.module.ts b/src/operations/operation.module.ts index b229b3b..34f87ef 100644 --- a/src/operations/operation.module.ts +++ b/src/operations/operation.module.ts @@ -10,6 +10,7 @@ import { RestangularModule } from 'ngx-restangular'; import { BalanceChartComponent } from './balanceChart.component'; import { CategoryChartComponent } from './categoryChart.component'; +import { OperationRowComponent } from './operationRow.component'; import { CategoryService } from './category.service'; import { OperationService } from './operation.service'; @@ -45,10 +46,12 @@ export function accountIdServiceFactory(i: any) { declarations: [ BalanceChartComponent, CategoryChartComponent, + OperationRowComponent, ], entryComponents: [ BalanceChartComponent, CategoryChartComponent, + OperationRowComponent, ] }) export class OperationModule {} diff --git a/src/operations/operationRow.component.ts b/src/operations/operationRow.component.ts new file mode 100644 index 0000000..e97e1f6 --- /dev/null +++ b/src/operations/operationRow.component.ts @@ -0,0 +1,169 @@ +// vim: set tw=80 ts=2 sw=2 sts=2 : +import { CurrencyPipe } from '@angular/common'; +import { Component, Inject, Input, Output, EventEmitter } from '@angular/core'; + +import { ToastrService } from 'ngx-toastr'; + +var operationFormTmpl = require('./operation.form.tmpl.html'), + operationDeleteTmpl = require('./operation.delete.tmpl.html'); + +import { Account } from '../accounts/account'; +import { Operation } from './operation'; +import { OperationService } from './operation.service'; + +@Component({ + selector: 'tr[operation-row]', + host: { + "[id]": "operation.id", + "[class.stroke]": "operation.canceled", + "[class.italic]": "!operation.confirmed", + "[class.warning]": "operation.balance < 0, danger: operation.balance < operationsCtrl.account.authorized_overdraft" + }, + template: ` +
{{ operation.operation_date | date:"yyyy-MM-dd" }}{{ operation.label }}{{ operation.value | currency:'EUR':yes }} + {{ operation.balance | currency:'EUR':true }} +{{ operation.category }} +
+ + + + + + + + + + + +
+
{{ operation.operation_date | date:"yyyy-MM-dd" }}
+ + + + + + + + + + + + + + + + + + + +
Date d'op.Libellé de l'opérationMontantSoldeCatégorieActions
+ +
+
+ + ` +}) +export class OperationController implements OnInit { private account: Account; private minDate: Date; private maxDate: Date; private operations: Operation[]; constructor( - private $modal, - private accountIdService, + @Inject("$modal") private $modal, + @Inject("accountIdService") private accountIdService, private toastrService: ToastrService, private operationService: OperationService, - private AccountService: AccountService - ){ - AccountService.get(this.accountIdService.get()).subscribe(account => { + private accountService: AccountService + ) {} + + ngOnInit() { + this.accountService.get(this.accountIdService.get()).subscribe(account => { this.account = account }); } @@ -51,28 +103,10 @@ export class OperationController { minDate, maxDate ).subscribe((operations: Operation[]) => { - this.operations = operations; + this.operations = operations.reverse(); }); }; - /* - * Toggle pointed indicator for an operation. - */ - togglePointed(operation, rowform) { - operation.pointed = !operation.pointed; - - this.save(operation); - }; - - /* - * Toggle cancel indicator for an operation. - */ - toggleCanceled(operation) { - operation.canceled = !operation.canceled; - - this.save(operation); - }; - /* * Save an operation and return a promise. */ @@ -100,60 +134,9 @@ export class OperationController { }); }; - /* - * Delete an operation and return a promise. - */ - confirmDelete(operation) { - var title = "Delete operation #" + operation.id; - - this.$modal({ - templateUrl: operationDeleteTmpl, - controller: function($scope, title, operation, $delete) { - $scope.title = title; - $scope.operation = operation; - $scope.$delete = () => { - $scope.$hide(); - $delete($scope.operation); - }; - }, - locals: { - title: title, - operation: operation, - $delete: (operation: Operation) => { - this.delete(operation); - } - } - }); - }; - - delete(operation) { - var id = operation.id; - - return this.operationService.delete(operation).subscribe(() => { - this.toastrService.success('Operation #' + id + ' deleted.'); - - this.load(this.minDate, this.maxDate); - - return operation; - }, (result) => { - this.toastrService.error( - 'An error occurred while trying to delete operation #' + - id + ':
' + result - ); - }); - }; - - /* - * Open the popup to modify the operation, save it on confirm. - * @returns a promise. - */ modify(operation) { // FIXME Alexis Lahouze 2017-06-15 i18n - var title = "Operation"; - - if (operation.id) { - title = title + " #" + operation.id; - } + var title = "New operation"; this.$modal({ templateUrl: operationFormTmpl, diff --git a/src/operations/operation.module.ts b/src/operations/operation.module.ts index 34f87ef..0ef9db3 100644 --- a/src/operations/operation.module.ts +++ b/src/operations/operation.module.ts @@ -13,6 +13,7 @@ import { CategoryChartComponent } from './categoryChart.component'; import { OperationRowComponent } from './operationRow.component'; import { CategoryService } from './category.service'; import { OperationService } from './operation.service'; +import { OperationController } from './operation.controller'; export function $modalServiceFactory(i: any) { return i.get('$modal'); @@ -47,11 +48,13 @@ export function accountIdServiceFactory(i: any) { BalanceChartComponent, CategoryChartComponent, OperationRowComponent, + OperationController, ], entryComponents: [ BalanceChartComponent, CategoryChartComponent, OperationRowComponent, + OperationController, ] }) export class OperationModule {} diff --git a/src/operations/operation.states.ts b/src/operations/operation.states.ts index 0998ad9..f3af619 100644 --- a/src/operations/operation.states.ts +++ b/src/operations/operation.states.ts @@ -1,11 +1,7 @@ // vim: set tw=80 ts=2 sw=2 sts=2 : -var operationsTmpl = require('./operations.html'); - export const OperationListState = { name: 'operations', url: '/account/:accountId/operations', - templateUrl: operationsTmpl, - controller: 'OperationController', - controllerAs: 'operationsCtrl' + component: 'operationListComponent' } From 8d63b30a32787abeb5bf6ae84142a6ac23245f9f Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 15:14:02 +0200 Subject: [PATCH 152/222] Remove unused template. --- src/operations/operations.html | 116 --------------------------------- 1 file changed, 116 deletions(-) delete mode 100644 src/operations/operations.html diff --git a/src/operations/operations.html b/src/operations/operations.html deleted file mode 100644 index b5d1ed3..0000000 --- a/src/operations/operations.html +++ /dev/null @@ -1,116 +0,0 @@ - - -
-
-
- -
-
- -
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Date d'op.Libellé de l'opérationMontantSoldeCatégorieActions
- -
- {{ operation.operation_date | date:"yyyy-MM-dd" }} - - {{ operation.label }} - - {{ operation.value | currency:"€" }} - - {{ operation.balance | currency:"€" }} - - {{ operation.category }} - -
- - - - - - - - - - - -
-
-
-
From 072efe7fc32cca88ff34e7e75833e7f72384b4f1 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 15:16:44 +0200 Subject: [PATCH 153/222] Rename Operation controller to Operation List component. --- src/operations/index.ts | 4 ++-- src/operations/operation.module.ts | 6 +++--- .../{operation.controller.ts => operationList.component.ts} | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) rename src/operations/{operation.controller.ts => operationList.component.ts} (98%) diff --git a/src/operations/index.ts b/src/operations/index.ts index 140ca28..47d6a20 100644 --- a/src/operations/index.ts +++ b/src/operations/index.ts @@ -36,7 +36,7 @@ import { BalanceChartComponent } from './balanceChart.component'; import { CategoryChartComponent } from './categoryChart.component'; import { OperationService } from './operation.service'; -import { OperationController } from './operation.controller'; +import { OperationListComponent } from './operationList.component'; export default angular.module('accountant.operations', [ ngResource, @@ -45,7 +45,7 @@ export default angular.module('accountant.operations', [ ]) .directive('operationListComponent', downgradeComponent({ - component: OperationController + component: OperationListComponent })) .name; diff --git a/src/operations/operation.module.ts b/src/operations/operation.module.ts index 0ef9db3..2aa005c 100644 --- a/src/operations/operation.module.ts +++ b/src/operations/operation.module.ts @@ -13,7 +13,7 @@ import { CategoryChartComponent } from './categoryChart.component'; import { OperationRowComponent } from './operationRow.component'; import { CategoryService } from './category.service'; import { OperationService } from './operation.service'; -import { OperationController } from './operation.controller'; +import { OperationListComponent } from './operationList.component'; export function $modalServiceFactory(i: any) { return i.get('$modal'); @@ -48,13 +48,13 @@ export function accountIdServiceFactory(i: any) { BalanceChartComponent, CategoryChartComponent, OperationRowComponent, - OperationController, + OperationListComponent, ], entryComponents: [ BalanceChartComponent, CategoryChartComponent, OperationRowComponent, - OperationController, + OperationListComponent, ] }) export class OperationModule {} diff --git a/src/operations/operation.controller.ts b/src/operations/operationList.component.ts similarity index 98% rename from src/operations/operation.controller.ts rename to src/operations/operationList.component.ts index 4dc0c5e..ad62393 100644 --- a/src/operations/operation.controller.ts +++ b/src/operations/operationList.component.ts @@ -61,7 +61,7 @@ import { OperationService } from './operation.service'; ` }) -export class OperationController implements OnInit { +export class OperationListComponent implements OnInit { private account: Account; private minDate: Date; private maxDate: Date; From b5e4b1cd087244775d6e93cbffe484782ee9de9b Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 15:22:25 +0200 Subject: [PATCH 154/222] Add Operation Delete Modal component. --- src/operations/operation.module.ts | 3 ++ .../operationDeleteModal.component.ts | 45 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 src/operations/operationDeleteModal.component.ts diff --git a/src/operations/operation.module.ts b/src/operations/operation.module.ts index 2aa005c..834f3f1 100644 --- a/src/operations/operation.module.ts +++ b/src/operations/operation.module.ts @@ -14,6 +14,7 @@ import { OperationRowComponent } from './operationRow.component'; import { CategoryService } from './category.service'; import { OperationService } from './operation.service'; import { OperationListComponent } from './operationList.component'; +import { OperationDeleteModalComponent } from './operationDeleteModal.component'; export function $modalServiceFactory(i: any) { return i.get('$modal'); @@ -49,12 +50,14 @@ export function accountIdServiceFactory(i: any) { CategoryChartComponent, OperationRowComponent, OperationListComponent, + OperationDeleteModalComponent, ], entryComponents: [ BalanceChartComponent, CategoryChartComponent, OperationRowComponent, OperationListComponent, + OperationDeleteModalComponent, ] }) export class OperationModule {} diff --git a/src/operations/operationDeleteModal.component.ts b/src/operations/operationDeleteModal.component.ts new file mode 100644 index 0000000..f3f9570 --- /dev/null +++ b/src/operations/operationDeleteModal.component.ts @@ -0,0 +1,45 @@ +// vim: set tw=80 ts=2 sw=2 sts=2: +import { Component, Input } from '@angular/core'; + +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; + +import { Operation } from './operation'; + +@Component({ + selector: 'operation-delete-modal', + template: ` + + + + + + ` +}) +export class OperationDeleteModalComponent { + @Input() operation: Operation + + constructor(private activeModal: NgbActiveModal) {} + + submit(): void { + this.activeModal.close(this.operation); + } + + cancel(): void { + this.activeModal.dismiss("closed"); + } +} From 162d98add749673dc39e778053908cb646335f92 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 15:34:12 +0200 Subject: [PATCH 155/222] Add id in operation list. --- src/operations/operationList.component.ts | 1 + src/operations/operationRow.component.ts | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/operations/operationList.component.ts b/src/operations/operationList.component.ts index ad62393..3ee8a21 100644 --- a/src/operations/operationList.component.ts +++ b/src/operations/operationList.component.ts @@ -32,6 +32,7 @@ import { OperationService } from './operation.service'; + diff --git a/src/operations/operationRow.component.ts b/src/operations/operationRow.component.ts index 9afe471..baa590c 100644 --- a/src/operations/operationRow.component.ts +++ b/src/operations/operationRow.component.ts @@ -21,6 +21,8 @@ import { OperationService } from './operation.service'; "[class.danger]": "operation.balance < account.authorized_overdraft" }, template: ` + + From bc4a69b64c3364dd80ee89fc31d6eeb82e63e98b Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 15:35:26 +0200 Subject: [PATCH 156/222] Use Operation Delete Modal in List Component. --- src/operations/operationRow.component.ts | 34 +++++++++--------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/src/operations/operationRow.component.ts b/src/operations/operationRow.component.ts index baa590c..ef7d208 100644 --- a/src/operations/operationRow.component.ts +++ b/src/operations/operationRow.component.ts @@ -2,14 +2,15 @@ import { CurrencyPipe } from '@angular/common'; import { Component, Inject, Input, Output, EventEmitter } from '@angular/core'; +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { ToastrService } from 'ngx-toastr'; -var operationFormTmpl = require('./operation.form.tmpl.html'), - operationDeleteTmpl = require('./operation.delete.tmpl.html'); +var operationFormTmpl = require('./operation.form.tmpl.html'); import { Account } from '../accounts/account'; import { Operation } from './operation'; import { OperationService } from './operation.service'; +import { OperationDeleteModalComponent } from './operationDeleteModal.component'; @Component({ selector: 'tr[operation-row]', @@ -80,6 +81,7 @@ export class OperationRowComponent { constructor( private operationService: OperationService, private toastrService: ToastrService, + private modal: NgbModal, @Inject('$modal') private $modal, ) {} @@ -110,26 +112,16 @@ export class OperationRowComponent { } confirmDelete(operation) { - var title = "Delete operation #" + operation.id; + const modal = this.modal.open(OperationDeleteModalComponent); - this.$modal({ - templateUrl: operationDeleteTmpl, - controller: function($scope, title, operation, $delete) { - $scope.title = title; - $scope.operation = operation; - $scope.$delete = () => { - $scope.$hide(); - $delete($scope.operation); - }; - }, - locals: { - title: title, - operation: operation, - $delete: (operation: Operation) => { - this.delete(operation); - } - } - }); + modal.componentInstance.operation = this.operation; + + var id = operation.id; + + modal.result.then((operation: Operation) => { + this.delete(operation); + }, (reason) => { + }) }; delete(operation) { From a5769dad839d34f060a562f11ccb603b68b43e0e Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 15:35:46 +0200 Subject: [PATCH 157/222] Fix currency. --- src/operations/operationRow.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/operations/operationRow.component.ts b/src/operations/operationRow.component.ts index ef7d208..d978268 100644 --- a/src/operations/operationRow.component.ts +++ b/src/operations/operationRow.component.ts @@ -28,7 +28,7 @@ import { OperationDeleteModalComponent } from './operationDeleteModal.component' - +
# Date d'op. Libellé de l'opération Montant{{ operation.id }}{{ operation.operation_date | date:"yyyy-MM-dd" }} {{ operation.label }}{{ operation.label }}{{ operation.value | currency:'EUR':yes }}{{ operation.value | currency:'EUR':true }} From 896daa70c5c7c0ab2ce8dfca72714ea26e38d052 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 15:36:12 +0200 Subject: [PATCH 158/222] Cleanup. --- src/scheduler/index.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/scheduler/index.ts b/src/scheduler/index.ts index 53cf72f..fdf30d9 100644 --- a/src/scheduler/index.ts +++ b/src/scheduler/index.ts @@ -40,14 +40,6 @@ export default angular.module('accountant.scheduler', [ ngStrap, accountModule ]) - .factory('toastrService', downgradeInjectable(ToastrService)) - - .factory('ngbModal', downgradeInjectable(NgbModal)) - - .factory('logger', downgradeInjectable(Logger)) - - .factory('scheduleService', downgradeInjectable(ScheduleService)) - .directive('scheduleListComponent', downgradeComponent({ component: ScheduleListComponent })) From 70eb1febff1fb96474385763e3df560bb516bc29 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 15:36:57 +0200 Subject: [PATCH 159/222] Fix Operation confirmation. --- src/operations/operationRow.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/operations/operationRow.component.ts b/src/operations/operationRow.component.ts index d978268..0b9da73 100644 --- a/src/operations/operationRow.component.ts +++ b/src/operations/operationRow.component.ts @@ -98,9 +98,9 @@ export class OperationRowComponent { }; save(operation) { - return this.operationService.update(operation).subscribe((operation) => { - operation.confirmed = true; + operation.confirmed = true; + return this.operationService.update(operation).subscribe((operation) => { this.toastrService.success('Operation #' + operation.id + ' saved.'); this.needsReload.emit(); From dcd79d085a62119528534849320e0e65de99a802 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 15:38:26 +0200 Subject: [PATCH 160/222] Remove unused template. --- src/operations/operation.delete.tmpl.html | 25 ----------------------- src/operations/operationList.component.ts | 3 +-- 2 files changed, 1 insertion(+), 27 deletions(-) delete mode 100644 src/operations/operation.delete.tmpl.html diff --git a/src/operations/operation.delete.tmpl.html b/src/operations/operation.delete.tmpl.html deleted file mode 100644 index 904ae6d..0000000 --- a/src/operations/operation.delete.tmpl.html +++ /dev/null @@ -1,25 +0,0 @@ - - diff --git a/src/operations/operationList.component.ts b/src/operations/operationList.component.ts index 3ee8a21..75196c7 100644 --- a/src/operations/operationList.component.ts +++ b/src/operations/operationList.component.ts @@ -3,8 +3,7 @@ import { Observable } from 'rxjs/Rx'; import { ToastrService } from 'ngx-toastr'; -var operationFormTmpl = require('./operation.form.tmpl.html'), - operationDeleteTmpl = require('./operation.delete.tmpl.html'); +var operationFormTmpl = require('./operation.form.tmpl.html'); import { Account } from '../accounts/account'; import { AccountService } from '../accounts/account.service'; From 10d8959178a279eb3853549ec31a31026d6a938d Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 15:40:20 +0200 Subject: [PATCH 161/222] Remove unused factory. --- src/operations/operation.factory.ts | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 src/operations/operation.factory.ts diff --git a/src/operations/operation.factory.ts b/src/operations/operation.factory.ts deleted file mode 100644 index 6e79a00..0000000 --- a/src/operations/operation.factory.ts +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = function($resource) { - return $resource( - '/api/operation/:id', { - id: '@id' - } - ); -}; From 3f6d60bb5098dc739391645cdab9427c98402cb1 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 15:50:14 +0200 Subject: [PATCH 162/222] Add Operation Form component. --- src/operations/operation.module.ts | 3 ++ src/operations/operationForm.component.ts | 63 +++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 src/operations/operationForm.component.ts diff --git a/src/operations/operation.module.ts b/src/operations/operation.module.ts index 834f3f1..7cd9bbd 100644 --- a/src/operations/operation.module.ts +++ b/src/operations/operation.module.ts @@ -15,6 +15,7 @@ import { CategoryService } from './category.service'; import { OperationService } from './operation.service'; import { OperationListComponent } from './operationList.component'; import { OperationDeleteModalComponent } from './operationDeleteModal.component'; +import { OperationFormComponent } from './operationForm.component'; export function $modalServiceFactory(i: any) { return i.get('$modal'); @@ -51,6 +52,7 @@ export function accountIdServiceFactory(i: any) { OperationRowComponent, OperationListComponent, OperationDeleteModalComponent, + OperationFormComponent, ], entryComponents: [ BalanceChartComponent, @@ -58,6 +60,7 @@ export function accountIdServiceFactory(i: any) { OperationRowComponent, OperationListComponent, OperationDeleteModalComponent, + OperationFormComponent, ] }) export class OperationModule {} diff --git a/src/operations/operationForm.component.ts b/src/operations/operationForm.component.ts new file mode 100644 index 0000000..a0669c1 --- /dev/null +++ b/src/operations/operationForm.component.ts @@ -0,0 +1,63 @@ +// vim: set tw=80 ts=2 sw=2 sts=2 : +import { AfterViewChecked, Component, EventEmitter, Input, Output, ViewChild } from '@angular/core'; +import { NgForm } from '@angular/forms'; + +import { Operation } from './operation'; + +@Component({ + selector: 'operation-form', + template: ` + +
+ +
+ +
+
+ +
+ +
+ + +
+
+ +
+ +
+ + +
+
+ +
+ +
+ + +
+
+ + ` +}) +export class OperationFormComponent implements AfterViewChecked { + @Input() operation: Operation; + @Output() onValid: EventEmitter = new EventEmitter(); + @ViewChild('form') form: NgForm; + + //dateMask = [/\d{4}/, '-', /0[1-9]|1[0-2]/, '-', /[0-2]\d|3[0-1]/]; + dateMask = ['2', '0', /\d/, /\d/, '-', /[0-1]/, /\d/, '-', /[0-3]/, /\d/]; + + constructor() {} + + ngAfterViewChecked() { + this.onValid.emit(this.form.form.valid); + } +} From fb477429ccd324c3a225aeb940808a4a833be34e Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 15:55:24 +0200 Subject: [PATCH 163/222] Add Operation Edit Modal component. --- src/operations/operation.module.ts | 3 ++ .../operationEditModal.component.ts | 53 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/operations/operationEditModal.component.ts diff --git a/src/operations/operation.module.ts b/src/operations/operation.module.ts index 7cd9bbd..ed51404 100644 --- a/src/operations/operation.module.ts +++ b/src/operations/operation.module.ts @@ -16,6 +16,7 @@ import { OperationService } from './operation.service'; import { OperationListComponent } from './operationList.component'; import { OperationDeleteModalComponent } from './operationDeleteModal.component'; import { OperationFormComponent } from './operationForm.component'; +import { OperationEditModalComponent } from './operationEditModal.component' export function $modalServiceFactory(i: any) { return i.get('$modal'); @@ -53,6 +54,7 @@ export function accountIdServiceFactory(i: any) { OperationListComponent, OperationDeleteModalComponent, OperationFormComponent, + OperationEditModalComponent, ], entryComponents: [ BalanceChartComponent, @@ -61,6 +63,7 @@ export function accountIdServiceFactory(i: any) { OperationListComponent, OperationDeleteModalComponent, OperationFormComponent, + OperationEditModalComponent, ] }) export class OperationModule {} diff --git a/src/operations/operationEditModal.component.ts b/src/operations/operationEditModal.component.ts new file mode 100644 index 0000000..064df28 --- /dev/null +++ b/src/operations/operationEditModal.component.ts @@ -0,0 +1,53 @@ +// vim: set tw=80 ts=2 sw=2 sts=2: +import { Component, Input } from '@angular/core'; +import { NgForm } from '@angular/forms'; + +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; + +import { Operation } from './operation'; + +@Component({ + selector: 'operation-edit-modal', + template: ` + + + + + + ` +}) +export class OperationEditModalComponent { + @Input() operation: Operation; + + valid: boolean = false; + + constructor(private activeModal: NgbActiveModal) {} + + title(): string { + if(this.operation.id) { + return "Operation #" + this.operation.id; + } else { + return "New operation"; + } + } + + submit(): void { + this.activeModal.close(this.operation); + } + + cancel(): void { + this.activeModal.dismiss("closed"); + } +} From 796630165170272c6db70ff4d94ec06bcd89946a Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 16:04:05 +0200 Subject: [PATCH 164/222] Add missing modules. --- src/operations/operation.module.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/operations/operation.module.ts b/src/operations/operation.module.ts index ed51404..f3e8651 100644 --- a/src/operations/operation.module.ts +++ b/src/operations/operation.module.ts @@ -5,8 +5,11 @@ import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http'; -import { NgLoggerModule, Level } from '@nsalaun/ng-logger'; import { RestangularModule } from 'ngx-restangular'; +import { NgLoggerModule, Level } from '@nsalaun/ng-logger'; +import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; +import { ToastrModule } from 'ngx-toastr'; +import { TextMaskModule } from 'angular2-text-mask'; import { BalanceChartComponent } from './balanceChart.component'; import { CategoryChartComponent } from './categoryChart.component'; @@ -33,6 +36,9 @@ export function accountIdServiceFactory(i: any) { FormsModule, NgLoggerModule, RestangularModule, + ToastrModule, + NgbModule, + TextMaskModule ], providers: [ CategoryService, From 0782675d193dbe90c95ff5a7105cac78a077ddea Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 16:04:28 +0200 Subject: [PATCH 165/222] Fix form template. --- src/operations/operationForm.component.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/operations/operationForm.component.ts b/src/operations/operationForm.component.ts index a0669c1..a069161 100644 --- a/src/operations/operationForm.component.ts +++ b/src/operations/operationForm.component.ts @@ -23,7 +23,6 @@ import { Operation } from './operation';
-
@@ -32,7 +31,6 @@ import { Operation } from './operation';
-
@@ -41,7 +39,6 @@ import { Operation } from './operation';
-
From 7b368df9b9d1b271b15b008c6cd22b6efb428c8a Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 16:10:28 +0200 Subject: [PATCH 166/222] Cleanup component. --- src/scheduler/scheduleForm.component.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/scheduler/scheduleForm.component.ts b/src/scheduler/scheduleForm.component.ts index f887594..a2155f1 100644 --- a/src/scheduler/scheduleForm.component.ts +++ b/src/scheduler/scheduleForm.component.ts @@ -2,9 +2,6 @@ import { AfterViewChecked, Component, EventEmitter, Input, Output, ViewChild } from '@angular/core'; import { NgForm } from '@angular/forms'; -import { Logger } from '@nsalaun/ng-logger'; -import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; - import { Schedule } from './schedule'; @Component({ From f6bcdcfc2b08bf8d9bb4f166150bd6ca3daf3702 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 16:10:45 +0200 Subject: [PATCH 167/222] Fix form. --- src/operations/operationForm.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/operations/operationForm.component.ts b/src/operations/operationForm.component.ts index a069161..914bb20 100644 --- a/src/operations/operationForm.component.ts +++ b/src/operations/operationForm.component.ts @@ -7,7 +7,7 @@ import { Operation } from './operation'; @Component({ selector: 'operation-form', template: ` -
+
From 6da186113907d28445bc5d48384f32a81c3f7c32 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 16:11:47 +0200 Subject: [PATCH 168/222] Use Operation Edit form to add new operation in Operation List component. --- src/operations/operationList.component.ts | 36 +++++++++-------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/src/operations/operationList.component.ts b/src/operations/operationList.component.ts index 75196c7..17aa54c 100644 --- a/src/operations/operationList.component.ts +++ b/src/operations/operationList.component.ts @@ -1,14 +1,15 @@ import { Component, Inject, OnInit } from '@angular/core'; import { Observable } from 'rxjs/Rx'; +import { Logger } from '@nsalaun/ng-logger'; +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { ToastrService } from 'ngx-toastr'; -var operationFormTmpl = require('./operation.form.tmpl.html'); - import { Account } from '../accounts/account'; import { AccountService } from '../accounts/account.service'; import { Operation } from './operation'; import { OperationService } from './operation.service'; +import { OperationEditModalComponent } from './operationEditModal.component'; @Component({ selector: 'operation-list', @@ -68,11 +69,12 @@ export class OperationListComponent implements OnInit { private operations: Operation[]; constructor( - @Inject("$modal") private $modal, @Inject("accountIdService") private accountIdService, private toastrService: ToastrService, private operationService: OperationService, - private accountService: AccountService + private accountService: AccountService, + private logger: Logger, + private ngbModal: NgbModal, ) {} ngOnInit() { @@ -136,25 +138,15 @@ export class OperationListComponent implements OnInit { modify(operation) { // FIXME Alexis Lahouze 2017-06-15 i18n - var title = "New operation"; + const modal = this.ngbModal.open(OperationEditModalComponent, { + windowClass: 'in' + }); - this.$modal({ - templateUrl: operationFormTmpl, - controller: function($scope, title, operation, $save) { - $scope.title = title; - $scope.operation = operation; - $scope.$save = () => { - $scope.$hide(); - $save($scope.operation); - }; - }, - locals: { - title: title, - operation: operation, - $save: (operation: Operation) => { - this.save(operation); - } - } + modal.componentInstance.operation = operation; + + modal.result.then((operation: Operation) => { + this.save(operation); + }, (reason) => { }); }; From 1c18d93d137479aa30caaef73a0bd6a74a8a80e1 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 16:15:22 +0200 Subject: [PATCH 169/222] Use Operation Edit form to edit operation in Operation Row component. --- src/operations/operationRow.component.ts | 34 ++++++++---------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/src/operations/operationRow.component.ts b/src/operations/operationRow.component.ts index 0b9da73..6991a4d 100644 --- a/src/operations/operationRow.component.ts +++ b/src/operations/operationRow.component.ts @@ -5,12 +5,11 @@ import { Component, Inject, Input, Output, EventEmitter } from '@angular/core'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { ToastrService } from 'ngx-toastr'; -var operationFormTmpl = require('./operation.form.tmpl.html'); - import { Account } from '../accounts/account'; import { Operation } from './operation'; import { OperationService } from './operation.service'; import { OperationDeleteModalComponent } from './operationDeleteModal.component'; +import { OperationEditModalComponent } from './operationEditModal.component'; @Component({ selector: 'tr[operation-row]', @@ -81,8 +80,7 @@ export class OperationRowComponent { constructor( private operationService: OperationService, private toastrService: ToastrService, - private modal: NgbModal, - @Inject('$modal') private $modal, + private ngbModal: NgbModal, ) {} togglePointed(operation, rowform) { @@ -112,7 +110,7 @@ export class OperationRowComponent { } confirmDelete(operation) { - const modal = this.modal.open(OperationDeleteModalComponent); + const modal = this.ngbModal.open(OperationDeleteModalComponent); modal.componentInstance.operation = this.operation; @@ -141,25 +139,15 @@ export class OperationRowComponent { modify(operation) { // FIXME Alexis Lahouze 2017-06-15 i18n - var title = "Modify operation #" + operation.id; + const modal = this.ngbModal.open(OperationEditModalComponent, { + windowClass: 'in' + }); - this.$modal({ - templateUrl: operationFormTmpl, - controller: function($scope, title, operation, $save) { - $scope.title = title; - $scope.operation = operation; - $scope.$save = () => { - $scope.$hide(); - $save($scope.operation); - }; - }, - locals: { - title: title, - operation: operation, - $save: (operation: Operation) => { - this.save(operation); - } - } + modal.componentInstance.operation = operation; + + modal.result.then((operation: Operation) => { + this.save(operation); + }, (reason) => { }); }; } From 03f069fc74676538e6bc60609a30e7d49ff9e324 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 16:22:44 +0200 Subject: [PATCH 170/222] Fix delete function in services. --- src/accounts/account.service.ts | 2 +- src/operations/operation.service.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/accounts/account.service.ts b/src/accounts/account.service.ts index c9b9f3a..5003350 100644 --- a/src/accounts/account.service.ts +++ b/src/accounts/account.service.ts @@ -37,6 +37,6 @@ export class AccountService { } delete(account: Account): Observable { - return this.one(account.id).delete(); + return this.one(account.id).remove(); } } diff --git a/src/operations/operation.service.ts b/src/operations/operation.service.ts index 084c544..5ff0931 100644 --- a/src/operations/operation.service.ts +++ b/src/operations/operation.service.ts @@ -64,6 +64,6 @@ export class OperationService { } delete(operation: Operation): Observable { - return this.one(operation.id).delete(); + return this.one(operation.id).remove(); } } From 6bc53a0cd22d0f6df54ff3fb0f8ac015a98f928f Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 16:25:10 +0200 Subject: [PATCH 171/222] Remove unused dependency. --- src/operations/balanceChart.component.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/operations/balanceChart.component.ts b/src/operations/balanceChart.component.ts index cff6d46..3773418 100644 --- a/src/operations/balanceChart.component.ts +++ b/src/operations/balanceChart.component.ts @@ -31,7 +31,6 @@ export class BalanceChartComponent implements OnInit, OnChanges { constructor( private elementRef: ElementRef, private dailyBalanceService: DailyBalanceService, - @Inject('accountIdService') private accountIdService, ) { } From 5b7a4f8aa55029ba12c48e6b55270640837288f3 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 16:27:17 +0200 Subject: [PATCH 172/222] Cleanup dependencies. --- src/operations/categoryChart.component.ts | 3 --- src/operations/index.ts | 11 ----------- 2 files changed, 14 deletions(-) diff --git a/src/operations/categoryChart.component.ts b/src/operations/categoryChart.component.ts index d041a36..5b0bd2b 100644 --- a/src/operations/categoryChart.component.ts +++ b/src/operations/categoryChart.component.ts @@ -8,8 +8,6 @@ import { OnInit, OnChanges } from '@angular/core'; -import { Logger } from '@nsalaun/ng-logger'; - import { Account } from '../accounts/account'; import { CategoryService } from './category.service'; @@ -27,7 +25,6 @@ export class CategoryChartComponent implements OnInit, OnChanges { constructor( private elementRef: ElementRef, private categoryService: CategoryService, - private logger: Logger, ) {} loadData(account: Account) { diff --git a/src/operations/index.ts b/src/operations/index.ts index 47d6a20..7c42883 100644 --- a/src/operations/index.ts +++ b/src/operations/index.ts @@ -25,22 +25,11 @@ import { downgradeComponent } from '@angular/upgrade/static'; -import { ToastrService } from 'ngx-toastr'; - -var ngResource = require('angular-resource'), - ngStrap = require('angular-strap'); - import accountModule from '@accountant/accounts'; -import { BalanceChartComponent } from './balanceChart.component'; -import { CategoryChartComponent } from './categoryChart.component'; -import { OperationService } from './operation.service'; - import { OperationListComponent } from './operationList.component'; export default angular.module('accountant.operations', [ - ngResource, - ngStrap, accountModule, ]) From d977286637387dfee4e41322290271c8c7d38627 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 16:29:07 +0200 Subject: [PATCH 173/222] Remove unused service. --- src/operations/operation.form.tmpl.html | 77 ------------------------- src/operations/operation.module.ts | 4 -- 2 files changed, 81 deletions(-) delete mode 100644 src/operations/operation.form.tmpl.html diff --git a/src/operations/operation.form.tmpl.html b/src/operations/operation.form.tmpl.html deleted file mode 100644 index c40557f..0000000 --- a/src/operations/operation.form.tmpl.html +++ /dev/null @@ -1,77 +0,0 @@ - - - - diff --git a/src/operations/operation.module.ts b/src/operations/operation.module.ts index f3e8651..2b252ce 100644 --- a/src/operations/operation.module.ts +++ b/src/operations/operation.module.ts @@ -44,10 +44,6 @@ export function accountIdServiceFactory(i: any) { CategoryService, OperationService, { - provide: '$modal', - deps: ['$injector'], - useFactory: $modalServiceFactory - }, { provide: 'accountIdService', deps: ['$injector'], useFactory: accountIdServiceFactory From 745eee03c563c51722a027010a3a5e54d6f1c2bf Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 16:32:39 +0200 Subject: [PATCH 174/222] Remove unused dependency. --- src/operations/operationEditModal.component.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/operations/operationEditModal.component.ts b/src/operations/operationEditModal.component.ts index 064df28..987287a 100644 --- a/src/operations/operationEditModal.component.ts +++ b/src/operations/operationEditModal.component.ts @@ -1,6 +1,5 @@ // vim: set tw=80 ts=2 sw=2 sts=2: import { Component, Input } from '@angular/core'; -import { NgForm } from '@angular/forms'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; From 08a35f0d2c990ecf5e1712e6c1fed571abeaefc6 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 16:33:38 +0200 Subject: [PATCH 175/222] Style. --- src/operations/operationForm.component.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/operations/operationForm.component.ts b/src/operations/operationForm.component.ts index 914bb20..2ace4f3 100644 --- a/src/operations/operationForm.component.ts +++ b/src/operations/operationForm.component.ts @@ -1,5 +1,7 @@ // vim: set tw=80 ts=2 sw=2 sts=2 : -import { AfterViewChecked, Component, EventEmitter, Input, Output, ViewChild } from '@angular/core'; +import { + AfterViewChecked, Component, EventEmitter, Input, Output, ViewChild +} from '@angular/core'; import { NgForm } from '@angular/forms'; import { Operation } from './operation'; From 73485ac1af1e4aff194fcf303f93420470d8cb12 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 16:35:15 +0200 Subject: [PATCH 176/222] Indent. --- src/operations/operationList.component.ts | 166 +++++++++++----------- 1 file changed, 84 insertions(+), 82 deletions(-) diff --git a/src/operations/operationList.component.ts b/src/operations/operationList.component.ts index 17aa54c..28285e6 100644 --- a/src/operations/operationList.component.ts +++ b/src/operations/operationList.component.ts @@ -1,3 +1,4 @@ +// vim: set tw=80 ts=2 sw=2 sts=2 : import { Component, Inject, OnInit } from '@angular/core'; import { Observable } from 'rxjs/Rx'; @@ -12,14 +13,15 @@ import { OperationService } from './operation.service'; import { OperationEditModalComponent } from './operationEditModal.component'; @Component({ - selector: 'operation-list', - template: ` + selector: 'operation-list', + template: `
+
{ - this.account = account - }); + ngOnInit() { + this.accountService.get(this.accountIdService.get()).subscribe(account => { + this.account = account + }); + } + + /* + * Add an empty operation. + */ + add() { + var operation = new Operation(); + operation.account_id = this.accountIdService.get(); + + return this.modify(operation); + }; + + /* + * Load operations. + */ + load(minDate, maxDate) { + this.minDate = minDate; + this.maxDate = maxDate; + + return this.operationService.query( + this.accountIdService.get(), + minDate, + maxDate + ).subscribe((operations: Operation[]) => { + this.operations = operations.reverse(); + }); + }; + + /* + * Save an operation and return a promise. + */ + save(operation) { + operation.confirmed = true; + + var observable: Observable; + + if(operation.id){ + observable = this.operationService.update(operation); + } else { + observable = this.operationService.create(operation); } - /* - * Add an empty operation. - */ - add() { - var operation = new Operation(); - operation.account_id = this.accountIdService.get(); + return observable.subscribe((operation) => { + this.toastrService.success('Operation #' + operation.id + ' saved.'); - return this.modify(operation); - }; + this.load(this.minDate, this.maxDate); - /* - * Load operations. - */ - load(minDate, maxDate) { - this.minDate = minDate; - this.maxDate = maxDate; + return operation; + }, (result) => { + this.toastrService.error( + 'Error while saving operation: ' + result.message + ); + }); + }; - return this.operationService.query( - this.accountIdService.get(), - minDate, - maxDate - ).subscribe((operations: Operation[]) => { - this.operations = operations.reverse(); - }); - }; + modify(operation) { + // FIXME Alexis Lahouze 2017-06-15 i18n + const modal = this.ngbModal.open(OperationEditModalComponent, { + windowClass: 'in' + }); - /* - * Save an operation and return a promise. - */ - save(operation) { - operation.confirmed = true; + modal.componentInstance.operation = operation; - var observable: Observable; + modal.result.then((operation: Operation) => { + this.save(operation); + }, (reason) => { + }); + }; - if(operation.id){ - observable = this.operationService.update(operation); - } else { - observable = this.operationService.create(operation); - } - - return observable.subscribe((operation) => { - this.toastrService.success('Operation #' + operation.id + ' saved.'); - - this.load(this.minDate, this.maxDate); - - return operation; - }, (result) => { - this.toastrService.error( - 'Error while saving operation: ' + result.message - ); - }); - }; - - modify(operation) { - // FIXME Alexis Lahouze 2017-06-15 i18n - const modal = this.ngbModal.open(OperationEditModalComponent, { - windowClass: 'in' - }); - - modal.componentInstance.operation = operation; - - modal.result.then((operation: Operation) => { - this.save(operation); - }, (reason) => { - }); - }; - - onUpdate(dateRange) { - this.load(dateRange.minDate, dateRange.maxDate); - }; + onUpdate(dateRange) { + this.load(dateRange.minDate, dateRange.maxDate); + }; }; From 25fcc34b689e50e0911ece31a2de45fcd3b17bac Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 16:36:54 +0200 Subject: [PATCH 177/222] Merge add ans modify functions in Operation List Component. --- src/operations/operationList.component.ts | 24 +++++++++-------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/operations/operationList.component.ts b/src/operations/operationList.component.ts index 28285e6..9b5a5ac 100644 --- a/src/operations/operationList.component.ts +++ b/src/operations/operationList.component.ts @@ -92,7 +92,15 @@ export class OperationListComponent implements OnInit { var operation = new Operation(); operation.account_id = this.accountIdService.get(); - return this.modify(operation); + // FIXME Alexis Lahouze 2017-06-15 i18n + const modal = this.ngbModal.open(OperationEditModalComponent); + + modal.componentInstance.operation = operation; + + modal.result.then((operation: Operation) => { + this.save(operation); + }, (reason) => { + }); }; /* @@ -138,20 +146,6 @@ export class OperationListComponent implements OnInit { }); }; - modify(operation) { - // FIXME Alexis Lahouze 2017-06-15 i18n - const modal = this.ngbModal.open(OperationEditModalComponent, { - windowClass: 'in' - }); - - modal.componentInstance.operation = operation; - - modal.result.then((operation: Operation) => { - this.save(operation); - }, (reason) => { - }); - }; - onUpdate(dateRange) { this.load(dateRange.minDate, dateRange.maxDate); }; From 5e964dd8e859e611cce64f6fb60b766b35f26c0a Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 16:38:28 +0200 Subject: [PATCH 178/222] Simplify save function. --- src/operations/operationList.component.ts | 28 +++++++++-------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/operations/operationList.component.ts b/src/operations/operationList.component.ts index 9b5a5ac..dd68568 100644 --- a/src/operations/operationList.component.ts +++ b/src/operations/operationList.component.ts @@ -125,25 +125,19 @@ export class OperationListComponent implements OnInit { save(operation) { operation.confirmed = true; - var observable: Observable; + return this.operationService.create(operation).subscribe( + (operation) => { + this.toastrService.success('Operation #' + operation.id + ' saved.'); - if(operation.id){ - observable = this.operationService.update(operation); - } else { - observable = this.operationService.create(operation); - } + this.load(this.minDate, this.maxDate); - return observable.subscribe((operation) => { - this.toastrService.success('Operation #' + operation.id + ' saved.'); - - this.load(this.minDate, this.maxDate); - - return operation; - }, (result) => { - this.toastrService.error( - 'Error while saving operation: ' + result.message - ); - }); + return operation; + }, (result) => { + this.toastrService.error( + 'Error while saving operation: ' + result.message + ); + } + ); }; onUpdate(dateRange) { From 28460e10ff890570da7d6c478be0aa060603d4c0 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 16:39:11 +0200 Subject: [PATCH 179/222] Remove return statement. --- src/operations/operationList.component.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/operations/operationList.component.ts b/src/operations/operationList.component.ts index dd68568..07743ba 100644 --- a/src/operations/operationList.component.ts +++ b/src/operations/operationList.component.ts @@ -130,8 +130,6 @@ export class OperationListComponent implements OnInit { this.toastrService.success('Operation #' + operation.id + ' saved.'); this.load(this.minDate, this.maxDate); - - return operation; }, (result) => { this.toastrService.error( 'Error while saving operation: ' + result.message From efb0f70f310c2118d890a137b08df0be1e428e23 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 16:42:02 +0200 Subject: [PATCH 180/222] Modal related stuff. --- src/accounts/accountRow.component.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/accounts/accountRow.component.ts b/src/accounts/accountRow.component.ts index 4e224d3..c78516c 100644 --- a/src/accounts/accountRow.component.ts +++ b/src/accounts/accountRow.component.ts @@ -67,14 +67,14 @@ export class AccountRowComponent implements OnInit { @Input('account-row') account: Account; @Output() needsReload: EventEmitter = new EventEmitter(); - accountBalances: AccountBalances; + private accountBalances: AccountBalances; constructor( private accountService: AccountService, private accountBalancesService: AccountBalancesService, private toastrService: ToastrService, private logger: Logger, - private modal: NgbModal + private ngbModal: NgbModal ) { this.logger.log("AccountRowComponent constructor"); } @@ -115,9 +115,7 @@ export class AccountRowComponent implements OnInit { }; confirmDelete() { - const modal = this.modal.open(AccountDeleteModalComponent, { - windowClass: 'in' - }); + const modal = this.ngbModal.open(AccountDeleteModalComponent); modal.componentInstance.account = this.account; @@ -149,9 +147,7 @@ export class AccountRowComponent implements OnInit { * Open the popup to modify the account, save it on confirm. */ modify() { - const modal = this.modal.open(AccountEditModalComponent, { - windowClass: 'in' - }); + const modal = this.ngbModal.open(AccountEditModalComponent); modal.componentInstance.account = this.account; From 3559d4acc063aadd3bc5506a601cb4e326da9fcc Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 16:44:58 +0200 Subject: [PATCH 181/222] Remove windowClass in modal open. --- src/accounts/accountList.component.ts | 4 +--- src/operations/operationRow.component.ts | 4 +--- src/scheduler/scheduleList.component.ts | 4 +--- src/scheduler/scheduleRow.component.ts | 8 ++------ 4 files changed, 5 insertions(+), 15 deletions(-) diff --git a/src/accounts/accountList.component.ts b/src/accounts/accountList.component.ts index 7ffe65c..9fc510d 100644 --- a/src/accounts/accountList.component.ts +++ b/src/accounts/accountList.component.ts @@ -70,9 +70,7 @@ export class AccountListComponent implements OnInit { * Add an empty account. */ add() { - const modal = this.ngbModal.open(AccountEditModalComponent, { - windowClass: 'in' - }); + const modal = this.ngbModal.open(AccountEditModalComponent); modal.componentInstance.account = new Account(); diff --git a/src/operations/operationRow.component.ts b/src/operations/operationRow.component.ts index 6991a4d..317e15b 100644 --- a/src/operations/operationRow.component.ts +++ b/src/operations/operationRow.component.ts @@ -139,9 +139,7 @@ export class OperationRowComponent { modify(operation) { // FIXME Alexis Lahouze 2017-06-15 i18n - const modal = this.ngbModal.open(OperationEditModalComponent, { - windowClass: 'in' - }); + const modal = this.ngbModal.open(OperationEditModalComponent); modal.componentInstance.operation = operation; diff --git a/src/scheduler/scheduleList.component.ts b/src/scheduler/scheduleList.component.ts index 244c594..17c50fc 100644 --- a/src/scheduler/scheduleList.component.ts +++ b/src/scheduler/scheduleList.component.ts @@ -76,9 +76,7 @@ export class ScheduleListComponent implements OnInit { var schedule = new Schedule(); schedule.account_id = this.accountId; - const modal = this.ngbModal.open(ScheduleEditModalComponent, { - windowClass: 'in' - }); + const modal = this.ngbModal.open(ScheduleEditModalComponent); modal.componentInstance.schedule = schedule; diff --git a/src/scheduler/scheduleRow.component.ts b/src/scheduler/scheduleRow.component.ts index 62b3547..4d67edb 100644 --- a/src/scheduler/scheduleRow.component.ts +++ b/src/scheduler/scheduleRow.component.ts @@ -75,9 +75,7 @@ export class ScheduleRowComponent { } confirmDelete() { - const modal = this.ngbModal.open(ScheduleDeleteModalComponent, { - windowClass: 'in' - }); + const modal = this.ngbModal.open(ScheduleDeleteModalComponent); modal.componentInstance.schedule = this.schedule; @@ -103,9 +101,7 @@ export class ScheduleRowComponent { } modify() { - const modal = this.ngbModal.open(ScheduleEditModalComponent, { - windowClass: 'in' - }); + const modal = this.ngbModal.open(ScheduleEditModalComponent); modal.componentInstance.schedule = this.schedule; From 19fdb785ba088d6e56cdb38adabdc3a001e0ba00 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 16:49:42 +0200 Subject: [PATCH 182/222] Remove unused template. --- src/scheduler/schedule.form.tmpl.html | 89 ------------------------- src/scheduler/scheduleList.component.ts | 2 - 2 files changed, 91 deletions(-) delete mode 100644 src/scheduler/schedule.form.tmpl.html diff --git a/src/scheduler/schedule.form.tmpl.html b/src/scheduler/schedule.form.tmpl.html deleted file mode 100644 index df1cda7..0000000 --- a/src/scheduler/schedule.form.tmpl.html +++ /dev/null @@ -1,89 +0,0 @@ - - diff --git a/src/scheduler/scheduleList.component.ts b/src/scheduler/scheduleList.component.ts index 17c50fc..c5a1f10 100644 --- a/src/scheduler/scheduleList.component.ts +++ b/src/scheduler/scheduleList.component.ts @@ -9,8 +9,6 @@ import { ScheduleEditModalComponent } from './scheduleEditModal.component'; import { ScheduleService } from './schedule.service'; import { Schedule } from './schedule'; -var scheduleFormTmpl = require('./schedule.form.tmpl.html'); - @Component({ selector: 'schedule-list', template: ` From 474b7de02d20af2b99a53abe9fe2a99bc58a3d05 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 16:49:55 +0200 Subject: [PATCH 183/222] Cleanup schedule module. --- src/scheduler/index.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/scheduler/index.ts b/src/scheduler/index.ts index fdf30d9..1a3d42e 100644 --- a/src/scheduler/index.ts +++ b/src/scheduler/index.ts @@ -18,26 +18,18 @@ /* jshint node: true */ 'use strict'; -var angular = require('angular'); +import * as angular from 'angular'; import { downgradeInjectable, downgradeComponent } from '@angular/upgrade/static'; -import { Logger } from '@nsalaun/ng-logger'; -import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; -import { ToastrService } from 'ngx-toastr'; - -var ngStrap = require('angular-strap'); - import accountModule from '@accountant/accounts'; import { ScheduleListComponent } from './scheduleList.component'; -import { ScheduleService } from './schedule.service'; export default angular.module('accountant.scheduler', [ - ngStrap, accountModule ]) .directive('scheduleListComponent', downgradeComponent({ From 38208f642067a899063f782ac3a414f8ecd6164d Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 16:51:20 +0200 Subject: [PATCH 184/222] Add missing module. --- src/login/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/login/index.ts b/src/login/index.ts index b6f3f77..78f5748 100644 --- a/src/login/index.ts +++ b/src/login/index.ts @@ -13,6 +13,7 @@ var LoginConfig = require('./login.config'); export default angular.module('accountant.login', [ ngHttpAuth, + ngStrap, ngStorage ]) From 849a7ae95c66d0eb716fcea837cd1724d270b0af Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Sun, 30 Jul 2017 16:51:41 +0200 Subject: [PATCH 185/222] Style. --- src/accounts/account.module.ts | 1 - src/accounts/accountForm.component.ts | 4 +++- src/operations/category.ts | 6 +++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/accounts/account.module.ts b/src/accounts/account.module.ts index cd1917a..bdb5bf4 100644 --- a/src/accounts/account.module.ts +++ b/src/accounts/account.module.ts @@ -50,4 +50,3 @@ import { DailyBalanceService } from './dailyBalance.service'; ] }) export class AccountModule {} - diff --git a/src/accounts/accountForm.component.ts b/src/accounts/accountForm.component.ts index 7948f1f..8de5cf0 100644 --- a/src/accounts/accountForm.component.ts +++ b/src/accounts/accountForm.component.ts @@ -1,5 +1,7 @@ // vim: set tw=80 ts=2 sw=2 sts=2 : -import { AfterViewChecked, Component, EventEmitter, Input, Output, ViewChild } from '@angular/core'; +import { + AfterViewChecked, Component, EventEmitter, Input, Output, ViewChild +} from '@angular/core'; import { NgForm } from '@angular/forms'; import { Logger } from '@nsalaun/ng-logger'; diff --git a/src/operations/category.ts b/src/operations/category.ts index fc7f2a6..3e523f9 100644 --- a/src/operations/category.ts +++ b/src/operations/category.ts @@ -1,7 +1,7 @@ // vim: set tw=80 ts=2 sw=2 sts=2 : export class Category { - category: string; - expenses: number; - revenues: number; + category: string; + expenses: number; + revenues: number; } From c9e148320614920658bafe5d7a93d32f7f0ba3ce Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Mon, 31 Jul 2017 12:50:59 +0200 Subject: [PATCH 186/222] Migrate to HttpClient in Operation module. --- src/operations/category.service.ts | 12 ++++---- src/operations/operation.module.ts | 6 ++-- src/operations/operation.service.ts | 44 +++++++++++++++-------------- 3 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/operations/category.service.ts b/src/operations/category.service.ts index 411d4b7..c7559df 100644 --- a/src/operations/category.service.ts +++ b/src/operations/category.service.ts @@ -5,14 +5,14 @@ import * as moment from 'moment'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs/Rx'; -import { Restangular } from "ngx-restangular"; +import { HttpClient, HttpParams } from "@angular/common/http"; import { Category } from './category'; @Injectable() export class CategoryService { constructor( - private restangular: Restangular + private http: HttpClient ) {} formatDate(date: Date|string) { @@ -24,16 +24,16 @@ export class CategoryService { } query(id: number, minDate: Date = null, maxDate: Date = null): Observable { - var dateRange: any = {}; + let params: HttpParams = new HttpParams(); if(minDate) { - dateRange.begin = this.formatDate(minDate); + params = params.set('begin', this.formatDate(minDate)); } if(maxDate) { - dateRange.end = this.formatDate(maxDate); + params = params.set('end', this.formatDate(maxDate)); } - return this.restangular.one('account', id).getList('category', dateRange); + return this.http.get(`/api/account/${id}/category`, { params: params}); } } diff --git a/src/operations/operation.module.ts b/src/operations/operation.module.ts index 2b252ce..fd87ff7 100644 --- a/src/operations/operation.module.ts +++ b/src/operations/operation.module.ts @@ -3,9 +3,8 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; -import { HttpModule } from '@angular/http'; +import { HttpClientModule } from '@angular/common/http'; -import { RestangularModule } from 'ngx-restangular'; import { NgLoggerModule, Level } from '@nsalaun/ng-logger'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { ToastrModule } from 'ngx-toastr'; @@ -31,11 +30,10 @@ export function accountIdServiceFactory(i: any) { @NgModule({ imports: [ - HttpModule, + HttpClientModule, CommonModule, FormsModule, NgLoggerModule, - RestangularModule, ToastrModule, NgbModule, TextMaskModule diff --git a/src/operations/operation.service.ts b/src/operations/operation.service.ts index 5ff0931..0286040 100644 --- a/src/operations/operation.service.ts +++ b/src/operations/operation.service.ts @@ -3,26 +3,18 @@ import * as moment from 'moment'; import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs/Rx'; +import { HttpClient, HttpParams } from '@angular/common/http'; -import { Restangular } from "ngx-restangular"; +import { Observable } from 'rxjs/Rx'; import { Operation } from './operation'; @Injectable() export class OperationService { constructor( - private restangular: Restangular + private http: HttpClient, ) {} - private all() { - return this.restangular.all('operation'); - } - - private one(id: number) { - return this.restangular.one('operation', id); - } - formatDate(date: Date|string) { if(date instanceof Date) { return moment(date).format('YYYY-MM-DD'); @@ -31,39 +23,49 @@ export class OperationService { return date; } + url(id?: Number): string { + if(id) { + return `/api/operation/${id}`; + } + + return `/api/operation`; + } + query( accountId: number, minDate: Date|string = null, maxDate: Date|string = null ): Observable { - var dateRange: any = { - account_id: accountId - }; + let params = new HttpParams(); + + params = params.set('account_id', `${accountId}`); if(minDate) { - dateRange.begin = this.formatDate(minDate); + params = params.set('begin', this.formatDate(minDate)); } if(maxDate) { - dateRange.end = this.formatDate(maxDate); + params = params.set('end', this.formatDate(maxDate)); } - return this.all().getList(dateRange); + return this.http.get(this.url(), { + params: params + }); } get(id: number): Observable { - return this.one(id).get(); + return this.http.get(this.url(id)); } create(operation: Operation): Observable { - return this.all().post(operation); + return this.http.post(this.url(), operation); } update(operation: Operation): Observable { - return this.one(operation.id).post(null, operation); + return this.http.post(this.url(operation.id), operation); } delete(operation: Operation): Observable { - return this.one(operation.id).remove(); + return this.http.delete(this.url(operation.id)); } } From 2d8d39442d02356919de6fcbefed2307e8cf72d2 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Mon, 31 Jul 2017 13:00:17 +0200 Subject: [PATCH 187/222] Migrate to HttpClient in Account module. --- src/accounts/account.module.ts | 6 ++---- src/accounts/account.service.ts | 27 ++++++++++++------------- src/accounts/accountBalances.service.ts | 6 +++--- src/accounts/dailyBalance.service.ts | 8 ++++---- 4 files changed, 22 insertions(+), 25 deletions(-) diff --git a/src/accounts/account.module.ts b/src/accounts/account.module.ts index bdb5bf4..c2c5e59 100644 --- a/src/accounts/account.module.ts +++ b/src/accounts/account.module.ts @@ -3,10 +3,9 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; -import { HttpModule } from '@angular/http'; +import { HttpClientModule } from '@angular/common/http'; import { NgLoggerModule, Level } from '@nsalaun/ng-logger'; -import { RestangularModule } from 'ngx-restangular'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { ToastrModule } from 'ngx-toastr'; @@ -21,11 +20,10 @@ import { DailyBalanceService } from './dailyBalance.service'; @NgModule({ imports: [ - HttpModule, + HttpClientModule, CommonModule, FormsModule, NgLoggerModule, - RestangularModule, ToastrModule, NgbModule ], diff --git a/src/accounts/account.service.ts b/src/accounts/account.service.ts index 5003350..f183fbb 100644 --- a/src/accounts/account.service.ts +++ b/src/accounts/account.service.ts @@ -1,42 +1,41 @@ // vim: set tw=80 ts=2 sw=2 sts=2 : import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs/Rx'; +import { HttpClient } from '@angular/common/http'; -import { Restangular } from "ngx-restangular"; +import { Observable } from 'rxjs/Rx'; import { Account } from './account'; @Injectable() export class AccountService { constructor( - private restangular: Restangular + private http: HttpClient ) {} - private all() { - return this.restangular.all('account'); - } + url(id?: Number): string { + if(id) { + return `/api/account/${id}`; + } - private one(id: number) { - return this.restangular.one('account', id); + return `/api/account`; } - query(): Observable { - return this.all().getList(); + return this.http.get(this.url()); } get(id: number): Observable { - return this.one(id).get(); + return this.http.get(this.url(id)); } create(account: Account): Observable { - return this.all().post(account); + return this.http.post(this.url(), account); } update(account: Account): Observable { - return this.one(account.id).post(null, account); + return this.http.post(this.url(account.id), account); } delete(account: Account): Observable { - return this.one(account.id).remove(); + return this.http.delete(this.url(account.id)); } } diff --git a/src/accounts/accountBalances.service.ts b/src/accounts/accountBalances.service.ts index 77b99fa..020b4c3 100644 --- a/src/accounts/accountBalances.service.ts +++ b/src/accounts/accountBalances.service.ts @@ -2,17 +2,17 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs/Rx'; -import { Restangular } from "ngx-restangular"; +import { HttpClient, HttpParams } from "@angular/common/http"; import { AccountBalances } from './accountBalances'; @Injectable() export class AccountBalancesService { constructor( - private restangular: Restangular + private http: HttpClient ) {} get(id: number): Observable { - return this.restangular.one('account', id).one('balances').get(); + return this.http.get(`/api/account/${id}/balances`); } } diff --git a/src/accounts/dailyBalance.service.ts b/src/accounts/dailyBalance.service.ts index 8c41dcf..774c8ea 100644 --- a/src/accounts/dailyBalance.service.ts +++ b/src/accounts/dailyBalance.service.ts @@ -1,19 +1,19 @@ // vim: set tw=80 ts=2 sw=2 sts=2: import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs/Rx'; +import { HttpClient, HttpParams } from '@angular/common/http'; -import { Restangular } from "ngx-restangular"; +import { Observable } from 'rxjs/Rx'; import { DailyBalance } from './dailyBalance'; @Injectable() export class DailyBalanceService { constructor( - private restangular: Restangular + private http: HttpClient ) {} query(id: number): Observable { - return this.restangular.one('account', id).one('daily_balances').getList(); + return this.http.get(`/api/account/${id}/daily_balances`); } } From d71656412a8b3a114bcadf07fc131e61ea4d78c1 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Mon, 31 Jul 2017 13:00:44 +0200 Subject: [PATCH 188/222] Remove unused services. --- src/accounts/index.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/accounts/index.ts b/src/accounts/index.ts index 553182b..90fe1a3 100644 --- a/src/accounts/index.ts +++ b/src/accounts/index.ts @@ -48,10 +48,6 @@ export default angular.module('accountant.accounts', [ } }) - .factory('AccountService', downgradeInjectable(AccountService)) - - .factory('DailyBalanceService', downgradeInjectable(DailyBalanceService)) - .directive('accountList', downgradeComponent({ component: AccountListComponent })) From dc30f386621cff7d8a6fd84908957e4a2613a74f Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Mon, 31 Jul 2017 13:15:45 +0200 Subject: [PATCH 189/222] Migrate to HttpClient in Schedule module. --- src/scheduler/schedule.module.ts | 6 ++---- src/scheduler/schedule.service.ts | 36 +++++++++++++++---------------- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/src/scheduler/schedule.module.ts b/src/scheduler/schedule.module.ts index b7e7649..5d2b435 100644 --- a/src/scheduler/schedule.module.ts +++ b/src/scheduler/schedule.module.ts @@ -3,9 +3,8 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; -import { HttpModule } from '@angular/http'; +import { HttpClientModule } from '@angular/common/http'; -import { RestangularModule } from 'ngx-restangular'; import { NgLoggerModule, Level } from '@nsalaun/ng-logger'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { ToastrModule } from 'ngx-toastr'; @@ -24,11 +23,10 @@ export function accountIdServiceFactory(i: any) { @NgModule({ imports: [ - HttpModule, + HttpClientModule, CommonModule, FormsModule, NgLoggerModule, - RestangularModule, ToastrModule, NgbModule, TextMaskModule diff --git a/src/scheduler/schedule.service.ts b/src/scheduler/schedule.service.ts index d29036b..1d6ced2 100644 --- a/src/scheduler/schedule.service.ts +++ b/src/scheduler/schedule.service.ts @@ -1,49 +1,47 @@ // vim: set tw=80 ts=2 sw=2 sts=2 : import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs/Rx'; +import { HttpClient, HttpParams } from '@angular/common/http'; -import { Restangular } from "ngx-restangular"; +import { Observable } from 'rxjs/Rx'; import { Schedule } from './schedule'; @Injectable() export class ScheduleService { constructor( - private restangular: Restangular + private http: HttpClient ) {} - private all() { - //return this.accountService.one(accountId).all('scheduled_operation'); - return this.restangular.all('scheduled_operation'); - } + private url(id?: number): string { + if(id) { + return `/api/scheduled_operation/${id}`; + } - private one(id: number) { - //return this.accountService.one(accountId).one('scheduled_operation', id); - return this.restangular.one('scheduled_operation', id); + return `/api/scheduled_operation`; } query(accountId: number): Observable { - return this.all().getList({ - account_id: accountId - }); + let params = new HttpParams().set('account_id', `${accountId}`); + + return this.http.get(this.url(), { params: params }); } get(accountId: number, id: number): Observable { - return this.one(id).get({ - account_id: accountId - }); + let params = new HttpParams().set('account_id', `${accountId}`); + + return this.http.get(this.url(id), { params: params }); } create(schedule: Schedule): Observable { - return this.all().post(schedule); + return this.http.post(this.url(), schedule); } update(schedule: Schedule): Observable { - return this.one(schedule.id).post(null, schedule); + return this.http.post(this.url(schedule.id), schedule); } delete(schedule: Schedule): Observable { - return this.one(schedule.id).remove(); + return this.http.delete(this.url(schedule.id)); } } From 0b0c771558988915ebe011c93a43b57f3e118b50 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Mon, 31 Jul 2017 13:16:18 +0200 Subject: [PATCH 190/222] Set url function to private. --- src/accounts/account.service.ts | 3 ++- src/operations/operation.service.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/accounts/account.service.ts b/src/accounts/account.service.ts index f183fbb..74b55eb 100644 --- a/src/accounts/account.service.ts +++ b/src/accounts/account.service.ts @@ -12,13 +12,14 @@ export class AccountService { private http: HttpClient ) {} - url(id?: Number): string { + private url(id?: Number): string { if(id) { return `/api/account/${id}`; } return `/api/account`; } + query(): Observable { return this.http.get(this.url()); } diff --git a/src/operations/operation.service.ts b/src/operations/operation.service.ts index 0286040..7504612 100644 --- a/src/operations/operation.service.ts +++ b/src/operations/operation.service.ts @@ -23,7 +23,7 @@ export class OperationService { return date; } - url(id?: Number): string { + private url(id?: Number): string { if(id) { return `/api/operation/${id}`; } From 2ae8a9cfad03ec012058aa33eb4cca55b06ad958 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Mon, 31 Jul 2017 13:17:54 +0200 Subject: [PATCH 191/222] Remove Restangular. --- package.json | 1 - src/app.module.ts | 13 ------------- 2 files changed, 14 deletions(-) diff --git a/package.json b/package.json index a500369..5df83e3 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,6 @@ "jquery": "^3.2.1", "meanie-angular-storage": "^1.3.1", "moment": "^2.18.1", - "ngx-restangular": "^1.0.11", "ngx-toastr": "^5.3.1", "reflect-metadata": "^0.1.10", "rxjs": "^5.4.2", diff --git a/src/app.module.ts b/src/app.module.ts index b7af799..5184371 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -12,7 +12,6 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { UpgradeModule } from '@angular/upgrade/static'; import { NgLoggerModule } from '@nsalaun/ng-logger'; -import { RestangularModule } from 'ngx-restangular'; import { ToastrModule } from 'ngx-toastr'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; @@ -31,18 +30,6 @@ import { ApiBaseURL, LogLevel } from './app.config'; ScheduleModule, OperationModule, NgLoggerModule.forRoot(LogLevel), - RestangularModule.forRoot((RestangularProvider) => { - RestangularProvider.setBaseUrl(ApiBaseURL); - - // Inject JSON in error instead the full response object. - RestangularProvider.setErrorInterceptor( - function(response, subject, responseHandler) { - // TODO Alexis Lahouze 2017-07-16 Handle 401 error. - subject.error(response.json()); - return false; - } - ); - }), ToastrModule.forRoot(), NgbModule.forRoot() ] From 5726d8bf2eb2e9aa197d8f84ec36b021dbd77695 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 1 Aug 2017 23:09:21 +0200 Subject: [PATCH 192/222] Upgrade routing to Angular2. --- package.json | 1 + src/accounts/account.module.ts | 5 ++++ src/accounts/account.states.ts | 7 ++--- src/accounts/accountRow.component.ts | 4 +-- src/app.component.ts | 18 +++++++++++++ src/app.module.ts | 32 ++++++++++++++--------- src/index.ejs | 9 +------ src/operations/operation.module.ts | 18 ++++--------- src/operations/operation.states.ts | 7 ++--- src/operations/operationList.component.ts | 12 ++++++--- src/scheduler/schedule.module.ts | 14 ++++------ src/scheduler/schedule.states.ts | 7 ++--- src/scheduler/scheduleList.component.ts | 6 +++-- 13 files changed, 81 insertions(+), 59 deletions(-) create mode 100644 src/app.component.ts diff --git a/package.json b/package.json index 5df83e3..9ec518a 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "@angular/http": "^4.3.2", "@angular/platform-browser": "^4.3.2", "@angular/platform-browser-dynamic": "^4.3.2", + "@angular/router": "^4.3.2", "@angular/upgrade": "^4.3.2", "@ng-bootstrap/ng-bootstrap": "^1.0.0-alpha.29", "@nsalaun/ng-logger": "^2.0.1", diff --git a/src/accounts/account.module.ts b/src/accounts/account.module.ts index c2c5e59..e19d292 100644 --- a/src/accounts/account.module.ts +++ b/src/accounts/account.module.ts @@ -4,6 +4,7 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { HttpClientModule } from '@angular/common/http'; +import { RouterModule } from '@angular/router'; import { NgLoggerModule, Level } from '@nsalaun/ng-logger'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; @@ -17,12 +18,16 @@ import { AccountEditModalComponent } from './accountEditModal.component'; import { AccountFormComponent } from './accountForm.component'; import { AccountRowComponent } from './accountRow.component'; import { DailyBalanceService } from './dailyBalance.service'; +import { AccountListState } from './account.states' @NgModule({ imports: [ HttpClientModule, CommonModule, FormsModule, + RouterModule.forChild([ + AccountListState + ]), NgLoggerModule, ToastrModule, NgbModule diff --git a/src/accounts/account.states.ts b/src/accounts/account.states.ts index e691de6..2b75fc0 100644 --- a/src/accounts/account.states.ts +++ b/src/accounts/account.states.ts @@ -1,7 +1,8 @@ // vim: set tw=80 ts=2 sw=2 sts=2 : +import { AccountListComponent } from './accountList.component'; + export const AccountListState = { - name: 'accounts', - url: '/accounts', - component: 'accountList' + path: 'accounts', + component: AccountListComponent } diff --git a/src/accounts/accountRow.component.ts b/src/accounts/accountRow.component.ts index c78516c..0ef93a6 100644 --- a/src/accounts/accountRow.component.ts +++ b/src/accounts/accountRow.component.ts @@ -22,7 +22,7 @@ import { AccountEditModalComponent } from './accountEditModal.component'; }, template: `
- {{ account.name }} + {{ account.name }} @@ -56,7 +56,7 @@ import { AccountEditModalComponent } from './accountEditModal.component'; + [routerLink]="['/account', account.id, 'scheduler']"> diff --git a/src/app.component.ts b/src/app.component.ts new file mode 100644 index 0000000..3ef7f99 --- /dev/null +++ b/src/app.component.ts @@ -0,0 +1,18 @@ +// vim: set tw=80 ts=2 sw=2 sts=2 : + +import { Component } from '@angular/core'; + +@Component({ + selector: 'accountant', + template: ` + + + +
+ +
+ ` +}) +export class AppComponent { } diff --git a/src/app.module.ts b/src/app.module.ts index 5184371..0bab9c5 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -4,12 +4,10 @@ import 'reflect-metadata'; require('./main.less'); -import { AppModule as Ng1AppModule } from './app'; - import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { UpgradeModule } from '@angular/upgrade/static'; +import { RouterModule } from '@angular/router'; import { NgLoggerModule } from '@nsalaun/ng-logger'; import { ToastrModule } from 'ngx-toastr'; @@ -19,27 +17,37 @@ import { AccountModule } from './accounts/account.module'; import { ScheduleModule } from './scheduler/schedule.module'; import { OperationModule } from './operations/operation.module'; +import { AppComponent } from './app.component'; + import { ApiBaseURL, LogLevel } from './app.config'; @NgModule({ imports: [ BrowserModule, BrowserAnimationsModule, - UpgradeModule, AccountModule, ScheduleModule, OperationModule, NgLoggerModule.forRoot(LogLevel), ToastrModule.forRoot(), - NgbModule.forRoot() - ] + NgbModule.forRoot(), + RouterModule.forRoot([ + { + path: '', + redirectTo: '/accounts', + pathMatch: 'full' + } + ], { + enableTracing: true, + useHash: true + }) + ], + declarations: [ + AppComponent + ], + bootstrap: [ AppComponent ] }) export class AppModule { - constructor(private upgrade: UpgradeModule) { } - - ngDoBootstrap() { - this.upgrade.bootstrap(document.body, [Ng1AppModule.name], { strictDi: false }); - } + constructor() {} } - diff --git a/src/index.ejs b/src/index.ejs index 2292ec3..e69bd09 100644 --- a/src/index.ejs +++ b/src/index.ejs @@ -28,14 +28,7 @@ - - - -
-
-
+ diff --git a/src/operations/operation.module.ts b/src/operations/operation.module.ts index fd87ff7..1cbb3c4 100644 --- a/src/operations/operation.module.ts +++ b/src/operations/operation.module.ts @@ -4,6 +4,7 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { HttpClientModule } from '@angular/common/http'; +import { RouterModule } from '@angular/router'; import { NgLoggerModule, Level } from '@nsalaun/ng-logger'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; @@ -19,20 +20,16 @@ import { OperationListComponent } from './operationList.component'; import { OperationDeleteModalComponent } from './operationDeleteModal.component'; import { OperationFormComponent } from './operationForm.component'; import { OperationEditModalComponent } from './operationEditModal.component' - -export function $modalServiceFactory(i: any) { - return i.get('$modal'); -} - -export function accountIdServiceFactory(i: any) { - return i.get('accountIdService'); -} +import { OperationListState } from './operation.states' @NgModule({ imports: [ HttpClientModule, CommonModule, FormsModule, + RouterModule.forChild([ + OperationListState + ]), NgLoggerModule, ToastrModule, NgbModule, @@ -41,11 +38,6 @@ export function accountIdServiceFactory(i: any) { providers: [ CategoryService, OperationService, - { - provide: 'accountIdService', - deps: ['$injector'], - useFactory: accountIdServiceFactory - } ], declarations: [ BalanceChartComponent, diff --git a/src/operations/operation.states.ts b/src/operations/operation.states.ts index f3af619..7c0de6a 100644 --- a/src/operations/operation.states.ts +++ b/src/operations/operation.states.ts @@ -1,7 +1,8 @@ // vim: set tw=80 ts=2 sw=2 sts=2 : +import { OperationListComponent } from './operationList.component'; + export const OperationListState = { - name: 'operations', - url: '/account/:accountId/operations', - component: 'operationListComponent' + path: 'account/:accountId/operations', + component: OperationListComponent } diff --git a/src/operations/operationList.component.ts b/src/operations/operationList.component.ts index 07743ba..46aa328 100644 --- a/src/operations/operationList.component.ts +++ b/src/operations/operationList.component.ts @@ -1,5 +1,7 @@ // vim: set tw=80 ts=2 sw=2 sts=2 : import { Component, Inject, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; + import { Observable } from 'rxjs/Rx'; import { Logger } from '@nsalaun/ng-logger'; @@ -71,16 +73,18 @@ export class OperationListComponent implements OnInit { private operations: Operation[]; constructor( - @Inject("accountIdService") private accountIdService, private toastrService: ToastrService, private operationService: OperationService, private accountService: AccountService, private logger: Logger, private ngbModal: NgbModal, + private route: ActivatedRoute ) {} ngOnInit() { - this.accountService.get(this.accountIdService.get()).subscribe(account => { + this.accountService.get( + +this.route.snapshot.paramMap.get('accountId') + ).subscribe(account => { this.account = account }); } @@ -90,7 +94,7 @@ export class OperationListComponent implements OnInit { */ add() { var operation = new Operation(); - operation.account_id = this.accountIdService.get(); + operation.account_id = this.account.id; // FIXME Alexis Lahouze 2017-06-15 i18n const modal = this.ngbModal.open(OperationEditModalComponent); @@ -111,7 +115,7 @@ export class OperationListComponent implements OnInit { this.maxDate = maxDate; return this.operationService.query( - this.accountIdService.get(), + this.account.id, minDate, maxDate ).subscribe((operations: Operation[]) => { diff --git a/src/scheduler/schedule.module.ts b/src/scheduler/schedule.module.ts index 5d2b435..a252add 100644 --- a/src/scheduler/schedule.module.ts +++ b/src/scheduler/schedule.module.ts @@ -4,6 +4,7 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { HttpClientModule } from '@angular/common/http'; +import { RouterModule } from '@angular/router'; import { NgLoggerModule, Level } from '@nsalaun/ng-logger'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; @@ -16,16 +17,16 @@ import { ScheduleEditModalComponent } from './scheduleEditModal.component'; import { ScheduleFormComponent } from './scheduleForm.component'; import { ScheduleRowComponent } from './scheduleRow.component'; import { ScheduleListComponent } from './scheduleList.component'; - -export function accountIdServiceFactory(i: any) { - return i.get('accountIdService'); -} +import { ScheduleListState } from './schedule.states'; @NgModule({ imports: [ HttpClientModule, CommonModule, FormsModule, + RouterModule.forChild([ + ScheduleListState + ]), NgLoggerModule, ToastrModule, NgbModule, @@ -33,11 +34,6 @@ export function accountIdServiceFactory(i: any) { ], providers: [ ScheduleService, - { - provide: 'accountIdService', - deps: ['$injector'], - useFactory: accountIdServiceFactory - } ], declarations: [ ScheduleDeleteModalComponent, diff --git a/src/scheduler/schedule.states.ts b/src/scheduler/schedule.states.ts index 7361322..74d95fc 100644 --- a/src/scheduler/schedule.states.ts +++ b/src/scheduler/schedule.states.ts @@ -1,7 +1,8 @@ // vim: set tw=80 ts=2 sw=2 sts=2 : +import { ScheduleListComponent } from './scheduleList.component'; + export const ScheduleListState = { - name: 'scheduler', - url: '/account/:accountId/scheduler', - component: 'scheduleListComponent', + path: 'account/:accountId/scheduler', + component: ScheduleListComponent, } diff --git a/src/scheduler/scheduleList.component.ts b/src/scheduler/scheduleList.component.ts index c5a1f10..5778fe3 100644 --- a/src/scheduler/scheduleList.component.ts +++ b/src/scheduler/scheduleList.component.ts @@ -1,4 +1,6 @@ import { Component, Inject, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; + import { Observable } from 'rxjs/Rx'; import { Logger } from '@nsalaun/ng-logger'; @@ -53,7 +55,7 @@ export class ScheduleListComponent implements OnInit { private scheduleService: ScheduleService, private logger: Logger, private ngbModal: NgbModal, - @Inject('accountIdService') private accountIdService + private route: ActivatedRoute, ) {} $onInit() { @@ -62,7 +64,7 @@ export class ScheduleListComponent implements OnInit { ngOnInit() { this.logger.log("ngOnInit"); - this.accountId = this.accountIdService.get(); + this.accountId = +this.route.snapshot.paramMap.get('accountId') // Load operations on controller initialization. this.load(); } From 17754f9a880d57637af4853efa493c731af7516f Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 1 Aug 2017 23:12:51 +0200 Subject: [PATCH 193/222] Cleanup Angular1 modules. --- src/accounts/index.ts | 61 ----------------------------------------- src/app.ts | 60 ---------------------------------------- src/operations/index.ts | 40 --------------------------- src/scheduler/index.ts | 39 -------------------------- 4 files changed, 200 deletions(-) delete mode 100644 src/accounts/index.ts delete mode 100644 src/app.ts delete mode 100644 src/operations/index.ts delete mode 100644 src/scheduler/index.ts diff --git a/src/accounts/index.ts b/src/accounts/index.ts deleted file mode 100644 index 90fe1a3..0000000 --- a/src/accounts/index.ts +++ /dev/null @@ -1,61 +0,0 @@ -// vim: set tw=80 ts=4 sw=4 sts=4: -/* - This file is part of Accountant. - - Accountant is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Accountant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with Accountant. If not, see . - */ -/* jshint node: true */ -'use strict'; -var angular = require('angular'); - -//declare var angular: angular.IAngularStatic; -import { - downgradeInjectable, - downgradeComponent -} from '@angular/upgrade/static'; - -import uiRouter from '@uirouter/angularjs'; - -import { AccountService } from './account.service'; -import { AccountListComponent } from './accountList.component'; -import { DailyBalanceService } from './dailyBalance.service'; - -export default angular.module('accountant.accounts', [ - uiRouter -]) - - .factory('accountIdService', function() { - var accountId: null; - - return { - get: () => { - return accountId; - }, - set: (value) => { - accountId = value; - } - } - }) - - .directive('accountList', downgradeComponent({ - component: AccountListComponent - })) - - .run(function($transitions, accountIdService) { - $transitions.onEnter({}, (transition) => { - accountIdService.set(transition.params().accountId); - }); - }) - - .name; diff --git a/src/app.ts b/src/app.ts deleted file mode 100644 index de46970..0000000 --- a/src/app.ts +++ /dev/null @@ -1,60 +0,0 @@ -// vim: set tw=80 ts=4 sw=4 sts=4: -/* - This file is part of Accountant. - - Accountant is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Accountant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with Accountant. If not, see . - */ -/* jshint node: true */ -'use strict'; - -var angular = require('angular'); - -import uiRouter from '@uirouter/angularjs'; - -import { AccountListState } from './accounts/account.states'; -import { OperationListState } from './operations/operation.states'; -import { ScheduleListState } from './scheduler/schedule.states'; - -import accountModule from '@accountant/accounts'; -import loginModule from '@accountant/login'; -import operationModule from '@accountant/operations'; -import schedulerModule from '@accountant/scheduler'; - -export const AppModule = angular.module('accountant', [ - uiRouter, - accountModule, - loginModule, - operationModule, - schedulerModule, -]); - -AppModule.config(['$uiRouterProvider', ($uiRouterProvider) => { - $uiRouterProvider.trace.enable(1); - - // Defining template and controller in function of route. - const $stateRegistry = $uiRouterProvider.stateRegistry; - - $stateRegistry.register(OperationListState); - - $stateRegistry.register(ScheduleListState); - - $stateRegistry.register(AccountListState); - - const $urlService = $uiRouterProvider.urlService; - $urlService.rules.otherwise({ - state: 'accounts' - }); -}]); - -AppModule.run(['$trace', $trace => { $trace.enable(1); }]); diff --git a/src/operations/index.ts b/src/operations/index.ts deleted file mode 100644 index 7c42883..0000000 --- a/src/operations/index.ts +++ /dev/null @@ -1,40 +0,0 @@ -// vim: set tw=80 ts=4 sw=4 sts=4: -/* - This file is part of Accountant. - - Accountant is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Accountant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with Accountant. If not, see . - */ -/* jshint node: true */ -'use strict'; - -import * as angular from 'angular'; - -import { - downgradeInjectable, - downgradeComponent -} from '@angular/upgrade/static'; - -import accountModule from '@accountant/accounts'; - -import { OperationListComponent } from './operationList.component'; - -export default angular.module('accountant.operations', [ - accountModule, -]) - - .directive('operationListComponent', downgradeComponent({ - component: OperationListComponent - })) - - .name; diff --git a/src/scheduler/index.ts b/src/scheduler/index.ts deleted file mode 100644 index 1a3d42e..0000000 --- a/src/scheduler/index.ts +++ /dev/null @@ -1,39 +0,0 @@ -// vim: set tw=80 ts=4 sw=4 sts=4: -/* - This file is part of Accountant. - - Accountant is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Accountant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with Accountant. If not, see . - */ -/* jshint node: true */ -'use strict'; - -import * as angular from 'angular'; - -import { - downgradeInjectable, - downgradeComponent -} from '@angular/upgrade/static'; - -import accountModule from '@accountant/accounts'; - -import { ScheduleListComponent } from './scheduleList.component'; - -export default angular.module('accountant.scheduler', [ - accountModule -]) - .directive('scheduleListComponent', downgradeComponent({ - component: ScheduleListComponent - })) - - .name; From a1d71b92d5c43ec1d1f41e4387fb87c62b28c08d Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 1 Aug 2017 23:14:56 +0200 Subject: [PATCH 194/222] Module order in App module. --- src/app.module.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/app.module.ts b/src/app.module.ts index 0bab9c5..1a8c58d 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -25,12 +25,6 @@ import { ApiBaseURL, LogLevel } from './app.config'; imports: [ BrowserModule, BrowserAnimationsModule, - AccountModule, - ScheduleModule, - OperationModule, - NgLoggerModule.forRoot(LogLevel), - ToastrModule.forRoot(), - NgbModule.forRoot(), RouterModule.forRoot([ { path: '', @@ -40,7 +34,13 @@ import { ApiBaseURL, LogLevel } from './app.config'; ], { enableTracing: true, useHash: true - }) + }), + NgLoggerModule.forRoot(LogLevel), + ToastrModule.forRoot(), + NgbModule.forRoot(), + AccountModule, + ScheduleModule, + OperationModule, ], declarations: [ AppComponent From 3e6cadffbd8881fd28094e2f16828a6ed2af4032 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 1 Aug 2017 23:22:44 +0200 Subject: [PATCH 195/222] Indent. --- src/scheduler/scheduleList.component.ts | 125 ++++++++++++------------ 1 file changed, 63 insertions(+), 62 deletions(-) diff --git a/src/scheduler/scheduleList.component.ts b/src/scheduler/scheduleList.component.ts index 5778fe3..9e71cfd 100644 --- a/src/scheduler/scheduleList.component.ts +++ b/src/scheduler/scheduleList.component.ts @@ -1,3 +1,4 @@ +// vim: set tw=80 ts=2 sw=2 sts=2 : import { Component, Inject, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; @@ -12,8 +13,8 @@ import { ScheduleService } from './schedule.service'; import { Schedule } from './schedule'; @Component({ - selector: 'schedule-list', - template: ` + selector: 'schedule-list', + template: `
@@ -47,70 +48,70 @@ import { Schedule } from './schedule'; ` }) export class ScheduleListComponent implements OnInit { - accountId: number; - schedules = []; + accountId: number; + schedules = []; - constructor( - private toastrService: ToastrService, - private scheduleService: ScheduleService, - private logger: Logger, - private ngbModal: NgbModal, - private route: ActivatedRoute, - ) {} + constructor( + private toastrService: ToastrService, + private scheduleService: ScheduleService, + private logger: Logger, + private ngbModal: NgbModal, + private route: ActivatedRoute, + ) {} - $onInit() { - this.ngOnInit(); + $onInit() { + this.ngOnInit(); + } + + ngOnInit() { + this.logger.log("ngOnInit"); + this.accountId = +this.route.snapshot.paramMap.get('accountId') + // Load operations on controller initialization. + this.load(); + } + + /* + * Add a new operation at the beginning of th array. + */ + add() { + var schedule = new Schedule(); + schedule.account_id = this.accountId; + + const modal = this.ngbModal.open(ScheduleEditModalComponent); + + modal.componentInstance.schedule = schedule; + + modal.result.then((schedule: Schedule) => { + this.save(schedule); + }, (reason) => function(reason) { + }); + }; + + load() { + this.logger.log("Loading schedules for accountId", this.accountId); + if(!this.accountId) { + return; } - ngOnInit() { - this.logger.log("ngOnInit"); - this.accountId = +this.route.snapshot.paramMap.get('accountId') - // Load operations on controller initialization. - this.load(); - } + this.scheduleService.query(this.accountId) + .subscribe((schedules: Schedule[]) => { + this.logger.log("Schedules loaded.", schedules); + this.schedules = schedules; + }, (reason) => { + this.logger.log("Got error", reason); + } + ); + }; - /* - * Add a new operation at the beginning of th array. - */ - add() { - var schedule = new Schedule(); - schedule.account_id = this.accountId; + save(schedule: Schedule) { + return this.scheduleService.create(schedule).subscribe((schedule: Schedule) => { + this.toastrService.success('Schedule #' + schedule.id + ' saved.'); - const modal = this.ngbModal.open(ScheduleEditModalComponent); - - modal.componentInstance.schedule = schedule; - - modal.result.then((schedule: Schedule) => { - this.save(schedule); - }, (reason) => function(reason) { - }); - }; - - load() { - this.logger.log("Loading schedules for accountId", this.accountId); - if(!this.accountId) { - return; - } - - this.scheduleService.query(this.accountId) - .subscribe((schedules: Schedule[]) => { - this.logger.log("Schedules loaded.", schedules); - this.schedules = schedules; - }, (reason) => { - this.logger.log("Got error", reason); - } - ); - }; - - save(schedule: Schedule) { - return this.scheduleService.create(schedule).subscribe((schedule: Schedule) => { - this.toastrService.success('Schedule #' + schedule.id + ' saved.'); - - this.load(); - }, (result) => { - this.toastrService.error( - 'Error while saving schedule: ' + result.message - ); - }); - }; + this.load(); + }, (result) => { + this.toastrService.error( + 'Error while saving schedule: ' + result.message + ); + }); + }; }; From 1310807939cfdc63735e6cd142c122dde9b6eab0 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 1 Aug 2017 23:25:29 +0200 Subject: [PATCH 196/222] Remove unused method. --- src/scheduler/scheduleList.component.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/scheduler/scheduleList.component.ts b/src/scheduler/scheduleList.component.ts index 9e71cfd..96a19b1 100644 --- a/src/scheduler/scheduleList.component.ts +++ b/src/scheduler/scheduleList.component.ts @@ -59,10 +59,6 @@ export class ScheduleListComponent implements OnInit { private route: ActivatedRoute, ) {} - $onInit() { - this.ngOnInit(); - } - ngOnInit() { this.logger.log("ngOnInit"); this.accountId = +this.route.snapshot.paramMap.get('accountId') From 57256e9ba7800fbdafd190bd7d27add43658cd78 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 1 Aug 2017 23:47:51 +0200 Subject: [PATCH 197/222] Cleanup old dependencies. --- package.json | 10 ---------- src/login/index.ts | 32 -------------------------------- webpack.config.js | 12 ------------ 3 files changed, 54 deletions(-) delete mode 100644 src/login/index.ts diff --git a/package.json b/package.json index 9ec518a..37dcc14 100644 --- a/package.json +++ b/package.json @@ -45,26 +45,16 @@ "@angular/platform-browser": "^4.3.2", "@angular/platform-browser-dynamic": "^4.3.2", "@angular/router": "^4.3.2", - "@angular/upgrade": "^4.3.2", "@ng-bootstrap/ng-bootstrap": "^1.0.0-alpha.29", "@nsalaun/ng-logger": "^2.0.1", - "@types/angular": "^1.6.28", "@types/c3": "^0.4.44", "@types/node": "^8.0.17", - "@uirouter/angularjs": "^1.0.5", - "@uirouter/core": "^5.0.5", - "angular": "^1.6.5", - "angular-http-auth": "^1.5.0", - "angular-resource": "^1.6.5", - "angular-strap": "^2.3.12", "angular2-text-mask": "^8.0.2", "base64util": "^1.0.2", - "bootbox": "^4.4.0", "bootstrap": "4.0.0-alpha.6", "c3": "^0.4.15", "font-awesome": "^4.7.0", "jquery": "^3.2.1", - "meanie-angular-storage": "^1.3.1", "moment": "^2.18.1", "ngx-toastr": "^5.3.1", "reflect-metadata": "^0.1.10", diff --git a/src/login/index.ts b/src/login/index.ts deleted file mode 100644 index 78f5748..0000000 --- a/src/login/index.ts +++ /dev/null @@ -1,32 +0,0 @@ -// vim: set tw=80 ts=4 sw=4 sts=4: -var angular = require('angular'); - -var ngStorage = require('meanie-angular-storage'), - ngHttpAuth = require('angular-http-auth'), - ngStrap = require('angular-strap'); - -// Note: ngHttpAuth seems to have no module.exports. -ngHttpAuth = 'http-auth-interceptor'; - -var LoginService = require('./login.service'); -var LoginConfig = require('./login.config'); - -export default angular.module('accountant.login', [ - ngHttpAuth, - ngStrap, - ngStorage -]) - - .service('LoginService', LoginService) - - .config(LoginConfig) - - .run(function($rootScope, LoginService) { - var onAuthLoginRequired = $rootScope.$on('event:auth-loginRequired', LoginService.loginModal); - - $rootScope.$on('$destroy', function() { - onAuthLoginRequired = angular.noop(); - }); - }) - - .name; diff --git a/webpack.config.js b/webpack.config.js index f4861cd..097cbe3 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -9,18 +9,6 @@ module.exports = { devtool: 'source-map', resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx', '.html'], - alias: { - '@accountant/accounts': path.resolve( - __dirname, 'src/accounts/index.ts'), - '@accountant/operations': path.resolve( - __dirname, 'src/operations/index.ts'), - '@accountant/login': path.resolve( - __dirname, 'src/login/index.ts'), - '@accountant/scheduler': path.resolve( - __dirname, 'src/scheduler/index.ts'), - '@angular/upgrade/static': path.resolve( - __dirname, 'node_modules/@angular/upgrade/bundles/upgrade-static.umd.js'), - } }, module: { rules: [{ From e2a4b0b7ec013b0a6d71956ba4e866efc9f500c8 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 1 Aug 2017 23:50:28 +0200 Subject: [PATCH 198/222] Upgrade Login service. --- src/login/login.service.ts | 49 ++++++-------------------------------- 1 file changed, 7 insertions(+), 42 deletions(-) diff --git a/src/login/login.service.ts b/src/login/login.service.ts index 8140b79..14e6994 100644 --- a/src/login/login.service.ts +++ b/src/login/login.service.ts @@ -1,45 +1,10 @@ -var base64 = require('base64util'); +import { Injectable } from '@angular/core'; -var loginTmpl = require('./login.tmpl.html'); +import * as base64 from 'base64util'; -module.exports = function($storage, $http, authService, $modal) { - var login = function(email, password) { - // Encode authentication data. - var authdata = base64.encode(email + ':' + password); - - return $http.post('/api/user/login', {}, { - ignoreAuthModule: true, - headers: { - 'authorization': 'Basic ' + authdata - } - }).then(function (result) { - $storage.session.set('refresh_token', result.data.refresh_token); - $storage.session.set('access_token', result.data.access_token); - - authService.loginConfirmed(); - }, function(result) { - loginModal(); - }); - }; - - var loginModal = function () { - $storage.session.clear(); - - $modal({ - templateUrl: loginTmpl, - controller: function($scope, $login) { - $scope.$login = function() { - $scope.$hide(); - $login($scope.email, $scope.password); - }; - }, - locals: { - $login: login, - } - }); - }; - - return { - 'loginModal': loginModal, - }; +@Injectable() +export class LoginService { + accessToken() { + return sessionStorage.getItem('access_token'); + } }; From ef4baeed881e8d4044652092314e583f8351a600 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 1 Aug 2017 23:51:52 +0200 Subject: [PATCH 199/222] Add auth interceptor bootstrap. --- src/login/authInterceptor.ts | 49 ++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/login/authInterceptor.ts diff --git a/src/login/authInterceptor.ts b/src/login/authInterceptor.ts new file mode 100644 index 0000000..7dce326 --- /dev/null +++ b/src/login/authInterceptor.ts @@ -0,0 +1,49 @@ +// vim: set tw=80 ts=2 sw=2 sts=2 : + +import { Injectable } from '@angular/core'; +import { + HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpErrorResponse +} from '@angular/common/http'; + +import { Observable} from 'rxjs/Rx'; +import 'rxjs/add/operator/map'; + +import { Logger } from '@nsalaun/ng-logger'; + +import { LoginService } from './login.service'; + +@Injectable() +export class AuthInterceptor implements HttpInterceptor { + constructor( + private logger: Logger, + private loginService: LoginService, + ) {} + + intercept( + req: HttpRequest, + next: HttpHandler + ): Observable> { + this.logger.log('Intercepted request', req, next); + + if(!req.headers.has('Authorization')) { + let accessToken: string = this.loginService.accessToken(); + + if(accessToken){ + req = req.clone({ + headers: req.headers.set('Authorization', `Bearer ${accessToken}`) + }); + } + } + + this.logger.log('Request', req); + + return next.handle(req).map( + (event: HttpEvent) => event, + (error) => { + if(error instanceof HttpErrorResponse && error.status === 401) { + this.logger.error('Unauthorized', error); + } + } + ); + } +} From beac7c6eaaa1ae17e1e6c875c79976ac24403a26 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 1 Aug 2017 23:52:34 +0200 Subject: [PATCH 200/222] Add Login module. --- src/login/login.module.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/login/login.module.ts diff --git a/src/login/login.module.ts b/src/login/login.module.ts new file mode 100644 index 0000000..d84e07c --- /dev/null +++ b/src/login/login.module.ts @@ -0,0 +1,24 @@ +// vim: set tw=80 ts=2 sw=2 sts=2 : + +import { NgModule } from '@angular/core'; +import { HTTP_INTERCEPTORS } from '@angular/common/http'; + +import { NgLoggerModule } from '@nsalaun/ng-logger'; + +import { LoginService } from './login.service'; +import { AuthInterceptor } from './authInterceptor'; + +@NgModule({ + imports: [ + NgLoggerModule, + ], + providers: [ + LoginService, + { + provide: HTTP_INTERCEPTORS, + useClass: AuthInterceptor, + multi: true + } + ] +}) +export class LoginModule {}; From cdbaf582532c343fb7450306420b9b4a97eab850 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 1 Aug 2017 23:53:27 +0200 Subject: [PATCH 201/222] Add Login class. --- src/login/login.ts | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/login/login.ts diff --git a/src/login/login.ts b/src/login/login.ts new file mode 100644 index 0000000..3424c59 --- /dev/null +++ b/src/login/login.ts @@ -0,0 +1,6 @@ +// vim: set tw=80 ts=2 sw=2 sts=2: + +export class Login { + email: string; + password: string; +} From 16bbc6785095ca2fc20127d8be262d812d73b08f Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Tue, 1 Aug 2017 23:53:57 +0200 Subject: [PATCH 202/222] Use Login module in app. --- src/app.module.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/app.module.ts b/src/app.module.ts index 1a8c58d..b4123ca 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -13,6 +13,7 @@ import { NgLoggerModule } from '@nsalaun/ng-logger'; import { ToastrModule } from 'ngx-toastr'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; +import { LoginModule } from './login/login.module'; import { AccountModule } from './accounts/account.module'; import { ScheduleModule } from './scheduler/schedule.module'; import { OperationModule } from './operations/operation.module'; @@ -35,6 +36,7 @@ import { ApiBaseURL, LogLevel } from './app.config'; enableTracing: true, useHash: true }), + LoginModule, NgLoggerModule.forRoot(LogLevel), ToastrModule.forRoot(), NgbModule.forRoot(), From 58f1abce210edb86af04559abc028a4be3ed2d3c Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Fri, 4 Aug 2017 08:32:49 +0200 Subject: [PATCH 203/222] Implement login mechanism. --- src/login/authInterceptor.ts | 85 +++++++++++++++++++++++-------- src/login/login.module.ts | 16 +++++- src/login/login.service.ts | 59 ++++++++++++++++++++- src/login/loginForm.component.ts | 33 ++++++++++++ src/login/loginModal.component.ts | 47 +++++++++++++++++ src/login/token.ts | 6 +++ 6 files changed, 223 insertions(+), 23 deletions(-) create mode 100644 src/login/loginForm.component.ts create mode 100644 src/login/loginModal.component.ts create mode 100644 src/login/token.ts diff --git a/src/login/authInterceptor.ts b/src/login/authInterceptor.ts index 7dce326..bd3c984 100644 --- a/src/login/authInterceptor.ts +++ b/src/login/authInterceptor.ts @@ -1,48 +1,91 @@ // vim: set tw=80 ts=2 sw=2 sts=2 : -import { Injectable } from '@angular/core'; +import { Injectable, Injector } from '@angular/core'; import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpErrorResponse } from '@angular/common/http'; import { Observable} from 'rxjs/Rx'; -import 'rxjs/add/operator/map'; +import 'rxjs/add/operator/catch'; import { Logger } from '@nsalaun/ng-logger'; import { LoginService } from './login.service'; +import { Token } from './token'; @Injectable() export class AuthInterceptor implements HttpInterceptor { + private observable: Observable; + constructor( private logger: Logger, - private loginService: LoginService, + private injector: Injector, ) {} + injectAuthorizationHeader(request: HttpRequest, accessToken: string) { + this.logger.log('Injecting Authorization header'); + + return request; + } + intercept( - req: HttpRequest, - next: HttpHandler + request: HttpRequest, + next: HttpHandler, + pass?: number ): Observable> { - this.logger.log('Intercepted request', req, next); - - if(!req.headers.has('Authorization')) { - let accessToken: string = this.loginService.accessToken(); - - if(accessToken){ - req = req.clone({ - headers: req.headers.set('Authorization', `Bearer ${accessToken}`) - }); - } + if(!pass) { + pass = 1; } - this.logger.log('Request', req); + let loginService = this.injector.get(LoginService); - return next.handle(req).map( - (event: HttpEvent) => event, - (error) => { - if(error instanceof HttpErrorResponse && error.status === 401) { - this.logger.error('Unauthorized', error); + if(request.url == loginService.url) { + this.logger.log("Login URL, do not handle."); + + return next.handle(request); + } + + this.logger.log(`Intercepted request, pass #${pass}`, request, next); + + let accessToken = loginService.accessToken; + + if(accessToken){ + request = request.clone({ + headers: request.headers.set('Authorization', `Bearer ${accessToken}`) + }); + } + + this.logger.log('Request', request); + + let observable: Observable = next.handle(request); + + return observable.catch( + (error, caught): Observable => { + this.logger.error("Error", error, caught); + + if(!(error instanceof HttpErrorResponse) || error.status != 401) { + return Observable.throw(error); } + + this.logger.log('Unauthorized', error); + + if(pass === 3) { + return Observable.throw(error); + } + + if(!this.observable) { + this.logger.log("No current login observable.") + this.observable = loginService.login(); + } + + return this.observable.flatMap((token: Token): Observable> => { + this.logger.log("Logged in, access_token:", token.access_token); + this.observable = null; + return this.intercept(request, next, ++pass); + }).catch((error) => { + this.observable = null; + return Observable.throw(error); + }); } ); } diff --git a/src/login/login.module.ts b/src/login/login.module.ts index d84e07c..cb1a735 100644 --- a/src/login/login.module.ts +++ b/src/login/login.module.ts @@ -1,15 +1,21 @@ // vim: set tw=80 ts=2 sw=2 sts=2 : import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { HttpClientModule } from '@angular/common/http'; import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { NgLoggerModule } from '@nsalaun/ng-logger'; -import { LoginService } from './login.service'; import { AuthInterceptor } from './authInterceptor'; +import { LoginService } from './login.service'; +import { LoginForm } from './loginForm.component'; +import { LoginModalComponent } from './loginModal.component'; @NgModule({ imports: [ + HttpClientModule, + FormsModule, NgLoggerModule, ], providers: [ @@ -19,6 +25,14 @@ import { AuthInterceptor } from './authInterceptor'; useClass: AuthInterceptor, multi: true } + ], + declarations: [ + LoginModalComponent, + LoginForm, + ], + entryComponents: [ + LoginModalComponent, + LoginForm, ] }) export class LoginModule {}; diff --git a/src/login/login.service.ts b/src/login/login.service.ts index 14e6994..7418807 100644 --- a/src/login/login.service.ts +++ b/src/login/login.service.ts @@ -1,10 +1,67 @@ import { Injectable } from '@angular/core'; +import { HttpClient, HttpHeaders } from '@angular/common/http'; + +import { Observable} from 'rxjs/Rx'; import * as base64 from 'base64util'; +import { Logger } from '@nsalaun/ng-logger'; +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; + +import { Token } from './token'; +import { LoginModalComponent } from './loginModal.component'; +import { Login } from './login'; + @Injectable() export class LoginService { - accessToken() { + + constructor( + private httpClient: HttpClient, + private logger: Logger, + private ngbModal: NgbModal, + ) {} + + public readonly url: string = '/api/user/login'; + + login(): Observable { + let modal = this.ngbModal.open(LoginModalComponent); + + sessionStorage.clear(); + + let observable: Observable = Observable.fromPromise(modal.result); + + return observable.flatMap((login: Login) => + this.doLogin(login) + ).map((token: Token): Token => { + this.accessToken = token.access_token; + return token; + }); + } + + logout() { + sessionStorage.clear(); + } + + doLogin(login: Login): Observable { + var authdata = base64.encode( + `${login.email}:${login.password}` + ); + + let headers = new HttpHeaders() + headers = headers.set('Authorization', `Basic ${authdata}`); + + this.logger.log("Headers", headers); + + return this.httpClient.post(this.url, {}, { + headers: headers + }); + } + + get accessToken(): string { return sessionStorage.getItem('access_token'); } + + set accessToken(token: string) { + sessionStorage.setItem('access_token', token); + } }; diff --git a/src/login/loginForm.component.ts b/src/login/loginForm.component.ts new file mode 100644 index 0000000..078f940 --- /dev/null +++ b/src/login/loginForm.component.ts @@ -0,0 +1,33 @@ +// vim: set tw=80 ts=2 sw=2 sts=2 : + +import { Component, Input } from '@angular/core'; +import { NgForm } from '@angular/forms'; + +import { Login } from './login'; + +@Component({ + selector: 'form[login-form]', + template: ` +
+ + +
+ +
+
+ +
+ + +
+ +
+
+ ` +}) + +export class LoginForm { + @Input('login-form') private login: Login +} diff --git a/src/login/loginModal.component.ts b/src/login/loginModal.component.ts new file mode 100644 index 0000000..7d4650e --- /dev/null +++ b/src/login/loginModal.component.ts @@ -0,0 +1,47 @@ +// vim: set tw=80 ts=2 sw=2 sts=2: + +import { Component } from '@angular/core' + +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; + +import { Login } from './login'; + +@Component({ + selector: 'login-modal', + template: ` + + + + + + ` +}) +export class LoginModalComponent { + private login: Login = new Login(); + + constructor(private activeModal: NgbActiveModal) { + + } + + submit(): void { + this.activeModal.close(this.login); + } + + cancel(): void { + this.activeModal.dismiss("closed"); + } +} diff --git a/src/login/token.ts b/src/login/token.ts new file mode 100644 index 0000000..bd6902d --- /dev/null +++ b/src/login/token.ts @@ -0,0 +1,6 @@ +// vim: set tw=80 ts=2 sw=2 sts=2 : + +export class Token { + access_token: string; + refresh_token: string; +} From e68db9f54af2b6f5490c6bb893f52d472f832643 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Fri, 4 Aug 2017 14:52:37 +0200 Subject: [PATCH 204/222] Improve Account form and edit modal. --- src/accounts/account.module.ts | 4 +- src/accounts/accountEditModal.component.ts | 19 +++-- src/accounts/accountForm.component.ts | 81 +++++++++++++--------- 3 files changed, 63 insertions(+), 41 deletions(-) diff --git a/src/accounts/account.module.ts b/src/accounts/account.module.ts index e19d292..92b0cc0 100644 --- a/src/accounts/account.module.ts +++ b/src/accounts/account.module.ts @@ -2,7 +2,7 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { FormsModule } from '@angular/forms'; +import { ReactiveFormsModule } from '@angular/forms'; import { HttpClientModule } from '@angular/common/http'; import { RouterModule } from '@angular/router'; @@ -24,7 +24,7 @@ import { AccountListState } from './account.states' imports: [ HttpClientModule, CommonModule, - FormsModule, + ReactiveFormsModule, RouterModule.forChild([ AccountListState ]), diff --git a/src/accounts/accountEditModal.component.ts b/src/accounts/accountEditModal.component.ts index 5ee29b1..231ec5f 100644 --- a/src/accounts/accountEditModal.component.ts +++ b/src/accounts/accountEditModal.component.ts @@ -1,10 +1,11 @@ // vim: set tw=80 ts=2 sw=2 sts=2: -import { Component, Input } from '@angular/core'; +import { Component, Input, ViewChild } from '@angular/core'; import { NgForm } from '@angular/forms'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { Account } from './account'; +import { AccountFormComponent } from './accountForm.component'; @Component({ selector: 'account-edit-modal', @@ -14,11 +15,11 @@ import { Account } from './account';