From dae20339184f24a9a283c8aca6373846cb1203c1 Mon Sep 17 00:00:00 2001 From: Noel Mace Date: Mon, 26 Nov 2018 22:53:26 +0100 Subject: [PATCH] feat(directive-use): create project from branch step-20 --- angular.json | 99 +++++++++++++ steps/directive-use/browserslist | 11 ++ steps/directive-use/src/app/app.component.css | 46 ++++++ .../directive-use/src/app/app.component.html | 11 ++ steps/directive-use/src/app/app.component.ts | 10 ++ steps/directive-use/src/app/app.module.ts | 65 +++++++++ steps/directive-use/src/app/app.routes.ts | 15 ++ .../src/app/home/home.component.css | 10 ++ .../src/app/home/home.component.html | 3 + .../src/app/home/home.component.ts | 30 ++++ steps/directive-use/src/app/home/index.ts | 1 + steps/directive-use/src/app/index.ts | 2 + .../add-dialog/add-dialog.component.css | 0 .../add-dialog/add-dialog.component.html | 1 + .../add-dialog/add-dialog.component.spec.ts | 24 +++ .../people/add-dialog/add-dialog.component.ts | 25 ++++ steps/directive-use/src/app/people/index.ts | 1 + .../src/app/people/people.component.css | 65 +++++++++ .../src/app/people/people.component.html | 28 ++++ .../src/app/people/people.component.ts | 60 ++++++++ .../src/app/shared/card/card.component.css | 137 ++++++++++++++++++ .../src/app/shared/card/card.component.html | 38 +++++ .../src/app/shared/card/card.component.ts | 30 ++++ .../src/app/shared/card/index.ts | 1 + .../src/app/shared/form/custom-validators.ts | 22 +++ .../src/app/shared/form/form.component.css | 51 +++++++ .../src/app/shared/form/form.component.html | 102 +++++++++++++ .../src/app/shared/form/form.component.ts | 81 +++++++++++ .../src/app/shared/form/index.ts | 1 + steps/directive-use/src/app/shared/index.ts | 4 + .../src/app/shared/na-pipe/index.ts | 1 + .../src/app/shared/na-pipe/na.pipe.ts | 18 +++ .../src/app/shared/people-service/index.ts | 1 + .../shared/people-service/people.service.ts | 48 ++++++ steps/directive-use/src/app/update/index.ts | 1 + .../src/app/update/update.component.css | 10 ++ .../src/app/update/update.component.html | 1 + .../src/app/update/update.component.ts | 42 ++++++ steps/directive-use/src/assets/.gitkeep | 0 steps/directive-use/src/assets/.npmignore | 0 .../src/assets/images/bg_right.png | Bin 0 -> 16377 bytes .../src/assets/images/icon-delete.svg | 1 + .../src/assets/images/icon-edit.svg | 1 + .../src/assets/images/icon-mail.svg | 1 + .../src/assets/images/icon-maps.svg | 23 +++ .../src/assets/images/icon-phone.svg | 1 + .../src/assets/images/logo-sfeir.svg | 18 +++ .../src/assets/images/search-icon.svg | 16 ++ .../src/environments/environment.prod.ts | 13 ++ .../src/environments/environment.ts | 18 +++ steps/directive-use/src/favicon.ico | Bin 0 -> 5430 bytes steps/directive-use/src/index.html | 21 +++ steps/directive-use/src/main.ts | 13 ++ steps/directive-use/src/polyfills.ts | 79 ++++++++++ steps/directive-use/src/styles.css | 103 +++++++++++++ steps/directive-use/tsconfig.app.json | 8 + 56 files changed, 1412 insertions(+) create mode 100644 steps/directive-use/browserslist create mode 100644 steps/directive-use/src/app/app.component.css create mode 100644 steps/directive-use/src/app/app.component.html create mode 100644 steps/directive-use/src/app/app.component.ts create mode 100644 steps/directive-use/src/app/app.module.ts create mode 100644 steps/directive-use/src/app/app.routes.ts create mode 100644 steps/directive-use/src/app/home/home.component.css create mode 100644 steps/directive-use/src/app/home/home.component.html create mode 100644 steps/directive-use/src/app/home/home.component.ts create mode 100644 steps/directive-use/src/app/home/index.ts create mode 100644 steps/directive-use/src/app/index.ts create mode 100644 steps/directive-use/src/app/people/add-dialog/add-dialog.component.css create mode 100644 steps/directive-use/src/app/people/add-dialog/add-dialog.component.html create mode 100644 steps/directive-use/src/app/people/add-dialog/add-dialog.component.spec.ts create mode 100644 steps/directive-use/src/app/people/add-dialog/add-dialog.component.ts create mode 100644 steps/directive-use/src/app/people/index.ts create mode 100644 steps/directive-use/src/app/people/people.component.css create mode 100644 steps/directive-use/src/app/people/people.component.html create mode 100644 steps/directive-use/src/app/people/people.component.ts create mode 100644 steps/directive-use/src/app/shared/card/card.component.css create mode 100644 steps/directive-use/src/app/shared/card/card.component.html create mode 100644 steps/directive-use/src/app/shared/card/card.component.ts create mode 100644 steps/directive-use/src/app/shared/card/index.ts create mode 100644 steps/directive-use/src/app/shared/form/custom-validators.ts create mode 100644 steps/directive-use/src/app/shared/form/form.component.css create mode 100644 steps/directive-use/src/app/shared/form/form.component.html create mode 100644 steps/directive-use/src/app/shared/form/form.component.ts create mode 100644 steps/directive-use/src/app/shared/form/index.ts create mode 100644 steps/directive-use/src/app/shared/index.ts create mode 100644 steps/directive-use/src/app/shared/na-pipe/index.ts create mode 100644 steps/directive-use/src/app/shared/na-pipe/na.pipe.ts create mode 100644 steps/directive-use/src/app/shared/people-service/index.ts create mode 100644 steps/directive-use/src/app/shared/people-service/people.service.ts create mode 100644 steps/directive-use/src/app/update/index.ts create mode 100644 steps/directive-use/src/app/update/update.component.css create mode 100644 steps/directive-use/src/app/update/update.component.html create mode 100644 steps/directive-use/src/app/update/update.component.ts create mode 100644 steps/directive-use/src/assets/.gitkeep create mode 100644 steps/directive-use/src/assets/.npmignore create mode 100644 steps/directive-use/src/assets/images/bg_right.png create mode 100644 steps/directive-use/src/assets/images/icon-delete.svg create mode 100644 steps/directive-use/src/assets/images/icon-edit.svg create mode 100644 steps/directive-use/src/assets/images/icon-mail.svg create mode 100644 steps/directive-use/src/assets/images/icon-maps.svg create mode 100644 steps/directive-use/src/assets/images/icon-phone.svg create mode 100644 steps/directive-use/src/assets/images/logo-sfeir.svg create mode 100644 steps/directive-use/src/assets/images/search-icon.svg create mode 100644 steps/directive-use/src/environments/environment.prod.ts create mode 100644 steps/directive-use/src/environments/environment.ts create mode 100644 steps/directive-use/src/favicon.ico create mode 100644 steps/directive-use/src/index.html create mode 100644 steps/directive-use/src/main.ts create mode 100644 steps/directive-use/src/polyfills.ts create mode 100644 steps/directive-use/src/styles.css create mode 100644 steps/directive-use/tsconfig.app.json diff --git a/angular.json b/angular.json index 478e15ee..c4e4c28c 100644 --- a/angular.json +++ b/angular.json @@ -3751,6 +3751,105 @@ } } } + }, + "directive-use": { + "root": "steps/directive-use/", + "sourceRoot": "steps/directive-use/src", + "projectType": "application", + "prefix": "app", + "schematics": {}, + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist/directive-use", + "index": "steps/directive-use/src/index.html", + "main": "steps/directive-use/src/main.ts", + "polyfills": "steps/directive-use/src/polyfills.ts", + "tsConfig": "steps/directive-use/tsconfig.app.json", + "assets": [ + "steps/directive-use/src/favicon.ico", + "steps/directive-use/src/assets" + ], + "styles": [ + "steps/directive-use/src/styles.css" + ], + "scripts": [] + }, + "configurations": { + "production": { + "fileReplacements": [ + { + "replace": "steps/directive-use/src/environments/environment.ts", + "with": "steps/directive-use/src/environments/environment.prod.ts" + } + ], + "optimization": true, + "outputHashing": "all", + "sourceMap": false, + "extractCss": true, + "namedChunks": false, + "aot": true, + "extractLicenses": true, + "vendorChunk": false, + "buildOptimizer": true, + "budgets": [ + { + "type": "initial", + "maximumWarning": "2mb", + "maximumError": "5mb" + } + ] + } + } + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "options": { + "browserTarget": "directive-use:build" + }, + "configurations": { + "production": { + "browserTarget": "directive-use:build:production" + } + } + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "directive-use:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "steps/directive-use/src/test.ts", + "polyfills": "steps/directive-use/src/polyfills.ts", + "tsConfig": "steps/directive-use/tsconfig.spec.json", + "karmaConfig": "steps/directive-use/karma.conf.js", + "styles": [ + "steps/directive-use/src/styles.css" + ], + "scripts": [], + "assets": [ + "steps/directive-use/src/favicon.ico", + "steps/directive-use/src/assets" + ] + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": [ + "steps/directive-use/tsconfig.app.json", + "steps/directive-use/tsconfig.spec.json" + ], + "exclude": [ + "**/node_modules/**" + ] + } + } + } } }, "defaultProject": "angular-200", diff --git a/steps/directive-use/browserslist b/steps/directive-use/browserslist new file mode 100644 index 00000000..37371cb0 --- /dev/null +++ b/steps/directive-use/browserslist @@ -0,0 +1,11 @@ +# This file is currently used by autoprefixer to adjust CSS to support the below specified browsers +# For additional information regarding the format and rule options, please see: +# https://github.com/browserslist/browserslist#queries +# +# For IE 9-11 support, please remove 'not' from the last line of the file and adjust as needed + +> 0.5% +last 2 versions +Firefox ESR +not dead +not IE 9-11 \ No newline at end of file diff --git a/steps/directive-use/src/app/app.component.css b/steps/directive-use/src/app/app.component.css new file mode 100644 index 00000000..b06df838 --- /dev/null +++ b/steps/directive-use/src/app/app.component.css @@ -0,0 +1,46 @@ +mat-toolbar.extend-toolbar { + background-color: #0168ab; + background-image: url('/assets/images/bg_right.png'); + background-repeat: no-repeat; + background-position: right; + top: 0px; + box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26); + width: 100%; + z-index: 1; + color: white; + margin-bottom: 10px; +} + +mat-toolbar .flex { + flex: 1 1 auto; +} + +mat-toolbar a { + color: inherit; + text-decoration: none; + height: 100%; + margin: 0px 10px 0px 10px; + border-bottom: 2px solid transparent; + font-size: 1.1em; + font-weight: normal; + font-family: 'Open Sans', sans-serif; +} + +mat-toolbar a:not(.active):hover { + border-bottom: 2px solid white; +} + +mat-toolbar a img { + height: 100%; + margin-left: -60px; +} + +mat-toolbar-row:nth-child(1) { + margin-bottom: 66px; +} +mat-toolbar-row:nth-child(2) { + padding-left: 30px; + text-align: center; + height: 56px; + margin-top: 56px; +} diff --git a/steps/directive-use/src/app/app.component.html b/steps/directive-use/src/app/app.component.html new file mode 100644 index 00000000..0fe6f9d9 --- /dev/null +++ b/steps/directive-use/src/app/app.component.html @@ -0,0 +1,11 @@ + + + Sfeir + + + + + Maps List + + + diff --git a/steps/directive-use/src/app/app.component.ts b/steps/directive-use/src/app/app.component.ts new file mode 100644 index 00000000..16713fa3 --- /dev/null +++ b/steps/directive-use/src/app/app.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'sfeir-app', + templateUrl: 'app.component.html', + styleUrls: ['app.component.css'] +}) +export class PeopleAppComponent { + constructor() {} +} diff --git a/steps/directive-use/src/app/app.module.ts b/steps/directive-use/src/app/app.module.ts new file mode 100644 index 00000000..0160d64c --- /dev/null +++ b/steps/directive-use/src/app/app.module.ts @@ -0,0 +1,65 @@ +// CORE DEPS +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { HttpClientModule, HttpClient } from '@angular/common/http'; +import { ReactiveFormsModule } from '@angular/forms'; +// MATERIAL DESIGN MODULES +import { + MatToolbarModule, + MatCardModule, + MatTabsModule, + MatButtonModule, + MatInputModule, + MatCheckboxModule, + MatRadioModule, + MatIconModule, + MatListModule, + MatDialogModule +} from '@angular/material'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; + +import { APP_ROUTES } from './app.routes'; + +import { PeopleAppComponent } from './app.component'; +import { HomeComponent } from './home'; +import { PeopleComponent } from './people'; +import { CardComponent } from './shared/card'; +import { AddDialogComponent } from './people/add-dialog/add-dialog.component'; +import { FormComponent } from './shared/form'; +import { UpdateComponent } from './update/update.component'; +import { PeopleService } from 'app/shared/people-service'; +import { NaPipe } from 'app/shared/na-pipe'; + +@NgModule({ + imports: [ + BrowserModule, + BrowserAnimationsModule, + MatToolbarModule, + MatCardModule, + MatTabsModule, + MatButtonModule, + MatInputModule, + MatCheckboxModule, + MatRadioModule, + MatIconModule, + MatListModule, + MatDialogModule, + APP_ROUTES, + HttpClientModule, + ReactiveFormsModule + ], + declarations: [ + PeopleAppComponent, + HomeComponent, + PeopleComponent, + CardComponent, + AddDialogComponent, + FormComponent, + UpdateComponent, + NaPipe + ], + entryComponents: [AddDialogComponent], + providers: [HttpClient, PeopleService], + bootstrap: [PeopleAppComponent] +}) +export class AppModule {} diff --git a/steps/directive-use/src/app/app.routes.ts b/steps/directive-use/src/app/app.routes.ts new file mode 100644 index 00000000..1406a666 --- /dev/null +++ b/steps/directive-use/src/app/app.routes.ts @@ -0,0 +1,15 @@ +import { RouterModule, Routes } from '@angular/router'; + +// APP COMPONENTS +import { HomeComponent } from './home/index'; +import { PeopleComponent } from './people/index'; +import { UpdateComponent } from './update/index'; + +const ROUTES: Routes = [ + { path: '', redirectTo: 'home', pathMatch: 'full' }, + { path: 'home', component: HomeComponent }, + { path: 'people', component: PeopleComponent }, + { path: 'edit/:id', component: UpdateComponent } +]; + +export const APP_ROUTES = RouterModule.forRoot(ROUTES, { useHash: true }); diff --git a/steps/directive-use/src/app/home/home.component.css b/steps/directive-use/src/app/home/home.component.css new file mode 100644 index 00000000..f9428ad8 --- /dev/null +++ b/steps/directive-use/src/app/home/home.component.css @@ -0,0 +1,10 @@ +h1 { + text-align: center; +} + +section { + display: flex; + flex-flow: row wrap; + align-items: center; + justify-content: center; +} diff --git a/steps/directive-use/src/app/home/home.component.html b/steps/directive-use/src/app/home/home.component.html new file mode 100644 index 00000000..6a1dd6c9 --- /dev/null +++ b/steps/directive-use/src/app/home/home.component.html @@ -0,0 +1,3 @@ +
+ + diff --git a/steps/directive-use/src/app/home/home.component.ts b/steps/directive-use/src/app/home/home.component.ts new file mode 100644 index 00000000..d7b8fa17 --- /dev/null +++ b/steps/directive-use/src/app/home/home.component.ts @@ -0,0 +1,30 @@ +import { Component, OnInit } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { environment } from '../../environments/environment'; + +const BASE_URL = 'http://localhost:9000'; + +@Component({ + selector: 'sfeir-home', + templateUrl: 'home.component.html', + styleUrls: ['home.component.css'] +}) +export class HomeComponent implements OnInit { + private person: any = {}; + + constructor(private _http: HttpClient) {} + + /** + * OnInit implementation + */ + ngOnInit() { + this._http.get(`${BASE_URL}/api/peoples/`).subscribe(people => (this.person = people[0])); + } + + /** + * Returns random people + */ + random() { + this._http.get(`${BASE_URL}/api/peoples/random`).subscribe(person => (this.person = person)); + } +} diff --git a/steps/directive-use/src/app/home/index.ts b/steps/directive-use/src/app/home/index.ts new file mode 100644 index 00000000..ab5a522c --- /dev/null +++ b/steps/directive-use/src/app/home/index.ts @@ -0,0 +1 @@ +export * from './home.component'; diff --git a/steps/directive-use/src/app/index.ts b/steps/directive-use/src/app/index.ts new file mode 100644 index 00000000..875bdb2f --- /dev/null +++ b/steps/directive-use/src/app/index.ts @@ -0,0 +1,2 @@ +export * from './app.component'; +export * from './app.module'; diff --git a/steps/directive-use/src/app/people/add-dialog/add-dialog.component.css b/steps/directive-use/src/app/people/add-dialog/add-dialog.component.css new file mode 100644 index 00000000..e69de29b diff --git a/steps/directive-use/src/app/people/add-dialog/add-dialog.component.html b/steps/directive-use/src/app/people/add-dialog/add-dialog.component.html new file mode 100644 index 00000000..00b10c2c --- /dev/null +++ b/steps/directive-use/src/app/people/add-dialog/add-dialog.component.html @@ -0,0 +1 @@ + diff --git a/steps/directive-use/src/app/people/add-dialog/add-dialog.component.spec.ts b/steps/directive-use/src/app/people/add-dialog/add-dialog.component.spec.ts new file mode 100644 index 00000000..e7099893 --- /dev/null +++ b/steps/directive-use/src/app/people/add-dialog/add-dialog.component.spec.ts @@ -0,0 +1,24 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AddDialogComponent } from './add-dialog.component'; + +describe('AddDialogComponent', () => { + let component: AddDialogComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [AddDialogComponent] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AddDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/steps/directive-use/src/app/people/add-dialog/add-dialog.component.ts b/steps/directive-use/src/app/people/add-dialog/add-dialog.component.ts new file mode 100644 index 00000000..2710287e --- /dev/null +++ b/steps/directive-use/src/app/people/add-dialog/add-dialog.component.ts @@ -0,0 +1,25 @@ +import { Component, OnInit } from '@angular/core'; +import { MatDialogRef } from '@angular/material'; + +@Component({ + selector: 'sfeir-add-dialog', + templateUrl: './add-dialog.component.html', + styleUrls: ['./add-dialog.component.css'] +}) +export class AddDialogComponent implements OnInit { + constructor(public dialogRef: MatDialogRef) {} + + closeDialog(result = null) { + this.dialogRef.close(result); + } + + ngOnInit() {} + + onCancel() { + this.closeDialog(); + } + + onSave(person) { + this.closeDialog(person); + } +} diff --git a/steps/directive-use/src/app/people/index.ts b/steps/directive-use/src/app/people/index.ts new file mode 100644 index 00000000..469a1b27 --- /dev/null +++ b/steps/directive-use/src/app/people/index.ts @@ -0,0 +1 @@ +export * from './people.component'; diff --git a/steps/directive-use/src/app/people/people.component.css b/steps/directive-use/src/app/people/people.component.css new file mode 100644 index 00000000..e896bb5d --- /dev/null +++ b/steps/directive-use/src/app/people/people.component.css @@ -0,0 +1,65 @@ +h1 { + text-align: center; +} + +section { + display: flex; + flex-flow: row wrap; + align-items: center; + justify-content: center; +} + +.list { + padding-bottom: 100px; +} + +.dialog-modal { + top: 0; + position: fixed; + background: rgba(0, 0, 0, 0.5); + height: 100%; + width: 100%; + display: flex; + flex-basis: auto; + visibility: hidden; + color: white; +} +.dialog-modal.active { + visibility: visible; +} + +mat-list-item { + border: 1px solid rgba(0, 0, 0, 0.1); + color: rgba(0, 0, 0, 0.87); + background-color: white; + margin-left: -12px; + font-size: 14px; + display: block; + margin: 3px 0; + padding: 0; + height: 70px; + width: 400px; + transition: box-shadow 0.2s; + cursor: pointer; +} + +mat-list-item:hover { + box-shadow: 0 24px 38px 3px rgba(0, 0, 0, 0.14), 0 9px 46px 8px rgba(0, 0, 0, 0.12); +} + +.buttons-fab { + display: block; + height: 170px; + width: 90px; + position: fixed; + bottom: 0; + right: 0; +} + +.buttons-fab button { + transition: bottom 0.2s; +} + +.buttons-fab:hover .button-add { + bottom: 90px; +} diff --git a/steps/directive-use/src/app/people/people.component.html b/steps/directive-use/src/app/people/people.component.html new file mode 100644 index 00000000..44e74b55 --- /dev/null +++ b/steps/directive-use/src/app/people/people.component.html @@ -0,0 +1,28 @@ +
+ +
+ +
+ + + +

{{ person.firstname }} {{ person.lastname }}

+

+ {{ person.entity }} {{ person.email }} +

+
+
+
+ +
+ +
+ +
+ + + +
diff --git a/steps/directive-use/src/app/people/people.component.ts b/steps/directive-use/src/app/people/people.component.ts new file mode 100644 index 00000000..729c03a2 --- /dev/null +++ b/steps/directive-use/src/app/people/people.component.ts @@ -0,0 +1,60 @@ +import { Component, OnInit } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; +import { AddDialogComponent } from './add-dialog/add-dialog.component'; +import { PeopleService } from '../shared/people-service'; +import 'rxjs/add/operator/mergeMap'; + +@Component({ + selector: 'sfeir-people', + templateUrl: 'people.component.html', + styleUrls: ['people.component.css'] +}) +export class PeopleComponent implements OnInit { + private addDialog: MatDialogRef; + people; + dialogStatus = 'inactive'; + + constructor(private _http: HttpClient, public dialog: MatDialog, private _peopleService: PeopleService) {} + + /** + * OnInit implementation + */ + ngOnInit() { + this._peopleService.fetch().subscribe(people => (this.people = people)); + } + + delete(person: any) { + this._peopleService.delete(person.id).subscribe(people => (this.people = people)); + } + + add(person: any) { + this._peopleService + .update(person) + .mergeMap(res => this._peopleService.fetch()) + .subscribe((people: any[]) => { + this.people = people; + this.hideDialog(); + }); + } + + showDialog() { + this.dialogStatus = 'active'; + this.addDialog = this.dialog.open(AddDialogComponent, { + width: '450px', + data: {} + }); + + this.addDialog.afterClosed().subscribe(person => { + this.dialogStatus = 'inactive'; + if (person) { + this.add(person); + } + }); + } + + hideDialog() { + this.dialogStatus = 'inactive'; + this.addDialog.close(); + } +} diff --git a/steps/directive-use/src/app/shared/card/card.component.css b/steps/directive-use/src/app/shared/card/card.component.css new file mode 100644 index 00000000..8febb8ac --- /dev/null +++ b/steps/directive-use/src/app/shared/card/card.component.css @@ -0,0 +1,137 @@ +@media (min-width: 768px) { + :host(.wide) mat-card, + :host(.wide) mat-list-item { + width: 600px; + } +} + +mat-card, +mat-list-item { + color: rgba(0, 0, 0, 0.87); + background-color: white; + margin: 10px; + width: 360px; +} + +mat-card:hover { + box-shadow: 0 11px 15px -7px rgba(0, 0, 0, 0.2), 0 24px 38px 3px rgba(0, 0, 0, 0.14), + 0 9px 46px 8px rgba(0, 0, 0, 0.12); +} + +mat-list-item { + height: 22px; + padding: 0; + margin-left: -12px; + font-size: 14px; +} + +mat-card-title { + margin-bottom: 0; +} + +mat-card-title span { + font-size: 24px; + font-weight: 400; + line-height: 32px; +} + +mat-card-subtitle.contact-info { + margin-top: -7px; + height: 20px; +} + +mat-card-title-group { + margin-bottom: 20px; +} + +.contact-info mat-icon + a { + top: -8px; + position: relative; + height: 18px; +} + +.contact-info a:hover { + text-decoration: underline; +} + +.buttons-info { + float: right; + margin-top: -50px; +} + +@media (max-width: 412px) { + .buttons-info { + margin-top: -34px; + } +} + +.buttons-info [mat-button] { + min-width: 0px; + padding: 2px; + height: 40px; +} + +mat-icon { + color: rgba(0, 0, 0, 0.54); + margin: 4px; +} + +a { + color: #337ab7; + text-decoration: none; +} + +mat-card-actions button[mat-raised-button] { + margin: 5px; +} + +.hl { + background-color: orange; + color: white; +} + +.skills { + padding: 10px; + background-color: #fafafa; +} + +a.truncate { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + display: inline-block; + width: 188px; +} + +@media (max-width: 600px) { + a.truncate { + width: 170px; + } +} + +@media (max-width: 768px) { + a.truncate { + width: 190px; + } +} + +.mat-whiteframe-2dp { + box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12); +} + +img { + border-radius: 50%; + margin-right: 18px; +} + +@media (max-width: 412px) { + img { + margin-right: 3px; + } +} + +@media (max-width: 600px) { + img { + margin-right: 5px; + } +} diff --git a/steps/directive-use/src/app/shared/card/card.component.html b/steps/directive-use/src/app/shared/card/card.component.html new file mode 100644 index 00000000..1b2790cb --- /dev/null +++ b/steps/directive-use/src/app/shared/card/card.component.html @@ -0,0 +1,38 @@ + + + + + + {{ person.firstname }} {{ person.lastname }} + + + {{ person.entity }} + + email + {{ person.email }} + + + phone + {{ person.phone }} + + + +
+ Manager :  {{ person.manager | na }} +
+
Location : SFEIR
+
+ Birth Date : {{ person.birthDate | date: 'dd/MM/yyyy' }} +
+ +
+
diff --git a/steps/directive-use/src/app/shared/card/card.component.ts b/steps/directive-use/src/app/shared/card/card.component.ts new file mode 100644 index 00000000..b7aecc77 --- /dev/null +++ b/steps/directive-use/src/app/shared/card/card.component.ts @@ -0,0 +1,30 @@ +import { Component, OnInit, Input, EventEmitter, Output } from '@angular/core'; + +@Component({ + selector: 'sfeir-card', + templateUrl: 'card.component.html', + styleUrls: ['card.component.css'] +}) +export class CardComponent implements OnInit { + @Input() person: any; + @Output('personDelete') delete$: EventEmitter; + + constructor() { + this.person = {}; + this.delete$ = new EventEmitter(); + } + + /** + * OnInit implementation + */ + ngOnInit() {} + + /** + * Function to emit event to delete current person + * + * @param person + */ + delete(person: any) { + this.delete$.emit(person); + } +} diff --git a/steps/directive-use/src/app/shared/card/index.ts b/steps/directive-use/src/app/shared/card/index.ts new file mode 100644 index 00000000..54bbbca7 --- /dev/null +++ b/steps/directive-use/src/app/shared/card/index.ts @@ -0,0 +1 @@ +export * from './card.component'; diff --git a/steps/directive-use/src/app/shared/form/custom-validators.ts b/steps/directive-use/src/app/shared/form/custom-validators.ts new file mode 100644 index 00000000..c52bf184 --- /dev/null +++ b/steps/directive-use/src/app/shared/form/custom-validators.ts @@ -0,0 +1,22 @@ +import { FormControl } from '@angular/forms'; + +export class CustomValidators { + /** + * Function to control email with custom validator + * + * @param control + * + * @returns {{sfeirEmail: boolean}} + */ + static sfeirEmail(control: FormControl) { + // email regex + const regex = /^\w+\.\w@sfeir\.com$/; + + // returns control + return regex.test(control.value) + ? null + : { + sfeirEmail: true + }; + } +} diff --git a/steps/directive-use/src/app/shared/form/form.component.css b/steps/directive-use/src/app/shared/form/form.component.css new file mode 100644 index 00000000..7ddb2dc6 --- /dev/null +++ b/steps/directive-use/src/app/shared/form/form.component.css @@ -0,0 +1,51 @@ +mat-card, +mat-list-item { + color: rgba(0, 0, 0, 0.87); + background-color: white; + width: 360px; +} + +mat-card:hover { + box-shadow: 0 11px 15px -7px rgba(0, 0, 0, 0.2), 0 24px 38px 3px rgba(0, 0, 0, 0.14), + 0 9px 46px 8px rgba(0, 0, 0, 0.12); +} + +mat-list-item { + height: 22px; + padding: 0; + margin-left: -12px; + font-size: 14px; +} + +mat-card-title { + margin-bottom: 0; +} + +mat-card-title span { + font-size: 24px; + font-weight: 400; + line-height: 32px; +} + +mat-card-subtitle { + margin-top: -18px; + height: 17px; +} + +mat-card-title-group { + margin-bottom: 20px; +} + +img { + border-radius: 50%; + margin-right: 18px; + -webkit-filter: grayscale(100%); +} + +.align-right { + text-align: right; +} + +.errors { + color: red; +} diff --git a/steps/directive-use/src/app/shared/form/form.component.html b/steps/directive-use/src/app/shared/form/form.component.html new file mode 100644 index 00000000..275b9043 --- /dev/null +++ b/steps/directive-use/src/app/shared/form/form.component.html @@ -0,0 +1,102 @@ + + + Update {{ form.controls.firstname.value }} {{ form.controls.lastname.value }} + Create new person + + + +
+

+ ID (disabled)
+ {{ model.id }} +

+ + + + + + +
+

+ + + + +
First name is required
+
First name is 2 chars min
+

+ +

+ + + + +
Last name is required
+
Last name is 2 chars min
+

+
+ + +
+ +

+ + + + + Email is mandatory +
Invalid email (ex: chegham.w@sfeir.com)
+

+ +

+ + + +

+ +

+ + + + +

+ +

+ + + + + Phone number is mandatory + Phone number must be 10 digits +

+ +

Manager

+
+
+ + + + + +
diff --git a/steps/directive-use/src/app/shared/form/form.component.ts b/steps/directive-use/src/app/shared/form/form.component.ts new file mode 100644 index 00000000..7fb31299 --- /dev/null +++ b/steps/directive-use/src/app/shared/form/form.component.ts @@ -0,0 +1,81 @@ +import { Component, OnInit, Output, Input, EventEmitter, OnChanges } from '@angular/core'; +import { FormControl, Validators, FormGroup } from '@angular/forms'; + +import { CustomValidators } from './custom-validators'; + +@Component({ + selector: 'sfeir-form', + templateUrl: 'form.component.html', + styleUrls: ['form.component.css'] +}) +export class FormComponent implements OnInit, OnChanges { + private form: FormGroup; + @Input() model: any; + isUpdateMode: boolean; + + @Output('cancel') cancel$: EventEmitter; + @Output('submit') submit$: EventEmitter; + + constructor() { + this.submit$ = new EventEmitter(); + this.cancel$ = new EventEmitter(); + this.model = { address: {} }; + this.form = this._buildForm(); + } + + /** + * OnInit implementation + */ + ngOnInit() {} + + /** + * Function to handle component update + * + * @param record + */ + ngOnChanges(record) { + if (record.model && record.model.currentValue) { + this.model = record.model.currentValue; + this.isUpdateMode = !!this.model; + this.form.patchValue(this.model); + } + } + + /** + * Function to emit event to cancel process + */ + cancel() { + this.cancel$.emit(); + } + + /** + * Function to emit event to submit form and person + */ + submit(person: any) { + this.submit$.emit(person); + } + + /** + * Function to build our form + * + * @returns {FormGroup} + * + * @private + */ + private _buildForm(): FormGroup { + return new FormGroup({ + id: new FormControl(''), + firstname: new FormControl('', Validators.compose([Validators.required, Validators.minLength(2)])), + lastname: new FormControl('', Validators.compose([Validators.required, Validators.minLength(2)])), + email: new FormControl('', Validators.compose([Validators.required, CustomValidators.sfeirEmail])), + photo: new FormControl('https://randomuser.me/api/portraits/lego/6.jpg'), + address: new FormGroup({ + street: new FormControl(''), + city: new FormControl(''), + postalCode: new FormControl('') + }), + phone: new FormControl('', Validators.compose([Validators.required, Validators.pattern('\\d{10}')])), + isManager: new FormControl('') + }); + } +} diff --git a/steps/directive-use/src/app/shared/form/index.ts b/steps/directive-use/src/app/shared/form/index.ts new file mode 100644 index 00000000..780c593b --- /dev/null +++ b/steps/directive-use/src/app/shared/form/index.ts @@ -0,0 +1 @@ +export * from './form.component'; diff --git a/steps/directive-use/src/app/shared/index.ts b/steps/directive-use/src/app/shared/index.ts new file mode 100644 index 00000000..403503fc --- /dev/null +++ b/steps/directive-use/src/app/shared/index.ts @@ -0,0 +1,4 @@ +export * from './card/index'; +export * from './form/index'; +export * from './na-pipe/index'; +export * from './people-service/index'; diff --git a/steps/directive-use/src/app/shared/na-pipe/index.ts b/steps/directive-use/src/app/shared/na-pipe/index.ts new file mode 100644 index 00000000..029c3506 --- /dev/null +++ b/steps/directive-use/src/app/shared/na-pipe/index.ts @@ -0,0 +1 @@ +export * from './na.pipe'; diff --git a/steps/directive-use/src/app/shared/na-pipe/na.pipe.ts b/steps/directive-use/src/app/shared/na-pipe/na.pipe.ts new file mode 100644 index 00000000..18e5a158 --- /dev/null +++ b/steps/directive-use/src/app/shared/na-pipe/na.pipe.ts @@ -0,0 +1,18 @@ +import { Pipe, PipeTransform } from '@angular/core'; + +@Pipe({ + name: 'na' +}) +export class NaPipe implements PipeTransform { + /** + * Function to transform input value + * + * @param value + * @param args + * + * @returns {any|string} + */ + transform(value: any, args?: any): any { + return value || 'N/A'; + } +} diff --git a/steps/directive-use/src/app/shared/people-service/index.ts b/steps/directive-use/src/app/shared/people-service/index.ts new file mode 100644 index 00000000..1f73446f --- /dev/null +++ b/steps/directive-use/src/app/shared/people-service/index.ts @@ -0,0 +1 @@ +export * from './people.service'; diff --git a/steps/directive-use/src/app/shared/people-service/people.service.ts b/steps/directive-use/src/app/shared/people-service/people.service.ts new file mode 100644 index 00000000..98a7b24e --- /dev/null +++ b/steps/directive-use/src/app/shared/people-service/people.service.ts @@ -0,0 +1,48 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { environment } from '../../../environments/environment'; + +@Injectable() +export class PeopleService { + private _backendURL: any; + + constructor(private _http: HttpClient) { + this._backendURL = {}; + + // build backend base url + let baseUrl = `${environment.backend.protocol}://${environment.backend.host}`; + if (environment.backend.port) { + baseUrl += `:${environment.backend.port}`; + } + + // build all backend urls + Object.keys(environment.backend.endpoints).forEach( + k => (this._backendURL[k] = `${baseUrl}${environment.backend.endpoints[k]}`) + ); + } + + fetch(): Observable { + return this._http.get(this._backendURL.allPeople); + } + + fetchRandom(): Observable { + return this._http.get(this._backendURL.randomPeople); + } + + fetchOne(id: string): Observable { + return this._http.get(this._backendURL.onePeople.replace(':id', id)); + } + + delete(id: string): Observable { + return this._http.delete(this._backendURL.onePeople.replace(':id', id)); + } + + update(person: any): Observable { + return this._http.put(this._backendURL.onePeople.replace(':id', person.id), person); + } + + create(person): Observable { + return this._http.post(this._backendURL.allPeople, person); + } +} diff --git a/steps/directive-use/src/app/update/index.ts b/steps/directive-use/src/app/update/index.ts new file mode 100644 index 00000000..50848161 --- /dev/null +++ b/steps/directive-use/src/app/update/index.ts @@ -0,0 +1 @@ +export * from './update.component'; diff --git a/steps/directive-use/src/app/update/update.component.css b/steps/directive-use/src/app/update/update.component.css new file mode 100644 index 00000000..f9428ad8 --- /dev/null +++ b/steps/directive-use/src/app/update/update.component.css @@ -0,0 +1,10 @@ +h1 { + text-align: center; +} + +section { + display: flex; + flex-flow: row wrap; + align-items: center; + justify-content: center; +} diff --git a/steps/directive-use/src/app/update/update.component.html b/steps/directive-use/src/app/update/update.component.html new file mode 100644 index 00000000..872c9372 --- /dev/null +++ b/steps/directive-use/src/app/update/update.component.html @@ -0,0 +1 @@ +
diff --git a/steps/directive-use/src/app/update/update.component.ts b/steps/directive-use/src/app/update/update.component.ts new file mode 100644 index 00000000..e08ce778 --- /dev/null +++ b/steps/directive-use/src/app/update/update.component.ts @@ -0,0 +1,42 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import 'rxjs/add/operator/map'; +import 'rxjs/add/operator/mergeMap'; +import { Observable } from 'rxjs'; +import { PeopleService } from '../shared/people-service'; + +@Component({ + selector: 'sfeir-update', + templateUrl: 'update.component.html', + styleUrls: ['update.component.css'] +}) +export class UpdateComponent implements OnInit { + person: any; + + /** + * Component constructor + */ + constructor(private _route: ActivatedRoute, private _router: Router, private _peopleService: PeopleService) { + this.person = { + address: {} + }; + } + + /** + * OnInit implementation + */ + ngOnInit() { + this._route.params + .map((params: any) => params.id) + .mergeMap((id: string) => this._peopleService.fetchOne(id)) + .subscribe((person: any) => (this.person = person)); + } + + submit(person: any) { + this._peopleService.update(person).subscribe(() => this._router.navigate(['/people'])); + } + + cancel() { + this._router.navigate(['/people']); + } +} diff --git a/steps/directive-use/src/assets/.gitkeep b/steps/directive-use/src/assets/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/steps/directive-use/src/assets/.npmignore b/steps/directive-use/src/assets/.npmignore new file mode 100644 index 00000000..e69de29b diff --git a/steps/directive-use/src/assets/images/bg_right.png b/steps/directive-use/src/assets/images/bg_right.png new file mode 100644 index 0000000000000000000000000000000000000000..449e4bc82c2a6aecd449bbfcf9aad413ffc64968 GIT binary patch literal 16377 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 diff --git a/steps/directive-use/src/assets/images/icon-edit.svg b/steps/directive-use/src/assets/images/icon-edit.svg new file mode 100644 index 00000000..bb07333e --- /dev/null +++ b/steps/directive-use/src/assets/images/icon-edit.svg @@ -0,0 +1 @@ + diff --git a/steps/directive-use/src/assets/images/icon-mail.svg b/steps/directive-use/src/assets/images/icon-mail.svg new file mode 100644 index 00000000..040a7e7f --- /dev/null +++ b/steps/directive-use/src/assets/images/icon-mail.svg @@ -0,0 +1 @@ + diff --git a/steps/directive-use/src/assets/images/icon-maps.svg b/steps/directive-use/src/assets/images/icon-maps.svg new file mode 100644 index 00000000..989697e2 --- /dev/null +++ b/steps/directive-use/src/assets/images/icon-maps.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + diff --git a/steps/directive-use/src/assets/images/icon-phone.svg b/steps/directive-use/src/assets/images/icon-phone.svg new file mode 100644 index 00000000..15ac4a3e --- /dev/null +++ b/steps/directive-use/src/assets/images/icon-phone.svg @@ -0,0 +1 @@ + diff --git a/steps/directive-use/src/assets/images/logo-sfeir.svg b/steps/directive-use/src/assets/images/logo-sfeir.svg new file mode 100644 index 00000000..9d6e4c3e --- /dev/null +++ b/steps/directive-use/src/assets/images/logo-sfeir.svg @@ -0,0 +1,18 @@ + + + + + + + + + diff --git a/steps/directive-use/src/assets/images/search-icon.svg b/steps/directive-use/src/assets/images/search-icon.svg new file mode 100644 index 00000000..92e95a18 --- /dev/null +++ b/steps/directive-use/src/assets/images/search-icon.svg @@ -0,0 +1,16 @@ + + + + + + + diff --git a/steps/directive-use/src/environments/environment.prod.ts b/steps/directive-use/src/environments/environment.prod.ts new file mode 100644 index 00000000..051ee330 --- /dev/null +++ b/steps/directive-use/src/environments/environment.prod.ts @@ -0,0 +1,13 @@ +export const environment = { + production: true, + backend: { + protocol: 'http', + host: '127.0.0.1', + port: '9000', + endpoints: { + allPeople: '/api/peoples', + onePeople: '/api/peoples/:id', + randomPeople: '/api/peoples/random' + } + } +}; diff --git a/steps/directive-use/src/environments/environment.ts b/steps/directive-use/src/environments/environment.ts new file mode 100644 index 00000000..0a0c15f8 --- /dev/null +++ b/steps/directive-use/src/environments/environment.ts @@ -0,0 +1,18 @@ +// The file contents for the current environment will overwrite these during build. +// The build system defaults to the dev environment which uses `environment.ts`, but if you do +// `ng build --env=prod` then `environment.prod.ts` will be used instead. +// The list of which env maps to which file can be found in `angular-cli.json`. + +export const environment = { + production: false, + backend: { + protocol: 'http', + host: '127.0.0.1', + port: '9000', + endpoints: { + allPeople: '/api/peoples', + onePeople: '/api/peoples/:id', + randomPeople: '/api/peoples/random' + } + } +}; diff --git a/steps/directive-use/src/favicon.ico b/steps/directive-use/src/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..8081c7ceaf2be08bf59010158c586170d9d2d517 GIT binary patch literal 5430 zcmc(je{54#6vvCoAI3i*G5%$U7!sA3wtMZ$fH6V9C`=eXGJb@R1%(I_{vnZtpD{6n z5Pl{DmxzBDbrB>}`90e12m8T*36WoeDLA&SD_hw{H^wM!cl_RWcVA!I+x87ee975; z@4kD^=bYPn&pmG@(+JZ`rqQEKxW<}RzhW}I!|ulN=fmjVi@x{p$cC`)5$a!)X&U+blKNvN5tg=uLvuLnuqRM;Yc*swiexsoh#XPNu{9F#c`G zQLe{yWA(Y6(;>y|-efAy11k<09(@Oo1B2@0`PtZSkqK&${ zgEY}`W@t{%?9u5rF?}Y7OL{338l*JY#P!%MVQY@oqnItpZ}?s z!r?*kwuR{A@jg2Chlf0^{q*>8n5Ir~YWf*wmsh7B5&EpHfd5@xVaj&gqsdui^spyL zB|kUoblGoO7G(MuKTfa9?pGH0@QP^b#!lM1yHWLh*2iq#`C1TdrnO-d#?Oh@XV2HK zKA{`eo{--^K&MW66Lgsktfvn#cCAc*(}qsfhrvOjMGLE?`dHVipu1J3Kgr%g?cNa8 z)pkmC8DGH~fG+dlrp(5^-QBeEvkOvv#q7MBVLtm2oD^$lJZx--_=K&Ttd=-krx(Bb zcEoKJda@S!%%@`P-##$>*u%T*mh+QjV@)Qa=Mk1?#zLk+M4tIt%}wagT{5J%!tXAE;r{@=bb%nNVxvI+C+$t?!VJ@0d@HIyMJTI{vEw0Ul ze(ha!e&qANbTL1ZneNl45t=#Ot??C0MHjjgY8%*mGisN|S6%g3;Hlx#fMNcL<87MW zZ>6moo1YD?P!fJ#Jb(4)_cc50X5n0KoDYfdPoL^iV`k&o{LPyaoqMqk92wVM#_O0l z09$(A-D+gVIlq4TA&{1T@BsUH`Bm=r#l$Z51J-U&F32+hfUP-iLo=jg7Xmy+WLq6_tWv&`wDlz#`&)Jp~iQf zZP)tu>}pIIJKuw+$&t}GQuqMd%Z>0?t%&BM&Wo^4P^Y z)c6h^f2R>X8*}q|bblAF?@;%?2>$y+cMQbN{X$)^R>vtNq_5AB|0N5U*d^T?X9{xQnJYeU{ zoZL#obI;~Pp95f1`%X3D$Mh*4^?O?IT~7HqlWguezmg?Ybq|7>qQ(@pPHbE9V?f|( z+0xo!#m@Np9PljsyxBY-UA*{U*la#8Wz2sO|48_-5t8%_!n?S$zlGe+NA%?vmxjS- zHE5O3ZarU=X}$7>;Okp(UWXJxI%G_J-@IH;%5#Rt$(WUX?6*Ux!IRd$dLP6+SmPn= z8zjm4jGjN772R{FGkXwcNv8GBcZI#@Y2m{RNF_w8(Z%^A*!bS*!}s6sh*NnURytky humW;*g7R+&|Ledvc- + + + + Angular2200 + + + + + + + + +
+ + + +
+
+ + diff --git a/steps/directive-use/src/main.ts b/steps/directive-use/src/main.ts new file mode 100644 index 00000000..fa4e0aef --- /dev/null +++ b/steps/directive-use/src/main.ts @@ -0,0 +1,13 @@ +import { enableProdMode } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; +import { environment } from './environments/environment'; + +if (environment.production) { + enableProdMode(); +} + +platformBrowserDynamic() + .bootstrapModule(AppModule) + .catch(err => console.error(err)); diff --git a/steps/directive-use/src/polyfills.ts b/steps/directive-use/src/polyfills.ts new file mode 100644 index 00000000..b9a73c9a --- /dev/null +++ b/steps/directive-use/src/polyfills.ts @@ -0,0 +1,79 @@ +/** + * This file includes polyfills needed by Angular and is loaded before the app. + * You can add your own extra polyfills to this file. + * + * This file is divided into 2 sections: + * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. + * 2. Application imports. Files imported after ZoneJS that should be loaded before your main + * file. + * + * The current setup is for so-called "evergreen" browsers; the last versions of browsers that + * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), + * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. + * + * Learn more in https://angular.io/guide/browser-support + */ + +/*************************************************************************************************** + * BROWSER POLYFILLS + */ + +/** IE9, IE10 and IE11 requires all of the following polyfills. **/ +// import 'core-js/es6/symbol'; +// import 'core-js/es6/object'; +// import 'core-js/es6/function'; +// import 'core-js/es6/parse-int'; +// import 'core-js/es6/parse-float'; +// import 'core-js/es6/number'; +// import 'core-js/es6/math'; +// import 'core-js/es6/string'; +// import 'core-js/es6/date'; +// import 'core-js/es6/array'; +// import 'core-js/es6/regexp'; +// import 'core-js/es6/map'; +// import 'core-js/es6/weak-map'; +// import 'core-js/es6/set'; + +/** + * If the application will be indexed by Google Search, the following is required. + * Googlebot uses a renderer based on Chrome 41. + * https://developers.google.com/search/docs/guides/rendering + **/ +// import 'core-js/es6/array'; + +/** IE10 and IE11 requires the following for NgClass support on SVG elements */ +// import 'classlist.js'; // Run `npm install --save classlist.js`. + +/** IE10 and IE11 requires the following for the Reflect API. */ +// import 'core-js/es6/reflect'; + +/** + * Web Animations `@angular/platform-browser/animations` + * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. + * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). + **/ +// import 'web-animations-js'; // Run `npm install --save web-animations-js`. + +/** + * By default, zone.js will patch all possible macroTask and DomEvents + * user can disable parts of macroTask/DomEvents patch by setting following flags + */ + +// (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame +// (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick +// (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames + +/* + * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js + * with the following flag, it will bypass `zone.js` patch for IE/Edge + */ +// (window as any).__Zone_enable_cross_context_check = true; + +/*************************************************************************************************** + * Zone JS is required by default for Angular itself. + */ +import 'zone.js/dist/zone'; // Included with Angular CLI. + +/*************************************************************************************************** + * APPLICATION IMPORTS + */ diff --git a/steps/directive-use/src/styles.css b/steps/directive-use/src/styles.css new file mode 100644 index 00000000..57faf2d8 --- /dev/null +++ b/steps/directive-use/src/styles.css @@ -0,0 +1,103 @@ +@import '~@angular/material/prebuilt-themes/indigo-pink.css'; + +body { + background: red; + padding: 0; + margin: 0; + font-family: 'Open Sans', sans-serif; + background-color: #fafafa; + -webkit-font-smoothing: antialiased; +} +* /deep/ * { + font-family: inherit; + font-size: 14px; + line-height: 1.42857143; + color: inherit; +} +h1, +* /deep/ h1 { + font-size: 36px; + margin-top: 20px; + margin-bottom: 10px; +} + +button[mat-fab], +a[mat-fab] { + position: fixed; + bottom: 20px; + right: 20px; +} + +[mat-fab] mat-icon { + font-size: 2em; + line-height: 18.6px; +} + +.loader { + position: relative; + margin: 0 auto; + width: 100px; + transform: scale(1.5); +} +.loader:before { + content: ''; + display: block; + padding-top: 100%; +} + +.circular { + animation: rotate 2s linear infinite; + height: 100%; + transform-origin: center center; + width: 100%; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; +} + +.path { + stroke-dasharray: 1, 200; + stroke-dashoffset: 0; + animation: dash 1.5s ease-in-out infinite, color 6s ease-in-out infinite; + stroke-linecap: round; +} + +@keyframes rotate { + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} +@keyframes dash { + 0% { + stroke-dasharray: 1, 200; + stroke-dashoffset: 0; + } + 50% { + stroke-dasharray: 89, 200; + stroke-dashoffset: -35px; + } + 100% { + stroke-dasharray: 89, 200; + stroke-dashoffset: -124px; + } +} +@keyframes color { + 100%, + 0% { + stroke: #d62d20; + } + 40% { + stroke: #0057e7; + } + 66% { + stroke: #008744; + } + 80%, + 90% { + stroke: #ffa700; + } +} diff --git a/steps/directive-use/tsconfig.app.json b/steps/directive-use/tsconfig.app.json new file mode 100644 index 00000000..7beda31d --- /dev/null +++ b/steps/directive-use/tsconfig.app.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/app", + "types": [] + }, + "exclude": ["test.ts", "**/*.spec.ts"] +}