diff --git a/package.json b/package.json index f704d17..ab526a4 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,11 @@ "repository": "https://git.lahouze.org/xals/accountant", "license": "AGPL-1.0", "devDependencies": { + "@types/angular": "^1.6.25", + "@types/angular-resource": "^1.5.9", + "@types/angular-strap": "^2.2.32", + "@types/angular-ui-notification": "^0.0.4", + "angular-tslint-rules": "^1.0.3", "babel-core": "^6.25.0", "babel-eslint": "^7.2.3", "babel-loader": "^7.0.0", @@ -29,6 +34,9 @@ "less-loader": "^4.0.4", "ngtemplate-loader": "^2.0.0", "style-loader": "^0.18.2", + "ts-loader": "^2.2.2", + "tslint": "^5.5.0", + "tslint-loader": "^3.5.3", "url-loader": "^0.5.8", "webpack": "^2.6.1", "webpack-dev-server": "2.4.5" diff --git a/src/accounts/account.config.js b/src/accounts/account.config.js deleted file mode 100644 index e3d412b..0000000 --- a/src/accounts/account.config.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = function($resourceProvider) { - // Keep trailing slashes to avoid redirect by flask. - $resourceProvider.defaults.stripTrailingSlashes = false; -}; diff --git a/src/accounts/account.config.ts b/src/accounts/account.config.ts new file mode 100644 index 0000000..d0db34e --- /dev/null +++ b/src/accounts/account.config.ts @@ -0,0 +1,7 @@ +/// +/// + +export default function AccountConfig ($resourceProvider) { + // Keep trailing slashes to avoid redirect by flask. + $resourceProvider.defaults.stripTrailingSlashes = false; +}; diff --git a/src/accounts/account.controller.js b/src/accounts/account.controller.ts similarity index 61% rename from src/accounts/account.controller.js rename to src/accounts/account.controller.ts index 9ef9e2d..a07243f 100644 --- a/src/accounts/account.controller.js +++ b/src/accounts/account.controller.ts @@ -1,20 +1,44 @@ -var accountFormTmpl = require('./account.form.tmpl.html'), - accountDeleteTmpl = require('./account.delete.tmpl.html'); +/// +/// -module.exports = function(Account, Notification, $log, $modal) { - var vm = this; +//import accountFormTmpl from './account.form.tmpl.html'; +//import accountDeleteTmpl from './account.delete.tmpl.html'; + +import IAccount from './account.factory'; + +export interface IAccountController { + rowClass(account: IAccount) : string; + valueClass(account: IAccount, value: number) : string; + add() : void; + save(account: IAccount) : void; + confirmDelete(account: IAccount): void; + delete(account: IAccount): void; + modify(account: IAccount): void; +}; + +export default class AccountController { + static $inject = ['AccountResource', 'Notification', '$log', '$modal']; + + private accounts: IAccount[]; + + constructor( + public AccountResource: AccountResource, + public Notification: angular.uiNotification.INotificationService, + public $modal: mgcrea.ngStrap.modal.IModalService) { + + // Load accounts. + this.accounts = Account.query(); + }; /* * Return the class for an account current value compared to authorized * overdraft. */ - vm.rowClass = function(account) { - // eslint-disable-next-line camelcase + rowClass(account : IAccount): string { if (!account || !account.authorized_overdraft || !account.current) { - return; + return ''; } - // eslint-disable-next-line camelcase if (account.current < account.authorized_overdraft) { return 'danger'; } else if (account.current < 0) { @@ -25,12 +49,11 @@ module.exports = function(Account, Notification, $log, $modal) { /* * Return the class for a value compared to account authorized overdraft. */ - vm.valueClass = function(account, value) { + valueClass (account: IAccount, value: number): string { if (!account || !value) { - return; + return ''; } - // eslint-disable-next-line camelcase if (value < account.authorized_overdraft) { return 'text-danger'; } else if (value < 0) { @@ -41,36 +64,34 @@ module.exports = function(Account, Notification, $log, $modal) { /* * Add an empty account. */ - vm.add = function() { + add(): void { var account = new Account({ // eslint-disable-next-line camelcase authorized_overdraft: 0 }); // Insert account at the begining of the array. - return vm.modify(account); + this.modify(account); }; /* * Save account. */ - vm.save = function(account) { + save(account: IAccount): void { return account.$save().then(function(data) { - Notification.success('Account #' + data.id + ' saved.'); + this.Notification.success('Account #' + data.id + ' saved.'); - vm.accounts = Account.query(); - - return data; + this.accounts = Account.query(); }, function(result){ $log.error('Error while saving account', account, result); - Notification.error( + this.Notification.error( 'Error while saving account: ' + result.message ); }); }; - vm.confirmDelete = function(account) { + confirmDelete(account: IAccount): void { var title = "Delete account #" + account.id; $modal({ @@ -86,7 +107,7 @@ module.exports = function(Account, Notification, $log, $modal) { locals: { title: title, account: account, - $delete: vm.delete + $delete: this.delete } }); }; @@ -94,17 +115,15 @@ module.exports = function(Account, Notification, $log, $modal) { /* * Delete an account. */ - vm.delete = function(account) { + delete(account: IAccount): void { var id = account.id; - return account.$delete().then(function() { - Notification.success('account #' + id + ' deleted.'); + account.$delete().then(function() { + this.Notification.success('account #' + id + ' deleted.'); - vm.accounts = Account.query(); - - return account; + this.accounts = Account.query(); }, function(result) { - Notification.error( + this.Notification.error( 'An error occurred while trying to delete account #' + id + ':
' + result ); @@ -114,7 +133,7 @@ module.exports = function(Account, Notification, $log, $modal) { /* * Open the popup to modify the account, save it on confirm. */ - vm.modify = function(account) { + modify(account: IAccount): void { // FIXME Alexis Lahouze 2017-06-15 i18n var title = "Account"; @@ -137,11 +156,8 @@ module.exports = function(Account, Notification, $log, $modal) { locals: { title: title, account: account, - $save: vm.save + $save: this.save } }); }; - - // Load accounts. - vm.accounts = Account.query(); }; diff --git a/src/accounts/account.factory.js b/src/accounts/account.factory.js deleted file mode 100644 index e604e97..0000000 --- a/src/accounts/account.factory.js +++ /dev/null @@ -1,26 +0,0 @@ -module.exports = function($resource) { - var Account = $resource( - '/api/account/:id', { - id: '@id' - } - ); - - Account.prototype.getBalances = function() { - var Balances = $resource('/api/account/:id/balances', {id: this.id}); - - this.balances = Balances.get(); - }; - - Account.prototype.getBalance = function(begin, end) { - var Balance = $resource( - '/api/account/:id/balance', { - id: this.id, - begin: begin.format('YYYY-MM-DD'), - end: end.format('YYYY-MM-DD') - }); - - this.balance = Balance.get(); - }; - - return Account; -}; diff --git a/src/accounts/account.factory.ts b/src/accounts/account.factory.ts new file mode 100644 index 0000000..22305b6 --- /dev/null +++ b/src/accounts/account.factory.ts @@ -0,0 +1,19 @@ +/// +/// + +export interface IAccount extends ng.resource.IResource { + id: number; + name: string; + authorized_overdraft: number; +}; + +export interface IAccountResource extends ng.resource.IResourceClass { +}; + +export default function AccountResource($resource) { + return $resource( + '/api/account/:id', { + id: '@id' + } + ); +}; diff --git a/src/accounts/accountBalances.factory.ts b/src/accounts/accountBalances.factory.ts new file mode 100644 index 0000000..360222a --- /dev/null +++ b/src/accounts/accountBalances.factory.ts @@ -0,0 +1,21 @@ +import * as angular from 'angular'; +import 'angular-resource'; + +export interface IAccountBalances + extends ng.resource.IResource { + current: number; + pointed: number; + future: number; +}; + +export interface IAccountBalancesResource + extends ng.resource.IResourceClass { +}; + +export default function AccountBalancesResource($resource) { + return $resource( + '/api/account/:id/balances', { + id: '@id' + } + ); +}; diff --git a/src/accounts/index.js b/src/accounts/index.js index 4ae9dce..0492d03 100644 --- a/src/accounts/index.js +++ b/src/accounts/index.js @@ -25,9 +25,10 @@ var ngResource = require('angular-resource'), ngUiNotification = require('angular-ui-notification'), ngStrap = require('angular-strap'); -var AccountFactory = require('./account.factory.js'); -var AccountConfig = require('./account.config.js'); -var AccountController = require('./account.controller.js'); +var AccountBalancesFactory = require('./accountBalances.factory'); +var AccountFactory = require('./account.factory'); +var AccountConfig = require('./account.config'); +var AccountController = require('./account.controller'); module.exports = angular.module('accountant.accounts', [ ngResource, @@ -39,6 +40,7 @@ module.exports = angular.module('accountant.accounts', [ .config(AccountConfig) .factory('Account', AccountFactory) + .factory('AccountBalances', AccountBalancesFactory) .controller('AccountController', AccountController) diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..e69de29 diff --git a/webpack.config.js b/webpack.config.js index 6323694..9fedd6f 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -7,6 +7,10 @@ module.exports = { context: path.resolve(__dirname, 'src'), entry: './app.js', devtool: 'source-map', + resolve: { + // Add '.ts' and '.tsx' as a resolvable extension. + extensions: ['.webpack.js', '.web.js', '.ts', '.tsx', '.js', '.html'] + }, module: { rules: [{ enforce: 'pre', @@ -24,6 +28,31 @@ module.exports = { indent: ['error', 4] }, }, + }, { + // typescript linting + enforce: 'pre', + test: /\.tsx?$/, + exclude: /(node_modules|bootstrap)/, + loader: 'tslint-loader', + options: { + configFile: false, + emitErrors: true, + baseConfig: 'angular', + allowJs: true, + configuration: { + extends: ["angular-tslint-rules"], + include: [ + 'src/**/*' + ], + rules: { + indent: ['error', 4] + }, + }, + }, + }, { + test: /\.tsx?$/, + exclude: /node_modules/, + loader: 'ts-loader' }, { // Javascript enforce: 'pre',