diff --git a/.all-contributorsrc b/.all-contributorsrc index f82debe..41b441c 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -26,9 +26,9 @@ "symbol": "🇵🇹", "description": "Translate in Portuguese" }, - "translation-pt-BR": { - "symbol": "🇧🇷", - "description": "Translate in Brazilian Portuguese" + "translation-ru": { + "symbol": "🇷🇺", + "description": "Translate in Russian" } }, "contributors": [ @@ -47,6 +47,38 @@ "translation-fr" ] }, + { + "login": "jdegand", + "name": "J. Degand", + "avatar_url": "https://avatars.githubusercontent.com/u/70610011?v=4", + "profile": "https://github.com/jdegand", + "contributions": [ + "doc", + "content", + "code" + ] + }, + { + "login": "DeveshChau", + "name": "Devesh Chaudhari", + "avatar_url": "https://avatars.githubusercontent.com/u/9509673?v=4", + "profile": "https://github.com/DeveshChau", + "contributions": [ + "code", + "bug", + "challenge" + ] + }, + { + "login": "stillst", + "name": "stillst", + "avatar_url": "https://avatars.githubusercontent.com/u/1463098?v=4", + "profile": "https://github.com/stillst", + "contributions": [ + "challenge", + "translation-ru" + ] + }, { "login": "alan-bio", "name": "Alan Dragicevich", @@ -94,26 +126,6 @@ "code" ] }, - { - "login": "jdegand", - "name": "J. Degand", - "avatar_url": "https://avatars.githubusercontent.com/u/70610011?v=4", - "profile": "https://github.com/jdegand", - "contributions": [ - "doc" - ] - }, - { - "login": "DeveshChau", - "name": "Devesh Chaudhari", - "avatar_url": "https://avatars.githubusercontent.com/u/9509673?v=4", - "profile": "https://github.com/DeveshChau", - "contributions": [ - "code", - "bug", - "challenge" - ] - }, { "login": "dmmishchenko", "name": "Dmitriy Mishchenko", @@ -157,13 +169,32 @@ "avatar_url": "https://avatars.githubusercontent.com/u/142346548?v=4", "profile": "https://github.com/kabrunko-dev/", "contributions": [ - "translation-pt-BR", + "code", + "translation-pt", + "doc" + ] + }, + { + "login": "ErickRodrCodes", + "name": "Erick Rodriguez", + "avatar_url": "https://avatars.githubusercontent.com/u/1978642?v=4", + "profile": "http://www.streamoverlaypro.com", + "contributions": [ + "translation-es" + ] + }, + { + "login": "eduardoRoth", + "name": "Eduardo Roth", + "avatar_url": "https://avatars.githubusercontent.com/u/5419161?v=4", + "profile": "https://eduardoroth.dev", + "contributions": [ "doc", - "code" + "translation-es" ] } ], "contributorsPerLine": 7, "linkToUsage": true, "commitType": "docs" -} +} \ No newline at end of file diff --git a/.github/workflows/close-inactive-pr.yml b/.github/workflows/close-inactive-pr.yml index 19a62db..d92c25c 100644 --- a/.github/workflows/close-inactive-pr.yml +++ b/.github/workflows/close-inactive-pr.yml @@ -16,10 +16,12 @@ jobs: days-before-issue-close: -1 stale-issue-label: 'stale' stale-issue-message: 'This issue is stale because it has been open for 20 days with no activity.' + exempt-issue-labels: 'long-term' days-before-pr-stale: 20 days-before-pr-close: 7 stale-pr-label: 'stale' stale-pr-message: 'This pull request is stale because it has been open for 20 days with no activity.' close-pr-message: 'This pull request was closed because it has been inactive for 7 days since being marked as stale.' only-pr-labels: 'answer' + exempt-pr-labels: 'challenge-creation, long-term' repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index b0decd9..5472d6b 100644 --- a/.gitignore +++ b/.gitignore @@ -19,7 +19,6 @@ node_modules # IDE - VSCode .vscode/* -!.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json @@ -41,4 +40,4 @@ Thumbs.db .angular TODO.md -.nx/cache \ No newline at end of file +.nx/cache diff --git a/.vscode/settings.json b/.vscode/settings.json index 1471fb9..e0a1291 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,6 @@ { - "eslint.validate": ["json"] + "eslint.validate": [ + "json" + ], + "cSpell.language": "en,es-ES" } diff --git a/README.md b/README.md index 25713df..af4d668 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ If you would like to propose a challenge, this project is open source, so feel f ## Challenges -Check [all 40 challenges](https://angular-challenges.vercel.app/) +Check [all 43 challenges](https://angular-challenges.vercel.app/) ## Contributors ✨ @@ -35,20 +35,25 @@ Check [all 40 challenges](https://angular-challenges.vercel.app/) Laforge Thomas
Laforge Thomas

🧩 💻 📖 🖋 🤔 🎨 🇫🇷 + J. Degand
J. Degand

📖 🖋 💻 + Devesh Chaudhari
Devesh Chaudhari

💻 🐛 🧩 + stillst
stillst

🧩 🇷🇺 Alan Dragicevich
Alan Dragicevich

📖 Michel EDIGHOFFER
Michel EDIGHOFFER

📖 Gerardo Sebastian Gonzalez
Gerardo Sebastian Gonzalez

📖 - Evseev Yuriy
Evseev Yuriy

🐛 - Tomer953
Tomer953

🐛 📖 💻 - J. Degand
J. Degand

📖 - Devesh Chaudhari
Devesh Chaudhari

💻 🐛 🧩 + Evseev Yuriy
Evseev Yuriy

🐛 + Tomer953
Tomer953

🐛 📖 💻 Dmitriy Mishchenko
Dmitriy Mishchenko

📖 Sagar Devkota
Sagar Devkota

📖 💻 Nelson Gutierrez
Nelson Gutierrez

🇪🇸 Hossain K. M.
Hossain K. M.

📖 - Diogo Nishikawa
Diogo Nishikawa

🇧🇷 📖 💻 + Diogo Nishikawa
Diogo Nishikawa

🇵🇹 📖 💻 + + + Erick Rodriguez
Erick Rodriguez

🇪🇸 + Eduardo Roth
Eduardo Roth

📖 🇪🇸 diff --git a/apps/angular/anchor-scrolling/jest.config.ts b/apps/angular/anchor-scrolling/jest.config.ts index 6915111..1665728 100644 --- a/apps/angular/anchor-scrolling/jest.config.ts +++ b/apps/angular/anchor-scrolling/jest.config.ts @@ -2,7 +2,7 @@ export default { displayName: 'angular-anchor-scrolling', preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], + setupFilesAfterEnv: ['/src/subscription-setup.ts'], coverageDirectory: '../../../coverage/apps/angular/anchor-scrolling', transform: { '^.+\\.(ts|mjs|js|html)$': [ diff --git a/apps/angular/anchor-scrolling/src/app/app.component.ts b/apps/angular/anchor-scrolling/src/app/app.component.ts index 5a930fb..3fb7c5d 100644 --- a/apps/angular/anchor-scrolling/src/app/app.component.ts +++ b/apps/angular/anchor-scrolling/src/app/app.component.ts @@ -5,6 +5,8 @@ import { RouterOutlet } from '@angular/router'; standalone: true, imports: [RouterOutlet], selector: 'app-root', - template: ` `, + template: ` + + `, }) export class AppComponent {} diff --git a/apps/angular/anchor-scrolling/src/app/foo.component.ts b/apps/angular/anchor-scrolling/src/app/foo.component.ts index a5109a8..87f9b59 100644 --- a/apps/angular/anchor-scrolling/src/app/foo.component.ts +++ b/apps/angular/anchor-scrolling/src/app/foo.component.ts @@ -7,7 +7,7 @@ import { NavButtonComponent } from './nav-button.component'; selector: 'app-foo', template: ` Welcome to foo page - Home Page + Home Page
section 1
section 2
`, diff --git a/apps/angular/anchor-scrolling/src/app/home.component.ts b/apps/angular/anchor-scrolling/src/app/home.component.ts index 836a198..0f24ff6 100644 --- a/apps/angular/anchor-scrolling/src/app/home.component.ts +++ b/apps/angular/anchor-scrolling/src/app/home.component.ts @@ -6,7 +6,7 @@ import { NavButtonComponent } from './nav-button.component'; imports: [NavButtonComponent], selector: 'app-home', template: ` - Foo Page + Foo Page
Empty Scroll Bottom diff --git a/apps/angular/anchor-scrolling/src/index.html b/apps/angular/anchor-scrolling/src/index.html index 9a98ab3..7a2a4b3 100644 --- a/apps/angular/anchor-scrolling/src/index.html +++ b/apps/angular/anchor-scrolling/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/angular/anchor-scrolling/src/main.ts b/apps/angular/anchor-scrolling/src/main.ts index 4ecc5cf..7961924 100644 --- a/apps/angular/anchor-scrolling/src/main.ts +++ b/apps/angular/anchor-scrolling/src/main.ts @@ -1,8 +1,8 @@ -import { appConfig } from './app/app.config'; import { bootstrapApplication } from '@angular/platform-browser'; +import { appConfig } from './app/app.config'; import { AppComponent } from './app/app.component'; bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err) + console.error(err), ); diff --git a/apps/angular/bug-cd/jest.config.ts b/apps/angular/bug-cd/jest.config.ts index 1f24a7c..ded316d 100644 --- a/apps/angular/bug-cd/jest.config.ts +++ b/apps/angular/bug-cd/jest.config.ts @@ -2,7 +2,7 @@ export default { displayName: 'angular-bug-cd', preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], + setupFilesAfterEnv: ['/src/subscription-setup.ts'], coverageDirectory: '../../../coverage/apps/angular/bug-cd', transform: { '^.+\\.(ts|mjs|js|html)$': [ diff --git a/apps/angular/bug-cd/src/app/app.component.ts b/apps/angular/bug-cd/src/app/app.component.ts index 3b45baa..046492f 100644 --- a/apps/angular/bug-cd/src/app/app.component.ts +++ b/apps/angular/bug-cd/src/app/app.component.ts @@ -6,7 +6,7 @@ import { RouterOutlet } from '@angular/router'; imports: [RouterOutlet], selector: 'app-root', template: ` -

My Application

+

My Application

diff --git a/apps/angular/bug-cd/src/app/bar.component.ts b/apps/angular/bug-cd/src/app/bar.component.ts index 26eef1e..b7a5392 100644 --- a/apps/angular/bug-cd/src/app/bar.component.ts +++ b/apps/angular/bug-cd/src/app/bar.component.ts @@ -2,6 +2,8 @@ import { Component } from '@angular/core'; @Component({ selector: 'app-bar', standalone: true, - template: ` BarComponent `, + template: ` + BarComponent + `, }) export class BarComponent {} diff --git a/apps/angular/bug-cd/src/app/foo.component.ts b/apps/angular/bug-cd/src/app/foo.component.ts index 8006ecb..a5b1207 100644 --- a/apps/angular/bug-cd/src/app/foo.component.ts +++ b/apps/angular/bug-cd/src/app/foo.component.ts @@ -2,6 +2,8 @@ import { Component } from '@angular/core'; @Component({ selector: 'app-foo', standalone: true, - template: `Foo Component `, + template: ` + Foo Component + `, }) export class FooComponent {} diff --git a/apps/angular/bug-cd/src/app/main-navigation.component.ts b/apps/angular/bug-cd/src/app/main-navigation.component.ts index c30281a..c8a6f6d 100644 --- a/apps/angular/bug-cd/src/app/main-navigation.component.ts +++ b/apps/angular/bug-cd/src/app/main-navigation.component.ts @@ -15,7 +15,7 @@ interface MenuItem { template: ` {{ menu.name }} diff --git a/apps/angular/bug-cd/src/index.html b/apps/angular/bug-cd/src/index.html index c05f415..ab925a7 100644 --- a/apps/angular/bug-cd/src/index.html +++ b/apps/angular/bug-cd/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/angular/bug-cd/src/main.ts b/apps/angular/bug-cd/src/main.ts index 514c89a..f3a7223 100644 --- a/apps/angular/bug-cd/src/main.ts +++ b/apps/angular/bug-cd/src/main.ts @@ -1,7 +1,7 @@ import { bootstrapApplication } from '@angular/platform-browser'; -import { appConfig } from './app/app.config'; import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err) + console.error(err), ); diff --git a/apps/angular/context-outlet-type/src/app/list.component.ts b/apps/angular/context-outlet-type/src/app/list.component.ts index 4c58a1c..5212a42 100644 --- a/apps/angular/context-outlet-type/src/app/list.component.ts +++ b/apps/angular/context-outlet-type/src/app/list.component.ts @@ -17,11 +17,10 @@ import { *ngTemplateOutlet=" listTemplateRef || emptyRef; context: { $implicit: item, appList: item, index: i } - "> - + ">
- No Template + No Template `, changeDetection: ChangeDetectionStrategy.OnPush, }) diff --git a/apps/angular/context-outlet-type/src/app/person.component.ts b/apps/angular/context-outlet-type/src/app/person.component.ts index 4c33ae3..1550cf2 100644 --- a/apps/angular/context-outlet-type/src/app/person.component.ts +++ b/apps/angular/context-outlet-type/src/app/person.component.ts @@ -17,7 +17,7 @@ interface Person { context: { $implicit: person.name, age: person.age } "> - No Template + No Template `, }) export class PersonComponent { diff --git a/apps/angular/context-outlet-type/src/index.html b/apps/angular/context-outlet-type/src/index.html index 0f087d3..b3ee6c6 100644 --- a/apps/angular/context-outlet-type/src/index.html +++ b/apps/angular/context-outlet-type/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/angular/crud/jest.config.ts b/apps/angular/crud/jest.config.ts index 74a17f1..4850991 100644 --- a/apps/angular/crud/jest.config.ts +++ b/apps/angular/crud/jest.config.ts @@ -2,7 +2,7 @@ export default { displayName: 'angular-crud', preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], + setupFilesAfterEnv: ['/src/subscription-setup.ts'], globals: {}, coverageDirectory: '../../../coverage/apps/angular/crud', transform: { diff --git a/apps/angular/crud/src/app/app.component.ts b/apps/angular/crud/src/app/app.component.ts index 400d403..8c3d1b8 100644 --- a/apps/angular/crud/src/app/app.component.ts +++ b/apps/angular/crud/src/app/app.component.ts @@ -42,7 +42,7 @@ export class AppComponent implements OnInit { headers: { 'Content-type': 'application/json; charset=UTF-8', }, - } + }, ) .subscribe((todoUpdated: any) => { this.todos[todoUpdated.id - 1] = todoUpdated; diff --git a/apps/angular/crud/src/app/app.config.ts b/apps/angular/crud/src/app/app.config.ts index cf4075b..de0a3cc 100644 --- a/apps/angular/crud/src/app/app.config.ts +++ b/apps/angular/crud/src/app/app.config.ts @@ -1,6 +1,5 @@ -import { ApplicationConfig } from '@angular/core'; -import { enableProdMode, importProvidersFrom } from '@angular/core'; import { HttpClientModule } from '@angular/common/http'; +import { ApplicationConfig, importProvidersFrom } from '@angular/core'; export const appConfig: ApplicationConfig = { providers: [importProvidersFrom(HttpClientModule)], }; diff --git a/apps/angular/crud/src/index.html b/apps/angular/crud/src/index.html index 601c359..c556437 100644 --- a/apps/angular/crud/src/index.html +++ b/apps/angular/crud/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/angular/crud/src/main.ts b/apps/angular/crud/src/main.ts index ea9f26c..9bb5c30 100644 --- a/apps/angular/crud/src/main.ts +++ b/apps/angular/crud/src/main.ts @@ -4,5 +4,5 @@ import { bootstrapApplication } from '@angular/platform-browser'; import { AppComponent } from './app/app.component'; bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err) + console.error(err), ); diff --git a/apps/angular/decoupling/src/app/app.component.ts b/apps/angular/decoupling/src/app/app.component.ts index e595318..34082c3 100644 --- a/apps/angular/decoupling/src/app/app.component.ts +++ b/apps/angular/decoupling/src/app/app.component.ts @@ -6,6 +6,8 @@ import { Component } from '@angular/core'; standalone: true, imports: [BtnDisabledDirective, BtnHelmetDirective], selector: 'app-root', - template: ` `, + template: ` + + `, }) export class AppComponent {} diff --git a/apps/angular/decoupling/src/index.html b/apps/angular/decoupling/src/index.html index c1bf2b7..25b5ea1 100644 --- a/apps/angular/decoupling/src/index.html +++ b/apps/angular/decoupling/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/angular/di/src/app/app.component.ts b/apps/angular/di/src/app/app.component.ts index bacff72..e57a5a5 100644 --- a/apps/angular/di/src/app/app.component.ts +++ b/apps/angular/di/src/app/app.component.ts @@ -16,7 +16,7 @@ interface ProductContext { export class ProductDirective { static ngTemplateContextGuard( dir: ProductDirective, - ctx: unknown + ctx: unknown, ): ctx is ProductContext { return true; } diff --git a/apps/angular/di/src/app/currency.pipe.ts b/apps/angular/di/src/app/currency.pipe.ts index 1c8fcc0..9d90e52 100644 --- a/apps/angular/di/src/app/currency.pipe.ts +++ b/apps/angular/di/src/app/currency.pipe.ts @@ -11,7 +11,7 @@ export class CurrencyPipe implements PipeTransform { transform(price: number) { return this.currencyService.symbol$.pipe( - map((s) => `${String(price)}${s}`) + map((s) => `${String(price)}${s}`), ); } } diff --git a/apps/angular/di/src/app/currency.service.ts b/apps/angular/di/src/app/currency.service.ts index 076ffa1..38b403e 100644 --- a/apps/angular/di/src/app/currency.service.ts +++ b/apps/angular/di/src/app/currency.service.ts @@ -20,7 +20,7 @@ export const currency: Currency[] = [ export class CurrencyService extends ComponentStore<{ code: string }> { readonly code$ = this.select((state) => state.code); readonly symbol$ = this.code$.pipe( - map((code) => currency.find((c) => c.code === code)?.symbol ?? code) + map((code) => currency.find((c) => c.code === code)?.symbol ?? code), ); constructor() { diff --git a/apps/angular/di/src/index.html b/apps/angular/di/src/index.html index 98e94c0..c120f5b 100644 --- a/apps/angular/di/src/index.html +++ b/apps/angular/di/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/angular/injection-token/jest.config.ts b/apps/angular/injection-token/jest.config.ts index d7105f8..c48bb49 100644 --- a/apps/angular/injection-token/jest.config.ts +++ b/apps/angular/injection-token/jest.config.ts @@ -2,7 +2,7 @@ export default { displayName: 'angular-injection-token', preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], + setupFilesAfterEnv: ['/src/subscription-setup.ts'], coverageDirectory: '../../../coverage/apps/angular/injection-token', transform: { '^.+\\.(ts|mjs|js|html)$': [ diff --git a/apps/angular/injection-token/src/app/app.component.ts b/apps/angular/injection-token/src/app/app.component.ts index 51cf42e..5ac8087 100644 --- a/apps/angular/injection-token/src/app/app.component.ts +++ b/apps/angular/injection-token/src/app/app.component.ts @@ -5,15 +5,17 @@ import { RouterLink, RouterOutlet } from '@angular/router'; standalone: true, imports: [RouterOutlet, RouterLink], selector: 'app-root', - template: `
- -
- `, + + `, host: { class: 'p-10 flex flex-col', }, diff --git a/apps/angular/injection-token/src/app/phone.component.ts b/apps/angular/injection-token/src/app/phone.component.ts index 73866ca..a58b3cd 100644 --- a/apps/angular/injection-token/src/app/phone.component.ts +++ b/apps/angular/injection-token/src/app/phone.component.ts @@ -5,10 +5,12 @@ import { TimerContainerComponent } from './timer-container.component'; selector: 'app-phone', standalone: true, imports: [TimerContainerComponent], - template: `
+ template: ` +
Phone Call Timer:

(should be 2000s)

- `, + + `, }) export default class PhoneComponent {} diff --git a/apps/angular/injection-token/src/app/timer.component.ts b/apps/angular/injection-token/src/app/timer.component.ts index db5b963..95707ec 100644 --- a/apps/angular/injection-token/src/app/timer.component.ts +++ b/apps/angular/injection-token/src/app/timer.component.ts @@ -6,7 +6,9 @@ import { DEFAULT_TIMER } from './data'; @Component({ selector: 'timer', standalone: true, - template: ` Timer running {{ timer() }} `, + template: ` + Timer running {{ timer() }} + `, }) export class TimerComponent { timer = toSignal(interval(DEFAULT_TIMER)); diff --git a/apps/angular/injection-token/src/app/video.component.ts b/apps/angular/injection-token/src/app/video.component.ts index 5ea2c2b..2c21807 100644 --- a/apps/angular/injection-token/src/app/video.component.ts +++ b/apps/angular/injection-token/src/app/video.component.ts @@ -5,10 +5,12 @@ import { TimerContainerComponent } from './timer-container.component'; selector: 'app-video', standalone: true, imports: [TimerContainerComponent], - template: `
+ template: ` +
Video Call Timer:

(should be the default 1000s)

- `, + + `, }) export default class VideoComponent {} diff --git a/apps/angular/injection-token/src/index.html b/apps/angular/injection-token/src/index.html index befe4cf..3c35787 100644 --- a/apps/angular/injection-token/src/index.html +++ b/apps/angular/injection-token/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/angular/injection-token/src/main.ts b/apps/angular/injection-token/src/main.ts index 514c89a..f3a7223 100644 --- a/apps/angular/injection-token/src/main.ts +++ b/apps/angular/injection-token/src/main.ts @@ -1,7 +1,7 @@ import { bootstrapApplication } from '@angular/platform-browser'; -import { appConfig } from './app/app.config'; import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err) + console.error(err), ); diff --git a/apps/angular/interop-rxjs-signal/jest.config.ts b/apps/angular/interop-rxjs-signal/jest.config.ts index 23956eb..53f7481 100644 --- a/apps/angular/interop-rxjs-signal/jest.config.ts +++ b/apps/angular/interop-rxjs-signal/jest.config.ts @@ -2,7 +2,7 @@ export default { displayName: 'angular-interop-rxjs-signal', preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], + setupFilesAfterEnv: ['/src/subscription-setup.ts'], coverageDirectory: '../../../coverage/apps/angular/interop-rxjs-signal', transform: { '^.+\\.(ts|mjs|js|html)$': [ diff --git a/apps/angular/interop-rxjs-signal/src/app/app.component.ts b/apps/angular/interop-rxjs-signal/src/app/app.component.ts index f63192e..7b83d14 100644 --- a/apps/angular/interop-rxjs-signal/src/app/app.component.ts +++ b/apps/angular/interop-rxjs-signal/src/app/app.component.ts @@ -5,7 +5,9 @@ import { RouterOutlet } from '@angular/router'; standalone: true, imports: [RouterOutlet], selector: 'app-root', - template: ``, + template: ` + + `, styles: [''], }) export class AppComponent {} diff --git a/apps/angular/interop-rxjs-signal/src/app/app.config.ts b/apps/angular/interop-rxjs-signal/src/app/app.config.ts index cd49643..2885bb0 100644 --- a/apps/angular/interop-rxjs-signal/src/app/app.config.ts +++ b/apps/angular/interop-rxjs-signal/src/app/app.config.ts @@ -23,7 +23,7 @@ export const appConfig: ApplicationConfig = { redirectTo: '', }, ], - withComponentInputBinding() + withComponentInputBinding(), ), ], }; diff --git a/apps/angular/interop-rxjs-signal/src/app/detail/detail.component.ts b/apps/angular/interop-rxjs-signal/src/app/detail/detail.component.ts index c1493b2..3576db4 100644 --- a/apps/angular/interop-rxjs-signal/src/app/detail/detail.component.ts +++ b/apps/angular/interop-rxjs-signal/src/app/detail/detail.component.ts @@ -9,13 +9,25 @@ import { Photo } from '../photo.model'; imports: [DatePipe, RouterLink], template: ` {{ photo.title }} -

Title: {{ photo.title }}

-

Owner: {{ photo.ownername }}

-

Date: {{ photo.datetaken | date }}

-

Tags: {{ photo.tags }}

+

+ Title: + {{ photo.title }} +

+

+ Owner: + {{ photo.ownername }} +

+

+ Date: + {{ photo.datetaken | date }} +

+

+ Tags: + {{ photo.tags }} +

diff --git a/apps/angular/interop-rxjs-signal/src/app/list/photos.component.ts b/apps/angular/interop-rxjs-signal/src/app/list/photos.component.ts index b8705e3..29dc0c3 100644 --- a/apps/angular/interop-rxjs-signal/src/app/list/photos.component.ts +++ b/apps/angular/interop-rxjs-signal/src/app/list/photos.component.ts @@ -25,7 +25,7 @@ import { PhotoStore } from './photos.store'; RouterLinkWithHref, ], template: ` -

Photos

+

Photos

Search @@ -33,23 +33,23 @@ import { PhotoStore } from './photos.store'; type="text" matInput [formControl]="search" - placeholder="write an article" /> + placeholder="find a photo" />
-
+
@@ -93,7 +93,7 @@ export default class PhotosComponent implements OnInit { this.search.setValue(search); this.formInit = true; } - }) + }), ); private formInit = false; @@ -104,8 +104,8 @@ export default class PhotosComponent implements OnInit { this.search.valueChanges.pipe( skipWhile(() => !this.formInit), debounceTime(300), - distinctUntilChanged() - ) + distinctUntilChanged(), + ), ); } diff --git a/apps/angular/interop-rxjs-signal/src/app/list/photos.store.ts b/apps/angular/interop-rxjs-signal/src/app/list/photos.store.ts index 8f039c4..01de2d4 100644 --- a/apps/angular/interop-rxjs-signal/src/app/list/photos.store.ts +++ b/apps/angular/interop-rxjs-signal/src/app/list/photos.store.ts @@ -47,7 +47,7 @@ export class PhotoStore private readonly endOfPage$ = this.select( this.page$, this.pages$, - (page, pages) => page === pages + (page, pages) => page === pages, ); readonly vm$ = this.select( @@ -60,7 +60,7 @@ export class PhotoStore loading: this.loading$, error: this.error$, }, - { debounce: true } + { debounce: true }, ); ngrxOnStoreInit() { @@ -82,7 +82,7 @@ export class PhotoStore this.select({ search: this.search$, page: this.page$, - }) + }), ); } @@ -91,21 +91,21 @@ export class PhotoStore ...state, search, page: 1, - }) + }), ); readonly nextPage = this.updater( (state): PhotoState => ({ ...state, page: state.page + 1, - }) + }), ); readonly previousPage = this.updater( (state): PhotoState => ({ ...state, page: state.page - 1, - }) + }), ); readonly searchPhotos = this.effect<{ search: string; page: number }>( @@ -123,13 +123,13 @@ export class PhotoStore }); localStorage.setItem( PHOTO_STATE_KEY, - JSON.stringify({ search, page }) + JSON.stringify({ search, page }), ); }, - (error: unknown) => this.patchState({ error, loading: false }) - ) - ) - ) - ) + (error: unknown) => this.patchState({ error, loading: false }), + ), + ), + ), + ), ); } diff --git a/apps/angular/interop-rxjs-signal/src/app/photo.model.ts b/apps/angular/interop-rxjs-signal/src/app/photo.model.ts index 5c78a91..c3360fd 100644 --- a/apps/angular/interop-rxjs-signal/src/app/photo.model.ts +++ b/apps/angular/interop-rxjs-signal/src/app/photo.model.ts @@ -1,10 +1,22 @@ export interface Photo { id: string; - title: string; - tags: string; owner: string; - ownername: string; + secret: string; + server: string; + farm: number; + title: string; + ispublic: number; + isfriend: number; + isfamily: number; datetaken: string; + datetakengranularity: number; + datetakenunknown: string; + ownername: string; + tags: string; url_q: string; + height_q: number; + width_q: number; url_m: string; + height_m: number; + width_m: number; } diff --git a/apps/angular/interop-rxjs-signal/src/app/photos.service.ts b/apps/angular/interop-rxjs-signal/src/app/photos.service.ts index a7999e6..c540118 100644 --- a/apps/angular/interop-rxjs-signal/src/app/photos.service.ts +++ b/apps/angular/interop-rxjs-signal/src/app/photos.service.ts @@ -5,9 +5,13 @@ import { Photo } from './photo.model'; export interface FlickrAPIResponse { photos: { + page: number; pages: number; + perpage: number; + total: number; photo: Photo[]; }; + stat: string; } @Injectable({ providedIn: 'root' }) @@ -16,7 +20,7 @@ export class PhotoService { public searchPublicPhotos( searchTerm: string, - page: number + page: number, ): Observable { return this.http.get( 'https://www.flickr.com/services/rest/', @@ -33,7 +37,7 @@ export class PhotoService { extras: 'tags,date_taken,owner_name,url_q,url_m', api_key: 'c3050d39a5bb308d9921bef0e15c437d', }, - } + }, ); } } diff --git a/apps/angular/interop-rxjs-signal/src/index.html b/apps/angular/interop-rxjs-signal/src/index.html index b072aa4..1c69fbc 100644 --- a/apps/angular/interop-rxjs-signal/src/index.html +++ b/apps/angular/interop-rxjs-signal/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/angular/interop-rxjs-signal/src/main.ts b/apps/angular/interop-rxjs-signal/src/main.ts index 514c89a..f3a7223 100644 --- a/apps/angular/interop-rxjs-signal/src/main.ts +++ b/apps/angular/interop-rxjs-signal/src/main.ts @@ -1,7 +1,7 @@ import { bootstrapApplication } from '@angular/platform-browser'; -import { appConfig } from './app/app.config'; import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err) + console.error(err), ); diff --git a/apps/angular/module-to-standalone/src/app/app.component.ts b/apps/angular/module-to-standalone/src/app/app.component.ts index 91a72fa..95eeab5 100644 --- a/apps/angular/module-to-standalone/src/app/app.component.ts +++ b/apps/angular/module-to-standalone/src/app/app.component.ts @@ -2,24 +2,26 @@ import { Component } from '@angular/core'; @Component({ selector: 'app-root', - template: `
+ template: ` +
- `, + + `, host: { class: 'flex flex-col p-4 gap-3', }, diff --git a/apps/angular/module-to-standalone/src/index.html b/apps/angular/module-to-standalone/src/index.html index 153133d..4902faa 100644 --- a/apps/angular/module-to-standalone/src/index.html +++ b/apps/angular/module-to-standalone/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/angular/ngfor-enhancement/src/index.html b/apps/angular/ngfor-enhancement/src/index.html index 02e3b69..c38d89d 100644 --- a/apps/angular/ngfor-enhancement/src/index.html +++ b/apps/angular/ngfor-enhancement/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/angular/permissions/src/app/app.component.ts b/apps/angular/permissions/src/app/app.component.ts index 5fc4531..d89a2f5 100644 --- a/apps/angular/permissions/src/app/app.component.ts +++ b/apps/angular/permissions/src/app/app.component.ts @@ -5,7 +5,9 @@ import { RouterOutlet } from '@angular/router'; standalone: true, imports: [RouterOutlet], selector: 'app-root', - template: ` `, + template: ` + + `, styles: [], }) export class AppComponent {} diff --git a/apps/angular/permissions/src/app/button.component.ts b/apps/angular/permissions/src/app/button.component.ts index b6599e5..b1d59e8 100644 --- a/apps/angular/permissions/src/app/button.component.ts +++ b/apps/angular/permissions/src/app/button.component.ts @@ -4,7 +4,9 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; @Component({ standalone: true, selector: 'button[app-button]', - template: ``, + template: ` + + `, host: { class: 'border border-blue-700 bg-blue-400 p-2 rounded-sm text-white', }, diff --git a/apps/angular/permissions/src/app/login.component.ts b/apps/angular/permissions/src/app/login.component.ts index ab27b11..cd36d96 100644 --- a/apps/angular/permissions/src/app/login.component.ts +++ b/apps/angular/permissions/src/app/login.component.ts @@ -18,7 +18,7 @@ import { UserStore } from './user.store'; imports: [InformationComponent, RouterLink, ButtonComponent], selector: 'app-login', template: ` -
+
Log as : @@ -26,12 +26,12 @@ import { UserStore } from './user.store'; - +
- `, diff --git a/apps/angular/permissions/src/app/routes.ts b/apps/angular/permissions/src/app/routes.ts index 79a3ecc..4db203f 100644 --- a/apps/angular/permissions/src/app/routes.ts +++ b/apps/angular/permissions/src/app/routes.ts @@ -8,7 +8,7 @@ export const APP_ROUTES = [ path: 'enter', loadComponent: () => import('./dashboard/admin.component').then( - (m) => m.AdminDashboardComponent + (m) => m.AdminDashboardComponent, ), }, ]; diff --git a/apps/angular/permissions/src/index.html b/apps/angular/permissions/src/index.html index b78cf57..14ab31c 100644 --- a/apps/angular/permissions/src/index.html +++ b/apps/angular/permissions/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/angular/permissions/src/main.ts b/apps/angular/permissions/src/main.ts index 5679319..7961924 100644 --- a/apps/angular/permissions/src/main.ts +++ b/apps/angular/permissions/src/main.ts @@ -4,5 +4,5 @@ import { appConfig } from './app/app.config'; import { AppComponent } from './app/app.component'; bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err) + console.error(err), ); diff --git a/apps/angular/pipe-easy/src/index.html b/apps/angular/pipe-easy/src/index.html index 63b45d4..eacdd37 100644 --- a/apps/angular/pipe-easy/src/index.html +++ b/apps/angular/pipe-easy/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/angular/pipe-hard/src/index.html b/apps/angular/pipe-hard/src/index.html index 748c8e6..0b81de3 100644 --- a/apps/angular/pipe-hard/src/index.html +++ b/apps/angular/pipe-hard/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/angular/pipe-intermediate/src/index.html b/apps/angular/pipe-intermediate/src/index.html index 07ccccc..1a8b2ee 100644 --- a/apps/angular/pipe-intermediate/src/index.html +++ b/apps/angular/pipe-intermediate/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/angular/projection/jest.config.ts b/apps/angular/projection/jest.config.ts index 289a9b0..2af97a3 100644 --- a/apps/angular/projection/jest.config.ts +++ b/apps/angular/projection/jest.config.ts @@ -2,7 +2,7 @@ export default { displayName: 'angular-projection', preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], + setupFilesAfterEnv: ['/src/subscription-setup.ts'], globals: {}, coverageDirectory: '../../../coverage/apps/angular/projection', transform: { diff --git a/apps/angular/projection/src/app/component/student-card/student-card.component.ts b/apps/angular/projection/src/app/component/student-card/student-card.component.ts index 421630a..441cda1 100644 --- a/apps/angular/projection/src/app/component/student-card/student-card.component.ts +++ b/apps/angular/projection/src/app/component/student-card/student-card.component.ts @@ -7,10 +7,12 @@ import { CardComponent } from '../../ui/card/card.component'; @Component({ selector: 'app-student-card', - template: ``, + template: ` + + `, standalone: true, styles: [ ` @@ -25,7 +27,10 @@ export class StudentCardComponent implements OnInit { students: Student[] = []; cardType = CardType.STUDENT; - constructor(private http: FakeHttpService, private store: StudentStore) {} + constructor( + private http: FakeHttpService, + private store: StudentStore, + ) {} ngOnInit(): void { this.http.fetchStudents$.subscribe((s) => this.store.addAll(s)); diff --git a/apps/angular/projection/src/app/component/teacher-card/teacher-card.component.ts b/apps/angular/projection/src/app/component/teacher-card/teacher-card.component.ts index 006b8db..995cb7c 100644 --- a/apps/angular/projection/src/app/component/teacher-card/teacher-card.component.ts +++ b/apps/angular/projection/src/app/component/teacher-card/teacher-card.component.ts @@ -7,10 +7,12 @@ import { CardComponent } from '../../ui/card/card.component'; @Component({ selector: 'app-teacher-card', - template: ``, + template: ` + + `, styles: [ ` ::ng-deep .bg-light-red { @@ -25,7 +27,10 @@ export class TeacherCardComponent implements OnInit { teachers: Teacher[] = []; cardType = CardType.TEACHER; - constructor(private http: FakeHttpService, private store: TeacherStore) {} + constructor( + private http: FakeHttpService, + private store: TeacherStore, + ) {} ngOnInit(): void { this.http.fetchTeachers$.subscribe((t) => this.store.addAll(t)); diff --git a/apps/angular/projection/src/app/ui/list-item/list-item.component.ts b/apps/angular/projection/src/app/ui/list-item/list-item.component.ts index 2258602..c0f9cff 100644 --- a/apps/angular/projection/src/app/ui/list-item/list-item.component.ts +++ b/apps/angular/projection/src/app/ui/list-item/list-item.component.ts @@ -6,7 +6,7 @@ import { CardType } from '../../model/card.model'; @Component({ selector: 'app-list-item', template: ` -
+
{{ name }} - `, + + `, }) export class AppComponent { userName = new FormControl(); diff --git a/apps/angular/router-input/src/app/app.routes.ts b/apps/angular/router-input/src/app/app.routes.ts index 215c016..f5d3487 100644 --- a/apps/angular/router-input/src/app/app.routes.ts +++ b/apps/angular/router-input/src/app/app.routes.ts @@ -6,7 +6,7 @@ export const appRoutes: Route[] = [ loadComponent: () => import('./home.component'), }, { - path: 'test/:testId', + path: 'subscription/:testId', loadComponent: () => import('./test.component'), data: { permission: 'admin', diff --git a/apps/angular/router-input/src/app/home.component.ts b/apps/angular/router-input/src/app/home.component.ts index be6a891..2ef8c5e 100644 --- a/apps/angular/router-input/src/app/home.component.ts +++ b/apps/angular/router-input/src/app/home.component.ts @@ -3,6 +3,8 @@ import { Component } from '@angular/core'; selector: 'app-home', standalone: true, imports: [], - template: `
Home
`, + template: ` +
Home
+ `, }) export default class HomeComponent {} diff --git a/apps/angular/router-input/src/app/test.component.ts b/apps/angular/router-input/src/app/test.component.ts index 56ac3f7..88c1465 100644 --- a/apps/angular/router-input/src/app/test.component.ts +++ b/apps/angular/router-input/src/app/test.component.ts @@ -2,8 +2,9 @@ import { AsyncPipe } from '@angular/common'; import { Component, inject } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { map } from 'rxjs'; + @Component({ - selector: 'app-test', + selector: 'app-subscription', standalone: true, imports: [AsyncPipe], template: ` diff --git a/apps/angular/router-input/src/index.html b/apps/angular/router-input/src/index.html index 43f4b79..daa1215 100644 --- a/apps/angular/router-input/src/index.html +++ b/apps/angular/router-input/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/angular/router-input/src/main.ts b/apps/angular/router-input/src/main.ts index 514c89a..f3a7223 100644 --- a/apps/angular/router-input/src/main.ts +++ b/apps/angular/router-input/src/main.ts @@ -1,7 +1,7 @@ import { bootstrapApplication } from '@angular/platform-browser'; -import { appConfig } from './app/app.config'; import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err) + console.error(err), ); diff --git a/apps/angular/signal-input/.eslintrc.json b/apps/angular/signal-input/.eslintrc.json new file mode 100644 index 0000000..8ebcbfd --- /dev/null +++ b/apps/angular/signal-input/.eslintrc.json @@ -0,0 +1,36 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": [ + "plugin:@nx/angular", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "app", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "app", + "style": "kebab-case" + } + ] + } + }, + { + "files": ["*.html"], + "extends": ["plugin:@nx/angular-template"], + "rules": {} + } + ] +} diff --git a/apps/angular/signal-input/README.md b/apps/angular/signal-input/README.md new file mode 100644 index 0000000..78ef74d --- /dev/null +++ b/apps/angular/signal-input/README.md @@ -0,0 +1,13 @@ +# Signal Input + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve angular-signal-input +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/43-signal-input/). diff --git a/apps/angular/signal-input/project.json b/apps/angular/signal-input/project.json new file mode 100644 index 0000000..00f1a67 --- /dev/null +++ b/apps/angular/signal-input/project.json @@ -0,0 +1,73 @@ +{ + "name": "angular-signal-input", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/angular/signal-input/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/signal-input", + "index": "apps/angular/signal-input/src/index.html", + "browser": "apps/angular/signal-input/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/angular/signal-input/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/angular/signal-input/src/favicon.ico", + "apps/angular/signal-input/src/assets" + ], + "styles": ["apps/angular/signal-input/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-signal-input:build:production" + }, + "development": { + "buildTarget": "angular-signal-input:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-signal-input:build" + } + }, + "lint": { + "executor": "@nx/eslint:lint", + "outputs": ["{options.outputFile}"] + } + } +} diff --git a/apps/angular/signal-input/src/app/app.component.ts b/apps/angular/signal-input/src/app/app.component.ts new file mode 100644 index 0000000..22e6438 --- /dev/null +++ b/apps/angular/signal-input/src/app/app.component.ts @@ -0,0 +1,45 @@ +import { JsonPipe } from '@angular/common'; +import { Component } from '@angular/core'; +import { UserComponent } from './user.component'; + +@Component({ + standalone: true, + imports: [UserComponent, JsonPipe], + selector: 'app-root', + template: ` +
+
+ Name: + + @if (showUser && !name.value) { +
name required
+ } +
+
+ LastName: + +
+
+ Age: + +
+ +
+ @if (showUser && !!name.value) { + + } + `, + host: { + class: 'p-10 block flex flex-col gap-10', + }, +}) +export class AppComponent { + showUser = false; +} diff --git a/apps/angular/signal-input/src/app/app.config.ts b/apps/angular/signal-input/src/app/app.config.ts new file mode 100644 index 0000000..81a6edd --- /dev/null +++ b/apps/angular/signal-input/src/app/app.config.ts @@ -0,0 +1,5 @@ +import { ApplicationConfig } from '@angular/core'; + +export const appConfig: ApplicationConfig = { + providers: [], +}; diff --git a/apps/angular/signal-input/src/app/user.component.ts b/apps/angular/signal-input/src/app/user.component.ts new file mode 100644 index 0000000..082638b --- /dev/null +++ b/apps/angular/signal-input/src/app/user.component.ts @@ -0,0 +1,41 @@ +import { TitleCasePipe } from '@angular/common'; +import { + ChangeDetectionStrategy, + Component, + Input, + OnChanges, +} from '@angular/core'; + +type Category = 'Youth' | 'Junior' | 'Open' | 'Senior'; +const ageToCategory = (age: number): Category => { + if (age < 10) return 'Youth'; + else if (age < 18) return 'Junior'; + else if (age < 35) return 'Open'; + return 'Senior'; +}; + +@Component({ + selector: 'app-user', + standalone: true, + imports: [TitleCasePipe], + template: ` + {{ fullName | titlecase }} plays tennis in the {{ category }} category!! + `, + host: { + class: 'text-xl text-green-800', + }, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class UserComponent implements OnChanges { + @Input({ required: true }) name!: string; + @Input() lastName?: string; + @Input() age?: string; + + fullName = ''; + category: Category = 'Junior'; + + ngOnChanges(): void { + this.fullName = `${this.name} ${this.lastName ?? ''}`; + this.category = ageToCategory(Number(this.age) ?? 0); + } +} diff --git a/apps/angular/signal-input/src/assets/.gitkeep b/apps/angular/signal-input/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/apps/angular/signal-input/src/favicon.ico b/apps/angular/signal-input/src/favicon.ico new file mode 100644 index 0000000..317ebcb Binary files /dev/null and b/apps/angular/signal-input/src/favicon.ico differ diff --git a/apps/angular/signal-input/src/index.html b/apps/angular/signal-input/src/index.html new file mode 100644 index 0000000..4fc2af8 --- /dev/null +++ b/apps/angular/signal-input/src/index.html @@ -0,0 +1,13 @@ + + + + + angular-signal-input + + + + + + + + diff --git a/apps/angular/signal-input/src/main.ts b/apps/angular/signal-input/src/main.ts new file mode 100644 index 0000000..f3a7223 --- /dev/null +++ b/apps/angular/signal-input/src/main.ts @@ -0,0 +1,7 @@ +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(AppComponent, appConfig).catch((err) => + console.error(err), +); diff --git a/apps/angular/signal-input/src/styles.scss b/apps/angular/signal-input/src/styles.scss new file mode 100644 index 0000000..77e408a --- /dev/null +++ b/apps/angular/signal-input/src/styles.scss @@ -0,0 +1,5 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* You can add global styles to this file, and also import other style files */ diff --git a/apps/angular/signal-input/tailwind.config.js b/apps/angular/signal-input/tailwind.config.js new file mode 100644 index 0000000..38183db --- /dev/null +++ b/apps/angular/signal-input/tailwind.config.js @@ -0,0 +1,14 @@ +const { createGlobPatternsForDependencies } = require('@nx/angular/tailwind'); +const { join } = require('path'); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + join(__dirname, 'src/**/!(*.stories|*.spec).{ts,html}'), + ...createGlobPatternsForDependencies(__dirname), + ], + theme: { + extend: {}, + }, + plugins: [], +}; diff --git a/apps/angular/signal-input/tsconfig.app.json b/apps/angular/signal-input/tsconfig.app.json new file mode 100644 index 0000000..5822042 --- /dev/null +++ b/apps/angular/signal-input/tsconfig.app.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [] + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/angular/signal-input/tsconfig.editor.json b/apps/angular/signal-input/tsconfig.editor.json new file mode 100644 index 0000000..4ee6393 --- /dev/null +++ b/apps/angular/signal-input/tsconfig.editor.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": { + "types": [] + } +} diff --git a/apps/angular/signal-input/tsconfig.json b/apps/angular/signal-input/tsconfig.json new file mode 100644 index 0000000..b94f883 --- /dev/null +++ b/apps/angular/signal-input/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/angular/styling/src/app/page.component.ts b/apps/angular/styling/src/app/page.component.ts index a378647..0674532 100644 --- a/apps/angular/styling/src/app/page.component.ts +++ b/apps/angular/styling/src/app/page.component.ts @@ -11,7 +11,7 @@ import { TextComponent } from './text.component'; - This a a blue text + This is a blue text `, }) export class PageComponent {} diff --git a/apps/angular/styling/src/index.html b/apps/angular/styling/src/index.html index 67d4296..7ea1636 100644 --- a/apps/angular/styling/src/index.html +++ b/apps/angular/styling/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/forms/control-value-accessor/.eslintrc.json b/apps/forms/control-value-accessor/.eslintrc.json new file mode 100644 index 0000000..8ebcbfd --- /dev/null +++ b/apps/forms/control-value-accessor/.eslintrc.json @@ -0,0 +1,36 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": [ + "plugin:@nx/angular", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "app", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "app", + "style": "kebab-case" + } + ] + } + }, + { + "files": ["*.html"], + "extends": ["plugin:@nx/angular-template"], + "rules": {} + } + ] +} diff --git a/apps/forms/control-value-accessor/README.md b/apps/forms/control-value-accessor/README.md new file mode 100644 index 0000000..a91920a --- /dev/null +++ b/apps/forms/control-value-accessor/README.md @@ -0,0 +1,13 @@ +# Control Value Accessor + +> author: stanislav-gavrilov + +### Run Application + +```bash +npx nx serve forms-control-value-accessor +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/forms/41-control-value-accessor/). diff --git a/apps/forms/control-value-accessor/jest.config.ts b/apps/forms/control-value-accessor/jest.config.ts new file mode 100644 index 0000000..a52c898 --- /dev/null +++ b/apps/forms/control-value-accessor/jest.config.ts @@ -0,0 +1,22 @@ +/* eslint-disable */ +export default { + displayName: 'forms-control-value-accessor', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/subscription-setup.ts'], + coverageDirectory: '../../../coverage/apps/forms/control-value-accessor', + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/apps/forms/control-value-accessor/project.json b/apps/forms/control-value-accessor/project.json new file mode 100644 index 0000000..3f232a9 --- /dev/null +++ b/apps/forms/control-value-accessor/project.json @@ -0,0 +1,86 @@ +{ + "name": "forms-control-value-accessor", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/forms/control-value-accessor/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/forms/control-value-accessor", + "index": "apps/forms/control-value-accessor/src/index.html", + "browser": "apps/forms/control-value-accessor/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/forms/control-value-accessor/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/forms/control-value-accessor/src/favicon.ico", + "apps/forms/control-value-accessor/src/assets" + ], + "styles": ["apps/forms/control-value-accessor/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "forms-control-value-accessor:build:production" + }, + "development": { + "buildTarget": "forms-control-value-accessor:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "forms-control-value-accessor:build" + } + }, + "lint": { + "executor": "@nx/eslint:lint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": [ + "apps/forms/control-value-accessor/**/*.ts", + "apps/forms/control-value-accessor/**/*.html" + ] + } + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "apps/forms/control-value-accessor/jest.config.ts" + } + } + } +} diff --git a/apps/forms/control-value-accessor/src/app/app.component.ts b/apps/forms/control-value-accessor/src/app/app.component.ts new file mode 100644 index 0000000..f56b5d7 --- /dev/null +++ b/apps/forms/control-value-accessor/src/app/app.component.ts @@ -0,0 +1,16 @@ +import { Component } from '@angular/core'; +import { FeedbackFormComponent } from './feedback-form/feedback-form.component'; + +@Component({ + standalone: true, + imports: [FeedbackFormComponent], + selector: 'app-root', + template: ` + + `, +}) +export class AppComponent { + apiCall(event: Record): void { + console.log(event); + } +} diff --git a/apps/forms/control-value-accessor/src/app/feedback-form/feedback-form.component.html b/apps/forms/control-value-accessor/src/app/feedback-form/feedback-form.component.html new file mode 100644 index 0000000..9334b5b --- /dev/null +++ b/apps/forms/control-value-accessor/src/app/feedback-form/feedback-form.component.html @@ -0,0 +1,29 @@ + diff --git a/apps/forms/control-value-accessor/src/app/feedback-form/feedback-form.component.scss b/apps/forms/control-value-accessor/src/app/feedback-form/feedback-form.component.scss new file mode 100644 index 0000000..ac4868a --- /dev/null +++ b/apps/forms/control-value-accessor/src/app/feedback-form/feedback-form.component.scss @@ -0,0 +1,50 @@ +* { + box-sizing: border-box; +} + +:host { + display: block; + padding: 20px; +} + +.feedback-form { + display: flex; + flex-direction: column; + width: 500px; + padding: 20px; + border: 1px solid #000000; +} + +.feedback-form-title { + margin-bottom: 20px; + font-size: 24px; +} + +.feedback-form-control { + max-height: 200px; + margin-bottom: 20px; + padding: 12px 12px 12px 20px; + border-radius: 0; + background-color: #fbfbfb; + color: #3c3c3c; + font-size: 18px; + + &:focus { + padding: 10px 10px 10px 18px; + border: 2px solid #054ada; + outline: none; + background: #fff; + } +} + +.feedback-form-submit { + padding: 10px; + background-color: #054ada; + color: #ffffff; + font-size: 18px; + + &[disabled] { + background-color: #cccccc; + color: #ffffff; + } +} diff --git a/apps/forms/control-value-accessor/src/app/feedback-form/feedback-form.component.ts b/apps/forms/control-value-accessor/src/app/feedback-form/feedback-form.component.ts new file mode 100644 index 0000000..d99700d --- /dev/null +++ b/apps/forms/control-value-accessor/src/app/feedback-form/feedback-form.component.ts @@ -0,0 +1,42 @@ +import { Component, EventEmitter, Output } from '@angular/core'; +import { + FormControl, + FormGroup, + ReactiveFormsModule, + Validators, +} from '@angular/forms'; +import { RatingControlComponent } from '../rating-control/rating-control.component'; + +@Component({ + standalone: true, + imports: [RatingControlComponent, ReactiveFormsModule], + selector: 'app-feedback-form', + templateUrl: 'feedback-form.component.html', + styleUrls: ['feedback-form.component.scss'], +}) +export class FeedbackFormComponent { + @Output() + readonly feedBackSubmit: EventEmitter> = + new EventEmitter>(); + + readonly feedbackForm = new FormGroup({ + name: new FormControl('', { + validators: Validators.required, + }), + email: new FormControl('', { + validators: Validators.required, + }), + comment: new FormControl(), + }); + + rating: string | null = null; + + submitForm(): void { + this.feedBackSubmit.emit({ + ...this.feedbackForm.value, + rating: this.rating, + }); + + this.feedbackForm.reset(); + } +} diff --git a/apps/forms/control-value-accessor/src/app/rating-control/rating-control.component.html b/apps/forms/control-value-accessor/src/app/rating-control/rating-control.component.html new file mode 100644 index 0000000..05b96c1 --- /dev/null +++ b/apps/forms/control-value-accessor/src/app/rating-control/rating-control.component.html @@ -0,0 +1,16 @@ + + + + + +
+ @for (item of [].constructor(5); track item) { + + + + } +
diff --git a/apps/forms/control-value-accessor/src/app/rating-control/rating-control.component.scss b/apps/forms/control-value-accessor/src/app/rating-control/rating-control.component.scss new file mode 100644 index 0000000..1e174f1 --- /dev/null +++ b/apps/forms/control-value-accessor/src/app/rating-control/rating-control.component.scss @@ -0,0 +1,26 @@ +.rating { + display: flex; + justify-content: center; + padding: 0 10px; + + &:hover { + .star { + fill: #ffd055; + } + } +} + +.star { + width: 50px; + height: 50px; + fill: #cccccc; + cursor: pointer; + + &:hover ~ .star { + fill: #d8d8d8; + } +} + +.star-active { + fill: #ffd055 !important; +} diff --git a/apps/forms/control-value-accessor/src/app/rating-control/rating-control.component.ts b/apps/forms/control-value-accessor/src/app/rating-control/rating-control.component.ts new file mode 100644 index 0000000..d6dc316 --- /dev/null +++ b/apps/forms/control-value-accessor/src/app/rating-control/rating-control.component.ts @@ -0,0 +1,23 @@ +import { Component, EventEmitter, Output } from '@angular/core'; + +@Component({ + standalone: true, + selector: 'app-rating-control', + templateUrl: 'rating-control.component.html', + styleUrls: ['rating-control.component.scss'], +}) +export class RatingControlComponent { + @Output() + readonly ratingUpdated: EventEmitter = new EventEmitter(); + + value: number | null = null; + + setRating(index: number): void { + this.value = index + 1; + this.ratingUpdated.emit(`${this.value}`); + } + + isStarActive(index: number, value: number | null): boolean { + return value ? index < value : false; + } +} diff --git a/apps/forms/control-value-accessor/src/assets/.gitkeep b/apps/forms/control-value-accessor/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/apps/forms/control-value-accessor/src/favicon.ico b/apps/forms/control-value-accessor/src/favicon.ico new file mode 100644 index 0000000..317ebcb Binary files /dev/null and b/apps/forms/control-value-accessor/src/favicon.ico differ diff --git a/apps/forms/control-value-accessor/src/index.html b/apps/forms/control-value-accessor/src/index.html new file mode 100644 index 0000000..957806c --- /dev/null +++ b/apps/forms/control-value-accessor/src/index.html @@ -0,0 +1,13 @@ + + + + + forms-control-value-accessor + + + + + + + + diff --git a/apps/forms/control-value-accessor/src/main.ts b/apps/forms/control-value-accessor/src/main.ts new file mode 100644 index 0000000..31c5da4 --- /dev/null +++ b/apps/forms/control-value-accessor/src/main.ts @@ -0,0 +1,4 @@ +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent).catch((err) => console.error(err)); diff --git a/apps/forms/control-value-accessor/src/styles.scss b/apps/forms/control-value-accessor/src/styles.scss new file mode 100644 index 0000000..77e408a --- /dev/null +++ b/apps/forms/control-value-accessor/src/styles.scss @@ -0,0 +1,5 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* You can add global styles to this file, and also import other style files */ diff --git a/apps/forms/control-value-accessor/src/test-setup.ts b/apps/forms/control-value-accessor/src/test-setup.ts new file mode 100644 index 0000000..15de72a --- /dev/null +++ b/apps/forms/control-value-accessor/src/test-setup.ts @@ -0,0 +1,2 @@ +import '@testing-library/jest-dom'; +import 'jest-preset-angular/setup-jest'; diff --git a/apps/forms/control-value-accessor/tailwind.config.js b/apps/forms/control-value-accessor/tailwind.config.js new file mode 100644 index 0000000..38183db --- /dev/null +++ b/apps/forms/control-value-accessor/tailwind.config.js @@ -0,0 +1,14 @@ +const { createGlobPatternsForDependencies } = require('@nx/angular/tailwind'); +const { join } = require('path'); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + join(__dirname, 'src/**/!(*.stories|*.spec).{ts,html}'), + ...createGlobPatternsForDependencies(__dirname), + ], + theme: { + extend: {}, + }, + plugins: [], +}; diff --git a/apps/forms/control-value-accessor/tsconfig.app.json b/apps/forms/control-value-accessor/tsconfig.app.json new file mode 100644 index 0000000..5822042 --- /dev/null +++ b/apps/forms/control-value-accessor/tsconfig.app.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [] + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/forms/control-value-accessor/tsconfig.editor.json b/apps/forms/control-value-accessor/tsconfig.editor.json new file mode 100644 index 0000000..8ae117d --- /dev/null +++ b/apps/forms/control-value-accessor/tsconfig.editor.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": { + "types": ["jest", "node"] + } +} diff --git a/apps/forms/control-value-accessor/tsconfig.json b/apps/forms/control-value-accessor/tsconfig.json new file mode 100644 index 0000000..25ca437 --- /dev/null +++ b/apps/forms/control-value-accessor/tsconfig.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/forms/control-value-accessor/tsconfig.spec.json b/apps/forms/control-value-accessor/tsconfig.spec.json new file mode 100644 index 0000000..1a4817a --- /dev/null +++ b/apps/forms/control-value-accessor/tsconfig.spec.json @@ -0,0 +1,15 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node", "@testing-library/jest-dom"] + }, + "files": ["src/test-setup.ts"], + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/apps/ngrx/effect-selector/jest.config.ts b/apps/ngrx/effect-selector/jest.config.ts index 86ed38d..7e97f0b 100644 --- a/apps/ngrx/effect-selector/jest.config.ts +++ b/apps/ngrx/effect-selector/jest.config.ts @@ -2,7 +2,7 @@ export default { displayName: 'ngrx-effect-selector', preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], + setupFilesAfterEnv: ['/src/subscription-setup.ts'], globals: {}, coverageDirectory: '../../../coverage/apps/ngrx/effect-selector', transform: { diff --git a/apps/ngrx/effect-selector/src/app/app.component.ts b/apps/ngrx/effect-selector/src/app/app.component.ts index 0411abc..1e48366 100644 --- a/apps/ngrx/effect-selector/src/app/app.component.ts +++ b/apps/ngrx/effect-selector/src/app/app.component.ts @@ -2,8 +2,8 @@ import { AsyncPipe, NgFor } from '@angular/common'; import { ChangeDetectionStrategy, Component, - inject, OnInit, + inject, } from '@angular/core'; import { Store } from '@ngrx/store'; import { loadActivities } from './store/activity/activity.actions'; diff --git a/apps/ngrx/effect-selector/src/app/app.config.ts b/apps/ngrx/effect-selector/src/app/app.config.ts index e18cd33..d59c436 100644 --- a/apps/ngrx/effect-selector/src/app/app.config.ts +++ b/apps/ngrx/effect-selector/src/app/app.config.ts @@ -1,13 +1,13 @@ import { ApplicationConfig } from '@angular/core'; -import { provideStore } from '@ngrx/store'; import { provideEffects } from '@ngrx/effects'; +import { provideStore } from '@ngrx/store'; import { ActivityEffects } from './store/activity/activity.effects'; -import { UserEffects } from './store/user/user.effects'; -import { StatusEffects } from './store/status/status.effects'; import { activityFeatureKey, activityReducer, } from './store/activity/activity.reducer'; +import { StatusEffects } from './store/status/status.effects'; +import { UserEffects } from './store/user/user.effects'; import { statusFeatureKey, statusReducer } from './store/status/status.reducer'; diff --git a/apps/ngrx/effect-selector/src/app/store/activity/activity.actions.ts b/apps/ngrx/effect-selector/src/app/store/activity/activity.actions.ts index 214586f..c8affff 100644 --- a/apps/ngrx/effect-selector/src/app/store/activity/activity.actions.ts +++ b/apps/ngrx/effect-selector/src/app/store/activity/activity.actions.ts @@ -1,14 +1,14 @@ import { createAction, props } from '@ngrx/store'; import { Activity } from './activity.model'; -export const loadActivities = createAction('[AppComponent] Load Activities'); +export const loadActivities = createAction('[Activity Effect] Load Activities'); export const loadActivitiesSuccess = createAction( - '[Activity Effect] Load Activitys Success', - props<{ activities: Activity[] }>() + '[Activity Effect] Load Activities Success', + props<{ activities: Activity[] }>(), ); export const loadActivitiesFailure = createAction( '[Activity Effect] Load Activities Failure', - props<{ error: any }>() + props<{ error: unknown }>(), ); diff --git a/apps/ngrx/effect-selector/src/app/store/activity/activity.effects.ts b/apps/ngrx/effect-selector/src/app/store/activity/activity.effects.ts index 63b27e9..88f8b23 100644 --- a/apps/ngrx/effect-selector/src/app/store/activity/activity.effects.ts +++ b/apps/ngrx/effect-selector/src/app/store/activity/activity.effects.ts @@ -13,18 +13,18 @@ export class ActivityEffects { concatMap(() => this.ActivityService.fetchActivities().pipe( map((activities) => - ActivityActions.loadActivitiesSuccess({ activities }) + ActivityActions.loadActivitiesSuccess({ activities }), ), catchError((error) => - of(ActivityActions.loadActivitiesFailure({ error })) - ) - ) - ) + of(ActivityActions.loadActivitiesFailure({ error })), + ), + ), + ), ); }); constructor( private actions$: Actions, - private ActivityService: ActivityService + private ActivityService: ActivityService, ) {} } diff --git a/apps/ngrx/effect-selector/src/app/store/activity/activity.reducer.ts b/apps/ngrx/effect-selector/src/app/store/activity/activity.reducer.ts index f370b4b..b7285e8 100644 --- a/apps/ngrx/effect-selector/src/app/store/activity/activity.reducer.ts +++ b/apps/ngrx/effect-selector/src/app/store/activity/activity.reducer.ts @@ -21,5 +21,5 @@ export const activityReducer = createReducer( on(ActivityActions.loadActivitiesFailure, (state) => ({ state, activities: [], - })) + })), ); diff --git a/apps/ngrx/effect-selector/src/app/store/activity/activity.selectors.ts b/apps/ngrx/effect-selector/src/app/store/activity/activity.selectors.ts index 7e200de..6c6a25a 100644 --- a/apps/ngrx/effect-selector/src/app/store/activity/activity.selectors.ts +++ b/apps/ngrx/effect-selector/src/app/store/activity/activity.selectors.ts @@ -1,10 +1,10 @@ import { createFeatureSelector, createSelector } from '@ngrx/store'; -import { activityFeatureKey, ActivityState } from './activity.reducer'; +import { ActivityState, activityFeatureKey } from './activity.reducer'; export const selectActivityState = createFeatureSelector(activityFeatureKey); export const selectActivities = createSelector( selectActivityState, - (state) => state.activities + (state) => state.activities, ); diff --git a/apps/ngrx/effect-selector/src/app/store/status/status.actions.ts b/apps/ngrx/effect-selector/src/app/store/status/status.actions.ts index c966824..8fc2ddc 100644 --- a/apps/ngrx/effect-selector/src/app/store/status/status.actions.ts +++ b/apps/ngrx/effect-selector/src/app/store/status/status.actions.ts @@ -5,5 +5,5 @@ export const loadStatuses = createAction('[Status] Load Statuses'); export const loadStatusesSuccess = createAction( '[Status] Load Statuses Success', - props<{ statuses: Status[] }>() + props<{ statuses: Status[] }>(), ); diff --git a/apps/ngrx/effect-selector/src/app/store/status/status.effects.ts b/apps/ngrx/effect-selector/src/app/store/status/status.effects.ts index 3459a59..997eb0c 100644 --- a/apps/ngrx/effect-selector/src/app/store/status/status.effects.ts +++ b/apps/ngrx/effect-selector/src/app/store/status/status.effects.ts @@ -22,7 +22,7 @@ export class StatusEffects { return activities.reduce( (status: Status[], activity): Status[] => { const index = status.findIndex( - (s) => s.name === activity.type + (s) => s.name === activity.type, ); if (index === -1) { return [ @@ -34,16 +34,19 @@ export class StatusEffects { return status; } }, - [] + [], ); } return []; }), - map((statuses) => StatusActions.loadStatusesSuccess({ statuses })) - ) - ) + map((statuses) => StatusActions.loadStatusesSuccess({ statuses })), + ), + ), ); }); - constructor(private actions$: Actions, private store: Store) {} + constructor( + private actions$: Actions, + private store: Store, + ) {} } diff --git a/apps/ngrx/effect-selector/src/app/store/status/status.reducer.ts b/apps/ngrx/effect-selector/src/app/store/status/status.reducer.ts index 1dd8ece..b91cbe2 100644 --- a/apps/ngrx/effect-selector/src/app/store/status/status.reducer.ts +++ b/apps/ngrx/effect-selector/src/app/store/status/status.reducer.ts @@ -25,5 +25,5 @@ export const statusReducer = createReducer( statuses, teachersMap: map, }; - }) + }), ); diff --git a/apps/ngrx/effect-selector/src/app/store/status/status.selectors.ts b/apps/ngrx/effect-selector/src/app/store/status/status.selectors.ts index 85b72f8..80ed059 100644 --- a/apps/ngrx/effect-selector/src/app/store/status/status.selectors.ts +++ b/apps/ngrx/effect-selector/src/app/store/status/status.selectors.ts @@ -1,17 +1,17 @@ import { createFeatureSelector, createSelector } from '@ngrx/store'; import { ActivityType } from '../activity/activity.model'; -import { statusFeatureKey, StatusState } from './status.reducer'; +import { StatusState, statusFeatureKey } from './status.reducer'; export const selectStatusState = createFeatureSelector(statusFeatureKey); export const selectStatuses = createSelector( selectStatusState, - (state) => state.statuses + (state) => state.statuses, ); export const selectAllTeachersByActivityType = (name: ActivityType) => createSelector( selectStatusState, - (state) => state.teachersMap.get(name) ?? [] + (state) => state.teachersMap.get(name) ?? [], ); diff --git a/apps/ngrx/effect-selector/src/app/store/user/user.actions.ts b/apps/ngrx/effect-selector/src/app/store/user/user.actions.ts index dcc8b1d..a73147d 100644 --- a/apps/ngrx/effect-selector/src/app/store/user/user.actions.ts +++ b/apps/ngrx/effect-selector/src/app/store/user/user.actions.ts @@ -1,14 +1,14 @@ import { createAction, props } from '@ngrx/store'; import { User } from './user.model'; -export const loadUsers = createAction('[User] Load User'); +export const loadUsers = createAction('[User] Load Users'); export const loadUsersSuccess = createAction( '[User] Load Users Success', - props<{ user: User }>() + props<{ user: User }>(), ); export const loadUsersFailure = createAction( '[User] Load Users Failure', - props<{ error: any }>() + props<{ error: unknown }>(), ); diff --git a/apps/ngrx/effect-selector/src/app/store/user/user.effects.ts b/apps/ngrx/effect-selector/src/app/store/user/user.effects.ts index 6f68e5b..fff3f6f 100644 --- a/apps/ngrx/effect-selector/src/app/store/user/user.effects.ts +++ b/apps/ngrx/effect-selector/src/app/store/user/user.effects.ts @@ -13,11 +13,14 @@ export class UserEffects { concatMap(() => this.userService.fetchUser().pipe( map((user) => UserActions.loadUsersSuccess({ user })), - catchError((error) => of(UserActions.loadUsersFailure({ error }))) - ) - ) + catchError((error) => of(UserActions.loadUsersFailure({ error }))), + ), + ), ); }); - constructor(private actions$: Actions, private userService: UserService) {} + constructor( + private actions$: Actions, + private userService: UserService, + ) {} } diff --git a/apps/ngrx/effect-selector/src/app/store/user/user.reducer.ts b/apps/ngrx/effect-selector/src/app/store/user/user.reducer.ts index 45596af..3f4768c 100644 --- a/apps/ngrx/effect-selector/src/app/store/user/user.reducer.ts +++ b/apps/ngrx/effect-selector/src/app/store/user/user.reducer.ts @@ -15,5 +15,5 @@ export const initialState: UserState = { export const userReducer = createReducer( initialState, on(UserActions.loadUsersSuccess, (state, { user }) => ({ ...state, user })), - on(UserActions.loadUsersFailure, (state) => ({ ...state, user: undefined })) + on(UserActions.loadUsersFailure, (state) => ({ ...state, user: undefined })), ); diff --git a/apps/ngrx/effect-selector/src/app/store/user/user.selectors.ts b/apps/ngrx/effect-selector/src/app/store/user/user.selectors.ts index eb6deda..7970b0d 100644 --- a/apps/ngrx/effect-selector/src/app/store/user/user.selectors.ts +++ b/apps/ngrx/effect-selector/src/app/store/user/user.selectors.ts @@ -1,9 +1,9 @@ import { createFeatureSelector, createSelector } from '@ngrx/store'; -import { userFeatureKey, UserState } from './user.reducer'; +import { UserState, userFeatureKey } from './user.reducer'; export const selectUserState = createFeatureSelector(userFeatureKey); export const selectUser = createSelector( selectUserState, - (state) => state.user + (state) => state.user, ); diff --git a/apps/ngrx/effect-selector/src/index.html b/apps/ngrx/effect-selector/src/index.html index 5664dcf..21d5736 100644 --- a/apps/ngrx/effect-selector/src/index.html +++ b/apps/ngrx/effect-selector/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/ngrx/notification/project.json b/apps/ngrx/notification/project.json index 4e31872..5182ec8 100644 --- a/apps/ngrx/notification/project.json +++ b/apps/ngrx/notification/project.json @@ -19,7 +19,10 @@ "apps/ngrx/notification/src/favicon.ico", "apps/ngrx/notification/src/assets" ], - "styles": ["apps/ngrx/notification/src/styles.scss"], + "styles": [ + "apps/ngrx/notification/src/styles.scss", + "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css" + ], "scripts": [], "allowedCommonJsDependencies": ["seedrandom"] }, diff --git a/apps/ngrx/notification/src/app/app.actions.ts b/apps/ngrx/notification/src/app/app.actions.ts index 8292b19..3dcba81 100644 --- a/apps/ngrx/notification/src/app/app.actions.ts +++ b/apps/ngrx/notification/src/app/app.actions.ts @@ -1,5 +1,6 @@ import { createActionGroup, emptyProps } from '@ngrx/store'; +// This is the global actions. export const appActions = createActionGroup({ source: 'App Component', events: { diff --git a/apps/ngrx/notification/src/app/app.config.ts b/apps/ngrx/notification/src/app/app.config.ts index 52badc4..b368223 100644 --- a/apps/ngrx/notification/src/app/app.config.ts +++ b/apps/ngrx/notification/src/app/app.config.ts @@ -1,21 +1,21 @@ -import { ApplicationConfig } from '@angular/core'; -import { provideStore } from '@ngrx/store'; -import { provideEffects } from '@ngrx/effects'; -import { TeacherEffects } from './teacher/store/teacher.effects'; -import { StudentEffects } from './student/store/student.effects'; -import { provideRouter } from '@angular/router'; -import { ROUTES } from './routes'; -import { APP_INITIALIZER, inject } from '@angular/core'; import { FakeBackendService } from '@angular-challenges/ngrx-notification/backend'; +import { APP_INITIALIZER, ApplicationConfig, inject } from '@angular/core'; +import { provideAnimations } from '@angular/platform-browser/animations'; +import { provideRouter } from '@angular/router'; +import { provideEffects } from '@ngrx/effects'; +import { provideStore } from '@ngrx/store'; import { NotificationService } from './data-access/notification.service'; -import { - teacherReducer, - teachersFeatureKey, -} from './teacher/store/teacher.reducer'; +import { ROUTES } from './routes'; +import { StudentEffects } from './student/store/student.effects'; import { studentReducer, studentsFeatureKey, } from './student/store/student.reducer'; +import { TeacherEffects } from './teacher/store/teacher.effects'; +import { + teacherReducer, + teachersFeatureKey, +} from './teacher/store/teacher.reducer'; const REDUCERS = { [teachersFeatureKey]: teacherReducer, @@ -43,5 +43,6 @@ export const appConfig: ApplicationConfig = { return () => service.init(); }, }, + provideAnimations(), ], }; diff --git a/apps/ngrx/notification/src/app/data-access/http.service.ts b/apps/ngrx/notification/src/app/data-access/http.service.ts index 84aadda..b5a59aa 100644 --- a/apps/ngrx/notification/src/app/data-access/http.service.ts +++ b/apps/ngrx/notification/src/app/data-access/http.service.ts @@ -10,5 +10,5 @@ export class HttpService { getAllStudents = () => this.fakeBackend.getAllStudents().pipe(take(1)); - getAllSchools = () => this.fakeBackend.getAllStchools().pipe(take(1)); + getAllSchools = () => this.fakeBackend.getAllSchools().pipe(take(1)); } diff --git a/apps/ngrx/notification/src/app/data-access/notification.service.ts b/apps/ngrx/notification/src/app/data-access/notification.service.ts index 2daca97..b116140 100644 --- a/apps/ngrx/notification/src/app/data-access/notification.service.ts +++ b/apps/ngrx/notification/src/app/data-access/notification.service.ts @@ -22,18 +22,17 @@ export class NotificationService { .subscribe((notification: Push) => { if (isTeacher(notification)) { this.store.dispatch( - teacherActions.addOneTeacher({ teacher: notification }) + teacherActions.addOneTeacher({ teacher: notification }), ); } if (isStudent(notification)) { this.store.dispatch( - studentActions.addOneStudent({ student: notification }) + studentActions.addOneStudent({ student: notification }), ); } if (isSchool(notification)) { - // SchoolStore is not providedin root. thus at initialization, SchoolStore is undefined - // Option 1: set SchoolStore in root, but we don't want this to separate our class. - // Option 2: your turn + // SchoolStore is a ComponentStore. We can't dispatch a school action here. + // We are stuck. We must have done something wrong and need to refactor... } }); } diff --git a/apps/ngrx/notification/src/app/routes.ts b/apps/ngrx/notification/src/app/routes.ts index f84b13e..7db44a4 100644 --- a/apps/ngrx/notification/src/app/routes.ts +++ b/apps/ngrx/notification/src/app/routes.ts @@ -1,11 +1,11 @@ import { Route } from '@angular/router'; +import { TeacherComponent } from './teacher/teacher.component'; export const ROUTES: Route[] = [ { path: '', pathMatch: 'full', redirectTo: 'teacher' }, { path: 'teacher', - loadComponent: () => - import('./teacher/teacher.component').then((m) => m.TeacherComponent), + component: TeacherComponent, }, { path: 'student', diff --git a/apps/ngrx/notification/src/app/school/school.store.ts b/apps/ngrx/notification/src/app/school/school.store.ts index 59899dc..0fd31fa 100644 --- a/apps/ngrx/notification/src/app/school/school.store.ts +++ b/apps/ngrx/notification/src/app/school/school.store.ts @@ -35,11 +35,11 @@ export class SchoolStore this.httpService.getAllSchools().pipe( tapResponse( (schools) => this.patchState({ schools }), - (_) => _ - ) - ) - ) - ) + (_) => _, // not handling the error + ), + ), + ), + ), ); ngrxOnStoreInit() { diff --git a/apps/ngrx/notification/src/app/student/store/student.effects.ts b/apps/ngrx/notification/src/app/student/store/student.effects.ts index 1eef890..b741bd2 100644 --- a/apps/ngrx/notification/src/app/student/store/student.effects.ts +++ b/apps/ngrx/notification/src/app/student/store/student.effects.ts @@ -16,8 +16,8 @@ export class StudentEffects { switchMap(() => this.httpService .getAllStudents() - .pipe(map((students) => studentActions.addAllStudents({ students }))) - ) - ) + .pipe(map((students) => studentActions.addAllStudents({ students }))), + ), + ), ); } diff --git a/apps/ngrx/notification/src/app/student/store/student.reducer.ts b/apps/ngrx/notification/src/app/student/store/student.reducer.ts index 068d890..0b02cd3 100644 --- a/apps/ngrx/notification/src/app/student/store/student.reducer.ts +++ b/apps/ngrx/notification/src/app/student/store/student.reducer.ts @@ -13,11 +13,11 @@ export const studentAdapter: EntityAdapter = export const studentReducer = createReducer( studentAdapter.getInitialState(), on(studentActions.addOneStudent, (state, { student }) => - studentAdapter.upsertOne(student, state) + studentAdapter.upsertOne(student, state), ), on(studentActions.addAllStudents, (state, { students }) => - studentAdapter.setAll(students, state) - ) + studentAdapter.setAll(students, state), + ), ); export const { selectIds, selectEntities, selectAll, selectTotal } = diff --git a/apps/ngrx/notification/src/app/student/store/student.selectors.ts b/apps/ngrx/notification/src/app/student/store/student.selectors.ts index 5c04e23..b041ff4 100644 --- a/apps/ngrx/notification/src/app/student/store/student.selectors.ts +++ b/apps/ngrx/notification/src/app/student/store/student.selectors.ts @@ -1,8 +1,8 @@ import { createFeatureSelector, createSelector } from '@ngrx/store'; import { + StudentState, studentAdapter, studentsFeatureKey, - StudentState, } from './student.reducer'; const selectStudentState = diff --git a/apps/ngrx/notification/src/app/teacher/store/teacher.effects.ts b/apps/ngrx/notification/src/app/teacher/store/teacher.effects.ts index 9eca53b..43c3fab 100644 --- a/apps/ngrx/notification/src/app/teacher/store/teacher.effects.ts +++ b/apps/ngrx/notification/src/app/teacher/store/teacher.effects.ts @@ -16,8 +16,8 @@ export class TeacherEffects { switchMap(() => this.httpService .getAllTeachers() - .pipe(map((teachers) => teacherActions.addAllTeachers({ teachers }))) - ) - ) + .pipe(map((teachers) => teacherActions.addAllTeachers({ teachers }))), + ), + ), ); } diff --git a/apps/ngrx/notification/src/app/teacher/store/teacher.reducer.ts b/apps/ngrx/notification/src/app/teacher/store/teacher.reducer.ts index ecc95a0..d793b96 100644 --- a/apps/ngrx/notification/src/app/teacher/store/teacher.reducer.ts +++ b/apps/ngrx/notification/src/app/teacher/store/teacher.reducer.ts @@ -13,11 +13,11 @@ export const teacherAdapter: EntityAdapter = export const teacherReducer = createReducer( teacherAdapter.getInitialState(), on(teacherActions.addOneTeacher, (state, { teacher }) => - teacherAdapter.upsertOne(teacher, state) + teacherAdapter.upsertOne(teacher, state), ), on(teacherActions.addAllTeachers, (state, { teachers }) => - teacherAdapter.setAll(teachers, state) - ) + teacherAdapter.setAll(teachers, state), + ), ); export const { selectIds, selectEntities, selectAll, selectTotal } = diff --git a/apps/ngrx/notification/src/app/teacher/store/teacher.selectors.ts b/apps/ngrx/notification/src/app/teacher/store/teacher.selectors.ts index f9fc4f1..a32e82c 100644 --- a/apps/ngrx/notification/src/app/teacher/store/teacher.selectors.ts +++ b/apps/ngrx/notification/src/app/teacher/store/teacher.selectors.ts @@ -1,8 +1,8 @@ import { createFeatureSelector, createSelector } from '@ngrx/store'; import { + TeacherState, teacherAdapter, teachersFeatureKey, - TeacherState, } from './teacher.reducer'; const selectTeacherState = diff --git a/apps/ngrx/notification/src/index.html b/apps/ngrx/notification/src/index.html index a8fe88b..cc46b13 100644 --- a/apps/ngrx/notification/src/index.html +++ b/apps/ngrx/notification/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/ngrx/notification/src/main.ts b/apps/ngrx/notification/src/main.ts index 444ad6d..6f91f21 100644 --- a/apps/ngrx/notification/src/main.ts +++ b/apps/ngrx/notification/src/main.ts @@ -5,5 +5,5 @@ import { bootstrapApplication } from '@angular/platform-browser'; import { AppComponent } from './app/app.component'; bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err) + console.error(err), ); diff --git a/apps/nx/static-dynamic-import/.eslintrc.json b/apps/nx/static-dynamic-import/.eslintrc.json new file mode 100644 index 0000000..8ebcbfd --- /dev/null +++ b/apps/nx/static-dynamic-import/.eslintrc.json @@ -0,0 +1,36 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": [ + "plugin:@nx/angular", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "app", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "app", + "style": "kebab-case" + } + ] + } + }, + { + "files": ["*.html"], + "extends": ["plugin:@nx/angular-template"], + "rules": {} + } + ] +} diff --git a/apps/nx/static-dynamic-import/README.md b/apps/nx/static-dynamic-import/README.md new file mode 100644 index 0000000..54691c7 --- /dev/null +++ b/apps/nx/static-dynamic-import/README.md @@ -0,0 +1,13 @@ +# Static vs Dynamic Import + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve nx-static-dynamic-import +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/nx/42-static-dynamic-import/). diff --git a/apps/nx/static-dynamic-import/project.json b/apps/nx/static-dynamic-import/project.json new file mode 100644 index 0000000..c0208b0 --- /dev/null +++ b/apps/nx/static-dynamic-import/project.json @@ -0,0 +1,77 @@ +{ + "name": "nx-static-dynamic-import", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/nx/static-dynamic-import/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/nx/static-dynamic-import", + "index": "apps/nx/static-dynamic-import/src/index.html", + "browser": "apps/nx/static-dynamic-import/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/nx/static-dynamic-import/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/nx/static-dynamic-import/src/favicon.ico", + "apps/nx/static-dynamic-import/src/assets" + ], + "styles": [ + "apps/nx/static-dynamic-import/src/styles.scss", + "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css" + ], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all", + "sourceMap": true + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "nx-static-dynamic-import:build:production" + }, + "development": { + "buildTarget": "nx-static-dynamic-import:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "nx-static-dynamic-import:build" + } + }, + "lint": { + "executor": "@nx/eslint:lint", + "outputs": ["{options.outputFile}"] + } + } +} diff --git a/apps/nx/static-dynamic-import/src/app/app.component.ts b/apps/nx/static-dynamic-import/src/app/app.component.ts new file mode 100644 index 0000000..9c5bd67 --- /dev/null +++ b/apps/nx/static-dynamic-import/src/app/app.component.ts @@ -0,0 +1,27 @@ +import { + UserComponent, + type User, +} from '@angular-challenges/static-dynamic-import/users'; +import { Component } from '@angular/core'; +import { RouterOutlet } from '@angular/router'; + +@Component({ + standalone: true, + imports: [UserComponent, RouterOutlet], + selector: 'app-root', + template: ` + Author: + + + `, + host: { + class: 'flex flex-col', + }, +}) +export class AppComponent { + author: User = { + name: 'Thomas', + lastName: 'Laforge', + country: 'France', + }; +} diff --git a/apps/nx/static-dynamic-import/src/app/app.config.ts b/apps/nx/static-dynamic-import/src/app/app.config.ts new file mode 100644 index 0000000..6525263 --- /dev/null +++ b/apps/nx/static-dynamic-import/src/app/app.config.ts @@ -0,0 +1,16 @@ +import { ApplicationConfig } from '@angular/core'; +import { provideAnimations } from '@angular/platform-browser/animations'; +import { provideRouter } from '@angular/router'; + +export const appConfig: ApplicationConfig = { + providers: [ + provideAnimations(), + provideRouter([ + { + path: '', + loadComponent: () => + import('@angular-challenges/static-dynamic-import/users'), + }, + ]), + ], +}; diff --git a/apps/nx/static-dynamic-import/src/assets/.gitkeep b/apps/nx/static-dynamic-import/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/apps/nx/static-dynamic-import/src/favicon.ico b/apps/nx/static-dynamic-import/src/favicon.ico new file mode 100644 index 0000000..317ebcb Binary files /dev/null and b/apps/nx/static-dynamic-import/src/favicon.ico differ diff --git a/apps/nx/static-dynamic-import/src/index.html b/apps/nx/static-dynamic-import/src/index.html new file mode 100644 index 0000000..77adec4 --- /dev/null +++ b/apps/nx/static-dynamic-import/src/index.html @@ -0,0 +1,16 @@ + + + + + nx-static-dynamic-import + + + + + + + + + diff --git a/apps/nx/static-dynamic-import/src/main.ts b/apps/nx/static-dynamic-import/src/main.ts new file mode 100644 index 0000000..f3a7223 --- /dev/null +++ b/apps/nx/static-dynamic-import/src/main.ts @@ -0,0 +1,7 @@ +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; + +bootstrapApplication(AppComponent, appConfig).catch((err) => + console.error(err), +); diff --git a/apps/nx/static-dynamic-import/src/styles.scss b/apps/nx/static-dynamic-import/src/styles.scss new file mode 100644 index 0000000..77e408a --- /dev/null +++ b/apps/nx/static-dynamic-import/src/styles.scss @@ -0,0 +1,5 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* You can add global styles to this file, and also import other style files */ diff --git a/apps/nx/static-dynamic-import/tailwind.config.js b/apps/nx/static-dynamic-import/tailwind.config.js new file mode 100644 index 0000000..38183db --- /dev/null +++ b/apps/nx/static-dynamic-import/tailwind.config.js @@ -0,0 +1,14 @@ +const { createGlobPatternsForDependencies } = require('@nx/angular/tailwind'); +const { join } = require('path'); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + join(__dirname, 'src/**/!(*.stories|*.spec).{ts,html}'), + ...createGlobPatternsForDependencies(__dirname), + ], + theme: { + extend: {}, + }, + plugins: [], +}; diff --git a/apps/nx/static-dynamic-import/tsconfig.app.json b/apps/nx/static-dynamic-import/tsconfig.app.json new file mode 100644 index 0000000..5822042 --- /dev/null +++ b/apps/nx/static-dynamic-import/tsconfig.app.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [] + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/nx/static-dynamic-import/tsconfig.editor.json b/apps/nx/static-dynamic-import/tsconfig.editor.json new file mode 100644 index 0000000..4ee6393 --- /dev/null +++ b/apps/nx/static-dynamic-import/tsconfig.editor.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": { + "types": [] + } +} diff --git a/apps/nx/static-dynamic-import/tsconfig.json b/apps/nx/static-dynamic-import/tsconfig.json new file mode 100644 index 0000000..b94f883 --- /dev/null +++ b/apps/nx/static-dynamic-import/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/performance/christmas-web-worker/src/app/unknown-person/unknown-person.component.css b/apps/performance/christmas-web-worker/src/app/unknown-person/unknown-person.component.css index 254caa2..edc1f75 100644 --- a/apps/performance/christmas-web-worker/src/app/unknown-person/unknown-person.component.css +++ b/apps/performance/christmas-web-worker/src/app/unknown-person/unknown-person.component.css @@ -147,7 +147,9 @@ body { position: absolute; top: 40px; left: 40px; - box-shadow: 38px 0 #0078ca, 19px 20px #f69697; + box-shadow: + 38px 0 #0078ca, + 19px 20px #f69697; } .eyes:before { height: 12px; diff --git a/apps/performance/christmas-web-worker/src/index.html b/apps/performance/christmas-web-worker/src/index.html index fc6ebdf..4ca3789 100644 --- a/apps/performance/christmas-web-worker/src/index.html +++ b/apps/performance/christmas-web-worker/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/performance/default-onpush/src/app/person-list.component.ts b/apps/performance/default-onpush/src/app/person-list.component.ts index 3c6535e..c4f5569 100644 --- a/apps/performance/default-onpush/src/app/person-list.component.ts +++ b/apps/performance/default-onpush/src/app/person-list.component.ts @@ -21,7 +21,7 @@ import { MatListModule } from '@angular/material/list'; CDFlashingDirective, ], template: ` -

+

{{ title | titlecase }}

diff --git a/apps/performance/default-onpush/src/app/random.component.ts b/apps/performance/default-onpush/src/app/random.component.ts index 105f7b9..d46cdd0 100644 --- a/apps/performance/default-onpush/src/app/random.component.ts +++ b/apps/performance/default-onpush/src/app/random.component.ts @@ -4,7 +4,9 @@ import { Component } from '@angular/core'; @Component({ selector: 'app-random', standalone: true, - template: `
I do nothing but I'm here
`, + template: ` +
I do nothing but I'm here
+ `, imports: [CDFlashingDirective], }) export class RandomComponent {} diff --git a/apps/performance/default-onpush/src/index.html b/apps/performance/default-onpush/src/index.html index dcea384..eecd767 100644 --- a/apps/performance/default-onpush/src/index.html +++ b/apps/performance/default-onpush/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/performance/default-onpush/src/main.ts b/apps/performance/default-onpush/src/main.ts index 514c89a..f3a7223 100644 --- a/apps/performance/default-onpush/src/main.ts +++ b/apps/performance/default-onpush/src/main.ts @@ -1,7 +1,7 @@ import { bootstrapApplication } from '@angular/platform-browser'; -import { appConfig } from './app/app.config'; import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err) + console.error(err), ); diff --git a/apps/performance/memoized/src/app/app.component.ts b/apps/performance/memoized/src/app/app.component.ts index 01d0493..4b24fce 100644 --- a/apps/performance/memoized/src/app/app.component.ts +++ b/apps/performance/memoized/src/app/app.component.ts @@ -11,7 +11,7 @@ import { PersonListComponent } from './person-list.component';

Performance is key!!

diff --git a/apps/performance/memoized/src/app/person-list.component.ts b/apps/performance/memoized/src/app/person-list.component.ts index 1f8ae15..4a425d4 100644 --- a/apps/performance/memoized/src/app/person-list.component.ts +++ b/apps/performance/memoized/src/app/person-list.component.ts @@ -27,7 +27,7 @@ const fibonacci = (num: number): number => { MatChipsModule, ], template: ` -

+

{{ title | titlecase }}

@@ -43,7 +43,7 @@ const fibonacci = (num: number): number => {

{{ person.name }}

- {{ calculate(person.fib) }} + {{ calculate(person.fib) }}
diff --git a/apps/performance/memoized/src/index.html b/apps/performance/memoized/src/index.html index 459031f..1c07d98 100644 --- a/apps/performance/memoized/src/index.html +++ b/apps/performance/memoized/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/performance/memoized/src/main.ts b/apps/performance/memoized/src/main.ts index 514c89a..f3a7223 100644 --- a/apps/performance/memoized/src/main.ts +++ b/apps/performance/memoized/src/main.ts @@ -1,7 +1,7 @@ import { bootstrapApplication } from '@angular/platform-browser'; -import { appConfig } from './app/app.config'; import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err) + console.error(err), ); diff --git a/apps/performance/ngfor-biglist/src/app/app.component.ts b/apps/performance/ngfor-biglist/src/app/app.component.ts index 1baa61d..9c26149 100644 --- a/apps/performance/ngfor-biglist/src/app/app.component.ts +++ b/apps/performance/ngfor-biglist/src/app/app.component.ts @@ -21,13 +21,13 @@ import { PersonListComponent } from './person-list.component'; template: ` `, host: { diff --git a/apps/performance/ngfor-biglist/src/app/list.service.ts b/apps/performance/ngfor-biglist/src/app/list.service.ts index e56bdde..9a54824 100644 --- a/apps/performance/ngfor-biglist/src/app/list.service.ts +++ b/apps/performance/ngfor-biglist/src/app/list.service.ts @@ -16,7 +16,7 @@ export class PersonService { this.persons.set( this.fakeBackend .returnNewList(this.persons()) - .filter((p) => p.email !== email) + .filter((p) => p.email !== email), ); } @@ -24,7 +24,7 @@ export class PersonService { this.persons.set( this.fakeBackend .returnNewList(this.persons()) - .map((p) => (p.email === email ? { email, name: randFirstName() } : p)) + .map((p) => (p.email === email ? { email, name: randFirstName() } : p)), ); } diff --git a/apps/performance/ngfor-biglist/src/app/person-list.component.ts b/apps/performance/ngfor-biglist/src/app/person-list.component.ts index e9bbb17..4d438e6 100644 --- a/apps/performance/ngfor-biglist/src/app/person-list.component.ts +++ b/apps/performance/ngfor-biglist/src/app/person-list.component.ts @@ -9,11 +9,11 @@ import { Person } from './person.model'; standalone: true, imports: [CommonModule, NgForTrackByModule], template: ` -
+
+ class="flex h-9 items-center justify-between border-b">

{{ person.name }}

{{ person.email }}

diff --git a/apps/performance/ngfor-biglist/src/index.html b/apps/performance/ngfor-biglist/src/index.html index f23a85c..1b05827 100644 --- a/apps/performance/ngfor-biglist/src/index.html +++ b/apps/performance/ngfor-biglist/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/performance/ngfor-biglist/src/main.ts b/apps/performance/ngfor-biglist/src/main.ts index 514c89a..f3a7223 100644 --- a/apps/performance/ngfor-biglist/src/main.ts +++ b/apps/performance/ngfor-biglist/src/main.ts @@ -1,7 +1,7 @@ import { bootstrapApplication } from '@angular/platform-browser'; -import { appConfig } from './app/app.config'; import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err) + console.error(err), ); diff --git a/apps/performance/ngfor-optimize/jest.config.ts b/apps/performance/ngfor-optimize/jest.config.ts index 5b2ccae..49ac9d7 100644 --- a/apps/performance/ngfor-optimize/jest.config.ts +++ b/apps/performance/ngfor-optimize/jest.config.ts @@ -2,7 +2,7 @@ export default { displayName: 'performance-ngfor-optimize', preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], + setupFilesAfterEnv: ['/src/subscription-setup.ts'], coverageDirectory: '../../../coverage/apps/performance/ngfor-optimize', transform: { '^.+\\.(ts|mjs|js|html)$': [ diff --git a/apps/performance/ngfor-optimize/src/app/app.component.ts b/apps/performance/ngfor-optimize/src/app/app.component.ts index 58d89f4..fb9e985 100644 --- a/apps/performance/ngfor-optimize/src/app/app.component.ts +++ b/apps/performance/ngfor-optimize/src/app/app.component.ts @@ -16,7 +16,7 @@ import { PersonListComponent } from './person-list.component'; providers: [PersonService], selector: 'app-root', template: ` -

+

List of Persons

@@ -30,7 +30,7 @@ import { PersonListComponent } from './person-list.component'; diff --git a/apps/performance/ngfor-optimize/src/app/list.service.ts b/apps/performance/ngfor-optimize/src/app/list.service.ts index e56bdde..9a54824 100644 --- a/apps/performance/ngfor-optimize/src/app/list.service.ts +++ b/apps/performance/ngfor-optimize/src/app/list.service.ts @@ -16,7 +16,7 @@ export class PersonService { this.persons.set( this.fakeBackend .returnNewList(this.persons()) - .filter((p) => p.email !== email) + .filter((p) => p.email !== email), ); } @@ -24,7 +24,7 @@ export class PersonService { this.persons.set( this.fakeBackend .returnNewList(this.persons()) - .map((p) => (p.email === email ? { email, name: randFirstName() } : p)) + .map((p) => (p.email === email ? { email, name: randFirstName() } : p)), ); } diff --git a/apps/performance/ngfor-optimize/src/app/person-list.component.ts b/apps/performance/ngfor-optimize/src/app/person-list.component.ts index 69aee34..ca04956 100644 --- a/apps/performance/ngfor-optimize/src/app/person-list.component.ts +++ b/apps/performance/ngfor-optimize/src/app/person-list.component.ts @@ -10,16 +10,16 @@ import { Person } from './person.model'; template: `
+ class="flex items-center justify-between border-b">

{{ person.name }}

diff --git a/apps/performance/ngfor-optimize/src/index.html b/apps/performance/ngfor-optimize/src/index.html index 63fe2ad..e5b7990 100644 --- a/apps/performance/ngfor-optimize/src/index.html +++ b/apps/performance/ngfor-optimize/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/performance/ngfor-optimize/src/main.ts b/apps/performance/ngfor-optimize/src/main.ts index 514c89a..f3a7223 100644 --- a/apps/performance/ngfor-optimize/src/main.ts +++ b/apps/performance/ngfor-optimize/src/main.ts @@ -1,7 +1,7 @@ import { bootstrapApplication } from '@angular/platform-browser'; -import { appConfig } from './app/app.config'; import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err) + console.error(err), ); diff --git a/apps/performance/scroll-cd/jest.config.ts b/apps/performance/scroll-cd/jest.config.ts index 4c91050..7e8ea5b 100644 --- a/apps/performance/scroll-cd/jest.config.ts +++ b/apps/performance/scroll-cd/jest.config.ts @@ -2,7 +2,7 @@ export default { displayName: 'performance-scroll-cd', preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], + setupFilesAfterEnv: ['/src/subscription-setup.ts'], globals: {}, coverageDirectory: '../../../coverage/apps/performance/scroll-cd', transform: { diff --git a/apps/performance/scroll-cd/src/index.html b/apps/performance/scroll-cd/src/index.html index 5a26734..1d22cac 100644 --- a/apps/performance/scroll-cd/src/index.html +++ b/apps/performance/scroll-cd/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/rxjs/catch-error/jest.config.ts b/apps/rxjs/catch-error/jest.config.ts index f823420..be57e8c 100644 --- a/apps/rxjs/catch-error/jest.config.ts +++ b/apps/rxjs/catch-error/jest.config.ts @@ -2,7 +2,7 @@ export default { displayName: 'rxjs-catch-error', preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], + setupFilesAfterEnv: ['/src/subscription-setup.ts'], coverageDirectory: '../../../coverage/apps/rxjs/catch-error', transform: { '^.+\\.(ts|mjs|js|html)$': [ diff --git a/apps/rxjs/catch-error/src/app/app.component.ts b/apps/rxjs/catch-error/src/app/app.component.ts index 6974c93..b6ac066 100644 --- a/apps/rxjs/catch-error/src/app/app.component.ts +++ b/apps/rxjs/catch-error/src/app/app.component.ts @@ -1,8 +1,8 @@ -import { Component, DestroyRef, inject } from '@angular/core'; import { CommonModule } from '@angular/common'; import { HttpClient } from '@angular/common/http'; -import { FormsModule } from '@angular/forms'; +import { Component, DestroyRef, OnInit, inject } from '@angular/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; +import { FormsModule } from '@angular/forms'; import { Subject, concatMap, map } from 'rxjs'; @Component({ @@ -11,11 +11,11 @@ import { Subject, concatMap, map } from 'rxjs'; selector: 'app-root', template: `
- possible values: posts, comments, albums, photos, todos, users + + possible values: posts, comments, albums, photos, todos, users +
-
+ (); +export class AppComponent implements OnInit { + submit$ = new Subject(); input = ''; response: unknown; + private destroyRef = inject(DestroyRef); - constructor(private http: HttpClient) {} + private http = inject(HttpClient); + ngOnInit() { - this.submit$$ + this.submit$ .pipe( map(() => this.input), concatMap((value) => - this.http.get(`https://jsonplaceholder.typicode.com/${value}/1`) + this.http.get(`https://jsonplaceholder.typicode.com/${value}/1`), ), - takeUntilDestroyed(this.destroyRef) + takeUntilDestroyed(this.destroyRef), ) .subscribe({ next: (value) => { diff --git a/apps/rxjs/catch-error/src/app/app.config.ts b/apps/rxjs/catch-error/src/app/app.config.ts index 610704b..c5abc2a 100644 --- a/apps/rxjs/catch-error/src/app/app.config.ts +++ b/apps/rxjs/catch-error/src/app/app.config.ts @@ -1,5 +1,5 @@ -import { ApplicationConfig, importProvidersFrom } from '@angular/core'; import { HttpClientModule } from '@angular/common/http'; +import { ApplicationConfig, importProvidersFrom } from '@angular/core'; export const appConfig: ApplicationConfig = { providers: [importProvidersFrom(HttpClientModule)], diff --git a/apps/rxjs/catch-error/src/index.html b/apps/rxjs/catch-error/src/index.html index 07c9d66..7a765fa 100644 --- a/apps/rxjs/catch-error/src/index.html +++ b/apps/rxjs/catch-error/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/rxjs/catch-error/src/main.ts b/apps/rxjs/catch-error/src/main.ts index 514c89a..f3a7223 100644 --- a/apps/rxjs/catch-error/src/main.ts +++ b/apps/rxjs/catch-error/src/main.ts @@ -1,7 +1,7 @@ import { bootstrapApplication } from '@angular/platform-browser'; -import { appConfig } from './app/app.config'; import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err) + console.error(err), ); diff --git a/apps/rxjs/pipe-bug/src/app/app.component.ts b/apps/rxjs/pipe-bug/src/app/app.component.ts index b0c6951..f22b167 100644 --- a/apps/rxjs/pipe-bug/src/app/app.component.ts +++ b/apps/rxjs/pipe-bug/src/app/app.component.ts @@ -1,6 +1,6 @@ /* eslint-disable @angular-eslint/component-selector */ import { AsyncPipe, NgFor } from '@angular/common'; -import { Component, inject, Input } from '@angular/core'; +import { Component, Input, inject } from '@angular/core'; import { BehaviorSubject, take } from 'rxjs'; import { AppService } from './app.service'; import { TopicType } from './localDB.service'; @@ -29,8 +29,8 @@ export class ButtonDeleteComponent { this.message$$.next( result ? `All ${this.topic} have been deleted` - : `Error: deletion of some ${this.topic} failed` - ) + : `Error: deletion of some ${this.topic} failed`, + ), ); } } diff --git a/apps/rxjs/pipe-bug/src/app/app.service.ts b/apps/rxjs/pipe-bug/src/app/app.service.ts index 09a9ed1..7c81735 100644 --- a/apps/rxjs/pipe-bug/src/app/app.service.ts +++ b/apps/rxjs/pipe-bug/src/app/app.service.ts @@ -16,8 +16,8 @@ export class AppService { ? topicToDelete .map((t) => this.dbService.deleteOneTopic(t.id)) .reduce((acc, curr) => merge(acc, curr), of(true)) - : of(true) - ) + : of(true), + ), ); } } diff --git a/apps/rxjs/pipe-bug/src/app/localDB.service.ts b/apps/rxjs/pipe-bug/src/app/localDB.service.ts index 88d1e1d..d13d0ed 100644 --- a/apps/rxjs/pipe-bug/src/app/localDB.service.ts +++ b/apps/rxjs/pipe-bug/src/app/localDB.service.ts @@ -44,7 +44,7 @@ export class LocalDBService extends ComponentStore { deleteOne = this.updater( (state, id: number): DBState => ({ infos: state.infos.filter((i) => i.id !== id), - }) + }), ); deleteOneTopic = (id: number) => diff --git a/apps/rxjs/pipe-bug/src/index.html b/apps/rxjs/pipe-bug/src/index.html index caa71f3..401ddc0 100644 --- a/apps/rxjs/pipe-bug/src/index.html +++ b/apps/rxjs/pipe-bug/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/rxjs/race-condition/cypress.config.ts b/apps/rxjs/race-condition/cypress.config.ts index 7287d91..1abef9c 100644 --- a/apps/rxjs/race-condition/cypress.config.ts +++ b/apps/rxjs/race-condition/cypress.config.ts @@ -1,5 +1,5 @@ -import { defineConfig } from 'cypress'; import { nxComponentTestingPreset } from '@nx/angular/plugins/component-testing'; +import { defineConfig } from 'cypress'; export default defineConfig({ component: nxComponentTestingPreset(__filename), diff --git a/apps/rxjs/race-condition/cypress/support/component-index.html b/apps/rxjs/race-condition/cypress/support/component-index.html index 5ce08c7..6afcd57 100644 --- a/apps/rxjs/race-condition/cypress/support/component-index.html +++ b/apps/rxjs/race-condition/cypress/support/component-index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/rxjs/race-condition/cypress/support/component.ts b/apps/rxjs/race-condition/cypress/support/component.ts index e3684db..e7c3e3c 100644 --- a/apps/rxjs/race-condition/cypress/support/component.ts +++ b/apps/rxjs/race-condition/cypress/support/component.ts @@ -1,6 +1,6 @@ // *********************************************************** // This example support/component.ts is processed and -// loaded automatically before your test files. +// loaded automatically before your subscription files. // // This is a great place to put global configuration and // behavior that modifies Cypress. diff --git a/apps/rxjs/race-condition/jest.config.ts b/apps/rxjs/race-condition/jest.config.ts index 2e2e892..b774568 100644 --- a/apps/rxjs/race-condition/jest.config.ts +++ b/apps/rxjs/race-condition/jest.config.ts @@ -2,7 +2,7 @@ export default { displayName: 'rxjs-race-condition', preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], + setupFilesAfterEnv: ['/src/subscription-setup.ts'], globals: {}, coverageDirectory: '../../../coverage/apps/rxjs/race-condition', transform: { diff --git a/apps/rxjs/race-condition/src/app/app.component.ts b/apps/rxjs/race-condition/src/app/app.component.ts index 8b3a04a..a7eb777 100644 --- a/apps/rxjs/race-condition/src/app/app.component.ts +++ b/apps/rxjs/race-condition/src/app/app.component.ts @@ -12,7 +12,9 @@ import { TopicService, TopicType } from './topic.service'; @Component({ standalone: true, selector: 'app-root', - template: ` `, + template: ` + + `, changeDetection: ChangeDetectionStrategy.OnPush, }) export class AppComponent implements OnInit { diff --git a/apps/rxjs/race-condition/src/app/app.config.ts b/apps/rxjs/race-condition/src/app/app.config.ts index d580f04..692a8f2 100644 --- a/apps/rxjs/race-condition/src/app/app.config.ts +++ b/apps/rxjs/race-condition/src/app/app.config.ts @@ -1,5 +1,4 @@ -import { ApplicationConfig } from '@angular/core'; -import { importProvidersFrom } from '@angular/core'; +import { ApplicationConfig, importProvidersFrom } from '@angular/core'; import { MatDialogModule } from '@angular/material/dialog'; export const appConfig: ApplicationConfig = { providers: [importProvidersFrom(MatDialogModule)], diff --git a/apps/rxjs/race-condition/src/app/topic-dialog.component.ts b/apps/rxjs/race-condition/src/app/topic-dialog.component.ts index 3171241..d63ed4a 100644 --- a/apps/rxjs/race-condition/src/app/topic-dialog.component.ts +++ b/apps/rxjs/race-condition/src/app/topic-dialog.component.ts @@ -1,10 +1,11 @@ import { NgFor } from '@angular/common'; import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; -import { MatDialogModule, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog'; @Component({ - template: `

Show all Topics

+ template: ` +

Show all Topics

  • @@ -14,7 +15,8 @@ import { MatDialogModule, MAT_DIALOG_DATA } from '@angular/material/dialog';
-
`, +
+ `, imports: [MatDialogModule, MatButtonModule, NgFor], standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, diff --git a/apps/rxjs/race-condition/src/index.html b/apps/rxjs/race-condition/src/index.html index 4160653..af75950 100644 --- a/apps/rxjs/race-condition/src/index.html +++ b/apps/rxjs/race-condition/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/rxjs/race-condition/src/main.ts b/apps/rxjs/race-condition/src/main.ts index ea9f26c..9bb5c30 100644 --- a/apps/rxjs/race-condition/src/main.ts +++ b/apps/rxjs/race-condition/src/main.ts @@ -4,5 +4,5 @@ import { bootstrapApplication } from '@angular/platform-browser'; import { AppComponent } from './app/app.component'; bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err) + console.error(err), ); diff --git a/apps/testing/checkbox/jest.config.ts b/apps/testing/checkbox/jest.config.ts index 0c59029..ea6f808 100644 --- a/apps/testing/checkbox/jest.config.ts +++ b/apps/testing/checkbox/jest.config.ts @@ -2,7 +2,7 @@ export default { displayName: 'testing-checkbox', preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], + setupFilesAfterEnv: ['/src/subscription-setup.ts'], coverageDirectory: '../../../coverage/apps/testing/checkbox', transform: { '^.+\\.(ts|mjs|js|html)$': [ diff --git a/apps/testing/checkbox/src/app/app.component.ts b/apps/testing/checkbox/src/app/app.component.ts index 3a2eb36..936cc78 100644 --- a/apps/testing/checkbox/src/app/app.component.ts +++ b/apps/testing/checkbox/src/app/app.component.ts @@ -3,7 +3,8 @@ import { Component } from '@angular/core'; @Component({ standalone: true, selector: 'app-root', - template: ` + template: ` + `, + + `, }) export class AppComponent { check = false; diff --git a/apps/testing/checkbox/src/index.html b/apps/testing/checkbox/src/index.html index c4f1121..75e95fe 100644 --- a/apps/testing/checkbox/src/index.html +++ b/apps/testing/checkbox/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/testing/create-harness/jest.config.ts b/apps/testing/create-harness/jest.config.ts index 1178b8a..195dab1 100644 --- a/apps/testing/create-harness/jest.config.ts +++ b/apps/testing/create-harness/jest.config.ts @@ -2,7 +2,7 @@ export default { displayName: 'testing-create-harness', preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], + setupFilesAfterEnv: ['/src/subscription-setup.ts'], transform: { '^.+\\.(ts|mjs|js|html)$': [ 'jest-preset-angular', diff --git a/apps/testing/create-harness/src/app/slider.component.ts b/apps/testing/create-harness/src/app/slider.component.ts index 1c07c11..bc77ff1 100644 --- a/apps/testing/create-harness/src/app/slider.component.ts +++ b/apps/testing/create-harness/src/app/slider.component.ts @@ -11,7 +11,7 @@ import { skip } from 'rxjs'; template: ` -
+
diff --git a/apps/testing/create-harness/src/index.html b/apps/testing/create-harness/src/index.html index 491a132..03bd39e 100644 --- a/apps/testing/create-harness/src/index.html +++ b/apps/testing/create-harness/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/testing/create-harness/src/main.ts b/apps/testing/create-harness/src/main.ts index 514c89a..f3a7223 100644 --- a/apps/testing/create-harness/src/main.ts +++ b/apps/testing/create-harness/src/main.ts @@ -1,7 +1,7 @@ import { bootstrapApplication } from '@angular/platform-browser'; -import { appConfig } from './app/app.config'; import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err) + console.error(err), ); diff --git a/apps/testing/harness/jest.config.ts b/apps/testing/harness/jest.config.ts index 2b9e6d4..e342863 100644 --- a/apps/testing/harness/jest.config.ts +++ b/apps/testing/harness/jest.config.ts @@ -2,7 +2,7 @@ export default { displayName: 'testing-harness', preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], + setupFilesAfterEnv: ['/src/subscription-setup.ts'], transform: { '^.+\\.(ts|mjs|js|html)$': [ 'jest-preset-angular', diff --git a/apps/testing/harness/src/app/app.component.ts b/apps/testing/harness/src/app/app.component.ts index 76ccd4d..1f89505 100644 --- a/apps/testing/harness/src/app/app.component.ts +++ b/apps/testing/harness/src/app/app.component.ts @@ -5,7 +5,9 @@ import { ChildComponent } from './child.component'; standalone: true, imports: [ChildComponent], selector: 'app-root', - template: ``, + template: ` + + `, styles: [''], }) export class AppComponent {} diff --git a/apps/testing/harness/src/app/child.component.ts b/apps/testing/harness/src/app/child.component.ts index 178c06c..cc9a03e 100644 --- a/apps/testing/harness/src/app/child.component.ts +++ b/apps/testing/harness/src/app/child.component.ts @@ -15,7 +15,7 @@ import { MatSliderModule } from '@angular/material/slider';

Slider configuration

- + Value - + Min value - + Max value - + Step size diff --git a/apps/testing/harness/src/index.html b/apps/testing/harness/src/index.html index 1141708..a412201 100644 --- a/apps/testing/harness/src/index.html +++ b/apps/testing/harness/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/testing/harness/src/main.ts b/apps/testing/harness/src/main.ts index 514c89a..f3a7223 100644 --- a/apps/testing/harness/src/main.ts +++ b/apps/testing/harness/src/main.ts @@ -1,7 +1,7 @@ import { bootstrapApplication } from '@angular/platform-browser'; -import { appConfig } from './app/app.config'; import { AppComponent } from './app/app.component'; +import { appConfig } from './app/app.config'; bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err) + console.error(err), ); diff --git a/apps/testing/input-output/cypress.config.ts b/apps/testing/input-output/cypress.config.ts index 7287d91..1abef9c 100644 --- a/apps/testing/input-output/cypress.config.ts +++ b/apps/testing/input-output/cypress.config.ts @@ -1,5 +1,5 @@ -import { defineConfig } from 'cypress'; import { nxComponentTestingPreset } from '@nx/angular/plugins/component-testing'; +import { defineConfig } from 'cypress'; export default defineConfig({ component: nxComponentTestingPreset(__filename), diff --git a/apps/testing/input-output/cypress/support/component-index.html b/apps/testing/input-output/cypress/support/component-index.html index c04f2f6..57debcf 100644 --- a/apps/testing/input-output/cypress/support/component-index.html +++ b/apps/testing/input-output/cypress/support/component-index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/testing/input-output/cypress/support/component.ts b/apps/testing/input-output/cypress/support/component.ts index e3684db..e7c3e3c 100644 --- a/apps/testing/input-output/cypress/support/component.ts +++ b/apps/testing/input-output/cypress/support/component.ts @@ -1,6 +1,6 @@ // *********************************************************** // This example support/component.ts is processed and -// loaded automatically before your test files. +// loaded automatically before your subscription files. // // This is a great place to put global configuration and // behavior that modifies Cypress. diff --git a/apps/testing/input-output/jest.config.ts b/apps/testing/input-output/jest.config.ts index 63370e2..7d23121 100644 --- a/apps/testing/input-output/jest.config.ts +++ b/apps/testing/input-output/jest.config.ts @@ -2,7 +2,7 @@ export default { displayName: 'testing-input-output', preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], + setupFilesAfterEnv: ['/src/subscription-setup.ts'], transform: { '^.+\\.(ts|mjs|js|html)$': [ 'jest-preset-angular', diff --git a/apps/testing/input-output/src/index.html b/apps/testing/input-output/src/index.html index 435d4bb..bb1c5ed 100644 --- a/apps/testing/input-output/src/index.html +++ b/apps/testing/input-output/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/testing/modal/cypress.config.ts b/apps/testing/modal/cypress.config.ts index 7287d91..1abef9c 100644 --- a/apps/testing/modal/cypress.config.ts +++ b/apps/testing/modal/cypress.config.ts @@ -1,5 +1,5 @@ -import { defineConfig } from 'cypress'; import { nxComponentTestingPreset } from '@nx/angular/plugins/component-testing'; +import { defineConfig } from 'cypress'; export default defineConfig({ component: nxComponentTestingPreset(__filename), diff --git a/apps/testing/modal/cypress/support/component-index.html b/apps/testing/modal/cypress/support/component-index.html index 539b1d2..7af6567 100644 --- a/apps/testing/modal/cypress/support/component-index.html +++ b/apps/testing/modal/cypress/support/component-index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/testing/modal/cypress/support/component.ts b/apps/testing/modal/cypress/support/component.ts index e3684db..e7c3e3c 100644 --- a/apps/testing/modal/cypress/support/component.ts +++ b/apps/testing/modal/cypress/support/component.ts @@ -1,6 +1,6 @@ // *********************************************************** // This example support/component.ts is processed and -// loaded automatically before your test files. +// loaded automatically before your subscription files. // // This is a great place to put global configuration and // behavior that modifies Cypress. diff --git a/apps/testing/modal/jest.config.ts b/apps/testing/modal/jest.config.ts index 809080b..137c0c8 100644 --- a/apps/testing/modal/jest.config.ts +++ b/apps/testing/modal/jest.config.ts @@ -2,7 +2,7 @@ export default { displayName: 'testing-modal', preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], + setupFilesAfterEnv: ['/src/subscription-setup.ts'], transform: { '^.+\\.(ts|mjs|js|html)$': [ 'jest-preset-angular', diff --git a/apps/testing/modal/src/app/app.component.ts b/apps/testing/modal/src/app/app.component.ts index 8c0fd8d..afb4b29 100644 --- a/apps/testing/modal/src/app/app.component.ts +++ b/apps/testing/modal/src/app/app.component.ts @@ -58,8 +58,8 @@ export class AppComponent { .afterClosed() .subscribe((result) => this.result.next( - result ? 'Name has been submitted' : 'Name is invalid !!' - ) + result ? 'Name has been submitted' : 'Name is invalid !!', + ), ); } } diff --git a/apps/testing/modal/src/app/error.dialog.ts b/apps/testing/modal/src/app/error.dialog.ts index 2dd11e1..38412ba 100644 --- a/apps/testing/modal/src/app/error.dialog.ts +++ b/apps/testing/modal/src/app/error.dialog.ts @@ -9,7 +9,9 @@ import { MatDialogModule } from '@angular/material/dialog'; template: `

Error

- You must enter a name first!! + You must enter a + name + first!!
diff --git a/apps/testing/modal/src/index.html b/apps/testing/modal/src/index.html index ce6d8d4..f63ff68 100644 --- a/apps/testing/modal/src/index.html +++ b/apps/testing/modal/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/testing/modal/src/main.ts b/apps/testing/modal/src/main.ts index 4ecc5cf..7961924 100644 --- a/apps/testing/modal/src/main.ts +++ b/apps/testing/modal/src/main.ts @@ -1,8 +1,8 @@ -import { appConfig } from './app/app.config'; import { bootstrapApplication } from '@angular/platform-browser'; +import { appConfig } from './app/app.config'; import { AppComponent } from './app/app.component'; bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err) + console.error(err), ); diff --git a/apps/testing/nested/cypress.config.ts b/apps/testing/nested/cypress.config.ts index 7287d91..1abef9c 100644 --- a/apps/testing/nested/cypress.config.ts +++ b/apps/testing/nested/cypress.config.ts @@ -1,5 +1,5 @@ -import { defineConfig } from 'cypress'; import { nxComponentTestingPreset } from '@nx/angular/plugins/component-testing'; +import { defineConfig } from 'cypress'; export default defineConfig({ component: nxComponentTestingPreset(__filename), diff --git a/apps/testing/nested/cypress/support/component-index.html b/apps/testing/nested/cypress/support/component-index.html index ee5b073..f1b19dd 100644 --- a/apps/testing/nested/cypress/support/component-index.html +++ b/apps/testing/nested/cypress/support/component-index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/testing/nested/cypress/support/component.ts b/apps/testing/nested/cypress/support/component.ts index e3684db..e7c3e3c 100644 --- a/apps/testing/nested/cypress/support/component.ts +++ b/apps/testing/nested/cypress/support/component.ts @@ -1,6 +1,6 @@ // *********************************************************** // This example support/component.ts is processed and -// loaded automatically before your test files. +// loaded automatically before your subscription files. // // This is a great place to put global configuration and // behavior that modifies Cypress. diff --git a/apps/testing/nested/jest.config.ts b/apps/testing/nested/jest.config.ts index a89947b..b6643db 100644 --- a/apps/testing/nested/jest.config.ts +++ b/apps/testing/nested/jest.config.ts @@ -2,7 +2,7 @@ export default { displayName: 'testing-nested', preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], + setupFilesAfterEnv: ['/src/subscription-setup.ts'], transform: { '^.+\\.(ts|mjs|js|html)$': [ 'jest-preset-angular', diff --git a/apps/testing/nested/src/app/app.component.ts b/apps/testing/nested/src/app/app.component.ts index 8877b8c..098836b 100644 --- a/apps/testing/nested/src/app/app.component.ts +++ b/apps/testing/nested/src/app/app.component.ts @@ -5,6 +5,8 @@ import { ChildComponent } from './child.component'; standalone: true, imports: [ChildComponent], selector: 'app-root', - template: ` `, + template: ` + + `, }) export class AppComponent {} diff --git a/apps/testing/nested/src/app/child.component.ts b/apps/testing/nested/src/app/child.component.ts index e148cca..bcee84e 100644 --- a/apps/testing/nested/src/app/child.component.ts +++ b/apps/testing/nested/src/app/child.component.ts @@ -14,7 +14,9 @@ import { HttpService } from './http.service'; selector: 'app-input', standalone: true, imports: [ReactiveFormsModule], - template: ` `, + template: ` + + `, changeDetection: ChangeDetectionStrategy.OnPush, }) export class InputComponent { @@ -24,7 +26,9 @@ export class InputComponent { @Component({ selector: 'result', standalone: true, - template: `

Title is {{ title }}

`, + template: ` +

Title is {{ title }}

+ `, changeDetection: ChangeDetectionStrategy.OnPush, }) export class ResultComponent { @@ -34,7 +38,9 @@ export class ResultComponent { @Component({ selector: 'app-button', standalone: true, - template: ``, + template: ` + + `, changeDetection: ChangeDetectionStrategy.OnPush, }) export class ButtonComponent { @@ -44,7 +50,9 @@ export class ButtonComponent { @Component({ selector: 'app-error', standalone: true, - template: `

Title is required !!!

`, + template: ` +

Title is required !!!

+ `, changeDetection: ChangeDetectionStrategy.OnPush, }) export class ErrorComponent { diff --git a/apps/testing/nested/src/index.html b/apps/testing/nested/src/index.html index 93eefa7..620e0cd 100644 --- a/apps/testing/nested/src/index.html +++ b/apps/testing/nested/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/testing/router-outlet/cypress.config.ts b/apps/testing/router-outlet/cypress.config.ts index 7287d91..1abef9c 100644 --- a/apps/testing/router-outlet/cypress.config.ts +++ b/apps/testing/router-outlet/cypress.config.ts @@ -1,5 +1,5 @@ -import { defineConfig } from 'cypress'; import { nxComponentTestingPreset } from '@nx/angular/plugins/component-testing'; +import { defineConfig } from 'cypress'; export default defineConfig({ component: nxComponentTestingPreset(__filename), diff --git a/apps/testing/router-outlet/cypress/support/component-index.html b/apps/testing/router-outlet/cypress/support/component-index.html index 4d7f518..208ea71 100644 --- a/apps/testing/router-outlet/cypress/support/component-index.html +++ b/apps/testing/router-outlet/cypress/support/component-index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/testing/router-outlet/cypress/support/component.ts b/apps/testing/router-outlet/cypress/support/component.ts index e3684db..e7c3e3c 100644 --- a/apps/testing/router-outlet/cypress/support/component.ts +++ b/apps/testing/router-outlet/cypress/support/component.ts @@ -1,6 +1,6 @@ // *********************************************************** // This example support/component.ts is processed and -// loaded automatically before your test files. +// loaded automatically before your subscription files. // // This is a great place to put global configuration and // behavior that modifies Cypress. diff --git a/apps/testing/router-outlet/jest.config.ts b/apps/testing/router-outlet/jest.config.ts index 0bca8ae..f8f0ad1 100644 --- a/apps/testing/router-outlet/jest.config.ts +++ b/apps/testing/router-outlet/jest.config.ts @@ -2,7 +2,7 @@ export default { displayName: 'testing-router-outlet', preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], + setupFilesAfterEnv: ['/src/subscription-setup.ts'], globals: {}, transform: { '^.+\\.(ts|mjs|js|html)$': [ diff --git a/apps/testing/router-outlet/src/app/book.guard.ts b/apps/testing/router-outlet/src/app/book.guard.ts index 3fe568e..1419047 100644 --- a/apps/testing/router-outlet/src/app/book.guard.ts +++ b/apps/testing/router-outlet/src/app/book.guard.ts @@ -4,7 +4,7 @@ import { availableBooks } from './book.model'; export const bookGuard = ( route: ActivatedRouteSnapshot, - router = inject(Router) + router = inject(Router), ) => { const searchParam = route.queryParams?.['book'].toLowerCase(); @@ -13,7 +13,7 @@ export const bookGuard = ( availableBooks.some( (b) => b.author.toLowerCase().includes(searchParam) || - b.name.toLowerCase().includes(searchParam) + b.name.toLowerCase().includes(searchParam), ); return isBookAvailable || router.parseUrl('no-result'); diff --git a/apps/testing/router-outlet/src/app/no-book-search.component.ts b/apps/testing/router-outlet/src/app/no-book-search.component.ts index ed41f51..17d6b97 100644 --- a/apps/testing/router-outlet/src/app/no-book-search.component.ts +++ b/apps/testing/router-outlet/src/app/no-book-search.component.ts @@ -2,7 +2,9 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; @Component({ standalone: true, - template: `
No book found for this search
`, + template: ` +
No book found for this search
+ `, changeDetection: ChangeDetectionStrategy.OnPush, }) export default class ShelfComponent {} diff --git a/apps/testing/router-outlet/src/app/shelf.component.ts b/apps/testing/router-outlet/src/app/shelf.component.ts index bb4fd5d..a7da5af 100644 --- a/apps/testing/router-outlet/src/app/shelf.component.ts +++ b/apps/testing/router-outlet/src/app/shelf.component.ts @@ -25,8 +25,8 @@ export default class ShelfComponent { availableBooks.filter( (b) => b.name.toLowerCase().includes(param) || - b.author.toLowerCase().includes(param) - ) - ) + b.author.toLowerCase().includes(param), + ), + ), ); } diff --git a/apps/testing/router-outlet/src/index.html b/apps/testing/router-outlet/src/index.html index dc98015..b706580 100644 --- a/apps/testing/router-outlet/src/index.html +++ b/apps/testing/router-outlet/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/testing/router-outlet/src/main.ts b/apps/testing/router-outlet/src/main.ts index 4ecc5cf..7961924 100644 --- a/apps/testing/router-outlet/src/main.ts +++ b/apps/testing/router-outlet/src/main.ts @@ -1,8 +1,8 @@ -import { appConfig } from './app/app.config'; import { bootstrapApplication } from '@angular/platform-browser'; +import { appConfig } from './app/app.config'; import { AppComponent } from './app/app.component'; bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err) + console.error(err), ); diff --git a/apps/testing/table/README.md b/apps/testing/table/README.md index 36451ff..ff3b4b5 100644 --- a/apps/testing/table/README.md +++ b/apps/testing/table/README.md @@ -10,13 +10,13 @@ NOT IMPLEMENTED YET If the title is correctly typed, you can send the request otherwise you get a nice error and the request is not sent. You can play with it by running : `npx nx serve testing-table`. -The goal is to test this behavior with Testing library and Cypress +The goal is to subscription this behavior with Testing library and Cypress -The file named `child.component.spec.ts` will let test your application using Testing Library. To run the test suits, you need to run `npx nx test testing-table`. You can also install [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner) to execute your test by clicking on the `Run` button above each `describe` or `it` blocks. +The file named `child.component.spec.ts` will let subscription your application using Testing Library. To run the subscription suits, you need to run `npx nx subscription testing-table`. You can also install [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner) to execute your subscription by clicking on the `Run` button above each `describe` or `it` blocks. -For testing cypress, you will execute your test inside the `child.component.cy.ts` and run `npx nx component-test testing-table` to execute your test suits. You can add the `--watch` flag to execute your test in watch mode. +For testing cypress, you will execute your subscription inside the `child.component.cy.ts` and run `npx nx component-subscription testing-table` to execute your subscription suits. You can add the `--watch` flag to execute your subscription in watch mode. -I created some `it` blocks but feel free to add more test if you like to. --> +I created some `it` blocks but feel free to add more subscription if you like to. --> ### Submitting your work diff --git a/apps/testing/table/cypress.config.ts b/apps/testing/table/cypress.config.ts index 7287d91..1abef9c 100644 --- a/apps/testing/table/cypress.config.ts +++ b/apps/testing/table/cypress.config.ts @@ -1,5 +1,5 @@ -import { defineConfig } from 'cypress'; import { nxComponentTestingPreset } from '@nx/angular/plugins/component-testing'; +import { defineConfig } from 'cypress'; export default defineConfig({ component: nxComponentTestingPreset(__filename), diff --git a/apps/testing/table/cypress/support/component-index.html b/apps/testing/table/cypress/support/component-index.html index a749e54..c0a4681 100644 --- a/apps/testing/table/cypress/support/component-index.html +++ b/apps/testing/table/cypress/support/component-index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/testing/table/cypress/support/component.ts b/apps/testing/table/cypress/support/component.ts index e3684db..e7c3e3c 100644 --- a/apps/testing/table/cypress/support/component.ts +++ b/apps/testing/table/cypress/support/component.ts @@ -1,6 +1,6 @@ // *********************************************************** // This example support/component.ts is processed and -// loaded automatically before your test files. +// loaded automatically before your subscription files. // // This is a great place to put global configuration and // behavior that modifies Cypress. diff --git a/apps/testing/table/jest.config.ts b/apps/testing/table/jest.config.ts index 56b0e7d..98474ec 100644 --- a/apps/testing/table/jest.config.ts +++ b/apps/testing/table/jest.config.ts @@ -2,7 +2,7 @@ export default { displayName: 'testing-table', preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], + setupFilesAfterEnv: ['/src/subscription-setup.ts'], transform: { '^.+\\.(ts|mjs|js|html)$': [ 'jest-preset-angular', diff --git a/apps/testing/table/src/app/app.component.ts b/apps/testing/table/src/app/app.component.ts index 534b449..236bc50 100644 --- a/apps/testing/table/src/app/app.component.ts +++ b/apps/testing/table/src/app/app.component.ts @@ -5,6 +5,8 @@ import { TableComponent } from './table.component'; standalone: true, imports: [TableComponent], selector: 'app-root', - template: ` `, + template: ` + + `, }) export class AppComponent {} diff --git a/apps/testing/table/src/app/table.component.spec.ts b/apps/testing/table/src/app/table.component.spec.ts index 2b71f26..db4015d 100644 --- a/apps/testing/table/src/app/table.component.spec.ts +++ b/apps/testing/table/src/app/table.component.spec.ts @@ -40,7 +40,7 @@ describe('AppComponent', () => { // await userEvent.click(okButton); }); - // test('error message is shown if you click "Cancel" in the confirmation modal after submitting a name', async () => { + // subscription('error message is shown if you click "Cancel" in the confirmation modal after submitting a name', async () => { // userEvent.setup(); // await render(AppComponent); @@ -68,7 +68,7 @@ describe('AppComponent', () => { // expect(errorText).toBeInTheDocument(); // }); - // test('confirm message is shown if you click "Confirm" in the confirmation modal after submitting a name', async () => { + // subscription('confirm message is shown if you click "Confirm" in the confirmation modal after submitting a name', async () => { // userEvent.setup(); // await render(AppComponent); diff --git a/apps/testing/table/src/app/table.component.ts b/apps/testing/table/src/app/table.component.ts index a2c6d4c..74df216 100644 --- a/apps/testing/table/src/app/table.component.ts +++ b/apps/testing/table/src/app/table.component.ts @@ -94,7 +94,7 @@ export class TableComponent private api = inject(FakeBackendService); readonly issues$ = this.select((s) => s.users).pipe( - tap((t) => console.log('UserNEw ', t)) + tap((t) => console.log('UserNEw ', t)), ); readonly loading$ = this.select((s) => s.loading); readonly error$ = this.select((s) => s.error); @@ -124,11 +124,11 @@ export class TableComponent tap((t) => console.log('user', t)), tapResponse( (data) => this.patchState({ users: data, loading: false }), - (err) => this.patchState({ error: err as string, loading: false }) - ) - ) - ) - ) + (err) => this.patchState({ error: err as string, loading: false }), + ), + ), + ), + ), ); ngAfterViewInit(): void { @@ -137,7 +137,7 @@ export class TableComponent this.loadData( this.select({ sortActive: this.sort.sortChange.pipe( - map((s) => s.active as keyof User) + map((s) => s.active as keyof User), ), sortDir: this.sort.sortChange.pipe(map((s) => s.direction)), pageIndex: this.paginator.page.pipe(map((p) => p.pageIndex)), @@ -146,8 +146,8 @@ export class TableComponent sortActive: this.sort.active as keyof User, sortDir: this.sort.direction, pageIndex: 1, - }) - ) + }), + ), ); } diff --git a/apps/testing/table/src/index.html b/apps/testing/table/src/index.html index 2eadaaa..11da4b0 100644 --- a/apps/testing/table/src/index.html +++ b/apps/testing/table/src/index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/testing/todos-list/cypress.config.ts b/apps/testing/todos-list/cypress.config.ts index 7287d91..1abef9c 100644 --- a/apps/testing/todos-list/cypress.config.ts +++ b/apps/testing/todos-list/cypress.config.ts @@ -1,5 +1,5 @@ -import { defineConfig } from 'cypress'; import { nxComponentTestingPreset } from '@nx/angular/plugins/component-testing'; +import { defineConfig } from 'cypress'; export default defineConfig({ component: nxComponentTestingPreset(__filename), diff --git a/apps/testing/todos-list/cypress/support/component-index.html b/apps/testing/todos-list/cypress/support/component-index.html index 8b1d587..57c8a3d 100644 --- a/apps/testing/todos-list/cypress/support/component-index.html +++ b/apps/testing/todos-list/cypress/support/component-index.html @@ -1,4 +1,4 @@ - + diff --git a/apps/testing/todos-list/cypress/support/component.ts b/apps/testing/todos-list/cypress/support/component.ts index e3684db..e7c3e3c 100644 --- a/apps/testing/todos-list/cypress/support/component.ts +++ b/apps/testing/todos-list/cypress/support/component.ts @@ -1,6 +1,6 @@ // *********************************************************** // This example support/component.ts is processed and -// loaded automatically before your test files. +// loaded automatically before your subscription files. // // This is a great place to put global configuration and // behavior that modifies Cypress. diff --git a/apps/testing/todos-list/jest.config.ts b/apps/testing/todos-list/jest.config.ts index eb61074..3b92b56 100644 --- a/apps/testing/todos-list/jest.config.ts +++ b/apps/testing/todos-list/jest.config.ts @@ -2,7 +2,7 @@ export default { displayName: 'testing-todos-list', preset: '../../../jest.preset.js', - setupFilesAfterEnv: ['/src/test-setup.ts'], + setupFilesAfterEnv: ['/src/subscription-setup.ts'], transform: { '^.+\\.(ts|mjs|js|html)$': [ 'jest-preset-angular', diff --git a/apps/testing/todos-list/src/app/app.component.ts b/apps/testing/todos-list/src/app/app.component.ts index a3de393..6b61097 100644 --- a/apps/testing/todos-list/src/app/app.component.ts +++ b/apps/testing/todos-list/src/app/app.component.ts @@ -5,6 +5,8 @@ import { RouterOutlet } from '@angular/router'; selector: 'app-root', standalone: true, imports: [RouterOutlet], - template: ``, + template: ` + + `, }) export class AppComponent {} diff --git a/apps/testing/todos-list/src/app/backend.service.ts b/apps/testing/todos-list/src/app/backend.service.ts index 2af814b..08929ed 100644 --- a/apps/testing/todos-list/src/app/backend.service.ts +++ b/apps/testing/todos-list/src/app/backend.service.ts @@ -101,7 +101,7 @@ export class BackendService { const updatedTicket = { ...foundTicket, ...updates }; this.storedTickets = this.storedTickets.map((t) => - t.id === ticketId ? updatedTicket : t + t.id === ticketId ? updatedTicket : t, ); return of(updatedTicket).pipe(delay(randomDelay())); diff --git a/apps/testing/todos-list/src/app/detail/detail.component.ts b/apps/testing/todos-list/src/app/detail/detail.component.ts index 5b5214c..7e5eed8 100644 --- a/apps/testing/todos-list/src/app/detail/detail.component.ts +++ b/apps/testing/todos-list/src/app/detail/detail.component.ts @@ -19,22 +19,28 @@ import { DetailStore } from './detail.store'; LetDirective, ], template: ` -

Ticket Detail:

+

Ticket Detail:

-
Ticket: {{ ticket.id }}
- Description: {{ ticket.description }} + Ticket: + {{ ticket.id }}
- AssigneeId: {{ ticket.assigneeId }} + Description: + {{ ticket.description }}
- Is done: {{ ticket.completed }} + AssigneeId: + {{ ticket.assigneeId }} +
+
+ Is done: + {{ ticket.completed }}
diff --git a/apps/testing/todos-list/src/app/detail/detail.store.ts b/apps/testing/todos-list/src/app/detail/detail.store.ts index 9d0f421..9425b25 100644 --- a/apps/testing/todos-list/src/app/detail/detail.store.ts +++ b/apps/testing/todos-list/src/app/detail/detail.store.ts @@ -36,14 +36,17 @@ export class DetailStore loading: this.loading$, }); - constructor(private backend: BackendService, private route: ActivatedRoute) { + constructor( + private backend: BackendService, + private route: ActivatedRoute, + ) { super(initialState); } readonly loadTicket = this.effect( pipe( concatLatestFrom(() => - this.route.params.pipe(map((p) => p[PARAM_TICKET_ID])) + this.route.params.pipe(map((p) => p[PARAM_TICKET_ID])), ), tap(() => this.patchState({ loading: true, error: '' })), mergeMap(([, id]) => @@ -54,11 +57,11 @@ export class DetailStore loading: false, ticket, }), - (error: unknown) => this.patchState({ error }) - ) - ) - ) - ) + (error: unknown) => this.patchState({ error }), + ), + ), + ), + ), ); ngrxOnStateInit() { diff --git a/apps/testing/todos-list/src/app/list/list.component.ts b/apps/testing/todos-list/src/app/list/list.component.ts index bc24485..8942f7c 100644 --- a/apps/testing/todos-list/src/app/list/list.component.ts +++ b/apps/testing/todos-list/src/app/list/list.component.ts @@ -25,7 +25,7 @@ import { RowComponent } from './ui/row.component'; LetDirective, ], template: ` -

Tickets

+

Tickets

Search @@ -45,14 +45,13 @@ import { RowComponent } from './ui/row.component'; mode="query" *ngIf="vm.loading" class="mt-5"> -