import { ChangeDetectionStrategy, Component, DestroyRef, effect, inject, signal, untracked, } from '@angular/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { RouterLink } from '@angular/router'; import { PiActionButtonComponent, PiEmptyStateComponent } from '@pi/ui'; import { ToastService } from '@task-stream/web/shared/ui'; import { ProjectFacade } from '@task-stream/web/tracker/application'; import { IssueSummary, IssuesGateway } from '@task-stream/web/tracker/domain'; import { timeAgo } from '../ui/copy'; /** /p/:key/trash — tickets deleted in the last 30 days, to bring back. */ @Component({ selector: 'ts-trash-page', changeDetection: ChangeDetectionStrategy.OnPush, imports: [RouterLink, PiActionButtonComponent, PiEmptyStateComponent], template: `

Tickets borrados en los últimos 30 días. Después se borran del todo, con sus comentarios.

@if (issues().length) { } @else if (loaded()) { } `, styles: ` .ts-trash { margin: 0; padding: 0.25rem 0; list-style: none; } .ts-trash__row { display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; gap: 0.75rem; align-items: center; padding: 0.5rem 0.875rem; border-top: 1px solid var(--ts-line); &:first-child { border-top: 0; } } .ts-trash__title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } `, }) export class TrashPage { protected readonly project = inject(ProjectFacade); private readonly gateway = inject(IssuesGateway); private readonly toast = inject(ToastService); private readonly destroyRef = inject(DestroyRef); protected readonly issues = signal([]); protected readonly loaded = signal(false); protected readonly ago = timeAgo; constructor() { effect(() => { const projectId = this.project.project()?.id; if (projectId) untracked(() => this.reload(projectId)); }); } protected restore(issue: IssueSummary): void { this.gateway .restore(issue.id) .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe({ next: () => { this.toast.success(`${issue.key} recuperado`); this.issues.update((list) => list.filter((i) => i.id !== issue.id)); }, error: (error) => this.toast.error( (error as { message?: string })?.message?.split('\n')[0] || 'No se pudo recuperar', ), }); } private reload(projectId: string): void { this.gateway .trashed(projectId) .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe({ next: (issues) => { this.issues.set(issues); this.loaded.set(true); }, error: () => this.loaded.set(true), }); } }