From 9c42dc8845e50ed2c42bcdb213a48114d857b1be Mon Sep 17 00:00:00 2001 From: jpaberzs Date: Tue, 25 Aug 2026 13:06:16 +0300 Subject: [PATCH] fix: done refactorind of card component --- .../city-card/city-card.component.ts | 59 ++++++++++++++-- .../student-card/student-card.component.ts | 53 +++++++++----- .../teacher-card/teacher-card.component.ts | 53 +++++++++----- .../src/app/data-access/city.store.ts | 2 +- .../1-projection/src/app/model/card.model.ts | 5 -- .../src/app/ui/card/card.component.ts | 70 ++++++++++--------- .../app/ui/list-item/list-item.component.ts | 26 +++---- 7 files changed, 177 insertions(+), 91 deletions(-) delete mode 100644 apps/angular/1-projection/src/app/model/card.model.ts 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 8895c8c84..748f23254 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,9 +1,60 @@ -import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { NgOptimizedImage } from '@angular/common'; +import { + ChangeDetectionStrategy, + Component, + inject, + WritableSignal, +} from '@angular/core'; +import { + FakeHttpService, + randomCity, +} from '../../data-access/fake-http.service'; +import { City } from '../../model/city.model'; +import { CardComponent } from '../../ui/card/card.component'; +import { ListItemComponent } from '../../ui/list-item/list-item.component'; +import { CityStore } from './../../data-access/city.store'; @Component({ selector: 'app-city-card', - template: 'TODO City', - imports: [], + template: ` + + + + + + + + `, + imports: [CardComponent, NgOptimizedImage, ListItemComponent], changeDetection: ChangeDetectionStrategy.OnPush, }) -export class CityCardComponent {} +export class CityCardComponent { + private http: FakeHttpService = inject(FakeHttpService); + private store: CityStore = inject(CityStore); + + protected cities: WritableSignal = this.store.cities; + + ngOnInit(): void { + this.http.fetchCities$.subscribe((s) => this.store.addAll(s)); + } + + public addNewItem(): void { + this.store.addOne(randomCity()); + } + + public deleteItem(id: number): void { + this.store.deleteOne(id); + } +} 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 bdfa4abd4..6b83c55ba 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,40 +1,61 @@ +import { NgOptimizedImage } from '@angular/common'; import { ChangeDetectionStrategy, Component, inject, OnInit, + WritableSignal, } from '@angular/core'; -import { FakeHttpService } from '../../data-access/fake-http.service'; +import { + FakeHttpService, + randStudent, +} 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'; +import { ListItemComponent } from '../../ui/list-item/list-item.component'; @Component({ selector: 'app-student-card', template: ` + [template]="listItem" + (addNewItem)="addNewItem()"> + + + + + + `, - styles: [ - ` - ::ng-deep .bg-light-green { - background-color: rgba(0, 250, 0, 0.1); - } - `, - ], - imports: [CardComponent], + imports: [CardComponent, NgOptimizedImage, ListItemComponent], changeDetection: ChangeDetectionStrategy.OnPush, }) export class StudentCardComponent implements OnInit { - private http = inject(FakeHttpService); - private store = inject(StudentStore); + private http: FakeHttpService = inject(FakeHttpService); + private store: StudentStore = inject(StudentStore); - students = this.store.students; - cardType = CardType.STUDENT; + protected students: WritableSignal = this.store.students; ngOnInit(): void { this.http.fetchStudents$.subscribe((s) => this.store.addAll(s)); } + + public addNewItem(): void { + this.store.addOne(randStudent()); + } + + public deleteItem(id: number): void { + this.store.deleteOne(id); + } } 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 3e454ac19..5f3919983 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,40 +1,61 @@ +import { NgOptimizedImage } from '@angular/common'; import { ChangeDetectionStrategy, Component, inject, OnInit, + WritableSignal, } from '@angular/core'; -import { FakeHttpService } from '../../data-access/fake-http.service'; +import { + FakeHttpService, + randTeacher, +} from '../../data-access/fake-http.service'; import { TeacherStore } from '../../data-access/teacher.store'; -import { CardType } from '../../model/card.model'; import { CardComponent } from '../../ui/card/card.component'; +import { ListItemComponent } from '../../ui/list-item/list-item.component'; +import { Teacher } from './../../model/teacher.model'; @Component({ selector: 'app-teacher-card', template: ` + [template]="listItem" + (addNewItem)="addNewItem()" + customClass="bg-light-red"> + + + + + + `, - styles: [ - ` - ::ng-deep .bg-light-red { - background-color: rgba(250, 0, 0, 0.1); - } - `, - ], changeDetection: ChangeDetectionStrategy.Eager, - imports: [CardComponent], + imports: [CardComponent, NgOptimizedImage, ListItemComponent], }) export class TeacherCardComponent implements OnInit { - private http = inject(FakeHttpService); - private store = inject(TeacherStore); + private http: FakeHttpService = inject(FakeHttpService); + private store: TeacherStore = inject(TeacherStore); - teachers = this.store.teachers; - cardType = CardType.TEACHER; + protected teachers: WritableSignal = this.store.teachers; ngOnInit(): void { this.http.fetchTeachers$.subscribe((t) => this.store.addAll(t)); } + + public addNewItem(): void { + this.store.addOne(randTeacher()); + } + + public deleteItem(id: number): void { + this.store.deleteOne(id); + } } 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 a8b523569..9fbcb346b 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 @@ -5,7 +5,7 @@ import { City } from '../model/city.model'; providedIn: 'root', }) export class CityStore { - private cities = signal([]); + public cities = signal([]); addAll(cities: City[]) { this.cities.set(cities); diff --git a/apps/angular/1-projection/src/app/model/card.model.ts b/apps/angular/1-projection/src/app/model/card.model.ts deleted file mode 100644 index 740cd2ae4..000000000 --- a/apps/angular/1-projection/src/app/model/card.model.ts +++ /dev/null @@ -1,5 +0,0 @@ -export enum CardType { - TEACHER, - STUDENT, - CITY, -} 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 d395474e2..092020c36 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,15 +1,21 @@ -import { NgOptimizedImage } from '@angular/common'; +import { NgTemplateOutlet } from '@angular/common'; import { ChangeDetectionStrategy, Component, - inject, input, + InputSignal, + output, + OutputEmitterRef, + TemplateRef, } 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'; -import { CardType } from '../../model/card.model'; -import { ListItemComponent } from '../list-item/list-item.component'; +import { City } from '../../model/city.model'; +import { Student } from '../../model/student.model'; +import { Teacher } from '../../model/teacher.model'; +interface CardTemplateContext { + $implicit: TCardTuple; +} + +type TCardTuple = Student | Teacher | City; @Component({ selector: 'app-card', @@ -17,48 +23,48 @@ import { ListItemComponent } from '../list-item/list-item.component';
- @if (type() === CardType.TEACHER) { - - } - @if (type() === CardType.STUDENT) { - - } +
@for (item of list(); track item) { - + }
`, + styles: [ + ` + .bg-light-green { + background-color: rgba(0, 250, 0, 0.1); + } + .bg-light-red { + background-color: rgba(250, 0, 0, 0.1); + } + .bg-light-blue { + background-color: rgba(0, 0, 250, 0.1); + } + `, + ], changeDetection: ChangeDetectionStrategy.Eager, - imports: [ListItemComponent, NgOptimizedImage], + imports: [NgTemplateOutlet], }) export class CardComponent { - private teacherStore = inject(TeacherStore); - private studentStore = inject(StudentStore); + public addNewItem: OutputEmitterRef = output(); - readonly list = input(null); - readonly type = input.required(); + public template: InputSignal> = + input.required>(); + readonly list = input(null); readonly customClass = input(''); - CardType = CardType; - - addNewItem() { - const type = this.type(); - if (type === CardType.TEACHER) { - this.teacherStore.addOne(randTeacher()); - } else if (type === CardType.STUDENT) { - this.studentStore.addOne(randStudent()); - } + public onAddNewItem(event: Event): void { + this.addNewItem.emit(event); } } 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 c04a29c05..305121831 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,19 +1,18 @@ import { ChangeDetectionStrategy, Component, - inject, input, + InputSignal, + output, + OutputEmitterRef, } from '@angular/core'; -import { StudentStore } from '../../data-access/student.store'; -import { TeacherStore } from '../../data-access/teacher.store'; -import { CardType } from '../../model/card.model'; @Component({ selector: 'app-list-item', template: `
{{ name() }} -
@@ -21,19 +20,12 @@ import { CardType } from '../../model/card.model'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class ListItemComponent { - private teacherStore = inject(TeacherStore); - private studentStore = inject(StudentStore); + public deleteItem: OutputEmitterRef = output(); - readonly id = input.required(); - readonly name = input.required(); - readonly type = input.required(); + readonly id: InputSignal = input.required(); + readonly name: InputSignal = input.required(); - delete(id: number) { - const type = this.type(); - if (type === CardType.TEACHER) { - this.teacherStore.deleteOne(id); - } else if (type === CardType.STUDENT) { - this.studentStore.deleteOne(id); - } + public onDeleteItem(id: number): void { + this.deleteItem.emit(id); } }