From 5ccc27ae8063e59bda0e89196f717d2129bb2bb6 Mon Sep 17 00:00:00 2001 From: adam klein Date: Wed, 18 Mar 2015 16:54:46 +0200 Subject: [PATCH] Added ui-router, changed folder structure, using controller as, completed, logout --- .gitignore | 1 + .tmp/styles/main.css | 81 --------------- app/app.js | 27 +++++ .../fonts/glyphicons-halflings-regular.eot | Bin .../fonts/glyphicons-halflings-regular.svg | 0 .../fonts/glyphicons-halflings-regular.ttf | Bin .../fonts/glyphicons-halflings-regular.woff | Bin app/{ => assets}/images/yeoman.png | Bin app/{ => assets}/styles/main.css | 4 + .../interceptors/httpInterceptor.js | 0 app/index.html | 15 +-- app/scripts/app.js | 27 ----- app/scripts/controllers/login.js | 33 ------ app/scripts/controllers/main.js | 79 -------------- app/{scripts/Services => services}/backand.js | 15 ++- app/views/{ => login}/login.html | 10 +- app/views/login/login.js | 37 +++++++ app/views/main.html | 27 ----- app/views/main/main.html | 38 +++++++ app/views/main/main.js | 97 ++++++++++++++++++ bower.json | 3 +- test/karma.conf.js | 1 + 22 files changed, 233 insertions(+), 262 deletions(-) delete mode 100644 .tmp/styles/main.css create mode 100644 app/app.js rename app/{ => assets}/fonts/glyphicons-halflings-regular.eot (100%) rename app/{ => assets}/fonts/glyphicons-halflings-regular.svg (100%) rename app/{ => assets}/fonts/glyphicons-halflings-regular.ttf (100%) rename app/{ => assets}/fonts/glyphicons-halflings-regular.woff (100%) rename app/{ => assets}/images/yeoman.png (100%) rename app/{ => assets}/styles/main.css (94%) rename app/{scripts/common => config}/interceptors/httpInterceptor.js (100%) delete mode 100644 app/scripts/app.js delete mode 100644 app/scripts/controllers/login.js delete mode 100644 app/scripts/controllers/main.js rename app/{scripts/Services => services}/backand.js (75%) rename app/views/{ => login}/login.html (87%) create mode 100644 app/views/login/login.js delete mode 100644 app/views/main.html create mode 100644 app/views/main/main.html create mode 100644 app/views/main/main.js diff --git a/.gitignore b/.gitignore index e7cc9fe..a88b3ed 100755 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # general .idea .DS_Store +.tmp/** # package control node_modules diff --git a/.tmp/styles/main.css b/.tmp/styles/main.css deleted file mode 100644 index d44d7c5..0000000 --- a/.tmp/styles/main.css +++ /dev/null @@ -1,81 +0,0 @@ -/* Space out content a bit */ -body { - padding-top: 20px; - padding-bottom: 20px; -} - -/* Everything but the jumbotron gets side spacing for mobile first views */ -.header, -.marketing, -.footer { - padding-left: 15px; - padding-right: 15px; -} - -/* Custom page header */ -.header { - border-bottom: 1px solid #e5e5e5; -} -/* Make the masthead heading the same height as the navigation */ -.header h3 { - margin-top: 0; - margin-bottom: 0; - line-height: 40px; - padding-bottom: 19px; -} - -/* Custom page footer */ -.footer { - padding-top: 19px; - color: #777; - border-top: 1px solid #e5e5e5; -} - -/* Customize container */ -@media (min-width: 768px) { - .container { - max-width: 730px; - } -} -.container-narrow > hr { - margin: 30px 0; -} - -/* Main marketing message and sign up button */ -.jumbotron { - text-align: center; - border-bottom: 1px solid #e5e5e5; -} -.jumbotron .btn { - font-size: 21px; - padding: 14px 24px; -} - -/* Supporting marketing content */ -.marketing { - margin: 40px 0; -} -.marketing p + h4 { - margin-top: 28px; -} - -/* Responsive: Portrait tablets and up */ -@media screen and (min-width: 768px) { - /* Remove the padding we set earlier */ - .header, - .marketing, - .footer { - padding-left: 0; - padding-right: 0; - } - /* Space out the masthead */ - .header { - margin-bottom: 30px; - } - /* Remove the bottom border on the jumbotron for visual effect */ - .jumbotron { - border-bottom: 0; - } -} - -/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm1haW4uY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDhCQUE2QjtBQUM3QjtFQUNFLG1CQUFrQjtFQUNsQixzQkFBcUI7RUFDdEI7O0FBRUQsNEVBQTJFO0FBQzNFOzs7RUFHRSxvQkFBbUI7RUFDbkIscUJBQW9CO0VBQ3JCOztBQUVELHlCQUF3QjtBQUN4QjtFQUNFLGtDQUFpQztFQUNsQztBQUNELGtFQUFpRTtBQUNqRTtFQUNFLGVBQWM7RUFDZCxrQkFBaUI7RUFDakIsbUJBQWtCO0VBQ2xCLHNCQUFxQjtFQUN0Qjs7QUFFRCx5QkFBd0I7QUFDeEI7RUFDRSxtQkFBa0I7RUFDbEIsYUFBWTtFQUNaLCtCQUE4QjtFQUMvQjs7QUFFRCwwQkFBeUI7QUFDekI7RUFDRTtJQUNFLGtCQUFpQjtJQUNsQjtFQUNGO0FBQ0Q7RUFDRSxnQkFBZTtFQUNoQjs7QUFFRCxnREFBK0M7QUFDL0M7RUFDRSxvQkFBbUI7RUFDbkIsa0NBQWlDO0VBQ2xDO0FBQ0Q7RUFDRSxpQkFBZ0I7RUFDaEIsb0JBQW1CO0VBQ3BCOztBQUVELG1DQUFrQztBQUNsQztFQUNFLGdCQUFlO0VBQ2hCO0FBQ0Q7RUFDRSxrQkFBaUI7RUFDbEI7O0FBRUQsMENBQXlDO0FBQ3pDO0VBQ0Usd0NBQXVDO0VBQ3ZDOzs7SUFHRSxpQkFBZ0I7SUFDaEIsa0JBQWlCO0lBQ2xCO0VBQ0QsNkJBQTRCO0VBQzVCO0lBQ0UscUJBQW9CO0lBQ3JCO0VBQ0Qsa0VBQWlFO0VBQ2pFO0lBQ0Usa0JBQWlCO0lBQ2xCO0VBQ0YiLCJmaWxlIjoibWFpbi5jc3MiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBTcGFjZSBvdXQgY29udGVudCBhIGJpdCAqL1xuYm9keSB7XG4gIHBhZGRpbmctdG9wOiAyMHB4O1xuICBwYWRkaW5nLWJvdHRvbTogMjBweDtcbn1cblxuLyogRXZlcnl0aGluZyBidXQgdGhlIGp1bWJvdHJvbiBnZXRzIHNpZGUgc3BhY2luZyBmb3IgbW9iaWxlIGZpcnN0IHZpZXdzICovXG4uaGVhZGVyLFxuLm1hcmtldGluZyxcbi5mb290ZXIge1xuICBwYWRkaW5nLWxlZnQ6IDE1cHg7XG4gIHBhZGRpbmctcmlnaHQ6IDE1cHg7XG59XG5cbi8qIEN1c3RvbSBwYWdlIGhlYWRlciAqL1xuLmhlYWRlciB7XG4gIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAjZTVlNWU1O1xufVxuLyogTWFrZSB0aGUgbWFzdGhlYWQgaGVhZGluZyB0aGUgc2FtZSBoZWlnaHQgYXMgdGhlIG5hdmlnYXRpb24gKi9cbi5oZWFkZXIgaDMge1xuICBtYXJnaW4tdG9wOiAwO1xuICBtYXJnaW4tYm90dG9tOiAwO1xuICBsaW5lLWhlaWdodDogNDBweDtcbiAgcGFkZGluZy1ib3R0b206IDE5cHg7XG59XG5cbi8qIEN1c3RvbSBwYWdlIGZvb3RlciAqL1xuLmZvb3RlciB7XG4gIHBhZGRpbmctdG9wOiAxOXB4O1xuICBjb2xvcjogIzc3NztcbiAgYm9yZGVyLXRvcDogMXB4IHNvbGlkICNlNWU1ZTU7XG59XG5cbi8qIEN1c3RvbWl6ZSBjb250YWluZXIgKi9cbkBtZWRpYSAobWluLXdpZHRoOiA3NjhweCkge1xuICAuY29udGFpbmVyIHtcbiAgICBtYXgtd2lkdGg6IDczMHB4O1xuICB9XG59XG4uY29udGFpbmVyLW5hcnJvdyA+IGhyIHtcbiAgbWFyZ2luOiAzMHB4IDA7XG59XG5cbi8qIE1haW4gbWFya2V0aW5nIG1lc3NhZ2UgYW5kIHNpZ24gdXAgYnV0dG9uICovXG4uanVtYm90cm9uIHtcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xuICBib3JkZXItYm90dG9tOiAxcHggc29saWQgI2U1ZTVlNTtcbn1cbi5qdW1ib3Ryb24gLmJ0biB7XG4gIGZvbnQtc2l6ZTogMjFweDtcbiAgcGFkZGluZzogMTRweCAyNHB4O1xufVxuXG4vKiBTdXBwb3J0aW5nIG1hcmtldGluZyBjb250ZW50ICovXG4ubWFya2V0aW5nIHtcbiAgbWFyZ2luOiA0MHB4IDA7XG59XG4ubWFya2V0aW5nIHAgKyBoNCB7XG4gIG1hcmdpbi10b3A6IDI4cHg7XG59XG5cbi8qIFJlc3BvbnNpdmU6IFBvcnRyYWl0IHRhYmxldHMgYW5kIHVwICovXG5AbWVkaWEgc2NyZWVuIGFuZCAobWluLXdpZHRoOiA3NjhweCkge1xuICAvKiBSZW1vdmUgdGhlIHBhZGRpbmcgd2Ugc2V0IGVhcmxpZXIgKi9cbiAgLmhlYWRlcixcbiAgLm1hcmtldGluZyxcbiAgLmZvb3RlciB7XG4gICAgcGFkZGluZy1sZWZ0OiAwO1xuICAgIHBhZGRpbmctcmlnaHQ6IDA7XG4gIH1cbiAgLyogU3BhY2Ugb3V0IHRoZSBtYXN0aGVhZCAqL1xuICAuaGVhZGVyIHtcbiAgICBtYXJnaW4tYm90dG9tOiAzMHB4O1xuICB9XG4gIC8qIFJlbW92ZSB0aGUgYm90dG9tIGJvcmRlciBvbiB0aGUganVtYm90cm9uIGZvciB2aXN1YWwgZWZmZWN0ICovXG4gIC5qdW1ib3Ryb24ge1xuICAgIGJvcmRlci1ib3R0b206IDA7XG4gIH1cbn1cbiJdfQ== */ \ No newline at end of file diff --git a/app/app.js b/app/app.js new file mode 100644 index 0000000..0ce4dba --- /dev/null +++ b/app/app.js @@ -0,0 +1,27 @@ +'use strict'; + +angular.module('mytodoApp', [ + 'ngCookies', + 'ngResource', + 'ngSanitize', + 'ui.router', + 'ui.sortable', + 'LocalStorageModule', + 'common.interceptors.http', + 'backand' +]) + .config(['$stateProvider','$httpProvider', '$urlRouterProvider', function($stateProvider, $httpProvider, $urlRouterProvider) { + $httpProvider.interceptors.push('httpInterceptor'); + $urlRouterProvider.otherwise("/"); + $stateProvider + .state('todos', { + url: '/', + templateUrl: 'views/main/main.html', + controller: 'MainCtrl as vm' + }) + .state('login', { + url: '/login', + templateUrl: 'views/login/login.html', + controller: 'LoginCtrl as vm' + }); + }]); diff --git a/app/fonts/glyphicons-halflings-regular.eot b/app/assets/fonts/glyphicons-halflings-regular.eot similarity index 100% rename from app/fonts/glyphicons-halflings-regular.eot rename to app/assets/fonts/glyphicons-halflings-regular.eot diff --git a/app/fonts/glyphicons-halflings-regular.svg b/app/assets/fonts/glyphicons-halflings-regular.svg similarity index 100% rename from app/fonts/glyphicons-halflings-regular.svg rename to app/assets/fonts/glyphicons-halflings-regular.svg diff --git a/app/fonts/glyphicons-halflings-regular.ttf b/app/assets/fonts/glyphicons-halflings-regular.ttf similarity index 100% rename from app/fonts/glyphicons-halflings-regular.ttf rename to app/assets/fonts/glyphicons-halflings-regular.ttf diff --git a/app/fonts/glyphicons-halflings-regular.woff b/app/assets/fonts/glyphicons-halflings-regular.woff similarity index 100% rename from app/fonts/glyphicons-halflings-regular.woff rename to app/assets/fonts/glyphicons-halflings-regular.woff diff --git a/app/images/yeoman.png b/app/assets/images/yeoman.png similarity index 100% rename from app/images/yeoman.png rename to app/assets/images/yeoman.png diff --git a/app/styles/main.css b/app/assets/styles/main.css similarity index 94% rename from app/styles/main.css rename to app/assets/styles/main.css index ae7a83f..b57199b 100644 --- a/app/styles/main.css +++ b/app/assets/styles/main.css @@ -77,3 +77,7 @@ body { border-bottom: 0; } } + +.todo-completed, .todo-completed input { + text-decoration: line-through; +} \ No newline at end of file diff --git a/app/scripts/common/interceptors/httpInterceptor.js b/app/config/interceptors/httpInterceptor.js similarity index 100% rename from app/scripts/common/interceptors/httpInterceptor.js rename to app/config/interceptors/httpInterceptor.js diff --git a/app/index.html b/app/index.html index e364db2..3641f5a 100644 --- a/app/index.html +++ b/app/index.html @@ -15,7 +15,7 @@ - + @@ -24,7 +24,7 @@ -
+
+ @@ -63,11 +64,11 @@ - - - - - + + + + + diff --git a/app/scripts/app.js b/app/scripts/app.js deleted file mode 100644 index b7c89ac..0000000 --- a/app/scripts/app.js +++ /dev/null @@ -1,27 +0,0 @@ -'use strict'; - -angular.module('mytodoApp', [ - 'ngCookies', - 'ngResource', - 'ngSanitize', - 'ngRoute', - 'ui.sortable', - 'LocalStorageModule', - 'common.interceptors.http', - 'backand' -]) - .config(['$routeProvider','$httpProvider', function($routeProvider, $httpProvider){ - $httpProvider.interceptors.push('httpInterceptor'); - $routeProvider - .when('/', { - templateUrl: 'views/main.html', - controller: 'MainCtrl' - }) - .when('/login', { - templateUrl: 'views/login.html', - controller: 'LoginCtrl' - }) - .otherwise({ - redirectTo: '/' - }); - }]); diff --git a/app/scripts/controllers/login.js b/app/scripts/controllers/login.js deleted file mode 100644 index 7d1126e..0000000 --- a/app/scripts/controllers/login.js +++ /dev/null @@ -1,33 +0,0 @@ -'use strict'; - -/** - * @ngdoc function - * @name todoApp.controller:LoginCtrl - * @description - * # LoginCtrl - * Backand login control - need to implement in order to get the token for authentication - */ - -angular.module('mytodoApp') - .controller('LoginCtrl', function ($scope, $cookieStore, Backand, $location) { - - $scope.username = 'guest@backand.com'; - $scope.password = 'guest1234'; - $scope.appName = 'prod1103'; - - $scope.signIn = function() { - Backand.signin($scope.username, $scope.password, $scope.appName) - .then( - function (token) { - //save the token in the cookie - $cookieStore.put(Backand.configuration.tokenName, token); - $location.path('/'); - }, - function (data) { - console.log(data); - $scope.error = data.error_description; - } - ); - } - - }); diff --git a/app/scripts/controllers/main.js b/app/scripts/controllers/main.js deleted file mode 100644 index abc2190..0000000 --- a/app/scripts/controllers/main.js +++ /dev/null @@ -1,79 +0,0 @@ -'use strict'; - -/** - * @ngdoc function - * @name todoApp.controller:MainCtrl - * @description - * # MainCtrl - * Main controller of the todoApp fot viewing and adding to do items - */ - -angular.module('mytodoApp') - .controller('MainCtrl', function ($scope, $cookieStore, Backand, BackandService) { - - /** - * init by reading the to do list from the database - */ - (function init() { - BackandService.tableName = 'todo'; - readTodoList(); - }()); - - /** - * Read the to do list from the database - */ - function readTodoList(){ - BackandService.readAll().then(successReadList, errorHandler); - } - - /** - * Success promise call with the lit data - * @param data - */ - function successReadList(data){ - $scope.todos = data.data.data; - } - - /** - * Update item in the database - * @param todo - */ - $scope.updateTodo = function (todo){ - BackandService.update(todo.id, todo).then(null, errorHandler); - }; - - /** - * Add new item - */ - $scope.addTodo = function () { - BackandService.create({description: $scope.todo}).then(successAddTodo, errorHandler); - $scope.todo = ''; - }; - - /** - * Success promise call with the new item added - * @param data - */ - function successAddTodo(data){ - $scope.todos.push(data.data); - } - - /** - * Remove item from the database and from the scope list - * @param todo - */ - $scope.removeTodo = function (todo) { - $scope.todos.splice($scope.todos.indexOf(todo), 1); - BackandService.delete(todo.id).then(null, errorHandler); - }; - - /** - * Handle promise error call - * @param error - * @param message - */ - function errorHandler(error) { - console.log(error); - } - - }); diff --git a/app/scripts/Services/backand.js b/app/services/backand.js similarity index 75% rename from app/scripts/Services/backand.js rename to app/services/backand.js index 105d7fa..bc3ec98 100644 --- a/app/scripts/Services/backand.js +++ b/app/services/backand.js @@ -14,6 +14,11 @@ return $http({ method: 'GET', url: Backand.configuration.apiUrl + baseUrl + self.tableName + }).then(function(response) { + return response.data.data.map(function(todo) { + todo.id = parseInt(todo.id); + return todo; + }); }); }; @@ -21,6 +26,8 @@ return $http({ method: 'GET', url: Backand.configuration.apiUrl + baseUrl + self.tableName + '/' + id + }).then(function(response) { + return response.data; }); }; @@ -32,7 +39,9 @@ params: { returnObject: true } - }) + }).then(function(response) { + return response.data; + }); }; self.update = function (id, data) { @@ -40,7 +49,9 @@ method: 'PUT', url : Backand.configuration.apiUrl + baseUrl + self.tableName + '/' + id, data: data - }) + }).then(function(response) { + return response.data; + }); }; self.delete = function (id) { diff --git a/app/views/login.html b/app/views/login/login.html similarity index 87% rename from app/views/login.html rename to app/views/login/login.html index eb7879d..3677cad 100644 --- a/app/views/login.html +++ b/app/views/login/login.html @@ -4,14 +4,14 @@

Backand Login

Use your Backand username and password to login

-
+
This is not a valid email.
@@ -21,7 +21,7 @@

Use your Backand username and password to login

class="form-control" name = "password" placeholder="Your Backand password" - ng-model = "password" + ng-model = "vm.password" ng-model-options="{debounce: 200}" required>
@@ -30,7 +30,7 @@

Use your Backand username and password to login

class="form-control" name = "appName" placeholder="Your Backand app name" - ng-model = "appName" + ng-model = "vm.appName" ng-model-options="{debounce: 200}" required>
@@ -42,7 +42,7 @@

Use your Backand username and password to login

-
{{error}}
+
{{vm.error}}

diff --git a/app/views/login/login.js b/app/views/login/login.js new file mode 100644 index 0000000..52965d6 --- /dev/null +++ b/app/views/login/login.js @@ -0,0 +1,37 @@ +'use strict'; +(function() { + /** + * @ngdoc function + * @name todoApp.controller:LoginCtrl + * @description + * # LoginCtrl + * Backand login control - need to implement in order to get the token for authentication + */ + function LoginCtrl($cookieStore, Backand, $location) { + var self = this; + function init() { + self.username = 'guest@backand.com'; + self.password = 'guest1234'; + self.appName = 'prod1103'; + } + + self.signIn = function() { + Backand.signin(self.username, self.password, self.appName) + .then( + function (token) { + //save the token in the cookie + $cookieStore.put(Backand.configuration.tokenName, token); + $location.path('/'); + }, + function (data) { + console.log(data); + self.error = data && data.error_description || 'Unkown error from server'; + } + ); + } + init(); + } + + angular.module('mytodoApp') + .controller('LoginCtrl', LoginCtrl); +})(); \ No newline at end of file diff --git a/app/views/main.html b/app/views/main.html deleted file mode 100644 index f971dd9..0000000 --- a/app/views/main.html +++ /dev/null @@ -1,27 +0,0 @@ -

-

My todos

- - -
-
-
- - - - -
-
-
-

- - -
-

- - - - - -

-
-
\ No newline at end of file diff --git a/app/views/main/main.html b/app/views/main/main.html new file mode 100644 index 0000000..f72a4f3 --- /dev/null +++ b/app/views/main/main.html @@ -0,0 +1,38 @@ +
+ Log out +

My todos

+ + +
+
+
+ + + + +
+
+
+

+ + +
+

+ + + + + +

+
+
\ No newline at end of file diff --git a/app/views/main/main.js b/app/views/main/main.js new file mode 100644 index 0000000..e60a505 --- /dev/null +++ b/app/views/main/main.js @@ -0,0 +1,97 @@ +'use strict'; +(function() { + /** + * @ngdoc function + * @name todoApp.controller:MainCtrl + * @description + * # MainCtrl + * Main controller of the todoApp fot viewing and adding to do items + */ + + function MainCtrl($cookieStore, Backand, BackandService, $window) { + var self = this; + + /** + * init by reading the to do list from the database + */ + function init() { + BackandService.tableName = 'todo'; + readTodoList(); + } + + /** + * Read the to do list from the database + */ + function readTodoList(){ + BackandService.readAll().then(onReadListSuccess, errorHandler); + } + + /** + * Success promise call with the lit data + * @param data + */ + function onReadListSuccess(todos){ + self.todos = todos; + } + + /** + * Update item in the database + * @param todo + */ + self.updateTodo = function (todo){ + BackandService.update(todo.id, todo).then(null, errorHandler); + }; + + /** + * Add new item + */ + self.addTodo = function () { + BackandService.create({description: self.todo}).then(onAddTodoSuccess, errorHandler); + self.todo = ''; + }; + + /** + * Success promise call with the new item added + * @param data + */ + function onAddTodoSuccess(todo){ + self.todos.push(todo); + } + + /** + * Remove item from the database and from the list + * @param todo + */ + self.removeTodo = function (todo) { + BackandService.delete(todo.id).then(function() { + self.todos.splice(self.todos.indexOf(todo), 1); + }, errorHandler); + }; + + /** + * Handle promise error call + * @param error + * @param message + */ + function errorHandler(error) { + console.log(error); + } + + /** + * toggle completion of todo + */ + self.toggleTodo = function (todo) { + self.updateTodo(todo); + } + + self.logout = function () { + Backand.signout(); + $cookieStore.remove(Backand.configuration.tokenName); + $window.location.reload(); + } + + init(); + } + + angular.module('mytodoApp').controller('MainCtrl', MainCtrl); +})(); diff --git a/bower.json b/bower.json index 888b224..a95e70b 100644 --- a/bower.json +++ b/bower.json @@ -12,7 +12,8 @@ "angular-touch": "^1.3.0", "angular-ui-sortable": "~0.13.3", "jquery-ui": "~1.11.4", - "angular-local-storage": "~0.1.5" + "angular-local-storage": "~0.1.5", + "angular-ui-router": "~0.2.13" }, "devDependencies": { "angular-mocks": "^1.3.0" diff --git a/test/karma.conf.js b/test/karma.conf.js index afabfaa..0ff4169 100644 --- a/test/karma.conf.js +++ b/test/karma.conf.js @@ -31,6 +31,7 @@ module.exports = function(config) { 'bower_components/jquery-ui/jquery-ui.js', 'bower_components/angular-ui-sortable/sortable.js', 'bower_components/angular-local-storage/dist/angular-local-storage.js', + 'bower_components/angular-ui-router/release/angular-ui-router.js', 'bower_components/angular-mocks/angular-mocks.js', // endbower 'app/scripts/**/*.js',