diff --git a/.circleci/config.ch9.yml b/.circleci/config.ch9.yml deleted file mode 100644 index 32637dd5..00000000 --- a/.circleci/config.ch9.yml +++ /dev/null @@ -1,83 +0,0 @@ -version: 2.1 -orbs: - coveralls: coveralls/coveralls@1.0.4 -jobs: - build: - docker: - - image: circleci/node:lts-browsers - working_directory: ~/repo - steps: - - checkout - - restore_cache: - keys: - - v1-dependencies-{{ checksum "package-lock.json" }} - # fallback to using the latest cache if no exact match is found - - v1-dependencies- - - - run: npm ci - - # force update the webdriver, so it runs with latest version of Chrome - - run: cd ./node_modules/protractor && npm i webdriver-manager@latest - - # because we use "npm ci" to install NPM dependencies - # we cache "~/.npm" folder - - save_cache: - paths: - - ~/.npm - key: v1-dependencies-{{ checksum "package-lock.json" }} - - - run: npm run style - - run: npm run lint - - run: npm run build:prod - - run: npm test -- --watch=false --code-coverage - - run: npm run e2e - - - store_test_results: - path: ./test_results - - store_artifacts: - path: ./coverage - - # upload coverage report to coveralls for readme badge support - # requires config.yml version 2.1 and orbs: coveralls: coveralls/coveralls@1.0.4 - # requires coveralls account and token named COVERALLS_REPO_TOKEN specific to repo to be stored in CircleCI - - coveralls/upload - - - run: - name: Tar & Gzip compiled app - command: tar zcf dist.tar.gz dist/lemon-mart - - store_artifacts: - path: dist.tar.gz - - - run: - name: Move compiled app to workspace - command: | - set -exu - mkdir -p /tmp/workspace/dist - mv dist/lemon-mart /tmp/workspace/dist/ - - persist_to_workspace: - root: /tmp/workspace - paths: - - dist/lemon-mart - deploy: - docker: - - image: circleci/node:lts - working_directory: ~/repo - steps: - - attach_workspace: - at: /tmp/workspace - - run: npx now --token $NOW_TOKEN --platform-version 2 --prod /tmp/workspace/dist/lemon-mart --confirm -workflows: - version: 2 - build-test-and-approval-deploy: - jobs: - - build - - hold: - type: approval - requires: - - build - filters: - branches: - only: master - - deploy: - requires: - - hold diff --git a/.circleci/config.docker-integration.yml b/.circleci/config.docker-integration.yml deleted file mode 100644 index 2b8d6981..00000000 --- a/.circleci/config.docker-integration.yml +++ /dev/null @@ -1,61 +0,0 @@ -version: 2.1 -orbs: - aws-cli: circleci/aws-cli@0.1.19 -jobs: - build: - docker: - - image: circleci/node:lts - working_directory: ~/repo - steps: - - checkout - - setup_remote_docker - - run: - name: Execute Pipeline (Build Source -> Test -> Build Web Server) - command: | - docker build -f integration.Dockerfile . -t lemon-mart:$CIRCLE_BRANCH - mkdir -p docker-cache - docker save lemon-mart:$CIRCLE_BRANCH | gzip > docker-cache/built-image.tar.gz - - save_cache: - key: built-image-{{ .BuildNum }} - paths: - - docker-cache - - store_artifacts: - path: docker-cache/built-image.tar.gz - destination: built-image.tar.gz - - deploy: - executor: aws-cli/default - steps: - - restore_cache: - keys: - - built-image-{{ .BuildNum }} - - built-image - - setup_remote_docker - - run: - name: Sign into AWS ecr - command: $(aws ecr get-login --no-include-email --region us-east-1) - - run: - name: Push it to ECR - command: | - docker load < docker-cache/built-image.tar.gz - docker tag my_app:$CIRCLE_BRANCH $AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/lemon-mart:$CIRCLE_BRANCH - docker push $AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/lemon-mart:$CIRCLE_BRANCH - - run: echo 'do deployment here' - -workflows: - version: 2 - build-and-deploy: - jobs: - - build - - hold: - type: approval - requires: - - build - - deploy: - requires: - - hold -# Deployment Integrations https://circleci.com/docs/2.0/deployment-integrations -# For Docker Hub deploy see https://circleci.com/docs/2.0/building-docker-images/ -# For AWS ECS deploy see https://circleci.com/blog/how-to-build-a-docker-image-on-circleci-2-0/ -# For Heroku see https://devcenter.heroku.com/articles/container-registry-and-runtime#pushing-an-image-s -# For cache optimization read https://medium.com/@gajus/making-docker-in-docker-builds-x2-faster-using-docker-cache-from-option-c01febd8ef84 diff --git a/.circleci/config.yml b/.circleci/config.yml index df2c3267..2f98565c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,213 +1,78 @@ version: 2.1 orbs: - coveralls: coveralls/coveralls@1.0.4 - cypress: cypress-io/cypress@1 -commands: - install: - description: 'Install project dependencies' - parameters: - warm-cache: - type: boolean - default: false + aws-cli: circleci/aws-cli@1.0.0 +jobs: + build: + docker: + - image: circleci/node:lts + working_directory: ~/repo steps: - checkout - - restore_cache: - keys: - - node_modules-{{ checksum "package-lock.json" }} - - when: - condition: << parameters.warm-cache >> - steps: - - run: npm install - # Pre-build Angular modules - - run: npx ngcc --properties es2015 --async false # async false is temp CI build fix - # force update the webdriver, so it runs with latest version of Chrome - - run: cd ./node_modules/protractor && npm i webdriver-manager@latest - - save_cache: - key: node_modules-{{ checksum "package-lock.json" }} - paths: - - node_modules - - ~/.cache/Cypress - lint: - description: 'Check for code style and linting errors' - steps: - - run: npm run style - - run: npm run lint - build_and_test: - description: 'Build command that accepts Angular project name as parameter' - parameters: - project: - type: string - default: 'lemon-mart' - run-tests: - type: boolean - default: true - steps: - - run: npx ng build --prod --project << parameters.project >> - - when: - condition: << parameters.run-tests >> - steps: - - run: npx ng test --code-coverage --watch=false --project << parameters.project >> - - run: npx ng e2e << parameters.project >> - store: - description: 'Stores build_and_test artifacts' - parameters: - project: - type: string - default: 'lemon-mart' - steps: + - setup_remote_docker - run: - name: Run Cypress tests - command: 'npx cypress run --record' - - - store_test_results: - path: ./test_results - - store_artifacts: - path: ./coverage - - # upload coverage report to coveralls for readme badge support - # requires config.yml version 2.1 and orbs: coveralls: coveralls/coveralls@1.0.4 - # requires coveralls account and token named COVERALLS_REPO_TOKEN specific to repo to be stored in CircleCI - - coveralls/upload + name: Execute Pipeline (Build Source -> Test -> Build Web Server) + command: | + docker build -f integration.Dockerfile . -t lemon-mart:$CIRCLE_BRANCH + mkdir -p docker-cache + docker save lemon-mart:$CIRCLE_BRANCH | gzip > docker-cache/built-image.tar.gz - - run: - name: Tar & Gzip compiled app - command: tar zcf dist.tar.gz dist/<< parameters.project >> - store_artifacts: - path: dist.tar.gz - + path: docker-cache/built-image.tar.gz + destination: built-image.tar.gz - run: name: Move compiled app to workspace command: | set -exu - mkdir -p /tmp/workspace/dist - mv dist/<< parameters.project >> /tmp/workspace/dist/ + mkdir -p /tmp/workspace + mv docker-cache/built-image.tar.gz /tmp/workspace/ - persist_to_workspace: root: /tmp/workspace paths: - - dist/<< parameters.project >> - deploy_now: - description: 'Deploys project to Zeit Now --> https://now.sh' - parameters: - project: - type: string - default: 'lemon-mart' - steps: - - attach_workspace: - at: /tmp/workspace - - run: npx now --token $NOW_TOKEN --platform-version 2 --prod /tmp/workspace/dist/<< parameters.project >> --confirm -jobs: - initialize: - docker: - - image: circleci/node:lts-browsers - working_directory: ~/repo - steps: - - install: - warm-cache: true - default: - docker: - - image: circleci/node:lts-browsers - working_directory: ~/repo - steps: - - install - - lint - - build_and_test - - store + - . deploy: - docker: - - image: circleci/node:lts + executor: aws-cli/default working_directory: ~/repo steps: - - deploy_now - - ch7: # this job is only here to verify sample code from the book, remove it in your own projects - docker: - - image: circleci/node:lts-browsers - working_directory: ~/repo - steps: - - install - - build_and_test: - project: 'ch7' - ch8: # this job is only here to verify sample code from the book, remove it in your own projects - docker: - - image: circleci/node:lts-browsers - working_directory: ~/repo - steps: - - install - - build_and_test: - project: 'ch8' - ch10: # this job is only here to verify sample code from the book, remove it in your own projects - docker: - - image: circleci/node:lts-browsers - working_directory: ~/repo - steps: - - install - - build_and_test: - project: 'ch10' - ch11: # this job is only here to verify sample code from the book, remove it in your own projects - docker: - - image: circleci/node:lts-browsers - working_directory: ~/repo - steps: - - install - - build_and_test: - project: 'ch11' - ch12: # this job is only here to verify sample code from the book, remove it in your own projects - docker: - - image: circleci/node:lts-browsers - working_directory: ~/repo - steps: - - install - - build_and_test: - project: 'ch12' - ch13: # this job is only here to verify sample code from the book, remove it in your own projects - docker: - - image: circleci/node:lts-browsers - working_directory: ~/repo - steps: - - install - - build_and_test: - project: 'ch13' - ch14: # this job is only here to verify sample code from the book, remove it in your own projects - docker: - - image: circleci/node:lts-browsers - working_directory: ~/repo - steps: - - install - - build_and_test: - project: 'ch14' + - attach_workspace: + at: /tmp/workspace + - checkout + - setup_remote_docker + - aws-cli/setup + - run: npm ci + - run: + name: Restore .env files + command: | + set +H + DOT_ENV=AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID\\nAWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY + echo -e $DOT_ENV > .env + - run: + name: Sign Docker into AWS ECR + command: | + aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/lemon-mart + - run: + name: Push it to ECR + command: | + docker load < /tmp/workspace/built-image.tar.gz + ECR_URI=$AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/lemon-mart + docker image tag lemon-mart:$CIRCLE_BRANCH $ECR_URI:$CIRCLE_BRANCH + docker image tag $ECR_URI:$CIRCLE_BRANCH $ECR_URI:latest + docker image push $ECR_URI:$CIRCLE_BRANCH + docker image push $ECR_URI:latest + - run: + name: Deploy + command: npm run aws:deploy workflows: version: 2 - build-test-and-approval-deploy: + build-and-deploy: jobs: - - initialize - - default: - requires: - - initialize - - ch7: # this job is only here to verify sample code from the book, remove it in your own projects - requires: - - initialize - - ch8: # this job is only here to verify sample code from the book, remove it in your own projects - requires: - - initialize - - ch10: # this job is only here to verify sample code from the book, remove it in your own projects - requires: - - initialize - - ch11: # this job is only here to verify sample code from the book, remove it in your own projects - requires: - - initialize - - ch12: # this job is only here to verify sample code from the book, remove it in your own projects - requires: - - initialize - - ch13: # this job is only here to verify sample code from the book, remove it in your own projects - requires: - - initialize - - ch14: # this job is only here to verify sample code from the book, remove it in your own projects - requires: - - initialize + - build - deploy: + context: aws requires: - - default - filters: - branches: - only: master + - build +# Deployment Integrations https://circleci.com/docs/2.0/deployment-integrations +# For Docker Hub deploy see https://circleci.com/docs/2.0/building-docker-images/ +# For AWS ECS deploy see https://circleci.com/blog/how-to-build-a-docker-image-on-circleci-2-0/ +# For Heroku see https://devcenter.heroku.com/articles/container-registry-and-runtime#pushing-an-image-s +# For cache optimization read https://medium.com/@gajus/making-docker-in-docker-builds-x2-faster-using-docker-cache-from-option-c01febd8ef84 diff --git a/angular.json b/angular.json index 895f6ffc..0e0e63c6 100644 --- a/angular.json +++ b/angular.json @@ -831,42 +831,42 @@ } } }, - "ch14": { + "ch13": { "projectType": "application", "schematics": {}, - "root": "projects/ch14", - "sourceRoot": "projects/ch14/src", + "root": "projects/ch13", + "sourceRoot": "projects/ch13/src", "prefix": "app", "architect": { "build": { "builder": "@angular-devkit/build-angular:browser", "options": { - "outputPath": "dist/ch14", - "index": "projects/ch14/src/index.html", - "main": "projects/ch14/src/main.ts", - "polyfills": "projects/ch14/src/polyfills.ts", - "tsConfig": "projects/ch14/tsconfig.app.json", + "outputPath": "dist/ch13", + "index": "projects/ch13/src/index.html", + "main": "projects/ch13/src/main.ts", + "polyfills": "projects/ch13/src/polyfills.ts", + "tsConfig": "projects/ch13/tsconfig.app.json", "aot": true, "assets": [ - "projects/ch14/src/favicon.ico", - "projects/ch14/src/assets", - "projects/ch14/src/android-chrome-192x192.png", - "projects/ch14/src/favicon-16x16.png", - "projects/ch14/src/mstile-310x150.png", - "projects/ch14/src/android-chrome-512x512.png", - "projects/ch14/src/favicon-32x32.png", - "projects/ch14/src/mstile-310x310.png", - "projects/ch14/src/apple-touch-icon.png", - "projects/ch14/src/manifest.json", - "projects/ch14/src/mstile-70x70.png", - "projects/ch14/src/browserconfig.xml", - "projects/ch14/src/mstile-144x144.png", - "projects/ch14/src/safari-pinned-tab.svg", - "projects/ch14/src/mstile-150x150.png" + "projects/ch13/src/favicon.ico", + "projects/ch13/src/assets", + "projects/ch13/src/android-chrome-192x192.png", + "projects/ch13/src/favicon-16x16.png", + "projects/ch13/src/mstile-310x150.png", + "projects/ch13/src/android-chrome-512x512.png", + "projects/ch13/src/favicon-32x32.png", + "projects/ch13/src/mstile-310x310.png", + "projects/ch13/src/apple-touch-icon.png", + "projects/ch13/src/manifest.json", + "projects/ch13/src/mstile-70x70.png", + "projects/ch13/src/browserconfig.xml", + "projects/ch13/src/mstile-144x144.png", + "projects/ch13/src/safari-pinned-tab.svg", + "projects/ch13/src/mstile-150x150.png" ], "styles": [ - "projects/ch14/src/lemonmart-theme.scss", - "projects/ch14/src/styles.css" + "projects/ch13/src/lemonmart-theme.scss", + "projects/ch13/src/styles.css" ], "scripts": [] }, @@ -874,8 +874,8 @@ "production": { "fileReplacements": [ { - "replace": "projects/ch14/src/environments/environment.ts", - "with": "projects/ch14/src/environments/environment.prod.ts" + "replace": "projects/ch13/src/environments/environment.ts", + "with": "projects/ch13/src/environments/environment.prod.ts" } ], "optimization": true, @@ -904,31 +904,31 @@ "serve": { "builder": "@angular-devkit/build-angular:dev-server", "options": { - "browserTarget": "ch14:build" + "browserTarget": "ch13:build" }, "configurations": { "production": { - "browserTarget": "ch14:build:production" + "browserTarget": "ch13:build:production" } } }, "extract-i18n": { "builder": "@angular-devkit/build-angular:extract-i18n", "options": { - "browserTarget": "ch14:build" + "browserTarget": "ch13:build" } }, "test": { "builder": "@angular-devkit/build-angular:karma", "options": { - "main": "projects/ch14/src/test.ts", - "polyfills": "projects/ch14/src/polyfills.ts", - "tsConfig": "projects/ch14/tsconfig.spec.json", - "karmaConfig": "projects/ch14/karma.conf.js", - "assets": ["projects/ch14/src/favicon.ico", "projects/ch14/src/assets"], + "main": "projects/ch13/src/test.ts", + "polyfills": "projects/ch13/src/polyfills.ts", + "tsConfig": "projects/ch13/tsconfig.spec.json", + "karmaConfig": "projects/ch13/karma.conf.js", + "assets": ["projects/ch13/src/favicon.ico", "projects/ch13/src/assets"], "styles": [ - "projects/ch14/src/lemonmart-theme.scss", - "projects/ch14/src/styles.css" + "projects/ch13/src/lemonmart-theme.scss", + "projects/ch13/src/styles.css" ], "scripts": [] } @@ -937,9 +937,9 @@ "builder": "@angular-devkit/build-angular:tslint", "options": { "tsConfig": [ - "projects/ch14/tsconfig.app.json", - "projects/ch14/tsconfig.spec.json", - "projects/ch14/e2e/tsconfig.json" + "projects/ch13/tsconfig.app.json", + "projects/ch13/tsconfig.spec.json", + "projects/ch13/e2e/tsconfig.json" ], "exclude": ["**/node_modules/**"] } @@ -947,12 +947,12 @@ "e2e": { "builder": "@angular-devkit/build-angular:protractor", "options": { - "protractorConfig": "projects/ch14/e2e/protractor.conf.js", - "devServerTarget": "ch14:serve" + "protractorConfig": "projects/ch13/e2e/protractor.conf.js", + "devServerTarget": "ch13:serve" }, "configurations": { "production": { - "devServerTarget": "ch14:serve:production" + "devServerTarget": "ch13:serve:production" } } } diff --git a/projects/ch11/src/polyfills.ts b/projects/ch11/src/polyfills.ts index 6b4dcb84..21e4e418 100644 --- a/projects/ch11/src/polyfills.ts +++ b/projects/ch11/src/polyfills.ts @@ -55,6 +55,7 @@ /*************************************************************************************************** * Zone JS is required by default for Angular itself. */ + import 'zone.js/dist/zone' // Included with Angular CLI. diff --git a/projects/ch12/src/polyfills.ts b/projects/ch12/src/polyfills.ts index 6b4dcb84..21e4e418 100644 --- a/projects/ch12/src/polyfills.ts +++ b/projects/ch12/src/polyfills.ts @@ -55,6 +55,7 @@ /*************************************************************************************************** * Zone JS is required by default for Angular itself. */ + import 'zone.js/dist/zone' // Included with Angular CLI. diff --git a/projects/ch13/src/app/app-material.module.ts b/projects/ch13/src/app/app-material.module.ts index 692b3c7b..babb9dff 100644 --- a/projects/ch13/src/app/app-material.module.ts +++ b/projects/ch13/src/app/app-material.module.ts @@ -1,3 +1,4 @@ +import { NgModule } from '@angular/core' import { MatButtonModule } from '@angular/material/button' import { MatCardModule } from '@angular/material/card' import { MatDialogModule } from '@angular/material/dialog' @@ -9,7 +10,6 @@ import { MatSidenavModule } from '@angular/material/sidenav' import { MatSnackBarModule } from '@angular/material/snack-bar' import { MatToolbarModule } from '@angular/material/toolbar' import { MatTooltipModule } from '@angular/material/tooltip' -import { NgModule } from '@angular/core' const modules = [ MatButtonModule, diff --git a/projects/ch13/src/app/app.module.ts b/projects/ch13/src/app/app.module.ts index 134422fb..db9a8b63 100644 --- a/projects/ch13/src/app/app.module.ts +++ b/projects/ch13/src/app/app.module.ts @@ -1,26 +1,23 @@ -import { AngularFireAuth, AngularFireAuthModule } from '@angular/fire/auth' import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http' +import { NgModule } from '@angular/core' +import { FlexLayoutModule } from '@angular/flex-layout' +import { ReactiveFormsModule } from '@angular/forms' +import { BrowserModule } from '@angular/platform-browser' +import { BrowserAnimationsModule } from '@angular/platform-browser/animations' import { IConfig, NgxMaskModule } from 'ngx-mask' -import { AppComponent } from './app.component' import { AppMaterialModule } from './app-material.module' import { AppRoutingModule } from './app-routing.module' +import { AppComponent } from './app.component' import { AuthHttpInterceptor } from './auth/auth-http-interceptor' -import { AuthService } from './auth/auth.service' -import { BrowserAnimationsModule } from '@angular/platform-browser/animations' -import { BrowserModule } from '@angular/platform-browser' import { CustomAuthService } from './auth/auth.custom.service' -import { EffectsModule } from '@ngrx/effects' -import { FieldErrorModule } from './user-controls/field-error/field-error.module' -import { FlexLayoutModule } from '@angular/flex-layout' +import { AuthService } from './auth/auth.service' +import { SimpleDialogComponent } from './common/simple-dialog.component' import { HomeComponent } from './home/home.component' import { LoginComponent } from './login/login.component' import { NavigationMenuComponent } from './navigation-menu/navigation-menu.component' -import { NgModule } from '@angular/core' import { PageNotFoundComponent } from './page-not-found/page-not-found.component' -import { ReactiveFormsModule } from '@angular/forms' -import { SimpleDialogComponent } from './common/simple-dialog.component' -import { StoreDevtoolsModule } from '@ngrx/store-devtools' +import { FieldErrorModule } from './user-controls/field-error/field-error.module' export const options: Partial | (() => Partial) = { showMaskTyped: true, diff --git a/projects/ch13/src/app/auth/auth.factory.ts b/projects/ch13/src/app/auth/auth.factory.ts deleted file mode 100644 index 34584772..00000000 --- a/projects/ch13/src/app/auth/auth.factory.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { HttpClient } from '@angular/common/http' -import { AngularFireAuth } from '@angular/fire/auth' - -import { environment } from '../../environments/environment' -import { CustomAuthService } from './auth.custom.service' -import { AuthMode } from './auth.enum' -import { FirebaseAuthService } from './auth.firebase.service' -import { InMemoryAuthService } from './auth.inmemory.service' - -export function authFactory(afAuth: AngularFireAuth, httpClient: HttpClient) { - switch (environment.authMode) { - case AuthMode.InMemory: - return new InMemoryAuthService() - case AuthMode.Firebase: - return new FirebaseAuthService(afAuth) - case AuthMode.CustomServer: - return new CustomAuthService(httpClient) - } -} diff --git a/projects/ch13/src/app/login/login.component.ts b/projects/ch13/src/app/login/login.component.ts index 3cd6b897..3b12b427 100644 --- a/projects/ch13/src/app/login/login.component.ts +++ b/projects/ch13/src/app/login/login.component.ts @@ -1,14 +1,14 @@ -import { ActivatedRoute, Router } from '@angular/router' import { Component, OnDestroy, OnInit } from '@angular/core' -import { EmailValidation, PasswordValidation } from '../common/validations' import { FormBuilder, FormGroup } from '@angular/forms' +import { ActivatedRoute, Router } from '@angular/router' +import { combineLatest } from 'rxjs' import { catchError, filter, tap } from 'rxjs/operators' +import { SubSink } from 'subsink' -import { AuthService } from '../auth/auth.service' import { Role } from '../auth/auth.enum' -import { SubSink } from 'subsink' +import { AuthService } from '../auth/auth.service' import { UiService } from '../common/ui.service' -import { combineLatest } from 'rxjs' +import { EmailValidation, PasswordValidation } from '../common/validations' @Component({ selector: 'app-login', diff --git a/projects/ch13/src/app/manager/manager.module.ts b/projects/ch13/src/app/manager/manager.module.ts index 66effda3..deb9c47e 100644 --- a/projects/ch13/src/app/manager/manager.module.ts +++ b/projects/ch13/src/app/manager/manager.module.ts @@ -1,18 +1,19 @@ -import { AppMaterialModule } from '../app-material.module' -import { AuthGuard } from '../auth/auth-guard.service' import { CommonModule } from '@angular/common' +import { NgModule } from '@angular/core' import { FlexLayoutModule } from '@angular/flex-layout' -import { ManagerComponent } from './manager.component' +import { FormsModule, ReactiveFormsModule } from '@angular/forms' + +import { AppMaterialModule } from '../app-material.module' +import { AuthGuard } from '../auth/auth-guard.service' +import { SharedComponentsModule } from '../shared-components.module' +import { UserResolve } from '../user/user/user.resolve' +import { UserService } from '../user/user/user.service' import { ManagerHomeComponent } from './manager-home/manager-home.component' import { ManagerMaterialModule } from './manager-material.module' import { ManagerRoutingModule } from './manager-routing.module' -import { NgModule } from '@angular/core' -import { ReactiveFormsModule } from '@angular/forms' +import { ManagerComponent } from './manager.component' import { ReceiptLookupComponent } from './receipt-lookup/receipt-lookup.component' -import { SharedComponentsModule } from '../shared-components.module' import { UserManagementComponent } from './user-management/user-management.component' -import { UserResolve } from '../user/user/user.resolve' -import { UserService } from '../user/user/user.service' import { UserTableComponent } from './user-table/user-table.component' @NgModule({ @@ -22,6 +23,7 @@ import { UserTableComponent } from './user-table/user-table.component' SharedComponentsModule, AppMaterialModule, ManagerMaterialModule, + FormsModule, ReactiveFormsModule, FlexLayoutModule, ], diff --git a/projects/ch13/src/app/manager/user-table/user-table.component.spec.ts b/projects/ch13/src/app/manager/user-table/user-table.component.spec.ts index 4988387f..7c0993ad 100644 --- a/projects/ch13/src/app/manager/user-table/user-table.component.spec.ts +++ b/projects/ch13/src/app/manager/user-table/user-table.component.spec.ts @@ -1,12 +1,11 @@ import { ComponentFixture, TestBed, async } from '@angular/core/testing' -import { commonTestingModules, commonTestingProviders } from '../../common/common.testing' - -import { EffectsModule } from '@ngrx/effects' import { FormsModule } from '@angular/forms' -import { ManagerMaterialModule } from '../manager-material.module' +import { of } from 'rxjs' + +import { commonTestingModules, commonTestingProviders } from '../../common/common.testing' import { User } from '../../user/user/user' +import { ManagerMaterialModule } from '../manager-material.module' import { UserTableComponent } from './user-table.component' -import { of } from 'rxjs' describe('UserTableComponent', () => { let component: UserTableComponent diff --git a/projects/ch13/src/app/manager/user-table/user-table.component.ts b/projects/ch13/src/app/manager/user-table/user-table.component.ts index 711640f1..6e07da23 100644 --- a/projects/ch13/src/app/manager/user-table/user-table.component.ts +++ b/projects/ch13/src/app/manager/user-table/user-table.component.ts @@ -1,14 +1,14 @@ import { AfterViewInit, Component, OnDestroy, ViewChild } from '@angular/core' -import { BehaviorSubject, Observable, Subject, merge, of } from 'rxjs' -import { IUsers, UserService } from '../../user/user/user.service' +import { FormControl } from '@angular/forms' +import { MatPaginator } from '@angular/material/paginator' import { MatSort, SortDirection } from '@angular/material/sort' +import { BehaviorSubject, Observable, Subject, merge, of } from 'rxjs' import { catchError, debounceTime, map, startWith, switchMap } from 'rxjs/operators' +import { SubSink } from 'subsink' -import { FormControl } from '@angular/forms' -import { IUser } from '../../user/user/user' -import { MatPaginator } from '@angular/material/paginator' import { OptionalTextValidation } from '../../common/validations' -import { SubSink } from 'subsink' +import { IUser } from '../../user/user/user' +import { IUsers, UserService } from '../../user/user/user.service' @Component({ selector: 'app-user-table', diff --git a/projects/ch13/src/polyfills.ts b/projects/ch13/src/polyfills.ts index 6b4dcb84..21e4e418 100644 --- a/projects/ch13/src/polyfills.ts +++ b/projects/ch13/src/polyfills.ts @@ -55,6 +55,7 @@ /*************************************************************************************************** * Zone JS is required by default for Angular itself. */ + import 'zone.js/dist/zone' // Included with Angular CLI.