line-gestao-frontend/src/app/pages/solicitacoes-linhas/solicitacoes-linhas.ts

187 lines
5.0 KiB
TypeScript

import { Component, OnDestroy, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { CustomSelectComponent } from '../../components/custom-select/custom-select';
import { SolicitacaoLinhaDto, SolicitacoesLinhasService } from '../../services/solicitacoes-linhas.service';
import {
buildPageNumbers,
clampPage,
computePageEnd,
computePageStart,
computeTotalPages
} from '../../utils/pagination.util';
@Component({
selector: 'app-solicitacoes-linhas',
standalone: true,
imports: [CommonModule, FormsModule, CustomSelectComponent],
templateUrl: './solicitacoes-linhas.html',
styleUrls: ['./solicitacoes-linhas.scss'],
})
export class SolicitacoesLinhas implements OnInit, OnDestroy {
items: SolicitacaoLinhaDto[] = [];
loading = false;
errorMsg = '';
page = 1;
pageSize = 20;
pageSizeOptions = [10, 20, 50, 100];
total = 0;
search = '';
private searchTimer: ReturnType<typeof setTimeout> | null = null;
constructor(private readonly solicitacoesService: SolicitacoesLinhasService) {}
ngOnInit(): void {
this.fetch(1);
}
ngOnDestroy(): void {
if (this.searchTimer) {
clearTimeout(this.searchTimer);
this.searchTimer = null;
}
}
refresh(): void {
this.fetch();
}
onSearchChange(): void {
if (this.searchTimer) {
clearTimeout(this.searchTimer);
}
this.searchTimer = setTimeout(() => {
this.page = 1;
this.fetch();
}, 300);
}
clearSearch(): void {
this.search = '';
this.page = 1;
this.fetch();
}
onPageSizeChange(): void {
this.page = 1;
this.fetch();
}
goToPage(pageNumber: number): void {
this.page = clampPage(pageNumber, this.totalPages);
this.fetch();
}
get totalPages(): number {
return computeTotalPages(this.total || 0, this.pageSize);
}
get pageNumbers(): number[] {
return buildPageNumbers(this.page, this.totalPages);
}
get pageStart(): number {
return computePageStart(this.total || 0, this.page, this.pageSize);
}
get pageEnd(): number {
return computePageEnd(this.total || 0, this.page, this.pageSize);
}
private parseDate(value?: string | null): Date | null {
if (!value) return null;
const d = new Date(value);
return Number.isNaN(d.getTime()) ? null : d;
}
formatDateTime(value?: string | null): string {
const d = this.parseDate(value);
if (!d) return '-';
return d.toLocaleString('pt-BR');
}
formatDate(value?: string | null): string {
const d = this.parseDate(value);
if (!d) return '-';
return d.toLocaleDateString('pt-BR');
}
formatTime(value?: string | null): string {
const d = this.parseDate(value);
if (!d) return '--:--';
return d.toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit' });
}
formatFranquiaValor(value?: number | null): string {
if (value === null || value === undefined) return '-';
return new Intl.NumberFormat('pt-BR', { maximumFractionDigits: 2 }).format(value);
}
formatFranquia(value?: number | null): string {
const formatted = this.formatFranquiaValor(value);
return formatted === '-' ? '-' : `${formatted} GB`;
}
tipoLabel(value?: string | null): string {
const v = (value ?? '').toString().trim().toUpperCase();
if (v === 'ALTERACAO_FRANQUIA') return 'Alteração de franquia';
if (v === 'BLOQUEIO') return 'Bloqueio';
return v || '-';
}
tipoBadgeClass(value?: string | null): string {
const v = (value ?? '').toString().trim().toUpperCase();
if (v === 'ALTERACAO_FRANQUIA') return 'type-badge type-badge--franquia';
if (v === 'BLOQUEIO') return 'type-badge type-badge--bloqueio';
return 'type-badge type-badge--default';
}
trackBySolicitacao(_: number, item: SolicitacaoLinhaDto): string {
return item.id;
}
descricao(item: SolicitacaoLinhaDto): string {
const tipo = (item.tipoSolicitacao ?? '').toString().trim().toUpperCase();
const linha = (item.linha ?? '').toString().trim();
if (tipo === 'ALTERACAO_FRANQUIA') {
return `Mudanca de franquia de ${this.formatFranquiaValor(item.franquiaLineAtual)} para ${this.formatFranquiaValor(item.franquiaLineNova)}`;
}
if (tipo === 'BLOQUEIO') {
return `Bloqueio da linha ${linha || '-'}`;
}
return (item.mensagem ?? '').toString().trim() || '-';
}
private fetch(goToPage?: number): void {
if (goToPage) this.page = goToPage;
this.loading = true;
this.errorMsg = '';
this.solicitacoesService
.list({
page: this.page,
pageSize: this.pageSize,
search: this.search?.trim() || undefined,
})
.subscribe({
next: (res) => {
this.items = res.items || [];
this.total = res.total || 0;
this.page = res.page || this.page;
this.pageSize = res.pageSize || this.pageSize;
this.loading = false;
},
error: () => {
this.loading = false;
this.errorMsg = 'Não foi possível carregar as solicitações.';
},
});
}
}