From 9ddb51c1b3311b26048a54fe7210f7f915cbd1a4 Mon Sep 17 00:00:00 2001 From: Anand raja Date: Fri, 20 Sep 2024 09:33:15 +0000 Subject: [PATCH 1/2] destroyRef added --- .../server-status/server-status.component.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/app/components/dashboard/server-status/server-status.component.ts b/src/app/components/dashboard/server-status/server-status.component.ts index c742a31..f3fe4d2 100644 --- a/src/app/components/dashboard/server-status/server-status.component.ts +++ b/src/app/components/dashboard/server-status/server-status.component.ts @@ -1,4 +1,5 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, DestroyRef, inject, OnInit } from '@angular/core'; +// import { OnDestroy } from '@angular/core'; @Component({ selector: 'app-server-status', @@ -8,12 +9,17 @@ import { Component, OnInit } from '@angular/core'; styleUrl: './server-status.component.scss', }) export class ServerStatusComponent implements OnInit { + // private interval?: NodeJS.Timeout; + // private interval?: ReturnType; + + destroyRef = inject(DestroyRef); + currentStatus: 'online' | 'offline' | 'unkown' = 'online'; constructor() {} ngOnInit() { - setInterval(() => { + const interval = setInterval(() => { const rnd = Math.random(); if (rnd < 0.5) { @@ -24,5 +30,9 @@ export class ServerStatusComponent implements OnInit { this.currentStatus = 'unkown'; } }, 5000); + + this.destroyRef.onDestroy(() => { + clearInterval(interval); + }); } } From bed91b09f7005a8516cb5aa8973ab3070f3a27ee Mon Sep 17 00:00:00 2001 From: Anand raja Date: Fri, 20 Sep 2024 16:25:18 +0000 Subject: [PATCH 2/2] ticket component design --- README.md | 22 ++++++ .../new-ticket/new-ticket.component.html | 6 +- .../new-ticket/new-ticket.component.ts | 19 ++++- .../tickets/ticket/ticket.component.html | 41 ++++++++++- .../tickets/ticket/ticket.component.scss | 73 +++++++++++++++++++ .../dashboard/tickets/tickets.component.html | 14 +++- .../dashboard/tickets/tickets.component.ts | 19 ++++- src/app/models/ticket.model.ts | 20 +++++ .../shared/ui/control/control.component.ts | 8 +- 9 files changed, 210 insertions(+), 12 deletions(-) create mode 100644 src/app/models/ticket.model.ts diff --git a/README.md b/README.md index adfc3ec..9c28319 100644 --- a/README.md +++ b/README.md @@ -220,6 +220,28 @@ To configure the pre-commit hook, simply add a `precommit` npm script. We want t 7. For more, please [check](https://prettier.io/docs/en/ignore.html) +## Code + +### Signal Effects Cleanup Functions + +When working with Signal effects, you sometimes might need to perform some cleanup work before the effect function runs again (e.g., to clear some timer or something like that). + +Angular's `effect()` allows you to do that! + +It does provide you with an `onCleanup` hook which you can execute as part of your effect function to define what should happen before the effect code runs the next time: + +```ts +effect(onCleanup => { + const tasks = getTasks(); + const timer = setTimeout(() => { + console.log(`Current number of tasks: ${tasks().length}`); + }, 1000); + onCleanup(() => { + clearTimeout(timer); + }); +}); +``` + ## Resources - [GitHub Actions for Angular](https://github.com/rodrigokamada/angular-github-actions) diff --git a/src/app/components/dashboard/tickets/new-ticket/new-ticket.component.html b/src/app/components/dashboard/tickets/new-ticket/new-ticket.component.html index 62d9f93..6f05348 100644 --- a/src/app/components/dashboard/tickets/new-ticket/new-ticket.component.html +++ b/src/app/components/dashboard/tickets/new-ticket/new-ticket.component.html @@ -1,9 +1,9 @@ -
+ - + - +

+ + + @if (true) { +

TEXT

+ + @if (true) { +

+ } + } + diff --git a/src/app/components/dashboard/tickets/ticket/ticket.component.scss b/src/app/components/dashboard/tickets/ticket/ticket.component.scss index e69de29..844bc54 100644 --- a/src/app/components/dashboard/tickets/ticket/ticket.component.scss +++ b/src/app/components/dashboard/tickets/ticket/ticket.component.scss @@ -0,0 +1,73 @@ +article { + border-radius: 4px; + background-color: #59555f; + color: #ded8e6; +} + +h3 { + padding: 0.5rem; + margin: 0; + font-size: 0.9rem; + display: flex; + gap: 0.5rem; + align-items: center; +} + +h3 div { + width: 0.9rem; + height: 0.9rem; + border-radius: 50%; +} + +.ticket-open { + background-color: #de62e9; +} + +.ticket-closed { + background-color: #51c788; +} + +.text { + text-align: left; +} + +button { + flex: 1; + width: 100%; + font: inherit; + background: transparent; + border: none; + color: #ded8e6; + display: flex; + justify-content: space-between; + align-items: center; +} + +button span:first-child { + margin-bottom: 0.1rem; +} + +button span:last-child { + width: 1rem; +} + +p { + margin: 0; + padding: 1rem; + font-size: 0.9rem; +} + +p:has(button) { + padding-top: 0; +} + +p button { + padding: 0; + width: auto; + display: inline; + font-size: 0.75rem; +} + +p button:hover { + color: #ec9fea; +} diff --git a/src/app/components/dashboard/tickets/tickets.component.html b/src/app/components/dashboard/tickets/tickets.component.html index 356aa4b..0e16148 100644 --- a/src/app/components/dashboard/tickets/tickets.component.html +++ b/src/app/components/dashboard/tickets/tickets.component.html @@ -1,3 +1,15 @@ +
+
    + @for (ticket of tickets; track ticket.id) { +
  • + +
  • + } @empty { +

    No Tickets Available!

    + } +
+
+
- +
diff --git a/src/app/components/dashboard/tickets/tickets.component.ts b/src/app/components/dashboard/tickets/tickets.component.ts index 1a3c40e..d9b6c88 100644 --- a/src/app/components/dashboard/tickets/tickets.component.ts +++ b/src/app/components/dashboard/tickets/tickets.component.ts @@ -1,12 +1,27 @@ import { Component } from '@angular/core'; import { NewTicketComponent } from './new-ticket/new-ticket.component'; +import { Status, Ticket } from '../../../models/ticket.model'; +import { TicketComponent } from './ticket/ticket.component'; @Component({ selector: 'app-tickets', standalone: true, - imports: [NewTicketComponent], + imports: [NewTicketComponent, TicketComponent], templateUrl: './tickets.component.html', styleUrl: './tickets.component.scss', }) -export class TicketsComponent {} +export class TicketsComponent { + tickets: Ticket[] = []; + + onAddTicket(ticketData: { title: string; text: string }) { + const ticket: Ticket = { + title: ticketData.title, + request: ticketData.text, + id: Math.random().toString(), + status: Status.OPEN, + }; + + this.tickets.unshift(ticket); + } +} diff --git a/src/app/models/ticket.model.ts b/src/app/models/ticket.model.ts new file mode 100644 index 0000000..5a92774 --- /dev/null +++ b/src/app/models/ticket.model.ts @@ -0,0 +1,20 @@ +/* +export interface Ticket { + id: string; + title: string; + request: string; + status: 'open' | 'close'; +} +*/ + +export interface Ticket { + id: string; + title: string; + request: string; + status: Status; +} + +export enum Status { + OPEN = 'open', + CLOSE = 'close', +} diff --git a/src/app/shared/ui/control/control.component.ts b/src/app/shared/ui/control/control.component.ts index 84588d2..975dd88 100644 --- a/src/app/shared/ui/control/control.component.ts +++ b/src/app/shared/ui/control/control.component.ts @@ -1,5 +1,5 @@ -import { Component, input, ViewEncapsulation } from '@angular/core'; -// import { HostBinding, HostListener } from '@angular/core'; +import { Component, contentChild, ElementRef, input, ViewEncapsulation } from '@angular/core'; +// import { HostBinding, HostListener, ContentChild } from '@angular/core'; @Component({ selector: 'app-control', @@ -23,7 +23,11 @@ export class ControlComponent { title = input.required(); + // @ContentChild('inputEl') private control?: ElementRef; + private control = contentChild.required>('inputEl'); + logTheClick() { console.log('clicked!'); + console.log(this.control()); } }