feat(nav): menu "Cadastro" agrupando Empresas/Produtos/Revendas/Clientes

Empresas, Produtos (com toda a árvore de submenus), Revendas e Clientes
saem do nível 1 do menu e passam a viver dentro de um novo item
"Cadastro". Isso exercita 3 níveis de submenu aninhado pela primeira
vez (Cadastro > Produtos > Grupos > Subgrupos) — a recursão do AppShell
já suportava isso estruturalmente, mas estava documentada como não
testada; verificado ao vivo via Playwright que funciona corretamente
(auto-expande só o caminho ativo em cada nível).

Suíte: 95/95. pnpm turbo run typecheck build: 28/28.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-18 12:20:24 -03:00
parent 4e4de2c259
commit 53c3031775
3 changed files with 42 additions and 19 deletions

View File

@@ -45,31 +45,38 @@ function withActive(items: NavItemDef[], pathname: string): AppShellNavItem[] {
const NAV_ITEM_DEFS: NavItemDef[] = [
{ key: "dashboard", label: "Painel", href: "/" },
{ key: "companies", label: "Empresas", href: "/companies" },
{
key: "products",
label: "Produtos",
href: "/products",
key: "registration",
label: "Cadastro",
href: "/companies",
children: [
{ key: "products-list", label: "Itens", href: "/products" },
{ key: "products-types", label: "Tipos", href: "/products/types" },
{ key: "companies", label: "Empresas", href: "/companies" },
{
key: "products-groups",
label: "Grupos",
href: "/products/groups",
key: "products",
label: "Produtos",
href: "/products",
children: [
{ key: "products-groups-list", label: "Grupos", href: "/products/groups" },
{ key: "products-subgroups", label: "Subgrupos", href: "/products/subgroups" },
{ key: "products-list", label: "Itens", href: "/products" },
{ key: "products-types", label: "Tipos", href: "/products/types" },
{
key: "products-groups",
label: "Grupos",
href: "/products/groups",
children: [
{ key: "products-groups-list", label: "Grupos", href: "/products/groups" },
{ key: "products-subgroups", label: "Subgrupos", href: "/products/subgroups" },
],
},
{ key: "products-brands", label: "Marcas", href: "/products/brands" },
{ key: "products-units", label: "Unidades", href: "/products/units" },
],
},
{ key: "products-brands", label: "Marcas", href: "/products/brands" },
{ key: "products-units", label: "Unidades", href: "/products/units" },
{ key: "resellers", label: "Revendas", href: "/resellers" },
{ key: "client-registrations", label: "Clientes", href: "/client-registrations" },
],
},
{ key: "resellers", label: "Revendas", href: "/resellers" },
{ key: "leads", label: "CRM", href: "/leads" },
{ key: "quotes", label: "Ofertas", href: "/quotes" },
{ key: "client-registrations", label: "Clientes", href: "/client-registrations" },
{ key: "contracts", label: "Contratos", href: "/contracts" },
{ key: "documents", label: "Documentos", href: "/documents/templates" },
{ key: "signatures", label: "Assinaturas", href: "/signatures" },

View File

@@ -678,3 +678,19 @@ Nenhuma ferramenta de browser automation (`claude-in-chrome`) estava disponível
### Verificação
`pnpm turbo run typecheck build` 28/28. Suíte 95/95 (uma corrida isolada apresentou uma falha pontual num `afterAll` de outro spec depois de várias execuções seguidas da suíte hoje contra o mesmo Postgres compartilhado — não reproduziu nas execuções seguintes, tratado como ambiental, não investigado a fundo). Verificação em navegador real via Playwright headless: dump de DOM confirmando os 5 rótulos corretos em `/products/{types,groups,subgroups,brands,units}`, screenshots confirmando visualmente o submenu aninhado "Grupos" expandido mostrando "Grupos"/"Subgrupos", a tela de Subgrupos com dropdown "Grupo" + campo "Nome do subgrupo" + coluna "Grupo" na tabela, e o painel "Ver subgrupos" dentro de um grupo específico também com "Nome do subgrupo". Linhas de teste acumuladas nos 5 catálogos ao longo do dia (múltiplas rodadas de suíte + smoke tests) desativadas ao final — só sobraram duas linhas de subgrupo não reconhecidas como teste automatizado ("teste"/"qqweqw", possivelmente exploração manual do próprio usuário) deliberadamente preservadas, não mexidas.
---
## Menu "Cadastro" — agrupando Empresas/Produtos/Revendas/Clientes
Data: 2026-09-18. Usuário pediu para agrupar os cadastros de dados mestres num menu próprio: "vamos criar um menu cadastro, e dentro do menu cadastro vai estar o cadastro do produto com seus submenus, cadastro de revenda cadastro de clientes e cadastro da empresa". Também sinalizou que o próximo passo será ajustar a tela de Cadastro de Cliente (`client-registrations`) — ainda sem especificar o quê, fica para a próxima leva.
`AuthenticatedLayout.tsx`: novo item de nível 1 "Cadastro" (logo após "Painel") reunindo "Empresas", "Produtos" (com toda a árvore de submenus já existente — Itens/Tipos/Grupos{Grupos,Subgrupos}/Marcas/Unidades, agora um nível mais fundo), "Revendas" e "Clientes" — os 4 saíram do nível 1 do menu. `withActive()` já era recursivo (nenhuma mudança de lógica necessária); só a estrutura de dados (`NAV_ITEM_DEFS`) mudou.
Isso exercita profundidade 3 no `AppShell` (Cadastro > Produtos > Grupos > Subgrupos) pela primeira vez — o comentário do componente dizia explicitamente "depth beyond 2 levels is untested". Verificado ao vivo via Playwright que funciona corretamente (auto-expande só o caminho ativo em cada nível, sem abrir irmãos à toa) — comentário atualizado para refletir que a recursão é validada, não só "estruturalmente não impedida".
### Verificação
`pnpm turbo run typecheck build` 28/28. Suíte 95/95. Verificado ao vivo com Playwright headless (login real, dump de DOM da sidebar em `/companies`, `/products/groups`, `/products/subgroups`, `/resellers`, `/client-registrations`, e no painel): "Cadastro" some fechado quando nenhum filho está ativo, abre exatamente o caminho certo nos outros casos, screenshot conferindo visualmente a indentação dos 3 níveis.
### Pendências
Ajustes na tela de Cadastro de Cliente — usuário sinalizou que é o próximo passo, ainda sem especificar quais ajustes.

View File

@@ -12,10 +12,10 @@ export interface AppShellNavItem {
* When present (even if empty), this item renders as an expandable
* accordion group instead of a direct link — `href` is then only a
* placeholder (typically duplicated by the first child) and is never
* navigated to directly. A child may itself declare `children`, nesting
* another accordion one level deeper (e.g. Produtos > Grupos >
* Subgrupos) — depth beyond that is untested but not structurally
* prevented.
* navigated to directly. Recursion is unbounded — a child may itself
* declare `children`, nesting another accordion arbitrarily deeper.
* Confirmed 3 levels deep in `core-web` (Cadastro > Produtos > Grupos >
* Subgrupos).
*/
children?: AppShellNavItem[];
}