ReportTable — Tabela de Relatórios com variante Pivot
ReportTable é um componente de tabela para relatórios do Vona. Suporta duas variantes — standard (tabela simples com colunas fixas) e pivot (tabela dinâmica com grupos de colunas por data ou fabricante) — com ordenação interativa por coluna, expansão hierárquica de linhas e botão de exportação.
Importação
import { ReportTable } from '@kit/ui/report-table';
Variante Standard
Exibe linhas com colunas fixas definidas explicitamente. Suporta ordenação por qualquer coluna marcada como sortable, e expansão de linhas filhas via depth e expandable.
import type { ReportColumn, ReportRow } from '@kit/ui/report-table';
const columns: ReportColumn[] = [
{ key: 'nome', label: 'Nome', minWidth: 120 },
{ key: 'volume', label: 'Volume', align: 'right', sortable: true, minWidth: 80 },
{ key: 'pct', label: '%', align: 'right', minWidth: 60 },
];
const rows: ReportRow[] = [
{ id: 'row_1', label: 'Toyota', cells: { volume: '1.234', pct: '22,1%' } },
{ id: 'row_2', label: 'Volkswagen', cells: { volume: '987', pct: '17,6%' }, isTotal: false },
{ id: 'total', label: 'TOTAL', cells: { volume: '5.580', pct: '100%' }, isTotal: true },
];
<ReportTable
title="Ranking de Marcas"
columns={columns}
rows={rows}
/>
Variante Pivot
Exibe grupos de colunas (cada grupo com sub-colunas Vol e %) organizados por data ou fabricante. As linhas podem ter hierarquia de dois níveis (área → concessionária).
import type { PivotCard } from '@kit/ui/report-table';
const card: PivotCard = {
id: 'ranking-marcas',
title: 'Ranking Anual por Marcas',
rowHeader: 'Fabricante',
rowHeaderSortable: true,
defaultSortKey: 'vol_acum_ano',
defaultSortDir: 'desc',
columnGroups: [
{
date: 'acum-ano',
label: 'Acum. Ano',
subLabel: '2025',
isCurrentDay: false,
volKey: 'vol_acum_ano',
pctKey: 'pct_acum_ano',
sortable: true,
},
],
rows: [
{
id: 'brand_toyota',
label: '1. Toyota',
depth: 0,
expandable: false,
isTotal: false,
cells: { vol_acum_ano: 12340, pct_acum_ano: '22,1' },
},
{
id: 'total',
label: 'TOTAL',
depth: 0,
expandable: false,
isTotal: true,
cells: { vol_acum_ano: 55800, pct_acum_ano: '100,0' },
},
],
};
<ReportTable variant="pivot" card={card} />
Props
Props comuns
| Prop | Tipo | Padrão | Descrição |
|---|---|---|---|
title | string | — | Título exibido no cabeçalho do card |
exportOptions | ReportExportOption[] | [] | Botão de exportação (ver abaixo) |
hasActiveFilters | boolean | false | Altera a mensagem de estado vazio |
isLoading | boolean | false | Exibe skeleton de carregamento |
className | string | — | Classe CSS adicional no container |
Props da variante standard
| Prop | Tipo | Descrição |
|---|---|---|
columns | ReportColumn[] | Definição das colunas |
rows | ReportRow[] | Linhas da tabela |
Props da variante pivot
| Prop | Tipo | Descrição |
|---|---|---|
card | PivotCard | Configuração completa da tabela pivot |
Tipos principais
ReportColumn
interface ReportColumn {
key: string;
label: string;
subLabel?: string; // Rótulo secundário abaixo do label
align?: 'left' | 'right' | 'center';
sortable?: boolean; // Habilita clique para ordenar
minWidth?: number; // Largura mínima em px (padrão: 80)
}
ReportRow
interface ReportRow {
id: string;
label: string; // Exibido na 1ª coluna fixa
depth?: number; // 0 = raiz, 1 = filho (indentation de 16px por nível)
expandable?: boolean; // Exibe chevron para expandir/recolher filhos
cells: Record<string, React.ReactNode>;
isTotal?: boolean; // Fixa no rodapé com bg diferenciado
isHighlighted?: boolean; // Aplica bg azul claro (destaque)
}
PivotCard
interface PivotCard {
id: string;
title: string;
subtitle?: string; // Rótulo da 2ª linha de cabeçalho
rowHeader?: string; // Label da 1ª coluna (padrão: "Áreas de influência")
columnGroups: PivotColumnGroup[];
rows: PivotRow[];
rowHeaderSortable?: boolean; // Habilita ordenação pela coluna de rótulo
defaultSortKey?: string; // volKey inicial ou '__label__' para ordenar por rótulo
defaultSortDir?: 'asc' | 'desc'; // Direção inicial (padrão: 'desc')
}
PivotColumnGroup
interface PivotColumnGroup {
date: string; // Identificador único do grupo (pode ser data ISO ou string)
label: string; // Rótulo exibido no cabeçalho (ex: "Acum. Ano")
subLabel: string; // Sub-rótulo (ex: "2025" ou "(1º dia útil)")
isCurrentDay: boolean; // Aplica ring de destaque visual no cabeçalho
volKey: string; // Chave para o valor de volume nas células da linha
pctKey: string; // Chave para o valor de percentual nas células da linha
sortable?: boolean; // Habilita clique para ordenar pela sub-coluna Vol
}
Ordenação
Standard
Qualquer ReportColumn com sortable: true pode ser ordenada. Ao clicar no cabeçalho, alterna entre ascendente → descendente → sem ordenação. Linhas isTotal são sempre fixadas no rodapé, independentemente da ordenação.
Pivot
- Por coluna de dados:
PivotColumnGroup.sortable = truehabilita clique no sub-cabeçalhoVol. - Por rótulo:
PivotCard.rowHeaderSortable = truehabilita clique na 1ª coluna fixa. UsadefaultSortKey: '__label__'. - Ordenação inicial: use
defaultSortKey(volKey de um grupo) edefaultSortDirpara controlar o estado inicial sem interação do usuário.
// Ordenar por volume acumulado descendente ao abrir
const card: PivotCard = {
defaultSortKey: 'vol_acum_ano',
defaultSortDir: 'desc',
...
};
Estado vazio
ReportEmptyState é exibido automaticamente quando não há linhas. O texto varia conforme hasActiveFilters:
- Com filtros ativos: "Nenhum dado para os filtros aplicados"
- Sem filtros: "Nenhum dado disponível para {title}"
// Também pode ser usado de forma independente
import { ReportEmptyState } from '@kit/ui/report-table';
<ReportEmptyState reportName="Ranking de Marcas" hasActiveFilters={true} />
Exportação
const exportOptions: ReportExportOption[] = [
{
format: 'xlsx',
label: 'Excel',
onExport: () => downloadExcel(data),
},
];
<ReportTable exportOptions={exportOptions} ... />
Com uma opção, exibe botão "Exportar". Com múltiplas opções, exibe botão + dropdown.