diff --git a/.all-contributorsrc b/.all-contributorsrc index 7d073e621..6f2f57401 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -29,6 +29,10 @@ "translation-ru": { "symbol": "🇷🇺", "description": "Translate in Russian" + }, + "translation-ch": { + "symbol": "🇨🇳", + "description": "Translate in Chinese" } }, "contributors": [ @@ -109,6 +113,25 @@ "challenge" ] }, + { + "login": "LMFinney", + "name": "Lance Finney", + "avatar_url": "https://avatars.githubusercontent.com/u/6683747?v=4", + "profile": "https://github.com/LMFinney", + "contributions": [ + "doc", + "challenge" + ] + }, + { + "login": "tsironis13", + "name": "Tsironis Ioannis", + "avatar_url": "https://avatars.githubusercontent.com/u/7561447?v=4", + "profile": "https://github.com/tsironis13", + "contributions": [ + "challenge" + ] + }, { "login": "alan-bio", "name": "Alan Dragicevich", @@ -258,6 +281,88 @@ "contributions": [ "doc" ] + }, + { + "login": "alannelucq", + "name": "Arthur LANNELUCQ", + "avatar_url": "https://avatars.githubusercontent.com/u/44091408?v=4", + "profile": "https://github.com/alannelucq", + "contributions": [ + "translation-fr" + ] + }, + { + "login": "fixedmichal", + "name": "fixed_michal", + "avatar_url": "https://avatars.githubusercontent.com/u/26270192?v=4", + "profile": "https://github.com/fixedmichal", + "contributions": [ + "bug" + ] + }, + { + "login": "Tenessy", + "name": "Tenessy", + "avatar_url": "https://avatars.githubusercontent.com/u/65855673?v=4", + "profile": "https://github.com/Tenessy", + "contributions": [ + "bug" + ] + }, + { + "login": "EnochGao", + "name": "Enoch Gao", + "avatar_url": "https://avatars.githubusercontent.com/u/41459067?v=4", + "profile": "https://enochgao.github.io/", + "contributions": [ + "doc", + "translation-ch" + ] + }, + { + "login": "fpalmab", + "name": "Francisco Palma", + "avatar_url": "https://avatars.githubusercontent.com/u/7729812?v=4", + "profile": "https://github.com/fpalmab", + "contributions": [ + "bug" + ] + }, + { + "login": "michalgrzegorczyk-dev", + "name": "Michał Grzegorczyk", + "avatar_url": "https://avatars.githubusercontent.com/u/47832176?v=4", + "profile": "https://github.com/michalgrzegorczyk-dev", + "contributions": [ + "doc" + ] + }, + { + "login": "tamim36", + "name": "Tamim Arefin Anik", + "avatar_url": "https://avatars.githubusercontent.com/u/42251521?v=4", + "profile": "https://github.com/tamim36", + "contributions": [ + "bug" + ] + }, + { + "login": "WhoisBsa", + "name": "Matheus B.", + "avatar_url": "https://avatars.githubusercontent.com/u/36895235?v=4", + "profile": "https://github.com/WhoisBsa", + "contributions": [ + "bug" + ] + }, + { + "login": "StefH", + "name": "Stef Heyenrath", + "avatar_url": "https://avatars.githubusercontent.com/u/249938?v=4", + "profile": "https://sourcerer.io/stefh", + "contributions": [ + "doc" + ] } ], "contributorsPerLine": 7, diff --git a/.eslintrc.json b/.eslintrc.json index c222fb084..de9b234b6 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -6,6 +6,7 @@ { "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], "rules": { + "@angular-eslint/no-host-metadata-property": "off", "@nx/enforce-module-boundaries": [ "error", { @@ -18,24 +19,24 @@ } ] } - ], - "@angular-eslint/no-host-metadata-property": [ - "error", - { - "allowStatic": true - } ] } }, { "files": ["*.ts", "*.tsx"], "extends": ["plugin:@nx/typescript"], - "rules": {} + "rules": { + "@typescript-eslint/no-extra-semi": "error", + "no-extra-semi": "off" + } }, { "files": ["*.js", "*.jsx"], "extends": ["plugin:@nx/javascript"], - "rules": {} + "rules": { + "@typescript-eslint/no-extra-semi": "error", + "no-extra-semi": "off" + } }, { "files": ["*.spec.ts", "*.spec.tsx", "*.spec.js", "*.spec.jsx"], diff --git a/.github/funding.yml b/.github/funding.yml new file mode 100644 index 000000000..f1327048f --- /dev/null +++ b/.github/funding.yml @@ -0,0 +1 @@ +github: [tomalaforge] diff --git a/.github/github-action/contributors.js b/.github/github-action/contributors.js index 1a9345f84..cea002096 100644 --- a/.github/github-action/contributors.js +++ b/.github/github-action/contributors.js @@ -8,9 +8,24 @@ const contributors = [ 'webbomj', 'kabrunko-dev', 'Sanjar1304', + 'tsironis13', + 'EnochGao', ]; -const sponsors = ['ddotx', 'LMFinney', 'alannelucq']; +const sponsors = [ + 'ddotx', + 'LMFinney', + 'alannelucq', + 'SidV2', + 'fpalmab', + 'CivilEngeneer', + 'apalaio', + 'amosISA', + 'michalgrzegorczyk-dev', + 'zealotrahl', + 'DzoeL123', + 'allan1989', +]; module.exports = { contributors, diff --git a/.github/workflows/close-inactive-pr.yml b/.github/workflows/close-inactive-pr.yml index 2d5925830..d5e0e9c95 100644 --- a/.github/workflows/close-inactive-pr.yml +++ b/.github/workflows/close-inactive-pr.yml @@ -17,11 +17,12 @@ jobs: stale-issue-label: 'stale' stale-issue-message: 'This issue is stale because it has been open for 15 days with no activity.' exempt-issue-labels: 'long-term' - days-before-pr-stale: 10 - days-before-pr-close: 2 + 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 15 days with no activity.' close-pr-message: 'This pull request was closed because it has been inactive for 5 days since being marked as stale.' only-pr-labels: 'answer' - exempt-pr-labels: 'challenge-creation, long-term' + exempt-pr-labels: 'challenge-creation, long-term, to be reviewed' + remove-pr-stale-when-updated: true repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/label-issue-update.yml b/.github/workflows/label-issue-update.yml new file mode 100644 index 000000000..5f79b0568 --- /dev/null +++ b/.github/workflows/label-issue-update.yml @@ -0,0 +1,21 @@ +name: updates Labels + +on: + push: + branches-ignore: + - main + +jobs: + update_labels: + runs-on: ubuntu-latest + if: | + contains(github.event.pull_request.labels.*.name, 'sponsor') || + contains(github.event.pull_request.labels.*.name, 'contributor') + steps: + - name: checkout + uses: actions/checkout@v2 + + - name: Add labels + uses: actions-ecosystem/action-add-labels@v1 + with: + labels: to be reviewed/update diff --git a/.github/workflows/label-issue.yml b/.github/workflows/label-issue.yml index 6918818fd..a5fd40632 100644 --- a/.github/workflows/label-issue.yml +++ b/.github/workflows/label-issue.yml @@ -2,9 +2,25 @@ name: Add Labels on: pull_request_target: - types: [ opened ] + types: [ opened, edited, synchronize ] jobs: + check-title: + runs-on: ubuntu-latest + steps: + - name: Check PR title + env: + PR_TITLE: ${{ github.event.pull_request.title }} + run: | + echo "Checking PR Title: '$PR_TITLE'" + if [[ ! "$PR_TITLE" =~ ^Answer: ]]; then + echo "❌ PR title should start with 'Answer:[#challenge number]'" + echo "### ❌ PR title should start with 'Answer:[#challenge number]'" >> $GITHUB_STEP_SUMMARY + exit 1 + else + echo "✅ PR title format is correct." + echo "### ✅ PR title format is correct." >> $GITHUB_STEP_SUMMARY + fi add_labels: runs-on: ubuntu-latest if: ${{ startsWith(github.event.pull_request.title, 'Answer') }} diff --git a/.gitignore b/.gitignore index 5472d6bdf..cad0abc01 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,6 @@ Thumbs.db TODO.md .nx/cache +.nx/workspace-data + +.cursorrules \ No newline at end of file diff --git a/.prettierignore b/.prettierignore index ab639d33d..a4684ea74 100644 --- a/.prettierignore +++ b/.prettierignore @@ -5,4 +5,5 @@ .angular -/.nx/cache \ No newline at end of file +/.nx/cache +/.nx/workspace-data \ No newline at end of file diff --git a/README.md b/README.md index a50b2c028..2965ecc08 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 51 challenges](https://angular-challenges.vercel.app/) +Check [all 59 challenges](https://angular-challenges.vercel.app/) ## Contributors ✨ @@ -43,26 +43,39 @@ Check [all 51 challenges](https://angular-challenges.vercel.app/) Timothy Alcaide
Timothy Alcaide

🧩 + Lance Finney
Lance Finney

📖 🧩 + Tsironis Ioannis
Tsironis Ioannis

🧩 Alan Dragicevich
Alan Dragicevich

📖 Michel EDIGHOFFER
Michel EDIGHOFFER

📖 Gerardo Sebastian Gonzalez
Gerardo Sebastian Gonzalez

📖 Evseev Yuriy
Evseev Yuriy

🐛 Tomer953
Tomer953

🐛 📖 💻 - Dmitriy Mishchenko
Dmitriy Mishchenko

📖 - Sagar Devkota
Sagar Devkota

📖 💻 + Dmitriy Mishchenko
Dmitriy Mishchenko

📖 + Sagar Devkota
Sagar Devkota

📖 💻 Nelson Gutierrez
Nelson Gutierrez

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

📖 Diogo Nishikawa
Diogo Nishikawa

💻 🇵🇹 📖 Erick Rodriguez
Erick Rodriguez

🇪🇸 Eduardo Roth
Eduardo Roth

📖 🇪🇸 - Fernando Bello
Fernando Bello

📖 - Лапин Андрей (Lapin Andrey)
Лапин Андрей (Lapin Andrey)

🇷🇺 + Fernando Bello
Fernando Bello

📖 + Лапин Андрей (Lapin Andrey)
Лапин Андрей (Lapin Andrey)

🇷🇺 Dinar Shagaliev
Dinar Shagaliev

🇷🇺 Vimulatus
Vimulatus

📖 + Arthur LANNELUCQ
Arthur LANNELUCQ

🇫🇷 + fixed_michal
fixed_michal

🐛 + Tenessy
Tenessy

🐛 + + + Enoch Gao
Enoch Gao

📖 🇨🇳 + Francisco Palma
Francisco Palma

🐛 + Michał Grzegorczyk
Michał Grzegorczyk

📖 + Tamim Arefin Anik
Tamim Arefin Anik

🐛 + Matheus B.
Matheus B.

🐛 + Stef Heyenrath
Stef Heyenrath

📖 diff --git a/apps/angular/1-projection/project.json b/apps/angular/1-projection/project.json index 0e6b88ba4..d40912c35 100644 --- a/apps/angular/1-projection/project.json +++ b/apps/angular/1-projection/project.json @@ -4,14 +4,15 @@ "projectType": "application", "sourceRoot": "apps/angular/1-projection/src", "prefix": "app", + "tags": [], "targets": { "build": { - "executor": "@angular-devkit/build-angular:application", + "executor": "@angular-devkit/build-angular:browser", "outputs": ["{options.outputPath}"], "options": { "outputPath": "dist/apps/angular/1-projection", "index": "apps/angular/1-projection/src/index.html", - "browser": "apps/angular/1-projection/src/main.ts", + "main": "apps/angular/1-projection/src/main.ts", "polyfills": ["apps/angular/1-projection/src/polyfills.ts"], "tsConfig": "apps/angular/1-projection/tsconfig.app.json", "inlineStyleLanguage": "scss", @@ -40,7 +41,9 @@ "outputHashing": "all" }, "development": { + "buildOptimizer": false, "optimization": false, + "vendorChunk": true, "extractLicenses": false, "sourceMap": true, "namedChunks": true @@ -66,16 +69,16 @@ "buildTarget": "angular-projection:build" } }, - "lint": { - "executor": "@nx/eslint:lint" - }, "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], "options": { - "jestConfig": "apps/angular/1-projection/jest.config.ts" + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } } } - }, - "tags": [] + } } diff --git a/apps/angular/1-projection/src/app/app.component.ts b/apps/angular/1-projection/src/app/app.component.ts index b1d076a9f..df654bbc2 100644 --- a/apps/angular/1-projection/src/app/app.component.ts +++ b/apps/angular/1-projection/src/app/app.component.ts @@ -7,12 +7,11 @@ import { TeacherCardComponent } from './component/teacher-card/teacher-card.comp selector: 'app-root', template: `
- - - + + +
`, - standalone: true, imports: [TeacherCardComponent, StudentCardComponent, CityCardComponent], }) export class AppComponent {} diff --git a/apps/angular/1-projection/src/app/component/city-card/city-card.component.ts b/apps/angular/1-projection/src/app/component/city-card/city-card.component.ts index 30c8f88ec..8895c8c84 100644 --- a/apps/angular/1-projection/src/app/component/city-card/city-card.component.ts +++ b/apps/angular/1-projection/src/app/component/city-card/city-card.component.ts @@ -1,13 +1,9 @@ -import { Component, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; @Component({ selector: 'app-city-card', template: 'TODO City', - standalone: true, imports: [], + changeDetection: ChangeDetectionStrategy.OnPush, }) -export class CityCardComponent implements OnInit { - constructor() {} - - ngOnInit(): void {} -} +export class CityCardComponent {} diff --git a/apps/angular/1-projection/src/app/component/student-card/student-card.component.ts b/apps/angular/1-projection/src/app/component/student-card/student-card.component.ts index 441cda189..bdfa4abd4 100644 --- a/apps/angular/1-projection/src/app/component/student-card/student-card.component.ts +++ b/apps/angular/1-projection/src/app/component/student-card/student-card.component.ts @@ -1,19 +1,22 @@ -import { Component, OnInit } from '@angular/core'; +import { + ChangeDetectionStrategy, + Component, + inject, + OnInit, +} from '@angular/core'; import { FakeHttpService } from '../../data-access/fake-http.service'; import { StudentStore } from '../../data-access/student.store'; import { CardType } from '../../model/card.model'; -import { Student } from '../../model/student.model'; import { CardComponent } from '../../ui/card/card.component'; @Component({ selector: 'app-student-card', template: ` + customClass="bg-light-green" /> `, - standalone: true, styles: [ ` ::ng-deep .bg-light-green { @@ -22,19 +25,16 @@ import { CardComponent } from '../../ui/card/card.component'; `, ], imports: [CardComponent], + changeDetection: ChangeDetectionStrategy.OnPush, }) export class StudentCardComponent implements OnInit { - students: Student[] = []; - cardType = CardType.STUDENT; + private http = inject(FakeHttpService); + private store = inject(StudentStore); - constructor( - private http: FakeHttpService, - private store: StudentStore, - ) {} + students = this.store.students; + cardType = CardType.STUDENT; ngOnInit(): void { this.http.fetchStudents$.subscribe((s) => this.store.addAll(s)); - - this.store.students$.subscribe((s) => (this.students = s)); } } diff --git a/apps/angular/1-projection/src/app/component/teacher-card/teacher-card.component.ts b/apps/angular/1-projection/src/app/component/teacher-card/teacher-card.component.ts index 995cb7c2f..adf0ad3c1 100644 --- a/apps/angular/1-projection/src/app/component/teacher-card/teacher-card.component.ts +++ b/apps/angular/1-projection/src/app/component/teacher-card/teacher-card.component.ts @@ -1,15 +1,14 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, inject, OnInit } from '@angular/core'; import { FakeHttpService } from '../../data-access/fake-http.service'; import { TeacherStore } from '../../data-access/teacher.store'; import { CardType } from '../../model/card.model'; -import { Teacher } from '../../model/teacher.model'; import { CardComponent } from '../../ui/card/card.component'; @Component({ selector: 'app-teacher-card', template: ` `, @@ -20,21 +19,16 @@ import { CardComponent } from '../../ui/card/card.component'; } `, ], - standalone: true, imports: [CardComponent], }) export class TeacherCardComponent implements OnInit { - teachers: Teacher[] = []; - cardType = CardType.TEACHER; + private http = inject(FakeHttpService); + private store = inject(TeacherStore); - constructor( - private http: FakeHttpService, - private store: TeacherStore, - ) {} + teachers = this.store.teachers; + cardType = CardType.TEACHER; ngOnInit(): void { this.http.fetchTeachers$.subscribe((t) => this.store.addAll(t)); - - this.store.teachers$.subscribe((t) => (this.teachers = t)); } } diff --git a/apps/angular/1-projection/src/app/data-access/city.store.ts b/apps/angular/1-projection/src/app/data-access/city.store.ts index 711dad1d7..a8b523569 100644 --- a/apps/angular/1-projection/src/app/data-access/city.store.ts +++ b/apps/angular/1-projection/src/app/data-access/city.store.ts @@ -1,23 +1,21 @@ -import { Injectable } from '@angular/core'; -import { BehaviorSubject } from 'rxjs'; +import { Injectable, signal } from '@angular/core'; import { City } from '../model/city.model'; @Injectable({ providedIn: 'root', }) export class CityStore { - private cities = new BehaviorSubject([]); - cities$ = this.cities.asObservable(); + private cities = signal([]); addAll(cities: City[]) { - this.cities.next(cities); + this.cities.set(cities); } - addOne(student: City) { - this.cities.next([...this.cities.value, student]); + addOne(city: City) { + this.cities.set([...this.cities(), city]); } deleteOne(id: number) { - this.cities.next(this.cities.value.filter((s) => s.id !== id)); + this.cities.set(this.cities().filter((s) => s.id !== id)); } } diff --git a/apps/angular/1-projection/src/app/data-access/student.store.ts b/apps/angular/1-projection/src/app/data-access/student.store.ts index 7918118c3..6e7f57022 100644 --- a/apps/angular/1-projection/src/app/data-access/student.store.ts +++ b/apps/angular/1-projection/src/app/data-access/student.store.ts @@ -1,23 +1,21 @@ -import { Injectable } from '@angular/core'; -import { BehaviorSubject } from 'rxjs'; +import { Injectable, signal } from '@angular/core'; import { Student } from '../model/student.model'; @Injectable({ providedIn: 'root', }) export class StudentStore { - private students = new BehaviorSubject([]); - students$ = this.students.asObservable(); + public students = signal([]); addAll(students: Student[]) { - this.students.next(students); + this.students.set(students); } addOne(student: Student) { - this.students.next([...this.students.value, student]); + this.students.set([...this.students(), student]); } deleteOne(id: number) { - this.students.next(this.students.value.filter((s) => s.id !== id)); + this.students.set(this.students().filter((s) => s.id !== id)); } } diff --git a/apps/angular/1-projection/src/app/data-access/teacher.store.ts b/apps/angular/1-projection/src/app/data-access/teacher.store.ts index 93f68c4b1..5f6dae989 100644 --- a/apps/angular/1-projection/src/app/data-access/teacher.store.ts +++ b/apps/angular/1-projection/src/app/data-access/teacher.store.ts @@ -1,23 +1,21 @@ -import { Injectable } from '@angular/core'; -import { BehaviorSubject } from 'rxjs'; +import { Injectable, signal } from '@angular/core'; import { Teacher } from '../model/teacher.model'; @Injectable({ providedIn: 'root', }) export class TeacherStore { - private teachers = new BehaviorSubject([]); - teachers$ = this.teachers.asObservable(); + public teachers = signal([]); addAll(teachers: Teacher[]) { - this.teachers.next(teachers); + this.teachers.set(teachers); } addOne(teacher: Teacher) { - this.teachers.next([...this.teachers.value, teacher]); + this.teachers.set([...this.teachers(), teacher]); } deleteOne(id: number) { - this.teachers.next(this.teachers.value.filter((t) => t.id !== id)); + this.teachers.set(this.teachers().filter((t) => t.id !== id)); } } diff --git a/apps/angular/1-projection/src/app/ui/card/card.component.ts b/apps/angular/1-projection/src/app/ui/card/card.component.ts index f06c9ae00..1a6c3648c 100644 --- a/apps/angular/1-projection/src/app/ui/card/card.component.ts +++ b/apps/angular/1-projection/src/app/ui/card/card.component.ts @@ -1,5 +1,5 @@ -import { NgFor, NgIf } from '@angular/common'; -import { Component, Input } from '@angular/core'; +import { NgOptimizedImage } from '@angular/common'; +import { Component, inject, input } from '@angular/core'; import { randStudent, randTeacher } from '../../data-access/fake-http.service'; import { StudentStore } from '../../data-access/student.store'; import { TeacherStore } from '../../data-access/teacher.store'; @@ -11,22 +11,21 @@ import { ListItemComponent } from '../list-item/list-item.component'; template: `
- - + [class]="customClass()"> + @if (type() === CardType.TEACHER) { + + } + @if (type() === CardType.STUDENT) { + + }
- + @for (item of list(); track item) { + + }
`, - standalone: true, - imports: [NgIf, NgFor, ListItemComponent], + imports: [ListItemComponent, NgOptimizedImage], }) export class CardComponent { - @Input() list: any[] | null = null; - @Input() type!: CardType; - @Input() customClass = ''; + private teacherStore = inject(TeacherStore); + private studentStore = inject(StudentStore); - CardType = CardType; + readonly list = input(null); + readonly type = input.required(); + readonly customClass = input(''); - constructor( - private teacherStore: TeacherStore, - private studentStore: StudentStore, - ) {} + CardType = CardType; addNewItem() { - if (this.type === CardType.TEACHER) { + const type = this.type(); + if (type === CardType.TEACHER) { this.teacherStore.addOne(randTeacher()); - } else if (this.type === CardType.STUDENT) { + } else if (type === CardType.STUDENT) { this.studentStore.addOne(randStudent()); } } diff --git a/apps/angular/1-projection/src/app/ui/list-item/list-item.component.ts b/apps/angular/1-projection/src/app/ui/list-item/list-item.component.ts index c0f9cff7f..cffabb451 100644 --- a/apps/angular/1-projection/src/app/ui/list-item/list-item.component.ts +++ b/apps/angular/1-projection/src/app/ui/list-item/list-item.component.ts @@ -1,4 +1,9 @@ -import { Component, Input } from '@angular/core'; +import { + ChangeDetectionStrategy, + Component, + inject, + input, +} from '@angular/core'; import { StudentStore } from '../../data-access/student.store'; import { TeacherStore } from '../../data-access/teacher.store'; import { CardType } from '../../model/card.model'; @@ -7,28 +12,28 @@ import { CardType } from '../../model/card.model'; selector: 'app-list-item', template: `
- {{ name }} -
`, standalone: true, + changeDetection: ChangeDetectionStrategy.OnPush, }) export class ListItemComponent { - @Input() id!: number; - @Input() name!: string; - @Input() type!: CardType; + private teacherStore = inject(TeacherStore); + private studentStore = inject(StudentStore); - constructor( - private teacherStore: TeacherStore, - private studentStore: StudentStore, - ) {} + readonly id = input.required(); + readonly name = input.required(); + readonly type = input.required(); delete(id: number) { - if (this.type === CardType.TEACHER) { + const type = this.type(); + if (type === CardType.TEACHER) { this.teacherStore.deleteOne(id); - } else if (this.type === CardType.STUDENT) { + } else if (type === CardType.STUDENT) { this.studentStore.deleteOne(id); } } diff --git a/apps/angular/1-projection/src/main.ts b/apps/angular/1-projection/src/main.ts index 9cd15da95..31c5da482 100644 --- a/apps/angular/1-projection/src/main.ts +++ b/apps/angular/1-projection/src/main.ts @@ -1,4 +1,4 @@ import { bootstrapApplication } from '@angular/platform-browser'; import { AppComponent } from './app/app.component'; -bootstrapApplication(AppComponent); +bootstrapApplication(AppComponent).catch((err) => console.error(err)); diff --git a/apps/angular/10-utility-wrapper-pipe/project.json b/apps/angular/10-utility-wrapper-pipe/project.json index 4946170ee..233fc183d 100644 --- a/apps/angular/10-utility-wrapper-pipe/project.json +++ b/apps/angular/10-utility-wrapper-pipe/project.json @@ -4,6 +4,7 @@ "projectType": "application", "sourceRoot": "apps/angular/10-utility-wrapper-pipe/src", "prefix": "app", + "tags": [], "targets": { "build": { "executor": "@angular-devkit/build-angular:browser", @@ -66,10 +67,6 @@ "options": { "buildTarget": "angular-utility-wrapper-pipe:build" } - }, - "lint": { - "executor": "@nx/eslint:lint" } - }, - "tags": [] + } } diff --git a/apps/angular/10-utility-wrapper-pipe/src/app/app.component.ts b/apps/angular/10-utility-wrapper-pipe/src/app/app.component.ts index d91fc7436..764d4b9d0 100644 --- a/apps/angular/10-utility-wrapper-pipe/src/app/app.component.ts +++ b/apps/angular/10-utility-wrapper-pipe/src/app/app.component.ts @@ -3,7 +3,6 @@ import { Component } from '@angular/core'; import { PersonUtils } from './person.utils'; @Component({ - standalone: true, imports: [NgFor], selector: 'app-root', template: ` diff --git a/apps/angular/13-highly-customizable-css/project.json b/apps/angular/13-highly-customizable-css/project.json index aa4ecb32e..8bdda5dba 100644 --- a/apps/angular/13-highly-customizable-css/project.json +++ b/apps/angular/13-highly-customizable-css/project.json @@ -4,6 +4,7 @@ "projectType": "application", "sourceRoot": "apps/angular/13-highly-customizable-css/src", "prefix": "app", + "tags": [], "targets": { "build": { "executor": "@angular-devkit/build-angular:browser", @@ -66,10 +67,6 @@ "options": { "buildTarget": "angular-highly-customizable-css:build" } - }, - "lint": { - "executor": "@nx/eslint:lint" } - }, - "tags": [] + } } diff --git a/apps/angular/13-highly-customizable-css/src/app/page.component.ts b/apps/angular/13-highly-customizable-css/src/app/page.component.ts index 067453294..029ca52d2 100644 --- a/apps/angular/13-highly-customizable-css/src/app/page.component.ts +++ b/apps/angular/13-highly-customizable-css/src/app/page.component.ts @@ -5,7 +5,6 @@ import { TextComponent } from './text.component'; @Component({ selector: 'page', - standalone: true, imports: [TextStaticComponent, TextComponent], template: ` diff --git a/apps/angular/13-highly-customizable-css/src/app/static-text.component.ts b/apps/angular/13-highly-customizable-css/src/app/static-text.component.ts index cdfd1c19f..70d57d9a3 100644 --- a/apps/angular/13-highly-customizable-css/src/app/static-text.component.ts +++ b/apps/angular/13-highly-customizable-css/src/app/static-text.component.ts @@ -6,7 +6,6 @@ export type StaticTextType = 'normal' | 'warning' | 'error'; @Component({ selector: 'static-text', - standalone: true, imports: [TextComponent], template: ` This is a static text diff --git a/apps/angular/16-master-dependency-injection/project.json b/apps/angular/16-master-dependency-injection/project.json index 40505693d..280ed3df4 100644 --- a/apps/angular/16-master-dependency-injection/project.json +++ b/apps/angular/16-master-dependency-injection/project.json @@ -4,6 +4,7 @@ "projectType": "application", "sourceRoot": "apps/angular/16-master-dependency-injection/src", "prefix": "app", + "tags": [], "targets": { "build": { "executor": "@angular-devkit/build-angular:browser", @@ -68,10 +69,6 @@ "options": { "buildTarget": "angular-master-dependency-injection:build" } - }, - "lint": { - "executor": "@nx/eslint:lint" } - }, - "tags": [] + } } diff --git a/apps/angular/16-master-dependency-injection/src/app/app.component.ts b/apps/angular/16-master-dependency-injection/src/app/app.component.ts index f80851729..5bb91c2b2 100644 --- a/apps/angular/16-master-dependency-injection/src/app/app.component.ts +++ b/apps/angular/16-master-dependency-injection/src/app/app.component.ts @@ -23,7 +23,6 @@ export class ProductDirective { } @Component({ - standalone: true, imports: [TableComponent, CurrencyPipe, AsyncPipe, NgFor, ProductDirective], providers: [CurrencyService], selector: 'app-root', diff --git a/apps/angular/21-anchor-navigation/project.json b/apps/angular/21-anchor-navigation/project.json index 45b1866e1..b8ba74b04 100644 --- a/apps/angular/21-anchor-navigation/project.json +++ b/apps/angular/21-anchor-navigation/project.json @@ -4,6 +4,7 @@ "projectType": "application", "sourceRoot": "apps/angular/21-anchor-navigation/src", "prefix": "app", + "tags": [], "targets": { "build": { "executor": "@angular-devkit/build-angular:browser", @@ -67,16 +68,16 @@ "buildTarget": "angular-anchor-navigation:build" } }, - "lint": { - "executor": "@nx/eslint:lint" - }, "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], "options": { - "jestConfig": "apps/angular/21-anchor-navigation/jest.config.ts" + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } } } - }, - "tags": [] + } } diff --git a/apps/angular/21-anchor-navigation/src/app/app.component.ts b/apps/angular/21-anchor-navigation/src/app/app.component.ts index 3fb7c5df0..5caca0271 100644 --- a/apps/angular/21-anchor-navigation/src/app/app.component.ts +++ b/apps/angular/21-anchor-navigation/src/app/app.component.ts @@ -2,7 +2,6 @@ import { Component } from '@angular/core'; import { RouterOutlet } from '@angular/router'; @Component({ - standalone: true, imports: [RouterOutlet], selector: 'app-root', template: ` diff --git a/apps/angular/21-anchor-navigation/src/app/foo.component.ts b/apps/angular/21-anchor-navigation/src/app/foo.component.ts index 87f9b59d9..6744c3662 100644 --- a/apps/angular/21-anchor-navigation/src/app/foo.component.ts +++ b/apps/angular/21-anchor-navigation/src/app/foo.component.ts @@ -2,7 +2,6 @@ import { Component } from '@angular/core'; import { NavButtonComponent } from './nav-button.component'; @Component({ - standalone: true, imports: [NavButtonComponent], selector: 'app-foo', template: ` diff --git a/apps/angular/21-anchor-navigation/src/app/home.component.ts b/apps/angular/21-anchor-navigation/src/app/home.component.ts index 0f24ff6e7..6ef9bc2b6 100644 --- a/apps/angular/21-anchor-navigation/src/app/home.component.ts +++ b/apps/angular/21-anchor-navigation/src/app/home.component.ts @@ -2,7 +2,6 @@ import { Component } from '@angular/core'; import { NavButtonComponent } from './nav-button.component'; @Component({ - standalone: true, imports: [NavButtonComponent], selector: 'app-home', template: ` diff --git a/apps/angular/22-router-input/project.json b/apps/angular/22-router-input/project.json index 1f14dbed2..58cd889c5 100644 --- a/apps/angular/22-router-input/project.json +++ b/apps/angular/22-router-input/project.json @@ -66,9 +66,6 @@ "options": { "buildTarget": "angular-router-input:build" } - }, - "lint": { - "executor": "@nx/eslint:lint" } } } diff --git a/apps/angular/22-router-input/src/app/app.component.ts b/apps/angular/22-router-input/src/app/app.component.ts index 1ef7e32aa..9dfc11200 100644 --- a/apps/angular/22-router-input/src/app/app.component.ts +++ b/apps/angular/22-router-input/src/app/app.component.ts @@ -3,7 +3,6 @@ import { FormControl, ReactiveFormsModule } from '@angular/forms'; import { RouterLink, RouterModule } from '@angular/router'; @Component({ - standalone: true, imports: [RouterLink, RouterModule, ReactiveFormsModule], selector: 'app-root', template: ` diff --git a/apps/angular/22-router-input/src/app/home.component.ts b/apps/angular/22-router-input/src/app/home.component.ts index 2ef8c5eb4..0ddc1501d 100644 --- a/apps/angular/22-router-input/src/app/home.component.ts +++ b/apps/angular/22-router-input/src/app/home.component.ts @@ -1,7 +1,6 @@ import { Component } from '@angular/core'; @Component({ selector: 'app-home', - standalone: true, imports: [], template: `
Home
diff --git a/apps/angular/22-router-input/src/app/test.component.ts b/apps/angular/22-router-input/src/app/test.component.ts index 88c1465f3..747ab4483 100644 --- a/apps/angular/22-router-input/src/app/test.component.ts +++ b/apps/angular/22-router-input/src/app/test.component.ts @@ -5,7 +5,6 @@ import { map } from 'rxjs'; @Component({ selector: 'app-subscription', - standalone: true, imports: [AsyncPipe], template: `
TestId: {{ testId$ | async }}
diff --git a/apps/angular/3-directive-enhancement/project.json b/apps/angular/3-directive-enhancement/project.json index 4401f45e7..f16c4d7a1 100644 --- a/apps/angular/3-directive-enhancement/project.json +++ b/apps/angular/3-directive-enhancement/project.json @@ -4,6 +4,7 @@ "projectType": "application", "sourceRoot": "apps/angular/3-directive-enhancement/src", "prefix": "app", + "tags": [], "targets": { "build": { "executor": "@angular-devkit/build-angular:browser", @@ -66,10 +67,6 @@ "options": { "buildTarget": "angular-directive-enhancement:build" } - }, - "lint": { - "executor": "@nx/eslint:lint" } - }, - "tags": [] + } } diff --git a/apps/angular/3-directive-enhancement/src/app/app.component.ts b/apps/angular/3-directive-enhancement/src/app/app.component.ts index cd1d5f23c..8d37369a1 100644 --- a/apps/angular/3-directive-enhancement/src/app/app.component.ts +++ b/apps/angular/3-directive-enhancement/src/app/app.component.ts @@ -6,7 +6,6 @@ interface Person { } @Component({ - standalone: true, imports: [NgFor, NgIf], selector: 'app-root', template: ` diff --git a/apps/angular/31-module-to-standalone/project.json b/apps/angular/31-module-to-standalone/project.json index d0a41e574..c1a51b5ed 100644 --- a/apps/angular/31-module-to-standalone/project.json +++ b/apps/angular/31-module-to-standalone/project.json @@ -66,9 +66,6 @@ "options": { "buildTarget": "angular-module-to-standalone:build" } - }, - "lint": { - "executor": "@nx/eslint:lint" } } } diff --git a/apps/angular/31-module-to-standalone/src/app/app.component.ts b/apps/angular/31-module-to-standalone/src/app/app.component.ts index 95eeab5b9..986df84b5 100644 --- a/apps/angular/31-module-to-standalone/src/app/app.component.ts +++ b/apps/angular/31-module-to-standalone/src/app/app.component.ts @@ -25,5 +25,6 @@ import { Component } from '@angular/core'; host: { class: 'flex flex-col p-4 gap-3', }, + standalone: false, }) export class AppComponent {} diff --git a/apps/angular/32-change-detection-bug/project.json b/apps/angular/32-change-detection-bug/project.json index ad8f0894f..48eb9ef1e 100644 --- a/apps/angular/32-change-detection-bug/project.json +++ b/apps/angular/32-change-detection-bug/project.json @@ -67,14 +67,15 @@ "buildTarget": "angular-change-detection-bug:build" } }, - "lint": { - "executor": "@nx/eslint:lint" - }, "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], "options": { - "jestConfig": "apps/angular/32-change-detection-bug/jest.config.ts" + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } } } } diff --git a/apps/angular/32-change-detection-bug/src/app/app.component.ts b/apps/angular/32-change-detection-bug/src/app/app.component.ts index 046492f9b..217999c3a 100644 --- a/apps/angular/32-change-detection-bug/src/app/app.component.ts +++ b/apps/angular/32-change-detection-bug/src/app/app.component.ts @@ -2,7 +2,6 @@ import { Component } from '@angular/core'; import { RouterOutlet } from '@angular/router'; @Component({ - standalone: true, imports: [RouterOutlet], selector: 'app-root', template: ` diff --git a/apps/angular/32-change-detection-bug/src/app/main-navigation.component.ts b/apps/angular/32-change-detection-bug/src/app/main-navigation.component.ts index c8a6f6d22..3d5ce20f8 100644 --- a/apps/angular/32-change-detection-bug/src/app/main-navigation.component.ts +++ b/apps/angular/32-change-detection-bug/src/app/main-navigation.component.ts @@ -10,7 +10,6 @@ interface MenuItem { @Component({ selector: 'app-nav', - standalone: true, imports: [RouterLink, RouterLinkActive, NgFor], template: ` @@ -38,7 +37,6 @@ export class NavigationComponent { } @Component({ - standalone: true, imports: [NavigationComponent, NgIf, AsyncPipe], template: ` diff --git a/apps/angular/33-decoupling-components/project.json b/apps/angular/33-decoupling-components/project.json index 88bad94cb..762fc01b5 100644 --- a/apps/angular/33-decoupling-components/project.json +++ b/apps/angular/33-decoupling-components/project.json @@ -66,9 +66,6 @@ "options": { "buildTarget": "angular-decoupling-components:build" } - }, - "lint": { - "executor": "@nx/eslint:lint" } } } diff --git a/apps/angular/33-decoupling-components/src/app/app.component.ts b/apps/angular/33-decoupling-components/src/app/app.component.ts index 34082c331..0d78f4d34 100644 --- a/apps/angular/33-decoupling-components/src/app/app.component.ts +++ b/apps/angular/33-decoupling-components/src/app/app.component.ts @@ -3,7 +3,6 @@ import { BtnHelmetDirective } from '@angular-challenges/decoupling/helmet'; import { Component } from '@angular/core'; @Component({ - standalone: true, imports: [BtnDisabledDirective, BtnHelmetDirective], selector: 'app-root', template: ` diff --git a/apps/angular/39-injection-token/project.json b/apps/angular/39-injection-token/project.json index 03f203b83..8dba72d55 100644 --- a/apps/angular/39-injection-token/project.json +++ b/apps/angular/39-injection-token/project.json @@ -67,14 +67,15 @@ "buildTarget": "angular-injection-token:build" } }, - "lint": { - "executor": "@nx/eslint:lint" - }, "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], "options": { - "jestConfig": "apps/angular/39-injection-token/jest.config.ts" + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } } } } diff --git a/apps/angular/39-injection-token/src/app/app.component.ts b/apps/angular/39-injection-token/src/app/app.component.ts index 5ac8087cb..280dc090a 100644 --- a/apps/angular/39-injection-token/src/app/app.component.ts +++ b/apps/angular/39-injection-token/src/app/app.component.ts @@ -2,7 +2,6 @@ import { Component } from '@angular/core'; import { RouterLink, RouterOutlet } from '@angular/router'; @Component({ - standalone: true, imports: [RouterOutlet, RouterLink], selector: 'app-root', template: ` diff --git a/apps/angular/39-injection-token/src/app/phone.component.ts b/apps/angular/39-injection-token/src/app/phone.component.ts index a58b3cd99..41ee3cfc0 100644 --- a/apps/angular/39-injection-token/src/app/phone.component.ts +++ b/apps/angular/39-injection-token/src/app/phone.component.ts @@ -3,7 +3,6 @@ import { TimerContainerComponent } from './timer-container.component'; @Component({ selector: 'app-phone', - standalone: true, imports: [TimerContainerComponent], template: `
diff --git a/apps/angular/39-injection-token/src/app/timer-container.component.ts b/apps/angular/39-injection-token/src/app/timer-container.component.ts index 30af69354..67db6059a 100644 --- a/apps/angular/39-injection-token/src/app/timer-container.component.ts +++ b/apps/angular/39-injection-token/src/app/timer-container.component.ts @@ -3,7 +3,6 @@ import { DEFAULT_TIMER } from './data'; import { TimerComponent } from './timer.component'; @Component({ selector: 'timer-container', - standalone: true, imports: [TimerComponent], template: `
diff --git a/apps/angular/39-injection-token/src/app/video.component.ts b/apps/angular/39-injection-token/src/app/video.component.ts index 2c218071a..ba0a218b4 100644 --- a/apps/angular/39-injection-token/src/app/video.component.ts +++ b/apps/angular/39-injection-token/src/app/video.component.ts @@ -3,7 +3,6 @@ import { TimerContainerComponent } from './timer-container.component'; @Component({ selector: 'app-video', - standalone: true, imports: [TimerContainerComponent], template: `
diff --git a/apps/angular/4-typed-context-outlet/project.json b/apps/angular/4-typed-context-outlet/project.json index 620a1791d..ccebf62c7 100644 --- a/apps/angular/4-typed-context-outlet/project.json +++ b/apps/angular/4-typed-context-outlet/project.json @@ -4,6 +4,7 @@ "projectType": "application", "sourceRoot": "apps/angular/4-typed-context-outlet/src", "prefix": "app", + "tags": [], "targets": { "build": { "executor": "@angular-devkit/build-angular:browser", @@ -66,10 +67,6 @@ "options": { "buildTarget": "angular-typed-context-outlet:build" } - }, - "lint": { - "executor": "@nx/eslint:lint" } - }, - "tags": [] + } } diff --git a/apps/angular/4-typed-context-outlet/src/app/app.component.ts b/apps/angular/4-typed-context-outlet/src/app/app.component.ts index 2683ba9d4..23be9dac6 100644 --- a/apps/angular/4-typed-context-outlet/src/app/app.component.ts +++ b/apps/angular/4-typed-context-outlet/src/app/app.component.ts @@ -4,7 +4,6 @@ import { ListComponent } from './list.component'; import { PersonComponent } from './person.component'; @Component({ - standalone: true, imports: [NgTemplateOutlet, PersonComponent, ListComponent], selector: 'app-root', template: ` diff --git a/apps/angular/4-typed-context-outlet/src/app/list.component.ts b/apps/angular/4-typed-context-outlet/src/app/list.component.ts index 5212a425e..b9946e428 100644 --- a/apps/angular/4-typed-context-outlet/src/app/list.component.ts +++ b/apps/angular/4-typed-context-outlet/src/app/list.component.ts @@ -9,7 +9,6 @@ import { @Component({ selector: 'list', - standalone: true, imports: [CommonModule], template: `
diff --git a/apps/angular/4-typed-context-outlet/src/app/person.component.ts b/apps/angular/4-typed-context-outlet/src/app/person.component.ts index 1550cf274..59eb00ab1 100644 --- a/apps/angular/4-typed-context-outlet/src/app/person.component.ts +++ b/apps/angular/4-typed-context-outlet/src/app/person.component.ts @@ -7,7 +7,6 @@ interface Person { } @Component({ - standalone: true, imports: [NgTemplateOutlet], selector: 'person', template: ` diff --git a/apps/angular/44-view-transition/project.json b/apps/angular/44-view-transition/project.json index 27fc865d9..9f4046607 100644 --- a/apps/angular/44-view-transition/project.json +++ b/apps/angular/44-view-transition/project.json @@ -64,10 +64,6 @@ "options": { "buildTarget": "angular-view-transition:build" } - }, - "lint": { - "executor": "@nx/eslint:lint", - "outputs": ["{options.outputFile}"] } } } diff --git a/apps/angular/44-view-transition/src/app/app.component.ts b/apps/angular/44-view-transition/src/app/app.component.ts index da56c04c0..1fcb0c548 100644 --- a/apps/angular/44-view-transition/src/app/app.component.ts +++ b/apps/angular/44-view-transition/src/app/app.component.ts @@ -2,7 +2,6 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import { RouterOutlet } from '@angular/router'; @Component({ - standalone: true, imports: [RouterOutlet], selector: 'app-root', template: ` diff --git a/apps/angular/44-view-transition/src/app/blog/blog.component.ts b/apps/angular/44-view-transition/src/app/blog/blog.component.ts index 68ffcde50..29291d21e 100644 --- a/apps/angular/44-view-transition/src/app/blog/blog.component.ts +++ b/apps/angular/44-view-transition/src/app/blog/blog.component.ts @@ -4,7 +4,6 @@ import { ThumbnailComponent } from './thumbnail.component'; @Component({ selector: 'blog', - standalone: true, imports: [ThumbnailComponent], template: `
diff --git a/apps/angular/44-view-transition/src/app/blog/thumbnail.component.ts b/apps/angular/44-view-transition/src/app/blog/thumbnail.component.ts index 6263e97ab..dd2e25e26 100644 --- a/apps/angular/44-view-transition/src/app/blog/thumbnail.component.ts +++ b/apps/angular/44-view-transition/src/app/blog/thumbnail.component.ts @@ -6,7 +6,6 @@ import { ThumbnailHeaderComponent } from './thumbnail-header.component'; @Component({ selector: 'blog-thumbnail', - standalone: true, imports: [NgOptimizedImage, ThumbnailHeaderComponent, RouterLinkWithHref], template: ` diff --git a/apps/angular/44-view-transition/src/app/post/post-header.component.ts b/apps/angular/44-view-transition/src/app/post/post-header.component.ts index 8b62a6c48..6d5f30e54 100644 --- a/apps/angular/44-view-transition/src/app/post/post-header.component.ts +++ b/apps/angular/44-view-transition/src/app/post/post-header.component.ts @@ -3,7 +3,6 @@ import { Component, input } from '@angular/core'; @Component({ selector: 'post-header', - standalone: true, imports: [NgOptimizedImage], template: `
diff --git a/apps/angular/44-view-transition/src/app/post/post.component.ts b/apps/angular/44-view-transition/src/app/post/post.component.ts index 1e1c6fd89..edb87f780 100644 --- a/apps/angular/44-view-transition/src/app/post/post.component.ts +++ b/apps/angular/44-view-transition/src/app/post/post.component.ts @@ -12,7 +12,6 @@ import { PostHeaderComponent } from './post-header.component'; @Component({ selector: 'post', - standalone: true, imports: [ ThumbnailHeaderComponent, NgOptimizedImage, diff --git a/apps/angular/45-react-in-angular/project.json b/apps/angular/45-react-in-angular/project.json index d23e5405b..bce6fe70e 100644 --- a/apps/angular/45-react-in-angular/project.json +++ b/apps/angular/45-react-in-angular/project.json @@ -65,15 +65,15 @@ "buildTarget": "angular-react-in-angular:build" } }, - "lint": { - "executor": "@nx/eslint:lint", - "outputs": ["{options.outputFile}"] - }, "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], "options": { - "jestConfig": "apps/angular/45-react-in-angular/jest.config.ts" + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } } } } diff --git a/apps/angular/45-react-in-angular/src/app/app.component.ts b/apps/angular/45-react-in-angular/src/app/app.component.ts index a914cc65f..87b9675cc 100644 --- a/apps/angular/45-react-in-angular/src/app/app.component.ts +++ b/apps/angular/45-react-in-angular/src/app/app.component.ts @@ -4,7 +4,6 @@ import { PostComponent } from './react/post.component'; type Post = { title: string; description: string }; @Component({ - standalone: true, imports: [PostComponent], selector: 'app-root', template: ` diff --git a/apps/angular/46-simple-animations/project.json b/apps/angular/46-simple-animations/project.json index e10aba44f..1d00fd246 100644 --- a/apps/angular/46-simple-animations/project.json +++ b/apps/angular/46-simple-animations/project.json @@ -65,15 +65,15 @@ "buildTarget": "angular-simple-animations:build" } }, - "lint": { - "executor": "@nx/eslint:lint", - "outputs": ["{options.outputFile}"] - }, "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], "options": { - "jestConfig": "apps/angular/46-simple-animations/jest.config.ts" + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } } } } diff --git a/apps/angular/46-simple-animations/src/app/app.component.ts b/apps/angular/46-simple-animations/src/app/app.component.ts index 9f537b3fb..ae63db419 100644 --- a/apps/angular/46-simple-animations/src/app/app.component.ts +++ b/apps/angular/46-simple-animations/src/app/app.component.ts @@ -1,7 +1,6 @@ import { Component } from '@angular/core'; @Component({ - standalone: true, imports: [], selector: 'app-root', styles: ` diff --git a/apps/angular/5-crud-application/project.json b/apps/angular/5-crud-application/project.json index 701cabe48..cdad9374a 100644 --- a/apps/angular/5-crud-application/project.json +++ b/apps/angular/5-crud-application/project.json @@ -4,6 +4,7 @@ "projectType": "application", "sourceRoot": "apps/angular/5-crud-application/src", "prefix": "app", + "tags": [], "targets": { "build": { "executor": "@angular-devkit/build-angular:browser", @@ -71,16 +72,16 @@ "buildTarget": "angular-crud-application:build" } }, - "lint": { - "executor": "@nx/eslint:lint" - }, "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], "options": { - "jestConfig": "apps/angular/5-crud-application/jest.config.ts" + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } } } - }, - "tags": [] + } } diff --git a/apps/angular/5-crud-application/src/app/app.component.ts b/apps/angular/5-crud-application/src/app/app.component.ts index 8c3d1b8ae..9152ff5e4 100644 --- a/apps/angular/5-crud-application/src/app/app.component.ts +++ b/apps/angular/5-crud-application/src/app/app.component.ts @@ -4,7 +4,6 @@ import { Component, OnInit } from '@angular/core'; import { randText } from '@ngneat/falso'; @Component({ - standalone: true, imports: [CommonModule], selector: 'app-root', template: ` diff --git a/apps/angular/5-crud-application/src/app/app.config.ts b/apps/angular/5-crud-application/src/app/app.config.ts index de0a3ccec..1c0c9422f 100644 --- a/apps/angular/5-crud-application/src/app/app.config.ts +++ b/apps/angular/5-crud-application/src/app/app.config.ts @@ -1,5 +1,6 @@ -import { HttpClientModule } from '@angular/common/http'; -import { ApplicationConfig, importProvidersFrom } from '@angular/core'; +import { provideHttpClient } from '@angular/common/http'; +import { ApplicationConfig } from '@angular/core'; + export const appConfig: ApplicationConfig = { - providers: [importProvidersFrom(HttpClientModule)], + providers: [provideHttpClient()], }; diff --git a/apps/ngrx/2-effect-vs-selector/.eslintrc.json b/apps/angular/52-lazy-load-component/.eslintrc.json similarity index 100% rename from apps/ngrx/2-effect-vs-selector/.eslintrc.json rename to apps/angular/52-lazy-load-component/.eslintrc.json diff --git a/apps/angular/52-lazy-load-component/README.md b/apps/angular/52-lazy-load-component/README.md new file mode 100644 index 000000000..7da25f89b --- /dev/null +++ b/apps/angular/52-lazy-load-component/README.md @@ -0,0 +1,13 @@ +# lazy-load-component + +> author: lance-finney + +### Run Application + +```bash +npx nx serve angular-lazy-load-component +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/52-lazy-load-component/). diff --git a/libs/power-of-effect/model/jest.config.ts b/apps/angular/52-lazy-load-component/jest.config.ts similarity index 83% rename from libs/power-of-effect/model/jest.config.ts rename to apps/angular/52-lazy-load-component/jest.config.ts index aadbfeb70..a0fd1100f 100644 --- a/libs/power-of-effect/model/jest.config.ts +++ b/apps/angular/52-lazy-load-component/jest.config.ts @@ -1,10 +1,9 @@ /* eslint-disable */ export default { - displayName: 'power-of-effect-model', + displayName: 'angular-lazy-load-component', preset: '../../../jest.preset.js', setupFilesAfterEnv: ['/src/test-setup.ts'], - globals: {}, - coverageDirectory: '../../../coverage/libs/power-of-effect/model', + coverageDirectory: '../../../coverage/apps/angular/52-lazy-load-component', transform: { '^.+\\.(ts|mjs|js|html)$': [ 'jest-preset-angular', diff --git a/apps/ngrx/7-power-of-effect/project.json b/apps/angular/52-lazy-load-component/project.json similarity index 50% rename from apps/ngrx/7-power-of-effect/project.json rename to apps/angular/52-lazy-load-component/project.json index ffec53a33..d3b28088a 100644 --- a/apps/ngrx/7-power-of-effect/project.json +++ b/apps/angular/52-lazy-load-component/project.json @@ -1,30 +1,27 @@ { - "name": "ngrx-power-of-effect", + "name": "angular-lazy-load-component", "$schema": "../../../node_modules/nx/schemas/project-schema.json", "projectType": "application", - "sourceRoot": "apps/ngrx/7-power-of-effect/src", "prefix": "app", + "sourceRoot": "apps/angular/52-lazy-load-component/src", + "tags": [], "targets": { "build": { - "executor": "@angular-devkit/build-angular:browser", + "executor": "@angular-devkit/build-angular:application", "outputs": ["{options.outputPath}"], "options": { - "outputPath": "dist/apps/ngrx/7-power-of-effect", - "index": "apps/ngrx/7-power-of-effect/src/index.html", - "main": "apps/ngrx/7-power-of-effect/src/main.ts", - "polyfills": "apps/ngrx/7-power-of-effect/src/polyfills.ts", - "tsConfig": "apps/ngrx/7-power-of-effect/tsconfig.app.json", + "outputPath": "dist/apps/angular/52-lazy-load-component", + "index": "apps/angular/52-lazy-load-component/src/index.html", + "browser": "apps/angular/52-lazy-load-component/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/angular/52-lazy-load-component/tsconfig.app.json", "inlineStyleLanguage": "scss", "assets": [ - "apps/ngrx/7-power-of-effect/src/favicon.ico", - "apps/ngrx/7-power-of-effect/src/assets" + "apps/angular/52-lazy-load-component/src/favicon.ico", + "apps/angular/52-lazy-load-component/src/assets" ], - "styles": [ - "apps/ngrx/7-power-of-effect/src/styles.scss", - "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css" - ], - "scripts": [], - "allowedCommonJsDependencies": ["seedrandom"] + "styles": ["apps/angular/52-lazy-load-component/src/styles.scss"], + "scripts": [] }, "configurations": { "production": { @@ -43,12 +40,9 @@ "outputHashing": "all" }, "development": { - "buildOptimizer": false, "optimization": false, - "vendorChunk": true, "extractLicenses": false, - "sourceMap": true, - "namedChunks": true + "sourceMap": true } }, "defaultConfiguration": "production" @@ -57,10 +51,10 @@ "executor": "@angular-devkit/build-angular:dev-server", "configurations": { "production": { - "buildTarget": "ngrx-power-of-effect:build:production" + "buildTarget": "angular-lazy-load-component:build:production" }, "development": { - "buildTarget": "ngrx-power-of-effect:build:development" + "buildTarget": "angular-lazy-load-component:build:development" } }, "defaultConfiguration": "development" @@ -68,12 +62,19 @@ "extract-i18n": { "executor": "@angular-devkit/build-angular:extract-i18n", "options": { - "buildTarget": "ngrx-power-of-effect:build" + "buildTarget": "angular-lazy-load-component:build" } }, - "lint": { - "executor": "@nx/eslint:lint" + "test": { + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } + } } - }, - "tags": [] + } } diff --git a/apps/angular/52-lazy-load-component/src/app/app.component.ts b/apps/angular/52-lazy-load-component/src/app/app.component.ts new file mode 100644 index 000000000..6d8c03d29 --- /dev/null +++ b/apps/angular/52-lazy-load-component/src/app/app.component.ts @@ -0,0 +1,23 @@ +import { Component, signal } from '@angular/core'; + +@Component({ + selector: 'app-root', + template: ` +
+ @if (topLoaded()) { + + } @else { + + + } +
+ `, + standalone: false, +}) +export class AppComponent { + topLoaded = signal(false); +} diff --git a/apps/angular/52-lazy-load-component/src/app/app.module.ts b/apps/angular/52-lazy-load-component/src/app/app.module.ts new file mode 100644 index 000000000..b5d430e67 --- /dev/null +++ b/apps/angular/52-lazy-load-component/src/app/app.module.ts @@ -0,0 +1,12 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { AppComponent } from './app.component'; +import { PlaceholderComponent } from './placeholder.component'; +import { TopComponent } from './top.component'; + +@NgModule({ + declarations: [AppComponent, PlaceholderComponent, TopComponent], + imports: [BrowserModule], + bootstrap: [AppComponent], +}) +export class AppModule {} diff --git a/apps/angular/52-lazy-load-component/src/app/placeholder.component.ts b/apps/angular/52-lazy-load-component/src/app/placeholder.component.ts new file mode 100644 index 000000000..cbb2b5fa6 --- /dev/null +++ b/apps/angular/52-lazy-load-component/src/app/placeholder.component.ts @@ -0,0 +1,18 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-placeholder', + template: ` + I'm a placeholder component. + `, + styles: ` + :host { + display: grid; + padding: 20px; + background-color: #f0f0f0; + height: 50%; + } + `, + standalone: false, +}) +export class PlaceholderComponent {} diff --git a/apps/angular/52-lazy-load-component/src/app/top.component.ts b/apps/angular/52-lazy-load-component/src/app/top.component.ts new file mode 100644 index 000000000..e1ca9012c --- /dev/null +++ b/apps/angular/52-lazy-load-component/src/app/top.component.ts @@ -0,0 +1,18 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-top', + template: ` + I am a very heavy, expensive component that should be lazy loaded. + `, + styles: ` + :host { + display: grid; + padding: 20px; + background-color: #f0f0f0; + height: 50%; + } + `, + standalone: false, +}) +export class TopComponent {} diff --git a/apps/ngrx/2-effect-vs-selector/src/assets/.gitkeep b/apps/angular/52-lazy-load-component/src/assets/.gitkeep similarity index 100% rename from apps/ngrx/2-effect-vs-selector/src/assets/.gitkeep rename to apps/angular/52-lazy-load-component/src/assets/.gitkeep diff --git a/apps/ngrx/2-effect-vs-selector/src/favicon.ico b/apps/angular/52-lazy-load-component/src/favicon.ico similarity index 100% rename from apps/ngrx/2-effect-vs-selector/src/favicon.ico rename to apps/angular/52-lazy-load-component/src/favicon.ico diff --git a/apps/ngrx/7-power-of-effect/src/index.html b/apps/angular/52-lazy-load-component/src/index.html similarity index 86% rename from apps/ngrx/7-power-of-effect/src/index.html rename to apps/angular/52-lazy-load-component/src/index.html index 91cf31032..242ec3e3f 100644 --- a/apps/ngrx/7-power-of-effect/src/index.html +++ b/apps/angular/52-lazy-load-component/src/index.html @@ -2,7 +2,7 @@ - ngrx-power-of-effect + angular-lazy-load-component diff --git a/apps/angular/52-lazy-load-component/src/main.ts b/apps/angular/52-lazy-load-component/src/main.ts new file mode 100644 index 000000000..16de2365d --- /dev/null +++ b/apps/angular/52-lazy-load-component/src/main.ts @@ -0,0 +1,6 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic() + .bootstrapModule(AppModule) + .catch((err) => console.error(err)); diff --git a/apps/ngrx/7-power-of-effect/src/styles.scss b/apps/angular/52-lazy-load-component/src/styles.scss similarity index 57% rename from apps/ngrx/7-power-of-effect/src/styles.scss rename to apps/angular/52-lazy-load-component/src/styles.scss index 90d4ee007..77e408aa8 100644 --- a/apps/ngrx/7-power-of-effect/src/styles.scss +++ b/apps/angular/52-lazy-load-component/src/styles.scss @@ -1 +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/ngrx/2-effect-vs-selector/src/test-setup.ts b/apps/angular/52-lazy-load-component/src/test-setup.ts similarity index 53% rename from apps/ngrx/2-effect-vs-selector/src/test-setup.ts rename to apps/angular/52-lazy-load-component/src/test-setup.ts index 1100b3e8a..15de72a3c 100644 --- a/apps/ngrx/2-effect-vs-selector/src/test-setup.ts +++ b/apps/angular/52-lazy-load-component/src/test-setup.ts @@ -1 +1,2 @@ +import '@testing-library/jest-dom'; import 'jest-preset-angular/setup-jest'; diff --git a/apps/angular/52-lazy-load-component/tailwind.config.js b/apps/angular/52-lazy-load-component/tailwind.config.js new file mode 100644 index 000000000..38183db2c --- /dev/null +++ b/apps/angular/52-lazy-load-component/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/52-lazy-load-component/tsconfig.app.json b/apps/angular/52-lazy-load-component/tsconfig.app.json new file mode 100644 index 000000000..58220429a --- /dev/null +++ b/apps/angular/52-lazy-load-component/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/52-lazy-load-component/tsconfig.editor.json b/apps/angular/52-lazy-load-component/tsconfig.editor.json new file mode 100644 index 000000000..a8ac182c0 --- /dev/null +++ b/apps/angular/52-lazy-load-component/tsconfig.editor.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": {}, + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/libs/shared/ngrx-callstate-store/tsconfig.json b/apps/angular/52-lazy-load-component/tsconfig.json similarity index 86% rename from libs/shared/ngrx-callstate-store/tsconfig.json rename to apps/angular/52-lazy-load-component/tsconfig.json index 888e0b0f1..4383e7eb8 100644 --- a/libs/shared/ngrx-callstate-store/tsconfig.json +++ b/apps/angular/52-lazy-load-component/tsconfig.json @@ -1,28 +1,29 @@ { - "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, "files": [], "include": [], "references": [ { - "path": "./tsconfig.lib.json" + "path": "./tsconfig.editor.json" }, { - "path": "./tsconfig.lib.prod.json" + "path": "./tsconfig.app.json" }, { "path": "./tsconfig.spec.json" } ], - "compilerOptions": { - "target": "es2022", - "useDefineForClassFields": false, - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true - }, + "extends": "../../../tsconfig.base.json", "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, diff --git a/apps/angular/52-lazy-load-component/tsconfig.spec.json b/apps/angular/52-lazy-load-component/tsconfig.spec.json new file mode 100644 index 000000000..1a4817a7d --- /dev/null +++ b/apps/angular/52-lazy-load-component/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/7-power-of-effect/.eslintrc.json b/apps/angular/55-back-button-navigation/.eslintrc.json similarity index 100% rename from apps/ngrx/7-power-of-effect/.eslintrc.json rename to apps/angular/55-back-button-navigation/.eslintrc.json diff --git a/apps/angular/55-back-button-navigation/README.md b/apps/angular/55-back-button-navigation/README.md new file mode 100644 index 000000000..2534d270c --- /dev/null +++ b/apps/angular/55-back-button-navigation/README.md @@ -0,0 +1,13 @@ +# Back-Button-Navigation + +> author: ioannis-tsironis + +### Run Application + +```bash +npx nx serve angular-back-button-navigation +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/55-back-button-navigation/). diff --git a/libs/power-of-effect/backend/jest.config.ts b/apps/angular/55-back-button-navigation/jest.config.ts similarity index 82% rename from libs/power-of-effect/backend/jest.config.ts rename to apps/angular/55-back-button-navigation/jest.config.ts index 4efb3bb24..845a03a01 100644 --- a/libs/power-of-effect/backend/jest.config.ts +++ b/apps/angular/55-back-button-navigation/jest.config.ts @@ -1,10 +1,9 @@ /* eslint-disable */ export default { - displayName: 'power-of-effect-backend', + displayName: 'angular-back-button-navigation', preset: '../../../jest.preset.js', setupFilesAfterEnv: ['/src/test-setup.ts'], - globals: {}, - coverageDirectory: '../../../coverage/libs/power-of-effect/backend', + coverageDirectory: '../../../coverage/apps/angular/55-back-button-navigation', transform: { '^.+\\.(ts|mjs|js|html)$': [ 'jest-preset-angular', diff --git a/apps/angular/55-back-button-navigation/project.json b/apps/angular/55-back-button-navigation/project.json new file mode 100644 index 000000000..f53d65e27 --- /dev/null +++ b/apps/angular/55-back-button-navigation/project.json @@ -0,0 +1,85 @@ +{ + "name": "angular-back-button-navigation", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/angular/55-back-button-navigation/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/55-back-button-navigation", + "index": "apps/angular/55-back-button-navigation/src/index.html", + "browser": "apps/angular/55-back-button-navigation/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/angular/55-back-button-navigation/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + { + "glob": "**/*", + "input": "apps/angular/55-back-button-navigation/public" + } + ], + "styles": [ + "apps/angular/55-back-button-navigation/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" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-back-button-navigation:build:production" + }, + "development": { + "buildTarget": "angular-back-button-navigation:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-back-button-navigation:build" + } + }, + "test": { + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } + } + } + } +} diff --git a/apps/angular/55-back-button-navigation/src/app/app.component.html b/apps/angular/55-back-button-navigation/src/app/app.component.html new file mode 100644 index 000000000..0680b43f9 --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/app/app.component.html @@ -0,0 +1 @@ + diff --git a/apps/angular/55-back-button-navigation/src/app/app.component.ts b/apps/angular/55-back-button-navigation/src/app/app.component.ts new file mode 100644 index 000000000..baffdae25 --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/app/app.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; +import { RouterLink, RouterOutlet } from '@angular/router'; + +@Component({ + imports: [RouterOutlet, RouterLink], + selector: 'app-root', + templateUrl: './app.component.html', +}) +export class AppComponent {} diff --git a/apps/angular/55-back-button-navigation/src/app/app.config.ts b/apps/angular/55-back-button-navigation/src/app/app.config.ts new file mode 100644 index 000000000..440cdf2c3 --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/app/app.config.ts @@ -0,0 +1,10 @@ +import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; +import { provideRouter } from '@angular/router'; +import { APP_ROUTES } from './app.routes'; + +export const appConfig: ApplicationConfig = { + providers: [ + provideZoneChangeDetection({ eventCoalescing: true }), + provideRouter(APP_ROUTES), + ], +}; diff --git a/apps/angular/55-back-button-navigation/src/app/app.routes.ts b/apps/angular/55-back-button-navigation/src/app/app.routes.ts new file mode 100644 index 000000000..7deecd57a --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/app/app.routes.ts @@ -0,0 +1,24 @@ +import { Routes } from '@angular/router'; +import { HomeComponent } from './home/home.component'; +import { SensitiveActionComponent } from './sensitive-action/sensitive-action.component'; +import { SimpleActionComponent } from './simple-action/simple-action.component'; + +export const APP_ROUTES: Routes = [ + { + path: '', + pathMatch: 'full', + redirectTo: 'home', + }, + { + path: 'home', + component: HomeComponent, + }, + { + path: 'simple-action', + component: SimpleActionComponent, + }, + { + path: 'sensitive-action', + component: SensitiveActionComponent, + }, +]; diff --git a/apps/angular/55-back-button-navigation/src/app/dialog/dialog.component.html b/apps/angular/55-back-button-navigation/src/app/dialog/dialog.component.html new file mode 100644 index 000000000..ff00ea965 --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/app/dialog/dialog.component.html @@ -0,0 +1,6 @@ +

Delete file

+Would you like to delete cat.jpeg? + + + + diff --git a/apps/angular/55-back-button-navigation/src/app/dialog/dialog.component.ts b/apps/angular/55-back-button-navigation/src/app/dialog/dialog.component.ts new file mode 100644 index 000000000..9a9dd0fef --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/app/dialog/dialog.component.ts @@ -0,0 +1,25 @@ +import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { + MatDialogActions, + MatDialogClose, + MatDialogContent, + MatDialogRef, + MatDialogTitle, +} from '@angular/material/dialog'; + +@Component({ + selector: 'app-dialog-dialog', + templateUrl: './dialog.component.html', + imports: [ + MatButtonModule, + MatDialogActions, + MatDialogClose, + MatDialogTitle, + MatDialogContent, + ], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class DialogComponent { + readonly dialogRef = inject(MatDialogRef); +} diff --git a/apps/angular/55-back-button-navigation/src/app/home/home.component.html b/apps/angular/55-back-button-navigation/src/app/home/home.component.html new file mode 100644 index 000000000..cce9e6d4f --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/app/home/home.component.html @@ -0,0 +1,7 @@ +
+ Go to simple dialog action page + + + + Go to sensitive dialog action page + diff --git a/apps/angular/55-back-button-navigation/src/app/home/home.component.ts b/apps/angular/55-back-button-navigation/src/app/home/home.component.ts new file mode 100644 index 000000000..18c4147b1 --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/app/home/home.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { RouterLink } from '@angular/router'; + +@Component({ + imports: [MatButtonModule, RouterLink], + selector: 'app-home', + templateUrl: './home.component.html', +}) +export class HomeComponent {} diff --git a/apps/angular/55-back-button-navigation/src/app/sensitive-action/sensitive-action.component.html b/apps/angular/55-back-button-navigation/src/app/sensitive-action/sensitive-action.component.html new file mode 100644 index 000000000..bcb7382e9 --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/app/sensitive-action/sensitive-action.component.html @@ -0,0 +1,3 @@ + diff --git a/apps/angular/55-back-button-navigation/src/app/sensitive-action/sensitive-action.component.ts b/apps/angular/55-back-button-navigation/src/app/sensitive-action/sensitive-action.component.ts new file mode 100644 index 000000000..a97282c33 --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/app/sensitive-action/sensitive-action.component.ts @@ -0,0 +1,19 @@ +import { Component, inject } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDialog } from '@angular/material/dialog'; +import { DialogComponent } from '../dialog/dialog.component'; + +@Component({ + imports: [MatButtonModule], + selector: 'app-sensitive-action', + templateUrl: './sensitive-action.component.html', +}) +export class SensitiveActionComponent { + readonly #dialog = inject(MatDialog); + + openDialog(): void { + this.#dialog.open(DialogComponent, { + width: '250px', + }); + } +} diff --git a/apps/angular/55-back-button-navigation/src/app/simple-action/simple-action.component.html b/apps/angular/55-back-button-navigation/src/app/simple-action/simple-action.component.html new file mode 100644 index 000000000..95f63e65e --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/app/simple-action/simple-action.component.html @@ -0,0 +1 @@ + diff --git a/apps/angular/55-back-button-navigation/src/app/simple-action/simple-action.component.ts b/apps/angular/55-back-button-navigation/src/app/simple-action/simple-action.component.ts new file mode 100644 index 000000000..fe97e7368 --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/app/simple-action/simple-action.component.ts @@ -0,0 +1,19 @@ +import { Component, inject } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDialog } from '@angular/material/dialog'; +import { DialogComponent } from '../dialog/dialog.component'; + +@Component({ + imports: [MatButtonModule], + selector: 'app-simple-action', + templateUrl: './simple-action.component.html', +}) +export class SimpleActionComponent { + readonly #dialog = inject(MatDialog); + + openDialog(): void { + this.#dialog.open(DialogComponent, { + width: '250px', + }); + } +} diff --git a/apps/angular/55-back-button-navigation/src/index.html b/apps/angular/55-back-button-navigation/src/index.html new file mode 100644 index 000000000..4e657d614 --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/index.html @@ -0,0 +1,13 @@ + + + + + angular-back-button-navigation + + + + + + + + diff --git a/apps/ngrx/7-power-of-effect/src/main.ts b/apps/angular/55-back-button-navigation/src/main.ts similarity index 99% rename from apps/ngrx/7-power-of-effect/src/main.ts rename to apps/angular/55-back-button-navigation/src/main.ts index 6f91f21a3..f3a7223da 100644 --- a/apps/ngrx/7-power-of-effect/src/main.ts +++ b/apps/angular/55-back-button-navigation/src/main.ts @@ -1,8 +1,6 @@ -import { appConfig } from './app/app.config'; - 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/55-back-button-navigation/src/styles.scss b/apps/angular/55-back-button-navigation/src/styles.scss new file mode 100644 index 000000000..acd290007 --- /dev/null +++ b/apps/angular/55-back-button-navigation/src/styles.scss @@ -0,0 +1,29 @@ +@use '@angular/material' as mat; + +/* You can add global styles to this file, and also import other style files */ + +@tailwind base; +@tailwind components; +@tailwind utilities; + +@include mat.elevation-classes(); +@include mat.app-background(); + +$theme-primary: mat.m2-define-palette(mat.$m2-indigo-palette); +$theme-accent: mat.m2-define-palette(mat.$m2-pink-palette, A200, A100, A400); + +$theme-warn: mat.m2-define-palette(mat.$m2-red-palette); + +$theme: mat.m2-define-light-theme( + ( + color: ( + primary: $theme-primary, + accent: $theme-accent, + warn: $theme-warn, + ), + typography: mat.m2-define-typography-config(), + ) +); + +@include mat.dialog-theme($theme); +@include mat.button-theme($theme); diff --git a/libs/power-of-effect/backend/src/test-setup.ts b/apps/angular/55-back-button-navigation/src/test-setup.ts similarity index 53% rename from libs/power-of-effect/backend/src/test-setup.ts rename to apps/angular/55-back-button-navigation/src/test-setup.ts index 1100b3e8a..15de72a3c 100644 --- a/libs/power-of-effect/backend/src/test-setup.ts +++ b/apps/angular/55-back-button-navigation/src/test-setup.ts @@ -1 +1,2 @@ +import '@testing-library/jest-dom'; import 'jest-preset-angular/setup-jest'; diff --git a/apps/angular/55-back-button-navigation/tailwind.config.js b/apps/angular/55-back-button-navigation/tailwind.config.js new file mode 100644 index 000000000..38183db2c --- /dev/null +++ b/apps/angular/55-back-button-navigation/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/55-back-button-navigation/tsconfig.app.json b/apps/angular/55-back-button-navigation/tsconfig.app.json new file mode 100644 index 000000000..58220429a --- /dev/null +++ b/apps/angular/55-back-button-navigation/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/55-back-button-navigation/tsconfig.editor.json b/apps/angular/55-back-button-navigation/tsconfig.editor.json new file mode 100644 index 000000000..a8ac182c0 --- /dev/null +++ b/apps/angular/55-back-button-navigation/tsconfig.editor.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": {}, + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/angular/55-back-button-navigation/tsconfig.json b/apps/angular/55-back-button-navigation/tsconfig.json new file mode 100644 index 000000000..4383e7eb8 --- /dev/null +++ b/apps/angular/55-back-button-navigation/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.editor.json" + }, + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/angular/55-back-button-navigation/tsconfig.spec.json b/apps/angular/55-back-button-navigation/tsconfig.spec.json new file mode 100644 index 000000000..1a4817a7d --- /dev/null +++ b/apps/angular/55-back-button-navigation/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/libs/power-of-effect/model/.eslintrc.json b/apps/angular/57-content-projection-default/.eslintrc.json similarity index 92% rename from libs/power-of-effect/model/.eslintrc.json rename to apps/angular/57-content-projection-default/.eslintrc.json index 9247a6e3c..8ebcbfd59 100644 --- a/libs/power-of-effect/model/.eslintrc.json +++ b/apps/angular/57-content-projection-default/.eslintrc.json @@ -13,7 +13,7 @@ "error", { "type": "attribute", - "prefix": "lib", + "prefix": "app", "style": "camelCase" } ], @@ -21,7 +21,7 @@ "error", { "type": "element", - "prefix": "lib", + "prefix": "app", "style": "kebab-case" } ] diff --git a/apps/angular/57-content-projection-default/README.md b/apps/angular/57-content-projection-default/README.md new file mode 100644 index 000000000..fc4579558 --- /dev/null +++ b/apps/angular/57-content-projection-default/README.md @@ -0,0 +1,13 @@ +# Content Projection Default + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve angular-content-projection-default +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/57-content-projection-default/). diff --git a/apps/angular/57-content-projection-default/project.json b/apps/angular/57-content-projection-default/project.json new file mode 100644 index 000000000..a57738bff --- /dev/null +++ b/apps/angular/57-content-projection-default/project.json @@ -0,0 +1,81 @@ +{ + "name": "angular-content-projection-default", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/angular/57-content-projection-default/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/57-content-projection-default", + "index": "apps/angular/57-content-projection-default/src/index.html", + "browser": "apps/angular/57-content-projection-default/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/angular/57-content-projection-default/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + { + "glob": "**/*", + "input": "apps/angular/57-content-projection-default/public" + } + ], + "styles": [ + "apps/angular/57-content-projection-default/src/styles.scss" + ], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "4kb", + "maximumError": "8kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-content-projection-default:build:production" + }, + "development": { + "buildTarget": "angular-content-projection-default:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-content-projection-default:build" + } + }, + "serve-static": { + "executor": "@nx/web:file-server", + "options": { + "buildTarget": "angular-content-projection-default:build", + "staticFilePath": "dist/apps/angular/57-content-projection-default/browser", + "spa": true + } + } + } +} diff --git a/apps/ngrx/7-power-of-effect/src/favicon.ico b/apps/angular/57-content-projection-default/public/favicon.ico similarity index 100% rename from apps/ngrx/7-power-of-effect/src/favicon.ico rename to apps/angular/57-content-projection-default/public/favicon.ico diff --git a/apps/angular/57-content-projection-default/src/app/app.component.ts b/apps/angular/57-content-projection-default/src/app/app.component.ts new file mode 100644 index 000000000..b3e370a34 --- /dev/null +++ b/apps/angular/57-content-projection-default/src/app/app.component.ts @@ -0,0 +1,16 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { CardComponent } from './card.component'; + +@Component({ + imports: [CardComponent], + selector: 'app-root', + template: ` + + + `, + host: { + class: 'p-4 block flex flex-col gap-1', + }, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class AppComponent {} diff --git a/apps/angular/57-content-projection-default/src/app/app.config.ts b/apps/angular/57-content-projection-default/src/app/app.config.ts new file mode 100644 index 000000000..034603cfd --- /dev/null +++ b/apps/angular/57-content-projection-default/src/app/app.config.ts @@ -0,0 +1,5 @@ +import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; + +export const appConfig: ApplicationConfig = { + providers: [provideZoneChangeDetection({ eventCoalescing: true })], +}; diff --git a/apps/angular/57-content-projection-default/src/app/card.component.ts b/apps/angular/57-content-projection-default/src/app/card.component.ts new file mode 100644 index 000000000..851a6619d --- /dev/null +++ b/apps/angular/57-content-projection-default/src/app/card.component.ts @@ -0,0 +1,22 @@ +import { ChangeDetectionStrategy, Component, input } from '@angular/core'; + +@Component({ + selector: 'app-card', + imports: [], + template: ` +
{{ title() }}
+ @if (message()) { +
{{ message() }}
+ } @else { +
Aucun message
+ } + `, + changeDetection: ChangeDetectionStrategy.OnPush, + host: { + class: 'p-4 border border-grey rounded-sm flex flex-col w-[200px]', + }, +}) +export class CardComponent { + title = input.required(); + message = input(undefined); +} diff --git a/apps/angular/57-content-projection-default/src/index.html b/apps/angular/57-content-projection-default/src/index.html new file mode 100644 index 000000000..8b3015d4b --- /dev/null +++ b/apps/angular/57-content-projection-default/src/index.html @@ -0,0 +1,13 @@ + + + + + angular-content-projection-default + + + + + + + + diff --git a/apps/ngrx/2-effect-vs-selector/src/main.ts b/apps/angular/57-content-projection-default/src/main.ts similarity index 65% rename from apps/ngrx/2-effect-vs-selector/src/main.ts rename to apps/angular/57-content-projection-default/src/main.ts index 31c2a3482..f3a7223da 100644 --- a/apps/ngrx/2-effect-vs-selector/src/main.ts +++ b/apps/angular/57-content-projection-default/src/main.ts @@ -1,6 +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); +bootstrapApplication(AppComponent, appConfig).catch((err) => + console.error(err), +); diff --git a/apps/angular/57-content-projection-default/src/styles.scss b/apps/angular/57-content-projection-default/src/styles.scss new file mode 100644 index 000000000..77e408aa8 --- /dev/null +++ b/apps/angular/57-content-projection-default/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/57-content-projection-default/tailwind.config.js b/apps/angular/57-content-projection-default/tailwind.config.js new file mode 100644 index 000000000..38183db2c --- /dev/null +++ b/apps/angular/57-content-projection-default/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/57-content-projection-default/tsconfig.app.json b/apps/angular/57-content-projection-default/tsconfig.app.json new file mode 100644 index 000000000..58220429a --- /dev/null +++ b/apps/angular/57-content-projection-default/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/57-content-projection-default/tsconfig.editor.json b/apps/angular/57-content-projection-default/tsconfig.editor.json new file mode 100644 index 000000000..a8ac182c0 --- /dev/null +++ b/apps/angular/57-content-projection-default/tsconfig.editor.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": {}, + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/ngrx/7-power-of-effect/tsconfig.json b/apps/angular/57-content-projection-default/tsconfig.json similarity index 92% rename from apps/ngrx/7-power-of-effect/tsconfig.json rename to apps/angular/57-content-projection-default/tsconfig.json index b2dbbf22e..1b86db04e 100644 --- a/apps/ngrx/7-power-of-effect/tsconfig.json +++ b/apps/angular/57-content-projection-default/tsconfig.json @@ -1,17 +1,7 @@ { - "extends": "../../../tsconfig.base.json", - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], "compilerOptions": { - "target": "es2020", + "target": "es2022", + "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, "noImplicitOverride": true, @@ -19,6 +9,17 @@ "noImplicitReturns": true, "noFallthroughCasesInSwitch": true }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.editor.json" + }, + { + "path": "./tsconfig.app.json" + } + ], + "extends": "../../../tsconfig.base.json", "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, diff --git a/libs/shared/ngrx-callstate-store/.eslintrc.json b/apps/angular/58-content-projection-condition/.eslintrc.json similarity index 92% rename from libs/shared/ngrx-callstate-store/.eslintrc.json rename to apps/angular/58-content-projection-condition/.eslintrc.json index 9247a6e3c..8ebcbfd59 100644 --- a/libs/shared/ngrx-callstate-store/.eslintrc.json +++ b/apps/angular/58-content-projection-condition/.eslintrc.json @@ -13,7 +13,7 @@ "error", { "type": "attribute", - "prefix": "lib", + "prefix": "app", "style": "camelCase" } ], @@ -21,7 +21,7 @@ "error", { "type": "element", - "prefix": "lib", + "prefix": "app", "style": "kebab-case" } ] diff --git a/apps/angular/58-content-projection-condition/README.md b/apps/angular/58-content-projection-condition/README.md new file mode 100644 index 000000000..755bd8854 --- /dev/null +++ b/apps/angular/58-content-projection-condition/README.md @@ -0,0 +1,13 @@ +# Content Projection Condition + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve angular-content-projection-condition +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/58-content-projection-condition/). diff --git a/apps/angular/58-content-projection-condition/project.json b/apps/angular/58-content-projection-condition/project.json new file mode 100644 index 000000000..42869e68b --- /dev/null +++ b/apps/angular/58-content-projection-condition/project.json @@ -0,0 +1,84 @@ +{ + "name": "angular-content-projection-condition", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/angular/58-content-projection-condition/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/58-content-projection-condition", + "index": "apps/angular/58-content-projection-condition/src/index.html", + "browser": "apps/angular/58-content-projection-condition/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/angular/58-content-projection-condition/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + { + "glob": "**/*", + "input": "apps/angular/58-content-projection-condition/public" + } + ], + "styles": [ + "apps/angular/58-content-projection-condition/src/styles.scss" + ], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "4kb", + "maximumError": "8kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-content-projection-condition:build:production" + }, + "development": { + "buildTarget": "angular-content-projection-condition:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-content-projection-condition:build" + } + }, + "lint": { + "executor": "@nx/eslint:lint" + }, + "serve-static": { + "executor": "@nx/web:file-server", + "options": { + "buildTarget": "angular-content-projection-condition:build", + "staticFilePath": "dist/apps/angular/58-content-projection-condition/browser", + "spa": true + } + } + } +} diff --git a/apps/angular/58-content-projection-condition/public/favicon.ico b/apps/angular/58-content-projection-condition/public/favicon.ico new file mode 100644 index 000000000..317ebcb23 Binary files /dev/null and b/apps/angular/58-content-projection-condition/public/favicon.ico differ diff --git a/apps/angular/58-content-projection-condition/src/app/app.component.ts b/apps/angular/58-content-projection-condition/src/app/app.component.ts new file mode 100644 index 000000000..afad56f22 --- /dev/null +++ b/apps/angular/58-content-projection-condition/src/app/app.component.ts @@ -0,0 +1,22 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { CardComponent } from './card.component'; + +@Component({ + imports: [CardComponent], + selector: 'app-root', + template: ` + +
Card 1
+
Message 1
+
+ +
Card 2
+
Message 2
+
+ `, + host: { + class: 'p-4 block flex flex-col gap-1', + }, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class AppComponent {} diff --git a/apps/angular/58-content-projection-condition/src/app/app.config.ts b/apps/angular/58-content-projection-condition/src/app/app.config.ts new file mode 100644 index 000000000..034603cfd --- /dev/null +++ b/apps/angular/58-content-projection-condition/src/app/app.config.ts @@ -0,0 +1,5 @@ +import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; + +export const appConfig: ApplicationConfig = { + providers: [provideZoneChangeDetection({ eventCoalescing: true })], +}; diff --git a/apps/angular/58-content-projection-condition/src/app/card.component.ts b/apps/angular/58-content-projection-condition/src/app/card.component.ts new file mode 100644 index 000000000..46925977c --- /dev/null +++ b/apps/angular/58-content-projection-condition/src/app/card.component.ts @@ -0,0 +1,25 @@ +import { ChangeDetectionStrategy, Component, input } from '@angular/core'; + +@Component({ + selector: 'app-card', + template: ` + @if (small()) { + + + } @else { +
+
+ +
+ +
+ } + `, + changeDetection: ChangeDetectionStrategy.OnPush, + host: { + class: 'p-4 border border-grey rounded-sm flex flex-col w-[200px]', + }, +}) +export class CardComponent { + small = input(false); +} diff --git a/apps/angular/58-content-projection-condition/src/index.html b/apps/angular/58-content-projection-condition/src/index.html new file mode 100644 index 000000000..f1768ec71 --- /dev/null +++ b/apps/angular/58-content-projection-condition/src/index.html @@ -0,0 +1,13 @@ + + + + + angular-content-projection-condition + + + + + + + + diff --git a/apps/angular/58-content-projection-condition/src/main.ts b/apps/angular/58-content-projection-condition/src/main.ts new file mode 100644 index 000000000..f3a7223da --- /dev/null +++ b/apps/angular/58-content-projection-condition/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/58-content-projection-condition/src/styles.scss b/apps/angular/58-content-projection-condition/src/styles.scss new file mode 100644 index 000000000..77e408aa8 --- /dev/null +++ b/apps/angular/58-content-projection-condition/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/58-content-projection-condition/tailwind.config.js b/apps/angular/58-content-projection-condition/tailwind.config.js new file mode 100644 index 000000000..38183db2c --- /dev/null +++ b/apps/angular/58-content-projection-condition/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/58-content-projection-condition/tsconfig.app.json b/apps/angular/58-content-projection-condition/tsconfig.app.json new file mode 100644 index 000000000..58220429a --- /dev/null +++ b/apps/angular/58-content-projection-condition/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/58-content-projection-condition/tsconfig.editor.json b/apps/angular/58-content-projection-condition/tsconfig.editor.json new file mode 100644 index 000000000..a8ac182c0 --- /dev/null +++ b/apps/angular/58-content-projection-condition/tsconfig.editor.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": {}, + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/ngrx/2-effect-vs-selector/tsconfig.json b/apps/angular/58-content-projection-condition/tsconfig.json similarity index 89% rename from apps/ngrx/2-effect-vs-selector/tsconfig.json rename to apps/angular/58-content-projection-condition/tsconfig.json index 52eb4f718..1b86db04e 100644 --- a/apps/ngrx/2-effect-vs-selector/tsconfig.json +++ b/apps/angular/58-content-projection-condition/tsconfig.json @@ -1,20 +1,7 @@ { - "extends": "../../../tsconfig.base.json", - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.spec.json" - }, - { - "path": "./tsconfig.editor.json" - } - ], "compilerOptions": { - "target": "es2020", + "target": "es2022", + "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, "noImplicitOverride": true, @@ -22,6 +9,17 @@ "noImplicitReturns": true, "noFallthroughCasesInSwitch": true }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.editor.json" + }, + { + "path": "./tsconfig.app.json" + } + ], + "extends": "../../../tsconfig.base.json", "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, diff --git a/apps/angular/59-content-projection-defer/.eslintrc.json b/apps/angular/59-content-projection-defer/.eslintrc.json new file mode 100644 index 000000000..995177b5b --- /dev/null +++ b/apps/angular/59-content-projection-defer/.eslintrc.json @@ -0,0 +1,37 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": [ + "plugin:@nx/angular", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": { + "@angular-eslint/component-class-suffix": "off", + "@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/59-content-projection-defer/README.md b/apps/angular/59-content-projection-defer/README.md new file mode 100644 index 000000000..f726842d1 --- /dev/null +++ b/apps/angular/59-content-projection-defer/README.md @@ -0,0 +1,13 @@ +# content-projection-defer + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve angular-content-projection-defer +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/59-content-projection-defer/). diff --git a/apps/angular/59-content-projection-defer/project.json b/apps/angular/59-content-projection-defer/project.json new file mode 100644 index 000000000..5572ab573 --- /dev/null +++ b/apps/angular/59-content-projection-defer/project.json @@ -0,0 +1,82 @@ +{ + "name": "angular-content-projection-defer", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/angular/59-content-projection-defer/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/59-content-projection-defer", + "index": "apps/angular/59-content-projection-defer/src/index.html", + "browser": "apps/angular/59-content-projection-defer/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/angular/59-content-projection-defer/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + { + "glob": "**/*", + "input": "apps/angular/59-content-projection-defer/public" + } + ], + "styles": ["apps/angular/59-content-projection-defer/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "4kb", + "maximumError": "8kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-content-projection-defer:build:production" + }, + "development": { + "buildTarget": "angular-content-projection-defer:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-content-projection-defer:build" + } + }, + "lint": { + "executor": "@nx/eslint:lint" + }, + "serve-static": { + "executor": "@nx/web:file-server", + "options": { + "buildTarget": "angular-content-projection-defer:build", + "staticFilePath": "dist/apps/angular/59-content-projection-defer/browser", + "spa": true + } + } + } +} diff --git a/apps/angular/59-content-projection-defer/public/favicon.ico b/apps/angular/59-content-projection-defer/public/favicon.ico new file mode 100644 index 000000000..317ebcb23 Binary files /dev/null and b/apps/angular/59-content-projection-defer/public/favicon.ico differ diff --git a/apps/angular/59-content-projection-defer/src/app/app.component.ts b/apps/angular/59-content-projection-defer/src/app/app.component.ts new file mode 100644 index 000000000..ae40bc880 --- /dev/null +++ b/apps/angular/59-content-projection-defer/src/app/app.component.ts @@ -0,0 +1,23 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { RouterLink, RouterOutlet } from '@angular/router'; + +@Component({ + imports: [RouterOutlet, RouterLink], + selector: 'app-root', + template: ` +
+ + +
+ + `, + changeDetection: ChangeDetectionStrategy.OnPush, + host: { + class: 'flex flex-col gap-2 ', + }, +}) +export class AppComponent {} diff --git a/apps/angular/59-content-projection-defer/src/app/app.config.ts b/apps/angular/59-content-projection-defer/src/app/app.config.ts new file mode 100644 index 000000000..faf4d099a --- /dev/null +++ b/apps/angular/59-content-projection-defer/src/app/app.config.ts @@ -0,0 +1,12 @@ +import { provideHttpClient } from '@angular/common/http'; +import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; +import { provideRouter } from '@angular/router'; +import { appRoutes } from './app.routes'; + +export const appConfig: ApplicationConfig = { + providers: [ + provideZoneChangeDetection({ eventCoalescing: true }), + provideRouter(appRoutes), + provideHttpClient(), + ], +}; diff --git a/apps/angular/59-content-projection-defer/src/app/app.routes.ts b/apps/angular/59-content-projection-defer/src/app/app.routes.ts new file mode 100644 index 000000000..3ca1b67cc --- /dev/null +++ b/apps/angular/59-content-projection-defer/src/app/app.routes.ts @@ -0,0 +1,13 @@ +import { Route } from '@angular/router'; + +export const appRoutes: Route[] = [ + { + path: 'page-1', + loadComponent: () => import('./page-1').then((m) => m.Page1), + }, + { + path: 'page-2', + loadComponent: () => import('./page-2').then((m) => m.Page2), + }, + { path: '**', redirectTo: 'page-1' }, +]; diff --git a/apps/angular/59-content-projection-defer/src/app/expandable-card.ts b/apps/angular/59-content-projection-defer/src/app/expandable-card.ts new file mode 100644 index 000000000..8f446ed80 --- /dev/null +++ b/apps/angular/59-content-projection-defer/src/app/expandable-card.ts @@ -0,0 +1,54 @@ +import { ChangeDetectionStrategy, Component, signal } from '@angular/core'; + +@Component({ + selector: 'app-expandable-card', + template: ` + + +
+ +
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, + host: { + class: 'flex flex-col gap-2 ', + }, +}) +export class ExpandableCard { + public isExpanded = signal(false); +} diff --git a/apps/angular/59-content-projection-defer/src/app/page-1.ts b/apps/angular/59-content-projection-defer/src/app/page-1.ts new file mode 100644 index 000000000..868d76959 --- /dev/null +++ b/apps/angular/59-content-projection-defer/src/app/page-1.ts @@ -0,0 +1,10 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; + +@Component({ + selector: 'app-page-1', + template: ` + page1 + `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class Page1 {} diff --git a/apps/angular/59-content-projection-defer/src/app/page-2.ts b/apps/angular/59-content-projection-defer/src/app/page-2.ts new file mode 100644 index 000000000..5665466d8 --- /dev/null +++ b/apps/angular/59-content-projection-defer/src/app/page-2.ts @@ -0,0 +1,43 @@ +import { httpResource } from '@angular/common/http'; +import { + ChangeDetectionStrategy, + Component, + ResourceStatus, +} from '@angular/core'; +import { ExpandableCard } from './expandable-card'; + +interface Post { + id: number; + title: string; + body: string; + userId: number; +} + +@Component({ + selector: 'app-page-2', + template: ` + page2 + +
Load Post
+
+ @if (postResource.isLoading()) { + Loading... + } @else if (postResource.status() === ResourceStatus.Error) { + Error... + } @else { + @for (post of postResource.value(); track post.id) { +
{{ post.title }}
+ } + } +
+
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [ExpandableCard], +}) +export class Page2 { + public postResource = httpResource( + 'https://jsonplaceholder.typicode.com/posts', + ); + protected readonly ResourceStatus = ResourceStatus; +} diff --git a/apps/angular/59-content-projection-defer/src/index.html b/apps/angular/59-content-projection-defer/src/index.html new file mode 100644 index 000000000..79f435fa6 --- /dev/null +++ b/apps/angular/59-content-projection-defer/src/index.html @@ -0,0 +1,13 @@ + + + + + angular-content-projection-defer + + + + + + + + diff --git a/apps/angular/59-content-projection-defer/src/main.ts b/apps/angular/59-content-projection-defer/src/main.ts new file mode 100644 index 000000000..f3a7223da --- /dev/null +++ b/apps/angular/59-content-projection-defer/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/59-content-projection-defer/src/styles.scss b/apps/angular/59-content-projection-defer/src/styles.scss new file mode 100644 index 000000000..77e408aa8 --- /dev/null +++ b/apps/angular/59-content-projection-defer/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/59-content-projection-defer/tailwind.config.js b/apps/angular/59-content-projection-defer/tailwind.config.js new file mode 100644 index 000000000..38183db2c --- /dev/null +++ b/apps/angular/59-content-projection-defer/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/59-content-projection-defer/tsconfig.app.json b/apps/angular/59-content-projection-defer/tsconfig.app.json new file mode 100644 index 000000000..58220429a --- /dev/null +++ b/apps/angular/59-content-projection-defer/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/59-content-projection-defer/tsconfig.editor.json b/apps/angular/59-content-projection-defer/tsconfig.editor.json new file mode 100644 index 000000000..a8ac182c0 --- /dev/null +++ b/apps/angular/59-content-projection-defer/tsconfig.editor.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": {}, + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/libs/power-of-effect/backend/tsconfig.json b/apps/angular/59-content-projection-defer/tsconfig.json similarity index 81% rename from libs/power-of-effect/backend/tsconfig.json rename to apps/angular/59-content-projection-defer/tsconfig.json index 7504c346e..1b86db04e 100644 --- a/libs/power-of-effect/backend/tsconfig.json +++ b/apps/angular/59-content-projection-defer/tsconfig.json @@ -1,17 +1,7 @@ { - "extends": "../../../tsconfig.base.json", - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.lib.json" - }, - { - "path": "./tsconfig.spec.json" - } - ], "compilerOptions": { - "target": "es2020", + "target": "es2022", + "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, "noImplicitOverride": true, @@ -19,6 +9,17 @@ "noImplicitReturns": true, "noFallthroughCasesInSwitch": true }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.editor.json" + }, + { + "path": "./tsconfig.app.json" + } + ], + "extends": "../../../tsconfig.base.json", "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, diff --git a/apps/angular/6-structural-directive/project.json b/apps/angular/6-structural-directive/project.json index fb02e886f..f803b0cb5 100644 --- a/apps/angular/6-structural-directive/project.json +++ b/apps/angular/6-structural-directive/project.json @@ -4,6 +4,7 @@ "projectType": "application", "sourceRoot": "apps/angular/6-structural-directive/src", "prefix": "app", + "tags": [], "targets": { "build": { "executor": "@angular-devkit/build-angular:browser", @@ -66,10 +67,6 @@ "options": { "buildTarget": "angular-structural-directive:build" } - }, - "lint": { - "executor": "@nx/eslint:lint" } - }, - "tags": [] + } } diff --git a/apps/angular/6-structural-directive/src/app/app.component.ts b/apps/angular/6-structural-directive/src/app/app.component.ts index d89a2f579..a3d63b374 100644 --- a/apps/angular/6-structural-directive/src/app/app.component.ts +++ b/apps/angular/6-structural-directive/src/app/app.component.ts @@ -2,7 +2,6 @@ import { Component } from '@angular/core'; import { RouterOutlet } from '@angular/router'; @Component({ - standalone: true, imports: [RouterOutlet], selector: 'app-root', template: ` diff --git a/apps/angular/6-structural-directive/src/app/dashboard/admin.component.ts b/apps/angular/6-structural-directive/src/app/dashboard/admin.component.ts index 72e4b3bef..26bb23284 100644 --- a/apps/angular/6-structural-directive/src/app/dashboard/admin.component.ts +++ b/apps/angular/6-structural-directive/src/app/dashboard/admin.component.ts @@ -4,7 +4,6 @@ import { ButtonComponent } from '../button.component'; @Component({ selector: 'app-dashboard', - standalone: true, imports: [RouterLink, ButtonComponent], template: `

dashboard for Admin works!

diff --git a/apps/angular/6-structural-directive/src/app/information.component.ts b/apps/angular/6-structural-directive/src/app/information.component.ts index e4adeb1b9..81b339520 100644 --- a/apps/angular/6-structural-directive/src/app/information.component.ts +++ b/apps/angular/6-structural-directive/src/app/information.component.ts @@ -4,7 +4,6 @@ import { UserStore } from './user.store'; @Component({ selector: 'app-information', - standalone: true, imports: [CommonModule], template: `

Information Panel

diff --git a/apps/angular/6-structural-directive/src/app/login.component.ts b/apps/angular/6-structural-directive/src/app/login.component.ts index cd36d9603..b8644ed38 100644 --- a/apps/angular/6-structural-directive/src/app/login.component.ts +++ b/apps/angular/6-structural-directive/src/app/login.component.ts @@ -14,7 +14,6 @@ import { import { UserStore } from './user.store'; @Component({ - standalone: true, imports: [InformationComponent, RouterLink, ButtonComponent], selector: 'app-login', template: ` diff --git a/apps/angular/8-pure-pipe/project.json b/apps/angular/8-pure-pipe/project.json index c9c5275a4..a684d542f 100644 --- a/apps/angular/8-pure-pipe/project.json +++ b/apps/angular/8-pure-pipe/project.json @@ -4,6 +4,7 @@ "projectType": "application", "sourceRoot": "apps/angular/8-pure-pipe/src", "prefix": "app", + "tags": [], "targets": { "build": { "executor": "@angular-devkit/build-angular:browser", @@ -66,10 +67,6 @@ "options": { "buildTarget": "angular-pure-pipe:build" } - }, - "lint": { - "executor": "@nx/eslint:lint" } - }, - "tags": [] + } } diff --git a/apps/angular/8-pure-pipe/src/app/app.component.ts b/apps/angular/8-pure-pipe/src/app/app.component.ts index 3c19fa169..41dd38e25 100644 --- a/apps/angular/8-pure-pipe/src/app/app.component.ts +++ b/apps/angular/8-pure-pipe/src/app/app.component.ts @@ -2,7 +2,6 @@ import { NgFor } from '@angular/common'; import { Component } from '@angular/core'; @Component({ - standalone: true, imports: [NgFor], selector: 'app-root', template: ` diff --git a/apps/angular/9-wrap-function-pipe/project.json b/apps/angular/9-wrap-function-pipe/project.json index 44802796d..dc5c4ab6e 100644 --- a/apps/angular/9-wrap-function-pipe/project.json +++ b/apps/angular/9-wrap-function-pipe/project.json @@ -4,6 +4,7 @@ "projectType": "application", "sourceRoot": "apps/angular/9-wrap-function-pipe/src", "prefix": "app", + "tags": [], "targets": { "build": { "executor": "@angular-devkit/build-angular:browser", @@ -66,10 +67,6 @@ "options": { "buildTarget": "angular-wrap-function-pipe:build" } - }, - "lint": { - "executor": "@nx/eslint:lint" } - }, - "tags": [] + } } diff --git a/apps/angular/9-wrap-function-pipe/src/app/app.component.ts b/apps/angular/9-wrap-function-pipe/src/app/app.component.ts index d9c163c93..dd576ae49 100644 --- a/apps/angular/9-wrap-function-pipe/src/app/app.component.ts +++ b/apps/angular/9-wrap-function-pipe/src/app/app.component.ts @@ -2,7 +2,6 @@ import { NgFor } from '@angular/common'; import { Component } from '@angular/core'; @Component({ - standalone: true, imports: [NgFor], selector: 'app-root', template: ` diff --git a/apps/forms/41-control-value-accessor/project.json b/apps/forms/41-control-value-accessor/project.json index 006ae8d16..a1ec26bac 100644 --- a/apps/forms/41-control-value-accessor/project.json +++ b/apps/forms/41-control-value-accessor/project.json @@ -65,14 +65,15 @@ "buildTarget": "forms-control-value-accessor:build" } }, - "lint": { - "executor": "@nx/eslint:lint" - }, "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], "options": { - "jestConfig": "apps/forms/41-control-value-accessor/jest.config.ts" + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "coverage": true + } } } } diff --git a/apps/forms/41-control-value-accessor/src/app/app.component.ts b/apps/forms/41-control-value-accessor/src/app/app.component.ts index f56b5d7d9..69134b864 100644 --- a/apps/forms/41-control-value-accessor/src/app/app.component.ts +++ b/apps/forms/41-control-value-accessor/src/app/app.component.ts @@ -2,7 +2,6 @@ import { Component } from '@angular/core'; import { FeedbackFormComponent } from './feedback-form/feedback-form.component'; @Component({ - standalone: true, imports: [FeedbackFormComponent], selector: 'app-root', template: ` diff --git a/apps/forms/41-control-value-accessor/src/app/feedback-form/feedback-form.component.ts b/apps/forms/41-control-value-accessor/src/app/feedback-form/feedback-form.component.ts index d99700db1..4110d6cf7 100644 --- a/apps/forms/41-control-value-accessor/src/app/feedback-form/feedback-form.component.ts +++ b/apps/forms/41-control-value-accessor/src/app/feedback-form/feedback-form.component.ts @@ -8,7 +8,6 @@ import { import { RatingControlComponent } from '../rating-control/rating-control.component'; @Component({ - standalone: true, imports: [RatingControlComponent, ReactiveFormsModule], selector: 'app-feedback-form', templateUrl: 'feedback-form.component.html', diff --git a/apps/forms/48-avoid-losing-form-data/project.json b/apps/forms/48-avoid-losing-form-data/project.json index d7d46731b..9517d3123 100644 --- a/apps/forms/48-avoid-losing-form-data/project.json +++ b/apps/forms/48-avoid-losing-form-data/project.json @@ -67,9 +67,6 @@ "options": { "buildTarget": "forms-avoid-losing-form-data:build" } - }, - "lint": { - "executor": "@nx/eslint:lint" } } } diff --git a/apps/forms/48-avoid-losing-form-data/src/app/app.component.ts b/apps/forms/48-avoid-losing-form-data/src/app/app.component.ts index 6ac465e12..2b5adc443 100644 --- a/apps/forms/48-avoid-losing-form-data/src/app/app.component.ts +++ b/apps/forms/48-avoid-losing-form-data/src/app/app.component.ts @@ -3,7 +3,6 @@ import { RouterOutlet } from '@angular/router'; import { NavComponent } from './ui/nav.component'; @Component({ - standalone: true, imports: [RouterOutlet, NavComponent], selector: 'app-root', template: ` diff --git a/apps/forms/48-avoid-losing-form-data/src/app/pages/join.component.ts b/apps/forms/48-avoid-losing-form-data/src/app/pages/join.component.ts index 6f5fea9af..51449a7fb 100644 --- a/apps/forms/48-avoid-losing-form-data/src/app/pages/join.component.ts +++ b/apps/forms/48-avoid-losing-form-data/src/app/pages/join.component.ts @@ -2,7 +2,6 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import { FormComponent } from '../ui/form.component'; @Component({ - standalone: true, imports: [FormComponent], template: `
diff --git a/apps/forms/48-avoid-losing-form-data/src/app/ui/form.component.ts b/apps/forms/48-avoid-losing-form-data/src/app/ui/form.component.ts index 2b28c540f..f3190d517 100644 --- a/apps/forms/48-avoid-losing-form-data/src/app/ui/form.component.ts +++ b/apps/forms/48-avoid-losing-form-data/src/app/ui/form.component.ts @@ -3,7 +3,6 @@ import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms'; @Component({ selector: 'app-form', - standalone: true, imports: [ReactiveFormsModule], template: `
diff --git a/apps/forms/48-avoid-losing-form-data/src/app/ui/nav.component.ts b/apps/forms/48-avoid-losing-form-data/src/app/ui/nav.component.ts index 491aecac9..269297280 100644 --- a/apps/forms/48-avoid-losing-form-data/src/app/ui/nav.component.ts +++ b/apps/forms/48-avoid-losing-form-data/src/app/ui/nav.component.ts @@ -3,7 +3,6 @@ import { RouterLink, RouterLinkActive } from '@angular/router'; @Component({ selector: 'app-nav', - standalone: true, imports: [RouterLink, RouterLinkActive], template: `
diff --git a/docs/src/components/VideoButton.astro b/docs/src/components/VideoButton.astro index a739090b5..723ef30e9 100644 --- a/docs/src/components/VideoButton.astro +++ b/docs/src/components/VideoButton.astro @@ -5,12 +5,13 @@ interface Props { lang: any; link: string; alt: string; - flag?: 'FR'; + flag?: 'FR' | 'ES'; } const { link, alt, flag, lang } = Astro.props; const { data } = await getEntry('i18n', lang); const isFR = flag === 'FR'; +const isES = flag === 'ES'; --- {data['challenge.footer.video']} - {isFR && 🇫🇷} + {isFR && 🇫🇷} + {isES && 🇪🇸} diff --git a/docs/src/components/github/SignUp.svelte b/docs/src/components/github/SignUp.svelte index 88f1bbac5..a98a2a943 100644 --- a/docs/src/components/github/SignUp.svelte +++ b/docs/src/components/github/SignUp.svelte @@ -53,6 +53,11 @@ background-color: #218838; } + a :global(svg) { + --sl-icon-color: initial; + } + + @media (width < 450px) { .github-sign-in { display: none; diff --git a/docs/src/components/github/SponsorUser.svelte b/docs/src/components/github/SponsorUser.svelte index f82b5e8d6..cc29003d7 100644 --- a/docs/src/components/github/SponsorUser.svelte +++ b/docs/src/components/github/SponsorUser.svelte @@ -7,7 +7,7 @@ onMount(async () => { const sponsorFetch = await fetch('http://github.com/service/https://ghs.vercel.app/v2/sponsors/tomalaforge'); const data = await sponsorFetch.json(); - sponsors = data.sponsors.past; + sponsors = data.sponsors.current; }); diff --git a/docs/src/components/leaderboard/LeaderboardAnswer.svelte b/docs/src/components/leaderboard/LeaderboardAnswer.svelte index 4a6872131..0ca776b3c 100644 --- a/docs/src/components/leaderboard/LeaderboardAnswer.svelte +++ b/docs/src/components/leaderboard/LeaderboardAnswer.svelte @@ -7,6 +7,7 @@ let loading = true; let error = null; let isUsernamePresent = false; + let globalCount = 0; token.subscribe(token => { if (token) { @@ -34,6 +35,8 @@ break; } + globalCount = globalCount + items.length; + items.forEach(pr => { const userLogin = pr.user.login; if (prCounts[userLogin]) { @@ -62,7 +65,7 @@ avatar: pr.avatar, count: pr.count, challengeNumber: pr.challengeNumber.sort((a, b) => a - b), - })).filter((r) => r.login !== 'allcontributors[bot]').sort((a, b) => b.count - a.count); + })).filter((r) => r.login !== 'allcontributors[bot]' && r.login !== 'tomalaforge').sort((a, b) => b.count - a.count); } catch (e) { error = e.message; @@ -76,6 +79,7 @@ {#if !$isConnected}
Log in to Github to see the list
{:else} +🔥Total Answers: { globalCount } {#if isUsernamePresent}