feat(nav): arrastar-e-soltar pra reordenar o menu, persistindo entre sessões
Pedido do usuário: "testa arrastando um sub menu pra ver se persiste" — o acordeão da fase anterior só tinha abrir/fechar, nada de arrastar. Perguntei o que ele queria dizer com "arrastar" antes de supor, e a resposta foi: quer a funcionalidade de verdade. @dnd-kit (core + sortable) — cada grupo do menu pode ser arrastado pra reordenar entre si; cada sub-item dentro de um grupo pode ser arrastado pra reordenar DENTRO do próprio grupo (nunca sai pra outro grupo arrastando, checado explicitamente no onDragEnd). Alça de arrastar dedicada (GripVertical) em vez do item inteiro, pra não conflitar com o clique de abrir/fechar acordeão ou navegar pelo link. Ordem salva em localStorage (nav-order.ts), nunca banco — preferência pessoal do navegador, mesma convenção já usada pelo ThemeToggle (claro/escuro/sistema). Uma chave só serve os dois menus (Platform e Tenant), sem colisão de rótulos entre eles. Achado real testando: aplicar a ordem salva direto no inicializador do useState diverge do HTML que o servidor mandou (SSR nunca tem acesso a localStorage) e disparava "Hydration failed" no React — inofensivo no resultado final, mas um erro real no console e uma renderização inteira desperdiçada. Corrigido aplicando a ordem salva só dentro de um useEffect (roda uma vez, só no client) — o mesmo padrão que o ThemeToggle já usava e eu não tinha replicado. Testado com Playwright de verdade em dois cenários: arrastar um grupo inteiro (ordem mudou e sobreviveu a um F5 completo) e arrastar um sub-item dentro de "Discador" (reordenou só ali dentro, confirmado que os outros grupos continuaram intactos, e também sobreviveu ao F5). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFaBaBSQGhyXGEgtTYZGV8
This commit is contained in:
38
TODO.md
38
TODO.md
@@ -2299,6 +2299,44 @@ arcordeon no menu para que eu poder reocler cada sub menu")
|
||||
`aria-expanded="false"`, clicar abre (`true`), clicar de novo fecha
|
||||
(`false`)
|
||||
|
||||
## PHASE 64 — Arrastar-e-soltar pra reordenar o menu (pedido do usuário:
|
||||
"testa arrastando um sub menu pra ver se persiste" — a resposta foi que
|
||||
não existia arrastar nenhum ainda, e depois de perguntar o usuário quis
|
||||
a funcionalidade de verdade)
|
||||
- [x] `@dnd-kit/core` + `@dnd-kit/sortable` — cada grupo do menu (nível
|
||||
raiz) pode ser arrastado pra reordenar entre si; cada sub-item
|
||||
dentro de um grupo pode ser arrastado pra reordenar DENTRO do
|
||||
próprio grupo (nunca sai pra outro grupo arrastando — checado
|
||||
explicitamente no `onDragEnd` comparando o rótulo da seção nos
|
||||
dois ids envolvidos). Alça de arrastar dedicada (ícone
|
||||
`GripVertical`) em vez do item inteiro, pra não conflitar com o
|
||||
clique de abrir/fechar acordeão ou navegar pelo link
|
||||
- [x] Ordem salva em `localStorage` (`nav-order.ts`), nunca banco —
|
||||
preferência pessoal do navegador, mesma convenção já usada pelo
|
||||
`ThemeToggle` (claro/escuro/sistema). Uma chave só serve os dois
|
||||
menus (Platform e Tenant): os rótulos de cada um nunca colidem, e
|
||||
cada um vive na sua própria entrada dentro do objeto salvo. Item
|
||||
novo que não estava salvo ainda (ex.: tela futura) entra no fim,
|
||||
nunca some por causa de uma ordem antiga
|
||||
- [x] **Achado real testando**: aplicar a ordem salva direto no
|
||||
inicializador do `useState` (`useState(() => aplicarOrdem(items))`)
|
||||
diverge do HTML que o servidor mandou (SSR nunca tem acesso a
|
||||
`localStorage`) e disparava "Hydration failed" no React —
|
||||
inofensivo no resultado final (React re-renderiza e corrige
|
||||
sozinho), mas um erro de verdade no console e uma renderização
|
||||
inteira desperdiçada. Corrigido aplicando a ordem salva só dentro
|
||||
de um `useEffect` (roda uma vez, só no client, depois de montar) —
|
||||
exatamente o mesmo padrão que o `ThemeToggle` já usava e eu não
|
||||
tinha replicado
|
||||
- [x] Testado com Playwright de verdade, dois cenários: (1) arrastar um
|
||||
GRUPO do menu (ex.: "Dashboard" pra depois de "Discador") — a
|
||||
ordem mudou na tela e sobreviveu a um F5 completo; (2) arrastar um
|
||||
SUB-ITEM dentro de "Discador" (ex.: "Campanhas" pra depois de
|
||||
"Leads") — reordenou só dentro do próprio grupo (confirmado que
|
||||
"Call Center" e os outros grupos continuaram intactos) e também
|
||||
sobreviveu ao F5. Confirmado ainda que corrigir a Hydration
|
||||
eliminou o erro do console sem quebrar nenhum dos dois cenários
|
||||
|
||||
---
|
||||
|
||||
## Riscos conhecidos
|
||||
|
||||
Reference in New Issue
Block a user