Skip to content

Commit b028da3

Browse files
IsmaestroIsmael Ramos
authored and
Ismael Ramos
committed
feat(new version): removed json-server and added API
fix(tests): solved problems with unit tests and e2e feat(readme): updated readme
1 parent 4875b2b commit b028da3

30 files changed

+155
-102
lines changed

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,16 @@ Sample app made with :heart:
44

55
### Demo
66

7+
Live demo at: https://ismaestro.github.io/angular4-sample-app/
8+
79
![angular-2-sample-project](http://i65.tinypic.com/1jqhx2.jpg)
810

911
## Based on
10-
Angular 4, Bootstrap 4, Angular CLI and more plugins like ng2 translate and json-server
12+
Angular 4, Bootstrap 4, Angular CLI and more plugins like ng2 translate
13+
14+
## Server
15+
16+
This repo is using an API which is [a simple app](https://github.com/Ismaestro/tour-of-heroes-sample-app) in NodeJS deployed on Heroku, to create, modify and delete heroes
1117

1218
## How can I support developers?
1319
- Star the GitHub repo :star:
@@ -21,6 +27,8 @@ Angular 4, Bootstrap 4, Angular CLI and more plugins like ng2 translate and json
2127
* Sass
2228
* Angular 4
2329
* jQuery
30+
* Tests with Protractor
31+
* Github pages deploy ready
2432

2533
Enjoy :metal:
2634

e2e/app.po.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {browser, element, by} from 'protractor';
1+
import {browser, by, element} from 'protractor';
22

33
export class AngularTOHPage {
44
navigateTo() {

karma.conf.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
module.exports = function (config) {
22
config.set({
33
basePath: '',
4-
frameworks: ['jasmine', 'angular-cli'],
4+
frameworks: ['jasmine', '@angular/cli'],
55
plugins: [
66
require('karma-jasmine'),
77
require('karma-chrome-launcher'),
88
require('karma-remap-istanbul'),
9-
require('angular-cli/plugins/karma')
9+
require('@angular/cli/plugins/karma')
1010
],
1111
files: [
1212
{pattern: './src/test.ts', watched: false}
1313
],
1414
preprocessors: {
15-
'./src/test.ts': ['angular-cli']
15+
'./src/test.ts': ['@angular/cli']
1616
},
1717
mime: {
1818
'text/x-typescript': ['ts', 'tsx']
@@ -24,7 +24,7 @@ module.exports = function (config) {
2424
}
2525
},
2626
angularCli: {
27-
config: './angular-cli.json',
27+
config: './.angular-cli.json',
2828
environment: 'dev'
2929
},
3030
reporters: config.angularCli && config.angularCli.codeCoverage

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"@angular/platform-server": "4.2.4",
2727
"@angular/router": "4.2.4",
2828
"@types/jasmine": "2.5.53",
29+
"@types/jasminewd2": "^2.0.2",
2930
"@types/node": "8.0.2",
3031
"angular-cli-ghpages": "0.5.1",
3132
"bootstrap": "4.0.0-alpha.6",
@@ -43,7 +44,7 @@
4344
"protractor": "5.1.2",
4445
"rxjs": "5.4.1",
4546
"ts-helpers": "1.1.2",
46-
"ts-node": "3.1.0",
47+
"ts-node": "3.0.0",
4748
"tslint": "5.4.3",
4849
"typescript": "2.3.4",
4950
"zone.js": "0.8.12"

protractor.conf.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// https://github.com/angular/protractor/blob/master/lib/config.ts
33

44
/*global jasmine */
5-
var SpecReporter = require('jasmine-spec-reporter');
5+
var SpecReporter = require('jasmine-spec-reporter').SpecReporter;
66

77
exports.config = {
88
allScriptsTimeout: 11000,

src/app/app-routing.module.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {NgModule} from '@angular/core';
1+
import {NgModule} from '@angular/core';
22
import {RouterModule, Routes} from '@angular/router';
33

44
import {HeroTopComponent} from './heroes/hero-top/hero-top.component';

src/app/app.component.scss

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.text-left {
2+
text-align: left !important;
3+
}
4+
5+
.text-right {
6+
text-align: right !important;
7+
}

src/app/app.component.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import {Component} from '@angular/core';
2-
import {TranslateService} from 'ng2-translate';
2+
import {TranslateService} from 'ng2-translate';
33
import {Title} from '@angular/platform-browser';
44

55
import {environment} from '../environments/environment';
66

77
@Component({
88
selector: 'toh-app',
9-
templateUrl: './app.component.html'
9+
templateUrl: './app.component.html',
10+
styles: ['./app.component.scss']
1011
})
1112

1213
export class AppComponent {

src/app/app.module.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
import {NgModule} from '@angular/core';
2-
import {BrowserModule} from '@angular/platform-browser';
3-
import {FormsModule} from '@angular/forms';
4-
import {Http, HttpModule} from '@angular/http';
5-
import {TranslateModule, TranslateLoader} from 'ng2-translate';
6-
import {TranslateLoaderFactory} from './app.translate.factory';
1+
import {NgModule} from '@angular/core';
2+
import {BrowserModule} from '@angular/platform-browser';
3+
import {FormsModule} from '@angular/forms';
4+
import {Http, HttpModule} from '@angular/http';
5+
import {TranslateLoader, TranslateModule} from 'ng2-translate';
6+
import {TranslateLoaderFactory} from './app.translate.factory';
77

88
import {APP_CONFIG, AppConfig} from './config/app.config';
99

1010
import {AppRoutingModule} from './app-routing.module';
11-
import {SharedModule} from './shared/shared.module';
12-
import {CoreModule} from './core/core.module';
13-
import {HeroesModule} from './heroes/heroes.module';
11+
import {SharedModule} from './shared/shared.module';
12+
import {CoreModule} from './core/core.module';
13+
import {HeroesModule} from './heroes/heroes.module';
1414

15-
import {AppComponent} from './app.component';
15+
import {AppComponent} from './app.component';
1616
import {HeroTopComponent} from './heroes/hero-top/hero-top.component';
1717

1818
@NgModule({

src/app/config/app.config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export const AppConfig: IAppConfig = {
1111
heroById: heroesRoute + '/:id'
1212
},
1313
endpoints: {
14-
heroes: 'https://jsonblob.com/api/jsonBlob/11ba5f87-5997-11e7-ae4c-997a6628ed33',
15-
heroesPowers: 'https://jsonblob.com/api/jsonBlob/f8234363-5991-11e7-ae4c-eb7c024ddb08'
14+
heroes: 'https://tour-of-heroes-sample-app.herokuapp.com/heroes',
15+
heroesPowers: 'https://tour-of-heroes-sample-app.herokuapp.com/heroesPowers'
1616
}
1717
};

src/app/core/core.module.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
import {NgModule, Optional, SkipSelf} from '@angular/core';
2-
import {CommonModule} from '@angular/common';
3-
import {FormsModule} from '@angular/forms';
4-
import {Http} from '@angular/http';
5-
import {TranslateModule, TranslateLoader} from 'ng2-translate';
6-
import {TranslateLoaderFactory} from '../app.translate.factory';
1+
import {NgModule, Optional, SkipSelf} from '@angular/core';
2+
import {CommonModule} from '@angular/common';
3+
import {FormsModule} from '@angular/forms';
4+
import {Http} from '@angular/http';
5+
import {TranslateLoader, TranslateModule} from 'ng2-translate';
6+
import {TranslateLoaderFactory} from '../app.translate.factory';
77

88
import {throwIfAlreadyLoaded} from './module-import-guard';
9-
import {LoggerService} from './logger.service';
9+
import {LoggerService} from './logger.service';
1010

11-
import {HeroesModule} from '../heroes/heroes.module';
11+
import {HeroesModule} from '../heroes/heroes.module';
1212
import {HeroRoutingModule} from '../heroes/heroes-routing.module';
1313

14-
import {NavComponent} from './nav/nav.component';
14+
import {NavComponent} from './nav/nav.component';
1515
import {FooterComponent} from './footer/footer.component';
1616

1717

src/app/core/nav/nav.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<div class="dropdown">
1313
<a class="btn btn-secondary dropdown-toggle" id="languagesDropdown" data-toggle="dropdown"
1414
aria-haspopup="true" aria-expanded="false">
15-
<i class="fa fa-globe" aria-hidden="true"></i> {{ 'language' | translate }}
15+
<i class="fa fa-globe" aria-hidden="true"></i> {{ language | translate }}
1616
</a>
1717
<div class="dropdown-menu" aria-labelledby="languagesDropdown">
1818
<a class="dropdown-item" (click)="changeLanguage('en')">{{ 'english' | translate }}</a>

src/app/core/nav/nav.component.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {Component, Inject, Input} from '@angular/core';
2-
import {TranslateService} from 'ng2-translate';
2+
import {TranslateService} from 'ng2-translate';
33

44
import {APP_CONFIG} from '../../config/app.config';
55
import {IAppConfig} from '../../config/iapp.config';
@@ -14,6 +14,7 @@ export class NavComponent {
1414
@Input() title: string;
1515

1616
menuItems: any[];
17+
language: string;
1718

1819
private translateService: TranslateService;
1920

@@ -24,6 +25,21 @@ export class NavComponent {
2425
{link: '/' + this.appConfig.routes.heroes, name: texts['heroesList']}
2526
];
2627
});
28+
29+
this.loadLanguageLabel();
30+
}
31+
32+
private loadLanguageLabel() {
33+
switch (this.translateService.currentLang) {
34+
case 'en':
35+
this.language = 'english';
36+
break;
37+
case 'es':
38+
this.language = 'spanish';
39+
break;
40+
default:
41+
this.language = 'language';
42+
}
2743
}
2844

2945
constructor(@Inject(APP_CONFIG) private appConfig: IAppConfig,
@@ -33,7 +49,8 @@ export class NavComponent {
3349
}
3450

3551
changeLanguage(language: string): void {
36-
this.translateService.use(language);
37-
this.loadMenus();
52+
this.translateService.use(language).subscribe(() => {
53+
this.loadMenus();
54+
});
3855
}
3956
}

src/app/heroes/hero-create-new/hero-create-new.component.html

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
<h3>{{ 'hero-create-new.newHero' | translate }}</h3>
2-
<form (ngSubmit)="onSubmit()" #heroForm="ngForm">
2+
<form (ngSubmit)="onSubmit()" #heroForm="ngForm" id="new-hero-form">
3+
<div class="form-group">
4+
<label class="form-label" for="id">Id</label>
5+
<input type="text" class="form-control" id="id"
6+
[(ngModel)]="hero.id" name="id">
7+
</div>
38
<div class="form-group">
49
<label class="form-label" for="name">{{ 'name' | translate }}</label>
510
<input type="text" class="form-control" id="name"
@@ -24,6 +29,9 @@ <h3>{{ 'hero-create-new.newHero' | translate }}</h3>
2429
<option *ngFor="let power of powers" [value]="power">{{power}}</option>
2530
</select>
2631
</div>
27-
<button type="submit" class="btn btn-success" [disabled]="!heroForm.form.valid">{{ 'createNewHero' | translate }}!
28-
</button>
32+
<div class="form-group alert alert-danger" *ngIf="error">{{error | translate}}</div>
33+
<div class="form-group">
34+
<button type="submit" class="btn btn-success" [disabled]="!heroForm.form.valid">{{ 'createNewHero' | translate }}!
35+
</button>
36+
</div>
2937
</form>

src/app/heroes/hero-create-new/hero-create-new.component.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,9 @@
1212
width: 35%;
1313
float: right;
1414
}
15+
16+
#new-hero-form {
17+
margin: 0 auto;
18+
display: table;
19+
}
1520
}

src/app/heroes/hero-create-new/hero-create-new.component.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,22 @@ export class HeroFormComponent {
1616

1717
hero: Hero;
1818
powers: string[];
19+
error: string;
1920

2021
constructor(private heroService: HeroService) {
21-
this.hero = new Hero(-1, '', '');
22+
this.hero = new Hero('', '', '');
2223

2324
this.heroService.getHeroesPowers().then(powers => this.powers = powers);
2425
}
2526

2627
onSubmit() {
2728
this.heroService.create(this.hero)
28-
.then(heroes => {
29-
this.heroes = heroes;
29+
.then(() => {
3030
this.selectedHero = null;
31+
}, (response) => {
32+
if (response.status === 500) {
33+
this.error = 'heroDuplicated';
34+
}
3135
});
3236
}
3337
}

src/app/heroes/hero-detail/hero-detail.component.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import {Component, OnInit} from '@angular/core';
1+
import {Component, OnInit} from '@angular/core';
22
import {ActivatedRoute, Params} from '@angular/router';
3-
import {Location} from '@angular/common';
3+
import {Location} from '@angular/common';
44

5-
import {Hero} from '../shared/hero.model';
6-
import {HeroService} from '../shared/hero.service';
5+
import {Hero} from '../shared/hero.model';
6+
import {HeroService} from '../shared/hero.service';
77

88
@Component({
99
selector: 'toh-hero-detail',

src/app/heroes/hero-list/hero-list.component.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22
<h2>
33
{{ 'heroesList' | translate }}
44
<button class="btn btn-success"
5+
*ngIf="!createNewHero"
56
(click)="createNewHero = !createNewHero">
67
<i class="fa fa-plus" aria-hidden="true"></i>
78
</button>
89
</h2>
910
<div>
1011
<div class="hero-list">
11-
<h3>{{ 'pickColor' | translate }}</h3>
12+
<h3 class="text-left">{{ 'pickColor' | translate }}</h3>
1213
<div class="color-picker">
1314
<label class="custom-control custom-radio">
1415
<input id="color1" name="radio" type="radio" class="custom-control-input" (click)="color='orange'">
@@ -73,7 +74,7 @@ <h5 class="modal-title" id="exampleModalLabel">{{ 'alert' | translate }}</h5>
7374
</li>
7475
</ul>
7576
</div>
76-
<div class="new-hero">
77+
<div class="new-hero" >
7778
<toh-hero-create-new *ngIf="createNewHero"
7879
[heroes]="heroes"
7980
[selectedHero]="selectedHero">

src/app/heroes/hero-list/hero-list.component.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {Component, OnInit, Inject} from '@angular/core';
1+
import {Component, Inject, OnInit} from '@angular/core';
22
import {Router} from '@angular/router';
33

44
import {APP_CONFIG} from '../../config/app.config';
@@ -24,6 +24,7 @@ export class HeroListComponent implements OnInit {
2424
constructor(@Inject(APP_CONFIG) private appConfig: IAppConfig,
2525
private router: Router,
2626
private heroService: HeroService) {
27+
this.heroService.refreshHeroes$.subscribe(heroes => this.heroes = heroes);
2728
}
2829

2930
getHeroes(): void {

src/app/heroes/hero-search/hero-search.component.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import {Component, OnInit, Inject} from '@angular/core';
2-
import {Router} from '@angular/router';
3-
import {Observable} from 'rxjs/Observable';
4-
import {Subject} from 'rxjs/Subject';
1+
import {Component, Inject, OnInit} from '@angular/core';
2+
import {Router} from '@angular/router';
3+
import {Observable} from 'rxjs/Observable';
4+
import {Subject} from 'rxjs/Subject';
55

6-
import {APP_CONFIG} from '../../config/app.config';
7-
import {IAppConfig} from '../../config/iapp.config';
6+
import {APP_CONFIG} from '../../config/app.config';
7+
import {IAppConfig} from '../../config/iapp.config';
88
import {LoggerService} from '../../core/logger.service';
99

1010
import {Hero} from '../shared/hero.model';

src/app/heroes/heroes-routing.module.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import {NgModule} from '@angular/core';
1+
import {NgModule} from '@angular/core';
22
import {RouterModule, Routes} from '@angular/router';
33

44
import {AppConfig} from '../config/app.config';
55

6-
import {HeroListComponent} from './hero-list/hero-list.component';
6+
import {HeroListComponent} from './hero-list/hero-list.component';
77
import {HeroDetailComponent} from './hero-detail/hero-detail.component';
88

99
const heroesRoutes: Routes = [

0 commit comments

Comments
 (0)