187 lines
5.0 KiB
TypeScript
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.';
|
|
},
|
|
});
|
|
}
|
|
}
|