Skip to content

Commit

Permalink
Merge pull request #4 from actionanand/2-features
Browse files Browse the repository at this point in the history
2 features
  • Loading branch information
actionanand authored Sep 20, 2024
2 parents 1697fe6 + bed91b0 commit be8e280
Show file tree
Hide file tree
Showing 10 changed files with 222 additions and 14 deletions.
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -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',
Expand All @@ -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<typeof setInterval>;

destroyRef = inject(DestroyRef);

currentStatus: 'online' | 'offline' | 'unkown' = 'online';

constructor() {}

ngOnInit() {
setInterval(() => {
const interval = setInterval(() => {
const rnd = Math.random();

if (rnd < 0.5) {
Expand All @@ -24,5 +30,9 @@ export class ServerStatusComponent implements OnInit {
this.currentStatus = 'unkown';
}
}, 5000);

this.destroyRef.onDestroy(() => {
clearInterval(interval);
});
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<form>
<form (ngSubmit)="onSubmit(titleInput.value, textInput.value)" #form>
<app-control title="Title">
<input name="title" id="title" />
<input name="title" id="title" #titleInput #inputEl />
</app-control>
<app-control title="Request">
<textarea name="request" id="request" rows="3"></textarea>
<textarea name="request" id="request" rows="3" #textInput #inputEl></textarea>
</app-control>
<p>
<button appButton>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
import { Component } from '@angular/core';
import { Component, ElementRef, EventEmitter, Output, viewChild } from '@angular/core';
import { FormsModule } from '@angular/forms';
// import { ViewChild } from '@angular/core';

import { ButtonComponent } from '../../../../shared/ui/button/button.component';
import { ControlComponent } from '../../../../shared/ui/control/control.component';

@Component({
selector: 'app-new-ticket',
standalone: true,
imports: [ButtonComponent, ControlComponent],
imports: [ButtonComponent, ControlComponent, FormsModule],
templateUrl: './new-ticket.component.html',
styleUrl: './new-ticket.component.scss',
})
export class NewTicketComponent {}
export class NewTicketComponent {
// @ViewChild('form') private form?: ElementRef<HTMLFormElement>;
private form = viewChild.required<ElementRef<HTMLFormElement>>('form');
@Output() addTicket = new EventEmitter<{ title: string; text: string }>();

onSubmit(title: string, text: string) {
console.log(this.form());
this.form()?.nativeElement.reset();

this.addTicket.emit({ title, text });
}
}
Original file line number Diff line number Diff line change
@@ -1 +1,40 @@
<p>ticket works!</p>
<article>
<h3>
<div
[class]="{
'ticket-open': true,
'ticket-closed': false,
}"></div>
<button>
<span class="text">TITLE</span>
<span>
@if (true) {
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
</svg>
} @else {
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6">
<path
fill-rule="evenodd"
d="M11.47 7.72a.75.75 0 0 1 1.06 0l7.5 7.5a.75.75 0 1 1-1.06 1.06L12 9.31l-6.97 6.97a.75.75 0 0 1-1.06-1.06l7.5-7.5Z"
clip-rule="evenodd" />
</svg>
}
</span>
</button>
</h3>

@if (true) {
<p>TEXT</p>

@if (true) {
<p><button>Mark as completed</button></p>
}
}
</article>
73 changes: 73 additions & 0 deletions src/app/components/dashboard/tickets/ticket/ticket.component.scss
Original file line number Diff line number Diff line change
@@ -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;
}
14 changes: 13 additions & 1 deletion src/app/components/dashboard/tickets/tickets.component.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
<div>
<ul>
@for (ticket of tickets; track ticket.id) {
<li>
<app-ticket />
</li>
} @empty {
<p>No Tickets Available!</p>
}
</ul>
</div>

<div id="new-ticket">
<app-new-ticket />
<app-new-ticket (addTicket)="onAddTicket($event)" />
</div>
19 changes: 17 additions & 2 deletions src/app/components/dashboard/tickets/tickets.component.ts
Original file line number Diff line number Diff line change
@@ -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);
}
}
20 changes: 20 additions & 0 deletions src/app/models/ticket.model.ts
Original file line number Diff line number Diff line change
@@ -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',
}
8 changes: 6 additions & 2 deletions src/app/shared/ui/control/control.component.ts
Original file line number Diff line number Diff line change
@@ -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',
Expand All @@ -23,7 +23,11 @@ export class ControlComponent {

title = input.required<string>();

// @ContentChild('inputEl') private control?: ElementRef<HTMLInputElement | HTMLTextAreaElement>;
private control = contentChild.required<ElementRef<HTMLInputElement | HTMLTextAreaElement>>('inputEl');

logTheClick() {
console.log('clicked!');
console.log(this.control());
}
}

0 comments on commit be8e280

Please sign in to comment.