build(aio): new migration

This commit is contained in:
Jesus Rodriguez
2017-04-01 01:57:13 +02:00
committed by Alex Rickabaugh
parent 309bae0a0b
commit 0e38bf9de0
147 changed files with 12713 additions and 11268 deletions

View File

@ -0,0 +1,19 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { DashboardComponent } from './dashboard.component';
import { HeroesComponent } from './heroes.component';
import { HeroDetailComponent } from './hero-detail.component';
const routes: Routes = [
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
{ path: 'dashboard', component: DashboardComponent },
{ path: 'detail/:id', component: HeroDetailComponent },
{ path: 'heroes', component: HeroesComponent }
];
@NgModule({
imports: [ RouterModule.forRoot(routes) ],
exports: [ RouterModule ]
})
export class AppRoutingModule {}

View File

@ -0,0 +1,29 @@
/* #docregion */
h1 {
font-size: 1.2em;
color: #999;
margin-bottom: 0;
}
h2 {
font-size: 2em;
margin-top: 0;
padding-top: 0;
}
nav a {
padding: 5px 10px;
text-decoration: none;
margin-top: 10px;
display: inline-block;
background-color: #eee;
border-radius: 4px;
}
nav a:visited, a:link {
color: #607D8B;
}
nav a:hover {
color: #039be5;
background-color: #CFD8DC;
}
nav a.active {
color: #039be5;
}

View File

@ -0,0 +1,19 @@
// #docplaster
// #docregion
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `
<h1>{{title}}</h1>
<nav>
<a routerLink="/dashboard" routerLinkActive="active">Dashboard</a>
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
</nav>
<router-outlet></router-outlet>
`,
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'Tour of Heroes';
}

View File

@ -0,0 +1,54 @@
// #docplaster
// #docregion
// #docregion v1, v2
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { AppRoutingModule } from './app-routing.module';
// #enddocregion v1
// Imports for loading & configuring the in-memory web api
import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
import { InMemoryDataService } from './in-memory-data.service';
// #docregion v1
import { AppComponent } from './app.component';
import { DashboardComponent } from './dashboard.component';
import { HeroesComponent } from './heroes.component';
import { HeroDetailComponent } from './hero-detail.component';
import { HeroService } from './hero.service';
// #enddocregion v1, v2
import { HeroSearchComponent } from './hero-search.component';
// #docregion v1, v2
@NgModule({
imports: [
BrowserModule.withServerTransition({
appId: 'toh-universal'
}),
FormsModule,
HttpModule,
// #enddocregion v1
// #docregion in-mem-web-api
InMemoryWebApiModule.forRoot(InMemoryDataService),
// #enddocregion in-mem-web-api
// #docregion v1
AppRoutingModule
],
// #docregion search
declarations: [
AppComponent,
DashboardComponent,
HeroDetailComponent,
HeroesComponent,
// #enddocregion v1, v2
HeroSearchComponent
// #docregion v1, v2
],
// #enddocregion search
providers: [ HeroService ],
bootstrap: [ AppComponent ]
})
export class AppModule { }

View File

@ -0,0 +1,62 @@
/* #docregion */
[class*='col-'] {
float: left;
padding-right: 20px;
padding-bottom: 20px;
}
[class*='col-']:last-of-type {
padding-right: 0;
}
a {
text-decoration: none;
}
*, *:after, *:before {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
h3 {
text-align: center; margin-bottom: 0;
}
h4 {
position: relative;
}
.grid {
margin: 0;
}
.col-1-4 {
width: 25%;
}
.module {
padding: 20px;
text-align: center;
color: #eee;
max-height: 120px;
min-width: 120px;
background-color: #607D8B;
border-radius: 2px;
}
.module:hover {
background-color: #EEE;
cursor: pointer;
color: #607d8b;
}
.grid-pad {
padding: 10px 0;
}
.grid-pad > [class*='col-']:last-of-type {
padding-right: 20px;
}
@media (max-width: 600px) {
.module {
font-size: 10px;
max-height: 75px; }
}
@media (max-width: 1024px) {
.grid {
margin: 0;
}
.module {
min-width: 60px;
}
}

View File

@ -0,0 +1,10 @@
<!-- #docregion -->
<h3>Top Heroes</h3>
<div class="grid grid-pad">
<a *ngFor="let hero of heroes" [routerLink]="['/detail', hero.id]" class="col-1-4">
<div class="module hero">
<h4>{{hero.name}}</h4>
</div>
</a>
</div>
<hero-search></hero-search>

View File

@ -0,0 +1,22 @@
// #docregion , search
import { Component, OnInit } from '@angular/core';
import { Hero } from './hero';
import { HeroService } from './hero.service';
@Component({
selector: 'my-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: [ './dashboard.component.css' ]
})
// #enddocregion search
export class DashboardComponent implements OnInit {
heroes: Hero[] = [];
constructor(private heroService: HeroService) { }
ngOnInit(): void {
this.heroService.getHeroes()
.then(heroes => this.heroes = heroes.slice(1, 5));
}
}

View File

@ -0,0 +1,30 @@
/* #docregion */
label {
display: inline-block;
width: 3em;
margin: .5em 0;
color: #607D8B;
font-weight: bold;
}
input {
height: 2em;
font-size: 1em;
padding-left: .4em;
}
button {
margin-top: 20px;
font-family: Arial;
background-color: #eee;
border: none;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer; cursor: hand;
}
button:hover {
background-color: #cfd8dc;
}
button:disabled {
background-color: #eee;
color: #ccc;
cursor: auto;
}

View File

@ -0,0 +1,14 @@
<!-- #docregion -->
<div *ngIf="hero">
<h2>{{hero.name}} details!</h2>
<div>
<label>id: </label>{{hero.id}}</div>
<div>
<label>name: </label>
<input [(ngModel)]="hero.name" placeholder="name" />
</div>
<button (click)="goBack()">Back</button>
<!-- #docregion save -->
<button (click)="save()">Save</button>
<!-- #enddocregion save -->
</div>

View File

@ -0,0 +1,40 @@
// #docregion
import 'rxjs/add/operator/switchMap';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
import { Location } from '@angular/common';
import { Hero } from './hero';
import { HeroService } from './hero.service';
@Component({
selector: 'my-hero-detail',
templateUrl: './hero-detail.component.html',
styleUrls: [ './hero-detail.component.css' ]
})
export class HeroDetailComponent implements OnInit {
hero: Hero;
constructor(
private heroService: HeroService,
private route: ActivatedRoute,
private location: Location
) {}
ngOnInit(): void {
this.route.params
.switchMap((params: Params) => this.heroService.getHero(+params['id']))
.subscribe(hero => this.hero = hero);
}
// #docregion save
save(): void {
this.heroService.update(this.hero)
.then(() => this.goBack());
}
// #enddocregion save
goBack(): void {
this.location.back();
}
}

View File

@ -0,0 +1,21 @@
/* #docregion */
.search-result{
border-bottom: 1px solid gray;
border-left: 1px solid gray;
border-right: 1px solid gray;
width:195px;
height: 16px;
padding: 5px;
background-color: white;
cursor: pointer;
}
.search-result:hover {
color: #eee;
background-color: #607D8B;
}
#search-box{
width: 200px;
height: 20px;
}

View File

@ -0,0 +1,11 @@
<!-- #docregion -->
<div id="search-component">
<h4>Hero Search</h4>
<input #searchBox id="search-box" (keyup)="search(searchBox.value)" />
<div>
<div *ngFor="let hero of heroes | async"
(click)="gotoDetail(hero)" class="search-result" >
{{hero.name}}
</div>
</div>
</div>

View File

@ -0,0 +1,69 @@
// #docplaster
// #docregion
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
// #docregion rxjs-imports
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
// Observable class extensions
import 'rxjs/add/observable/of';
// Observable operators
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
// #enddocregion rxjs-imports
import { HeroSearchService } from './hero-search.service';
import { Hero } from './hero';
@Component({
selector: 'hero-search',
templateUrl: './hero-search.component.html',
styleUrls: [ './hero-search.component.css' ],
providers: [HeroSearchService]
})
export class HeroSearchComponent implements OnInit {
// #docregion search
heroes: Observable<Hero[]>;
// #enddocregion search
// #docregion searchTerms
private searchTerms = new Subject<string>();
// #enddocregion searchTerms
constructor(
private heroSearchService: HeroSearchService,
private router: Router) {}
// #docregion searchTerms
// Push a search term into the observable stream.
search(term: string): void {
this.searchTerms.next(term);
}
// #enddocregion searchTerms
// #docregion search
ngOnInit(): void {
this.heroes = this.searchTerms
.debounceTime(300) // wait 300ms after each keystroke before considering the term
.distinctUntilChanged() // ignore if next search term is same as previous
.switchMap(term => term // switch to new observable each time the term changes
// return the http search observable
? this.heroSearchService.search(term)
// or the observable of empty heroes if there was no search term
: Observable.of<Hero[]>([]))
.catch(error => {
// TODO: add real error handling
console.log(error);
return Observable.of<Hero[]>([]);
});
}
// #enddocregion search
gotoDetail(hero: Hero): void {
let link = ['/detail', hero.id];
this.router.navigate(link);
}
}

View File

@ -0,0 +1,20 @@
// #docregion
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import { Hero } from './hero';
@Injectable()
export class HeroSearchService {
constructor(private http: Http) {}
search(term: string): Observable<Hero[]> {
return this.http
.get(`app/heroes/?name=${term}`)
.map(response => response.json().data as Hero[]);
}
}

View File

@ -0,0 +1,87 @@
// #docplaster
// #docregion , imports
import { Injectable } from '@angular/core';
import { Headers, Http } from '@angular/http';
// #docregion rxjs
import 'rxjs/add/operator/toPromise';
// #enddocregion rxjs
import { Hero } from './hero';
// #enddocregion imports
@Injectable()
export class HeroService {
// #docregion update
private headers = new Headers({'Content-Type': 'application/json'});
// #enddocregion update
// #docregion getHeroes
private heroesUrl = 'api/heroes'; // URL to web api
constructor(private http: Http) { }
getHeroes(): Promise<Hero[]> {
return this.http.get(this.heroesUrl)
// #docregion to-promise
.toPromise()
// #enddocregion to-promise
// #docregion to-data
.then(response => response.json().data as Hero[])
// #enddocregion to-data
// #docregion catch
.catch(this.handleError);
// #enddocregion catch
}
// #enddocregion getHeroes
// #docregion getHero
getHero(id: number): Promise<Hero> {
const url = `${this.heroesUrl}/${id}`;
return this.http.get(url)
.toPromise()
.then(response => response.json().data as Hero)
.catch(this.handleError);
}
// #enddocregion getHero
// #docregion delete
delete(id: number): Promise<void> {
const url = `${this.heroesUrl}/${id}`;
return this.http.delete(url, {headers: this.headers})
.toPromise()
.then(() => null)
.catch(this.handleError);
}
// #enddocregion delete
// #docregion create
create(name: string): Promise<Hero> {
return this.http
.post(this.heroesUrl, JSON.stringify({name: name}), {headers: this.headers})
.toPromise()
.then(res => res.json().data)
.catch(this.handleError);
}
// #enddocregion create
// #docregion update
update(hero: Hero): Promise<Hero> {
const url = `${this.heroesUrl}/${hero.id}`;
return this.http
.put(url, JSON.stringify(hero), {headers: this.headers})
.toPromise()
.then(() => hero)
.catch(this.handleError);
}
// #enddocregion update
// #docregion getHeroes, handleError
private handleError(error: any): Promise<any> {
console.error('An error occurred', error); // for demo purposes only
return Promise.reject(error.message || error);
}
// #enddocregion getHeroes, handleError
}

View File

@ -0,0 +1,4 @@
export class Hero {
id: number;
name: string;
}

View File

@ -0,0 +1,68 @@
/* #docregion */
.selected {
background-color: #CFD8DC !important;
color: white;
}
.heroes {
margin: 0 0 2em 0;
list-style-type: none;
padding: 0;
width: 15em;
}
.heroes li {
cursor: pointer;
position: relative;
left: 0;
background-color: #EEE;
margin: .5em;
padding: .3em 0;
height: 1.6em;
border-radius: 4px;
}
.heroes li:hover {
color: #607D8B;
background-color: #DDD;
left: .1em;
}
.heroes li.selected:hover {
background-color: #BBD8DC !important;
color: white;
}
.heroes .text {
position: relative;
top: -3px;
}
.heroes .badge {
display: inline-block;
font-size: small;
color: white;
padding: 0.8em 0.7em 0 0.7em;
background-color: #607D8B;
line-height: 1em;
position: relative;
left: -1px;
top: -4px;
height: 1.8em;
margin-right: .8em;
border-radius: 4px 0 0 4px;
}
button {
font-family: Arial;
background-color: #eee;
border: none;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer;
cursor: hand;
}
button:hover {
background-color: #cfd8dc;
}
/* #docregion additions */
button.delete {
float:right;
margin-top: 2px;
margin-right: .8em;
background-color: gray !important;
color:white;
}

View File

@ -0,0 +1,29 @@
<!-- #docregion -->
<h2>My Heroes</h2>
<!-- #docregion add -->
<div>
<label>Hero name:</label> <input #heroName />
<button (click)="add(heroName.value); heroName.value=''">
Add
</button>
</div>
<!-- #enddocregion add -->
<ul class="heroes">
<!-- #docregion li-element -->
<li *ngFor="let hero of heroes" (click)="onSelect(hero)"
[class.selected]="hero === selectedHero">
<span class="badge">{{hero.id}}</span>
<span>{{hero.name}}</span>
<!-- #docregion delete -->
<button class="delete"
(click)="delete(hero); $event.stopPropagation()">x</button>
<!-- #enddocregion delete -->
</li>
<!-- #enddocregion li-element -->
</ul>
<div *ngIf="selectedHero">
<h2>
{{selectedHero.name | uppercase}} is my hero
</h2>
<button (click)="gotoDetail()">View Details</button>
</div>

View File

@ -0,0 +1,61 @@
// #docregion
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Hero } from './hero';
import { HeroService } from './hero.service';
@Component({
selector: 'my-heroes',
templateUrl: './heroes.component.html',
styleUrls: [ './heroes.component.css' ]
})
export class HeroesComponent implements OnInit {
heroes: Hero[];
selectedHero: Hero;
constructor(
private heroService: HeroService,
private router: Router) { }
getHeroes(): void {
this.heroService
.getHeroes()
.then(heroes => this.heroes = heroes);
}
// #docregion add
add(name: string): void {
name = name.trim();
if (!name) { return; }
this.heroService.create(name)
.then(hero => {
this.heroes.push(hero);
this.selectedHero = null;
});
}
// #enddocregion add
// #docregion delete
delete(hero: Hero): void {
this.heroService
.delete(hero.id)
.then(() => {
this.heroes = this.heroes.filter(h => h !== hero);
if (this.selectedHero === hero) { this.selectedHero = null; }
});
}
// #enddocregion delete
ngOnInit(): void {
this.getHeroes();
}
onSelect(hero: Hero): void {
this.selectedHero = hero;
}
gotoDetail(): void {
this.router.navigate(['/detail', this.selectedHero.id]);
}
}

View File

@ -0,0 +1,19 @@
// #docregion , init
import { InMemoryDbService } from 'angular-in-memory-web-api';
export class InMemoryDataService implements InMemoryDbService {
createDb() {
let heroes = [
{id: 11, name: 'Mr. Nice'},
{id: 12, name: 'Narco'},
{id: 13, name: 'Bombasto'},
{id: 14, name: 'Celeritas'},
{id: 15, name: 'Magneta'},
{id: 16, name: 'RubberMan'},
{id: 17, name: 'Dynama'},
{id: 18, name: 'Dr IQ'},
{id: 19, name: 'Magma'},
{id: 20, name: 'Tornado'}
];
return {heroes};
}
}