Pular para o conteúdo principal

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

PropTipoPadrãoDescrição
titlestringTítulo exibido no cabeçalho do card
exportOptionsReportExportOption[][]Botão de exportação (ver abaixo)
hasActiveFiltersbooleanfalseAltera a mensagem de estado vazio
isLoadingbooleanfalseExibe skeleton de carregamento
classNamestringClasse CSS adicional no container

Props da variante standard

PropTipoDescrição
columnsReportColumn[]Definição das colunas
rowsReportRow[]Linhas da tabela

Props da variante pivot

PropTipoDescrição
cardPivotCardConfiguraçã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 = true habilita clique no sub-cabeçalho Vol.
  • Por rótulo: PivotCard.rowHeaderSortable = true habilita clique na 1ª coluna fixa. Usa defaultSortKey: '__label__'.
  • Ordenação inicial: use defaultSortKey (volKey de um grupo) e defaultSortDir para 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.