Skip to content

Seu primeiro Widget Svelte ​

Tipo
Tutorial
Para
Desenvolvedor
Na tela
DataViz › Aplicação › Editar › Dashboards › Editando Widget › Svelte

No fim deste caminho você tem um Widget Svelte com os dez maiores vendedores, cada um com uma barra proporcional ao valor vendido. O Widget mostra carregando, erro e "sem dados" quando é o caso, funciona no tema claro e no escuro, e um clique num vendedor filtra o Dashboard inteiro.

Antes de começar ​

  • Edição da Aplicação na Minha Mesa e um Dashboard aberto no editor. Veja Dashboards.
  • Uma tabela na Aplicação com uma dimensão e uma medida. O exemplo usa a tabela Vendas, com as colunas VENDEDOR e VALOR; troque pelos nomes da sua.
  • Conhecer o básico de Svelte 4: export let, {#if}, {#each}, on:click.

1. Ponha o Widget na grade ​

No Catálogo de widgets, escolha Svelte e arraste para a grade. Dê pelo menos 4 colunas e 4 linhas: o ranking precisa de altura.

O Widget aparece vazio, porque ainda não tem código.

2. Abra o editor ​

No configurador, aba Geral, em Código, clique em Editar Código.

O editor abre com uma aba, Main.svelte, vazia. No topo ficam Gerar com IA, Testar e Salvar e Sair.

3. Escreva a consulta ​

Cole o script abaixo em Main.svelte. Ele consulta a Aplicação quando o Widget monta e guarda o resultado já formatado.

svelte
<script>
  import { onMount } from 'svelte';

  export let app;

  const VENDEDOR = '[Vendas]."VENDEDOR":AGP';
  const VALOR = '[Vendas]."VALOR":SUM';

  let carregando = true;
  let erro = null;
  let linhas = [];

  onMount(async () => {
    try {
      const res = await app.fetchMatrix({
        columns: [VENDEDOR, VALOR],
        orderBy: [`${VALOR}:DESC`],
        limit: 10,
      });

      const maior = Math.max(...res.Result.map((r) => Number(r[1]) || 0), 1);

      linhas = res.Result.map(([nome, valor]) => ({
        nome,
        texto: app.formatValue(valor, res.Columns[1]),
        largura: Math.round(((Number(valor) || 0) / maior) * 100),
      }));
    } catch (e) {
      erro = e?.message ?? String(e);
    } finally {
      carregando = false;
    }
  });
</script>

Três escolhas desse script valem para qualquer Widget:

  • As colunas são referenciadas pelo nome ('[Vendas]."VALOR":SUM'), nunca pelo número da coluna, que muda de um Tenant para outro. Todo campo leva um sufixo, como :AGP ou :SUM; veja Referência de coluna.
  • O valor passa por app.formatValue, que aplica a máscara da coluna (moeda, casas decimais) no idioma de quem vê. Número cru na tela fica diferente de todo o resto do Dashboard.
  • A consulta fica dentro de try/catch. Um erro que escapa do onMount não aparece em lugar nenhum: o Widget fica em branco e ninguém sabe por quê.

Você não passa os filtros do Dashboard: app.fetchMatrix já aplica os da barra e os pré-aplicados do Widget.

4. Desenhe os quatro estados ​

Abaixo do script, no mesmo arquivo, cole o markup:

svelte
{#if carregando}
  <div class="flex h-full items-center justify-center text-sm text-slate-500 dark:text-navy-300">
    Carregando…
  </div>
{:else if erro}
  <div class="flex h-full items-center justify-center p-4">
    <p class="text-sm text-red-600 dark:text-red-400">{erro}</p>
  </div>
{:else if linhas.length === 0}
  <div class="flex h-full items-center justify-center text-sm text-slate-500 dark:text-navy-300">
    Sem dados no período
  </div>
{:else}
  <ul class="w-full space-y-1 p-4 text-slate-800 dark:text-navy-100">
    {#each linhas as l}
      <li>
        <button
          class="w-full rounded px-2 py-1 text-left hover:bg-slate-100 dark:hover:bg-navy-700"
          on:click={() => alternar(l.nome)}
        >
          <div class="flex justify-between text-sm">
            <span>{l.nome}</span>
            <span class="font-mono">{l.texto}</span>
          </div>
          <div class="mt-1 h-1.5 rounded bg-slate-200 dark:bg-navy-600">
            <div class="h-1.5 rounded bg-indigo-500" style="width: {l.largura}%"></div>
          </div>
        </button>
      </li>
    {/each}
  </ul>
{/if}

Cada cor tem o par dark:, e no escuro as superfícies e os textos usam a escala navy, a mesma do Dashboard. Sem o par, o Widget fica claro no meio de um Dashboard escuro. A raiz da lista não leva h-full com overflow-auto: a célula do Widget já controla a altura e a rolagem, e essa combinação na raiz corta o conteúdo na exportação para PDF. As outras regras de tema e tamanho estão em Boas práticas.

5. Filtre o Dashboard no clique ​

O markup chama alternar, que ainda não existe. Acrescente esta função dentro do <script>, depois do onMount:

javascript
function alternar(nome) {
  const coluna = app.columnFromString(VENDEDOR);
  if (!coluna) return;
  const atual = app.getFilter(coluna);
  if (atual && atual.value === nome) {
    app.addFilter(coluna, '=', false); // remove o filtro
  } else {
    app.addFilter(coluna, '=', nome);
  }
}

app.addFilter põe o filtro na barra do Dashboard, e todos os Widgets se atualizam, inclusive este. Valor false tira o filtro daquela coluna. Uma coluna que não está entre os filtros permitidos do Dashboard é ignorada sem aviso; veja Filtros.

6. Teste e salve ​

Clique em Testar. O botão mostra "Compilando..." e, se o código compila, aparece "Código compilado com sucesso!". Se não compila, a mensagem diz a linha. Sintaxe de Svelte 5 como onclick={...} no lugar de on:click={...} nem sempre dá erro: o clique só não faz nada. Veja Boas práticas.

Clique em Salvar e Sair e salve o Dashboard. O Widget mostra "Carregando…" e, em seguida, o ranking.

Confira que funcionou ​

  • O ranking mostra até dez vendedores, com o valor na máscara da coluna VALOR.
  • Ao clicar num vendedor, o filtro aparece na barra do Dashboard e os outros Widgets passam a mostrar só esse vendedor. Clicar de novo tira o filtro.
  • Com um filtro de período sem venda, o Widget mostra "Sem dados no período".
  • No tema escuro, fundo e texto acompanham o Dashboard.
  • Se você trocar VALOR por um nome que não existe e testar, o Widget mostra a mensagem de erro da consulta no lugar do ranking.

Gerar com IA ​

Gerar com IA abre um painel ao lado do código. Em Descreva o código que você quer gerar, escreva o que o Widget deve fazer ("Ex: Crie um gráfico de barras com os dados de vendas") e clique em Gerar. A IA conhece as tabelas da Aplicação e as regras do app. A mudança chega em Revisão de Mudanças, com o que muda linha a linha: Inserir código aplica, Rejeitar descarta. Copiar Prompt leva o mesmo contexto para uma IA externa.

Quando um Widget já salvo mostra Erro de compilação no editor do Dashboard, Corrigir com IA abre o editor com o erro já enviado ao painel.

Próximos passos ​

  • Exemplos: gráfico com Highcharts, drilldown para o Explorer, comparação com o período anterior.
  • Boas práticas: o que faz um Widget sobreviver a outro Tenant, ao tema do aplicativo móvel e à exportação.
  • Componentes paramétricos: transformar este ranking num tipo de Widget que outros configuram sem código.