├── .DS_Store ├── .gitignore ├── angular-components ├── .editorconfig ├── .gitignore ├── README.md ├── angular.json ├── browserslist ├── e2e │ ├── protractor.conf.js │ ├── src │ │ ├── app.e2e-spec.ts │ │ └── app.po.ts │ └── tsconfig.json ├── karma.conf.js ├── package-lock.json ├── package.json ├── src │ ├── app │ │ ├── app.component.html │ │ ├── app.component.scss │ │ ├── app.component.spec.ts │ │ ├── app.component.ts │ │ ├── app.module.ts │ │ ├── components │ │ │ ├── bindings-example │ │ │ │ ├── bindings-example.component.html │ │ │ │ ├── bindings-example.component.scss │ │ │ │ ├── bindings-example.component.spec.ts │ │ │ │ └── bindings-example.component.ts │ │ │ ├── content-example │ │ │ │ ├── content-example.component.html │ │ │ │ ├── content-example.component.scss │ │ │ │ ├── content-example.component.spec.ts │ │ │ │ ├── content-example.component.ts │ │ │ │ └── content-inner │ │ │ │ │ ├── content-inner.component.html │ │ │ │ │ ├── content-inner.component.scss │ │ │ │ │ ├── content-inner.component.spec.ts │ │ │ │ │ └── content-inner.component.ts │ │ │ ├── feed-decomposition │ │ │ │ ├── feed-decomposition.component.html │ │ │ │ ├── feed-decomposition.component.scss │ │ │ │ ├── feed-decomposition.component.spec.ts │ │ │ │ ├── feed-decomposition.component.ts │ │ │ │ └── post │ │ │ │ │ ├── post.component.html │ │ │ │ │ ├── post.component.scss │ │ │ │ │ ├── post.component.spec.ts │ │ │ │ │ └── post.component.ts │ │ │ ├── feed-simple │ │ │ │ ├── feed-simple.component.html │ │ │ │ ├── feed-simple.component.scss │ │ │ │ ├── feed-simple.component.spec.ts │ │ │ │ └── feed-simple.component.ts │ │ │ ├── lifecycle-hooks │ │ │ │ ├── inner │ │ │ │ │ ├── inner.component.html │ │ │ │ │ ├── inner.component.scss │ │ │ │ │ ├── inner.component.spec.ts │ │ │ │ │ └── inner.component.ts │ │ │ │ ├── lifecycle-hooks.component.html │ │ │ │ ├── lifecycle-hooks.component.scss │ │ │ │ ├── lifecycle-hooks.component.spec.ts │ │ │ │ └── lifecycle-hooks.component.ts │ │ │ └── template-syntax │ │ │ │ ├── inner │ │ │ │ ├── inner.component.html │ │ │ │ ├── inner.component.scss │ │ │ │ ├── inner.component.spec.ts │ │ │ │ └── inner.component.ts │ │ │ │ ├── template-syntax.component.html │ │ │ │ ├── template-syntax.component.scss │ │ │ │ ├── template-syntax.component.spec.ts │ │ │ │ └── template-syntax.component.ts │ │ └── models │ │ │ └── post.ts │ ├── assets │ │ ├── .gitkeep │ │ └── angular.png │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── favicon.ico │ ├── index.html │ ├── main.ts │ ├── polyfills.ts │ ├── styles.scss │ └── test.ts ├── tsconfig.app.json ├── tsconfig.json ├── tsconfig.spec.json └── tslint.json ├── angular-directives-pipes ├── .editorconfig ├── .gitignore ├── README.md ├── angular.json ├── browserslist ├── e2e │ ├── protractor.conf.js │ ├── src │ │ ├── app.e2e-spec.ts │ │ └── app.po.ts │ └── tsconfig.json ├── karma.conf.js ├── package-lock.json ├── package.json ├── src │ ├── app │ │ ├── app.component.html │ │ ├── app.component.scss │ │ ├── app.component.spec.ts │ │ ├── app.component.ts │ │ ├── app.module.ts │ │ └── components │ │ │ ├── attribute-directives │ │ │ ├── attribute-directives.component.html │ │ │ ├── attribute-directives.component.scss │ │ │ ├── attribute-directives.component.spec.ts │ │ │ ├── attribute-directives.component.ts │ │ │ ├── components │ │ │ │ └── element-with-props-to-override │ │ │ │ │ ├── element-with-props-to-override.component.html │ │ │ │ │ ├── element-with-props-to-override.component.scss │ │ │ │ │ ├── element-with-props-to-override.component.spec.ts │ │ │ │ │ └── element-with-props-to-override.component.ts │ │ │ └── directives │ │ │ │ ├── highlight-custom-color-binding.directive.spec.ts │ │ │ │ ├── highlight-custom-color-binding.directive.ts │ │ │ │ ├── highlight-on-hover.directive.spec.ts │ │ │ │ ├── highlight-on-hover.directive.ts │ │ │ │ ├── highlight-with-custom-color.directive.spec.ts │ │ │ │ ├── highlight-with-custom-color.directive.ts │ │ │ │ ├── highlight.directive.spec.ts │ │ │ │ └── highlight.directive.ts │ │ │ ├── pipes-examples │ │ │ ├── components │ │ │ │ ├── async-pipe │ │ │ │ │ ├── async-pipe.component.html │ │ │ │ │ ├── async-pipe.component.scss │ │ │ │ │ └── async-pipe.component.ts │ │ │ │ ├── pure-vs-impure │ │ │ │ │ ├── pure-vs-impure.component.html │ │ │ │ │ ├── pure-vs-impure.component.scss │ │ │ │ │ └── pure-vs-impure.component.ts │ │ │ │ └── tasks-example │ │ │ │ │ ├── tasks-example.component.html │ │ │ │ │ ├── tasks-example.component.scss │ │ │ │ │ └── tasks-example.component.ts │ │ │ ├── models │ │ │ │ └── task.ts │ │ │ ├── pipes-examples.component.html │ │ │ ├── pipes-examples.component.scss │ │ │ ├── pipes-examples.component.spec.ts │ │ │ ├── pipes-examples.component.ts │ │ │ └── pipes │ │ │ │ ├── is-done-impure.pipe.ts │ │ │ │ ├── is-done-pure.pipe.ts │ │ │ │ ├── please.pipe.ts │ │ │ │ └── status.pipe.ts │ │ │ └── structural-directives │ │ │ ├── directives │ │ │ ├── unless.directive.spec.ts │ │ │ └── unless.directive.ts │ │ │ ├── structural-directives.component.html │ │ │ ├── structural-directives.component.scss │ │ │ ├── structural-directives.component.spec.ts │ │ │ └── structural-directives.component.ts │ ├── assets │ │ └── .gitkeep │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── favicon.ico │ ├── index.html │ ├── main.ts │ ├── polyfills.ts │ ├── styles.scss │ └── test.ts ├── tsconfig.app.json ├── tsconfig.json ├── tsconfig.spec.json └── tslint.json ├── angular-http ├── .editorconfig ├── .gitignore ├── README.md ├── angular.json ├── browserslist ├── e2e │ ├── protractor.conf.js │ ├── src │ │ ├── app.e2e-spec.ts │ │ └── app.po.ts │ └── tsconfig.json ├── json-server │ ├── index.js │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ ├── images │ │ │ └── json.png │ │ ├── index.html │ │ └── stylesheets │ │ │ └── style.css │ ├── services │ │ ├── core │ │ │ ├── auth │ │ │ │ ├── auth.db.json │ │ │ │ ├── auth.middleware.js │ │ │ │ └── auth.routes.js │ │ │ ├── authors │ │ │ │ ├── authors.db.json │ │ │ │ ├── authors.middleware.js │ │ │ │ └── authors.routes.js │ │ │ └── courses │ │ │ │ ├── courses.db.json │ │ │ │ ├── courses.middleware.js │ │ │ │ └── courses.routes.js │ │ ├── db.js │ │ ├── index.js │ │ ├── middleware.js │ │ └── routes.js │ └── utils │ │ ├── cors.js │ │ └── walk.js ├── karma.conf.js ├── package-lock.json ├── package.json ├── src │ ├── app │ │ ├── app.component.html │ │ ├── app.component.scss │ │ ├── app.component.spec.ts │ │ ├── app.component.ts │ │ ├── app.module.ts │ │ ├── components │ │ │ └── courses │ │ │ │ ├── courses.component.html │ │ │ │ ├── courses.component.scss │ │ │ │ ├── courses.component.spec.ts │ │ │ │ └── courses.component.ts │ │ ├── directives │ │ │ ├── creation-date-status.directive.spec.ts │ │ │ └── creation-date-status.directive.ts │ │ ├── interceptors │ │ │ ├── api.interceptor.spec.ts │ │ │ ├── api.interceptor.ts │ │ │ ├── auth.interceptor.spec.ts │ │ │ └── auth.interceptor.ts │ │ ├── models │ │ │ └── course.ts │ │ ├── pipes │ │ │ ├── filter-by.pipe.spec.ts │ │ │ ├── filter-by.pipe.ts │ │ │ ├── minutes-to-time.pipe.spec.ts │ │ │ ├── minutes-to-time.pipe.ts │ │ │ ├── order-by.pipe.spec.ts │ │ │ └── order-by.pipe.ts │ │ └── services │ │ │ ├── courses.service.spec.ts │ │ │ └── courses.service.ts │ ├── assets │ │ └── .gitkeep │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── favicon.ico │ ├── index.html │ ├── main.ts │ ├── polyfills.ts │ ├── styles.scss │ └── test.ts ├── tsconfig.app.json ├── tsconfig.json ├── tsconfig.spec.json └── tslint.json ├── angular-modules-services ├── .editorconfig ├── .gitignore ├── README.md ├── angular.json ├── browserslist ├── e2e │ ├── protractor.conf.js │ ├── src │ │ ├── app.e2e-spec.ts │ │ └── app.po.ts │ └── tsconfig.json ├── karma.conf.js ├── package-lock.json ├── package.json ├── src │ ├── app │ │ ├── app-routing.module.ts │ │ ├── app.component.html │ │ ├── app.component.scss │ │ ├── app.component.spec.ts │ │ ├── app.component.ts │ │ ├── app.module.ts │ │ ├── core │ │ │ ├── components │ │ │ │ ├── footer │ │ │ │ │ ├── footer.component.html │ │ │ │ │ ├── footer.component.scss │ │ │ │ │ ├── footer.component.spec.ts │ │ │ │ │ └── footer.component.ts │ │ │ │ └── header │ │ │ │ │ ├── header.component.html │ │ │ │ │ ├── header.component.scss │ │ │ │ │ ├── header.component.spec.ts │ │ │ │ │ └── header.component.ts │ │ │ ├── core.module.ts │ │ │ └── services │ │ │ │ ├── logger.service.spec.ts │ │ │ │ └── logger.service.ts │ │ ├── feed │ │ │ ├── components │ │ │ │ └── posts-list │ │ │ │ │ ├── posts-list.component.html │ │ │ │ │ ├── posts-list.component.scss │ │ │ │ │ └── posts-list.component.ts │ │ │ ├── feed.module.ts │ │ │ └── services │ │ │ │ ├── feed.service.spec.ts │ │ │ │ ├── feed.service.ts │ │ │ │ └── index.ts │ │ └── shared │ │ │ ├── components │ │ │ └── post │ │ │ │ ├── post.component.html │ │ │ │ ├── post.component.scss │ │ │ │ ├── post.component.spec.ts │ │ │ │ └── post.component.ts │ │ │ ├── models │ │ │ ├── index.ts │ │ │ └── post.ts │ │ │ └── shared.module.ts │ ├── assets │ │ └── .gitkeep │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── favicon.ico │ ├── index.html │ ├── main.ts │ ├── polyfills.ts │ ├── styles.scss │ └── test.ts ├── tsconfig.app.json ├── tsconfig.json ├── tsconfig.spec.json └── tslint.json ├── angular-routing ├── .editorconfig ├── .gitignore ├── README.md ├── angular.json ├── browserslist ├── e2e │ ├── protractor.conf.js │ ├── src │ │ ├── app.e2e-spec.ts │ │ └── app.po.ts │ └── tsconfig.json ├── karma.conf.js ├── package-lock.json ├── package.json ├── src │ ├── app │ │ ├── another-module │ │ │ ├── another.module.ts │ │ │ └── pages │ │ │ │ ├── one │ │ │ │ ├── one.component.html │ │ │ │ ├── one.component.scss │ │ │ │ ├── one.component.spec.ts │ │ │ │ └── one.component.ts │ │ │ │ └── two │ │ │ │ ├── two.component.html │ │ │ │ ├── two.component.scss │ │ │ │ ├── two.component.spec.ts │ │ │ │ └── two.component.ts │ │ ├── app-routing.module.ts │ │ ├── app.component.html │ │ ├── app.component.scss │ │ ├── app.component.spec.ts │ │ ├── app.component.ts │ │ ├── app.module.ts │ │ ├── guards │ │ │ ├── auth.guard.spec.ts │ │ │ ├── auth.guard.ts │ │ │ ├── loading.guard.spec.ts │ │ │ ├── loading.guard.ts │ │ │ ├── new-one.guard.spec.ts │ │ │ └── new-one.guard.ts │ │ ├── lazy-loaded │ │ │ ├── lazy-loaded-routing.module.ts │ │ │ ├── lazy-loaded.module.ts │ │ │ └── pages │ │ │ │ └── lazy-loaded-page │ │ │ │ ├── lazy-loaded-page.component.html │ │ │ │ ├── lazy-loaded-page.component.scss │ │ │ │ ├── lazy-loaded-page.component.spec.ts │ │ │ │ └── lazy-loaded-page.component.ts │ │ ├── pages │ │ │ ├── admin-page │ │ │ │ ├── admin-page.component.html │ │ │ │ ├── admin-page.component.scss │ │ │ │ ├── admin-page.component.spec.ts │ │ │ │ └── admin-page.component.ts │ │ │ ├── home-page │ │ │ │ ├── home-page.component.html │ │ │ │ ├── home-page.component.scss │ │ │ │ ├── home-page.component.spec.ts │ │ │ │ └── home-page.component.ts │ │ │ ├── not-found │ │ │ │ ├── not-found.component.html │ │ │ │ ├── not-found.component.scss │ │ │ │ ├── not-found.component.spec.ts │ │ │ │ └── not-found.component.ts │ │ │ ├── simple-redicrect │ │ │ │ ├── simple-redicrect.component.html │ │ │ │ ├── simple-redicrect.component.scss │ │ │ │ ├── simple-redicrect.component.spec.ts │ │ │ │ └── simple-redicrect.component.ts │ │ │ ├── tabs │ │ │ │ ├── pages │ │ │ │ │ ├── left-tab │ │ │ │ │ │ ├── left-tab.component.html │ │ │ │ │ │ ├── left-tab.component.scss │ │ │ │ │ │ ├── left-tab.component.spec.ts │ │ │ │ │ │ └── left-tab.component.ts │ │ │ │ │ └── right-tab │ │ │ │ │ │ ├── right-tab.component.html │ │ │ │ │ │ ├── right-tab.component.scss │ │ │ │ │ │ ├── right-tab.component.spec.ts │ │ │ │ │ │ └── right-tab.component.ts │ │ │ │ ├── tabs.component.html │ │ │ │ ├── tabs.component.scss │ │ │ │ ├── tabs.component.spec.ts │ │ │ │ └── tabs.component.ts │ │ │ └── user-page │ │ │ │ ├── user-page.component.html │ │ │ │ ├── user-page.component.scss │ │ │ │ ├── user-page.component.spec.ts │ │ │ │ └── user-page.component.ts │ │ ├── resolvers │ │ │ └── data.resolver.ts │ │ └── some-other-feature │ │ │ ├── some-other-feature-routing.module.ts │ │ │ └── some-other-feature.module.ts │ ├── assets │ │ └── .gitkeep │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── favicon.ico │ ├── index.html │ ├── main.ts │ ├── polyfills.ts │ ├── styles.scss │ └── test.ts ├── tsconfig.app.json ├── tsconfig.json ├── tsconfig.spec.json └── tslint.json ├── angular-unit-testing ├── .editorconfig ├── .gitignore ├── README.md ├── angular.json ├── browserslist ├── e2e │ ├── protractor.conf.js │ ├── src │ │ ├── app.e2e-spec.ts │ │ └── app.po.ts │ └── tsconfig.json ├── karma.conf.js ├── package-lock.json ├── package.json ├── src │ ├── app │ │ ├── app.component.html │ │ ├── app.component.scss │ │ ├── app.component.spec.ts │ │ ├── app.component.ts │ │ ├── app.module.ts │ │ ├── first-look │ │ │ ├── dependencies-testing │ │ │ │ ├── components │ │ │ │ │ └── some │ │ │ │ │ │ ├── some.component.html │ │ │ │ │ │ ├── some.component.scss │ │ │ │ │ │ ├── some.component.spec.ts │ │ │ │ │ │ └── some.component.ts │ │ │ │ └── services │ │ │ │ │ ├── some.service.spec.ts │ │ │ │ │ └── some.service.ts │ │ │ └── instance-testing │ │ │ │ ├── instance-testing.component.html │ │ │ │ ├── instance-testing.component.scss │ │ │ │ ├── instance-testing.component.spec.ts │ │ │ │ └── instance-testing.component.ts │ │ └── test-bed │ │ │ ├── components │ │ │ ├── login-widget-with-service │ │ │ │ ├── login-widget-with-service.component.html │ │ │ │ ├── login-widget-with-service.component.scss │ │ │ │ ├── login-widget-with-service.component.spec.ts │ │ │ │ └── login-widget-with-service.component.ts │ │ │ ├── login-widget │ │ │ │ ├── login-widget.component.html │ │ │ │ ├── login-widget.component.scss │ │ │ │ ├── login-widget.component.spec.ts │ │ │ │ └── login-widget.component.ts │ │ │ ├── publication-card │ │ │ │ ├── publication-card.component.html │ │ │ │ ├── publication-card.component.scss │ │ │ │ ├── publication-card.component.spec.ts │ │ │ │ └── publication-card.component.ts │ │ │ └── user-profile │ │ │ │ ├── user-info │ │ │ │ ├── user-info.component.html │ │ │ │ ├── user-info.component.scss │ │ │ │ ├── user-info.component.spec.ts │ │ │ │ └── user-info.component.ts │ │ │ │ ├── user-menu │ │ │ │ ├── user-menu.component.html │ │ │ │ ├── user-menu.component.scss │ │ │ │ ├── user-menu.component.spec.ts │ │ │ │ └── user-menu.component.ts │ │ │ │ ├── user-picture │ │ │ │ ├── user-picture.component.html │ │ │ │ ├── user-picture.component.scss │ │ │ │ ├── user-picture.component.spec.ts │ │ │ │ └── user-picture.component.ts │ │ │ │ ├── user-profile.component.html │ │ │ │ ├── user-profile.component.scss │ │ │ │ ├── user-profile.component.spec.ts │ │ │ │ └── user-profile.component.ts │ │ │ └── services │ │ │ ├── login.service.spec.ts │ │ │ └── login.service.ts │ ├── assets │ │ └── .gitkeep │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── favicon.ico │ ├── index.html │ ├── main.ts │ ├── polyfills.ts │ ├── styles.scss │ └── test.ts ├── tsconfig.app.json ├── tsconfig.json ├── tsconfig.spec.json └── tslint.json ├── package-lock.json ├── rxjs-observables ├── live-examples.js ├── observable-custom.js ├── observables-intro.js ├── package-lock.json ├── package.json ├── src │ ├── 01-observable-creation.ts │ ├── 02-observable-handling.ts │ ├── 03-observable-error.ts │ ├── 04-observable-complete.ts │ ├── 05-creation-operators.ts │ └── 06-error-handling.ts └── tsconfig.json ├── ts-intro ├── package-lock.json ├── src │ ├── 00-primitives.ts │ ├── 01-objects-arrays.ts │ ├── 02-functions.ts │ ├── 03-interfaces-classess.ts │ ├── 04-features.js │ └── 04-features.ts └── tsconfig.json └── webpack-intro ├── package-lock.json ├── package.json ├── src ├── another.js ├── index.js ├── some.js ├── styles.css └── typed.ts ├── tsconfig.json └── webpack.config.js /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/node_modules 2 | **/.idea 3 | **/dist -------------------------------------------------------------------------------- /angular-components/.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 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /angular-components/.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 | -------------------------------------------------------------------------------- /angular-components/README.md: -------------------------------------------------------------------------------- 1 | # AngularComponentsNew 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.0.3. 4 | 5 | ## Development server 6 | 7 | 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. 8 | 9 | ## Code scaffolding 10 | 11 | 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`. 12 | 13 | ## Build 14 | 15 | 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. 16 | 17 | ## Running unit tests 18 | 19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 20 | 21 | ## Running end-to-end tests 22 | 23 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 24 | 25 | ## Further help 26 | 27 | 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). 28 | -------------------------------------------------------------------------------- /angular-components/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'. -------------------------------------------------------------------------------- /angular-components/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 | }; -------------------------------------------------------------------------------- /angular-components/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('Welcome to angular-components-new!'); 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 | -------------------------------------------------------------------------------- /angular-components/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get(browser.baseUrl) as Promise; 6 | } 7 | 8 | getTitleText() { 9 | return element(by.css('app-root h1')).getText() as Promise; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /angular-components/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 | -------------------------------------------------------------------------------- /angular-components/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 12 | -------------------------------------------------------------------------------- /angular-components/src/app/app.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-components/src/app/app.component.scss -------------------------------------------------------------------------------- /angular-components/src/app/components/bindings-example/bindings-example.component.scss: -------------------------------------------------------------------------------- 1 | .binding-examples { 2 | width: 100vw; 3 | display: flex; 4 | justify-content: space-around; 5 | flex-wrap: wrap; 6 | } 7 | 8 | .events-example { 9 | width: 100vw; 10 | display: flex; 11 | flex-direction: column; 12 | justify-content: center; 13 | align-items: center; 14 | 15 | &__list { 16 | display: flex; 17 | 18 | &__item { 19 | margin: 10px; 20 | display: flex; 21 | flex-direction: column; 22 | 23 | p { 24 | text-align: center; 25 | } 26 | 27 | .keyboard-area { 28 | width: 150px; 29 | height: 50px; 30 | border: 1px solid black; 31 | display: flex; 32 | justify-content: center; 33 | align-items: center; 34 | -webkit-user-select: none; 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /angular-components/src/app/components/bindings-example/bindings-example.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { BindingsExampleComponent } from './bindings-example.component'; 4 | 5 | describe('BindingsExampleComponent', () => { 6 | let component: BindingsExampleComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ BindingsExampleComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(BindingsExampleComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-components/src/app/components/content-example/content-example.component.html: -------------------------------------------------------------------------------- 1 | 2 |

I'm a message

3 |
4 | -------------------------------------------------------------------------------- /angular-components/src/app/components/content-example/content-example.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-components/src/app/components/content-example/content-example.component.scss -------------------------------------------------------------------------------- /angular-components/src/app/components/content-example/content-example.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ContentExampleComponent } from './content-example.component'; 4 | 5 | describe('ContentExampleComponent', () => { 6 | let component: ContentExampleComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ContentExampleComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ContentExampleComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-components/src/app/components/content-example/content-example.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-content-example', 5 | templateUrl: './content-example.component.html', 6 | styleUrls: ['./content-example.component.scss'] 7 | }) 8 | export class ContentExampleComponent { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /angular-components/src/app/components/content-example/content-inner/content-inner.component.html: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | -------------------------------------------------------------------------------- /angular-components/src/app/components/content-example/content-inner/content-inner.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-components/src/app/components/content-example/content-inner/content-inner.component.scss -------------------------------------------------------------------------------- /angular-components/src/app/components/content-example/content-inner/content-inner.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ContentInnerComponent } from './content-inner.component'; 4 | 5 | describe('ContentInnerComponent', () => { 6 | let component: ContentInnerComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ContentInnerComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ContentInnerComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-components/src/app/components/content-example/content-inner/content-inner.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-content-inner', 5 | templateUrl: './content-inner.component.html', 6 | styleUrls: ['./content-inner.component.scss'] 7 | }) 8 | export class ContentInnerComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /angular-components/src/app/components/feed-decomposition/feed-decomposition.component.html: -------------------------------------------------------------------------------- 1 |

My feed

2 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /angular-components/src/app/components/feed-decomposition/feed-decomposition.component.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | display: flex; 3 | flex-direction: column; 4 | justify-content: center; 5 | align-items: center; 6 | 7 | app-post { 8 | margin-top: 20px; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /angular-components/src/app/components/feed-decomposition/feed-decomposition.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { FeedDecompositionComponent } from './feed-decomposition.component'; 4 | 5 | describe('FeedDecompositionComponent', () => { 6 | let component: FeedDecompositionComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ FeedDecompositionComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(FeedDecompositionComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-components/src/app/components/feed-decomposition/post/post.component.html: -------------------------------------------------------------------------------- 1 | 2 | {{ post.title }} 3 | 4 |

{{ post.text }}

5 |
6 | 7 | 11 | 12 |
13 | -------------------------------------------------------------------------------- /angular-components/src/app/components/feed-decomposition/post/post.component.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | width: 500px; 3 | } 4 | -------------------------------------------------------------------------------- /angular-components/src/app/components/feed-decomposition/post/post.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { PostComponent } from './post.component'; 4 | 5 | describe('PostComponent', () => { 6 | let component: PostComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ PostComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(PostComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-components/src/app/components/feed-decomposition/post/post.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, Output, EventEmitter } from '@angular/core'; 2 | import { Post } from 'src/app/models/post'; 3 | 4 | @Component({ 5 | selector: 'app-post', 6 | templateUrl: './post.component.html', 7 | styleUrls: ['./post.component.scss'] 8 | }) 9 | export class PostComponent { 10 | @Input() post: Post; 11 | @Output() like = new EventEmitter(); 12 | @Output() unlike = new EventEmitter(); 13 | 14 | likePost() { 15 | this.like.emit(this.post); 16 | } 17 | 18 | unlikePost() { 19 | this.unlike.emit(this.post); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /angular-components/src/app/components/feed-simple/feed-simple.component.html: -------------------------------------------------------------------------------- 1 |

My feed

2 | 3 | 4 | {{ post.title }} 5 | 6 |

{{ post.text }}

7 |
8 | 9 | 15 | 16 |
17 | -------------------------------------------------------------------------------- /angular-components/src/app/components/feed-simple/feed-simple.component.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | display: flex; 3 | flex-direction: column; 4 | justify-content: center; 5 | align-items: center; 6 | 7 | mat-card { 8 | margin-top: 20px; 9 | width: 500px; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /angular-components/src/app/components/feed-simple/feed-simple.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { FeedSimpleComponent } from './feed-simple.component'; 4 | 5 | describe('FeedSimpleComponent', () => { 6 | let component: FeedSimpleComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ FeedSimpleComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(FeedSimpleComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-components/src/app/components/lifecycle-hooks/inner/inner.component.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /angular-components/src/app/components/lifecycle-hooks/inner/inner.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-components/src/app/components/lifecycle-hooks/inner/inner.component.scss -------------------------------------------------------------------------------- /angular-components/src/app/components/lifecycle-hooks/inner/inner.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { InnerComponent } from './inner.component'; 4 | 5 | describe('InnerComponent', () => { 6 | let component: InnerComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ InnerComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(InnerComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-components/src/app/components/lifecycle-hooks/lifecycle-hooks.component.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /angular-components/src/app/components/lifecycle-hooks/lifecycle-hooks.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-components/src/app/components/lifecycle-hooks/lifecycle-hooks.component.scss -------------------------------------------------------------------------------- /angular-components/src/app/components/lifecycle-hooks/lifecycle-hooks.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { LifecycleHooksComponent } from './lifecycle-hooks.component'; 4 | 5 | describe('LifecycleHooksComponent', () => { 6 | let component: LifecycleHooksComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ LifecycleHooksComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(LifecycleHooksComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-components/src/app/components/template-syntax/inner/inner.component.html: -------------------------------------------------------------------------------- 1 |

inner component works!

2 | -------------------------------------------------------------------------------- /angular-components/src/app/components/template-syntax/inner/inner.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-components/src/app/components/template-syntax/inner/inner.component.scss -------------------------------------------------------------------------------- /angular-components/src/app/components/template-syntax/inner/inner.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { InnerComponent } from './inner.component'; 4 | 5 | describe('InnerComponent', () => { 6 | let component: InnerComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ InnerComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(InnerComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-components/src/app/components/template-syntax/inner/inner.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-inner', 5 | templateUrl: './inner.component.html', 6 | styleUrls: ['./inner.component.scss'], 7 | exportAs: 'inner' 8 | }) 9 | export class InnerComponent { 10 | public innerProperty = 'Hi there!'; 11 | 12 | public innerMethod() { 13 | console.log('Hey! You\'ve just called the inner method'); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /angular-components/src/app/components/template-syntax/template-syntax.component.html: -------------------------------------------------------------------------------- 1 |

{{ el1.title }}

2 |

{{ el2.title }}

3 |

{{ el3.title }}

4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /angular-components/src/app/components/template-syntax/template-syntax.component.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | display: block; 3 | display: flex; 4 | flex-direction: column; 5 | align-items: center; 6 | 7 | .random-block { 8 | margin-top: 50px; 9 | 10 | width: 200px; 11 | height: 200px; 12 | 13 | border: 1px solid black; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /angular-components/src/app/components/template-syntax/template-syntax.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { TemplateSyntaxComponent } from './template-syntax.component'; 4 | 5 | describe('TemplateSyntaxComponent', () => { 6 | let component: TemplateSyntaxComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ TemplateSyntaxComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(TemplateSyntaxComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-components/src/app/models/post.ts: -------------------------------------------------------------------------------- 1 | export interface Post { 2 | id: number; 3 | title: string; 4 | text: string; 5 | likes: number; 6 | isLiked: boolean; 7 | } 8 | -------------------------------------------------------------------------------- /angular-components/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-components/src/assets/.gitkeep -------------------------------------------------------------------------------- /angular-components/src/assets/angular.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-components/src/assets/angular.png -------------------------------------------------------------------------------- /angular-components/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /angular-components/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 | -------------------------------------------------------------------------------- /angular-components/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-components/src/favicon.ico -------------------------------------------------------------------------------- /angular-components/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Angular Components 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /angular-components/src/main.ts: -------------------------------------------------------------------------------- 1 | import 'hammerjs'; 2 | import { enableProdMode } from '@angular/core'; 3 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 4 | 5 | import { AppModule } from './app/app.module'; 6 | import { environment } from './environments/environment'; 7 | 8 | if (environment.production) { 9 | enableProdMode(); 10 | } 11 | 12 | platformBrowserDynamic().bootstrapModule(AppModule) 13 | .catch(err => console.error(err)); 14 | -------------------------------------------------------------------------------- /angular-components/src/styles.scss: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | 3 | html, body { height: 100%; } 4 | body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; } 5 | -------------------------------------------------------------------------------- /angular-components/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: any; 11 | 12 | // First, initialize the Angular testing environment. 13 | getTestBed().initTestEnvironment( 14 | BrowserDynamicTestingModule, 15 | platformBrowserDynamicTesting() 16 | ); 17 | // Then we find all the tests. 18 | const context = require.context('./', true, /\.spec\.ts$/); 19 | // And load the modules. 20 | context.keys().map(context); 21 | -------------------------------------------------------------------------------- /angular-components/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/app", 5 | "types": [] 6 | }, 7 | "include": [ 8 | "src/**/*.ts" 9 | ], 10 | "exclude": [ 11 | "src/test.ts", 12 | "src/**/*.spec.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /angular-components/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 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "importHelpers": true, 14 | "target": "es2015", 15 | "typeRoots": [ 16 | "node_modules/@types" 17 | ], 18 | "lib": [ 19 | "es2018", 20 | "dom" 21 | ] 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /angular-components/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 | -------------------------------------------------------------------------------- /angular-directives-pipes/.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 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /angular-directives-pipes/.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 | -------------------------------------------------------------------------------- /angular-directives-pipes/README.md: -------------------------------------------------------------------------------- 1 | # AngularDirectivesPipes 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.3.2. 4 | 5 | ## Development server 6 | 7 | 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. 8 | 9 | ## Code scaffolding 10 | 11 | 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`. 12 | 13 | ## Build 14 | 15 | 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. 16 | 17 | ## Running unit tests 18 | 19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 20 | 21 | ## Running end-to-end tests 22 | 23 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 24 | 25 | ## Further help 26 | 27 | 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). 28 | -------------------------------------------------------------------------------- /angular-directives-pipes/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'. -------------------------------------------------------------------------------- /angular-directives-pipes/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 | }; -------------------------------------------------------------------------------- /angular-directives-pipes/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('angular-directives-pipes 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 | -------------------------------------------------------------------------------- /angular-directives-pipes/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get(browser.baseUrl) as Promise; 6 | } 7 | 8 | getTitleText() { 9 | return element(by.css('app-root .content span')).getText() as Promise; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /angular-directives-pipes/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 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/app.component.html: -------------------------------------------------------------------------------- 1 |

Angular Directives & Pipes

2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/app.component.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | width: 100%; 3 | height: 100%; 4 | display: flex; 5 | flex-direction: column; 6 | align-items: center; 7 | } 8 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | templateUrl: './app.component.html', 6 | styleUrls: ['./app.component.scss'] 7 | }) 8 | export class AppComponent { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/attribute-directives/attribute-directives.component.scss: -------------------------------------------------------------------------------- 1 | mat-card { 2 | margin: 20px 0; 3 | } 4 | 5 | .bold { 6 | font-weight: bold; 7 | } 8 | 9 | .italic { 10 | font-style: italic; 11 | } 12 | 13 | .red { 14 | color: red; 15 | } 16 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/attribute-directives/attribute-directives.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { AttributeDirectivesComponent } from './attribute-directives.component'; 4 | 5 | describe('AttributeDirectivesComponent', () => { 6 | let component: AttributeDirectivesComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ AttributeDirectivesComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(AttributeDirectivesComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/attribute-directives/attribute-directives.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-attribute-directives', 5 | templateUrl: './attribute-directives.component.html', 6 | styleUrls: ['./attribute-directives.component.scss'] 7 | }) 8 | export class AttributeDirectivesComponent { 9 | 10 | public paragraphColor = 'orange'; 11 | 12 | public color: string; 13 | 14 | public handleClick(event: MouseEvent | string) { 15 | console.log('click', event); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/attribute-directives/components/element-with-props-to-override/element-with-props-to-override.component.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/attribute-directives/components/element-with-props-to-override/element-with-props-to-override.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-directives-pipes/src/app/components/attribute-directives/components/element-with-props-to-override/element-with-props-to-override.component.scss -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/attribute-directives/components/element-with-props-to-override/element-with-props-to-override.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ElementWithPropsToOverrideComponent } from './element-with-props-to-override.component'; 4 | 5 | describe('ElementWithPropsToOverrideComponent', () => { 6 | let component: ElementWithPropsToOverrideComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ ElementWithPropsToOverrideComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ElementWithPropsToOverrideComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/attribute-directives/components/element-with-props-to-override/element-with-props-to-override.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, OnChanges, EventEmitter, Output } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-element-with-props-to-override', 5 | templateUrl: './element-with-props-to-override.component.html', 6 | styleUrls: ['./element-with-props-to-override.component.scss'] 7 | }) 8 | export class ElementWithPropsToOverrideComponent implements OnChanges { 9 | @Input() public propToOverride: string; 10 | @Output() public click = new EventEmitter(); 11 | 12 | public ngOnChanges(): void { 13 | console.log('ElementWithPropsToOverrideComponent has changed'); 14 | console.log('this.propToOverride -> ', this.propToOverride); 15 | } 16 | 17 | public onClick() { 18 | this.click.emit('Text from inner component'); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/attribute-directives/directives/highlight-custom-color-binding.directive.spec.ts: -------------------------------------------------------------------------------- 1 | import { HighlightCustomColorBindingDirective } from './highlight-custom-color-binding.directive'; 2 | 3 | describe('HighlightCustomColorBindingDirective', () => { 4 | it('should create an instance', () => { 5 | const directive = new HighlightCustomColorBindingDirective(); 6 | expect(directive).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/attribute-directives/directives/highlight-custom-color-binding.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, ElementRef, Renderer2, OnChanges, Input } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[appHighlightCustomColorBinding]' 5 | }) 6 | export class HighlightCustomColorBindingDirective implements OnChanges { 7 | @Input('appHighlightCustomColorBinding') color: string; 8 | 9 | constructor(private elementRef: ElementRef, private renderer2: Renderer2) { } 10 | 11 | public ngOnChanges(): void { 12 | this.highlight(this.color); 13 | } 14 | 15 | private highlight(color: string) { 16 | this.renderer2.setStyle(this.elementRef.nativeElement, 'background-color', color); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/attribute-directives/directives/highlight-on-hover.directive.spec.ts: -------------------------------------------------------------------------------- 1 | import { HighlightOnHoverDirective } from './highlight-on-hover.directive'; 2 | 3 | describe('HighlightOnHoverDirective', () => { 4 | it('should create an instance', () => { 5 | const directive = new HighlightOnHoverDirective(); 6 | expect(directive).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/attribute-directives/directives/highlight-on-hover.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, ElementRef, Renderer2, HostListener, HostBinding } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[appHighlightOnHover]' 5 | }) 6 | export class HighlightOnHoverDirective { 7 | @HostBinding('attr.aria-label') public label = 'This is an aria-label'; 8 | 9 | constructor(private elementRef: ElementRef, private renderer2: Renderer2) { } 10 | 11 | @HostListener('mouseenter', ['$event']) 12 | public onMouseEnter(event: MouseEvent) { 13 | console.log(event); 14 | this.highlight('yellow'); 15 | } 16 | 17 | @HostListener('mouseleave') 18 | public onMouseLeave() { 19 | this.highlight(null); // css-prop: unset; 20 | } 21 | 22 | private highlight(color: string) { 23 | this.renderer2.setStyle(this.elementRef.nativeElement, 'background-color', color); 24 | // this.elementRef.nativeElement.style.background = color; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/attribute-directives/directives/highlight-with-custom-color.directive.spec.ts: -------------------------------------------------------------------------------- 1 | import { HighlightWithCustomColorDirective } from './highlight-with-custom-color.directive'; 2 | 3 | describe('HighlightWithCustomColorDirective', () => { 4 | it('should create an instance', () => { 5 | const directive = new HighlightWithCustomColorDirective(); 6 | expect(directive).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/attribute-directives/directives/highlight-with-custom-color.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, ElementRef, Renderer2, OnChanges, Input } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[appHighlightWithCustomColor]' 5 | }) 6 | export class HighlightWithCustomColorDirective implements OnChanges { 7 | @Input() color: string; 8 | 9 | constructor(private elementRef: ElementRef, private renderer2: Renderer2) { } 10 | 11 | public ngOnChanges(): void { 12 | this.renderer2.setStyle(this.elementRef.nativeElement, 'background-color', this.color); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/attribute-directives/directives/highlight.directive.spec.ts: -------------------------------------------------------------------------------- 1 | import { HighlightDirective } from './highlight.directive'; 2 | 3 | describe('HighlightDirective', () => { 4 | it('should create an instance', () => { 5 | const directive = new HighlightDirective(); 6 | expect(directive).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/attribute-directives/directives/highlight.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, ElementRef, Renderer2 } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[appHighlight]' 5 | }) 6 | export class HighlightDirective { 7 | 8 | constructor(private elementRef: ElementRef, private renderer2: Renderer2) { 9 | this.renderer2.setStyle(this.elementRef.nativeElement, 'background-color', 'yellow'); 10 | // (this.elementRef.nativeElement).style.background = 'yellow'; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/pipes-examples/components/async-pipe/async-pipe.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Data: {{data | async}}

3 |

Seconds: {{seconds | async}}

4 |
5 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/pipes-examples/components/async-pipe/async-pipe.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-directives-pipes/src/app/components/pipes-examples/components/async-pipe/async-pipe.component.scss -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/pipes-examples/components/async-pipe/async-pipe.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { Observable } from 'rxjs'; 3 | 4 | @Component({ 5 | selector: 'app-async-pipe', 6 | templateUrl: './async-pipe.component.html', 7 | styleUrls: ['./async-pipe.component.scss'] 8 | }) 9 | export class AsyncPipeComponent { 10 | public data: Promise = new Promise(resolve => { 11 | setTimeout(() => { 12 | resolve('RECEIVED DATA!'); 13 | }, 5000); 14 | }); 15 | 16 | public count = 0; 17 | public seconds: Observable = new Observable(observer => { 18 | setInterval(() => { observer.next(this.count++); }, 1000); 19 | }); 20 | } 21 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/pipes-examples/components/pure-vs-impure/pure-vs-impure.component.scss: -------------------------------------------------------------------------------- 1 | mat-checkbox { 2 | margin: 0 5px; 3 | } 4 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/pipes-examples/components/pure-vs-impure/pure-vs-impure.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-pure-vs-impure', 5 | templateUrl: './pure-vs-impure.component.html', 6 | styleUrls: ['./pure-vs-impure.component.scss'] 7 | }) 8 | export class PureVsImpureComponent { 9 | public isDone = true; 10 | public tasks: any[] = [ 11 | { name: 'Todo1', isDone: true }, 12 | { name: 'Todo2', isDone: false } 13 | ]; 14 | public isDoneTasks: any[]; 15 | public someEl: boolean; 16 | 17 | constructor() { 18 | this.initIsDoneTasks(); 19 | } 20 | 21 | initIsDoneTasks() { 22 | this.isDoneTasks = this.tasks.filter(task => task.isDone === true); 23 | } 24 | 25 | addTask(name: string) { 26 | name = name.trim(); 27 | if (!name) { 28 | return; 29 | } 30 | const task = { name, isDone: this.isDone }; 31 | this.tasks.push(task); 32 | this.initIsDoneTasks(); 33 | } 34 | 35 | changeReference() { 36 | this.tasks = [...this.tasks]; 37 | this.initIsDoneTasks(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/pipes-examples/components/tasks-example/tasks-example.component.html: -------------------------------------------------------------------------------- 1 |
2 |

{{'started tasks' | uppercase}}

3 | Started 4 |
    5 |
  • {{task.name}}
  • 6 |
7 |
8 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/pipes-examples/components/tasks-example/tasks-example.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-directives-pipes/src/app/components/pipes-examples/components/tasks-example/tasks-example.component.scss -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/pipes-examples/components/tasks-example/tasks-example.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { ITask } from '../../models/task'; 3 | 4 | @Component({ 5 | selector: 'app-tasks-example', 6 | templateUrl: './tasks-example.component.html', 7 | styleUrls: ['./tasks-example.component.scss'] 8 | }) 9 | export class TasksExampleComponent { 10 | public tasks: ITask[] = [ 11 | { name: 'Completed task', status: 'completed' }, 12 | { name: 'Started task', status: 'started' }, 13 | { name: 'New task', status: 'new' }, 14 | { name: 'Started task', status: 'started' }, 15 | { name: 'Completed task', status: 'completed' } 16 | ]; 17 | 18 | public status = ''; 19 | 20 | public toggle(started: boolean) { 21 | this.status = started ? 'started' : ''; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/pipes-examples/models/task.ts: -------------------------------------------------------------------------------- 1 | export interface ITask { 2 | name: string; 3 | status: string; 4 | } 5 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/pipes-examples/pipes-examples.component.scss: -------------------------------------------------------------------------------- 1 | h2 { 2 | text-align: center; 3 | } 4 | 5 | mat-card { 6 | margin: 20px; 7 | min-width: 500px; 8 | flex-grow: 0; 9 | } 10 | 11 | main { 12 | display: flex; 13 | flex-wrap: wrap; 14 | justify-content: center; 15 | align-items: flex-start; 16 | } 17 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/pipes-examples/pipes-examples.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { PipesExamplesComponent } from './pipes-examples.component'; 4 | 5 | describe('PipesExamplesComponent', () => { 6 | let component: PipesExamplesComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ PipesExamplesComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(PipesExamplesComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/pipes-examples/pipes-examples.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-pipes-examples', 5 | templateUrl: './pipes-examples.component.html', 6 | styleUrls: ['./pipes-examples.component.scss'] 7 | }) 8 | export class PipesExamplesComponent { 9 | public dateString = new Date().toISOString(); 10 | } 11 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/pipes-examples/pipes/is-done-impure.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'isDoneImpure', 5 | pure: false 6 | }) 7 | export class IsDoneImpurePipe implements PipeTransform { 8 | transform(allTasks: any[], isDone: boolean) { 9 | console.log('Impure pipe'); 10 | return allTasks.filter(task => task.isDone === isDone); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/pipes-examples/pipes/is-done-pure.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'isDonePure', 5 | pure: true 6 | }) 7 | export class IsDonePurePipe implements PipeTransform { 8 | transform(allTasks: any[], isDone: boolean) { 9 | console.log('Pure pipe'); 10 | return allTasks.filter(task => task.isDone === isDone); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/pipes-examples/pipes/please.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'please' 5 | }) 6 | export class PleasePipe implements PipeTransform { 7 | 8 | transform(value: string, ...args: any[]): string { 9 | console.log(args); 10 | return `Please ${value}`; 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/pipes-examples/pipes/status.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from '@angular/core'; 2 | import { ITask } from '../models/task'; 3 | 4 | @Pipe({ 5 | name: 'filterByStatus' 6 | }) 7 | export class StatusPipe implements PipeTransform { 8 | transform(allTasks: ITask[], status: string) { 9 | if (!allTasks || !status) { 10 | return allTasks; 11 | } 12 | 13 | return allTasks.filter((task) => task.status === status); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/structural-directives/directives/unless.directive.spec.ts: -------------------------------------------------------------------------------- 1 | import { UnlessDirective } from './unless.directive'; 2 | 3 | describe('UnlessDirective', () => { 4 | it('should create an instance', () => { 5 | const directive = new UnlessDirective(); 6 | expect(directive).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/structural-directives/directives/unless.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core'; 2 | 3 | /** 4 | * Add the template content to the DOM unless the condition is true. 5 | */ 6 | @Directive({ selector: '[appUnless]' }) 7 | export class UnlessDirective { 8 | private hasView = false; 9 | 10 | constructor( 11 | private templateRef: TemplateRef, 12 | private viewContainer: ViewContainerRef) { } 13 | 14 | @Input() set appUnless(condition: boolean) { 15 | if (!condition && !this.hasView) { 16 | this.viewContainer.createEmbeddedView(this.templateRef); 17 | this.hasView = true; 18 | } else if (condition && this.hasView) { 19 | this.viewContainer.clear(); 20 | this.hasView = false; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/structural-directives/structural-directives.component.scss: -------------------------------------------------------------------------------- 1 | h2 { 2 | text-align: center; 3 | } 4 | 5 | mat-card { 6 | margin: 20px; 7 | min-width: 400px; 8 | } 9 | 10 | main { 11 | display: flex; 12 | flex-wrap: wrap; 13 | justify-content: center; 14 | align-items: flex-start; 15 | } 16 | 17 | .grey { 18 | background-color: lightgrey; 19 | } 20 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/app/components/structural-directives/structural-directives.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { StructuralDirectivesComponent } from './structural-directives.component'; 4 | 5 | describe('StructuralDirectivesComponent', () => { 6 | let component: StructuralDirectivesComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ StructuralDirectivesComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(StructuralDirectivesComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-directives-pipes/src/assets/.gitkeep -------------------------------------------------------------------------------- /angular-directives-pipes/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /angular-directives-pipes/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 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-directives-pipes/src/favicon.ico -------------------------------------------------------------------------------- /angular-directives-pipes/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AngularDirectivesPipes 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/main.ts: -------------------------------------------------------------------------------- 1 | import 'hammerjs'; 2 | import { enableProdMode } from '@angular/core'; 3 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 4 | 5 | import { AppModule } from './app/app.module'; 6 | import { environment } from './environments/environment'; 7 | 8 | if (environment.production) { 9 | enableProdMode(); 10 | } 11 | 12 | platformBrowserDynamic().bootstrapModule(AppModule) 13 | .catch(err => console.error(err)); 14 | -------------------------------------------------------------------------------- /angular-directives-pipes/src/styles.scss: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | 3 | html, body { height: 100%; } 4 | body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; } 5 | -------------------------------------------------------------------------------- /angular-directives-pipes/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: any; 11 | 12 | // First, initialize the Angular testing environment. 13 | getTestBed().initTestEnvironment( 14 | BrowserDynamicTestingModule, 15 | platformBrowserDynamicTesting() 16 | ); 17 | // Then we find all the tests. 18 | const context = require.context('./', true, /\.spec\.ts$/); 19 | // And load the modules. 20 | context.keys().map(context); 21 | -------------------------------------------------------------------------------- /angular-directives-pipes/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/**/*.ts" 13 | ], 14 | "exclude": [ 15 | "src/test.ts", 16 | "src/**/*.spec.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /angular-directives-pipes/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 | "typeRoots": [ 15 | "node_modules/@types" 16 | ], 17 | "lib": [ 18 | "es2018", 19 | "dom" 20 | ] 21 | }, 22 | "angularCompilerOptions": { 23 | "fullTemplateTypeCheck": true, 24 | "strictInjectionParameters": true 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /angular-directives-pipes/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 | -------------------------------------------------------------------------------- /angular-http/.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 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /angular-http/.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 | -------------------------------------------------------------------------------- /angular-http/README.md: -------------------------------------------------------------------------------- 1 | # AngularHttp 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.0.3. 4 | 5 | ## Development server 6 | 7 | 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. 8 | 9 | ## Code scaffolding 10 | 11 | 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`. 12 | 13 | ## Build 14 | 15 | 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. 16 | 17 | ## Running unit tests 18 | 19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 20 | 21 | ## Running end-to-end tests 22 | 23 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 24 | 25 | ## Further help 26 | 27 | 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). 28 | -------------------------------------------------------------------------------- /angular-http/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'. -------------------------------------------------------------------------------- /angular-http/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 | }; -------------------------------------------------------------------------------- /angular-http/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('Welcome to angular-http!'); 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 | -------------------------------------------------------------------------------- /angular-http/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get(browser.baseUrl) as Promise; 6 | } 7 | 8 | getTitleText() { 9 | return element(by.css('app-root h1')).getText() as Promise; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /angular-http/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 | -------------------------------------------------------------------------------- /angular-http/json-server/index.js: -------------------------------------------------------------------------------- 1 | const jsonServer = require('json-server'); 2 | const server = jsonServer.create(); 3 | const middleware = jsonServer.defaults(); 4 | const init = require('./services'); 5 | const walk = require('./utils/walk'); 6 | const cors = require('./utils/cors'); 7 | 8 | let ang; 9 | 10 | walk('./services', function (err, results) { 11 | if (err) { 12 | console.log(err); 13 | } else { 14 | ang = init(results); 15 | 16 | server.use(cors); 17 | 18 | server.use(jsonServer.bodyParser); 19 | server.use(middleware); 20 | 21 | // 22 | server.use(ang.routes); 23 | server.use(ang.middleware); 24 | server.use(ang.db); 25 | 26 | server.listen(3004, function () { 27 | console.log('JSON Server is running on 3004'); 28 | }); 29 | } 30 | }); 31 | -------------------------------------------------------------------------------- /angular-http/json-server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mock-server", 3 | "version": "1.0.0", 4 | "description": "Mock backend for Angular course", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "express": "^4.14.1", 13 | "json-server": "^0.9.4", 14 | "lodash": "^4.17.4" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /angular-http/json-server/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-http/json-server/public/favicon.ico -------------------------------------------------------------------------------- /angular-http/json-server/public/images/json.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-http/json-server/public/images/json.png -------------------------------------------------------------------------------- /angular-http/json-server/public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | img { 2 | padding-top: 50px; 3 | padding-bottom: 20px; 4 | } 5 | 6 | li { 7 | list-style-type: square; 8 | } 9 | 10 | h4 { 11 | padding-top: 20px; 12 | } -------------------------------------------------------------------------------- /angular-http/json-server/services/core/auth/auth.routes.js: -------------------------------------------------------------------------------- 1 | // REWRITE EXAMPLE 2 | const express = require('express'); 3 | const jsonServer = require('json-server'); 4 | const router = express.Router(); 5 | 6 | router.use(jsonServer.rewriter({ 7 | '/auth/login': '/auth/login', 8 | '/auth/userInfo': '/auth/userInfo' 9 | })); 10 | 11 | module.exports = router; 12 | -------------------------------------------------------------------------------- /angular-http/json-server/services/core/authors/authors.middleware.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const url = require('url'); 4 | 5 | module.exports = (server) => { 6 | return router; 7 | }; 8 | -------------------------------------------------------------------------------- /angular-http/json-server/services/core/authors/authors.routes.js: -------------------------------------------------------------------------------- 1 | // REWRITE EXAMPLE 2 | const express = require('express'); 3 | const jsonServer = require('json-server'); 4 | const router = express.Router(); 5 | 6 | router.use(jsonServer.rewriter({ 7 | '/authors': '/authors', 8 | })); 9 | 10 | module.exports = router; 11 | -------------------------------------------------------------------------------- /angular-http/json-server/services/core/courses/courses.middleware.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const url = require('url'); 4 | 5 | module.exports = server => { 6 | router.get('/courses', (req, res) => { 7 | const token = req.headers['authorization']; 8 | 9 | if (!token) { 10 | return res.status(401).json({ message: 'Unauthorized' }); 11 | } 12 | 13 | let url_parts = url.parse(req.originalUrl, true), 14 | query = url_parts.query, 15 | from = query.start || 0, 16 | to = +query.start + +query.count, 17 | courses = server.db.getState().courses; 18 | 19 | if (!!query.textFragment) { 20 | courses = courses.filter( 21 | course => 22 | course.name 23 | .concat(course.description) 24 | .toUpperCase() 25 | .indexOf(query.textFragment.toUpperCase()) >= 0 26 | ); 27 | } 28 | 29 | if (courses.length < to || !to) { 30 | to = courses.length; 31 | } 32 | courses = courses.slice(from, to); 33 | 34 | res.json(courses); 35 | }); 36 | 37 | return router; 38 | }; 39 | -------------------------------------------------------------------------------- /angular-http/json-server/services/core/courses/courses.routes.js: -------------------------------------------------------------------------------- 1 | // REWRITE EXAMPLE 2 | const express = require('express'); 3 | const jsonServer = require('json-server'); 4 | const router = express.Router(); 5 | 6 | router.use(jsonServer.rewriter({ 7 | '/courses': '/courses', 8 | '/courses/:id': '/courses/:id', 9 | })); 10 | 11 | module.exports = router; 12 | -------------------------------------------------------------------------------- /angular-http/json-server/services/db.js: -------------------------------------------------------------------------------- 1 | const jsonServer = require('json-server'); 2 | const _ = require('lodash'); 3 | 4 | module.exports = (files) => { 5 | let db = {}; 6 | 7 | for (let file of files) { 8 | if (file.match(/db\.json$/gi)) { 9 | let data = require(file); 10 | db = _.merge(db, data); 11 | } 12 | } 13 | 14 | return jsonServer.router(db); 15 | }; -------------------------------------------------------------------------------- /angular-http/json-server/services/index.js: -------------------------------------------------------------------------------- 1 | module.exports = (files) => { 2 | const db = require('./db')(files); 3 | const routes = require('./routes')(files); 4 | const middleware = require('./middleware')(files, db); 5 | return {middleware, db, routes}; 6 | }; -------------------------------------------------------------------------------- /angular-http/json-server/services/middleware.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | 4 | module.exports = (files, db) => { 5 | 6 | for (let file of files) { 7 | if (file.match(/\.middleware\.js$/gi)) { 8 | let middleware = require(file)(db); 9 | router.use(middleware); 10 | } 11 | } 12 | 13 | return router; 14 | }; -------------------------------------------------------------------------------- /angular-http/json-server/services/routes.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | 4 | module.exports = (files) => { 5 | 6 | for (let file of files) { 7 | if (file.match(/\.routes\.js$/gi)) { 8 | let route = require(file); 9 | router.use(route); 10 | } 11 | } 12 | 13 | return router; 14 | }; -------------------------------------------------------------------------------- /angular-http/json-server/utils/cors.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | 4 | module.exports = router.use(function (req, res, next) { 5 | res.header("Access-Control-Allow-Origin", "*"); 6 | res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE, OPTIONS'); 7 | res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); 8 | 9 | next(); 10 | }); 11 | -------------------------------------------------------------------------------- /angular-http/json-server/utils/walk.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const walk = function(dir, done) { 4 | let results = []; 5 | fs.readdir(dir, function(err, list) { 6 | if (err) return done(err); 7 | let pending = list.length; 8 | if (!pending) return done(null, results); 9 | list.forEach(function(file) { 10 | file = path.resolve(dir, file); 11 | fs.stat(file, function(err, stat) { 12 | if (stat && stat.isDirectory()) { 13 | walk(file, function(err, res) { 14 | results = results.concat(res); 15 | if (!--pending) done(null, results); 16 | }); 17 | } else { 18 | results.push(file); 19 | if (!--pending) done(null, results); 20 | } 21 | }); 22 | }); 23 | }); 24 | }; 25 | 26 | module.exports = walk; -------------------------------------------------------------------------------- /angular-http/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/angular-http'), 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 | -------------------------------------------------------------------------------- /angular-http/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /angular-http/src/app/app.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-http/src/app/app.component.scss -------------------------------------------------------------------------------- /angular-http/src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async } from '@angular/core/testing'; 2 | import { AppComponent } from './app.component'; 3 | 4 | describe('AppComponent', () => { 5 | beforeEach(async(() => { 6 | TestBed.configureTestingModule({ 7 | declarations: [ 8 | AppComponent 9 | ], 10 | }).compileComponents(); 11 | })); 12 | 13 | it('should create the app', () => { 14 | const fixture = TestBed.createComponent(AppComponent); 15 | const app = fixture.debugElement.componentInstance; 16 | expect(app).toBeTruthy(); 17 | }); 18 | 19 | it(`should have as title 'angular-http'`, () => { 20 | const fixture = TestBed.createComponent(AppComponent); 21 | const app = fixture.debugElement.componentInstance; 22 | expect(app.title).toEqual('angular-http'); 23 | }); 24 | 25 | it('should render title in a h1 tag', () => { 26 | const fixture = TestBed.createComponent(AppComponent); 27 | fixture.detectChanges(); 28 | const compiled = fixture.debugElement.nativeElement; 29 | expect(compiled.querySelector('h1').textContent).toContain('Welcome to angular-http!'); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /angular-http/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | templateUrl: './app.component.html', 6 | styleUrls: ['./app.component.scss'] 7 | }) 8 | export class AppComponent { 9 | title = 'angular-http'; 10 | } 11 | -------------------------------------------------------------------------------- /angular-http/src/app/components/courses/courses.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { CoursesComponent } from './courses.component'; 4 | 5 | describe('CoursesComponent', () => { 6 | let component: CoursesComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ CoursesComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(CoursesComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-http/src/app/directives/creation-date-status.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, Input, ElementRef, Renderer2, OnChanges } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[appCreationDateStatus]' 5 | }) 6 | export class CreationDateStatusDirective implements OnChanges { 7 | @Input() public creationDateString: string; 8 | public readonly upcomingColor = '#29aeae'; 9 | public readonly freshColor = '#4a870e'; 10 | 11 | constructor(private element: ElementRef, private renderer: Renderer2) { } 12 | 13 | public ngOnChanges(): void { 14 | const now = new Date(); 15 | const creationDate = new Date(this.creationDateString); 16 | const daysDifference = Math.round((creationDate.getTime() - now.getTime()) / (24 * 3600 * 1000)); 17 | 18 | let color; 19 | 20 | switch (true) { 21 | case daysDifference > 0: 22 | color = this.upcomingColor; 23 | break; 24 | case daysDifference >= -14: 25 | color = this.freshColor; 26 | break; 27 | } 28 | 29 | if (color) { 30 | this.renderer.setStyle(this.element.nativeElement, 'border', `2px solid ${color}`); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /angular-http/src/app/interceptors/api.interceptor.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { ApiInterceptor } from './api.interceptor'; 4 | 5 | describe('ApiService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: ApiInterceptor = TestBed.get(ApiInterceptor); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /angular-http/src/app/interceptors/api.interceptor.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { 3 | HttpEvent, 4 | HttpHandler, 5 | HttpInterceptor, 6 | HttpRequest 7 | } from '@angular/common/http'; 8 | import { Observable } from 'rxjs'; 9 | import { environment } from 'src/environments/environment'; 10 | 11 | @Injectable({ 12 | providedIn: 'root' 13 | }) 14 | export class ApiInterceptor implements HttpInterceptor { 15 | public intercept(req: HttpRequest, next: HttpHandler): Observable> { 16 | return next.handle(req.clone({ 17 | url: `${environment.API_URL}/${req.url}` 18 | })); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /angular-http/src/app/interceptors/auth.interceptor.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { AuthInterceptor } from './auth.interceptor'; 4 | 5 | describe('AuthService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: AuthInterceptor = TestBed.get(AuthInterceptor); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /angular-http/src/app/interceptors/auth.interceptor.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { 3 | HttpEvent, 4 | HttpHandler, 5 | HttpInterceptor, 6 | HttpRequest 7 | } from '@angular/common/http'; 8 | import { Observable } from 'rxjs'; 9 | 10 | @Injectable() 11 | export class AuthInterceptor implements HttpInterceptor { 12 | 13 | public intercept(req: HttpRequest, next: HttpHandler): Observable> { 14 | const token = 'blah-blah'; 15 | 16 | return next.handle(req.clone({ 17 | headers: req.headers 18 | .set('Authorization', `Bearer ${token}`), 19 | })); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /angular-http/src/app/models/course.ts: -------------------------------------------------------------------------------- 1 | export interface CourseAuthor { 2 | id?: number; 3 | firstName: string; 4 | lastName?: string; 5 | } 6 | 7 | export interface Course { 8 | id?: number; 9 | name: string; 10 | date: string; 11 | length: number; 12 | description: string; 13 | authors?: CourseAuthor[]; 14 | isTopRated?: boolean; 15 | } 16 | 17 | export interface CourseResponse { 18 | courses: Course[]; 19 | hasMoreCourses: boolean; 20 | } 21 | -------------------------------------------------------------------------------- /angular-http/src/app/pipes/filter-by.pipe.spec.ts: -------------------------------------------------------------------------------- 1 | import { FilterByPipe } from './filter-by.pipe'; 2 | 3 | describe('FilterByPipe', () => { 4 | it('create an instance', () => { 5 | const pipe = new FilterByPipe(); 6 | expect(pipe).toBeTruthy(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /angular-http/src/app/pipes/filter-by.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'filterBy' 5 | }) 6 | export class FilterByPipe implements PipeTransform { 7 | 8 | transform(items: T[], field: string, searchCriteria: string): any { 9 | return searchCriteria ? items.filter((item) => item[field].toString().toLowerCase().includes(searchCriteria)) : items; 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /angular-http/src/app/pipes/minutes-to-time.pipe.spec.ts: -------------------------------------------------------------------------------- 1 | import { MinutesToTimePipe } from './minutes-to-time.pipe'; 2 | 3 | describe('MinutesToTimePipe', () => { 4 | let pipe: MinutesToTimePipe; 5 | 6 | beforeEach(() => { 7 | pipe = new MinutesToTimePipe(); 8 | }); 9 | 10 | it('create an instance', () => { 11 | expect(pipe).toBeTruthy(); 12 | }); 13 | 14 | describe('#transform', () => { 15 | it('should return minutes duration string', () => { 16 | expect(pipe.transform(30)).toEqual('30 min'); 17 | }); 18 | 19 | it('should return hours duration string', () => { 20 | expect(pipe.transform(60)).toEqual('1 h'); 21 | }); 22 | 23 | it('should return hours + minutes duration string', () => { 24 | expect(pipe.transform(90)).toEqual('1 h 30 min'); 25 | }); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /angular-http/src/app/pipes/minutes-to-time.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'minutesToTime' 5 | }) 6 | export class MinutesToTimePipe implements PipeTransform { 7 | 8 | transform(value: number): string { 9 | const hours = Math.floor(value / 60); 10 | const minutes = Math.floor(value % 60); 11 | 12 | const hoursString = hours ? `${hours} h` : ''; 13 | const minutesString = minutes ? `${minutes} min` : ''; 14 | 15 | return [hoursString, minutesString].filter((str) => str).join(' '); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /angular-http/src/app/pipes/order-by.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from '@angular/core'; 2 | 3 | @Pipe({ 4 | name: 'orderBy' 5 | }) 6 | export class OrderByPipe implements PipeTransform { 7 | 8 | transform(items: T[], field: string): T[] { 9 | return [...items].sort((first, second) => { 10 | if (first[field] < second[field]) { 11 | return -1; 12 | } else if (first[field] > second[field]) { 13 | return 1; 14 | } else { 15 | return 0; 16 | } 17 | }); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /angular-http/src/app/services/courses.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { CoursesService } from './courses.service'; 4 | 5 | describe('CoursesService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: CoursesService = TestBed.get(CoursesService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /angular-http/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-http/src/assets/.gitkeep -------------------------------------------------------------------------------- /angular-http/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /angular-http/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 | API_URL: 'http://localhost:3004', 8 | }; 9 | 10 | /* 11 | * For easier debugging in development mode, you can import the following file 12 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 13 | * 14 | * This import should be commented out in production mode because it will have a negative impact 15 | * on performance if an error is thrown. 16 | */ 17 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 18 | -------------------------------------------------------------------------------- /angular-http/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-http/src/favicon.ico -------------------------------------------------------------------------------- /angular-http/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AngularHttp 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /angular-http/src/main.ts: -------------------------------------------------------------------------------- 1 | import 'hammerjs'; 2 | import { enableProdMode } from '@angular/core'; 3 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 4 | 5 | import { AppModule } from './app/app.module'; 6 | import { environment } from './environments/environment'; 7 | 8 | if (environment.production) { 9 | enableProdMode(); 10 | } 11 | 12 | platformBrowserDynamic().bootstrapModule(AppModule) 13 | .catch(err => console.error(err)); 14 | -------------------------------------------------------------------------------- /angular-http/src/styles.scss: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | 3 | html, body { height: 100%; } 4 | body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; } 5 | -------------------------------------------------------------------------------- /angular-http/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: any; 11 | 12 | // First, initialize the Angular testing environment. 13 | getTestBed().initTestEnvironment( 14 | BrowserDynamicTestingModule, 15 | platformBrowserDynamicTesting() 16 | ); 17 | // Then we find all the tests. 18 | const context = require.context('./', true, /\.spec\.ts$/); 19 | // And load the modules. 20 | context.keys().map(context); 21 | -------------------------------------------------------------------------------- /angular-http/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/app", 5 | "types": [] 6 | }, 7 | "include": [ 8 | "src/**/*.ts" 9 | ], 10 | "exclude": [ 11 | "src/test.ts", 12 | "src/**/*.spec.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /angular-http/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 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "importHelpers": true, 14 | "target": "es2015", 15 | "typeRoots": [ 16 | "node_modules/@types" 17 | ], 18 | "lib": [ 19 | "es2018", 20 | "dom" 21 | ] 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /angular-http/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 | -------------------------------------------------------------------------------- /angular-modules-services/.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 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /angular-modules-services/.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 | -------------------------------------------------------------------------------- /angular-modules-services/README.md: -------------------------------------------------------------------------------- 1 | # AngularModulesServices 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 9.0.1. 4 | 5 | ## Development server 6 | 7 | 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. 8 | 9 | ## Code scaffolding 10 | 11 | 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`. 12 | 13 | ## Build 14 | 15 | 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. 16 | 17 | ## Running unit tests 18 | 19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 20 | 21 | ## Running end-to-end tests 22 | 23 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 24 | 25 | ## Further help 26 | 27 | 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). 28 | -------------------------------------------------------------------------------- /angular-modules-services/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'. -------------------------------------------------------------------------------- /angular-modules-services/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 | }; -------------------------------------------------------------------------------- /angular-modules-services/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('angular-modules-services 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 | -------------------------------------------------------------------------------- /angular-modules-services/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('app-root .content span')).getText() as Promise; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /angular-modules-services/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 | -------------------------------------------------------------------------------- /angular-modules-services/src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | 4 | 5 | const routes: Routes = []; 6 | 7 | @NgModule({ 8 | imports: [RouterModule.forRoot(routes)], 9 | exports: [RouterModule] 10 | }) 11 | export class AppRoutingModule { } 12 | -------------------------------------------------------------------------------- /angular-modules-services/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /angular-modules-services/src/app/app.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-modules-services/src/app/app.component.scss -------------------------------------------------------------------------------- /angular-modules-services/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | templateUrl: './app.component.html', 6 | styleUrls: ['./app.component.scss'] 7 | }) 8 | export class AppComponent { 9 | title = 'angular-modules-services'; 10 | } 11 | -------------------------------------------------------------------------------- /angular-modules-services/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | 4 | import { AppRoutingModule } from './app-routing.module'; 5 | import { AppComponent } from './app.component'; 6 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 7 | import { CoreModule } from './core/core.module'; 8 | import { FeedModule } from './feed/feed.module'; 9 | 10 | @NgModule({ 11 | declarations: [ 12 | AppComponent, 13 | ], 14 | imports: [ 15 | BrowserModule, 16 | AppRoutingModule, 17 | BrowserAnimationsModule, 18 | CoreModule, 19 | FeedModule, 20 | ], 21 | providers: [], 22 | bootstrap: [AppComponent] 23 | }) 24 | export class AppModule { } 25 | -------------------------------------------------------------------------------- /angular-modules-services/src/app/core/components/footer/footer.component.html: -------------------------------------------------------------------------------- 1 |

footer works!

2 | -------------------------------------------------------------------------------- /angular-modules-services/src/app/core/components/footer/footer.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-modules-services/src/app/core/components/footer/footer.component.scss -------------------------------------------------------------------------------- /angular-modules-services/src/app/core/components/footer/footer.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { FooterComponent } from './footer.component'; 4 | 5 | describe('FooterComponent', () => { 6 | let component: FooterComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ FooterComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(FooterComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-modules-services/src/app/core/components/footer/footer.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-footer', 5 | templateUrl: './footer.component.html', 6 | styleUrls: ['./footer.component.scss'] 7 | }) 8 | export class FooterComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit(): void { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /angular-modules-services/src/app/core/components/header/header.component.html: -------------------------------------------------------------------------------- 1 |

header works!

2 | -------------------------------------------------------------------------------- /angular-modules-services/src/app/core/components/header/header.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-modules-services/src/app/core/components/header/header.component.scss -------------------------------------------------------------------------------- /angular-modules-services/src/app/core/components/header/header.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { HeaderComponent } from './header.component'; 4 | 5 | describe('HeaderComponent', () => { 6 | let component: HeaderComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ HeaderComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(HeaderComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-modules-services/src/app/core/components/header/header.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-header', 5 | templateUrl: './header.component.html', 6 | styleUrls: ['./header.component.scss'] 7 | }) 8 | export class HeaderComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit(): void { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /angular-modules-services/src/app/core/core.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { HeaderComponent } from './components/header/header.component'; 4 | import { FooterComponent } from './components/footer/footer.component'; 5 | 6 | @NgModule({ 7 | declarations: [HeaderComponent, FooterComponent], 8 | imports: [ 9 | CommonModule 10 | ], 11 | exports: [HeaderComponent, FooterComponent] 12 | }) 13 | export class CoreModule { } 14 | -------------------------------------------------------------------------------- /angular-modules-services/src/app/core/services/logger.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { LoggerService } from './logger.service'; 4 | 5 | describe('LoggerService', () => { 6 | let service: LoggerService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(LoggerService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /angular-modules-services/src/app/core/services/logger.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | @Injectable({ 4 | providedIn: 'root' 5 | }) 6 | export class LoggerService { 7 | 8 | constructor() { } 9 | 10 | public log(...args) { 11 | console.log(...args); 12 | } 13 | 14 | public info(...args) { 15 | console.info(...args); 16 | } 17 | 18 | public error(...args) { 19 | console.error(...args); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /angular-modules-services/src/app/feed/components/posts-list/posts-list.component.html: -------------------------------------------------------------------------------- 1 |

My feed

2 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /angular-modules-services/src/app/feed/components/posts-list/posts-list.component.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | display: flex; 3 | flex-direction: column; 4 | justify-content: center; 5 | align-items: center; 6 | 7 | app-post { 8 | margin-top: 20px; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /angular-modules-services/src/app/feed/components/posts-list/posts-list.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { Post } from '@shared/models'; 3 | 4 | import { FeedService } from '../../services'; 5 | 6 | @Component({ 7 | selector: 'app-posts-list', 8 | templateUrl: './posts-list.component.html', 9 | styleUrls: ['./posts-list.component.scss'] 10 | }) 11 | export class PostsListComponent implements OnInit { 12 | posts: Post[]; 13 | 14 | constructor(private feedService: FeedService) {} 15 | 16 | ngOnInit(): void { 17 | this.posts = this.feedService.posts; 18 | } 19 | 20 | likePost(targetPost: Post) { 21 | this.feedService.likePost(targetPost); 22 | } 23 | 24 | unlikePost(targetPost: Post) { 25 | this.feedService.unlikePost(targetPost); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /angular-modules-services/src/app/feed/feed.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { PostsListComponent } from './components/posts-list/posts-list.component'; 4 | import { SharedModule } from '../shared/shared.module'; 5 | import { FeedService } from './services'; 6 | 7 | @NgModule({ 8 | declarations: [PostsListComponent], 9 | imports: [ 10 | CommonModule, 11 | SharedModule, 12 | ], 13 | providers: [FeedService], 14 | exports: [PostsListComponent] 15 | }) 16 | export class FeedModule { } 17 | -------------------------------------------------------------------------------- /angular-modules-services/src/app/feed/services/feed.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { FeedService } from './feed.service'; 4 | 5 | describe('FeedService', () => { 6 | let service: FeedService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(FeedService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /angular-modules-services/src/app/feed/services/feed.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Post } from '../../shared/models/post'; 3 | 4 | @Injectable() 5 | export class FeedService { 6 | public posts: Post[] = [ 7 | { 8 | id: 1, 9 | title: 'Breaking news!', 10 | text: 'Voluptate labore veniam sit exercitation nisi fugiat voluptate laboris', 11 | likes: 2, 12 | isLiked: false 13 | }, 14 | { 15 | id: 2, 16 | title: 'Meows news!', 17 | text: 'Laborum minim sit incididunt exercitation laborum commodo laborum.', 18 | likes: 42, 19 | isLiked: false 20 | } 21 | ]; 22 | 23 | likePost(targetPost: Post) { 24 | const postIdx = this.posts.findIndex((post) => post.id === targetPost.id); 25 | this.posts[postIdx].isLiked = true; 26 | this.posts[postIdx].likes = this.posts[postIdx].likes + 1; 27 | } 28 | 29 | unlikePost(targetPost: Post) { 30 | const postIdx = this.posts.findIndex((post) => post.id === targetPost.id); 31 | this.posts[postIdx].isLiked = false; 32 | this.posts[postIdx].likes = this.posts[postIdx].likes - 1; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /angular-modules-services/src/app/feed/services/index.ts: -------------------------------------------------------------------------------- 1 | export * from './feed.service'; 2 | -------------------------------------------------------------------------------- /angular-modules-services/src/app/shared/components/post/post.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | {{ post.title }} 4 | 5 |

{{ post.text }}

6 |
7 | 8 | 12 | 13 |
14 |
15 | -------------------------------------------------------------------------------- /angular-modules-services/src/app/shared/components/post/post.component.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | width: 500px; 3 | } 4 | -------------------------------------------------------------------------------- /angular-modules-services/src/app/shared/components/post/post.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { PostComponent } from './post.component'; 4 | 5 | describe('PostComponent', () => { 6 | let component: PostComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ PostComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(PostComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-modules-services/src/app/shared/components/post/post.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, Output, EventEmitter } from '@angular/core'; 2 | import { Post } from '../../models/post'; 3 | 4 | @Component({ 5 | selector: 'app-post', 6 | templateUrl: './post.component.html', 7 | styleUrls: ['./post.component.scss'], 8 | }) 9 | export class PostComponent { 10 | @Input() post: Post; 11 | @Output() like = new EventEmitter(); 12 | @Output() unlike = new EventEmitter(); 13 | 14 | constructor() {} 15 | 16 | likePost() { 17 | this.like.emit(this.post); 18 | } 19 | 20 | unlikePost() { 21 | this.unlike.emit(this.post); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /angular-modules-services/src/app/shared/models/index.ts: -------------------------------------------------------------------------------- 1 | export * from './post'; 2 | -------------------------------------------------------------------------------- /angular-modules-services/src/app/shared/models/post.ts: -------------------------------------------------------------------------------- 1 | export interface Post { 2 | id: number; 3 | title: string; 4 | text: string; 5 | likes: number; 6 | isLiked: boolean; 7 | } 8 | -------------------------------------------------------------------------------- /angular-modules-services/src/app/shared/shared.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { MatIconModule } from '@angular/material/icon'; 5 | import { MatCardModule } from '@angular/material/card'; 6 | import { MatButtonModule } from '@angular/material/button'; 7 | import { PostComponent } from './components/post/post.component'; 8 | 9 | const materialModules = [ 10 | MatIconModule, 11 | MatCardModule, 12 | MatButtonModule 13 | ]; 14 | 15 | @NgModule({ 16 | declarations: [ 17 | PostComponent 18 | ], 19 | imports: [ 20 | CommonModule, 21 | ...materialModules 22 | ], 23 | exports: [ 24 | ...materialModules, 25 | PostComponent, 26 | ] 27 | }) 28 | export class SharedModule { } 29 | -------------------------------------------------------------------------------- /angular-modules-services/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-modules-services/src/assets/.gitkeep -------------------------------------------------------------------------------- /angular-modules-services/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /angular-modules-services/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 | -------------------------------------------------------------------------------- /angular-modules-services/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-modules-services/src/favicon.ico -------------------------------------------------------------------------------- /angular-modules-services/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AngularModulesServices 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /angular-modules-services/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 | -------------------------------------------------------------------------------- /angular-modules-services/src/styles.scss: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | 3 | html, body { height: 100%; } 4 | body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; } 5 | -------------------------------------------------------------------------------- /angular-modules-services/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 | -------------------------------------------------------------------------------- /angular-modules-services/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 | -------------------------------------------------------------------------------- /angular-modules-services/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 | "typeRoots": [ 15 | "node_modules/@types" 16 | ], 17 | "lib": [ 18 | "es2018", 19 | "dom" 20 | ], 21 | "paths": { 22 | "@feed/*": ["src/app/feed/*"], 23 | "@core/*": ["src/app/core/*"], 24 | "@shared/*": ["src/app/shared/*"], 25 | }, 26 | }, 27 | "angularCompilerOptions": { 28 | "fullTemplateTypeCheck": true, 29 | "strictInjectionParameters": true 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /angular-modules-services/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 | -------------------------------------------------------------------------------- /angular-routing/.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 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /angular-routing/.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 | -------------------------------------------------------------------------------- /angular-routing/README.md: -------------------------------------------------------------------------------- 1 | # AngularRouting 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.0.3. 4 | 5 | ## Development server 6 | 7 | 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. 8 | 9 | ## Code scaffolding 10 | 11 | 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`. 12 | 13 | ## Build 14 | 15 | 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. 16 | 17 | ## Running unit tests 18 | 19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 20 | 21 | ## Running end-to-end tests 22 | 23 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 24 | 25 | ## Further help 26 | 27 | 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). 28 | -------------------------------------------------------------------------------- /angular-routing/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'. -------------------------------------------------------------------------------- /angular-routing/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 | }; -------------------------------------------------------------------------------- /angular-routing/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('Welcome to angular-routing!'); 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 | -------------------------------------------------------------------------------- /angular-routing/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get(browser.baseUrl) as Promise; 6 | } 7 | 8 | getTitleText() { 9 | return element(by.css('app-root h1')).getText() as Promise; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /angular-routing/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 | -------------------------------------------------------------------------------- /angular-routing/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/angular-routing'), 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 | -------------------------------------------------------------------------------- /angular-routing/src/app/another-module/another.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from "@angular/core"; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | 4 | import { OneComponent } from './pages/one/one.component'; 5 | import { TwoComponent } from './pages/two/two.component'; 6 | 7 | const routes: Routes = [ 8 | { path: '', component: OneComponent }, 9 | { path: 'two', component: TwoComponent }, 10 | ]; 11 | 12 | @NgModule({ 13 | declarations: [ 14 | OneComponent, 15 | TwoComponent, 16 | ], 17 | imports: [ 18 | RouterModule.forChild(routes), 19 | ], 20 | }) 21 | export class AnotherModule {} -------------------------------------------------------------------------------- /angular-routing/src/app/another-module/pages/one/one.component.html: -------------------------------------------------------------------------------- 1 |

2 | one works! 3 |

4 | -------------------------------------------------------------------------------- /angular-routing/src/app/another-module/pages/one/one.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-routing/src/app/another-module/pages/one/one.component.scss -------------------------------------------------------------------------------- /angular-routing/src/app/another-module/pages/one/one.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { OneComponent } from './one.component'; 4 | 5 | describe('OneComponent', () => { 6 | let component: OneComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ OneComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(OneComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-routing/src/app/another-module/pages/one/one.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-one', 5 | templateUrl: './one.component.html', 6 | styleUrls: ['./one.component.scss'] 7 | }) 8 | export class OneComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /angular-routing/src/app/another-module/pages/two/two.component.html: -------------------------------------------------------------------------------- 1 |

2 | two works! 3 |

4 | -------------------------------------------------------------------------------- /angular-routing/src/app/another-module/pages/two/two.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-routing/src/app/another-module/pages/two/two.component.scss -------------------------------------------------------------------------------- /angular-routing/src/app/another-module/pages/two/two.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { TwoComponent } from './two.component'; 4 | 5 | describe('TwoComponent', () => { 6 | let component: TwoComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ TwoComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(TwoComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-routing/src/app/another-module/pages/two/two.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-two', 5 | templateUrl: './two.component.html', 6 | styleUrls: ['./two.component.scss'] 7 | }) 8 | export class TwoComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /angular-routing/src/app/app.component.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | text-align: center; 3 | } 4 | 5 | mat-toolbar { 6 | justify-content: center; 7 | } 8 | 9 | a { 10 | display: inline-block; 11 | margin: 0 10px; 12 | padding: 0 10px; 13 | text-decoration: none; 14 | font-size: 16px; 15 | } 16 | 17 | .active { 18 | background-color: lightblue; 19 | font-weight: bold; 20 | } 21 | -------------------------------------------------------------------------------- /angular-routing/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { NavigationEnd, NavigationStart, Router } from '@angular/router'; 3 | 4 | @Component({ 5 | selector: 'app-root', 6 | templateUrl: './app.component.html', 7 | styleUrls: ['./app.component.scss'] 8 | }) 9 | export class AppComponent implements OnInit { 10 | constructor(public router: Router) {} 11 | 12 | public ngOnInit() { 13 | this.router.events.subscribe(event => { 14 | if (event instanceof NavigationStart) { 15 | console.log('Show spinner'); 16 | } 17 | 18 | if (event instanceof NavigationEnd) { 19 | console.log('Hide spinner'); 20 | } 21 | }); 22 | } 23 | 24 | public performSimpleRedirect() { 25 | this.router.navigateByUrl('/simple'); 26 | } 27 | 28 | public goToUserPage() { 29 | const obtainedUserId = '456'; 30 | this.router.navigate(['user', obtainedUserId]); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /angular-routing/src/app/guards/auth.guard.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async, inject } from '@angular/core/testing'; 2 | 3 | import { AuthGuard } from './auth.guard'; 4 | 5 | describe('SecurityGuard', () => { 6 | beforeEach(() => { 7 | TestBed.configureTestingModule({ 8 | providers: [AuthGuard] 9 | }); 10 | }); 11 | 12 | it('should ...', inject([AuthGuard], (guard: AuthGuard) => { 13 | expect(guard).toBeTruthy(); 14 | })); 15 | }); 16 | -------------------------------------------------------------------------------- /angular-routing/src/app/guards/auth.guard.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Observable, of } from 'rxjs'; 3 | import { CanActivate, Router, UrlTree } from '@angular/router'; 4 | 5 | @Injectable({ 6 | providedIn: 'root' 7 | }) 8 | export class AuthGuard implements CanActivate { 9 | constructor(private router: Router) {} 10 | 11 | public canActivate(): Observable | Promise | boolean { 12 | console.log('check Auth Guard'); 13 | return Promise.resolve(true); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /angular-routing/src/app/guards/loading.guard.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async, inject } from '@angular/core/testing'; 2 | 3 | import { LoadingGuard } from './loading.guard'; 4 | 5 | describe('LoadingGuardGuard', () => { 6 | beforeEach(() => { 7 | TestBed.configureTestingModule({ 8 | providers: [LoadingGuard] 9 | }); 10 | }); 11 | 12 | it('should ...', inject([LoadingGuard], (guard: LoadingGuard) => { 13 | expect(guard).toBeTruthy(); 14 | })); 15 | }); 16 | -------------------------------------------------------------------------------- /angular-routing/src/app/guards/loading.guard.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { CanLoad, Route } from '@angular/router'; 3 | import { Observable } from 'rxjs'; 4 | 5 | @Injectable({ 6 | providedIn: 'root' 7 | }) 8 | export class LoadingGuard implements CanLoad { 9 | public canLoad(route: Route): boolean | Observable | Promise { 10 | console.log('check Loading Guard'); 11 | return true; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /angular-routing/src/app/guards/new-one.guard.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async, inject } from '@angular/core/testing'; 2 | 3 | import { NewOneGuard } from './new-one.guard'; 4 | 5 | describe('NewOneGuard', () => { 6 | beforeEach(() => { 7 | TestBed.configureTestingModule({ 8 | providers: [NewOneGuard] 9 | }); 10 | }); 11 | 12 | it('should ...', inject([NewOneGuard], (guard: NewOneGuard) => { 13 | expect(guard).toBeTruthy(); 14 | })); 15 | }); 16 | -------------------------------------------------------------------------------- /angular-routing/src/app/guards/new-one.guard.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { CanActivate, CanLoad, Route, UrlSegment, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router'; 3 | import { Observable } from 'rxjs'; 4 | 5 | @Injectable({ 6 | providedIn: 'root' 7 | }) 8 | export class NewOneGuard implements CanActivate, CanLoad { 9 | canActivate( 10 | next: ActivatedRouteSnapshot, 11 | state: RouterStateSnapshot): Observable | Promise | boolean | UrlTree { 12 | return true; 13 | } 14 | canLoad( 15 | route: Route, 16 | segments: UrlSegment[]): Observable | Promise | boolean { 17 | return true; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /angular-routing/src/app/lazy-loaded/lazy-loaded-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | import { LazyLoadedPageComponent } from './pages/lazy-loaded-page/lazy-loaded-page.component'; 4 | 5 | const routes: Routes = [ 6 | { path: '', component: LazyLoadedPageComponent }, 7 | { path: 'another', component: LazyLoadedPageComponent } 8 | ]; 9 | 10 | @NgModule({ 11 | imports: [RouterModule.forChild(routes)], 12 | exports: [RouterModule] 13 | }) 14 | export class LazyLoadedRoutingModule { } 15 | -------------------------------------------------------------------------------- /angular-routing/src/app/lazy-loaded/lazy-loaded.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { LazyLoadedRoutingModule } from './lazy-loaded-routing.module'; 5 | import { LazyLoadedPageComponent } from './pages/lazy-loaded-page/lazy-loaded-page.component'; 6 | 7 | @NgModule({ 8 | declarations: [LazyLoadedPageComponent], 9 | imports: [ 10 | CommonModule, 11 | LazyLoadedRoutingModule 12 | ] 13 | }) 14 | export class LazyLoadedModule { } 15 | -------------------------------------------------------------------------------- /angular-routing/src/app/lazy-loaded/pages/lazy-loaded-page/lazy-loaded-page.component.html: -------------------------------------------------------------------------------- 1 |

lazy-loaded-page works!

2 | -------------------------------------------------------------------------------- /angular-routing/src/app/lazy-loaded/pages/lazy-loaded-page/lazy-loaded-page.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-routing/src/app/lazy-loaded/pages/lazy-loaded-page/lazy-loaded-page.component.scss -------------------------------------------------------------------------------- /angular-routing/src/app/lazy-loaded/pages/lazy-loaded-page/lazy-loaded-page.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { LazyLoadedPageComponent } from './lazy-loaded-page.component'; 4 | 5 | describe('LazyLoadedPageComponent', () => { 6 | let component: LazyLoadedPageComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ LazyLoadedPageComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(LazyLoadedPageComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-routing/src/app/lazy-loaded/pages/lazy-loaded-page/lazy-loaded-page.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-lazy-loaded-page', 5 | templateUrl: './lazy-loaded-page.component.html', 6 | styleUrls: ['./lazy-loaded-page.component.scss'] 7 | }) 8 | export class LazyLoadedPageComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /angular-routing/src/app/pages/admin-page/admin-page.component.html: -------------------------------------------------------------------------------- 1 |

2 | admin-page works! 3 |

4 | -------------------------------------------------------------------------------- /angular-routing/src/app/pages/admin-page/admin-page.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-routing/src/app/pages/admin-page/admin-page.component.scss -------------------------------------------------------------------------------- /angular-routing/src/app/pages/admin-page/admin-page.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { AdminPageComponent } from './admin-page.component'; 4 | 5 | describe('AdminPageComponent', () => { 6 | let component: AdminPageComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ AdminPageComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(AdminPageComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-routing/src/app/pages/admin-page/admin-page.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-admin-page', 5 | templateUrl: './admin-page.component.html', 6 | styleUrls: ['./admin-page.component.scss'] 7 | }) 8 | export class AdminPageComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /angular-routing/src/app/pages/home-page/home-page.component.html: -------------------------------------------------------------------------------- 1 |

2 | home-page works! 3 |

4 | -------------------------------------------------------------------------------- /angular-routing/src/app/pages/home-page/home-page.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-routing/src/app/pages/home-page/home-page.component.scss -------------------------------------------------------------------------------- /angular-routing/src/app/pages/home-page/home-page.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { HomePageComponent } from './home-page.component'; 4 | 5 | describe('HomePageComponent', () => { 6 | let component: HomePageComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ HomePageComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(HomePageComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-routing/src/app/pages/home-page/home-page.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-home-page', 5 | templateUrl: './home-page.component.html', 6 | styleUrls: ['./home-page.component.scss'] 7 | }) 8 | export class HomePageComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /angular-routing/src/app/pages/not-found/not-found.component.html: -------------------------------------------------------------------------------- 1 |

2 | 404 - Page not found 3 |

4 | -------------------------------------------------------------------------------- /angular-routing/src/app/pages/not-found/not-found.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-routing/src/app/pages/not-found/not-found.component.scss -------------------------------------------------------------------------------- /angular-routing/src/app/pages/not-found/not-found.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { NotFoundComponent } from './not-found.component'; 4 | 5 | describe('NotFoundComponent', () => { 6 | let component: NotFoundComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ NotFoundComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(NotFoundComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-routing/src/app/pages/not-found/not-found.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-not-found', 5 | templateUrl: './not-found.component.html', 6 | styleUrls: ['./not-found.component.scss'] 7 | }) 8 | export class NotFoundComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /angular-routing/src/app/pages/simple-redicrect/simple-redicrect.component.html: -------------------------------------------------------------------------------- 1 |

2 | simple-redicrect works! 3 |

4 | -------------------------------------------------------------------------------- /angular-routing/src/app/pages/simple-redicrect/simple-redicrect.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-routing/src/app/pages/simple-redicrect/simple-redicrect.component.scss -------------------------------------------------------------------------------- /angular-routing/src/app/pages/simple-redicrect/simple-redicrect.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { SimpleRedicrectComponent } from './simple-redicrect.component'; 4 | 5 | describe('SimpleRedicrectComponent', () => { 6 | let component: SimpleRedicrectComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ SimpleRedicrectComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(SimpleRedicrectComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-routing/src/app/pages/simple-redicrect/simple-redicrect.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-simple-redicrect', 5 | templateUrl: './simple-redicrect.component.html', 6 | styleUrls: ['./simple-redicrect.component.scss'] 7 | }) 8 | export class SimpleRedicrectComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /angular-routing/src/app/pages/tabs/pages/left-tab/left-tab.component.html: -------------------------------------------------------------------------------- 1 |

2 | left-tab works! 3 |

4 | -------------------------------------------------------------------------------- /angular-routing/src/app/pages/tabs/pages/left-tab/left-tab.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-routing/src/app/pages/tabs/pages/left-tab/left-tab.component.scss -------------------------------------------------------------------------------- /angular-routing/src/app/pages/tabs/pages/left-tab/left-tab.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { LeftTabComponent } from './left-tab.component'; 4 | 5 | describe('LeftTabComponent', () => { 6 | let component: LeftTabComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ LeftTabComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(LeftTabComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-routing/src/app/pages/tabs/pages/left-tab/left-tab.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-left-tab', 5 | templateUrl: './left-tab.component.html', 6 | styleUrls: ['./left-tab.component.scss'] 7 | }) 8 | export class LeftTabComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /angular-routing/src/app/pages/tabs/pages/right-tab/right-tab.component.html: -------------------------------------------------------------------------------- 1 |

2 | right-tab works! 3 |

4 | -------------------------------------------------------------------------------- /angular-routing/src/app/pages/tabs/pages/right-tab/right-tab.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-routing/src/app/pages/tabs/pages/right-tab/right-tab.component.scss -------------------------------------------------------------------------------- /angular-routing/src/app/pages/tabs/pages/right-tab/right-tab.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { RightTabComponent } from './right-tab.component'; 4 | 5 | describe('RightTabComponent', () => { 6 | let component: RightTabComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ RightTabComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(RightTabComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-routing/src/app/pages/tabs/pages/right-tab/right-tab.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-right-tab', 5 | templateUrl: './right-tab.component.html', 6 | styleUrls: ['./right-tab.component.scss'] 7 | }) 8 | export class RightTabComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /angular-routing/src/app/pages/tabs/tabs.component.html: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /angular-routing/src/app/pages/tabs/tabs.component.scss: -------------------------------------------------------------------------------- 1 | .nav-group { 2 | margin-top: 40px; 3 | 4 | a { 5 | color: grey; 6 | margin: 0 20px; 7 | } 8 | 9 | .active { 10 | color: #1976d2; 11 | font-weight: bold; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /angular-routing/src/app/pages/tabs/tabs.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { TabsComponent } from './tabs.component'; 4 | 5 | describe('TabsComponent', () => { 6 | let component: TabsComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ TabsComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(TabsComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-routing/src/app/pages/tabs/tabs.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-tabs', 5 | templateUrl: './tabs.component.html', 6 | styleUrls: ['./tabs.component.scss'] 7 | }) 8 | export class TabsComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /angular-routing/src/app/pages/user-page/user-page.component.html: -------------------------------------------------------------------------------- 1 |

2 | user-page works! 3 |

4 | 5 |

6 | User id: {{ userId }} 7 |

8 | 9 | 10 | -------------------------------------------------------------------------------- /angular-routing/src/app/pages/user-page/user-page.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-routing/src/app/pages/user-page/user-page.component.scss -------------------------------------------------------------------------------- /angular-routing/src/app/pages/user-page/user-page.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { UserPageComponent } from './user-page.component'; 4 | 5 | describe('UserPageComponent', () => { 6 | let component: UserPageComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ UserPageComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(UserPageComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-routing/src/app/pages/user-page/user-page.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { ActivatedRoute } from '@angular/router'; 3 | 4 | @Component({ 5 | selector: 'app-user-page', 6 | templateUrl: './user-page.component.html', 7 | styleUrls: ['./user-page.component.scss'] 8 | }) 9 | export class UserPageComponent implements OnInit { 10 | public userId: number; 11 | 12 | constructor(public route: ActivatedRoute) {} 13 | 14 | ngOnInit() { 15 | console.log(this.route.snapshot.data); 16 | } 17 | 18 | public showInfo() { 19 | console.log('Log Snapshot:', this.route.snapshot); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /angular-routing/src/app/resolvers/data.resolver.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router'; 3 | import { timer } from 'rxjs'; 4 | import { map } from 'rxjs/operators'; 5 | 6 | @Injectable({ 7 | providedIn: 'root' 8 | }) 9 | export class DataResolver implements Resolve { 10 | resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): any { 11 | console.log(route.data); 12 | return timer(5000).pipe(map(() => `current user id: ${route.params.id}`)); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /angular-routing/src/app/some-other-feature/some-other-feature-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | 4 | const routes: Routes = []; 5 | 6 | @NgModule({ 7 | imports: [RouterModule.forChild(routes)], 8 | exports: [RouterModule] 9 | }) 10 | export class SomeOtherFeatureRoutingModule { } 11 | -------------------------------------------------------------------------------- /angular-routing/src/app/some-other-feature/some-other-feature.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { SomeOtherFeatureRoutingModule } from './some-other-feature-routing.module'; 5 | 6 | @NgModule({ 7 | declarations: [], 8 | imports: [ 9 | CommonModule, 10 | SomeOtherFeatureRoutingModule 11 | ] 12 | }) 13 | export class SomeOtherFeatureModule { } 14 | -------------------------------------------------------------------------------- /angular-routing/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-routing/src/assets/.gitkeep -------------------------------------------------------------------------------- /angular-routing/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /angular-routing/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 | -------------------------------------------------------------------------------- /angular-routing/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-routing/src/favicon.ico -------------------------------------------------------------------------------- /angular-routing/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AngularRouting 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /angular-routing/src/main.ts: -------------------------------------------------------------------------------- 1 | import 'hammerjs'; 2 | import { enableProdMode } from '@angular/core'; 3 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 4 | 5 | import { AppModule } from './app/app.module'; 6 | import { environment } from './environments/environment'; 7 | 8 | if (environment.production) { 9 | enableProdMode(); 10 | } 11 | 12 | platformBrowserDynamic().bootstrapModule(AppModule) 13 | .catch(err => console.error(err)); 14 | -------------------------------------------------------------------------------- /angular-routing/src/styles.scss: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | 3 | html, body { height: 100%; } 4 | body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; } 5 | -------------------------------------------------------------------------------- /angular-routing/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: any; 11 | 12 | // First, initialize the Angular testing environment. 13 | getTestBed().initTestEnvironment( 14 | BrowserDynamicTestingModule, 15 | platformBrowserDynamicTesting() 16 | ); 17 | // Then we find all the tests. 18 | const context = require.context('./', true, /\.spec\.ts$/); 19 | // And load the modules. 20 | context.keys().map(context); 21 | -------------------------------------------------------------------------------- /angular-routing/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/app", 5 | "types": [] 6 | }, 7 | "include": [ 8 | "src/**/*.ts" 9 | ], 10 | "exclude": [ 11 | "src/test.ts", 12 | "src/**/*.spec.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /angular-routing/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 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "importHelpers": true, 14 | "target": "es2015", 15 | "typeRoots": [ 16 | "node_modules/@types" 17 | ], 18 | "lib": [ 19 | "es2018", 20 | "dom" 21 | ] 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /angular-routing/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 | -------------------------------------------------------------------------------- /angular-unit-testing/.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 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /angular-unit-testing/.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 | -------------------------------------------------------------------------------- /angular-unit-testing/README.md: -------------------------------------------------------------------------------- 1 | # AngularUnitTesting 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.0.3. 4 | 5 | ## Development server 6 | 7 | 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. 8 | 9 | ## Code scaffolding 10 | 11 | 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`. 12 | 13 | ## Build 14 | 15 | 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. 16 | 17 | ## Running unit tests 18 | 19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 20 | 21 | ## Running end-to-end tests 22 | 23 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 24 | 25 | ## Further help 26 | 27 | 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). 28 | -------------------------------------------------------------------------------- /angular-unit-testing/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'. -------------------------------------------------------------------------------- /angular-unit-testing/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 | }; -------------------------------------------------------------------------------- /angular-unit-testing/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('Welcome to angular-unit-testing!'); 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 | -------------------------------------------------------------------------------- /angular-unit-testing/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get(browser.baseUrl) as Promise; 6 | } 7 | 8 | getTitleText() { 9 | return element(by.css('app-root h1')).getText() as Promise; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /angular-unit-testing/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 | -------------------------------------------------------------------------------- /angular-unit-testing/src/app/app.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-unit-testing/src/app/app.component.scss -------------------------------------------------------------------------------- /angular-unit-testing/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | templateUrl: './app.component.html', 6 | styleUrls: ['./app.component.scss'] 7 | }) 8 | export class AppComponent { 9 | title = 'angular-unit-testing'; 10 | } 11 | -------------------------------------------------------------------------------- /angular-unit-testing/src/app/first-look/dependencies-testing/components/some/some.component.html: -------------------------------------------------------------------------------- 1 |

some works!

2 | -------------------------------------------------------------------------------- /angular-unit-testing/src/app/first-look/dependencies-testing/components/some/some.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-unit-testing/src/app/first-look/dependencies-testing/components/some/some.component.scss -------------------------------------------------------------------------------- /angular-unit-testing/src/app/first-look/dependencies-testing/components/some/some.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { SomeService } from '../../services/some.service'; 3 | 4 | @Component({ 5 | selector: 'app-some', 6 | templateUrl: './some.component.html', 7 | styleUrls: ['./some.component.scss'] 8 | }) 9 | export class SomeComponent implements OnInit { 10 | message: string; 11 | asyncData: string; 12 | 13 | constructor(private someService: SomeService) { } 14 | 15 | ngOnInit() { 16 | this.message = this.someService.getMessage(); 17 | } 18 | 19 | getAsyncData() { 20 | this.someService.getAsyncData().subscribe((data) => { 21 | this.asyncData = data; 22 | }); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /angular-unit-testing/src/app/first-look/dependencies-testing/services/some.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { SomeService } from './some.service'; 4 | 5 | describe('SomeService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: SomeService = TestBed.get(SomeService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /angular-unit-testing/src/app/first-look/dependencies-testing/services/some.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { of } from 'rxjs'; 3 | import { delay } from 'rxjs/operators'; 4 | 5 | @Injectable({ 6 | providedIn: 'root' 7 | }) 8 | export class SomeService { 9 | getMessage() { 10 | return 'Hey there!'; 11 | } 12 | 13 | getAsyncData() { 14 | return of('Hey there!').pipe(delay(2000)); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /angular-unit-testing/src/app/first-look/instance-testing/instance-testing.component.html: -------------------------------------------------------------------------------- 1 |

instance-testing works!

2 | -------------------------------------------------------------------------------- /angular-unit-testing/src/app/first-look/instance-testing/instance-testing.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-unit-testing/src/app/first-look/instance-testing/instance-testing.component.scss -------------------------------------------------------------------------------- /angular-unit-testing/src/app/first-look/instance-testing/instance-testing.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-instance-testing', 5 | templateUrl: './instance-testing.component.html', 6 | styleUrls: ['./instance-testing.component.scss'] 7 | }) 8 | export class InstanceTestingComponent implements OnInit { 9 | data: string; 10 | isLoggedIn = false; 11 | 12 | constructor() { } 13 | 14 | ngOnInit() { 15 | this.data = 'Hey there!'; 16 | } 17 | 18 | login() { 19 | this.isLoggedIn = true; 20 | } 21 | 22 | multiply(a: number, b: number) { 23 | return a * b; 24 | } 25 | 26 | decide(condition: boolean) { 27 | if (condition) { 28 | return 'It\'s true'; 29 | } else { 30 | return 'It\'s false'; 31 | } 32 | } 33 | 34 | decideTernaty(condition: boolean) { 35 | return `It's ${ condition ? 'true' : 'false' }`; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /angular-unit-testing/src/app/test-bed/components/login-widget-with-service/login-widget-with-service.component.html: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /angular-unit-testing/src/app/test-bed/components/login-widget-with-service/login-widget-with-service.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-unit-testing/src/app/test-bed/components/login-widget-with-service/login-widget-with-service.component.scss -------------------------------------------------------------------------------- /angular-unit-testing/src/app/test-bed/components/login-widget-with-service/login-widget-with-service.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { LoginService } from '../../services/login.service'; 3 | 4 | @Component({ 5 | selector: 'app-login-widget-with-service', 6 | templateUrl: './login-widget-with-service.component.html', 7 | styleUrls: ['./login-widget-with-service.component.scss'] 8 | }) 9 | export class LoginWidgetWithServiceComponent { 10 | public isLoggedIn = false; 11 | 12 | constructor(private loginService: LoginService) { } 13 | 14 | public login() { 15 | this.loginService.login().subscribe((isLoggedIn) => { 16 | this.isLoggedIn = isLoggedIn; 17 | }); 18 | } 19 | 20 | get message(): string { 21 | return this.isLoggedIn 22 | ? 'You are logged in' 23 | : 'You are logged out'; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /angular-unit-testing/src/app/test-bed/components/login-widget/login-widget.component.html: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /angular-unit-testing/src/app/test-bed/components/login-widget/login-widget.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-unit-testing/src/app/test-bed/components/login-widget/login-widget.component.scss -------------------------------------------------------------------------------- /angular-unit-testing/src/app/test-bed/components/login-widget/login-widget.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-login-widget', 5 | templateUrl: './login-widget.component.html', 6 | styleUrls: ['./login-widget.component.scss'] 7 | }) 8 | export class LoginWidgetComponent { 9 | public isLoggedIn = false; 10 | 11 | public login(): void { 12 | this.isLoggedIn = true; 13 | } 14 | 15 | get message(): string { 16 | return this.isLoggedIn 17 | ? 'You are logged in' 18 | : 'You are logged out'; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /angular-unit-testing/src/app/test-bed/components/publication-card/publication-card.component.html: -------------------------------------------------------------------------------- 1 |

{{ publication.title }}

2 | 3 | -------------------------------------------------------------------------------- /angular-unit-testing/src/app/test-bed/components/publication-card/publication-card.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-unit-testing/src/app/test-bed/components/publication-card/publication-card.component.scss -------------------------------------------------------------------------------- /angular-unit-testing/src/app/test-bed/components/publication-card/publication-card.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, Output, EventEmitter } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-publication-card', 5 | templateUrl: './publication-card.component.html', 6 | styleUrls: ['./publication-card.component.scss'] 7 | }) 8 | export class PublicationCardComponent { 9 | @Input() public publication: any; 10 | @Output() public like = new EventEmitter(); 11 | 12 | public onLike() { 13 | this.like.emit(this.publication); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /angular-unit-testing/src/app/test-bed/components/user-profile/user-info/user-info.component.html: -------------------------------------------------------------------------------- 1 |

user-info works!

2 | -------------------------------------------------------------------------------- /angular-unit-testing/src/app/test-bed/components/user-profile/user-info/user-info.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-unit-testing/src/app/test-bed/components/user-profile/user-info/user-info.component.scss -------------------------------------------------------------------------------- /angular-unit-testing/src/app/test-bed/components/user-profile/user-info/user-info.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { UserInfoComponent } from './user-info.component'; 4 | 5 | describe('UserInfoComponent', () => { 6 | let component: UserInfoComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ UserInfoComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(UserInfoComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-unit-testing/src/app/test-bed/components/user-profile/user-info/user-info.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-user-info', 5 | templateUrl: './user-info.component.html', 6 | styleUrls: ['./user-info.component.scss'] 7 | }) 8 | export class UserInfoComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /angular-unit-testing/src/app/test-bed/components/user-profile/user-menu/user-menu.component.html: -------------------------------------------------------------------------------- 1 |

user-menu works!

2 | -------------------------------------------------------------------------------- /angular-unit-testing/src/app/test-bed/components/user-profile/user-menu/user-menu.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-unit-testing/src/app/test-bed/components/user-profile/user-menu/user-menu.component.scss -------------------------------------------------------------------------------- /angular-unit-testing/src/app/test-bed/components/user-profile/user-menu/user-menu.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { UserMenuComponent } from './user-menu.component'; 4 | 5 | describe('UserMenuComponent', () => { 6 | let component: UserMenuComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ UserMenuComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(UserMenuComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-unit-testing/src/app/test-bed/components/user-profile/user-menu/user-menu.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-user-menu', 5 | templateUrl: './user-menu.component.html', 6 | styleUrls: ['./user-menu.component.scss'] 7 | }) 8 | export class UserMenuComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /angular-unit-testing/src/app/test-bed/components/user-profile/user-picture/user-picture.component.html: -------------------------------------------------------------------------------- 1 |

user-picture works!

2 | -------------------------------------------------------------------------------- /angular-unit-testing/src/app/test-bed/components/user-profile/user-picture/user-picture.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-unit-testing/src/app/test-bed/components/user-profile/user-picture/user-picture.component.scss -------------------------------------------------------------------------------- /angular-unit-testing/src/app/test-bed/components/user-profile/user-picture/user-picture.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { UserPictureComponent } from './user-picture.component'; 4 | 5 | describe('UserPictureComponent', () => { 6 | let component: UserPictureComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ UserPictureComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(UserPictureComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /angular-unit-testing/src/app/test-bed/components/user-profile/user-picture/user-picture.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-user-picture', 5 | templateUrl: './user-picture.component.html', 6 | styleUrls: ['./user-picture.component.scss'] 7 | }) 8 | export class UserPictureComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /angular-unit-testing/src/app/test-bed/components/user-profile/user-profile.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

User profile

4 | 7 |
8 | 9 | 10 | 11 | 12 | 14 | 15 |
16 | -------------------------------------------------------------------------------- /angular-unit-testing/src/app/test-bed/components/user-profile/user-profile.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-unit-testing/src/app/test-bed/components/user-profile/user-profile.component.scss -------------------------------------------------------------------------------- /angular-unit-testing/src/app/test-bed/components/user-profile/user-profile.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-user-profile', 5 | templateUrl: './user-profile.component.html', 6 | styleUrls: ['./user-profile.component.scss'] 7 | }) 8 | export class UserProfileComponent { 9 | public publications = [ 10 | { id: 1, title: 'Breaking news!' }, 11 | { id: 2, title: 'Meows news!' }, 12 | ]; 13 | } 14 | -------------------------------------------------------------------------------- /angular-unit-testing/src/app/test-bed/services/login.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { LoginService } from './login.service'; 4 | 5 | describe('LoginService', () => { 6 | beforeEach(() => TestBed.configureTestingModule({})); 7 | 8 | it('should be created', () => { 9 | const service: LoginService = TestBed.get(LoginService); 10 | expect(service).toBeTruthy(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /angular-unit-testing/src/app/test-bed/services/login.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { of } from 'rxjs'; 3 | 4 | @Injectable({ 5 | providedIn: 'root' 6 | }) 7 | export class LoginService { 8 | login() { return of(true); } 9 | } 10 | -------------------------------------------------------------------------------- /angular-unit-testing/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-unit-testing/src/assets/.gitkeep -------------------------------------------------------------------------------- /angular-unit-testing/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /angular-unit-testing/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 | -------------------------------------------------------------------------------- /angular-unit-testing/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pavelrazuvalau/angular-lectures/4fd13d60b7d4c55b0ab8850333701669c2054d5a/angular-unit-testing/src/favicon.ico -------------------------------------------------------------------------------- /angular-unit-testing/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AngularUnitTesting 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /angular-unit-testing/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 | -------------------------------------------------------------------------------- /angular-unit-testing/src/styles.scss: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /angular-unit-testing/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: any; 11 | 12 | // First, initialize the Angular testing environment. 13 | getTestBed().initTestEnvironment( 14 | BrowserDynamicTestingModule, 15 | platformBrowserDynamicTesting() 16 | ); 17 | // Then we find all the tests. 18 | const context = require.context('./', true, /\.spec\.ts$/); 19 | // And load the modules. 20 | context.keys().map(context); 21 | -------------------------------------------------------------------------------- /angular-unit-testing/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/app", 5 | "types": [] 6 | }, 7 | "include": [ 8 | "src/**/*.ts" 9 | ], 10 | "exclude": [ 11 | "src/test.ts", 12 | "src/**/*.spec.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /angular-unit-testing/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 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "importHelpers": true, 14 | "target": "es2015", 15 | "typeRoots": [ 16 | "node_modules/@types" 17 | ], 18 | "lib": [ 19 | "es2018", 20 | "dom" 21 | ] 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /angular-unit-testing/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 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "lockfileVersion": 1 3 | } 4 | -------------------------------------------------------------------------------- /rxjs-observables/live-examples.js: -------------------------------------------------------------------------------- 1 | const { of, interval } = require('rxjs'); 2 | const { map, pluck, mapTo, switchMapTo, delay, finalize, concatMapTo, concatMap, mergeMap } = require('rxjs/operators'); 3 | 4 | const obs1 = interval(1000); 5 | const obs2 = of(2).pipe( 6 | delay(5000), 7 | finalize(() => console.log('request has been cancelled')) 8 | ); 9 | 10 | console.log('obs1 start'); 11 | obs1.pipe( 12 | mergeMap(() => obs2) 13 | ).subscribe((value) => console.log('next: ', value)); 14 | -------------------------------------------------------------------------------- /rxjs-observables/observable-custom.js: -------------------------------------------------------------------------------- 1 | class Observable { 2 | constructor(source) { 3 | this.source = source; 4 | } 5 | 6 | subscribe(next, error, complete) { 7 | for (let data of this.source) { 8 | next(data); 9 | } 10 | 11 | complete(); 12 | } 13 | 14 | filter() { 15 | this.source = [...this.source].filter(data => data > 'h').join(''); 16 | return this; 17 | } 18 | } 19 | 20 | const source = new Observable('Observable') 21 | .filter() 22 | .subscribe((data) => { 23 | console.log(data); 24 | }, () => { console.error('error') }, 25 | () => { console.log('complete') } 26 | ) 27 | -------------------------------------------------------------------------------- /rxjs-observables/observables-intro.js: -------------------------------------------------------------------------------- 1 | function observe(source, next, error, complete) { 2 | source.forEach(data => { 3 | if (data > 2) { 4 | return error(); 5 | } 6 | 7 | next(data); 8 | }); 9 | 10 | complete(); 11 | } 12 | 13 | observe([1,2,3], (data) => { 14 | console.log(data); 15 | }, (error) => console.error('error'), 16 | () => console.log('complete') 17 | ) 18 | -------------------------------------------------------------------------------- /rxjs-observables/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rxjs-observables", 3 | "version": "1.0.0", 4 | "description": "", 5 | "scripts": { 6 | "start": "tsc" 7 | }, 8 | "author": "", 9 | "license": "ISC", 10 | "dependencies": { 11 | "rxjs": "^6.5.3", 12 | "typescript": "^3.6.4" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /rxjs-observables/src/01-observable-creation.ts: -------------------------------------------------------------------------------- 1 | import { Observable } from 'rxjs'; 2 | 3 | const source = new Observable((observer) => { 4 | let count = 0; 5 | 6 | const timer = setInterval(() => { 7 | observer.next(count); 8 | count++; 9 | }, 500); 10 | 11 | return () => clearInterval(timer); 12 | }); 13 | 14 | // source.subscribe((value) => console.log(value)); 15 | 16 | const promise = new Promise((resolve, reject) => { 17 | let count = 0; 18 | 19 | const timer = setInterval(() => { 20 | resolve(count); 21 | count++; 22 | }, 500); 23 | 24 | return () => clearInterval(timer); 25 | }).then(console.log); 26 | -------------------------------------------------------------------------------- /rxjs-observables/src/02-observable-handling.ts: -------------------------------------------------------------------------------- 1 | import { Observable } from 'rxjs'; 2 | 3 | const source = new Observable(observer => { 4 | let count = 0; 5 | console.log('Observable created'); 6 | 7 | const timer = setInterval(() => { 8 | observer.next(count); 9 | count++; 10 | }, 1000); 11 | 12 | setTimeout(() => observer.complete(), 4500); 13 | 14 | return () => { 15 | console.log('Observable destroyed'); 16 | clearInterval(timer); 17 | }; 18 | }); 19 | 20 | const subscription = source.subscribe( 21 | value => console.log('next: ', value), 22 | error => console.error('error: ', error), 23 | () => console.log('complete') 24 | ); 25 | -------------------------------------------------------------------------------- /rxjs-observables/src/03-observable-error.ts: -------------------------------------------------------------------------------- 1 | import { Observable } from 'rxjs'; 2 | 3 | const source = Observable.create(observer => { 4 | let count = 0; 5 | console.log('Observable created'); 6 | 7 | const timer = setInterval(() => { 8 | if (count < 3) { 9 | observer.next(count++); 10 | } else { 11 | observer.error('Whoops!'); 12 | } 13 | }, 1000); 14 | 15 | return () => { 16 | console.log('Observable destroyed'); 17 | clearInterval(timer); 18 | }; 19 | }); 20 | 21 | const subscription = source.subscribe( 22 | value => console.log('next: ', value), 23 | error => console.error('error: ', error), 24 | () => console.log('complete') 25 | ); 26 | -------------------------------------------------------------------------------- /rxjs-observables/src/04-observable-complete.ts: -------------------------------------------------------------------------------- 1 | import { Observable } from 'rxjs'; 2 | 3 | const source = Observable.create(observer => { 4 | let count = 0; 5 | console.log('Observable created'); 6 | 7 | const timer = setInterval(() => { 8 | if (count < 3) { 9 | observer.next(count++); 10 | } else { 11 | observer.complete(); 12 | } 13 | }, 1000); 14 | 15 | return () => { 16 | console.log('Observable destroyed'); 17 | clearInterval(timer); 18 | }; 19 | }); 20 | 21 | const subscription = source.subscribe( 22 | value => console.log('next: ', value), 23 | error => console.error('error: ', error), 24 | () => console.log('complete') 25 | ); 26 | -------------------------------------------------------------------------------- /rxjs-observables/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "outDir": "./dist/out-tsc", 5 | "sourceMap": true, 6 | "declaration": false, 7 | "moduleResolution": "node", 8 | "module": "commonjs", 9 | "experimentalDecorators": true, 10 | "target": "es5", 11 | "lib": [ 12 | "es2017", 13 | "dom" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /ts-intro/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "requires": true, 3 | "lockfileVersion": 1, 4 | "dependencies": { 5 | "typescript": { 6 | "version": "3.3.4000", 7 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.4000.tgz", 8 | "integrity": "sha512-jjOcCZvpkl2+z7JFn0yBOoLQyLoIkNZAs/fYJkUG6VKy6zLPHJGfQJYFHzibB6GJaF/8QrcECtlQ5cpvRHSMEA==" 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ts-intro/src/00-primitives.ts: -------------------------------------------------------------------------------- 1 | // Boolean 2 | let isMoodGood: boolean = true; 3 | // let isMoodGood = true; // the same 4 | 5 | // isMoodGood = 'Yes, it is!'; // Error 6 | 7 | // Number 8 | let integer: number = 42; 9 | let decimal: number = 10.23; 10 | let hex: number = 0xf00d; 11 | let binary: number = 0b1010; 12 | let octal: number = 0o444; 13 | 14 | // let decimal = 10.23; // the same 15 | // decimal = '10.23'; // Error 16 | 17 | // String 18 | let firstName: string = 'Tommy'; 19 | let lastName: string = 'Wiseau'; 20 | let greetings: string = `Hello ${firstName} ${lastName}!`; 21 | 22 | // firstName = 101; // Error 23 | 24 | // Multiple types 25 | 26 | let smth: number | string | boolean = 'some stuff'; 27 | smth = 34; 28 | smth = false; 29 | smth = 'string'; 30 | // smth = {}; // Error 31 | 32 | -------------------------------------------------------------------------------- /ts-intro/src/01-objects-arrays.ts: -------------------------------------------------------------------------------- 1 | let task: { name: string, description: string } = { 2 | name: '2Do', 3 | description: 'I\'m a cool task', 4 | // smthElse: 'Whoops', 5 | }; 6 | 7 | let mapLike: { [key: string]: string } = { 8 | key: 'value', 9 | key2: 'value2', 10 | key3: 'value2', 11 | key4: 'value2' 12 | // otherKey: 1, // Error 13 | }; 14 | 15 | let array: number[] = [1, 2, 3, 4]; 16 | // array.push('5'); // Error 17 | 18 | let tuple: [number, string] = [12, 'September']; 19 | tuple = [13, 'September']; 20 | // tuple = ['13', 'September']; // Error -------------------------------------------------------------------------------- /ts-intro/src/04-features.js: -------------------------------------------------------------------------------- 1 | function makeArr(arg) { 2 | return [arg]; 3 | } 4 | ; 5 | console.log(makeArr('abc'), makeArr(123), makeArr('a1b2c3')); 6 | var someStatus = 'on'; 7 | var daysOfWeek; 8 | (function (daysOfWeek) { 9 | daysOfWeek[daysOfWeek["Sun"] = 0] = "Sun"; 10 | daysOfWeek[daysOfWeek["Mon"] = 1] = "Mon"; 11 | daysOfWeek[daysOfWeek["Tue"] = 2] = "Tue"; 12 | daysOfWeek[daysOfWeek["Wed"] = 3] = "Wed"; 13 | daysOfWeek[daysOfWeek["Thu"] = 4] = "Thu"; 14 | daysOfWeek[daysOfWeek["Fri"] = 5] = "Fri"; 15 | daysOfWeek[daysOfWeek["Sat"] = 6] = "Sat"; 16 | })(daysOfWeek || (daysOfWeek = {})); 17 | ; 18 | var today = daysOfWeek.Fri; 19 | -------------------------------------------------------------------------------- /ts-intro/src/04-features.ts: -------------------------------------------------------------------------------- 1 | function makeArr(arg: T): T[] { 2 | return [arg]; 3 | }; 4 | 5 | console.log(makeArr('abc'), makeArr(123)); 6 | 7 | interface List { 8 | data: T, 9 | desc: string, 10 | } 11 | 12 | type StringList = List; 13 | 14 | class Abc { 15 | data: T; 16 | } 17 | 18 | let bar = new Abc(); 19 | 20 | // ------- 21 | 22 | type state = 'on' | 'off'; 23 | let someStatus: state = 'on'; 24 | 25 | enum DaysOfWeek { 26 | Sun, // 0 27 | Mon, // 1 28 | Tue, // 2 29 | Wed, // 3 30 | Thu, // 4 31 | Fri, // 5 32 | Sat = 6 33 | }; 34 | 35 | let today = DaysOfWeek.Thu; 36 | 37 | enum CatNames { 38 | Masya, // 0 39 | Lucy = 5, 40 | Chloe, // 6 41 | Sophie = 10, 42 | // .... // 11, 12, ... 43 | Barsik = 'justCat', 44 | Murzik = 1, // Error 45 | }; 46 | 47 | interface Cat { 48 | name: CatNames 49 | } 50 | 51 | const cat: Cat = { 52 | name: CatNames.Masya, 53 | } 54 | 55 | console.log(CatNames[0], CatNames.Lucy); // Masya, 5 -------------------------------------------------------------------------------- /ts-intro/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "outDir": "./dist/out-tsc", 5 | "sourceMap": true, 6 | "declaration": false, 7 | "moduleResolution": "node", 8 | "experimentalDecorators": true, 9 | "target": "es6", 10 | "lib": [ 11 | "es2017", 12 | "dom" 13 | ] 14 | } 15 | } -------------------------------------------------------------------------------- /webpack-intro/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-intro", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "src/index.js", 6 | "dependencies": { 7 | "css-loader": "^2.1.1", 8 | "file-loader": "^3.0.1", 9 | "html-webpack-plugin": "^3.2.0", 10 | "ts-loader": "5.3.3", 11 | "typescript": "^2.9.2", 12 | "webpack": "4.29.6" 13 | }, 14 | "devDependencies": { 15 | "extract-text-webpack-plugin": "^3.0.2", 16 | "mini-css-extract-plugin": "^0.5.0", 17 | "style-loader": "^0.23.1", 18 | "webpack-cli": "^3.3.0", 19 | "webpack-dev-server": "^3.2.1" 20 | }, 21 | "scripts": { 22 | "test": "echo \"Error: no test specified\" && exit 1", 23 | "webpack": "webpack", 24 | "dev-server": "webpack-dev-server" 25 | }, 26 | "author": "", 27 | "license": "ISC" 28 | } 29 | -------------------------------------------------------------------------------- /webpack-intro/src/another.js: -------------------------------------------------------------------------------- 1 | import './styles.css'; 2 | 3 | console.log('another log'); -------------------------------------------------------------------------------- /webpack-intro/src/index.js: -------------------------------------------------------------------------------- 1 | import { someLog } from './some'; 2 | 3 | console.log('Run index.js'); 4 | 5 | if (BOOL_VALUE) { 6 | console.log(SOME_VALUE); 7 | } 8 | 9 | someLog(); 10 | -------------------------------------------------------------------------------- /webpack-intro/src/some.js: -------------------------------------------------------------------------------- 1 | export function someLog() { 2 | console.log('log from some.js'); 3 | } 4 | -------------------------------------------------------------------------------- /webpack-intro/src/styles.css: -------------------------------------------------------------------------------- 1 | .header { 2 | color: red; 3 | } -------------------------------------------------------------------------------- /webpack-intro/src/typed.ts: -------------------------------------------------------------------------------- 1 | function plus(a: number, b: number): number { 2 | return a + b; 3 | } 4 | 5 | console.log('Plus:', plus(1, 3)); 6 | -------------------------------------------------------------------------------- /webpack-intro/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "outDir": "./dist/out-tsc", 5 | "sourceMap": true, 6 | "declaration": false, 7 | "moduleResolution": "node", 8 | "experimentalDecorators": true, 9 | "target": "es5", 10 | "lib": [ 11 | "es2017", 12 | "dom" 13 | ] 14 | } 15 | } --------------------------------------------------------------------------------