# Implementação frontend

## Views criadas

- `componentes/Missoes/Dashboards/sinais/Expedicao/html/configurando.php` — tela de transição centralizada (Metronic `card` + `app-content`); exibe spinner ou ícone de erro, título fixo, subtítulo dinâmico, alerta "demorando" e área de erro com botão retry. Variável de entrada: `$setupStatus` (array retornado por `AutoSetupExpedicaoLaboratorio::verificar()`).
- `componentes/Missoes/Dashboards/sinais/Expedicao/html/configurando.js` — polling 4s + rotação de subtítulos 8s + timer de 5min + retry. Ver seção "Decisões de UI" abaixo.

## Forms

Nenhum form novo — o fluxo de setup não expõe campo de entrada ao usuário.

## i18n

Chaves adicionadas nos 3 arquivos (`linguagens/pt-br.json`, `linguagens/en.json`, `linguagens/es.json`). As chaves são MD5 da string original em português (padrão do `show()` do framework):

| Chave MD5 | String pt-br | en | es |
|---|---|---|---|
| `cbda02c5f95d123e887e0d34d24ae6d2` | Estamos configurando os dados de acesso | We are setting up your access data | Estamos configurando los datos de acceso |
| `5023c4c1437c7df21aa9bf4cd7e89c65` | Aguardando início... | Waiting to start... | Esperando inicio... |
| `a21909da85b4f14ee3a2d367ff47f6cf` | Processando dados das últimas 7 entregas... | Processing data from the last 7 deliveries... | Procesando datos de las últimas 7 entregas... |
| `9f94003703a702b60adcd560f608890f` | Quase lá... | Almost there... | Casi listo... |
| `9cc77b9b1dd87ff916d33e6b359df460` | Demorando mais que o esperado, mas continuamos tentando... | Taking longer than expected, but we are still trying... | Demorando más de lo esperado, pero seguimos intentando... |
| `34ae55ce18e3413b274fa41750afa4ea` | Ocorreu um erro durante a configuração. | An error occurred during setup. | Ocurrió un error durante la configuración. |
| `836a00c1e6e94d9fc66f6f1b64e63793` | Tentar novamente | Try again | Intentar de nuevo |

Nota: o `show()` do Genesis usa MD5 da string literal como chave. As chaves do PRD (ex.: `dashboard.setup.titulo`) foram mapeadas para esse padrão. Não há dot-notation no sistema de i18n real.

## Endpoints consumidos

- `POST /labs/apis/Dashboards/Expedicao/StatusSetupSatelite/verificar`
  - Payload: vazio (block lido da sessão pelo backend)
  - Resposta: `{ status, iniciado_em, finalizado_em, erro, mensagem }`
  - Usado pelo: polling automático a cada 4s

- `POST /labs/apis/Dashboards/Expedicao/StatusSetupSatelite/iniciar`
  - Payload: vazio
  - Resposta: mesmo formato acima
  - Usado pelo: botão "Tentar novamente" quando `status = falhou`

## Decisões de UI relevantes

1. **Variável de entrada**: a view lê `$setupStatus` (array completo do laboratório), não variáveis separadas. Isso evita que o controller precise extrair campos individualmente.

2. **Subtítulos pré-renderizados**: as 3 strings de subtítulo são traduzidas no PHP via `show()` e embutidas em um `<input type="hidden">` como JSON. O JS lê esse campo e faz a rotação sem chamar o servidor — i18n funciona mesmo com cookie de idioma diferente do padrão.

3. **Estado inicial "falhou"**: se o backend renderiza a view com `status = falhou` (ex.: retry manual), o JS detecta isso via `<input id="setup-status-inicial">` e exibe a área de erro diretamente, sem iniciar polling — evita um ciclo de verificar + mostrar erro logo em seguida.

4. **Retry não reinicia o spinner até a resposta do `iniciar`**: o botão fica `disabled` durante a chamada; só após sucesso da chamada AJAX o spinner volta e o polling recomeça. Isso evita confusão visual se o `iniciar` falhar.

5. **Polling não para por erros de rede**: falhas HTTP transitórias no `verificar` são logadas no console mas não interrompem o intervalo — apenas um `status = falhou` do backend para o polling.

6. **Sem `setSemHeader`**: a tela de transição usa o layout padrão do Metronic (com header/menu). Isso é intencional — o usuário está autenticado e logado; remover o header criaria uma tela "vazia" confusa. A área `app-content` com `min-height` cobre o espaço disponível.

7. **IIFE no JS**: o script usa `(function(){ 'use strict'; ... }())` para isolar escopo e evitar colisão com globals de outras views do Metronic já carregadas.

## Smoke test sugerido

1. Em `dev_gx_goldie`, deletar a linha do block de teste: `DELETE FROM dashboard_expedicao_setup WHERE block = <N>;`
2. (Opcional) Deletar grupos do block: `DELETE FROM grupos_regioes WHERE block = <N>;`
3. Logar como usuário do block N e abrir `/missao/dashboards/Expedicao`.
4. Verificar: tela "Estamos configurando os dados de acesso" aparece com spinner e subtítulo.
5. Aguardar ~10s e observar o subtítulo rotacionar (troca a cada 8s).
6. Aguardar o cron concluir (~30s dependendo do volume) — a página deve recarregar automaticamente e exibir o dashboard com dados.
7. Para testar o fluxo "falhou": `UPDATE dashboard_expedicao_setup SET status='falhou', erro_mensagem='Teste de erro' WHERE block = <N>;` e recarregar a página — deve mostrar a mensagem de erro e o botão "Tentar novamente".
8. Clicar em "Tentar novamente" — deve limpar o erro, mostrar spinner e reiniciar o setup.
9. Para testar "demorando": abrir o devtools e reduzir `TIMEOUT_DEMORANDO_MS` para 5000 (5s) direto no console — após 5s sem `status = pronto` o alerta amarelo deve aparecer.
