Exemplos de Praxis Table
O percurso começa em resourcePath e avança para colunas, renderers, filtros, ações, expansion e authoring. Cada exemplo aproxima a demonstração, o contrato principal e a superfície de dados usada pela tabela.
Os previews ao vivo da página Angular requerem JavaScript; esta projeção publica os exemplos e o código fonte estáticos.
1. Uma tabela remota completa com uma tag
Declare um tableId estável e aponte para um resourcePath publicado pela API. A tabela resolve schema, dados reais, paginação e affordances de customização sem copiar colunas no template Angular.
O que você vê: Funcionários aparecem com o mesmo shape do recurso remoto: colunas vindas do contrato, registros paginados e nenhuma coluna declarada no Angular do host.
Modo: quickstart
Preview ao vivo: requer JavaScript para materializar a tabela Angular.
Endpoints: POST /api/human-resources/funcionarios/filter GET /schemas/filtered?path=/api/human-resources/funcionarios/filter&operation=post&schemaType=response
Arquivos
example.html(html)example.ts(ts)schema.http(http)
example.html
<praxis-table
tableId="employees-table"
resourcePath="human-resources/funcionarios"
[enableCustomization]="true"
></praxis-table>Aprenda neste exemplo
- O contrato mínimo é intencional: tableId identifica a instância; resourcePath conecta a tabela ao recurso remoto.
- /schemas/filtered descreve os campos da resposta usada pela tabela para iniciar colunas, rótulos e tipos.
- /filter entrega os registros paginados e preserva o backend como fonte de verdade para consulta.
- Com enableCustomization ativo, o runtime exibe as affordances de editor; sem ele, a tabela continua operacional em modo leitura.
2. Primeira customização por JSON
Depois da primeira tag, entra o primeiro TableConfig: um JSON pequeno que escolhe colunas, rótulos, renderers e densidade sem transformar a tela em código de grid.
O que você vê: O JSON pega a grade do recurso de funcionários e reduz a leitura: remove campos secundários, reordena as colunas principais, encurta rótulos e transforma o booleano ativo em badge de status.
Modo: quickstart
Preview ao vivo: requer JavaScript para materializar a tabela Angular.
Endpoints: POST /api/human-resources/funcionarios/filter GET /schemas/filtered?path=/api/human-resources/funcionarios/filter&operation=post&schemaType=response
Arquivos
table.config.json(json)example.html(html)schema.http(http)
table.config.json
{
"columns": [
{
"field": "avatarUrl",
"header": "Foto",
"width": "84px",
"align": "center",
"renderer": {
"type": "avatar",
"avatar": {
"srcField": "avatarUrl",
"initialsField": "nomeCompleto",
"shape": "circle",
"size": 32
}
}
},
{ "field": "nomeCompleto", "header": "Funcionário", "width": "220px" },
{ "field": "cargoNome", "header": "Cargo", "width": "240px" },
{ "field": "departamentoNome", "header": "Departamento", "width": "220px" },
{
"field": "ativo",
"header": "Status",
"renderer": {
"type": "badge",
"badge": { "textField": "ativo", "color": "primary" }
}
},
{ "field": "dataAdmissao", "header": "Admissão", "type": "date" }
],
"toolbar": {
"visible": true,
"position": "top",
"title": "Funcionários",
"subtitle": "Schema remoto refinado por TableConfig",
"appearance": {
"variant": "outlined",
"density": "comfortable",
"divider": "start"
},
"columnsVisibility": { "enabled": true }
},
"behavior": {
"pagination": {
"enabled": true,
"pageSize": 8,
"pageSizeOptions": [8, 10, 25, 50],
"showFirstLastButtons": true,
"showPageNumbers": true,
"showPageInfo": true,
"position": "bottom",
"style": "default",
"strategy": "client"
},
"sorting": {
"enabled": true,
"multiSort": false,
"strategy": "client",
"showSortIndicators": true,
"indicatorPosition": "end",
"allowClearSort": true
}
},
"appearance": { "density": "comfortable" }
}Aprenda neste exemplo
- A tag da página continua enxuta: [config]="employeeTableConfig" aponta para um documento declarativo.
- O desenvolvedor pode versionar esse JSON ou permitir que o editor publique variações por perfil, tenant ou ambiente.
- A configuração não duplica o DTO; ela seleciona e refina campos que o contrato remoto já conhece.
3. Modo local com pipeline completo
O modo local mostra o mesmo pipeline com dados em memória. Ele existe para protótipos, demos isoladas e testes visuais, sempre com localDataMode explícito.
O que você vê: Dados locais passam pelo pipeline oficial de colunas, paginação, sorting, renderização e ações por linha.
Modo: local
Preview ao vivo: requer JavaScript para materializar a tabela Angular.
Endpoints: Sem endpoint obrigatório: usa [data] + behavior.localDataMode.enabled = true.
Arquivos
example.html(html)example.ts(ts)table.config.json(json)
table.config.json
{
"behavior": {
"localDataMode": { "enabled": true },
"pagination": { "enabled": true, "pageSize": 10 },
"sorting": { "enabled": true }
},
"columns": [
{ "field": "nomeCompleto", "header": "Nome" },
{ "field": "cargoNome", "header": "Cargo" },
{ "field": "ativo", "header": "Status", "renderer": { "type": "badge" } }
],
"actions": {
"row": {
"enabled": true,
"display": "icons",
"trigger": "always",
"actions": [
{ "id": "profile", "label": "Perfil", "action": "profile" },
{
"id": "reactivate",
"label": "Reativar",
"action": "reactivate",
"tooltip": "Coletar motivo e confirmar reativação",
"visibleWhen": { "===": [{ "var": "ativo" }, false] }
},
{
"id": "audit",
"label": "Auditar",
"action": "audit",
"visibleWhen": { "===": [{ "var": "ativo" }, true] }
}
]
}
}
}Aprenda neste exemplo
- Modo local não é atalho para fugir do contrato; é uma fonte de dados explícita.
- O mesmo preview pode provar renderers, densidade, paginação, ordenação e ações de linha sem backend.
- visibleWhen usa JSON Logic para trocar Reativar por Auditar conforme o estado de cada funcionário.
- Quando existir API publicada, resourcePath continua sendo o caminho preferencial.
4. Colunas, tipos e formatação
Tipos, formatos, cálculos, regras visuais e animações ficam no contrato da coluna e da linha. A tabela transforma dados financeiros em leitura operacional sem pipes ou ifs espalhados no template.
O que você vê: Folhas de pagamento exibem moeda, percentual, data, compose, progress, computed, badge condicional, destaque de célula, destaque de linha e animação discreta para risco.
Modo: quickstart
Preview ao vivo: requer JavaScript para materializar a tabela Angular.
Endpoints: POST /api/human-resources/folhas-pagamento/filter GET /schemas/filtered?path=/api/human-resources/folhas-pagamento/filter&operation=post&schemaType=response
Arquivos
table.config.json(json)example.html(html)localization.json(json)
table.config.json
{
"appearance": {
"density": "compact",
"animations": {
"enabled": true,
"duration": 800,
"easing": "ease-in-out",
"specific": { "row": true, "cell": true }
}
},
"localization": {
"locale": "pt-BR",
"direction": "ltr",
"currency": { "code": "BRL", "symbol": "R$", "position": "before", "spacing": true, "precision": 2 }
},
"behavior": {
"pagination": { "enabled": true, "pageSize": 5 },
"sorting": { "enabled": true }
},
"columns": [
{
"field": "colaborador",
"header": "Colaborador",
"renderer": {
"type": "compose",
"compose": {
"layout": { "direction": "row", "gap": 8, "align": "center", "wrap": true },
"items": [
{ "type": "avatar", "avatar": { "initialsField": "colaborador", "shape": "circle", "size": 32 } },
{ "type": "value", "field": "colaborador" },
{ "type": "chip", "chip": { "textField": "centroCusto", "variant": "soft" } }
]
}
}
},
{ "field": "salarioBase", "header": "Salário", "type": "currency", "format": "BRL|symbol|2" },
{ "field": "bonus", "header": "Bônus", "type": "currency", "format": "BRL|symbol|2" },
{ "field": "desconto", "header": "Desconto", "type": "percentage", "format": "1.1-1|x100" },
{
"field": "liquido",
"header": "Líquido calculado",
"type": "currency",
"format": "BRL|symbol|2",
"computed": {
"expression": { "-": [{ "+": [{ "var": "salarioBase" }, { "var": "bonus" }] }, { "var": "descontoValor" }] },
"outputType": "number",
"dependencies": ["salarioBase", "bonus", "descontoValor"]
}
},
{
"field": "riscoFolha",
"header": "Risco",
"renderer": { "type": "progress", "progress": { "valueExpr": "= riscoFolha", "showLabel": true } },
"conditionalStyles": [
{ "condition": { ">=": [{ "var": "riscoFolha" }, 80] }, "cssClass": "row--warning" }
],
"conditionalRenderers": [
{
"condition": { ">=": [{ "var": "riscoFolha" }, 90] },
"animation": { "preset": "warning-attention", "trigger": "onAppear", "repeat": 3 }
}
]
},
{
"field": "status",
"header": "Status",
"renderer": { "type": "badge", "badge": { "textField": "status", "variant": "soft" } },
"conditionalRenderers": [
{
"condition": { "===": [{ "var": "status" }, "Aprovada"] },
"renderer": { "type": "badge", "badge": { "text": "Aprovada", "color": "success", "variant": "soft", "icon": "check_circle" } }
},
{
"condition": { "===": [{ "var": "status" }, "Revisar"] },
"renderer": { "type": "badge", "badge": { "text": "Revisar", "color": "warn", "variant": "soft", "icon": "priority_high" } },
"animation": { "preset": "pulse-soft", "trigger": "onAppear", "repeat": "once" }
}
]
},
{ "field": "dataPagamento", "header": "Pagamento", "type": "date", "format": "dd/MM/yyyy" }
],
"rowConditionalStyles": [
{ "condition": { "===": [{ "var": "status" }, "Bloqueada"] }, "cssClass": "row--danger" },
{ "condition": { ">=": [{ "var": "riscoFolha" }, 80] }, "cssClass": "row--warning" }
],
"rowConditionalRenderers": [
{
"condition": { "===": [{ "var": "status" }, "Bloqueada"] },
"tooltip": { "text": "Folha bloqueada para auditoria antes do pagamento." },
"animation": { "preset": "risk-critical", "trigger": "onAppear", "intensity": "subtle", "repeat": "once" }
}
]
}5. Catálogo de renderers ricos
Renderers transformam valores em representação visual. Avatar, badge, chip, icon, image, progress e compose entram no mesmo contrato que define as colunas.
O que você vê: Um perfil operacional com identidade visual, status e indicadores renderizados sem template customizado.
Modo: quickstart
Preview ao vivo: requer JavaScript para materializar a tabela Angular.
Endpoints: POST /api/human-resources/vw-perfil-heroi/filter GET /schemas/filtered?path=/api/human-resources/vw-perfil-heroi/filter&operation=post&schemaType=response
Arquivos
table.config.json(json)renderer.catalog.json(json)example.html(html)
table.config.json
{
"columns": [
{
"field": "nome",
"header": "Pessoa",
"renderer": {
"type": "avatar",
"avatar": { "srcField": "fotoUrl", "initialsField": "nome", "shape": "circle", "size": 32 }
}
},
{
"field": "status",
"header": "Status",
"renderer": { "type": "badge", "badge": { "textField": "status", "color": "primary" } }
}
]
}Aprenda neste exemplo
- Renderers ricos reduzem templates customizados por coluna.
- O editor pode trocar apresentação sem alterar datasource ou componente host.
- Cada renderer preserva semântica de campo, formato e fallback no contrato.
6. Micro-layout CRM com compose
Compose junta avatar, nome, função, status e sinais operacionais em uma célula densa. A composição continua declarativa e editável.
O que você vê: Uma linha compacta carrega identidade, status e sinais visuais sem criar componente de célula específico.
Modo: quickstart
Preview ao vivo: requer JavaScript para materializar a tabela Angular.
Endpoints: POST /api/human-resources/vw-perfil-heroi/filter GET /schemas/filtered?path=/api/human-resources/vw-perfil-heroi/filter&operation=post&schemaType=response
Arquivos
table.config.json(json)example.html(html)editor.patch.json(json)
table.config.json
{
"columns": [
{
"field": "perfil",
"header": "Perfil",
"renderer": {
"type": "compose",
"compose": {
"layout": { "direction": "row", "gap": 8, "wrap": false },
"items": [
{ "type": "avatar", "avatar": { "srcField": "fotoUrl", "initialsField": "nome" } },
{ "type": "badge", "badge": { "textField": "status", "color": "primary" } },
{ "type": "chip", "chip": { "textField": "categoria" } }
]
}
}
}
]
}Aprenda neste exemplo
- Compose é ideal para listas operacionais com identidade, cargo, status e sinais curtos.
- A célula fica rica sem acoplar a tela a um componente de domínio.
- O host muda composição, campo e layout sem redeploy quando a configuração é governada.
7. Superfícies ricas enterprise
Microvisualizações aparecem em células normais, a expansão abre contexto governado e um formulário em modo apresentação mostra o detalhe selecionado.
O que você vê: Uma operação densa com SLA, tendência, execução, delta, fluxo e risco em pequenos gráficos, além de detail row e formulário de leitura.
Modo: local
Preview ao vivo: requer JavaScript para materializar a tabela Angular.
Endpoints: Contrato local: TableConfig.columns[].renderer.microVisualization Contrato local: behavior.expansion.detail.source.mode=inline Contrato local: FormConfig + presentationModeGlobal
Arquivos
table.config.json(json)detail-form.config.json(json)example.html(html)
table.config.json
{
"columns": [
{
"field": "slaValue",
"header": "SLA",
"renderer": {
"type": "microVisualization",
"microVisualization": {
"visualization": {
"kind": "bullet",
"surface": "table-cell",
"valueExpr": "row.slaValue",
"targetExpr": "row.target",
"fallbackTextExpr": { "cat": ["SLA ", { "var": "row.slaValue" }, "%"] }
}
}
}
}
],
"behavior": {
"localDataMode": { "enabled": true },
"expansion": {
"enabled": true,
"detail": {
"schemaContract": {
"kind": "praxis.detail.schema",
"allowedNodes": ["card", "list", "timeline", "chartRef", "actionBar"]
},
"source": { "mode": "inline" }
}
}
},
"detailNode": {
"type": "chartRef",
"renderMode": "inline",
"schemaId": "operation-risk-trend",
"chartDocumentRef": "charts/operation-risk-trend",
"emptyText": "Fallback: abrir o chart no cockpit do host."
}
}Aprenda neste exemplo
- Células normais podem carregar pequenos gráficos sem EChartsOption na coluna.
- A expansão adiciona contexto sem virar HTML livre dentro da tabela.
- O formulário em apresentação materializa o mesmo registro como detalhe governado.
8. Avatar e status operacional
Avatar cobre identidade com fallback: imagem quando existir, iniciais quando faltar foto, tamanho, shape e cores controlados pela configuração.
O que você vê: A prévia compara foto circular, iniciais arredondadas coloridas, avatar compacto e status operacional sem código de template por coluna.
Modo: quickstart
Preview ao vivo: requer JavaScript para materializar a tabela Angular.
Endpoints: POST /api/human-resources/funcionarios/filter GET /schemas/filtered?path=/api/human-resources/funcionarios/filter&operation=post&schemaType=response
Arquivos
table.config.json(json)example.html(html)editor.patch.json(json)
table.config.json
{
"columns": [
{
"field": "fotoUrl",
"header": "Foto circular",
"renderer": {
"type": "avatar",
"avatar": { "srcField": "fotoUrl", "initialsField": "nome", "shape": "circle", "size": 44 }
}
},
{
"field": "avatarIniciais",
"header": "Iniciais coloridas",
"renderer": {
"type": "avatar",
"avatar": {
"initialsField": "nome",
"shape": "rounded",
"size": 36,
"backgroundColor": "#2563eb",
"textColor": "#eff6ff"
}
}
}
]
}Aprenda neste exemplo
- Avatar não precisa ser uma coluna de imagem manual.
- Status e identidade podem conviver na mesma tabela com renderers declarativos.
- O exemplo compara variações para mostrar que tamanho, forma e cor são authoráveis.
8. Colunas calculadas
Colunas calculadas derivam leituras a partir dos dados recebidos. O exemplo mostra saldo aberto sem duplicar expressao no template Angular.
O que você vê: Indicadores de risco calculam saldo aberto a partir de indenizações e total pago.
Modo: quickstart
Preview ao vivo: requer JavaScript para materializar a tabela Angular.
Endpoints: POST /api/risk-intelligence/vw-indicadores-incidentes/filter GET /schemas/filtered?path=/api/risk-intelligence/vw-indicadores-incidentes/filter&operation=post&schemaType=response
Arquivos
table.config.json(json)computed.notes.md(md)example.html(html)
table.config.json
{
"columns": [
{ "field": "totalIndenizacoes", "header": "Indenizações", "type": "currency", "format": "BRL|symbol|2" },
{ "field": "totalPago", "header": "Pago", "type": "currency", "format": "BRL|symbol|2" },
{
"field": "saldoAberto",
"header": "Saldo aberto",
"type": "currency",
"format": "BRL|symbol|2",
"computed": {
"expression": "totalIndenizacoes - totalPago",
"outputType": "number",
"dependencies": ["totalIndenizacoes", "totalPago"]
}
}
]
}Aprenda neste exemplo
- Coluna calculada evita duplicar expressão no template Angular.
- O cálculo fica auditável dentro do TableConfig.
- A mesma coluna derivada pode aparecer como valor, badge, progress ou regra visual.
9. Dashboard financeiro
Uma visão de risco pode virar cockpit financeiro quando valores, saldo aberto, severidade e destaque visual ficam juntos na configuração da tabela.
O que você vê: A mesma superfície combina schema remoto, computed fields, progress, renderer condicional, formato monetário, estilo por célula e animação de linha.
Modo: quickstart
Preview ao vivo: requer JavaScript para materializar a tabela Angular.
Endpoints: POST /api/risk-intelligence/vw-indicadores-incidentes/filter POST /api/risk-intelligence/vw-indicadores-incidentes/filter/cursor GET /schemas/filtered?path=/api/risk-intelligence/vw-indicadores-incidentes/filter&operation=post&schemaType=response
Arquivos
table.config.json(json)example.html(html)styling.css(css)
table.config.json
{
"appearance": {
"density": "compact",
"animations": { "enabled": true, "specific": { "row": true, "cell": true } }
},
"columns": [
{
"field": "saldoAberto",
"header": "Saldo aberto",
"type": "currency",
"format": "BRL|symbol|2",
"computed": {
"expression": { "-": [{ "var": "totalIndenizacoes" }, { "var": "totalPago" }] },
"outputType": "number",
"dependencies": ["totalIndenizacoes", "totalPago"]
},
"conditionalStyles": [
{
"condition": { ">": [{ "var": "computed.saldoAberto" }, 100000] },
"style": { "background": "rgba(248, 113, 113, 0.16)", "color": "#fecaca" },
"tooltip": { "text": "Saldo aberto relevante para acompanhamento financeiro." }
}
]
},
{
"field": "probabilidade",
"header": "Probabilidade",
"renderer": {
"type": "progress",
"progress": { "valueExpr": "= probabilidade * 100", "showLabel": true }
}
},
{
"field": "severidade",
"header": "Severidade",
"renderer": { "type": "badge", "badge": { "textField": "severidade", "variant": "soft" } },
"conditionalRenderers": [
{
"condition": { "===": [{ "var": "severidade" }, "CRITICA"] },
"renderer": { "type": "badge", "badge": { "text": "CRÍTICA", "color": "warn", "variant": "soft", "icon": "priority_high" } }
}
]
}
],
"rowConditionalStyles": [
{ "condition": { "===": [{ "var": "severidade" }, "CRITICA"] }, "cssClass": "row--danger" }
],
"rowConditionalRenderers": [
{
"condition": { "===": [{ "var": "severidade" }, "CRITICA"] },
"animation": { "preset": "risk-critical", "trigger": "onAppear", "intensity": "subtle", "repeat": "once" }
}
]
}Aprenda neste exemplo
- A mesma tabela pode evoluir de grade para cockpit sem trocar componente.
- Financeiro, risco e operação podem compartilhar a mesma linguagem de renderização.
- O contrato reúne apresentação, cálculo e alerta visual de forma versionável.
10. Formatação condicional com JSON Logic
Condições visuais ficam declarativas. JSON Logic permite destacar linhas e células por score, risco ou faixa de valor sem ifs no template.
O que você vê: Ranking de reputação destaca registros fortes ou críticos por score, sem espalhar if no template.
Modo: quickstart
Preview ao vivo: requer JavaScript para materializar a tabela Angular.
Endpoints: POST /api/human-resources/vw-ranking-reputacao/filter GET /schemas/filtered?path=/api/human-resources/vw-ranking-reputacao/filter&operation=post&schemaType=response
Arquivos
rules.json(json)table.config.json(json)example.html(html)
rules.json
{
"rowConditionalStyles": [
{ "condition": { ">=": [{ "var": "scoreReputacao" }, 90] }, "cssClass": "row--success" },
{ "condition": { "<": [{ "var": "scoreReputacao" }, 40] }, "cssClass": "row--danger" },
{
"condition": {
"and": [
{ ">=": [{ "var": "incidentes" }, 3] },
{ "<": [{ "var": "scoreReputacao" }, 70] }
]
},
"cssClass": "row--warning"
}
],
"appearance": {
"animations": {
"enabled": true,
"duration": 650,
"specific": { "row": true, "cell": true }
}
}
}Aprenda neste exemplo
- Formatação condicional é boa para risco, score, SLA, aging e qualquer sinal operacional recorrente.
- A mesma regra pode ser editada, versionada e revisada sem recompilar a tela.
- O backend continua dono da regra de negócio; a tabela governa a leitura visual do estado publicado.
11. Renderers condicionais
A regra também pode trocar o renderer da célula. Score, risco ou status escolhem badge, icon, progress ou compose pelo contrato.
O que você vê: Score, risco ou status alteram badge, icon, progress ou compose sem mudar o template Angular.
Modo: quickstart
Preview ao vivo: requer JavaScript para materializar a tabela Angular.
Endpoints: POST /api/human-resources/vw-ranking-reputacao/filter GET /schemas/filtered?path=/api/human-resources/vw-ranking-reputacao/filter&operation=post&schemaType=response
Arquivos
conditional-renderers.json(json)rules-editor.patch.json(json)example.html(html)
conditional-renderers.json
{
"columns": [
{
"field": "scoreReputacao",
"header": "Score",
"conditionalRenderers": [
{
"condition": { ">=": [{ "var": "scoreReputacao" }, 90] },
"renderer": {
"type": "badge",
"badge": {
"text": "Excelente",
"color": "success",
"variant": "soft",
"icon": "workspace_premium"
}
},
"animation": { "preset": "pulse-soft", "trigger": "onAppear", "repeat": "once" }
},
{
"condition": { "<": [{ "var": "scoreReputacao" }, 40] },
"renderer": {
"type": "badge",
"badge": {
"text": "Crítico",
"color": "warn",
"variant": "soft",
"icon": "priority_high"
}
},
"animation": { "preset": "warning-attention", "trigger": "onAppear", "repeat": "once" }
}
]
}
]
}Aprenda neste exemplo
- Não é necessário criar um componente Angular para cada estado visual.
- O contrato preserva fallback: se nenhuma condição bater, a coluna usa o renderer padrão.
- Renderer condicional é útil para status, risco, prioridade, tendência, aprovação e qualidade de dados.
12. Rastreador de SLA
SLA combina prioridade, idade e risco em leitura operacional imediata. A tabela deixa claro o que precisa de atenção sem criar uma tela especializada.
O que você vê: Missões agregadas mostram status, prioridade e idade operacional com destaque visual.
Modo: quickstart
Preview ao vivo: requer JavaScript para materializar a tabela Angular.
Endpoints: POST /api/operations/vw-resumo-missoes/filter GET /schemas/filtered?path=/api/operations/vw-resumo-missoes/filter&operation=post&schemaType=response
Arquivos
table.config.json(json)sla.rules.json(json)example.html(html)
sla.rules.json
{
"columns": [
{
"field": "ageDays",
"header": "Idade",
"computed": { "expression": { "daysSince": [{ "var": "createdAt" }] }, "outputType": "number" }
}
],
"rowConditionalStyles": [
{ "condition": { ">": [{ "var": "computed.ageDays" }, 5] }, "cssClass": "row--warning" },
{
"condition": {
"and": [
{ "===": [{ "var": "prioridade" }, "CRITICA"] },
{ ">=": [{ "var": "risco" }, 85] }
]
},
"cssClass": "row--danger"
}
]
}Aprenda neste exemplo
- Computed fields servem como ponte entre dado cru e decisão visual.
- O mesmo valor calculado pode ser exibido, filtrado visualmente e usado em regra condicional.
- SLA fica legível na primeira leitura: prioridade, idade e risco apontam onde agir.
13. Filtros server-side
Filtro, paginação e sort passam pelo backend da aplicação. A UI materializa multi-selects, lookup, ranges e atalhos publicados por /schemas/filtered.
O que você vê: A tabela usa o DTO real de operations.missoes para exibir status, prioridade, período previsto e ameaça como filtros removíveis na toolbar.
Modo: quickstart
Preview ao vivo: requer JavaScript para materializar a tabela Angular.
Endpoints: POST /api/operations/missoes/filter?page=0&size=20&sort=prioridade,desc GET /schemas/filtered?path=/api/operations/missoes/filter&operation=post&schemaType=request
Arquivos
filter.payload.json(json)example.html(html)table.config.json(json)
filter.payload.json
{
"statusIn": ["PAUSADA", "EM_ANDAMENTO"],
"prioridadeIn": ["ALTA", "CRITICA"],
"inicioPrevBetween": {
"startDate": "2026-04-01T00:00:00Z",
"endDate": "2026-04-30T23:59:59Z"
},
"ameacaId": 8
}Aprenda neste exemplo
- Server-side continua dono de filtro, paginação e sort.
- O botão de adicionar gerencia selectedFieldIds; filtros pré-exibidos podem ser removidos sem duplicar campos.
- O mesmo contrato alimenta toolbar compacta, painel avançado e payload final enviado para /filter.
14. Filtros inline na toolbar
Campos frequentes aparecem direto na toolbar. O mesmo DTO suporta busca textual, multi-select, lookup, período relativo e ranges sem formulário manual.
O que você vê: Título, status, prioridade, período previsto e preset de início aparecem como controles compactos acima da tabela, com opções vindas do DTO real.
Modo: quickstart
Preview ao vivo: requer JavaScript para materializar a tabela Angular.
Endpoints: POST /api/operations/missoes/filter GET /schemas/filtered?path=/api/operations/missoes/filter&operation=post&schemaType=request POST /api/risk-intelligence/ameacas/options/filter
Arquivos
filter.settings.json(json)example.html(html)payload.json(json)
filter.settings.json
{
"behavior": {
"filtering": {
"enabled": true,
"advancedFilters": {
"enabled": true,
"settings": {
"selectedFieldIds": ["titulo", "statusIn", "prioridadeIn", "inicioPrevBetween", "inicioPrevPreset"],
"advancedOpenMode": "modal",
"allowSaveTags": true,
"changeDebounceMs": 0
}
}
}
}
}Aprenda neste exemplo
- Filtros inline são ótimos para decisões recorrentes, sem esconder o restante do DTO.
- Campos densos continuam disponíveis no painel avançado pelo mesmo contrato.
- allowSaveTags permite transformar uma busca útil em atalho reutilizável na toolbar.
15. Configuração de filtro avançado
O filtro avançado mostra ranges, lookups, atalhos salvos e payload auditável como parte da experiência governada da tabela.
O que você vê: O painel avançado pode expor lookup de ameaça, status, prioridade e ranges de início/término sem sobrecarregar a toolbar principal.
Modo: quickstart
Preview ao vivo: requer JavaScript para materializar a tabela Angular.
Endpoints: POST /api/operations/missoes/filter GET /schemas/filtered?path=/api/operations/missoes/filter&operation=post&schemaType=request POST /api/risk-intelligence/ameacas/options/filter
Arquivos
filter.payload.json(json)shortcuts.json(json)example.html(html)
filter.payload.json
{
"statusIn": ["PAUSADA", "EM_ANDAMENTO"],
"prioridadeIn": ["ALTA", "CRITICA"],
"ameacaId": 8,
"inicioPrevBetween": {
"startDate": "2026-04-01T00:00:00Z",
"endDate": "2026-04-30T23:59:59Z"
},
"fimPrevBetween": {
"startDate": "2026-04-20T00:00:00Z",
"endDate": "2026-05-10T23:59:59Z"
}
}Aprenda neste exemplo
- O filtro deixa de ser dois selects soltos e vira uma superfície de consulta governada.
- O painel avançado acomoda campos densos sem sobrecarregar a toolbar principal.
- O payload final continua legível para auditoria e compatível com o backend.
16. Seleção e ações em lote
Seleção e bulk action formam um contrato de interação. A tabela captura a intenção, preserva os registros selecionados e abre o fluxo rico da aplicação.
O que você vê: A tabela permite selecionar missões, acionar comandos em lote e abrir ações por linha com contexto estruturado.
Modo: quickstart
Preview ao vivo: requer JavaScript para materializar a tabela Angular.
Endpoints: POST /api/operations/missoes/filter GET /api/operations/missoes/{id}/capabilities GET /schemas/actions?resource=operations.missoes
Arquivos
table.config.json(json)example.html(html)bulk-handler.ts(ts)
table.config.json
{
"behavior": {
"selection": { "enabled": true, "type": "multiple", "mode": "checkbox" }
},
"actions": {
"row": {
"enabled": true,
"display": "buttons",
"actions": [
{ "id": "summary", "label": "Resumo", "icon": "travel_explore", "action": "summary" },
{ "id": "capabilities", "label": "Capabilities", "icon": "security", "action": "capabilities" }
]
},
"bulk": {
"enabled": true,
"position": "toolbar",
"actions": [
{ "id": "briefing", "label": "Briefing", "icon": "assignment", "action": "briefing", "minSelections": 1 },
{ "id": "reprioritize", "label": "Repriorizar", "icon": "published_with_changes", "action": "reprioritize", "minSelections": 1 }
]
}
}
}Aprenda neste exemplo
- O clique abre contexto rico com métricas, timeline e registros selecionados.
- A tabela captura intenção estruturada; a aplicação executa workflow, confirmação e política.
- O mesmo padrão serve para exportar, aprovar, delegar, auditar ou abrir surfaces do item.
17. Aprovação em lote segura
Ação em lote liga seleção, confirmação, endpoint real e feedback estruturado. A UI mostra a intenção; a aplicação valida e executa.
O que você vê: Um fluxo de briefing ou repriorização recebe a seleção e abre contexto rico antes de executar o workflow.
Modo: integration
Preview ao vivo: requer JavaScript para materializar a tabela Angular.
Endpoints: POST /api/operations/missoes/filter GET /api/operations/missoes/{id}/capabilities GET /schemas/actions?resource=operations.missoes
Arquivos
bulk-handler.ts(ts)confirm-dialog.json(json)workflow-response.json(json)
bulk-handler.ts
onBulkAction(event: { action: string; rows: unknown[] }) {
if (event.action !== 'briefing' && event.action !== 'reprioritize') return;
this.dialog.open(MissionWorkflowDialog, {
data: {
action: event.action,
rows: event.rows,
surface: 'operations.missoes.workflow'
}
});
return this.http.post('/api/operations/missoes/actions/' + event.action, {
ids: event.rows.map((row: any) => row.id),
source: 'governed-table-action',
evidence: {
selectedCount: event.rows.length,
priorities: event.rows.map((row: any) => row.prioridade),
averageRisk: calculateAverageRisk(event.rows)
}
});
}Aprenda neste exemplo
- A ação em lote não deve executar no escuro: primeiro mostra contexto, risco e escopo.
- Briefing e repriorização podem compartilhar o mesmo contrato de seleção.
- A superfície rica ajuda o usuário a confirmar a intenção com confiança.
18. Linha expansível com conteúdo rico
Expansion abre contexto rico abaixo da linha: mediaBlock, detailList, cardGrid, timeline e actionBar aparecem por contrato.
O que você vê: Missões expandem para mostrar resumo, participantes, eventos recentes e ações contextuais.
Modo: quickstart
Preview ao vivo: requer JavaScript para materializar a tabela Angular.
Endpoints: POST /api/operations/missoes/filter GET /api/operations/missoes/{id}/capabilities GET /schemas/filtered?path=/api/operations/missoes/filter&operation=post&schemaType=response
Arquivos
expansion.config.json(json)example.html(html)detail-schema.json(json)
expansion.config.json
{
"behavior": {
"expansion": {
"enabled": true,
"interaction": { "trigger": "icon", "toggleOnRowClick": false },
"limits": { "allowMultiple": true, "maxExpandedRows": 2 },
"detail": {
"schemaContract": {
"kind": "praxis.detail.schema",
"version": "1.0.0",
"allowedNodes": ["mediaBlock", "cardGrid", "detailList", "timeline", "actionBar"]
},
"source": {
"mode": "inline",
"inlineSchema": {
"layout": "stack",
"items": [
{ "type": "mediaBlock" },
{ "type": "cardGrid", "title": "Resumo operacional" },
{ "type": "detailList", "field": "participantes" },
{ "type": "timeline", "field": "atividade" },
{ "type": "actionBar", "title": "Ações rápidas" }
]
}
},
"rendering": { "strategy": "registry", "registryId": "praxis.detail.default" }
}
}
}
}Aprenda neste exemplo
- Expansion mostra contexto sem tirar o usuário da tabela.
- O mesmo contrato pode renderizar cards, listas, timeline, badges, avatares e actions.
- A surface de detalhe é governada, cacheável e fechada para nós não permitidos.
19. Expansão por hypermedia e capabilities
O detail também pode nascer de _links.capabilities. Quando a aplicação não publica a affordance, a tabela fecha o caminho em vez de inventar contexto.
O que você vê: A tabela resolve surfaces e actions sob demanda ao expandir uma linha autorizada.
Modo: integration
Preview ao vivo: requer JavaScript para materializar a tabela Angular.
Endpoints: POST /api/operations/missoes/filter GET /api/operations/missoes/{id}/capabilities GET /schemas/surfaces?resource=operations.missoes
Arquivos
hypermedia.config.json(json)capabilities.response.json(json)example.html(html)
hypermedia.config.json
{
"behavior": {
"expansion": {
"enabled": true,
"detail": {
"schemaContract": {
"kind": "praxis.detail.schema",
"version": "1.0.0"
},
"source": {
"mode": "hypermedia",
"hypermedia": { "rel": "capabilities" }
},
"rendering": { "strategy": "registry", "registryId": "praxis.detail.default" }
}
}
}
}Aprenda neste exemplo
- Itens diferentes podem publicar surfaces diferentes sem redeploy da tela.
- A tabela atua como runtime de discovery: ela busca, valida e materializa capabilities.
- Capabilities agregam actions, views e read projections no contexto do item selecionado.
20. Editor visual de configuração
O editor visual transforma a tabela em superfície authorable: colunas, renderers, filtros, ações, regras, mensagens e aparência mudam em runtime.
O que você vê: O editor visual abre a configuração da tabela, aplica mudanças, salva e reabre sem perder o contrato.
Modo: integration
Preview ao vivo: requer JavaScript para materializar a tabela Angular.
Endpoints: POST /api/human-resources/funcionarios/filter GET /schemas/filtered?path=/api/human-resources/funcionarios/filter&operation=post&schemaType=response Config storage da aplicação para salvar TableAuthoringDocument
Arquivos
example.html(html)table-authoring-document.json(json)editor.patch.json(json)
example.html
<praxis-table
tableId="employees-authorable-table"
resourcePath="human-resources/funcionarios"
[enableCustomization]="true"
(configChange)="persistTableConfig($event)"
></praxis-table>