Proteção contra Perda

Confirmação ao sair com alterações não salvas

Implementado em: 2026-04-02 Status: Ativo


Resumo

O editor visual de fluxos (FlowBuilder) detecta automaticamente quando o usuário fez modificações não salvas e exibe um dialog customizado ao tentar sair, evitando perda acidental de trabalho.


Como Funciona

Dirty State Tracking

O sistema compara o estado atual dos nodes e edges com um snapshot salvo:

// FlowEditor.tsx
const savedSnapshotRef = useRef<string>("")
const [isDirty, setIsDirty] = useState(false)

// Salva snapshot inicial
useEffect(() => {
  savedSnapshotRef.current = JSON.stringify({ nodes: flow.nodes, edges: flow.edges })
}, [])

// Detecta mudanças
useEffect(() => {
  const current = JSON.stringify({ nodes, edges })
  setIsDirty(current !== savedSnapshotRef.current)
}, [nodes, edges])

// Após salvar, reseta dirty
const handleSave = useCallback(async () => {
  await onSave({ nodes, edges })
  savedSnapshotRef.current = JSON.stringify({ nodes, edges })
  setIsDirty(false)
}, [nodes, edges, onSave])

Indicador Visual no Botão Salvar

Estado Aparência Cor
Sem alterações "Salvo" Azul (#1e7fd4)
Com alterações "Salvar*" + ponto vermelho pulsante Amarelo (#f59e0b)
Salvando Spinner + "Salvar" Azul

Dialog de Confirmação

Exibido via createPortal(dialog, document.body) para renderizar fora do ReactFlow e centralizar na tela.

Trigger: Clicar no botão voltar (seta) quando isDirty === true

Opções:

  1. "Salvar e sair" — Executa onSave(), depois router.push("/flow-builder")
  2. "Descartar e sair" — Navega direto sem salvar
  3. "Continuar editando" — Fecha dialog, volta ao editor

Design:

  • Backdrop com blur (bg-black/40 backdrop-blur-sm)
  • Card branco centralizado (max-w-sm rounded-2xl)
  • Ícone de alerta amarelo (AlertTriangleIcon)
  • Segue identidade visual ConvertaFlow (sem popup nativo Chrome)

Decisão: Sem beforeunload

O evento beforeunload do navegador foi removido intencionalmente:

Aspecto beforeunload (removido) Dialog customizado (implementado)
Visual Popup nativo Chrome (não customizável) Design ConvertaFlow
Trigger Fechar aba, digitar URL Botão voltar do editor
Opções "Sair" / "Cancelar" Salvar e sair / Descartar / Continuar
Customização Impossível Total

Arquivos

Arquivo Função
frontend/src/components/flow-builder/FlowEditor.tsx Dirty state tracking (savedSnapshotRef, isDirty)
frontend/src/components/flow-builder/FlowToolbar.tsx Dialog via portal, indicador visual, botão voltar

Este artigo foi útil?