diff --git a/.gitignore b/.gitignore
index 13ed183..5584cd5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,4 +6,6 @@ tmp
.DS_Store
.idea
src/libs
-data/db.json
\ No newline at end of file
+data/db.json
+dist/
+src/dist/
\ No newline at end of file
diff --git a/README.md b/README.md
index d93a6f8..1fc486c 100644
--- a/README.md
+++ b/README.md
@@ -18,4 +18,50 @@ To run the application we type
`npm start` - this loads the application using a local webserver, check the console for the port number to use.
-The application is a simple contacts application where you can search, create or edit a contact.
\ No newline at end of file
+The application is a simple contacts application where you can search, create or edit a contact.
+
+# Steps for Migration.
+
+Preparing for migration:
+
+STEP 1:
+
+Follow the step 1 of angular style guide https://github.com/johnpapa/angular-styleguide
+
+Single Responsibility: Organize the code in such a maner that 1 file contains only one component.
+
+STEP 2:
+
+Move all the dependencies from bower to npm with approprate npm naming and version in package.json and run npm install.
+
+Convert all the JS files to TS files.
+Add index.ts files in each directory importing all the entities.
+
+install following dev dependencies: rimraf, ts-loader, typescript, webpack, @types/angular
+npm install rimraf ts-loader typescript webpack @types/angular --save-dev
+
+run tsc --init in project dir to generate tsconfig.json file and set appropriate ts configuration options.
+
+Create webpack.config.js file and configure webpack options accordingly.
+
+add amin.ts file containing all the imports corresponding to the scripts in index.html file and remove scripts from index.html file.
+
+add bundle.js file in script tag in index.html file.
+
+add build script in package.json rimraf src/dist && webpack --bail --progress --profile
+
+run build scipt start the app and verify if everything works file.
+
+optionally can add dist folders to .gitignore file.
+
+STEP 3:
+
+upgrade angularjs version to lates version by updating the version number in package.json file. Run npm i then npm run build and start the app to verify if everything is working if there are any errors refer to angularjs change log to look for breaking anges and fix those.
+
+STEP 4:
+
+Componentify the angularjs version.
+
+i.e : convert the controllers and directives i.e anything with a view to angularjs components.
+remove the imports of controllers and directives from main.ts and add components import.
+change the app.routes to refer to the new components.
diff --git a/package.json b/package.json
index 2e9e524..6ea3f15 100644
--- a/package.json
+++ b/package.json
@@ -6,14 +6,36 @@
"scripts": {
"server": "cp ./data/orig-db.json ./data/db.json && json-server --watch ./data/db.json",
"setup": "bower install",
- "start": "cd src && serve"
+ "start": "cd src && serve",
+ "build": "rimraf src/dist && webpack --bail --progress --profile"
},
"author": "",
"license": "ISC",
- "dependencies": {},
+ "dependencies": {
+ "angular": "1.8.2",
+ "angular-animate": "1.8.2",
+ "angular-auto-validate": "^1.19.0",
+ "angular-ladda": "^0.4.3",
+ "angular-resource": "1.8.2",
+ "angular-spinner": "^1.0.1",
+ "angular-strap": "^2.3.12",
+ "angular-ui-router": "^0.4.2",
+ "angularjs-toaster": "^2.1.0",
+ "bootstrap": "3.3.2",
+ "bootstrap-additions": "0.3.1",
+ "font-awesome": "4.3.0",
+ "jquery": "2.1.3",
+ "ng-infinite-scroll": "1.2.1"
+ },
"devDependencies": {
+ "@types/angular": "^1.8.4",
"bower": "^1.8.0",
"json-server": "^0.9.6",
- "serve": "^5.1.2"
+ "rimraf": "^3.0.2",
+ "serve": "^5.1.2",
+ "ts-loader": "^9.4.1",
+ "typescript": "^4.8.4",
+ "webpack": "^5.74.0",
+ "webpack-cli": "^4.10.0"
}
}
diff --git a/src/app/app.main.js b/src/app/app.main.ts
similarity index 80%
rename from src/app/app.main.js
rename to src/app/app.main.ts
index 197434d..5065e73 100644
--- a/src/app/app.main.js
+++ b/src/app/app.main.ts
@@ -11,10 +11,10 @@ angular
"ui.router"
])
.config(function(
- $httpProvider,
- $resourceProvider,
- laddaProvider,
- $datepickerProvider
+ $httpProvider: any,
+ $resourceProvider: any,
+ laddaProvider: any,
+ $datepickerProvider: any
) {
laddaProvider.setOption({
style: "expand-right"
diff --git a/src/app/app.routes.js b/src/app/app.routes.ts
similarity index 51%
rename from src/app/app.routes.js
rename to src/app/app.routes.ts
index 2f98217..84771ef 100644
--- a/src/app/app.routes.js
+++ b/src/app/app.routes.ts
@@ -1,17 +1,15 @@
angular
.module("codecraft")
- .config(function($stateProvider, $urlRouterProvider) {
+ .config(function($stateProvider: any, $urlRouterProvider: any) {
$stateProvider
.state("list", {
url: "/",
views: {
main: {
- templateUrl: "templates/list.html",
- controller: "PersonListController"
+ template: ''
},
search: {
- templateUrl: "templates/searchform.html",
- controller: "SearchController"
+ template: ''
}
}
})
@@ -19,8 +17,7 @@ angular
url: "/edit/:email",
views: {
main: {
- templateUrl: "templates/edit.html",
- controller: "PersonEditController"
+ template: '',
}
}
})
@@ -28,8 +25,7 @@ angular
url: "/create",
views: {
main: {
- templateUrl: "templates/create.html",
- controller: "PersonCreateController"
+ template: "",
}
}
});
diff --git a/src/app/components/card.component.ts b/src/app/components/card.component.ts
new file mode 100644
index 0000000..eae37e1
--- /dev/null
+++ b/src/app/components/card.component.ts
@@ -0,0 +1,28 @@
+let CardComponent = {
+ selector: 'ccCard', //
+ templateUrl: 'templates/card.html',
+ bindings: {
+ user: "="
+ },
+ controller: class CardController {
+ public isDeleting;
+ public ContactService;
+ public user: any;
+
+ constructor(ContactService: any) {
+ this.ContactService = ContactService;
+ this.isDeleting = false;
+ };
+
+ deleteUser = () => {
+ this.isDeleting = true;
+ this.ContactService.removeContact(this.user)
+ .then( () => {this.isDeleting = false;});
+ };
+
+ }
+}
+
+angular
+ .module("codecraft")
+ .component(CardComponent.selector, CardComponent);
diff --git a/src/app/components/index.ts b/src/app/components/index.ts
new file mode 100644
index 0000000..0d91d84
--- /dev/null
+++ b/src/app/components/index.ts
@@ -0,0 +1,6 @@
+import './person-create.component';
+import './spinner.component';
+import './card.component';
+import './person-edit.component';
+import './person-list.component';
+import './search.component';
diff --git a/src/app/components/person-create.component.ts b/src/app/components/person-create.component.ts
new file mode 100644
index 0000000..9b7d0d0
--- /dev/null
+++ b/src/app/components/person-create.component.ts
@@ -0,0 +1,27 @@
+import * as angular from 'angular';
+
+export let PersonCreateComponent = {
+ selector: 'personCreate', //
+ templateUrl: 'templates/create.html',
+ bindings: {},
+ controller: class PersonCreateController {
+ public contacts: any;
+ public person: any = {};
+ public $state: any;
+
+ constructor($state: any, ContactService: any) {
+ this.contacts = ContactService;
+ this.$state = $state;
+ }
+
+ save() {
+ console.log("createContact");
+ this.contacts.createContact(this.person)
+ .then(() => {this.$state.go("list");})
+ }
+ }
+}
+
+angular
+ .module("codecraft")
+ .component(PersonCreateComponent.selector, PersonCreateComponent);
diff --git a/src/app/components/person-edit.component.ts b/src/app/components/person-edit.component.ts
new file mode 100644
index 0000000..9c755c2
--- /dev/null
+++ b/src/app/components/person-edit.component.ts
@@ -0,0 +1,40 @@
+import * as angular from 'angular';
+
+export let PersonEditComponent = {
+ selector: 'personEdit', //
+ templateUrl: 'templates/edit.html',
+ bindings: {},
+ controller: class PersonEditController {
+ public $stateParams: any;
+ public $state: any;
+ public contacts: any;
+ public person: any;
+
+ constructor(
+ $state: any,
+ $stateParams: any,
+ ContactService: any
+ ) {
+ this.$state = $state;
+ this.$stateParams = $stateParams;
+ this.contacts = ContactService;
+ this.person = this.contacts.getPerson(this.$stateParams.email);
+ }
+
+ save() {
+ this.contacts.updateContact(this.person).then(() => {
+ this.$state.go("list");
+ });
+ };
+
+ remove() {
+ this.contacts.removeContact(this.person).then(() => {
+ this.$state.go("list");
+ });
+ };
+ },
+}
+
+angular
+ .module("codecraft")
+ .component(PersonEditComponent.selector, PersonEditComponent)
diff --git a/src/app/components/person-list.component.ts b/src/app/components/person-list.component.ts
new file mode 100644
index 0000000..1426af3
--- /dev/null
+++ b/src/app/components/person-list.component.ts
@@ -0,0 +1,18 @@
+import * as angular from 'angular';
+
+export let PersonListComponent = {
+ selector: 'personList', //
+ templateUrl: 'templates/list.html',
+ bindings: {},
+ controller: class PersonListController {
+ public contacts: any;
+
+ constructor(ContactService: any) {
+ this.contacts = ContactService;
+ }
+ },
+}
+
+angular
+ .module("codecraft")
+ .component(PersonListComponent.selector, PersonListComponent);
diff --git a/src/app/components/search.component.ts b/src/app/components/search.component.ts
new file mode 100644
index 0000000..e3bd6a4
--- /dev/null
+++ b/src/app/components/search.component.ts
@@ -0,0 +1,22 @@
+import * as angular from 'angular';
+
+export let SearchComponent = {
+ selector: 'search',
+ templateUrl: 'templates/searchform.html',
+ bindings: {},
+ controller: class SearchController {
+ public contacts: any;
+
+ constructor(ContactService: any) {
+ this.contacts = ContactService;
+ }
+
+ loadMore() {
+ this.contacts.loadMore();
+ }
+ }
+}
+
+angular
+ .module("codecraft")
+ .component(SearchComponent.selector, SearchComponent);
diff --git a/src/app/components/spinner.component.ts b/src/app/components/spinner.component.ts
new file mode 100644
index 0000000..0e12856
--- /dev/null
+++ b/src/app/components/spinner.component.ts
@@ -0,0 +1,15 @@
+import * as angular from 'angular';
+
+export let SpinnerComponent = {
+ selector: "ccSpinner", //
+ templateUrl: "templates/spinner.html",
+ bindings: {
+ isLoading: "=",
+ message: "@"
+ },
+ controller: class SpinnerController {},
+}
+
+angular
+ .module("codecraft")
+ .component(SpinnerComponent.selector, SpinnerComponent);
diff --git a/src/app/controllers.js b/src/app/controllers.js
deleted file mode 100644
index f78828c..0000000
--- a/src/app/controllers.js
+++ /dev/null
@@ -1,48 +0,0 @@
-angular
- .module("codecraft")
- .controller("PersonCreateController", function(
- $scope,
- $state,
- ContactService
- ) {
- $scope.contacts = ContactService;
- $scope.person = {};
-
- $scope.save = function() {
- console.log("createContact");
- $scope.contacts.createContact($scope.person).then(function() {
- $state.go("list");
- });
- };
- })
- .controller("PersonEditController", function(
- $scope,
- $stateParams,
- $state,
- ContactService
- ) {
- $scope.contacts = ContactService;
- $scope.person = $scope.contacts.getPerson($stateParams.email);
-
- $scope.save = function() {
- $scope.contacts.updateContact($scope.person).then(function() {
- $state.go("list");
- });
- };
-
- $scope.remove = function() {
- $scope.contacts.removeContact($scope.person).then(function() {
- $state.go("list");
- });
- };
- })
- .controller("PersonListController", function($scope, ContactService) {
- $scope.contacts = ContactService;
- })
- .controller("SearchController", function($scope, ContactService) {
- $scope.contacts = ContactService;
-
- $scope.loadMore = function() {
- $scope.contacts.loadMore();
- };
- });
diff --git a/src/app/directives.js b/src/app/directives.js
deleted file mode 100644
index 5a6d920..0000000
--- a/src/app/directives.js
+++ /dev/null
@@ -1,30 +0,0 @@
-angular
- .module("codecraft")
- .directive("ccCard", function() {
- return {
- restrict: "AE",
- templateUrl: "templates/card.html",
- scope: {
- user: "="
- },
- controller: function($scope, ContactService) {
- $scope.isDeleting = false;
- $scope.deleteUser = function() {
- $scope.isDeleting = true;
- ContactService.removeContact($scope.user).then(function() {
- $scope.isDeleting = false;
- });
- };
- }
- };
- })
- .directive("ccSpinner", function() {
- return {
- restrict: "AE",
- templateUrl: "templates/spinner.html",
- scope: {
- isLoading: "=",
- message: "@"
- }
- };
- });
diff --git a/src/app/filters.js b/src/app/filters.js
deleted file mode 100644
index 13193f3..0000000
--- a/src/app/filters.js
+++ /dev/null
@@ -1,11 +0,0 @@
-angular.module("codecraft").filter("defaultImage", function() {
- return function(input, param) {
- if (!param) {
- param = "/img/avatar.png";
- }
- if (!input) {
- return param;
- }
- return input;
- };
-});
diff --git a/src/app/filters/default-image.filter.ts b/src/app/filters/default-image.filter.ts
new file mode 100644
index 0000000..0dbfee2
--- /dev/null
+++ b/src/app/filters/default-image.filter.ts
@@ -0,0 +1,12 @@
+angular.module("codecraft").filter("defaultImage", function() {
+ return function(input: any, param: any) {
+ if (!param) {
+ param = "/img/avatar.png";
+ }
+ if (!input) {
+ return param;
+ }
+ return input;
+ };
+ });
+
\ No newline at end of file
diff --git a/src/app/filters/index.ts b/src/app/filters/index.ts
new file mode 100644
index 0000000..b3ecb76
--- /dev/null
+++ b/src/app/filters/index.ts
@@ -0,0 +1 @@
+import './default-image.filter';
\ No newline at end of file
diff --git a/src/app/main.ts b/src/app/main.ts
new file mode 100644
index 0000000..1d5930a
--- /dev/null
+++ b/src/app/main.ts
@@ -0,0 +1,18 @@
+import 'angular';
+import 'angular-resource';
+import 'angular-animate'
+
+import 'ng-infinite-scroll';
+import 'angular-spinner';
+import 'angular-auto-validate/dist/jcs-auto-validate';
+import 'angular-ladda';
+import 'angular-strap';
+import 'angularjs-toaster';
+import 'angular-ui-router';
+
+
+import './app.main';
+import './services';
+import './filters';
+import './components';
+import './app.routes';
diff --git a/src/app/services/contact.resource.ts b/src/app/services/contact.resource.ts
new file mode 100644
index 0000000..12e6620
--- /dev/null
+++ b/src/app/services/contact.resource.ts
@@ -0,0 +1,13 @@
+angular
+ .module("codecraft")
+ .factory("Contact", function($resource : any) {
+ return $resource(
+ "http://localhost:3000/contacts/:id",
+ {id: "@id"},
+ {
+ update: {
+ method: "PUT"
+ }
+ }
+ );
+ })
diff --git a/src/app/services.js b/src/app/services/contact.service.ts
similarity index 81%
rename from src/app/services.js
rename to src/app/services/contact.service.ts
index dc5196b..7cf64d9 100644
--- a/src/app/services.js
+++ b/src/app/services/contact.service.ts
@@ -1,22 +1,11 @@
angular
.module("codecraft")
- .factory("Contact", function($resource) {
- return $resource(
- "http://localhost:3000/contacts/:id",
- {id: "@id"},
- {
- update: {
- method: "PUT"
- }
- }
- );
- })
- .factory("ContactService", function(Contact, $rootScope, $q, toaster) {
+ .factory("ContactService", function(Contact: any, $rootScope: any, $q: any, toaster: any) {
var self = {
- getPerson: function(email) {
+ getPerson: function(email: any) {
console.log(email);
for (var i = 0; i < self.persons.length; i++) {
- var obj = self.persons[i];
+ var obj: any = self.persons[i];
if (obj.email == email) {
return obj;
}
@@ -26,10 +15,11 @@ angular
hasMore: true,
isLoading: false,
isSaving: false,
- persons: [],
+ persons: [] as any[],
search: null,
sorting: "name",
ordering: "ASC",
+ isDeleting: false,
doSearch: function() {
self.hasMore = true;
self.page = 1;
@@ -53,7 +43,7 @@ angular
q: self.search
};
- Contact.query(params, function(data) {
+ Contact.query(params, function(data: any) {
console.debug(data);
angular.forEach(data, function(person) {
self.persons.push(new Contact(person));
@@ -72,7 +62,7 @@ angular
self.loadContacts();
}
},
- updateContact: function(person) {
+ updateContact: function(person: any) {
var d = $q.defer();
self.isSaving = true;
person.$update().then(function() {
@@ -82,10 +72,10 @@ angular
});
return d.promise;
},
- removeContact: function(person) {
+ removeContact: function(person: any) {
var d = $q.defer();
self.isDeleting = true;
- name = person.name;
+ var name = person.name;
person.$remove().then(function() {
self.isDeleting = false;
var index = self.persons.indexOf(person);
@@ -95,7 +85,7 @@ angular
});
return d.promise;
},
- createContact: function(person) {
+ createContact: function(person: any) {
var d = $q.defer();
self.isSaving = true;
Contact.save(person).$promise.then(function() {
diff --git a/src/app/services/index.ts b/src/app/services/index.ts
new file mode 100644
index 0000000..df2669f
--- /dev/null
+++ b/src/app/services/index.ts
@@ -0,0 +1,2 @@
+import './contact.resource';
+import './contact.service';
diff --git a/src/index.html b/src/index.html
index 25ff5e7..37bb54e 100644
--- a/src/index.html
+++ b/src/index.html
@@ -49,30 +49,9 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+