import { ChangeDetectionStrategy, Component, inject, signal } from '@angular/core'; import { DatePipe } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { MatIconModule } from '@angular/material/icon'; import { JtGridBulkEvent, JtGridBulkService, JtGridCellDirective, JtGridColumn, JtGridComponent, JtGridRowEvent, RowAction } from '@jambotron/aria-grid'; import { ApiService } from '../../core/api.service'; import { BlacklistEntry, errorText } from '../../core/models'; import { ToastService } from '../../ui/toast.service'; /** Blocked senders: their mail goes straight to Spam. */ @Component({ selector: 'app-blocked', imports: [DatePipe, FormsModule, MatIconModule, JtGridComponent, JtGridCellDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: `
block

BLOCKED SENDERS

Messages from these addresses go straight to Spam

{{ row.senderEmail }} {{ row.reason || '' }} {{ row.createdAt | date: 'd MMM y, HH:mm' }}
` }) export class BlockedPage { private api = inject(ApiService); private bulk = inject(JtGridBulkService); private toasts = inject(ToastService); readonly entries = signal([]); readonly loading = signal(true); email = ''; reason = ''; readonly columns: JtGridColumn[] = [ { key: 'sender', label: 'Sender', sort: e => e.senderEmail }, { key: 'reason', label: 'Reason', sort: e => e.reason || '' }, { key: 'date', label: 'Blocked', sort: e => e.createdAt || '', align: 'end' } ]; readonly bulkActions: RowAction[] = [{ value: 'unblock', label: 'Unblock', icon: 'lock_open' }]; readonly rowActions = (): RowAction[] => [{ value: 'unblock', label: 'Unblock', icon: 'lock_open', inline: true }]; readonly bySender = (e: BlacklistEntry) => e.senderEmail; readonly senderOf = (e: BlacklistEntry) => e.senderEmail; constructor() { this.load(); } load(): void { this.api.blacklist().subscribe({ next: list => { this.entries.set(list); this.loading.set(false); }, error: e => { this.loading.set(false); this.toasts.error(errorText(e)); } }); } add(): void { const email = this.email.trim().toLowerCase(); if (!/^[^@\s]+@[^@\s]+$/.test(email)) { this.toasts.error('Enter a valid sender address'); return; } this.api.block(email, this.reason.trim()).subscribe({ next: () => { this.toasts.ok(`${email} blocked`); this.email = ''; this.reason = ''; this.load(); }, error: e => this.toasts.error(errorText(e)) }); } onRow(e: JtGridRowEvent): void { this.api.unblock(e.row.senderEmail).subscribe({ next: () => { this.toasts.ok(`${e.row.senderEmail} unblocked`); this.load(); }, error: err => this.toasts.error(errorText(err)) }); } onBulk(e: JtGridBulkEvent): void { this.bulk.run({ rows: e.rows, label: 'Unblock', run: x => this.api.unblock(x.senderEmail) }).subscribe(() => this.load()); } }