├── APM-Demo0 ├── src │ ├── assets │ │ ├── .gitkeep │ │ └── images │ │ │ └── logo.jpg │ ├── app │ │ ├── app.component.css │ │ ├── app.component.html │ │ ├── user │ │ │ ├── login.component.css │ │ │ ├── user.ts │ │ │ ├── user.module.ts │ │ │ ├── auth.service.ts │ │ │ ├── auth-guard.service.ts │ │ │ └── login.component.ts │ │ ├── home │ │ │ ├── shell.component.css │ │ │ ├── shell.component.html │ │ │ ├── welcome.component.ts │ │ │ ├── page-not-found.component.ts │ │ │ ├── shell.component.ts │ │ │ ├── menu.component.ts │ │ │ ├── welcome.component.html │ │ │ └── menu.component.html │ │ ├── products │ │ │ ├── product-list │ │ │ │ ├── product-list.component.css │ │ │ │ ├── product-list.component.html │ │ │ │ └── product-list.component.ts │ │ │ ├── product.ts │ │ │ ├── product-shell │ │ │ │ ├── product-shell.component.html │ │ │ │ └── product-shell.component.ts │ │ │ ├── product.module.ts │ │ │ └── product-data.ts │ │ ├── app.component.ts │ │ ├── shared │ │ │ ├── shared.module.ts │ │ │ └── number.validator.ts │ │ ├── app-routing.module.ts │ │ └── app.module.ts │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── favicon.ico │ ├── styles.css │ ├── index.html │ ├── main.ts │ └── test.ts ├── .vscode │ └── settings.json ├── e2e │ ├── tsconfig.json │ ├── src │ │ ├── app.po.ts │ │ └── app.e2e-spec.ts │ └── protractor.conf.js ├── tsconfig.app.json ├── .editorconfig ├── tsconfig.spec.json ├── browserslist ├── tsconfig.json ├── .gitignore ├── karma.conf.js ├── README.md └── package.json ├── APM-Demo1 ├── src │ ├── assets │ │ ├── .gitkeep │ │ └── images │ │ │ └── logo.jpg │ ├── app │ │ ├── app.component.css │ │ ├── app.component.html │ │ ├── user │ │ │ ├── login.component.css │ │ │ ├── user.ts │ │ │ ├── state │ │ │ │ └── user.reducer.ts │ │ │ ├── user.module.ts │ │ │ ├── auth.service.ts │ │ │ ├── auth-guard.service.ts │ │ │ └── login.component.ts │ │ ├── home │ │ │ ├── shell.component.css │ │ │ ├── shell.component.html │ │ │ ├── welcome.component.ts │ │ │ ├── page-not-found.component.ts │ │ │ ├── shell.component.ts │ │ │ ├── menu.component.ts │ │ │ ├── welcome.component.html │ │ │ └── menu.component.html │ │ ├── products │ │ │ ├── product-list │ │ │ │ ├── product-list.component.css │ │ │ │ └── product-list.component.html │ │ │ ├── product.ts │ │ │ ├── product-shell │ │ │ │ ├── product-shell.component.html │ │ │ │ └── product-shell.component.ts │ │ │ ├── state │ │ │ │ └── product.reducer.ts │ │ │ ├── product.module.ts │ │ │ └── product-data.ts │ │ ├── app.component.ts │ │ ├── shared │ │ │ ├── shared.module.ts │ │ │ └── number.validator.ts │ │ ├── app-routing.module.ts │ │ └── app.module.ts │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── favicon.ico │ ├── styles.css │ ├── index.html │ ├── main.ts │ └── test.ts ├── .vscode │ └── settings.json ├── e2e │ ├── tsconfig.json │ ├── src │ │ ├── app.po.ts │ │ └── app.e2e-spec.ts │ └── protractor.conf.js ├── tsconfig.app.json ├── .editorconfig ├── tsconfig.spec.json ├── browserslist ├── tsconfig.json ├── .gitignore ├── karma.conf.js ├── README.md └── package.json ├── APM-Demo2 ├── src │ ├── assets │ │ ├── .gitkeep │ │ └── images │ │ │ └── logo.jpg │ ├── app │ │ ├── app.component.css │ │ ├── app.component.html │ │ ├── user │ │ │ ├── login.component.css │ │ │ ├── user.ts │ │ │ ├── state │ │ │ │ ├── user.actions.ts │ │ │ │ └── user.reducer.ts │ │ │ ├── user.module.ts │ │ │ ├── auth.service.ts │ │ │ └── auth-guard.service.ts │ │ ├── home │ │ │ ├── shell.component.css │ │ │ ├── shell.component.html │ │ │ ├── welcome.component.ts │ │ │ ├── page-not-found.component.ts │ │ │ ├── shell.component.ts │ │ │ ├── menu.component.ts │ │ │ ├── welcome.component.html │ │ │ └── menu.component.html │ │ ├── products │ │ │ ├── product-list │ │ │ │ ├── product-list.component.css │ │ │ │ └── product-list.component.html │ │ │ ├── product.ts │ │ │ ├── product-shell │ │ │ │ ├── product-shell.component.html │ │ │ │ └── product-shell.component.ts │ │ │ ├── state │ │ │ │ └── product.actions.ts │ │ │ ├── product.module.ts │ │ │ └── product-data.ts │ │ ├── state │ │ │ └── app.state.ts │ │ ├── app.component.ts │ │ ├── shared │ │ │ ├── shared.module.ts │ │ │ └── number.validator.ts │ │ └── app-routing.module.ts │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── favicon.ico │ ├── styles.css │ ├── index.html │ ├── main.ts │ └── test.ts ├── .vscode │ └── settings.json ├── e2e │ ├── tsconfig.json │ ├── src │ │ ├── app.po.ts │ │ └── app.e2e-spec.ts │ └── protractor.conf.js ├── tsconfig.app.json ├── .editorconfig ├── tsconfig.spec.json ├── browserslist ├── tsconfig.json ├── .gitignore ├── karma.conf.js └── README.md ├── APM-Demo3 ├── src │ ├── assets │ │ ├── .gitkeep │ │ └── images │ │ │ └── logo.jpg │ ├── app │ │ ├── app.component.css │ │ ├── app.component.html │ │ ├── user │ │ │ ├── login.component.css │ │ │ ├── user.ts │ │ │ ├── state │ │ │ │ ├── user.actions.ts │ │ │ │ └── user.reducer.ts │ │ │ ├── user.module.ts │ │ │ ├── auth.service.ts │ │ │ ├── auth-guard.service.ts │ │ │ └── login.component.ts │ │ ├── home │ │ │ ├── shell.component.css │ │ │ ├── shell.component.html │ │ │ ├── welcome.component.ts │ │ │ ├── page-not-found.component.ts │ │ │ ├── shell.component.ts │ │ │ ├── menu.component.ts │ │ │ ├── welcome.component.html │ │ │ └── menu.component.html │ │ ├── products │ │ │ ├── product-list │ │ │ │ ├── product-list.component.css │ │ │ │ └── product-list.component.html │ │ │ ├── product.ts │ │ │ ├── product-shell │ │ │ │ ├── product-shell.component.html │ │ │ │ └── product-shell.component.ts │ │ │ ├── state │ │ │ │ ├── product.actions.ts │ │ │ │ └── product.effects.ts │ │ │ ├── product.module.ts │ │ │ └── product-data.ts │ │ ├── state │ │ │ └── app.state.ts │ │ ├── app.component.ts │ │ ├── shared │ │ │ ├── shared.module.ts │ │ │ └── number.validator.ts │ │ └── app-routing.module.ts │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── favicon.ico │ ├── styles.css │ ├── index.html │ ├── main.ts │ └── test.ts ├── .vscode │ └── settings.json ├── e2e │ ├── tsconfig.json │ ├── src │ │ ├── app.po.ts │ │ └── app.e2e-spec.ts │ └── protractor.conf.js ├── tsconfig.app.json ├── .editorconfig ├── tsconfig.spec.json ├── browserslist ├── tsconfig.json ├── .gitignore ├── karma.conf.js └── README.md ├── APM-Demo4 ├── src │ ├── assets │ │ ├── .gitkeep │ │ └── images │ │ │ └── logo.jpg │ ├── app │ │ ├── app.component.css │ │ ├── app.component.html │ │ ├── user │ │ │ ├── login.component.css │ │ │ ├── user.ts │ │ │ ├── state │ │ │ │ ├── user.actions.ts │ │ │ │ └── user.reducer.ts │ │ │ ├── user.module.ts │ │ │ ├── auth.service.ts │ │ │ ├── auth-guard.service.ts │ │ │ └── login.component.ts │ │ ├── home │ │ │ ├── shell.component.css │ │ │ ├── shell.component.html │ │ │ ├── welcome.component.ts │ │ │ ├── page-not-found.component.ts │ │ │ ├── shell.component.ts │ │ │ ├── menu.component.ts │ │ │ ├── welcome.component.html │ │ │ └── menu.component.html │ │ ├── products │ │ │ ├── product-list │ │ │ │ ├── product-list.component.css │ │ │ │ └── product-list.component.html │ │ │ ├── product.ts │ │ │ ├── product-shell │ │ │ │ ├── product-shell.component.html │ │ │ │ └── product-shell.component.ts │ │ │ ├── product.module.ts │ │ │ └── product-data.ts │ │ ├── state │ │ │ └── app.state.ts │ │ ├── app.component.ts │ │ ├── shared │ │ │ ├── shared.module.ts │ │ │ └── number.validator.ts │ │ └── app-routing.module.ts │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── favicon.ico │ ├── styles.css │ ├── index.html │ ├── main.ts │ └── test.ts ├── .vscode │ └── settings.json ├── e2e │ ├── tsconfig.json │ ├── src │ │ ├── app.po.ts │ │ └── app.e2e-spec.ts │ └── protractor.conf.js ├── tsconfig.app.json ├── .editorconfig ├── tsconfig.spec.json ├── browserslist ├── tsconfig.json ├── .gitignore ├── karma.conf.js └── README.md ├── APM-Demo5 ├── src │ ├── assets │ │ ├── .gitkeep │ │ └── images │ │ │ └── logo.jpg │ ├── app │ │ ├── app.component.css │ │ ├── app.component.html │ │ ├── user │ │ │ ├── login.component.css │ │ │ ├── state │ │ │ │ ├── actions │ │ │ │ │ ├── index.ts │ │ │ │ │ └── user-page.actions.ts │ │ │ │ └── user.reducer.ts │ │ │ ├── user.ts │ │ │ ├── user.module.ts │ │ │ ├── auth.service.ts │ │ │ ├── auth-guard.service.ts │ │ │ └── login.component.ts │ │ ├── home │ │ │ ├── shell.component.css │ │ │ ├── shell.component.html │ │ │ ├── welcome.component.ts │ │ │ ├── page-not-found.component.ts │ │ │ ├── shell.component.ts │ │ │ ├── menu.component.ts │ │ │ ├── welcome.component.html │ │ │ └── menu.component.html │ │ ├── products │ │ │ ├── product-list │ │ │ │ ├── product-list.component.css │ │ │ │ ├── product-list.component.ts │ │ │ │ └── product-list.component.html │ │ │ ├── state │ │ │ │ └── actions │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── product-page.actions.ts │ │ │ │ │ └── product-api.actions.ts │ │ │ ├── product.ts │ │ │ ├── product-shell │ │ │ │ └── product-shell.component.html │ │ │ └── product.module.ts │ │ ├── state │ │ │ └── app.state.ts │ │ ├── app.component.ts │ │ ├── shared │ │ │ ├── shared.module.ts │ │ │ └── number.validator.ts │ │ └── app-routing.module.ts │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── favicon.ico │ ├── styles.css │ ├── index.html │ ├── main.ts │ └── test.ts ├── .vscode │ └── settings.json ├── e2e │ ├── tsconfig.json │ ├── src │ │ ├── app.po.ts │ │ └── app.e2e-spec.ts │ └── protractor.conf.js ├── tsconfig.app.json ├── .editorconfig ├── tsconfig.spec.json ├── browserslist ├── tsconfig.json ├── .gitignore ├── karma.conf.js └── README.md ├── .gitignore ├── LICENSE └── README.md /APM-Demo0/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /APM-Demo1/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /APM-Demo2/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /APM-Demo3/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /APM-Demo4/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /APM-Demo5/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /APM-Demo0/src/app/app.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /APM-Demo1/src/app/app.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /APM-Demo2/src/app/app.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/app.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /APM-Demo4/src/app/app.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/app.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /APM-Demo0/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /APM-Demo1/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /APM-Demo2/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /APM-Demo4/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /APM-Demo0/src/app/user/login.component.css: -------------------------------------------------------------------------------- 1 | .main-content { 2 | margin-top: 25px; 3 | } -------------------------------------------------------------------------------- /APM-Demo1/src/app/user/login.component.css: -------------------------------------------------------------------------------- 1 | .main-content { 2 | margin-top: 25px; 3 | } -------------------------------------------------------------------------------- /APM-Demo2/src/app/user/login.component.css: -------------------------------------------------------------------------------- 1 | .main-content { 2 | margin-top: 25px; 3 | } -------------------------------------------------------------------------------- /APM-Demo3/src/app/user/login.component.css: -------------------------------------------------------------------------------- 1 | .main-content { 2 | margin-top: 25px; 3 | } -------------------------------------------------------------------------------- /APM-Demo4/src/app/user/login.component.css: -------------------------------------------------------------------------------- 1 | .main-content { 2 | margin-top: 25px; 3 | } -------------------------------------------------------------------------------- /APM-Demo5/src/app/user/login.component.css: -------------------------------------------------------------------------------- 1 | .main-content { 2 | margin-top: 25px; 3 | } -------------------------------------------------------------------------------- /APM-Demo0/src/app/home/shell.component.css: -------------------------------------------------------------------------------- 1 | .main-content { 2 | margin-top: 25px; 3 | } 4 | -------------------------------------------------------------------------------- /APM-Demo1/src/app/home/shell.component.css: -------------------------------------------------------------------------------- 1 | .main-content { 2 | margin-top: 25px; 3 | } 4 | -------------------------------------------------------------------------------- /APM-Demo2/src/app/home/shell.component.css: -------------------------------------------------------------------------------- 1 | .main-content { 2 | margin-top: 25px; 3 | } 4 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/home/shell.component.css: -------------------------------------------------------------------------------- 1 | .main-content { 2 | margin-top: 25px; 3 | } 4 | -------------------------------------------------------------------------------- /APM-Demo4/src/app/home/shell.component.css: -------------------------------------------------------------------------------- 1 | .main-content { 2 | margin-top: 25px; 3 | } 4 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/home/shell.component.css: -------------------------------------------------------------------------------- 1 | .main-content { 2 | margin-top: 25px; 3 | } 4 | -------------------------------------------------------------------------------- /APM-Demo0/src/app/products/product-list/product-list.component.css: -------------------------------------------------------------------------------- 1 | .card-body { 2 | padding: 0; 3 | } 4 | -------------------------------------------------------------------------------- /APM-Demo1/src/app/products/product-list/product-list.component.css: -------------------------------------------------------------------------------- 1 | .card-body { 2 | padding: 0; 3 | } 4 | -------------------------------------------------------------------------------- /APM-Demo2/src/app/products/product-list/product-list.component.css: -------------------------------------------------------------------------------- 1 | .card-body { 2 | padding: 0; 3 | } 4 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/products/product-list/product-list.component.css: -------------------------------------------------------------------------------- 1 | .card-body { 2 | padding: 0; 3 | } 4 | -------------------------------------------------------------------------------- /APM-Demo4/src/app/products/product-list/product-list.component.css: -------------------------------------------------------------------------------- 1 | .card-body { 2 | padding: 0; 3 | } 4 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/products/product-list/product-list.component.css: -------------------------------------------------------------------------------- 1 | .card-body { 2 | padding: 0; 3 | } 4 | -------------------------------------------------------------------------------- /APM-Demo0/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /APM-Demo1/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /APM-Demo2/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /APM-Demo3/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /APM-Demo4/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /APM-Demo5/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /APM-Demo0/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu-muthyala/Angular-NgRx-GettingStarted/master/APM-Demo0/src/favicon.ico -------------------------------------------------------------------------------- /APM-Demo1/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu-muthyala/Angular-NgRx-GettingStarted/master/APM-Demo1/src/favicon.ico -------------------------------------------------------------------------------- /APM-Demo2/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu-muthyala/Angular-NgRx-GettingStarted/master/APM-Demo2/src/favicon.ico -------------------------------------------------------------------------------- /APM-Demo3/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu-muthyala/Angular-NgRx-GettingStarted/master/APM-Demo3/src/favicon.ico -------------------------------------------------------------------------------- /APM-Demo4/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu-muthyala/Angular-NgRx-GettingStarted/master/APM-Demo4/src/favicon.ico -------------------------------------------------------------------------------- /APM-Demo5/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu-muthyala/Angular-NgRx-GettingStarted/master/APM-Demo5/src/favicon.ico -------------------------------------------------------------------------------- /APM-Demo5/src/app/user/state/actions/index.ts: -------------------------------------------------------------------------------- 1 | import * as UserPageActions from './user-page.actions'; 2 | 3 | export { UserPageActions }; 4 | -------------------------------------------------------------------------------- /APM-Demo0/src/assets/images/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu-muthyala/Angular-NgRx-GettingStarted/master/APM-Demo0/src/assets/images/logo.jpg -------------------------------------------------------------------------------- /APM-Demo1/src/assets/images/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu-muthyala/Angular-NgRx-GettingStarted/master/APM-Demo1/src/assets/images/logo.jpg -------------------------------------------------------------------------------- /APM-Demo2/src/assets/images/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu-muthyala/Angular-NgRx-GettingStarted/master/APM-Demo2/src/assets/images/logo.jpg -------------------------------------------------------------------------------- /APM-Demo3/src/assets/images/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu-muthyala/Angular-NgRx-GettingStarted/master/APM-Demo3/src/assets/images/logo.jpg -------------------------------------------------------------------------------- /APM-Demo4/src/assets/images/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu-muthyala/Angular-NgRx-GettingStarted/master/APM-Demo4/src/assets/images/logo.jpg -------------------------------------------------------------------------------- /APM-Demo5/src/assets/images/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chandu-muthyala/Angular-NgRx-GettingStarted/master/APM-Demo5/src/assets/images/logo.jpg -------------------------------------------------------------------------------- /APM-Demo0/src/app/home/shell.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
-------------------------------------------------------------------------------- /APM-Demo1/src/app/home/shell.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
-------------------------------------------------------------------------------- /APM-Demo2/src/app/home/shell.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
-------------------------------------------------------------------------------- /APM-Demo3/src/app/home/shell.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
-------------------------------------------------------------------------------- /APM-Demo4/src/app/home/shell.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
-------------------------------------------------------------------------------- /APM-Demo5/src/app/home/shell.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
-------------------------------------------------------------------------------- /APM-Demo0/src/app/user/user.ts: -------------------------------------------------------------------------------- 1 | /* Defines the user entity */ 2 | export interface User { 3 | id: number; 4 | userName: string; 5 | isAdmin: boolean; 6 | } 7 | -------------------------------------------------------------------------------- /APM-Demo1/src/app/user/user.ts: -------------------------------------------------------------------------------- 1 | /* Defines the user entity */ 2 | export interface User { 3 | id: number; 4 | userName: string; 5 | isAdmin: boolean; 6 | } 7 | -------------------------------------------------------------------------------- /APM-Demo2/src/app/user/user.ts: -------------------------------------------------------------------------------- 1 | /* Defines the user entity */ 2 | export interface User { 3 | id: number; 4 | userName: string; 5 | isAdmin: boolean; 6 | } 7 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/user/user.ts: -------------------------------------------------------------------------------- 1 | /* Defines the user entity */ 2 | export interface User { 3 | id: number; 4 | userName: string; 5 | isAdmin: boolean; 6 | } 7 | -------------------------------------------------------------------------------- /APM-Demo4/src/app/user/user.ts: -------------------------------------------------------------------------------- 1 | /* Defines the user entity */ 2 | export interface User { 3 | id: number; 4 | userName: string; 5 | isAdmin: boolean; 6 | } 7 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/user/user.ts: -------------------------------------------------------------------------------- 1 | /* Defines the user entity */ 2 | export interface User { 3 | id: number; 4 | userName: string; 5 | isAdmin: boolean; 6 | } 7 | -------------------------------------------------------------------------------- /APM-Demo2/src/app/user/state/user.actions.ts: -------------------------------------------------------------------------------- 1 | /* NgRx */ 2 | import { createAction } from '@ngrx/store'; 3 | 4 | export const maskUserName = createAction( 5 | '[User] Mask User Name' 6 | ); 7 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/user/state/user.actions.ts: -------------------------------------------------------------------------------- 1 | /* NgRx */ 2 | import { createAction } from '@ngrx/store'; 3 | 4 | export const maskUserName = createAction( 5 | '[User] Mask User Name' 6 | ); 7 | -------------------------------------------------------------------------------- /APM-Demo4/src/app/user/state/user.actions.ts: -------------------------------------------------------------------------------- 1 | /* NgRx */ 2 | import { createAction } from '@ngrx/store'; 3 | 4 | export const maskUserName = createAction( 5 | '[User] Mask User Name' 6 | ); 7 | -------------------------------------------------------------------------------- /APM-Demo0/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.autoSave": "afterDelay", 4 | "html.format.wrapAttributes": "force-aligned" 5 | } -------------------------------------------------------------------------------- /APM-Demo1/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.autoSave": "afterDelay", 4 | "html.format.wrapAttributes": "force-aligned" 5 | } -------------------------------------------------------------------------------- /APM-Demo2/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.autoSave": "afterDelay", 4 | "html.format.wrapAttributes": "force-aligned" 5 | } -------------------------------------------------------------------------------- /APM-Demo3/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.autoSave": "afterDelay", 4 | "html.format.wrapAttributes": "force-aligned" 5 | } -------------------------------------------------------------------------------- /APM-Demo4/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.autoSave": "afterDelay", 4 | "html.format.wrapAttributes": "force-aligned" 5 | } -------------------------------------------------------------------------------- /APM-Demo5/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.autoSave": "afterDelay", 4 | "html.format.wrapAttributes": "force-aligned" 5 | } -------------------------------------------------------------------------------- /APM-Demo5/src/app/user/state/actions/user-page.actions.ts: -------------------------------------------------------------------------------- 1 | /* NgRx */ 2 | import { createAction } from '@ngrx/store'; 3 | 4 | export const maskUserName = createAction( 5 | '[User Page] Mask User Name' 6 | ); 7 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/products/state/actions/index.ts: -------------------------------------------------------------------------------- 1 | import * as ProductPageActions from './product-page.actions'; 2 | import * as ProductApiActions from './product-api.actions'; 3 | 4 | export { ProductPageActions, ProductApiActions }; 5 | -------------------------------------------------------------------------------- /APM-Demo0/src/app/home/welcome.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | templateUrl: './welcome.component.html' 5 | }) 6 | export class WelcomeComponent { 7 | public pageTitle = 'Welcome'; 8 | } 9 | -------------------------------------------------------------------------------- /APM-Demo1/src/app/home/welcome.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | templateUrl: './welcome.component.html' 5 | }) 6 | export class WelcomeComponent { 7 | public pageTitle = 'Welcome'; 8 | } 9 | -------------------------------------------------------------------------------- /APM-Demo2/src/app/home/welcome.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | templateUrl: './welcome.component.html' 5 | }) 6 | export class WelcomeComponent { 7 | public pageTitle = 'Welcome'; 8 | } 9 | -------------------------------------------------------------------------------- /APM-Demo2/src/app/state/app.state.ts: -------------------------------------------------------------------------------- 1 | import { UserState } from '../user/state/user.reducer'; 2 | 3 | // Representation of the entire app state 4 | // Extended by lazy loaded modules 5 | export interface State { 6 | user: UserState; 7 | } 8 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/home/welcome.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | templateUrl: './welcome.component.html' 5 | }) 6 | export class WelcomeComponent { 7 | public pageTitle = 'Welcome'; 8 | } 9 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/state/app.state.ts: -------------------------------------------------------------------------------- 1 | import { UserState } from '../user/state/user.reducer'; 2 | 3 | // Representation of the entire app state 4 | // Extended by lazy loaded modules 5 | export interface State { 6 | user: UserState; 7 | } 8 | -------------------------------------------------------------------------------- /APM-Demo4/src/app/home/welcome.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | templateUrl: './welcome.component.html' 5 | }) 6 | export class WelcomeComponent { 7 | public pageTitle = 'Welcome'; 8 | } 9 | -------------------------------------------------------------------------------- /APM-Demo4/src/app/state/app.state.ts: -------------------------------------------------------------------------------- 1 | import { UserState } from '../user/state/user.reducer'; 2 | 3 | // Representation of the entire app state 4 | // Extended by lazy loaded modules 5 | export interface State { 6 | user: UserState; 7 | } 8 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/home/welcome.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | templateUrl: './welcome.component.html' 5 | }) 6 | export class WelcomeComponent { 7 | public pageTitle = 'Welcome'; 8 | } 9 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/state/app.state.ts: -------------------------------------------------------------------------------- 1 | import { UserState } from '../user/state/user.reducer'; 2 | 3 | // Representation of the entire app state 4 | // Extended by lazy loaded modules 5 | export interface State { 6 | user: UserState; 7 | } 8 | -------------------------------------------------------------------------------- /APM-Demo0/src/app/products/product.ts: -------------------------------------------------------------------------------- 1 | /* Defines the product entity */ 2 | export interface Product { 3 | id: number | null; 4 | productName: string; 5 | productCode: string; 6 | description: string; 7 | starRating: number; 8 | } 9 | -------------------------------------------------------------------------------- /APM-Demo1/src/app/products/product.ts: -------------------------------------------------------------------------------- 1 | /* Defines the product entity */ 2 | export interface Product { 3 | id: number | null; 4 | productName: string; 5 | productCode: string; 6 | description: string; 7 | starRating: number; 8 | } 9 | -------------------------------------------------------------------------------- /APM-Demo2/src/app/products/product.ts: -------------------------------------------------------------------------------- 1 | /* Defines the product entity */ 2 | export interface Product { 3 | id: number | null; 4 | productName: string; 5 | productCode: string; 6 | description: string; 7 | starRating: number; 8 | } 9 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/products/product.ts: -------------------------------------------------------------------------------- 1 | /* Defines the product entity */ 2 | export interface Product { 3 | id: number | null; 4 | productName: string; 5 | productCode: string; 6 | description: string; 7 | starRating: number; 8 | } 9 | -------------------------------------------------------------------------------- /APM-Demo4/src/app/products/product.ts: -------------------------------------------------------------------------------- 1 | /* Defines the product entity */ 2 | export interface Product { 3 | id: number | null; 4 | productName: string; 5 | productCode: string; 6 | description: string; 7 | starRating: number; 8 | } 9 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/products/product.ts: -------------------------------------------------------------------------------- 1 | /* Defines the product entity */ 2 | export interface Product { 3 | id: number | null; 4 | productName: string; 5 | productCode: string; 6 | description: string; 7 | starRating: number; 8 | } 9 | -------------------------------------------------------------------------------- /APM-Demo0/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'pm-root', 5 | templateUrl: './app.component.html', 6 | styleUrls: ['./app.component.css'] 7 | }) 8 | export class AppComponent { } 9 | -------------------------------------------------------------------------------- /APM-Demo1/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'pm-root', 5 | templateUrl: './app.component.html', 6 | styleUrls: ['./app.component.css'] 7 | }) 8 | export class AppComponent { } 9 | -------------------------------------------------------------------------------- /APM-Demo2/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'pm-root', 5 | templateUrl: './app.component.html', 6 | styleUrls: ['./app.component.css'] 7 | }) 8 | export class AppComponent { } 9 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'pm-root', 5 | templateUrl: './app.component.html', 6 | styleUrls: ['./app.component.css'] 7 | }) 8 | export class AppComponent { } 9 | -------------------------------------------------------------------------------- /APM-Demo4/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'pm-root', 5 | templateUrl: './app.component.html', 6 | styleUrls: ['./app.component.css'] 7 | }) 8 | export class AppComponent { } 9 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'pm-root', 5 | templateUrl: './app.component.html', 6 | styleUrls: ['./app.component.css'] 7 | }) 8 | export class AppComponent { } 9 | -------------------------------------------------------------------------------- /APM-Demo0/src/app/home/page-not-found.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | template: ` 5 |

This is not the page you were looking for!

6 | ` 7 | }) 8 | export class PageNotFoundComponent { } 9 | -------------------------------------------------------------------------------- /APM-Demo1/src/app/home/page-not-found.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | template: ` 5 |

This is not the page you were looking for!

6 | ` 7 | }) 8 | export class PageNotFoundComponent { } 9 | -------------------------------------------------------------------------------- /APM-Demo2/src/app/home/page-not-found.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | template: ` 5 |

This is not the page you were looking for!

6 | ` 7 | }) 8 | export class PageNotFoundComponent { } 9 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/home/page-not-found.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | template: ` 5 |

This is not the page you were looking for!

6 | ` 7 | }) 8 | export class PageNotFoundComponent { } 9 | -------------------------------------------------------------------------------- /APM-Demo4/src/app/home/page-not-found.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | template: ` 5 |

This is not the page you were looking for!

6 | ` 7 | }) 8 | export class PageNotFoundComponent { } 9 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/home/page-not-found.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | template: ` 5 |

This is not the page you were looking for!

6 | ` 7 | }) 8 | export class PageNotFoundComponent { } 9 | -------------------------------------------------------------------------------- /APM-Demo0/src/app/products/product-shell/product-shell.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 | 7 |
8 |
-------------------------------------------------------------------------------- /APM-Demo0/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | li { 3 | font-size: large; 4 | } 5 | 6 | div.panel-heading { 7 | font-size: x-large; 8 | } 9 | 10 | body { 11 | margin-top: 50px; 12 | } 13 | -------------------------------------------------------------------------------- /APM-Demo1/src/app/products/product-shell/product-shell.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 | 7 |
8 |
-------------------------------------------------------------------------------- /APM-Demo1/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | li { 3 | font-size: large; 4 | } 5 | 6 | div.panel-heading { 7 | font-size: x-large; 8 | } 9 | 10 | body { 11 | margin-top: 50px; 12 | } 13 | -------------------------------------------------------------------------------- /APM-Demo2/src/app/products/product-shell/product-shell.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 | 7 |
8 |
-------------------------------------------------------------------------------- /APM-Demo2/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | li { 3 | font-size: large; 4 | } 5 | 6 | div.panel-heading { 7 | font-size: x-large; 8 | } 9 | 10 | body { 11 | margin-top: 50px; 12 | } 13 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/products/product-shell/product-shell.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 | 7 |
8 |
-------------------------------------------------------------------------------- /APM-Demo3/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | li { 3 | font-size: large; 4 | } 5 | 6 | div.panel-heading { 7 | font-size: x-large; 8 | } 9 | 10 | body { 11 | margin-top: 50px; 12 | } 13 | -------------------------------------------------------------------------------- /APM-Demo4/src/app/products/product-shell/product-shell.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 | 7 |
8 |
-------------------------------------------------------------------------------- /APM-Demo4/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | li { 3 | font-size: large; 4 | } 5 | 6 | div.panel-heading { 7 | font-size: x-large; 8 | } 9 | 10 | body { 11 | margin-top: 50px; 12 | } 13 | -------------------------------------------------------------------------------- /APM-Demo5/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | li { 3 | font-size: large; 4 | } 5 | 6 | div.panel-heading { 7 | font-size: x-large; 8 | } 9 | 10 | body { 11 | margin-top: 50px; 12 | } 13 | -------------------------------------------------------------------------------- /APM-Demo0/e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/e2e", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /APM-Demo0/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/app", 5 | "types": [] 6 | }, 7 | "files": [ 8 | "src/main.ts", 9 | "src/polyfills.ts" 10 | ], 11 | "include": [ 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /APM-Demo1/e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/e2e", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /APM-Demo1/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/app", 5 | "types": [] 6 | }, 7 | "files": [ 8 | "src/main.ts", 9 | "src/polyfills.ts" 10 | ], 11 | "include": [ 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /APM-Demo2/e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/e2e", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /APM-Demo2/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/app", 5 | "types": [] 6 | }, 7 | "files": [ 8 | "src/main.ts", 9 | "src/polyfills.ts" 10 | ], 11 | "include": [ 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /APM-Demo3/e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/e2e", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /APM-Demo3/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/app", 5 | "types": [] 6 | }, 7 | "files": [ 8 | "src/main.ts", 9 | "src/polyfills.ts" 10 | ], 11 | "include": [ 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /APM-Demo4/e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/e2e", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /APM-Demo4/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/app", 5 | "types": [] 6 | }, 7 | "files": [ 8 | "src/main.ts", 9 | "src/polyfills.ts" 10 | ], 11 | "include": [ 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /APM-Demo5/e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/e2e", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /APM-Demo5/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/app", 5 | "types": [] 6 | }, 7 | "files": [ 8 | "src/main.ts", 9 | "src/polyfills.ts" 10 | ], 11 | "include": [ 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /APM-Demo0/src/app/products/product-shell/product-shell.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | templateUrl: './product-shell.component.html' 5 | }) 6 | export class ProductShellComponent implements OnInit { 7 | 8 | constructor() { } 9 | 10 | ngOnInit() { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /APM-Demo1/src/app/products/product-shell/product-shell.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | templateUrl: './product-shell.component.html' 5 | }) 6 | export class ProductShellComponent implements OnInit { 7 | 8 | constructor() { } 9 | 10 | ngOnInit() { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /APM-Demo2/src/app/products/product-shell/product-shell.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | templateUrl: './product-shell.component.html' 5 | }) 6 | export class ProductShellComponent implements OnInit { 7 | 8 | constructor() { } 9 | 10 | ngOnInit() { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/products/product-shell/product-shell.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | templateUrl: './product-shell.component.html' 5 | }) 6 | export class ProductShellComponent implements OnInit { 7 | 8 | constructor() { } 9 | 10 | ngOnInit() { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /APM-Demo4/src/app/products/product-shell/product-shell.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | templateUrl: './product-shell.component.html' 5 | }) 6 | export class ProductShellComponent implements OnInit { 7 | 8 | constructor() { } 9 | 10 | ngOnInit() { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /APM-Demo1/src/app/user/state/user.reducer.ts: -------------------------------------------------------------------------------- 1 | import { createReducer, on, createAction } from '@ngrx/store'; 2 | 3 | export const userReducer = createReducer( 4 | { maskUserName: true }, 5 | on(createAction('[User] Mask User Name'), state => { 6 | return { 7 | ...state, 8 | maskUserName: !state.maskUserName 9 | }; 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /APM-Demo0/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /APM-Demo1/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /APM-Demo2/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /APM-Demo3/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /APM-Demo4/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /APM-Demo5/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /APM-Demo0/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo(): Promise { 5 | return browser.get(browser.baseUrl) as Promise; 6 | } 7 | 8 | getTitleText(): Promise { 9 | return element(by.css('pm-root .content span')).getText() as Promise; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /APM-Demo0/src/app/home/shell.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'pm-shell', 5 | templateUrl: './shell.component.html', 6 | styleUrls: ['./shell.component.css'] 7 | }) 8 | export class ShellComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /APM-Demo1/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo(): Promise { 5 | return browser.get(browser.baseUrl) as Promise; 6 | } 7 | 8 | getTitleText(): Promise { 9 | return element(by.css('pm-root .content span')).getText() as Promise; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /APM-Demo1/src/app/home/shell.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'pm-shell', 5 | templateUrl: './shell.component.html', 6 | styleUrls: ['./shell.component.css'] 7 | }) 8 | export class ShellComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /APM-Demo2/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo(): Promise { 5 | return browser.get(browser.baseUrl) as Promise; 6 | } 7 | 8 | getTitleText(): Promise { 9 | return element(by.css('pm-root .content span')).getText() as Promise; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /APM-Demo2/src/app/home/shell.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'pm-shell', 5 | templateUrl: './shell.component.html', 6 | styleUrls: ['./shell.component.css'] 7 | }) 8 | export class ShellComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /APM-Demo3/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo(): Promise { 5 | return browser.get(browser.baseUrl) as Promise; 6 | } 7 | 8 | getTitleText(): Promise { 9 | return element(by.css('pm-root .content span')).getText() as Promise; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/home/shell.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'pm-shell', 5 | templateUrl: './shell.component.html', 6 | styleUrls: ['./shell.component.css'] 7 | }) 8 | export class ShellComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /APM-Demo4/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo(): Promise { 5 | return browser.get(browser.baseUrl) as Promise; 6 | } 7 | 8 | getTitleText(): Promise { 9 | return element(by.css('pm-root .content span')).getText() as Promise; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /APM-Demo4/src/app/home/shell.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'pm-shell', 5 | templateUrl: './shell.component.html', 6 | styleUrls: ['./shell.component.css'] 7 | }) 8 | export class ShellComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /APM-Demo5/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo(): Promise { 5 | return browser.get(browser.baseUrl) as Promise; 6 | } 7 | 8 | getTitleText(): Promise { 9 | return element(by.css('pm-root .content span')).getText() as Promise; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /APM-Demo0/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /APM-Demo1/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /APM-Demo2/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /APM-Demo3/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /APM-Demo4/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /APM-Demo5/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /APM-Demo0/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Acme Product Management 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /APM-Demo1/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Acme Product Management 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /APM-Demo2/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Acme Product Management 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /APM-Demo3/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Acme Product Management 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /APM-Demo4/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Acme Product Management 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /APM-Demo5/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Acme Product Management 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /APM-Demo0/src/app/shared/shared.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { FormsModule, ReactiveFormsModule } from '@angular/forms'; 4 | 5 | @NgModule({ 6 | imports: [ 7 | CommonModule 8 | ], 9 | exports: [ 10 | CommonModule, 11 | FormsModule, 12 | ReactiveFormsModule 13 | ] 14 | }) 15 | export class SharedModule { } 16 | -------------------------------------------------------------------------------- /APM-Demo1/src/app/shared/shared.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { FormsModule, ReactiveFormsModule } from '@angular/forms'; 4 | 5 | @NgModule({ 6 | imports: [ 7 | CommonModule 8 | ], 9 | exports: [ 10 | CommonModule, 11 | FormsModule, 12 | ReactiveFormsModule 13 | ] 14 | }) 15 | export class SharedModule { } 16 | -------------------------------------------------------------------------------- /APM-Demo2/src/app/shared/shared.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { FormsModule, ReactiveFormsModule } from '@angular/forms'; 4 | 5 | @NgModule({ 6 | imports: [ 7 | CommonModule 8 | ], 9 | exports: [ 10 | CommonModule, 11 | FormsModule, 12 | ReactiveFormsModule 13 | ] 14 | }) 15 | export class SharedModule { } 16 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/shared/shared.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { FormsModule, ReactiveFormsModule } from '@angular/forms'; 4 | 5 | @NgModule({ 6 | imports: [ 7 | CommonModule 8 | ], 9 | exports: [ 10 | CommonModule, 11 | FormsModule, 12 | ReactiveFormsModule 13 | ] 14 | }) 15 | export class SharedModule { } 16 | -------------------------------------------------------------------------------- /APM-Demo4/src/app/shared/shared.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { FormsModule, ReactiveFormsModule } from '@angular/forms'; 4 | 5 | @NgModule({ 6 | imports: [ 7 | CommonModule 8 | ], 9 | exports: [ 10 | CommonModule, 11 | FormsModule, 12 | ReactiveFormsModule 13 | ] 14 | }) 15 | export class SharedModule { } 16 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/shared/shared.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { FormsModule, ReactiveFormsModule } from '@angular/forms'; 4 | 5 | @NgModule({ 6 | imports: [ 7 | CommonModule 8 | ], 9 | exports: [ 10 | CommonModule, 11 | FormsModule, 12 | ReactiveFormsModule 13 | ] 14 | }) 15 | export class SharedModule { } 16 | -------------------------------------------------------------------------------- /APM-Demo0/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /APM-Demo1/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /APM-Demo2/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /APM-Demo3/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /APM-Demo4/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /APM-Demo5/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/home/shell.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'pm-shell', 5 | templateUrl: './shell.component.html', 6 | styleUrls: ['./shell.component.css'], 7 | changeDetection: ChangeDetectionStrategy.OnPush 8 | }) 9 | export class ShellComponent implements OnInit { 10 | 11 | constructor() { } 12 | 13 | ngOnInit() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /APM-Demo1/src/app/products/state/product.reducer.ts: -------------------------------------------------------------------------------- 1 | /* NgRx */ 2 | import { createReducer, on, createAction } from '@ngrx/store'; 3 | 4 | export const productReducer = createReducer( 5 | { showProductCode: true }, 6 | on(createAction('[Product] Toggle Product Code'), state => { 7 | return { 8 | ...state, 9 | showProductCode: !state.showProductCode 10 | // showProductCode: state.showProductCode = false, 11 | }; 12 | }) 13 | ); 14 | 15 | -------------------------------------------------------------------------------- /APM-Demo0/browserslist: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # You can see what browsers were selected by your queries by running: 6 | # npx browserslist 7 | 8 | > 0.5% 9 | last 2 versions 10 | Firefox ESR 11 | not dead 12 | not IE 9-11 # For IE 9-11 support, remove 'not'. -------------------------------------------------------------------------------- /APM-Demo1/browserslist: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # You can see what browsers were selected by your queries by running: 6 | # npx browserslist 7 | 8 | > 0.5% 9 | last 2 versions 10 | Firefox ESR 11 | not dead 12 | not IE 9-11 # For IE 9-11 support, remove 'not'. -------------------------------------------------------------------------------- /APM-Demo2/browserslist: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # You can see what browsers were selected by your queries by running: 6 | # npx browserslist 7 | 8 | > 0.5% 9 | last 2 versions 10 | Firefox ESR 11 | not dead 12 | not IE 9-11 # For IE 9-11 support, remove 'not'. -------------------------------------------------------------------------------- /APM-Demo3/browserslist: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # You can see what browsers were selected by your queries by running: 6 | # npx browserslist 7 | 8 | > 0.5% 9 | last 2 versions 10 | Firefox ESR 11 | not dead 12 | not IE 9-11 # For IE 9-11 support, remove 'not'. -------------------------------------------------------------------------------- /APM-Demo4/browserslist: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # You can see what browsers were selected by your queries by running: 6 | # npx browserslist 7 | 8 | > 0.5% 9 | last 2 versions 10 | Firefox ESR 11 | not dead 12 | not IE 9-11 # For IE 9-11 support, remove 'not'. -------------------------------------------------------------------------------- /APM-Demo5/browserslist: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # You can see what browsers were selected by your queries by running: 6 | # npx browserslist 7 | 8 | > 0.5% 9 | last 2 versions 10 | Firefox ESR 11 | not dead 12 | not IE 9-11 # For IE 9-11 support, remove 'not'. -------------------------------------------------------------------------------- /APM-Demo0/src/app/shared/number.validator.ts: -------------------------------------------------------------------------------- 1 | import { AbstractControl, ValidatorFn } from '@angular/forms'; 2 | 3 | export class NumberValidators { 4 | 5 | static range(min: number, max: number): ValidatorFn { 6 | return (c: AbstractControl): { [key: string]: boolean } | null => { 7 | if (c.value && (isNaN(c.value) || c.value < min || c.value > max)) { 8 | return { range: true }; 9 | } 10 | return null; 11 | }; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /APM-Demo1/src/app/shared/number.validator.ts: -------------------------------------------------------------------------------- 1 | import { AbstractControl, ValidatorFn } from '@angular/forms'; 2 | 3 | export class NumberValidators { 4 | 5 | static range(min: number, max: number): ValidatorFn { 6 | return (c: AbstractControl): { [key: string]: boolean } | null => { 7 | if (c.value && (isNaN(c.value) || c.value < min || c.value > max)) { 8 | return { range: true }; 9 | } 10 | return null; 11 | }; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /APM-Demo2/src/app/shared/number.validator.ts: -------------------------------------------------------------------------------- 1 | import { AbstractControl, ValidatorFn } from '@angular/forms'; 2 | 3 | export class NumberValidators { 4 | 5 | static range(min: number, max: number): ValidatorFn { 6 | return (c: AbstractControl): { [key: string]: boolean } | null => { 7 | if (c.value && (isNaN(c.value) || c.value < min || c.value > max)) { 8 | return { range: true }; 9 | } 10 | return null; 11 | }; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/shared/number.validator.ts: -------------------------------------------------------------------------------- 1 | import { AbstractControl, ValidatorFn } from '@angular/forms'; 2 | 3 | export class NumberValidators { 4 | 5 | static range(min: number, max: number): ValidatorFn { 6 | return (c: AbstractControl): { [key: string]: boolean } | null => { 7 | if (c.value && (isNaN(c.value) || c.value < min || c.value > max)) { 8 | return { range: true }; 9 | } 10 | return null; 11 | }; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /APM-Demo4/src/app/shared/number.validator.ts: -------------------------------------------------------------------------------- 1 | import { AbstractControl, ValidatorFn } from '@angular/forms'; 2 | 3 | export class NumberValidators { 4 | 5 | static range(min: number, max: number): ValidatorFn { 6 | return (c: AbstractControl): { [key: string]: boolean } | null => { 7 | if (c.value && (isNaN(c.value) || c.value < min || c.value > max)) { 8 | return { range: true }; 9 | } 10 | return null; 11 | }; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/shared/number.validator.ts: -------------------------------------------------------------------------------- 1 | import { AbstractControl, ValidatorFn } from '@angular/forms'; 2 | 3 | export class NumberValidators { 4 | 5 | static range(min: number, max: number): ValidatorFn { 6 | return (c: AbstractControl): { [key: string]: boolean } | null => { 7 | if (c.value && (isNaN(c.value) || c.value < min || c.value > max)) { 8 | return { range: true }; 9 | } 10 | return null; 11 | }; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /APM-Demo0/src/app/user/user.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | import { SharedModule } from '../shared/shared.module'; 5 | 6 | import { LoginComponent } from './login.component'; 7 | 8 | const userRoutes: Routes = [ 9 | { path: 'login', component: LoginComponent } 10 | ]; 11 | 12 | @NgModule({ 13 | imports: [ 14 | SharedModule, 15 | RouterModule.forChild(userRoutes) 16 | ], 17 | declarations: [ 18 | LoginComponent 19 | ] 20 | }) 21 | export class UserModule { } 22 | -------------------------------------------------------------------------------- /APM-Demo0/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "downlevelIteration": true, 9 | "experimentalDecorators": true, 10 | "module": "esnext", 11 | "moduleResolution": "node", 12 | "importHelpers": true, 13 | "target": "es2015", 14 | "lib": [ 15 | "es2018", 16 | "dom" 17 | ] 18 | }, 19 | "angularCompilerOptions": { 20 | "fullTemplateTypeCheck": true, 21 | "strictInjectionParameters": true, 22 | "strictTemplates": true 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /APM-Demo1/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "downlevelIteration": true, 9 | "experimentalDecorators": true, 10 | "module": "esnext", 11 | "moduleResolution": "node", 12 | "importHelpers": true, 13 | "target": "es2015", 14 | "lib": [ 15 | "es2018", 16 | "dom" 17 | ] 18 | }, 19 | "angularCompilerOptions": { 20 | "fullTemplateTypeCheck": true, 21 | "strictInjectionParameters": true, 22 | "strictTemplates": true 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /APM-Demo2/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "downlevelIteration": true, 9 | "experimentalDecorators": true, 10 | "module": "esnext", 11 | "moduleResolution": "node", 12 | "importHelpers": true, 13 | "target": "es2015", 14 | "lib": [ 15 | "es2018", 16 | "dom" 17 | ] 18 | }, 19 | "angularCompilerOptions": { 20 | "fullTemplateTypeCheck": true, 21 | "strictInjectionParameters": true, 22 | "strictTemplates": true 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /APM-Demo3/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "downlevelIteration": true, 9 | "experimentalDecorators": true, 10 | "module": "esnext", 11 | "moduleResolution": "node", 12 | "importHelpers": true, 13 | "target": "es2015", 14 | "lib": [ 15 | "es2018", 16 | "dom" 17 | ] 18 | }, 19 | "angularCompilerOptions": { 20 | "fullTemplateTypeCheck": true, 21 | "strictInjectionParameters": true, 22 | "strictTemplates": true 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /APM-Demo4/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "downlevelIteration": true, 9 | "experimentalDecorators": true, 10 | "module": "esnext", 11 | "moduleResolution": "node", 12 | "importHelpers": true, 13 | "target": "es2015", 14 | "lib": [ 15 | "es2018", 16 | "dom" 17 | ] 18 | }, 19 | "angularCompilerOptions": { 20 | "fullTemplateTypeCheck": true, 21 | "strictInjectionParameters": true, 22 | "strictTemplates": true 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /APM-Demo5/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "downlevelIteration": true, 9 | "experimentalDecorators": true, 10 | "module": "esnext", 11 | "moduleResolution": "node", 12 | "importHelpers": true, 13 | "target": "es2015", 14 | "lib": [ 15 | "es2018", 16 | "dom" 17 | ] 18 | }, 19 | "angularCompilerOptions": { 20 | "fullTemplateTypeCheck": true, 21 | "strictInjectionParameters": true, 22 | "strictTemplates": true 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | 8 | # dependencies 9 | /node_modules 10 | 11 | # IDEs and editors 12 | /.idea 13 | .project 14 | .classpath 15 | .c9/ 16 | *.launch 17 | .settings/ 18 | *.sublime-workspace 19 | 20 | # IDE - VSCode 21 | .vscode/* 22 | !.vscode/settings.json 23 | !.vscode/tasks.json 24 | !.vscode/launch.json 25 | !.vscode/extensions.json 26 | 27 | # misc 28 | /.sass-cache 29 | /connect.lock 30 | /coverage 31 | /libpeerconnection.log 32 | npm-debug.log 33 | testem.log 34 | /typings 35 | 36 | # e2e 37 | /e2e/*.js 38 | /e2e/*.map 39 | 40 | # System Files 41 | .DS_Store 42 | Thumbs.db 43 | -------------------------------------------------------------------------------- /APM-Demo1/src/app/user/user.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | import { SharedModule } from '../shared/shared.module'; 5 | 6 | import { LoginComponent } from './login.component'; 7 | 8 | /* NgRx */ 9 | import { StoreModule } from '@ngrx/store'; 10 | import { userReducer } from './state/user.reducer'; 11 | 12 | const userRoutes: Routes = [ 13 | { path: 'login', component: LoginComponent } 14 | ]; 15 | 16 | @NgModule({ 17 | imports: [ 18 | SharedModule, 19 | RouterModule.forChild(userRoutes), 20 | StoreModule.forFeature('users', userReducer) 21 | ], 22 | declarations: [ 23 | LoginComponent 24 | ] 25 | }) 26 | export class UserModule { } 27 | -------------------------------------------------------------------------------- /APM-Demo2/src/app/user/user.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | import { SharedModule } from '../shared/shared.module'; 5 | 6 | import { LoginComponent } from './login.component'; 7 | 8 | /* NgRx */ 9 | import { StoreModule } from '@ngrx/store'; 10 | import { userReducer } from './state/user.reducer'; 11 | 12 | const userRoutes: Routes = [ 13 | { path: 'login', component: LoginComponent } 14 | ]; 15 | 16 | @NgModule({ 17 | imports: [ 18 | SharedModule, 19 | RouterModule.forChild(userRoutes), 20 | StoreModule.forFeature('users', userReducer) 21 | ], 22 | declarations: [ 23 | LoginComponent 24 | ] 25 | }) 26 | export class UserModule { } 27 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/user/user.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | import { SharedModule } from '../shared/shared.module'; 5 | 6 | import { LoginComponent } from './login.component'; 7 | 8 | /* NgRx */ 9 | import { StoreModule } from '@ngrx/store'; 10 | import { userReducer } from './state/user.reducer'; 11 | 12 | const userRoutes: Routes = [ 13 | { path: 'login', component: LoginComponent } 14 | ]; 15 | 16 | @NgModule({ 17 | imports: [ 18 | SharedModule, 19 | RouterModule.forChild(userRoutes), 20 | StoreModule.forFeature('users', userReducer) 21 | ], 22 | declarations: [ 23 | LoginComponent 24 | ] 25 | }) 26 | export class UserModule { } 27 | -------------------------------------------------------------------------------- /APM-Demo4/src/app/user/user.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | import { SharedModule } from '../shared/shared.module'; 5 | 6 | import { LoginComponent } from './login.component'; 7 | 8 | /* NgRx */ 9 | import { StoreModule } from '@ngrx/store'; 10 | import { userReducer } from './state/user.reducer'; 11 | 12 | const userRoutes: Routes = [ 13 | { path: 'login', component: LoginComponent } 14 | ]; 15 | 16 | @NgModule({ 17 | imports: [ 18 | SharedModule, 19 | RouterModule.forChild(userRoutes), 20 | StoreModule.forFeature('users', userReducer) 21 | ], 22 | declarations: [ 23 | LoginComponent 24 | ] 25 | }) 26 | export class UserModule { } 27 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/user/user.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | import { SharedModule } from '../shared/shared.module'; 5 | 6 | import { LoginComponent } from './login.component'; 7 | 8 | /* NgRx */ 9 | import { StoreModule } from '@ngrx/store'; 10 | import { userReducer } from './state/user.reducer'; 11 | 12 | const userRoutes: Routes = [ 13 | { path: 'login', component: LoginComponent } 14 | ]; 15 | 16 | @NgModule({ 17 | imports: [ 18 | SharedModule, 19 | RouterModule.forChild(userRoutes), 20 | StoreModule.forFeature('users', userReducer) 21 | ], 22 | declarations: [ 23 | LoginComponent 24 | ] 25 | }) 26 | export class UserModule { } 27 | -------------------------------------------------------------------------------- /APM-Demo0/e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | import { browser, logging } from 'protractor'; 3 | 4 | describe('workspace-project App', () => { 5 | let page: AppPage; 6 | 7 | beforeEach(() => { 8 | page = new AppPage(); 9 | }); 10 | 11 | it('should display welcome message', () => { 12 | page.navigateTo(); 13 | expect(page.getTitleText()).toEqual('APM app is running!'); 14 | }); 15 | 16 | afterEach(async () => { 17 | // Assert that there are no errors emitted from the browser 18 | const logs = await browser.manage().logs().get(logging.Type.BROWSER); 19 | expect(logs).not.toContain(jasmine.objectContaining({ 20 | level: logging.Level.SEVERE, 21 | } as logging.Entry)); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /APM-Demo0/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /APM-Demo1/e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | import { browser, logging } from 'protractor'; 3 | 4 | describe('workspace-project App', () => { 5 | let page: AppPage; 6 | 7 | beforeEach(() => { 8 | page = new AppPage(); 9 | }); 10 | 11 | it('should display welcome message', () => { 12 | page.navigateTo(); 13 | expect(page.getTitleText()).toEqual('APM app is running!'); 14 | }); 15 | 16 | afterEach(async () => { 17 | // Assert that there are no errors emitted from the browser 18 | const logs = await browser.manage().logs().get(logging.Type.BROWSER); 19 | expect(logs).not.toContain(jasmine.objectContaining({ 20 | level: logging.Level.SEVERE, 21 | } as logging.Entry)); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /APM-Demo1/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /APM-Demo2/e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | import { browser, logging } from 'protractor'; 3 | 4 | describe('workspace-project App', () => { 5 | let page: AppPage; 6 | 7 | beforeEach(() => { 8 | page = new AppPage(); 9 | }); 10 | 11 | it('should display welcome message', () => { 12 | page.navigateTo(); 13 | expect(page.getTitleText()).toEqual('APM app is running!'); 14 | }); 15 | 16 | afterEach(async () => { 17 | // Assert that there are no errors emitted from the browser 18 | const logs = await browser.manage().logs().get(logging.Type.BROWSER); 19 | expect(logs).not.toContain(jasmine.objectContaining({ 20 | level: logging.Level.SEVERE, 21 | } as logging.Entry)); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /APM-Demo2/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /APM-Demo3/e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | import { browser, logging } from 'protractor'; 3 | 4 | describe('workspace-project App', () => { 5 | let page: AppPage; 6 | 7 | beforeEach(() => { 8 | page = new AppPage(); 9 | }); 10 | 11 | it('should display welcome message', () => { 12 | page.navigateTo(); 13 | expect(page.getTitleText()).toEqual('APM app is running!'); 14 | }); 15 | 16 | afterEach(async () => { 17 | // Assert that there are no errors emitted from the browser 18 | const logs = await browser.manage().logs().get(logging.Type.BROWSER); 19 | expect(logs).not.toContain(jasmine.objectContaining({ 20 | level: logging.Level.SEVERE, 21 | } as logging.Entry)); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /APM-Demo3/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /APM-Demo4/e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | import { browser, logging } from 'protractor'; 3 | 4 | describe('workspace-project App', () => { 5 | let page: AppPage; 6 | 7 | beforeEach(() => { 8 | page = new AppPage(); 9 | }); 10 | 11 | it('should display welcome message', () => { 12 | page.navigateTo(); 13 | expect(page.getTitleText()).toEqual('APM app is running!'); 14 | }); 15 | 16 | afterEach(async () => { 17 | // Assert that there are no errors emitted from the browser 18 | const logs = await browser.manage().logs().get(logging.Type.BROWSER); 19 | expect(logs).not.toContain(jasmine.objectContaining({ 20 | level: logging.Level.SEVERE, 21 | } as logging.Entry)); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /APM-Demo4/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /APM-Demo5/e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | import { browser, logging } from 'protractor'; 3 | 4 | describe('workspace-project App', () => { 5 | let page: AppPage; 6 | 7 | beforeEach(() => { 8 | page = new AppPage(); 9 | }); 10 | 11 | it('should display welcome message', () => { 12 | page.navigateTo(); 13 | expect(page.getTitleText()).toEqual('APM app is running!'); 14 | }); 15 | 16 | afterEach(async () => { 17 | // Assert that there are no errors emitted from the browser 18 | const logs = await browser.manage().logs().get(logging.Type.BROWSER); 19 | expect(logs).not.toContain(jasmine.objectContaining({ 20 | level: logging.Level.SEVERE, 21 | } as logging.Entry)); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /APM-Demo5/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /APM-Demo0/src/app/user/auth.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | import { User } from './user'; 4 | 5 | @Injectable({ 6 | providedIn: 'root', 7 | }) 8 | export class AuthService { 9 | currentUser: User | null; 10 | redirectUrl: string; 11 | 12 | constructor() { } 13 | 14 | isLoggedIn(): boolean { 15 | return !!this.currentUser; 16 | } 17 | 18 | login(userName: string, password: string): void { 19 | // Code here would log into a back end service 20 | // and return user information 21 | // This is just hard-coded here. 22 | this.currentUser = { 23 | id: 2, 24 | userName, 25 | isAdmin: false 26 | }; 27 | } 28 | 29 | logout(): void { 30 | this.currentUser = null; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /APM-Demo1/src/app/user/auth.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | import { User } from './user'; 4 | 5 | @Injectable({ 6 | providedIn: 'root', 7 | }) 8 | export class AuthService { 9 | currentUser: User | null; 10 | redirectUrl: string; 11 | 12 | constructor() { } 13 | 14 | isLoggedIn(): boolean { 15 | return !!this.currentUser; 16 | } 17 | 18 | login(userName: string, password: string): void { 19 | // Code here would log into a back end service 20 | // and return user information 21 | // This is just hard-coded here. 22 | this.currentUser = { 23 | id: 2, 24 | userName, 25 | isAdmin: false 26 | }; 27 | } 28 | 29 | logout(): void { 30 | this.currentUser = null; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /APM-Demo2/src/app/user/auth.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | import { User } from './user'; 4 | 5 | @Injectable({ 6 | providedIn: 'root', 7 | }) 8 | export class AuthService { 9 | currentUser: User | null; 10 | redirectUrl: string; 11 | 12 | constructor() { } 13 | 14 | isLoggedIn(): boolean { 15 | return !!this.currentUser; 16 | } 17 | 18 | login(userName: string, password: string): void { 19 | // Code here would log into a back end service 20 | // and return user information 21 | // This is just hard-coded here. 22 | this.currentUser = { 23 | id: 2, 24 | userName, 25 | isAdmin: false 26 | }; 27 | } 28 | 29 | logout(): void { 30 | this.currentUser = null; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/user/auth.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | import { User } from './user'; 4 | 5 | @Injectable({ 6 | providedIn: 'root', 7 | }) 8 | export class AuthService { 9 | currentUser: User | null; 10 | redirectUrl: string; 11 | 12 | constructor() { } 13 | 14 | isLoggedIn(): boolean { 15 | return !!this.currentUser; 16 | } 17 | 18 | login(userName: string, password: string): void { 19 | // Code here would log into a back end service 20 | // and return user information 21 | // This is just hard-coded here. 22 | this.currentUser = { 23 | id: 2, 24 | userName, 25 | isAdmin: false 26 | }; 27 | } 28 | 29 | logout(): void { 30 | this.currentUser = null; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /APM-Demo4/src/app/user/auth.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | import { User } from './user'; 4 | 5 | @Injectable({ 6 | providedIn: 'root', 7 | }) 8 | export class AuthService { 9 | currentUser: User | null; 10 | redirectUrl: string; 11 | 12 | constructor() { } 13 | 14 | isLoggedIn(): boolean { 15 | return !!this.currentUser; 16 | } 17 | 18 | login(userName: string, password: string): void { 19 | // Code here would log into a back end service 20 | // and return user information 21 | // This is just hard-coded here. 22 | this.currentUser = { 23 | id: 2, 24 | userName, 25 | isAdmin: false 26 | }; 27 | } 28 | 29 | logout(): void { 30 | this.currentUser = null; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/user/auth.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | import { User } from './user'; 4 | 5 | @Injectable({ 6 | providedIn: 'root', 7 | }) 8 | export class AuthService { 9 | currentUser: User | null; 10 | redirectUrl: string; 11 | 12 | constructor() { } 13 | 14 | isLoggedIn(): boolean { 15 | return !!this.currentUser; 16 | } 17 | 18 | login(userName: string, password: string): void { 19 | // Code here would log into a back end service 20 | // and return user information 21 | // This is just hard-coded here. 22 | this.currentUser = { 23 | id: 2, 24 | userName, 25 | isAdmin: false 26 | }; 27 | } 28 | 29 | logout(): void { 30 | this.currentUser = null; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /APM-Demo0/src/app/products/product.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | import { SharedModule } from '../shared/shared.module'; 5 | 6 | import { ProductShellComponent } from './product-shell/product-shell.component'; 7 | import { ProductListComponent } from './product-list/product-list.component'; 8 | import { ProductEditComponent } from './product-edit/product-edit.component'; 9 | 10 | const productRoutes: Routes = [ 11 | { path: '', component: ProductShellComponent } 12 | ]; 13 | 14 | @NgModule({ 15 | imports: [ 16 | SharedModule, 17 | RouterModule.forChild(productRoutes) 18 | ], 19 | declarations: [ 20 | ProductShellComponent, 21 | ProductListComponent, 22 | ProductEditComponent 23 | ] 24 | }) 25 | export class ProductModule { } 26 | -------------------------------------------------------------------------------- /APM-Demo0/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | # Only exists if Bazel was run 8 | /bazel-out 9 | 10 | # dependencies 11 | /node_modules 12 | 13 | # profiling files 14 | chrome-profiler-events*.json 15 | speed-measure-plugin*.json 16 | 17 | # IDEs and editors 18 | /.idea 19 | .project 20 | .classpath 21 | .c9/ 22 | *.launch 23 | .settings/ 24 | *.sublime-workspace 25 | 26 | # IDE - VSCode 27 | .vscode/* 28 | !.vscode/settings.json 29 | !.vscode/tasks.json 30 | !.vscode/launch.json 31 | !.vscode/extensions.json 32 | .history/* 33 | 34 | # misc 35 | /.sass-cache 36 | /connect.lock 37 | /coverage 38 | /libpeerconnection.log 39 | npm-debug.log 40 | yarn-error.log 41 | testem.log 42 | /typings 43 | 44 | # System Files 45 | .DS_Store 46 | Thumbs.db 47 | -------------------------------------------------------------------------------- /APM-Demo1/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | # Only exists if Bazel was run 8 | /bazel-out 9 | 10 | # dependencies 11 | /node_modules 12 | 13 | # profiling files 14 | chrome-profiler-events*.json 15 | speed-measure-plugin*.json 16 | 17 | # IDEs and editors 18 | /.idea 19 | .project 20 | .classpath 21 | .c9/ 22 | *.launch 23 | .settings/ 24 | *.sublime-workspace 25 | 26 | # IDE - VSCode 27 | .vscode/* 28 | !.vscode/settings.json 29 | !.vscode/tasks.json 30 | !.vscode/launch.json 31 | !.vscode/extensions.json 32 | .history/* 33 | 34 | # misc 35 | /.sass-cache 36 | /connect.lock 37 | /coverage 38 | /libpeerconnection.log 39 | npm-debug.log 40 | yarn-error.log 41 | testem.log 42 | /typings 43 | 44 | # System Files 45 | .DS_Store 46 | Thumbs.db 47 | -------------------------------------------------------------------------------- /APM-Demo2/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | # Only exists if Bazel was run 8 | /bazel-out 9 | 10 | # dependencies 11 | /node_modules 12 | 13 | # profiling files 14 | chrome-profiler-events*.json 15 | speed-measure-plugin*.json 16 | 17 | # IDEs and editors 18 | /.idea 19 | .project 20 | .classpath 21 | .c9/ 22 | *.launch 23 | .settings/ 24 | *.sublime-workspace 25 | 26 | # IDE - VSCode 27 | .vscode/* 28 | !.vscode/settings.json 29 | !.vscode/tasks.json 30 | !.vscode/launch.json 31 | !.vscode/extensions.json 32 | .history/* 33 | 34 | # misc 35 | /.sass-cache 36 | /connect.lock 37 | /coverage 38 | /libpeerconnection.log 39 | npm-debug.log 40 | yarn-error.log 41 | testem.log 42 | /typings 43 | 44 | # System Files 45 | .DS_Store 46 | Thumbs.db 47 | -------------------------------------------------------------------------------- /APM-Demo3/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | # Only exists if Bazel was run 8 | /bazel-out 9 | 10 | # dependencies 11 | /node_modules 12 | 13 | # profiling files 14 | chrome-profiler-events*.json 15 | speed-measure-plugin*.json 16 | 17 | # IDEs and editors 18 | /.idea 19 | .project 20 | .classpath 21 | .c9/ 22 | *.launch 23 | .settings/ 24 | *.sublime-workspace 25 | 26 | # IDE - VSCode 27 | .vscode/* 28 | !.vscode/settings.json 29 | !.vscode/tasks.json 30 | !.vscode/launch.json 31 | !.vscode/extensions.json 32 | .history/* 33 | 34 | # misc 35 | /.sass-cache 36 | /connect.lock 37 | /coverage 38 | /libpeerconnection.log 39 | npm-debug.log 40 | yarn-error.log 41 | testem.log 42 | /typings 43 | 44 | # System Files 45 | .DS_Store 46 | Thumbs.db 47 | -------------------------------------------------------------------------------- /APM-Demo4/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | # Only exists if Bazel was run 8 | /bazel-out 9 | 10 | # dependencies 11 | /node_modules 12 | 13 | # profiling files 14 | chrome-profiler-events*.json 15 | speed-measure-plugin*.json 16 | 17 | # IDEs and editors 18 | /.idea 19 | .project 20 | .classpath 21 | .c9/ 22 | *.launch 23 | .settings/ 24 | *.sublime-workspace 25 | 26 | # IDE - VSCode 27 | .vscode/* 28 | !.vscode/settings.json 29 | !.vscode/tasks.json 30 | !.vscode/launch.json 31 | !.vscode/extensions.json 32 | .history/* 33 | 34 | # misc 35 | /.sass-cache 36 | /connect.lock 37 | /coverage 38 | /libpeerconnection.log 39 | npm-debug.log 40 | yarn-error.log 41 | testem.log 42 | /typings 43 | 44 | # System Files 45 | .DS_Store 46 | Thumbs.db 47 | -------------------------------------------------------------------------------- /APM-Demo5/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | # Only exists if Bazel was run 8 | /bazel-out 9 | 10 | # dependencies 11 | /node_modules 12 | 13 | # profiling files 14 | chrome-profiler-events*.json 15 | speed-measure-plugin*.json 16 | 17 | # IDEs and editors 18 | /.idea 19 | .project 20 | .classpath 21 | .c9/ 22 | *.launch 23 | .settings/ 24 | *.sublime-workspace 25 | 26 | # IDE - VSCode 27 | .vscode/* 28 | !.vscode/settings.json 29 | !.vscode/tasks.json 30 | !.vscode/launch.json 31 | !.vscode/extensions.json 32 | .history/* 33 | 34 | # misc 35 | /.sass-cache 36 | /connect.lock 37 | /coverage 38 | /libpeerconnection.log 39 | npm-debug.log 40 | yarn-error.log 41 | testem.log 42 | /typings 43 | 44 | # System Files 45 | .DS_Store 46 | Thumbs.db 47 | -------------------------------------------------------------------------------- /APM-Demo0/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: { 11 | context(path: string, deep?: boolean, filter?: RegExp): { 12 | keys(): string[]; 13 | (id: string): T; 14 | }; 15 | }; 16 | 17 | // First, initialize the Angular testing environment. 18 | getTestBed().initTestEnvironment( 19 | BrowserDynamicTestingModule, 20 | platformBrowserDynamicTesting() 21 | ); 22 | // Then we find all the tests. 23 | const context = require.context('./', true, /\.spec\.ts$/); 24 | // And load the modules. 25 | context.keys().map(context); 26 | -------------------------------------------------------------------------------- /APM-Demo1/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: { 11 | context(path: string, deep?: boolean, filter?: RegExp): { 12 | keys(): string[]; 13 | (id: string): T; 14 | }; 15 | }; 16 | 17 | // First, initialize the Angular testing environment. 18 | getTestBed().initTestEnvironment( 19 | BrowserDynamicTestingModule, 20 | platformBrowserDynamicTesting() 21 | ); 22 | // Then we find all the tests. 23 | const context = require.context('./', true, /\.spec\.ts$/); 24 | // And load the modules. 25 | context.keys().map(context); 26 | -------------------------------------------------------------------------------- /APM-Demo2/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: { 11 | context(path: string, deep?: boolean, filter?: RegExp): { 12 | keys(): string[]; 13 | (id: string): T; 14 | }; 15 | }; 16 | 17 | // First, initialize the Angular testing environment. 18 | getTestBed().initTestEnvironment( 19 | BrowserDynamicTestingModule, 20 | platformBrowserDynamicTesting() 21 | ); 22 | // Then we find all the tests. 23 | const context = require.context('./', true, /\.spec\.ts$/); 24 | // And load the modules. 25 | context.keys().map(context); 26 | -------------------------------------------------------------------------------- /APM-Demo3/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: { 11 | context(path: string, deep?: boolean, filter?: RegExp): { 12 | keys(): string[]; 13 | (id: string): T; 14 | }; 15 | }; 16 | 17 | // First, initialize the Angular testing environment. 18 | getTestBed().initTestEnvironment( 19 | BrowserDynamicTestingModule, 20 | platformBrowserDynamicTesting() 21 | ); 22 | // Then we find all the tests. 23 | const context = require.context('./', true, /\.spec\.ts$/); 24 | // And load the modules. 25 | context.keys().map(context); 26 | -------------------------------------------------------------------------------- /APM-Demo4/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: { 11 | context(path: string, deep?: boolean, filter?: RegExp): { 12 | keys(): string[]; 13 | (id: string): T; 14 | }; 15 | }; 16 | 17 | // First, initialize the Angular testing environment. 18 | getTestBed().initTestEnvironment( 19 | BrowserDynamicTestingModule, 20 | platformBrowserDynamicTesting() 21 | ); 22 | // Then we find all the tests. 23 | const context = require.context('./', true, /\.spec\.ts$/); 24 | // And load the modules. 25 | context.keys().map(context); 26 | -------------------------------------------------------------------------------- /APM-Demo5/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: { 11 | context(path: string, deep?: boolean, filter?: RegExp): { 12 | keys(): string[]; 13 | (id: string): T; 14 | }; 15 | }; 16 | 17 | // First, initialize the Angular testing environment. 18 | getTestBed().initTestEnvironment( 19 | BrowserDynamicTestingModule, 20 | platformBrowserDynamicTesting() 21 | ); 22 | // Then we find all the tests. 23 | const context = require.context('./', true, /\.spec\.ts$/); 24 | // And load the modules. 25 | context.keys().map(context); 26 | -------------------------------------------------------------------------------- /APM-Demo0/src/app/user/auth-guard.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { ActivatedRouteSnapshot, RouterStateSnapshot, Router, CanActivate } from '@angular/router'; 3 | 4 | import { AuthService } from './auth.service'; 5 | 6 | @Injectable({ 7 | providedIn: 'root', 8 | }) 9 | export class AuthGuard implements CanActivate { 10 | 11 | constructor(private authService: AuthService, private router: Router) { } 12 | 13 | canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { 14 | return this.checkLoggedIn(state.url); 15 | } 16 | 17 | checkLoggedIn(url: string): boolean { 18 | if (this.authService.isLoggedIn()) { 19 | return true; 20 | } 21 | 22 | // Retain the attempted URL for redirection 23 | this.authService.redirectUrl = url; 24 | this.router.navigate(['/login']); 25 | return false; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /APM-Demo1/src/app/user/auth-guard.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { ActivatedRouteSnapshot, RouterStateSnapshot, Router, CanActivate } from '@angular/router'; 3 | 4 | import { AuthService } from './auth.service'; 5 | 6 | @Injectable({ 7 | providedIn: 'root', 8 | }) 9 | export class AuthGuard implements CanActivate { 10 | 11 | constructor(private authService: AuthService, private router: Router) { } 12 | 13 | canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { 14 | return this.checkLoggedIn(state.url); 15 | } 16 | 17 | checkLoggedIn(url: string): boolean { 18 | if (this.authService.isLoggedIn()) { 19 | return true; 20 | } 21 | 22 | // Retain the attempted URL for redirection 23 | this.authService.redirectUrl = url; 24 | this.router.navigate(['/login']); 25 | return false; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /APM-Demo2/src/app/user/auth-guard.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { ActivatedRouteSnapshot, RouterStateSnapshot, Router, CanActivate } from '@angular/router'; 3 | 4 | import { AuthService } from './auth.service'; 5 | 6 | @Injectable({ 7 | providedIn: 'root', 8 | }) 9 | export class AuthGuard implements CanActivate { 10 | 11 | constructor(private authService: AuthService, private router: Router) { } 12 | 13 | canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { 14 | return this.checkLoggedIn(state.url); 15 | } 16 | 17 | checkLoggedIn(url: string): boolean { 18 | if (this.authService.isLoggedIn()) { 19 | return true; 20 | } 21 | 22 | // Retain the attempted URL for redirection 23 | this.authService.redirectUrl = url; 24 | this.router.navigate(['/login']); 25 | return false; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/user/auth-guard.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { ActivatedRouteSnapshot, RouterStateSnapshot, Router, CanActivate } from '@angular/router'; 3 | 4 | import { AuthService } from './auth.service'; 5 | 6 | @Injectable({ 7 | providedIn: 'root', 8 | }) 9 | export class AuthGuard implements CanActivate { 10 | 11 | constructor(private authService: AuthService, private router: Router) { } 12 | 13 | canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { 14 | return this.checkLoggedIn(state.url); 15 | } 16 | 17 | checkLoggedIn(url: string): boolean { 18 | if (this.authService.isLoggedIn()) { 19 | return true; 20 | } 21 | 22 | // Retain the attempted URL for redirection 23 | this.authService.redirectUrl = url; 24 | this.router.navigate(['/login']); 25 | return false; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /APM-Demo4/src/app/user/auth-guard.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { ActivatedRouteSnapshot, RouterStateSnapshot, Router, CanActivate } from '@angular/router'; 3 | 4 | import { AuthService } from './auth.service'; 5 | 6 | @Injectable({ 7 | providedIn: 'root', 8 | }) 9 | export class AuthGuard implements CanActivate { 10 | 11 | constructor(private authService: AuthService, private router: Router) { } 12 | 13 | canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { 14 | return this.checkLoggedIn(state.url); 15 | } 16 | 17 | checkLoggedIn(url: string): boolean { 18 | if (this.authService.isLoggedIn()) { 19 | return true; 20 | } 21 | 22 | // Retain the attempted URL for redirection 23 | this.authService.redirectUrl = url; 24 | this.router.navigate(['/login']); 25 | return false; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/user/auth-guard.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { ActivatedRouteSnapshot, RouterStateSnapshot, Router, CanActivate } from '@angular/router'; 3 | 4 | import { AuthService } from './auth.service'; 5 | 6 | @Injectable({ 7 | providedIn: 'root', 8 | }) 9 | export class AuthGuard implements CanActivate { 10 | 11 | constructor(private authService: AuthService, private router: Router) { } 12 | 13 | canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { 14 | return this.checkLoggedIn(state.url); 15 | } 16 | 17 | checkLoggedIn(url: string): boolean { 18 | if (this.authService.isLoggedIn()) { 19 | return true; 20 | } 21 | 22 | // Retain the attempted URL for redirection 23 | this.authService.redirectUrl = url; 24 | this.router.navigate(['/login']); 25 | return false; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /APM-Demo0/src/app/home/menu.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { Router } from '@angular/router'; 3 | 4 | import { AuthService } from '../user/auth.service'; 5 | 6 | @Component({ 7 | selector: 'pm-menu', 8 | templateUrl: './menu.component.html' 9 | }) 10 | export class MenuComponent implements OnInit { 11 | pageTitle = 'Acme Product Management'; 12 | 13 | get isLoggedIn(): boolean { 14 | return this.authService.isLoggedIn(); 15 | } 16 | 17 | get userName(): string { 18 | if (this.authService.currentUser) { 19 | return this.authService.currentUser.userName; 20 | } 21 | return ''; 22 | } 23 | 24 | constructor(private router: Router, private authService: AuthService) { } 25 | 26 | ngOnInit() { 27 | } 28 | 29 | logOut(): void { 30 | this.authService.logout(); 31 | this.router.navigate(['/welcome']); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /APM-Demo1/src/app/home/menu.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { Router } from '@angular/router'; 3 | 4 | import { AuthService } from '../user/auth.service'; 5 | 6 | @Component({ 7 | selector: 'pm-menu', 8 | templateUrl: './menu.component.html' 9 | }) 10 | export class MenuComponent implements OnInit { 11 | pageTitle = 'Acme Product Management'; 12 | 13 | get isLoggedIn(): boolean { 14 | return this.authService.isLoggedIn(); 15 | } 16 | 17 | get userName(): string { 18 | if (this.authService.currentUser) { 19 | return this.authService.currentUser.userName; 20 | } 21 | return ''; 22 | } 23 | 24 | constructor(private router: Router, private authService: AuthService) { } 25 | 26 | ngOnInit() { 27 | } 28 | 29 | logOut(): void { 30 | this.authService.logout(); 31 | this.router.navigate(['/welcome']); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /APM-Demo2/src/app/home/menu.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { Router } from '@angular/router'; 3 | 4 | import { AuthService } from '../user/auth.service'; 5 | 6 | @Component({ 7 | selector: 'pm-menu', 8 | templateUrl: './menu.component.html' 9 | }) 10 | export class MenuComponent implements OnInit { 11 | pageTitle = 'Acme Product Management'; 12 | 13 | get isLoggedIn(): boolean { 14 | return this.authService.isLoggedIn(); 15 | } 16 | 17 | get userName(): string { 18 | if (this.authService.currentUser) { 19 | return this.authService.currentUser.userName; 20 | } 21 | return ''; 22 | } 23 | 24 | constructor(private router: Router, private authService: AuthService) { } 25 | 26 | ngOnInit() { 27 | } 28 | 29 | logOut(): void { 30 | this.authService.logout(); 31 | this.router.navigate(['/welcome']); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/home/menu.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { Router } from '@angular/router'; 3 | 4 | import { AuthService } from '../user/auth.service'; 5 | 6 | @Component({ 7 | selector: 'pm-menu', 8 | templateUrl: './menu.component.html' 9 | }) 10 | export class MenuComponent implements OnInit { 11 | pageTitle = 'Acme Product Management'; 12 | 13 | get isLoggedIn(): boolean { 14 | return this.authService.isLoggedIn(); 15 | } 16 | 17 | get userName(): string { 18 | if (this.authService.currentUser) { 19 | return this.authService.currentUser.userName; 20 | } 21 | return ''; 22 | } 23 | 24 | constructor(private router: Router, private authService: AuthService) { } 25 | 26 | ngOnInit() { 27 | } 28 | 29 | logOut(): void { 30 | this.authService.logout(); 31 | this.router.navigate(['/welcome']); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /APM-Demo4/src/app/home/menu.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { Router } from '@angular/router'; 3 | 4 | import { AuthService } from '../user/auth.service'; 5 | 6 | @Component({ 7 | selector: 'pm-menu', 8 | templateUrl: './menu.component.html' 9 | }) 10 | export class MenuComponent implements OnInit { 11 | pageTitle = 'Acme Product Management'; 12 | 13 | get isLoggedIn(): boolean { 14 | return this.authService.isLoggedIn(); 15 | } 16 | 17 | get userName(): string { 18 | if (this.authService.currentUser) { 19 | return this.authService.currentUser.userName; 20 | } 21 | return ''; 22 | } 23 | 24 | constructor(private router: Router, private authService: AuthService) { } 25 | 26 | ngOnInit() { 27 | } 28 | 29 | logOut(): void { 30 | this.authService.logout(); 31 | this.router.navigate(['/welcome']); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/home/menu.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { Router } from '@angular/router'; 3 | 4 | import { AuthService } from '../user/auth.service'; 5 | 6 | @Component({ 7 | selector: 'pm-menu', 8 | templateUrl: './menu.component.html' 9 | }) 10 | export class MenuComponent implements OnInit { 11 | pageTitle = 'Acme Product Management'; 12 | 13 | get isLoggedIn(): boolean { 14 | return this.authService.isLoggedIn(); 15 | } 16 | 17 | get userName(): string { 18 | if (this.authService.currentUser) { 19 | return this.authService.currentUser.userName; 20 | } 21 | return ''; 22 | } 23 | 24 | constructor(private router: Router, private authService: AuthService) { } 25 | 26 | ngOnInit() { 27 | } 28 | 29 | logOut(): void { 30 | this.authService.logout(); 31 | this.router.navigate(['/welcome']); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /APM-Demo0/e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | // Protractor configuration file, see link for more information 3 | // https://github.com/angular/protractor/blob/master/lib/config.ts 4 | 5 | const { SpecReporter } = require('jasmine-spec-reporter'); 6 | 7 | /** 8 | * @type { import("protractor").Config } 9 | */ 10 | exports.config = { 11 | allScriptsTimeout: 11000, 12 | specs: [ 13 | './src/**/*.e2e-spec.ts' 14 | ], 15 | capabilities: { 16 | browserName: 'chrome' 17 | }, 18 | directConnect: true, 19 | baseUrl: 'http://localhost:4200/', 20 | framework: 'jasmine', 21 | jasmineNodeOpts: { 22 | showColors: true, 23 | defaultTimeoutInterval: 30000, 24 | print: function() {} 25 | }, 26 | onPrepare() { 27 | require('ts-node').register({ 28 | project: require('path').join(__dirname, './tsconfig.json') 29 | }); 30 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 31 | } 32 | }; -------------------------------------------------------------------------------- /APM-Demo1/e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | // Protractor configuration file, see link for more information 3 | // https://github.com/angular/protractor/blob/master/lib/config.ts 4 | 5 | const { SpecReporter } = require('jasmine-spec-reporter'); 6 | 7 | /** 8 | * @type { import("protractor").Config } 9 | */ 10 | exports.config = { 11 | allScriptsTimeout: 11000, 12 | specs: [ 13 | './src/**/*.e2e-spec.ts' 14 | ], 15 | capabilities: { 16 | browserName: 'chrome' 17 | }, 18 | directConnect: true, 19 | baseUrl: 'http://localhost:4200/', 20 | framework: 'jasmine', 21 | jasmineNodeOpts: { 22 | showColors: true, 23 | defaultTimeoutInterval: 30000, 24 | print: function() {} 25 | }, 26 | onPrepare() { 27 | require('ts-node').register({ 28 | project: require('path').join(__dirname, './tsconfig.json') 29 | }); 30 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 31 | } 32 | }; -------------------------------------------------------------------------------- /APM-Demo2/e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | // Protractor configuration file, see link for more information 3 | // https://github.com/angular/protractor/blob/master/lib/config.ts 4 | 5 | const { SpecReporter } = require('jasmine-spec-reporter'); 6 | 7 | /** 8 | * @type { import("protractor").Config } 9 | */ 10 | exports.config = { 11 | allScriptsTimeout: 11000, 12 | specs: [ 13 | './src/**/*.e2e-spec.ts' 14 | ], 15 | capabilities: { 16 | browserName: 'chrome' 17 | }, 18 | directConnect: true, 19 | baseUrl: 'http://localhost:4200/', 20 | framework: 'jasmine', 21 | jasmineNodeOpts: { 22 | showColors: true, 23 | defaultTimeoutInterval: 30000, 24 | print: function() {} 25 | }, 26 | onPrepare() { 27 | require('ts-node').register({ 28 | project: require('path').join(__dirname, './tsconfig.json') 29 | }); 30 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 31 | } 32 | }; -------------------------------------------------------------------------------- /APM-Demo3/e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | // Protractor configuration file, see link for more information 3 | // https://github.com/angular/protractor/blob/master/lib/config.ts 4 | 5 | const { SpecReporter } = require('jasmine-spec-reporter'); 6 | 7 | /** 8 | * @type { import("protractor").Config } 9 | */ 10 | exports.config = { 11 | allScriptsTimeout: 11000, 12 | specs: [ 13 | './src/**/*.e2e-spec.ts' 14 | ], 15 | capabilities: { 16 | browserName: 'chrome' 17 | }, 18 | directConnect: true, 19 | baseUrl: 'http://localhost:4200/', 20 | framework: 'jasmine', 21 | jasmineNodeOpts: { 22 | showColors: true, 23 | defaultTimeoutInterval: 30000, 24 | print: function() {} 25 | }, 26 | onPrepare() { 27 | require('ts-node').register({ 28 | project: require('path').join(__dirname, './tsconfig.json') 29 | }); 30 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 31 | } 32 | }; -------------------------------------------------------------------------------- /APM-Demo4/e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | // Protractor configuration file, see link for more information 3 | // https://github.com/angular/protractor/blob/master/lib/config.ts 4 | 5 | const { SpecReporter } = require('jasmine-spec-reporter'); 6 | 7 | /** 8 | * @type { import("protractor").Config } 9 | */ 10 | exports.config = { 11 | allScriptsTimeout: 11000, 12 | specs: [ 13 | './src/**/*.e2e-spec.ts' 14 | ], 15 | capabilities: { 16 | browserName: 'chrome' 17 | }, 18 | directConnect: true, 19 | baseUrl: 'http://localhost:4200/', 20 | framework: 'jasmine', 21 | jasmineNodeOpts: { 22 | showColors: true, 23 | defaultTimeoutInterval: 30000, 24 | print: function() {} 25 | }, 26 | onPrepare() { 27 | require('ts-node').register({ 28 | project: require('path').join(__dirname, './tsconfig.json') 29 | }); 30 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 31 | } 32 | }; -------------------------------------------------------------------------------- /APM-Demo5/e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | // Protractor configuration file, see link for more information 3 | // https://github.com/angular/protractor/blob/master/lib/config.ts 4 | 5 | const { SpecReporter } = require('jasmine-spec-reporter'); 6 | 7 | /** 8 | * @type { import("protractor").Config } 9 | */ 10 | exports.config = { 11 | allScriptsTimeout: 11000, 12 | specs: [ 13 | './src/**/*.e2e-spec.ts' 14 | ], 15 | capabilities: { 16 | browserName: 'chrome' 17 | }, 18 | directConnect: true, 19 | baseUrl: 'http://localhost:4200/', 20 | framework: 'jasmine', 21 | jasmineNodeOpts: { 22 | showColors: true, 23 | defaultTimeoutInterval: 30000, 24 | print: function() {} 25 | }, 26 | onPrepare() { 27 | require('ts-node').register({ 28 | project: require('path').join(__dirname, './tsconfig.json') 29 | }); 30 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 31 | } 32 | }; -------------------------------------------------------------------------------- /APM-Demo2/src/app/products/state/product.actions.ts: -------------------------------------------------------------------------------- 1 | import { Product } from '../product'; 2 | 3 | /* NgRx */ 4 | import { createAction, props } from '@ngrx/store'; 5 | 6 | export const toggleProductCode = createAction( 7 | '[Product] Toggle Product Code' 8 | ); 9 | 10 | export const setCurrentProduct = createAction( 11 | '[Product] Set Current Product', 12 | props<{ product: Product }>() 13 | ); 14 | 15 | export const clearCurrentProduct = createAction( 16 | '[Product] Clear Current Product' 17 | ); 18 | 19 | export const initializeCurrentProduct = createAction( 20 | '[Product] Initialize Current Product' 21 | ); 22 | 23 | export const loadProducts = createAction( 24 | '[Product] Load' 25 | ); 26 | 27 | export const loadProductsSuccess = createAction( 28 | '[Product] Load Success', 29 | props<{ products: Product[] }>() 30 | ); 31 | 32 | export const loadProductsFailure = createAction( 33 | '[Product] Load Fail', 34 | props<{ error: string }>() 35 | ); 36 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/products/state/product.actions.ts: -------------------------------------------------------------------------------- 1 | import { Product } from '../product'; 2 | 3 | /* NgRx */ 4 | import { createAction, props } from '@ngrx/store'; 5 | 6 | export const toggleProductCode = createAction( 7 | '[Product] Toggle Product Code' 8 | ); 9 | 10 | export const setCurrentProduct = createAction( 11 | '[Product] Set Current Product', 12 | props<{ product: Product }>() 13 | ); 14 | 15 | export const clearCurrentProduct = createAction( 16 | '[Product] Clear Current Product' 17 | ); 18 | 19 | export const initializeCurrentProduct = createAction( 20 | '[Product] Initialize Current Product' 21 | ); 22 | 23 | export const loadProducts = createAction( 24 | '[Product] Load' 25 | ); 26 | 27 | export const loadProductsSuccess = createAction( 28 | '[Product] Load Success', 29 | props<{ products: Product[] }>() 30 | ); 31 | 32 | export const loadProductsFailure = createAction( 33 | '[Product] Load Fail', 34 | props<{ error: string }>() 35 | ); 36 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/products/state/product.effects.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | import { mergeMap, map, catchError } from 'rxjs/operators'; 4 | import { of } from 'rxjs'; 5 | import { ProductService } from '../product.service'; 6 | 7 | /* NgRx */ 8 | import { Actions, createEffect, ofType } from '@ngrx/effects'; 9 | import * as ProductActions from './product.actions'; 10 | 11 | @Injectable() 12 | export class ProductEffects { 13 | 14 | constructor(private actions$: Actions, private productService: ProductService) { } 15 | 16 | loadProducts$ = createEffect(() => { 17 | return this.actions$ 18 | .pipe( 19 | ofType(ProductActions.loadProducts), 20 | mergeMap(() => this.productService.getProducts() 21 | .pipe( 22 | map(products => ProductActions.loadProductsSuccess({ products })), 23 | catchError(error => of(ProductActions.loadProductsFailure({ error }))) 24 | ) 25 | ) 26 | ); 27 | }); 28 | } 29 | -------------------------------------------------------------------------------- /APM-Demo1/src/app/products/product.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | import { SharedModule } from '../shared/shared.module'; 5 | 6 | import { ProductShellComponent } from './product-shell/product-shell.component'; 7 | import { ProductListComponent } from './product-list/product-list.component'; 8 | import { ProductEditComponent } from './product-edit/product-edit.component'; 9 | 10 | /* NgRx */ 11 | import { StoreModule } from '@ngrx/store'; 12 | import { productReducer } from './state/product.reducer'; 13 | 14 | const productRoutes: Routes = [ 15 | { path: '', component: ProductShellComponent } 16 | ]; 17 | 18 | @NgModule({ 19 | imports: [ 20 | SharedModule, 21 | RouterModule.forChild(productRoutes), 22 | StoreModule.forFeature('products', productReducer) 23 | ], 24 | declarations: [ 25 | ProductShellComponent, 26 | ProductListComponent, 27 | ProductEditComponent 28 | ] 29 | }) 30 | export class ProductModule { } 31 | -------------------------------------------------------------------------------- /APM-Demo2/src/app/products/product.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | import { SharedModule } from '../shared/shared.module'; 5 | 6 | import { ProductShellComponent } from './product-shell/product-shell.component'; 7 | import { ProductListComponent } from './product-list/product-list.component'; 8 | import { ProductEditComponent } from './product-edit/product-edit.component'; 9 | 10 | /* NgRx */ 11 | import { StoreModule } from '@ngrx/store'; 12 | import { productReducer } from './state/product.reducer'; 13 | 14 | const productRoutes: Routes = [ 15 | { path: '', component: ProductShellComponent } 16 | ]; 17 | 18 | @NgModule({ 19 | imports: [ 20 | SharedModule, 21 | RouterModule.forChild(productRoutes), 22 | StoreModule.forFeature('products', productReducer) 23 | ], 24 | declarations: [ 25 | ProductShellComponent, 26 | ProductListComponent, 27 | ProductEditComponent 28 | ] 29 | }) 30 | export class ProductModule { } 31 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/products/product-shell/product-shell.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 10 |
11 |
12 | 18 |
19 |
-------------------------------------------------------------------------------- /APM-Demo2/src/app/user/state/user.reducer.ts: -------------------------------------------------------------------------------- 1 | // Homework 2 | import { User } from '../user'; 3 | 4 | /* NgRx */ 5 | import { createReducer, on, createFeatureSelector, createSelector } from '@ngrx/store'; 6 | import * as UserActions from './user.actions'; 7 | 8 | // State for this feature (User) 9 | export interface UserState { 10 | maskUserName: boolean; 11 | currentUser: User; 12 | } 13 | 14 | const initialState: UserState = { 15 | maskUserName: true, 16 | currentUser: null 17 | }; 18 | 19 | // Selector functions 20 | const getUserFeatureState = createFeatureSelector('users'); 21 | 22 | export const getMaskUserName = createSelector( 23 | getUserFeatureState, 24 | state => state.maskUserName 25 | ); 26 | 27 | export const getCurrentUser = createSelector( 28 | getUserFeatureState, 29 | state => state.currentUser 30 | ); 31 | 32 | export const userReducer = createReducer( 33 | initialState, 34 | on(UserActions.maskUserName, (state): UserState => { 35 | return { 36 | ...state, 37 | maskUserName: !state.maskUserName 38 | }; 39 | }) 40 | ); 41 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/user/state/user.reducer.ts: -------------------------------------------------------------------------------- 1 | // Homework 2 | import { User } from '../user'; 3 | 4 | /* NgRx */ 5 | import { createReducer, on, createFeatureSelector, createSelector } from '@ngrx/store'; 6 | import * as UserActions from './user.actions'; 7 | 8 | // State for this feature (User) 9 | export interface UserState { 10 | maskUserName: boolean; 11 | currentUser: User; 12 | } 13 | 14 | const initialState: UserState = { 15 | maskUserName: true, 16 | currentUser: null 17 | }; 18 | 19 | // Selector functions 20 | const getUserFeatureState = createFeatureSelector('users'); 21 | 22 | export const getMaskUserName = createSelector( 23 | getUserFeatureState, 24 | state => state.maskUserName 25 | ); 26 | 27 | export const getCurrentUser = createSelector( 28 | getUserFeatureState, 29 | state => state.currentUser 30 | ); 31 | 32 | export const userReducer = createReducer( 33 | initialState, 34 | on(UserActions.maskUserName, (state): UserState => { 35 | return { 36 | ...state, 37 | maskUserName: !state.maskUserName 38 | }; 39 | }) 40 | ); 41 | -------------------------------------------------------------------------------- /APM-Demo4/src/app/user/state/user.reducer.ts: -------------------------------------------------------------------------------- 1 | // Homework 2 | import { User } from '../user'; 3 | 4 | /* NgRx */ 5 | import { createReducer, on, createFeatureSelector, createSelector } from '@ngrx/store'; 6 | import * as UserActions from './user.actions'; 7 | 8 | // State for this feature (User) 9 | export interface UserState { 10 | maskUserName: boolean; 11 | currentUser: User; 12 | } 13 | 14 | const initialState: UserState = { 15 | maskUserName: true, 16 | currentUser: null 17 | }; 18 | 19 | // Selector functions 20 | const getUserFeatureState = createFeatureSelector('users'); 21 | 22 | export const getMaskUserName = createSelector( 23 | getUserFeatureState, 24 | state => state.maskUserName 25 | ); 26 | 27 | export const getCurrentUser = createSelector( 28 | getUserFeatureState, 29 | state => state.currentUser 30 | ); 31 | 32 | export const userReducer = createReducer( 33 | initialState, 34 | on(UserActions.maskUserName, (state): UserState => { 35 | return { 36 | ...state, 37 | maskUserName: !state.maskUserName 38 | }; 39 | }) 40 | ); 41 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/user/state/user.reducer.ts: -------------------------------------------------------------------------------- 1 | // Homework 2 | import { User } from '../user'; 3 | 4 | /* NgRx */ 5 | import { createReducer, on, createFeatureSelector, createSelector } from '@ngrx/store'; 6 | import { UserPageActions } from './actions'; 7 | 8 | // State for this feature (User) 9 | export interface UserState { 10 | maskUserName: boolean; 11 | currentUser: User; 12 | } 13 | 14 | const initialState: UserState = { 15 | maskUserName: true, 16 | currentUser: null 17 | }; 18 | 19 | // Selector functions 20 | const getUserFeatureState = createFeatureSelector('users'); 21 | 22 | export const getMaskUserName = createSelector( 23 | getUserFeatureState, 24 | state => state.maskUserName 25 | ); 26 | 27 | export const getCurrentUser = createSelector( 28 | getUserFeatureState, 29 | state => state.currentUser 30 | ); 31 | 32 | export const userReducer = createReducer( 33 | initialState, 34 | on(UserPageActions.maskUserName, (state): UserState => { 35 | return { 36 | ...state, 37 | maskUserName: !state.maskUserName 38 | }; 39 | }) 40 | ); 41 | -------------------------------------------------------------------------------- /APM-Demo0/src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | import { AuthGuard } from './user/auth-guard.service'; 5 | 6 | import { ShellComponent } from './home/shell.component'; 7 | import { WelcomeComponent } from './home/welcome.component'; 8 | import { PageNotFoundComponent } from './home/page-not-found.component'; 9 | 10 | const appRoutes: Routes = [ 11 | { 12 | path: '', 13 | component: ShellComponent, 14 | children: [ 15 | { path: 'welcome', component: WelcomeComponent }, 16 | { 17 | path: 'products', 18 | // canActivate: [AuthGuard], 19 | loadChildren: () => 20 | import('./products/product.module').then(m => m.ProductModule) 21 | }, 22 | { path: '', redirectTo: 'welcome', pathMatch: 'full' }, 23 | ] 24 | }, 25 | { path: '**', component: PageNotFoundComponent } 26 | ]; 27 | 28 | @NgModule({ 29 | imports: [ 30 | RouterModule.forRoot(appRoutes) 31 | ], 32 | exports: [RouterModule] 33 | }) 34 | export class AppRoutingModule { } 35 | -------------------------------------------------------------------------------- /APM-Demo1/src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | import { AuthGuard } from './user/auth-guard.service'; 5 | 6 | import { ShellComponent } from './home/shell.component'; 7 | import { WelcomeComponent } from './home/welcome.component'; 8 | import { PageNotFoundComponent } from './home/page-not-found.component'; 9 | 10 | const appRoutes: Routes = [ 11 | { 12 | path: '', 13 | component: ShellComponent, 14 | children: [ 15 | { path: 'welcome', component: WelcomeComponent }, 16 | { 17 | path: 'products', 18 | // canActivate: [AuthGuard], 19 | loadChildren: () => 20 | import('./products/product.module').then(m => m.ProductModule) 21 | }, 22 | { path: '', redirectTo: 'welcome', pathMatch: 'full' }, 23 | ] 24 | }, 25 | { path: '**', component: PageNotFoundComponent } 26 | ]; 27 | 28 | @NgModule({ 29 | imports: [ 30 | RouterModule.forRoot(appRoutes) 31 | ], 32 | exports: [RouterModule] 33 | }) 34 | export class AppRoutingModule { } 35 | -------------------------------------------------------------------------------- /APM-Demo2/src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | import { AuthGuard } from './user/auth-guard.service'; 5 | 6 | import { ShellComponent } from './home/shell.component'; 7 | import { WelcomeComponent } from './home/welcome.component'; 8 | import { PageNotFoundComponent } from './home/page-not-found.component'; 9 | 10 | const appRoutes: Routes = [ 11 | { 12 | path: '', 13 | component: ShellComponent, 14 | children: [ 15 | { path: 'welcome', component: WelcomeComponent }, 16 | { 17 | path: 'products', 18 | // canActivate: [AuthGuard], 19 | loadChildren: () => 20 | import('./products/product.module').then(m => m.ProductModule) 21 | }, 22 | { path: '', redirectTo: 'welcome', pathMatch: 'full' }, 23 | ] 24 | }, 25 | { path: '**', component: PageNotFoundComponent } 26 | ]; 27 | 28 | @NgModule({ 29 | imports: [ 30 | RouterModule.forRoot(appRoutes) 31 | ], 32 | exports: [RouterModule] 33 | }) 34 | export class AppRoutingModule { } 35 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | import { AuthGuard } from './user/auth-guard.service'; 5 | 6 | import { ShellComponent } from './home/shell.component'; 7 | import { WelcomeComponent } from './home/welcome.component'; 8 | import { PageNotFoundComponent } from './home/page-not-found.component'; 9 | 10 | const appRoutes: Routes = [ 11 | { 12 | path: '', 13 | component: ShellComponent, 14 | children: [ 15 | { path: 'welcome', component: WelcomeComponent }, 16 | { 17 | path: 'products', 18 | // canActivate: [AuthGuard], 19 | loadChildren: () => 20 | import('./products/product.module').then(m => m.ProductModule) 21 | }, 22 | { path: '', redirectTo: 'welcome', pathMatch: 'full' }, 23 | ] 24 | }, 25 | { path: '**', component: PageNotFoundComponent } 26 | ]; 27 | 28 | @NgModule({ 29 | imports: [ 30 | RouterModule.forRoot(appRoutes) 31 | ], 32 | exports: [RouterModule] 33 | }) 34 | export class AppRoutingModule { } 35 | -------------------------------------------------------------------------------- /APM-Demo4/src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | import { AuthGuard } from './user/auth-guard.service'; 5 | 6 | import { ShellComponent } from './home/shell.component'; 7 | import { WelcomeComponent } from './home/welcome.component'; 8 | import { PageNotFoundComponent } from './home/page-not-found.component'; 9 | 10 | const appRoutes: Routes = [ 11 | { 12 | path: '', 13 | component: ShellComponent, 14 | children: [ 15 | { path: 'welcome', component: WelcomeComponent }, 16 | { 17 | path: 'products', 18 | // canActivate: [AuthGuard], 19 | loadChildren: () => 20 | import('./products/product.module').then(m => m.ProductModule) 21 | }, 22 | { path: '', redirectTo: 'welcome', pathMatch: 'full' }, 23 | ] 24 | }, 25 | { path: '**', component: PageNotFoundComponent } 26 | ]; 27 | 28 | @NgModule({ 29 | imports: [ 30 | RouterModule.forRoot(appRoutes) 31 | ], 32 | exports: [RouterModule] 33 | }) 34 | export class AppRoutingModule { } 35 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | import { AuthGuard } from './user/auth-guard.service'; 5 | 6 | import { ShellComponent } from './home/shell.component'; 7 | import { WelcomeComponent } from './home/welcome.component'; 8 | import { PageNotFoundComponent } from './home/page-not-found.component'; 9 | 10 | const appRoutes: Routes = [ 11 | { 12 | path: '', 13 | component: ShellComponent, 14 | children: [ 15 | { path: 'welcome', component: WelcomeComponent }, 16 | { 17 | path: 'products', 18 | // canActivate: [AuthGuard], 19 | loadChildren: () => 20 | import('./products/product.module').then(m => m.ProductModule) 21 | }, 22 | { path: '', redirectTo: 'welcome', pathMatch: 'full' }, 23 | ] 24 | }, 25 | { path: '**', component: PageNotFoundComponent } 26 | ]; 27 | 28 | @NgModule({ 29 | imports: [ 30 | RouterModule.forRoot(appRoutes) 31 | ], 32 | exports: [RouterModule] 33 | }) 34 | export class AppRoutingModule { } 35 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/products/product-list/product-list.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core'; 2 | import { Product } from '../product'; 3 | 4 | @Component({ 5 | selector: 'pm-product-list', 6 | templateUrl: './product-list.component.html', 7 | styleUrls: ['./product-list.component.css'], 8 | changeDetection: ChangeDetectionStrategy.OnPush 9 | }) 10 | export class ProductListComponent { 11 | pageTitle = 'Products'; 12 | 13 | @Input() errorMessage: string; 14 | @Input() products: Product[]; 15 | @Input() displayCode: boolean; 16 | @Input() selectedProduct: Product; 17 | @Output() displayCodeChanged = new EventEmitter(); 18 | @Output() initializeNewProduct = new EventEmitter(); 19 | @Output() productWasSelected = new EventEmitter(); 20 | 21 | checkChanged(): void { 22 | this.displayCodeChanged.emit(); 23 | } 24 | 25 | newProduct(): void { 26 | this.initializeNewProduct.emit(); 27 | } 28 | 29 | productSelected(product: Product): void { 30 | this.productWasSelected.emit(product); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Deborah Kurata 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /APM-Demo0/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, './coverage/APM'), 20 | reports: ['html', 'lcovonly', 'text-summary'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false, 30 | restartOnFileChange: true 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /APM-Demo1/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, './coverage/APM'), 20 | reports: ['html', 'lcovonly', 'text-summary'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false, 30 | restartOnFileChange: true 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /APM-Demo2/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, './coverage/APM'), 20 | reports: ['html', 'lcovonly', 'text-summary'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false, 30 | restartOnFileChange: true 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /APM-Demo3/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, './coverage/APM'), 20 | reports: ['html', 'lcovonly', 'text-summary'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false, 30 | restartOnFileChange: true 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /APM-Demo4/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, './coverage/APM'), 20 | reports: ['html', 'lcovonly', 'text-summary'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false, 30 | restartOnFileChange: true 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /APM-Demo5/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, './coverage/APM'), 20 | reports: ['html', 'lcovonly', 'text-summary'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false, 30 | restartOnFileChange: true 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/products/state/actions/product-page.actions.ts: -------------------------------------------------------------------------------- 1 | import { Product } from '../../product'; 2 | 3 | /* NgRx */ 4 | import { createAction, props } from '@ngrx/store'; 5 | 6 | export const toggleProductCode = createAction( 7 | '[Product Page] Toggle Product Code' 8 | ); 9 | 10 | export const setCurrentProduct = createAction( 11 | '[Product Page] Set Current Product', 12 | props<{ currentProductId: number }>() 13 | ); 14 | 15 | export const clearCurrentProduct = createAction( 16 | '[Product Page] Clear Current Product' 17 | ); 18 | 19 | export const initializeCurrentProduct = createAction( 20 | '[Product Page] Initialize Current Product' 21 | ); 22 | 23 | export const loadProducts = createAction( 24 | '[Product Page] Load' 25 | ); 26 | 27 | export const updateProduct = createAction( 28 | '[Product Page] Update Product', 29 | props<{ product: Product }>() 30 | ); 31 | 32 | export const createProduct = createAction( 33 | '[Product Page] Create Product', 34 | props<{ product: Product }>() 35 | ); 36 | 37 | export const deleteProduct = createAction( 38 | '[Product Page] Delete Product', 39 | props<{ productId: number }>() 40 | ); 41 | -------------------------------------------------------------------------------- /APM-Demo0/README.md: -------------------------------------------------------------------------------- 1 | # APM-Demo0 2 | 3 | Starter files with no NgRx added. 4 | 5 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 9.1.3. 6 | 7 | ## Development server 8 | 9 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. 10 | 11 | ## Code scaffolding 12 | 13 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. 14 | 15 | ## Build 16 | 17 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. 18 | 19 | ## Running unit tests 20 | 21 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 22 | 23 | ## Running end-to-end tests 24 | 25 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 26 | 27 | ## Further help 28 | 29 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). 30 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/products/product.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | import { SharedModule } from '../shared/shared.module'; 5 | 6 | import { ProductShellComponent } from './product-shell/product-shell.component'; 7 | import { ProductListComponent } from './product-list/product-list.component'; 8 | import { ProductEditComponent } from './product-edit/product-edit.component'; 9 | 10 | /* NgRx */ 11 | import { StoreModule } from '@ngrx/store'; 12 | import { productReducer } from './state/product.reducer'; 13 | import { EffectsModule } from '@ngrx/effects'; 14 | import { ProductEffects } from './state/product.effects'; 15 | 16 | const productRoutes: Routes = [ 17 | { path: '', component: ProductShellComponent } 18 | ]; 19 | 20 | @NgModule({ 21 | imports: [ 22 | SharedModule, 23 | RouterModule.forChild(productRoutes), 24 | StoreModule.forFeature('products', productReducer), 25 | EffectsModule.forFeature([ProductEffects]) 26 | ], 27 | declarations: [ 28 | ProductShellComponent, 29 | ProductListComponent, 30 | ProductEditComponent 31 | ] 32 | }) 33 | export class ProductModule { } 34 | -------------------------------------------------------------------------------- /APM-Demo4/src/app/products/product.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | import { SharedModule } from '../shared/shared.module'; 5 | 6 | import { ProductShellComponent } from './product-shell/product-shell.component'; 7 | import { ProductListComponent } from './product-list/product-list.component'; 8 | import { ProductEditComponent } from './product-edit/product-edit.component'; 9 | 10 | /* NgRx */ 11 | import { StoreModule } from '@ngrx/store'; 12 | import { productReducer } from './state/product.reducer'; 13 | import { EffectsModule } from '@ngrx/effects'; 14 | import { ProductEffects } from './state/product.effects'; 15 | 16 | const productRoutes: Routes = [ 17 | { path: '', component: ProductShellComponent } 18 | ]; 19 | 20 | @NgModule({ 21 | imports: [ 22 | SharedModule, 23 | RouterModule.forChild(productRoutes), 24 | StoreModule.forFeature('products', productReducer), 25 | EffectsModule.forFeature([ProductEffects]) 26 | ], 27 | declarations: [ 28 | ProductShellComponent, 29 | ProductListComponent, 30 | ProductEditComponent 31 | ] 32 | }) 33 | export class ProductModule { } 34 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/products/product.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | import { SharedModule } from '../shared/shared.module'; 5 | 6 | import { ProductShellComponent } from './product-shell/product-shell.component'; 7 | import { ProductListComponent } from './product-list/product-list.component'; 8 | import { ProductEditComponent } from './product-edit/product-edit.component'; 9 | 10 | /* NgRx */ 11 | import { StoreModule } from '@ngrx/store'; 12 | import { productReducer } from './state/product.reducer'; 13 | import { EffectsModule } from '@ngrx/effects'; 14 | import { ProductEffects } from './state/product.effects'; 15 | 16 | const productRoutes: Routes = [ 17 | { path: '', component: ProductShellComponent } 18 | ]; 19 | 20 | @NgModule({ 21 | imports: [ 22 | SharedModule, 23 | RouterModule.forChild(productRoutes), 24 | StoreModule.forFeature('products', productReducer), 25 | EffectsModule.forFeature([ProductEffects]) 26 | ], 27 | declarations: [ 28 | ProductShellComponent, 29 | ProductListComponent, 30 | ProductEditComponent 31 | ] 32 | }) 33 | export class ProductModule { } 34 | -------------------------------------------------------------------------------- /APM-Demo4/README.md: -------------------------------------------------------------------------------- 1 | # APM-Demo4 2 | 3 | Demo of create, update, and delete operations using NgRx. 4 | 5 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 9.1.3. 6 | 7 | ## Development server 8 | 9 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. 10 | 11 | ## Code scaffolding 12 | 13 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. 14 | 15 | ## Build 16 | 17 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. 18 | 19 | ## Running unit tests 20 | 21 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 22 | 23 | ## Running end-to-end tests 24 | 25 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 26 | 27 | ## Further help 28 | 29 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). 30 | -------------------------------------------------------------------------------- /APM-Demo0/src/app/home/welcome.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | {{pageTitle}} 4 |
5 |
6 |
7 |
8 | 11 |
12 |
13 |
14 |
Developed by:
15 |
17 |

Deborah Kurata

18 | 19 |
@deborahkurata
20 | 23 |
24 |
26 |

Duncan Hunter

27 | 28 |
@dunchunter
29 | 32 |
33 |
34 |
35 |
-------------------------------------------------------------------------------- /APM-Demo1/src/app/home/welcome.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | {{pageTitle}} 4 |
5 |
6 |
7 |
8 | 11 |
12 |
13 |
14 |
Developed by:
15 |
17 |

Deborah Kurata

18 | 19 |
@deborahkurata
20 | 23 |
24 |
26 |

Duncan Hunter

27 | 28 |
@dunchunter
29 | 32 |
33 |
34 |
35 |
-------------------------------------------------------------------------------- /APM-Demo2/src/app/home/welcome.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | {{pageTitle}} 4 |
5 |
6 |
7 |
8 | 11 |
12 |
13 |
14 |
Developed by:
15 |
17 |

Deborah Kurata

18 | 19 |
@deborahkurata
20 | 23 |
24 |
26 |

Duncan Hunter

27 | 28 |
@dunchunter
29 | 32 |
33 |
34 |
35 |
-------------------------------------------------------------------------------- /APM-Demo3/src/app/home/welcome.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | {{pageTitle}} 4 |
5 |
6 |
7 |
8 | 11 |
12 |
13 |
14 |
Developed by:
15 |
17 |

Deborah Kurata

18 | 19 |
@deborahkurata
20 | 23 |
24 |
26 |

Duncan Hunter

27 | 28 |
@dunchunter
29 | 32 |
33 |
34 |
35 |
-------------------------------------------------------------------------------- /APM-Demo4/src/app/home/welcome.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | {{pageTitle}} 4 |
5 |
6 |
7 |
8 | 11 |
12 |
13 |
14 |
Developed by:
15 |
17 |

Deborah Kurata

18 | 19 |
@deborahkurata
20 | 23 |
24 |
26 |

Duncan Hunter

27 | 28 |
@dunchunter
29 | 32 |
33 |
34 |
35 |
-------------------------------------------------------------------------------- /APM-Demo5/src/app/home/welcome.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | {{pageTitle}} 4 |
5 |
6 |
7 |
8 | 11 |
12 |
13 |
14 |
Developed by:
15 |
17 |

Deborah Kurata

18 | 19 |
@deborahkurata
20 | 23 |
24 |
26 |

Duncan Hunter

27 | 28 |
@dunchunter
29 | 32 |
33 |
34 |
35 |
-------------------------------------------------------------------------------- /APM-Demo5/README.md: -------------------------------------------------------------------------------- 1 | # APM-Demo5 2 | 3 | Demo of container/presentational pattern and OnPush change detection strategy. 4 | 5 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 9.1.3. 6 | 7 | ## Development server 8 | 9 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. 10 | 11 | ## Code scaffolding 12 | 13 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. 14 | 15 | ## Build 16 | 17 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. 18 | 19 | ## Running unit tests 20 | 21 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 22 | 23 | ## Running end-to-end tests 24 | 25 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 26 | 27 | ## Further help 28 | 29 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). 30 | -------------------------------------------------------------------------------- /APM-Demo0/src/app/user/login.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { NgForm } from '@angular/forms'; 3 | import { Router } from '@angular/router'; 4 | 5 | import { AuthService } from './auth.service'; 6 | 7 | @Component({ 8 | templateUrl: './login.component.html', 9 | styleUrls: ['./login.component.css'] 10 | }) 11 | export class LoginComponent implements OnInit { 12 | pageTitle = 'Log In'; 13 | 14 | maskUserName: boolean; 15 | 16 | constructor(private authService: AuthService, private router: Router) { } 17 | 18 | ngOnInit(): void { 19 | 20 | } 21 | 22 | cancel(): void { 23 | this.router.navigate(['welcome']); 24 | } 25 | 26 | checkChanged(): void { 27 | this.maskUserName = !this.maskUserName; 28 | } 29 | 30 | login(loginForm: NgForm): void { 31 | if (loginForm && loginForm.valid) { 32 | const userName = loginForm.form.value.userName; 33 | const password = loginForm.form.value.password; 34 | this.authService.login(userName, password); 35 | 36 | if (this.authService.redirectUrl) { 37 | this.router.navigateByUrl(this.authService.redirectUrl); 38 | } else { 39 | this.router.navigate(['/products']); 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Angular-ngrx-GettingStarted 2 | Materials for NgRx course. 3 | 4 | `APM-Demo0`: The starter files for this course. **Use this to code along with the course**. 5 | 6 | `APM-Demo1`: Completed files after the *First Look at NgRx* module. It demonstrates a very simple NgRx example. 7 | 8 | `APM-Demo2`: Completed files after the *Strongly Typing Actions with Action Creators* module. It refactors the simple example to include developer tooling support and strong typing. 9 | 10 | `APM-Demo3`: Completed files after the *Working with Effects* module. It adds an effect to retrieve data via http. NOTE: Once we move the data retrieval to actions and the store, the create, update, and delete operations no longer work. These features are implemented with the store in the next demo. 11 | 12 | `APM-Demo4`: Completed files after the *Performing Update Operations* module. It adds the code needed for create, update, and delete operations via http. 13 | 14 | `APM-Demo5`: Completed files after the *Architectural Considerations* module. It implements the container/presentational component pattern and the OnPush change detection strategy. 15 | 16 | NOTE: 17 | - June 30, 2020: This code was modified to Angular version 9 and NgRx version 9. See the CHANGELOG.md file for details. 18 | -------------------------------------------------------------------------------- /APM-Demo2/README.md: -------------------------------------------------------------------------------- 1 | # APM-Demo2 2 | 3 | Demo of a basic implementation of NgRx for a simple boolean flag, but using strong typing. Includes implementation of the dev tools. 4 | 5 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 9.1.3. 6 | 7 | ## Development server 8 | 9 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. 10 | 11 | ## Code scaffolding 12 | 13 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. 14 | 15 | ## Build 16 | 17 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. 18 | 19 | ## Running unit tests 20 | 21 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 22 | 23 | ## Running end-to-end tests 24 | 25 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 26 | 27 | ## Further help 28 | 29 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). 30 | -------------------------------------------------------------------------------- /APM-Demo0/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { BrowserModule } from '@angular/platform-browser'; 3 | import { HttpClientModule } from '@angular/common/http'; 4 | 5 | // Imports for loading & configuring the in-memory web api 6 | import { HttpClientInMemoryWebApiModule } from 'angular-in-memory-web-api'; 7 | import { ProductData } from './products/product-data'; 8 | 9 | import { AppRoutingModule } from './app-routing.module'; 10 | 11 | import { AppComponent } from './app.component'; 12 | import { ShellComponent } from './home/shell.component'; 13 | import { MenuComponent } from './home/menu.component'; 14 | import { WelcomeComponent } from './home/welcome.component'; 15 | import { PageNotFoundComponent } from './home/page-not-found.component'; 16 | 17 | /* Feature Modules */ 18 | import { UserModule } from './user/user.module'; 19 | 20 | @NgModule({ 21 | imports: [ 22 | BrowserModule, 23 | HttpClientModule, 24 | HttpClientInMemoryWebApiModule.forRoot(ProductData), 25 | UserModule, 26 | AppRoutingModule 27 | ], 28 | declarations: [ 29 | AppComponent, 30 | ShellComponent, 31 | MenuComponent, 32 | WelcomeComponent, 33 | PageNotFoundComponent 34 | ], 35 | bootstrap: [AppComponent] 36 | }) 37 | export class AppModule { } 38 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/products/state/actions/product-api.actions.ts: -------------------------------------------------------------------------------- 1 | import { Product } from '../../product'; 2 | 3 | /* NgRx */ 4 | import { createAction, props } from '@ngrx/store'; 5 | 6 | export const loadProductsSuccess = createAction( 7 | '[Product API] Load Success', 8 | props<{ products: Product[] }>() 9 | ); 10 | 11 | export const loadProductsFailure = createAction( 12 | '[Product API] Load Fail', 13 | props<{ error: string }>() 14 | ); 15 | 16 | export const updateProductSuccess = createAction( 17 | '[Product API] Update Product Success', 18 | props<{ product: Product }>() 19 | ); 20 | 21 | export const updateProductFailure = createAction( 22 | '[Product API] Update Product Fail', 23 | props<{ error: string }>() 24 | ); 25 | 26 | export const createProductSuccess = createAction( 27 | '[Product API] Create Product Success', 28 | props<{ product: Product }>() 29 | ); 30 | 31 | export const createProductFailure = createAction( 32 | '[Product API] Create Product Fail', 33 | props<{ error: string }>() 34 | ); 35 | 36 | export const deleteProductSuccess = createAction( 37 | '[Product API] Delete Product Success', 38 | props<{ productId: number }>() 39 | ); 40 | 41 | export const deleteProductFailure = createAction( 42 | '[Product API] Delete Product Fail', 43 | props<{ error: string }>() 44 | ); 45 | -------------------------------------------------------------------------------- /APM-Demo1/README.md: -------------------------------------------------------------------------------- 1 | # APM-Demo1 2 | 3 | Demo of the most basic implementation of NgRx for a simple boolean flag. 4 | 5 | The goal of this demo is to introduce the parts of NgRx for a simple, easy to reason about, use case. 6 | 7 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 9.1.3. 8 | 9 | ## Development server 10 | 11 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. 12 | 13 | ## Code scaffolding 14 | 15 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. 16 | 17 | ## Build 18 | 19 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. 20 | 21 | ## Running unit tests 22 | 23 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 24 | 25 | ## Running end-to-end tests 26 | 27 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 28 | 29 | ## Further help 30 | 31 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). 32 | -------------------------------------------------------------------------------- /APM-Demo0/src/app/home/menu.component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /APM-Demo1/src/app/home/menu.component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /APM-Demo2/src/app/home/menu.component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/home/menu.component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /APM-Demo4/src/app/home/menu.component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/home/menu.component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /APM-Demo1/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { BrowserModule } from '@angular/platform-browser'; 3 | import { HttpClientModule } from '@angular/common/http'; 4 | 5 | // Imports for loading & configuring the in-memory web api 6 | import { HttpClientInMemoryWebApiModule } from 'angular-in-memory-web-api'; 7 | import { ProductData } from './products/product-data'; 8 | 9 | import { AppRoutingModule } from './app-routing.module'; 10 | 11 | import { AppComponent } from './app.component'; 12 | import { ShellComponent } from './home/shell.component'; 13 | import { MenuComponent } from './home/menu.component'; 14 | import { WelcomeComponent } from './home/welcome.component'; 15 | import { PageNotFoundComponent } from './home/page-not-found.component'; 16 | 17 | /* Feature Modules */ 18 | import { UserModule } from './user/user.module'; 19 | 20 | /* NgRx */ 21 | import { StoreModule } from '@ngrx/store'; 22 | 23 | @NgModule({ 24 | imports: [ 25 | BrowserModule, 26 | HttpClientModule, 27 | HttpClientInMemoryWebApiModule.forRoot(ProductData), 28 | UserModule, 29 | AppRoutingModule, 30 | StoreModule.forRoot({}) 31 | ], 32 | declarations: [ 33 | AppComponent, 34 | ShellComponent, 35 | MenuComponent, 36 | WelcomeComponent, 37 | PageNotFoundComponent 38 | ], 39 | bootstrap: [AppComponent] 40 | }) 41 | export class AppModule { } 42 | -------------------------------------------------------------------------------- /APM-Demo3/README.md: -------------------------------------------------------------------------------- 1 | # APM-Demo3 2 | 3 | Demo of using effects for retrieving and displaying data. 4 | NOTE: The create, update, and delete operations no longer work in this version of the demo since we moved only the retrieve to NgRx. 5 | The create, update, and delete are implemented with NgRx in Demo4. 6 | 7 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 9.1.3. 8 | 9 | ## Development server 10 | 11 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. 12 | 13 | ## Code scaffolding 14 | 15 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. 16 | 17 | ## Build 18 | 19 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. 20 | 21 | ## Running unit tests 22 | 23 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 24 | 25 | ## Running end-to-end tests 26 | 27 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 28 | 29 | ## Further help 30 | 31 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). 32 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/products/product-list/product-list.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | {{pageTitle}} 5 |
6 | 7 |
9 |
10 | 18 |
19 |
20 | 21 | 40 |
41 |
43 | Error: {{ errorMessage }} 44 |
-------------------------------------------------------------------------------- /APM-Demo0/src/app/products/product-list/product-list.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | {{pageTitle}} 5 |
6 | 7 |
9 |
10 | 18 |
19 |
20 | 21 | 40 |
41 |
43 | Error: {{ errorMessage }} 44 |
-------------------------------------------------------------------------------- /APM-Demo1/src/app/products/product-list/product-list.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | {{pageTitle}} 5 |
6 | 7 |
9 |
10 | 18 |
19 |
20 | 21 | 40 |
41 |
43 | Error: {{ errorMessage }} 44 |
-------------------------------------------------------------------------------- /APM-Demo2/src/app/products/product-list/product-list.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | {{pageTitle}} 5 |
6 | 7 |
9 |
10 | 18 |
19 |
20 | 21 | 40 |
41 |
43 | Error: {{ errorMessage }} 44 |
-------------------------------------------------------------------------------- /APM-Demo3/src/app/products/product-list/product-list.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | {{pageTitle}} 5 |
6 | 7 |
9 |
10 | 18 |
19 |
20 | 21 | 40 |
41 |
43 | Error: {{ errorMessage }} 44 |
-------------------------------------------------------------------------------- /APM-Demo4/src/app/products/product-list/product-list.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | {{pageTitle}} 5 |
6 | 7 |
9 |
10 | 18 |
19 |
20 | 21 | 40 |
41 |
43 | Error: {{ errorMessage }} 44 |
-------------------------------------------------------------------------------- /APM-Demo1/src/app/user/login.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { NgForm } from '@angular/forms'; 3 | import { Router } from '@angular/router'; 4 | 5 | import { AuthService } from './auth.service'; 6 | 7 | /* NgRx */ 8 | import { Store } from '@ngrx/store'; 9 | 10 | @Component({ 11 | templateUrl: './login.component.html', 12 | styleUrls: ['./login.component.css'] 13 | }) 14 | export class LoginComponent implements OnInit { 15 | pageTitle = 'Log In'; 16 | 17 | maskUserName: boolean; 18 | 19 | constructor(private store: Store, private authService: AuthService, private router: Router) { } 20 | 21 | ngOnInit(): void { 22 | // TODO: Unsubscribe 23 | this.store.select('users').subscribe( 24 | users => { 25 | if (users) { 26 | this.maskUserName = users.maskUserName; 27 | } 28 | }); 29 | } 30 | 31 | cancel(): void { 32 | this.router.navigate(['welcome']); 33 | } 34 | 35 | checkChanged(): void { 36 | this.store.dispatch( 37 | { type: '[User] Mask User Name' } 38 | ); 39 | } 40 | 41 | login(loginForm: NgForm): void { 42 | if (loginForm && loginForm.valid) { 43 | const userName = loginForm.form.value.userName; 44 | const password = loginForm.form.value.password; 45 | this.authService.login(userName, password); 46 | 47 | if (this.authService.redirectUrl) { 48 | this.router.navigateByUrl(this.authService.redirectUrl); 49 | } else { 50 | this.router.navigate(['/products']); 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /APM-Demo0/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "apm", 3 | "version": "0.0.0", 4 | "license": "MIT", 5 | "scripts": { 6 | "ng": "ng", 7 | "start": "ng serve -o", 8 | "build": "ng build", 9 | "test": "ng test", 10 | "lint": "ng lint", 11 | "e2e": "ng e2e" 12 | }, 13 | "private": true, 14 | "dependencies": { 15 | "@angular/animations": "~9.1.3", 16 | "@angular/common": "~9.1.3", 17 | "@angular/compiler": "~9.1.3", 18 | "@angular/core": "~9.1.3", 19 | "@angular/forms": "~9.1.3", 20 | "@angular/platform-browser": "~9.1.3", 21 | "@angular/platform-browser-dynamic": "~9.1.3", 22 | "@angular/router": "~9.1.3", 23 | "bootstrap": "^4.4.1", 24 | "rxjs": "~6.5.4", 25 | "tslib": "^1.10.0", 26 | "zone.js": "~0.10.2" 27 | }, 28 | "devDependencies": { 29 | "@angular-devkit/build-angular": "~0.901.3", 30 | "@angular/cli": "~9.1.3", 31 | "@angular/compiler-cli": "~9.1.3", 32 | "@angular/language-service": "~9.1.3", 33 | "@types/node": "^12.11.1", 34 | "@types/jasmine": "~3.5.0", 35 | "@types/jasminewd2": "~2.0.3", 36 | "angular-in-memory-web-api": "^0.9.0", 37 | "codelyzer": "^5.1.2", 38 | "jasmine-core": "~3.5.0", 39 | "jasmine-spec-reporter": "~4.2.1", 40 | "karma": "~5.0.0", 41 | "karma-chrome-launcher": "~3.1.0", 42 | "karma-coverage-istanbul-reporter": "~2.1.0", 43 | "karma-jasmine": "~3.0.1", 44 | "karma-jasmine-html-reporter": "^1.4.2", 45 | "protractor": "~5.4.3", 46 | "ts-node": "~8.3.0", 47 | "tslint": "~6.1.0", 48 | "typescript": "~3.8.3" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /APM-Demo0/src/app/products/product-list/product-list.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, OnDestroy } from '@angular/core'; 2 | 3 | import { Subscription } from 'rxjs'; 4 | 5 | import { Product } from '../product'; 6 | import { ProductService } from '../product.service'; 7 | 8 | @Component({ 9 | selector: 'pm-product-list', 10 | templateUrl: './product-list.component.html', 11 | styleUrls: ['./product-list.component.css'] 12 | }) 13 | export class ProductListComponent implements OnInit, OnDestroy { 14 | pageTitle = 'Products'; 15 | errorMessage: string; 16 | 17 | displayCode: boolean; 18 | 19 | products: Product[]; 20 | 21 | // Used to highlight the selected product in the list 22 | selectedProduct: Product | null; 23 | sub: Subscription; 24 | 25 | constructor(private productService: ProductService) { } 26 | 27 | ngOnInit(): void { 28 | this.sub = this.productService.selectedProductChanges$.subscribe( 29 | currentProduct => this.selectedProduct = currentProduct 30 | ); 31 | 32 | this.productService.getProducts().subscribe({ 33 | next: (products: Product[]) => this.products = products, 34 | error: err => this.errorMessage = err 35 | }); 36 | } 37 | 38 | ngOnDestroy(): void { 39 | this.sub.unsubscribe(); 40 | } 41 | 42 | checkChanged(): void { 43 | this.displayCode = !this.displayCode; 44 | } 45 | 46 | newProduct(): void { 47 | this.productService.changeSelectedProduct(this.productService.newProduct()); 48 | } 49 | 50 | productSelected(product: Product): void { 51 | this.productService.changeSelectedProduct(product); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /APM-Demo1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "apm", 3 | "version": "0.0.0", 4 | "license": "MIT", 5 | "scripts": { 6 | "ng": "ng", 7 | "start": "ng serve -o", 8 | "build": "ng build", 9 | "test": "ng test", 10 | "lint": "ng lint", 11 | "e2e": "ng e2e" 12 | }, 13 | "private": true, 14 | "dependencies": { 15 | "@angular/animations": "~9.1.3", 16 | "@angular/common": "~9.1.3", 17 | "@angular/compiler": "~9.1.3", 18 | "@angular/core": "~9.1.3", 19 | "@angular/forms": "~9.1.3", 20 | "@angular/platform-browser": "~9.1.3", 21 | "@angular/platform-browser-dynamic": "~9.1.3", 22 | "@angular/router": "~9.1.3", 23 | "@ngrx/store": "^9.1.0", 24 | "bootstrap": "^4.4.1", 25 | "rxjs": "~6.5.4", 26 | "tslib": "^1.10.0", 27 | "zone.js": "~0.10.2" 28 | }, 29 | "devDependencies": { 30 | "@angular-devkit/build-angular": "~0.901.3", 31 | "@angular/cli": "~9.1.3", 32 | "@angular/compiler-cli": "~9.1.3", 33 | "@angular/language-service": "~9.1.3", 34 | "@types/node": "^12.11.1", 35 | "@types/jasmine": "~3.5.0", 36 | "@types/jasminewd2": "~2.0.3", 37 | "angular-in-memory-web-api": "^0.9.0", 38 | "codelyzer": "^5.1.2", 39 | "jasmine-core": "~3.5.0", 40 | "jasmine-spec-reporter": "~4.2.1", 41 | "karma": "~5.0.0", 42 | "karma-chrome-launcher": "~3.1.0", 43 | "karma-coverage-istanbul-reporter": "~2.1.0", 44 | "karma-jasmine": "~3.0.1", 45 | "karma-jasmine-html-reporter": "^1.4.2", 46 | "protractor": "~5.4.3", 47 | "ts-node": "~8.3.0", 48 | "tslint": "~6.1.0", 49 | "typescript": "~3.8.3" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/user/login.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { NgForm } from '@angular/forms'; 3 | import { Router } from '@angular/router'; 4 | 5 | import { Observable } from 'rxjs'; 6 | 7 | import { AuthService } from './auth.service'; 8 | 9 | /* NgRx */ 10 | import { Store } from '@ngrx/store'; 11 | import { State } from '../state/app.state'; 12 | import { getMaskUserName } from './state/user.reducer'; 13 | import * as UserActions from './state/user.actions'; 14 | 15 | @Component({ 16 | templateUrl: './login.component.html', 17 | styleUrls: ['./login.component.css'] 18 | }) 19 | export class LoginComponent implements OnInit { 20 | pageTitle = 'Log In'; 21 | 22 | maskUserName$: Observable; 23 | 24 | constructor(private store: Store, private authService: AuthService, private router: Router) { } 25 | 26 | ngOnInit(): void { 27 | this.maskUserName$ = this.store.select(getMaskUserName); 28 | } 29 | 30 | cancel(): void { 31 | this.router.navigate(['welcome']); 32 | } 33 | 34 | checkChanged(): void { 35 | this.store.dispatch(UserActions.maskUserName()); 36 | } 37 | 38 | login(loginForm: NgForm): void { 39 | if (loginForm && loginForm.valid) { 40 | const userName = loginForm.form.value.userName; 41 | const password = loginForm.form.value.password; 42 | this.authService.login(userName, password); 43 | 44 | if (this.authService.redirectUrl) { 45 | this.router.navigateByUrl(this.authService.redirectUrl); 46 | } else { 47 | this.router.navigate(['/products']); 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /APM-Demo4/src/app/user/login.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { NgForm } from '@angular/forms'; 3 | import { Router } from '@angular/router'; 4 | 5 | import { Observable } from 'rxjs'; 6 | 7 | import { AuthService } from './auth.service'; 8 | 9 | /* NgRx */ 10 | import { Store } from '@ngrx/store'; 11 | import { State } from '../state/app.state'; 12 | import { getMaskUserName } from './state/user.reducer'; 13 | import * as UserActions from './state/user.actions'; 14 | 15 | @Component({ 16 | templateUrl: './login.component.html', 17 | styleUrls: ['./login.component.css'] 18 | }) 19 | export class LoginComponent implements OnInit { 20 | pageTitle = 'Log In'; 21 | 22 | maskUserName$: Observable; 23 | 24 | constructor(private store: Store, private authService: AuthService, private router: Router) { } 25 | 26 | ngOnInit(): void { 27 | this.maskUserName$ = this.store.select(getMaskUserName); 28 | } 29 | 30 | cancel(): void { 31 | this.router.navigate(['welcome']); 32 | } 33 | 34 | checkChanged(): void { 35 | this.store.dispatch(UserActions.maskUserName()); 36 | } 37 | 38 | login(loginForm: NgForm): void { 39 | if (loginForm && loginForm.valid) { 40 | const userName = loginForm.form.value.userName; 41 | const password = loginForm.form.value.password; 42 | this.authService.login(userName, password); 43 | 44 | if (this.authService.redirectUrl) { 45 | this.router.navigateByUrl(this.authService.redirectUrl); 46 | } else { 47 | this.router.navigate(['/products']); 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /APM-Demo5/src/app/user/login.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { NgForm } from '@angular/forms'; 3 | import { Router } from '@angular/router'; 4 | 5 | import { Observable } from 'rxjs'; 6 | 7 | import { AuthService } from './auth.service'; 8 | 9 | /* NgRx */ 10 | import { Store } from '@ngrx/store'; 11 | import { State } from '../state/app.state'; 12 | import { getMaskUserName } from './state/user.reducer'; 13 | import { UserPageActions } from './state/actions'; 14 | 15 | @Component({ 16 | templateUrl: './login.component.html', 17 | styleUrls: ['./login.component.css'] 18 | }) 19 | export class LoginComponent implements OnInit { 20 | pageTitle = 'Log In'; 21 | 22 | maskUserName$: Observable; 23 | 24 | constructor(private store: Store, private authService: AuthService, private router: Router) { } 25 | 26 | ngOnInit(): void { 27 | this.maskUserName$ = this.store.select(getMaskUserName); 28 | } 29 | 30 | cancel(): void { 31 | this.router.navigate(['welcome']); 32 | } 33 | 34 | checkChanged(): void { 35 | this.store.dispatch(UserPageActions.maskUserName()); 36 | } 37 | 38 | login(loginForm: NgForm): void { 39 | if (loginForm && loginForm.valid) { 40 | const userName = loginForm.form.value.userName; 41 | const password = loginForm.form.value.password; 42 | this.authService.login(userName, password); 43 | 44 | if (this.authService.redirectUrl) { 45 | this.router.navigateByUrl(this.authService.redirectUrl); 46 | } else { 47 | this.router.navigate(['/products']); 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /APM-Demo0/src/app/products/product-data.ts: -------------------------------------------------------------------------------- 1 | import { InMemoryDbService } from 'angular-in-memory-web-api'; 2 | 3 | import { Product } from './product'; 4 | 5 | export class ProductData implements InMemoryDbService { 6 | 7 | createDb() { 8 | const products: Product[] = [ 9 | { 10 | id: 1, 11 | productName: 'Leaf Rake', 12 | productCode: 'GDN-0011', 13 | description: 'Leaf rake with 48-inch wooden handle', 14 | starRating: 3.2 15 | }, 16 | { 17 | id: 2, 18 | productName: 'Garden Cart', 19 | productCode: 'GDN-0023', 20 | description: '15 gallon capacity rolling garden cart', 21 | starRating: 4.2 22 | }, 23 | { 24 | id: 5, 25 | productName: 'Hammer', 26 | productCode: 'TBX-0048', 27 | description: 'Curved claw steel hammer', 28 | starRating: 4.8 29 | }, 30 | { 31 | id: 8, 32 | productName: 'Saw', 33 | productCode: 'TBX-0022', 34 | description: '15-inch steel blade hand saw', 35 | starRating: 3.7 36 | }, 37 | { 38 | id: 10, 39 | productName: 'Video Game Controller', 40 | productCode: 'GMG-0042', 41 | description: 'Standard two-button video game controller', 42 | starRating: 4.6 43 | } 44 | ]; 45 | return { products }; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /APM-Demo1/src/app/products/product-data.ts: -------------------------------------------------------------------------------- 1 | import { InMemoryDbService } from 'angular-in-memory-web-api'; 2 | 3 | import { Product } from './product'; 4 | 5 | export class ProductData implements InMemoryDbService { 6 | 7 | createDb() { 8 | const products: Product[] = [ 9 | { 10 | id: 1, 11 | productName: 'Leaf Rake', 12 | productCode: 'GDN-0011', 13 | description: 'Leaf rake with 48-inch wooden handle', 14 | starRating: 3.2 15 | }, 16 | { 17 | id: 2, 18 | productName: 'Garden Cart', 19 | productCode: 'GDN-0023', 20 | description: '15 gallon capacity rolling garden cart', 21 | starRating: 4.2 22 | }, 23 | { 24 | id: 5, 25 | productName: 'Hammer', 26 | productCode: 'TBX-0048', 27 | description: 'Curved claw steel hammer', 28 | starRating: 4.8 29 | }, 30 | { 31 | id: 8, 32 | productName: 'Saw', 33 | productCode: 'TBX-0022', 34 | description: '15-inch steel blade hand saw', 35 | starRating: 3.7 36 | }, 37 | { 38 | id: 10, 39 | productName: 'Video Game Controller', 40 | productCode: 'GMG-0042', 41 | description: 'Standard two-button video game controller', 42 | starRating: 4.6 43 | } 44 | ]; 45 | return { products }; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /APM-Demo2/src/app/products/product-data.ts: -------------------------------------------------------------------------------- 1 | import { InMemoryDbService } from 'angular-in-memory-web-api'; 2 | 3 | import { Product } from './product'; 4 | 5 | export class ProductData implements InMemoryDbService { 6 | 7 | createDb() { 8 | const products: Product[] = [ 9 | { 10 | id: 1, 11 | productName: 'Leaf Rake', 12 | productCode: 'GDN-0011', 13 | description: 'Leaf rake with 48-inch wooden handle', 14 | starRating: 3.2 15 | }, 16 | { 17 | id: 2, 18 | productName: 'Garden Cart', 19 | productCode: 'GDN-0023', 20 | description: '15 gallon capacity rolling garden cart', 21 | starRating: 4.2 22 | }, 23 | { 24 | id: 5, 25 | productName: 'Hammer', 26 | productCode: 'TBX-0048', 27 | description: 'Curved claw steel hammer', 28 | starRating: 4.8 29 | }, 30 | { 31 | id: 8, 32 | productName: 'Saw', 33 | productCode: 'TBX-0022', 34 | description: '15-inch steel blade hand saw', 35 | starRating: 3.7 36 | }, 37 | { 38 | id: 10, 39 | productName: 'Video Game Controller', 40 | productCode: 'GMG-0042', 41 | description: 'Standard two-button video game controller', 42 | starRating: 4.6 43 | } 44 | ]; 45 | return { products }; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /APM-Demo3/src/app/products/product-data.ts: -------------------------------------------------------------------------------- 1 | import { InMemoryDbService } from 'angular-in-memory-web-api'; 2 | 3 | import { Product } from './product'; 4 | 5 | export class ProductData implements InMemoryDbService { 6 | 7 | createDb() { 8 | const products: Product[] = [ 9 | { 10 | id: 1, 11 | productName: 'Leaf Rake', 12 | productCode: 'GDN-0011', 13 | description: 'Leaf rake with 48-inch wooden handle', 14 | starRating: 3.2 15 | }, 16 | { 17 | id: 2, 18 | productName: 'Garden Cart', 19 | productCode: 'GDN-0023', 20 | description: '15 gallon capacity rolling garden cart', 21 | starRating: 4.2 22 | }, 23 | { 24 | id: 5, 25 | productName: 'Hammer', 26 | productCode: 'TBX-0048', 27 | description: 'Curved claw steel hammer', 28 | starRating: 4.8 29 | }, 30 | { 31 | id: 8, 32 | productName: 'Saw', 33 | productCode: 'TBX-0022', 34 | description: '15-inch steel blade hand saw', 35 | starRating: 3.7 36 | }, 37 | { 38 | id: 10, 39 | productName: 'Video Game Controller', 40 | productCode: 'GMG-0042', 41 | description: 'Standard two-button video game controller', 42 | starRating: 4.6 43 | } 44 | ]; 45 | return { products }; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /APM-Demo4/src/app/products/product-data.ts: -------------------------------------------------------------------------------- 1 | import { InMemoryDbService } from 'angular-in-memory-web-api'; 2 | 3 | import { Product } from './product'; 4 | 5 | export class ProductData implements InMemoryDbService { 6 | 7 | createDb() { 8 | const products: Product[] = [ 9 | { 10 | id: 1, 11 | productName: 'Leaf Rake', 12 | productCode: 'GDN-0011', 13 | description: 'Leaf rake with 48-inch wooden handle', 14 | starRating: 3.2 15 | }, 16 | { 17 | id: 2, 18 | productName: 'Garden Cart', 19 | productCode: 'GDN-0023', 20 | description: '15 gallon capacity rolling garden cart', 21 | starRating: 4.2 22 | }, 23 | { 24 | id: 5, 25 | productName: 'Hammer', 26 | productCode: 'TBX-0048', 27 | description: 'Curved claw steel hammer', 28 | starRating: 4.8 29 | }, 30 | { 31 | id: 8, 32 | productName: 'Saw', 33 | productCode: 'TBX-0022', 34 | description: '15-inch steel blade hand saw', 35 | starRating: 3.7 36 | }, 37 | { 38 | id: 10, 39 | productName: 'Video Game Controller', 40 | productCode: 'GMG-0042', 41 | description: 'Standard two-button video game controller', 42 | starRating: 4.6 43 | } 44 | ]; 45 | return { products }; 46 | } 47 | } 48 | --------------------------------------------------------------------------------